1 /****************************************************************************** 2 * 3 * Copyright (C) 2010-2014 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 /****************************************************************************** 20 * 21 * Handle ndef messages 22 * 23 ******************************************************************************/ 24 #include <string.h> 25 26 #include <android-base/stringprintf.h> 27 #include <base/logging.h> 28 29 #include "ndef_utils.h" 30 #include "nfa_api.h" 31 #include "nfa_dm_int.h" 32 33 using android::base::StringPrintf; 34 35 extern bool nfc_debug_enabled; 36 37 /******************************************************************************* 38 * URI Well-known-type prefixes 39 *******************************************************************************/ 40 const uint8_t* nfa_dm_ndef_wkt_uri_str_tbl[] = { 41 NULL, /* 0x00 */ 42 (const uint8_t*)"http://www.", /* 0x01 */ 43 (const uint8_t*)"https://www.", /* 0x02 */ 44 (const uint8_t*)"http://", /* 0x03 */ 45 (const uint8_t*)"https://", /* 0x04 */ 46 (const uint8_t*)"tel:", /* 0x05 */ 47 (const uint8_t*)"mailto:", /* 0x06 */ 48 (const uint8_t*)"ftp://anonymous:anonymous@", /* 0x07 */ 49 (const uint8_t*)"ftp://ftp.", /* 0x08 */ 50 (const uint8_t*)"ftps://", /* 0x09 */ 51 (const uint8_t*)"sftp://", /* 0x0A */ 52 (const uint8_t*)"smb://", /* 0x0B */ 53 (const uint8_t*)"nfs://", /* 0x0C */ 54 (const uint8_t*)"ftp://", /* 0x0D */ 55 (const uint8_t*)"dav://", /* 0x0E */ 56 (const uint8_t*)"news:", /* 0x0F */ 57 (const uint8_t*)"telnet://", /* 0x10 */ 58 (const uint8_t*)"imap:", /* 0x11 */ 59 (const uint8_t*)"rtsp://", /* 0x12 */ 60 (const uint8_t*)"urn:", /* 0x13 */ 61 (const uint8_t*)"pop:", /* 0x14 */ 62 (const uint8_t*)"sip:", /* 0x15 */ 63 (const uint8_t*)"sips:", /* 0x16 */ 64 (const uint8_t*)"tftp:", /* 0x17 */ 65 (const uint8_t*)"btspp://", /* 0x18 */ 66 (const uint8_t*)"btl2cap://", /* 0x19 */ 67 (const uint8_t*)"btgoep://", /* 0x1A */ 68 (const uint8_t*)"tcpobex://", /* 0x1B */ 69 (const uint8_t*)"irdaobex://", /* 0x1C */ 70 (const uint8_t*)"file://", /* 0x1D */ 71 (const uint8_t*)"urn:epc:id:", /* 0x1E */ 72 (const uint8_t*)"urn:epc:tag:", /* 0x1F */ 73 (const uint8_t*)"urn:epc:pat:", /* 0x20 */ 74 (const uint8_t*)"urn:epc:raw:", /* 0x21 */ 75 (const uint8_t*)"urn:epc:", /* 0x22 */ 76 (const uint8_t*)"urn:nfc:" /* 0x23 */ 77 }; 78 #define NFA_DM_NDEF_WKT_URI_STR_TBL_SIZE \ 79 (sizeof(nfa_dm_ndef_wkt_uri_str_tbl) / sizeof(uint8_t*)) 80 81 /******************************************************************************* 82 ** 83 ** Function nfa_dm_ndef_dereg_hdlr_by_handle 84 ** 85 ** Description Deregister NDEF record type handler 86 ** 87 ** Returns TRUE (message buffer to be freed by caller) 88 ** 89 *******************************************************************************/ 90 void nfa_dm_ndef_dereg_hdlr_by_handle(tNFA_HANDLE ndef_type_handle) { 91 tNFA_DM_CB* p_cb = &nfa_dm_cb; 92 uint16_t hdlr_idx; 93 hdlr_idx = (uint16_t)(ndef_type_handle & NFA_HANDLE_MASK); 94 95 if (p_cb->p_ndef_handler[hdlr_idx]) { 96 GKI_freebuf(p_cb->p_ndef_handler[hdlr_idx]); 97 p_cb->p_ndef_handler[hdlr_idx] = NULL; 98 } 99 } 100 101 /******************************************************************************* 102 ** 103 ** Function nfa_dm_ndef_dereg_all 104 ** 105 ** Description Deregister all NDEF record type handlers (called during 106 ** shutdown(. 107 ** 108 ** Returns Nothing 109 ** 110 *******************************************************************************/ 111 void nfa_dm_ndef_dereg_all(void) { 112 tNFA_DM_CB* p_cb = &nfa_dm_cb; 113 uint32_t i; 114 115 for (i = 0; i < NFA_NDEF_MAX_HANDLERS; i++) { 116 /* If this is a free slot, then remember it */ 117 if (p_cb->p_ndef_handler[i] != NULL) { 118 GKI_freebuf(p_cb->p_ndef_handler[i]); 119 p_cb->p_ndef_handler[i] = NULL; 120 } 121 } 122 } 123 124 /******************************************************************************* 125 ** 126 ** Function nfa_dm_ndef_reg_hdlr 127 ** 128 ** Description Register NDEF record type handler 129 ** 130 ** Returns TRUE if message buffer is to be freed by caller 131 ** 132 *******************************************************************************/ 133 bool nfa_dm_ndef_reg_hdlr(tNFA_DM_MSG* p_data) { 134 tNFA_DM_CB* p_cb = &nfa_dm_cb; 135 uint32_t hdlr_idx, i; 136 tNFA_DM_API_REG_NDEF_HDLR* p_reg_info = (tNFA_DM_API_REG_NDEF_HDLR*)p_data; 137 tNFA_NDEF_REGISTER ndef_register; 138 139 /* If registering default handler, check to see if one is already registered 140 */ 141 if (p_reg_info->tnf == NFA_TNF_DEFAULT) { 142 /* check if default handler is already registered */ 143 if (p_cb->p_ndef_handler[NFA_NDEF_DEFAULT_HANDLER_IDX]) { 144 LOG(WARNING) << StringPrintf("Default NDEF handler being changed."); 145 146 /* Free old registration info */ 147 nfa_dm_ndef_dereg_hdlr_by_handle( 148 (tNFA_HANDLE)NFA_NDEF_DEFAULT_HANDLER_IDX); 149 } 150 DLOG_IF(INFO, nfc_debug_enabled) 151 << StringPrintf("Default NDEF handler successfully registered."); 152 hdlr_idx = NFA_NDEF_DEFAULT_HANDLER_IDX; 153 } 154 /* Get available entry in ndef_handler table, and check if requested type is 155 already registered */ 156 else { 157 hdlr_idx = NFA_HANDLE_INVALID; 158 159 /* Check if this type is already registered */ 160 for (i = (NFA_NDEF_DEFAULT_HANDLER_IDX + 1); i < NFA_NDEF_MAX_HANDLERS; 161 i++) { 162 /* If this is a free slot, then remember it */ 163 if (p_cb->p_ndef_handler[i] == NULL) { 164 hdlr_idx = i; 165 break; 166 } 167 } 168 } 169 170 if (hdlr_idx != NFA_HANDLE_INVALID) { 171 /* Update the table */ 172 p_cb->p_ndef_handler[hdlr_idx] = p_reg_info; 173 174 p_reg_info->ndef_type_handle = 175 (tNFA_HANDLE)(NFA_HANDLE_GROUP_NDEF_HANDLER | hdlr_idx); 176 177 ndef_register.ndef_type_handle = p_reg_info->ndef_type_handle; 178 ndef_register.status = NFA_STATUS_OK; 179 180 DLOG_IF(INFO, nfc_debug_enabled) 181 << StringPrintf("NDEF handler successfully registered. Handle=0x%08x", 182 p_reg_info->ndef_type_handle); 183 tNFA_NDEF_EVT_DATA nfa_ndef_evt_data; 184 nfa_ndef_evt_data.ndef_reg = ndef_register; 185 (*(p_reg_info->p_ndef_cback))(NFA_NDEF_REGISTER_EVT, &nfa_ndef_evt_data); 186 187 /* indicate that we will free message buffer when type_handler is 188 * deregistered */ 189 return false; 190 } else { 191 /* Error */ 192 LOG(ERROR) << StringPrintf("NDEF handler failed to register."); 193 ndef_register.ndef_type_handle = NFA_HANDLE_INVALID; 194 ndef_register.status = NFA_STATUS_FAILED; 195 tNFA_NDEF_EVT_DATA nfa_ndef_evt_data; 196 nfa_ndef_evt_data.ndef_reg = ndef_register; 197 (*(p_reg_info->p_ndef_cback))(NFA_NDEF_REGISTER_EVT, &nfa_ndef_evt_data); 198 199 return true; 200 } 201 } 202 203 /******************************************************************************* 204 ** 205 ** Function nfa_dm_ndef_dereg_hdlr 206 ** 207 ** Description Deregister NDEF record type handler 208 ** 209 ** Returns TRUE (message buffer to be freed by caller) 210 ** 211 *******************************************************************************/ 212 bool nfa_dm_ndef_dereg_hdlr(tNFA_DM_MSG* p_data) { 213 tNFA_DM_API_DEREG_NDEF_HDLR* p_dereginfo = 214 (tNFA_DM_API_DEREG_NDEF_HDLR*)p_data; 215 216 /* Make sure this is a NDEF_HDLR handle */ 217 if (((p_dereginfo->ndef_type_handle & NFA_HANDLE_GROUP_MASK) != 218 NFA_HANDLE_GROUP_NDEF_HANDLER) || 219 ((p_dereginfo->ndef_type_handle & NFA_HANDLE_MASK) >= 220 NFA_NDEF_MAX_HANDLERS)) { 221 LOG(ERROR) << StringPrintf("Invalid handle for NDEF type handler: 0x%08x", 222 p_dereginfo->ndef_type_handle); 223 } else { 224 nfa_dm_ndef_dereg_hdlr_by_handle(p_dereginfo->ndef_type_handle); 225 } 226 227 return true; 228 } 229 230 /******************************************************************************* 231 ** 232 ** Function nfa_dm_ndef_find_next_handler 233 ** 234 ** Description Find next ndef handler for a given record type 235 ** 236 ** Returns void 237 ** 238 *******************************************************************************/ 239 tNFA_DM_API_REG_NDEF_HDLR* nfa_dm_ndef_find_next_handler( 240 tNFA_DM_API_REG_NDEF_HDLR* p_init_handler, uint8_t tnf, 241 uint8_t* p_type_name, uint8_t type_name_len, uint8_t* p_payload, 242 uint32_t payload_len) { 243 tNFA_DM_CB* p_cb = &nfa_dm_cb; 244 uint8_t i; 245 246 /* if init_handler is NULL, then start with the first non-default handler */ 247 if (!p_init_handler) 248 i = NFA_NDEF_DEFAULT_HANDLER_IDX + 1; 249 else { 250 /* Point to handler index after p_init_handler */ 251 i = (p_init_handler->ndef_type_handle & NFA_HANDLE_MASK) + 1; 252 } 253 254 /* Look for next handler */ 255 for (; i < NFA_NDEF_MAX_HANDLERS; i++) { 256 /* Check if TNF matches */ 257 if ((p_cb->p_ndef_handler[i]) && (p_cb->p_ndef_handler[i]->tnf == tnf)) { 258 /* TNF matches. */ 259 /* If handler is for a specific URI type, check if type is WKT URI, */ 260 /* and that the URI prefix abrieviation for this handler matches */ 261 if (p_cb->p_ndef_handler[i]->flags & NFA_NDEF_FLAGS_WKT_URI) { 262 /* This is a handler for a specific URI type */ 263 /* Check if this recurd is WKT URI */ 264 if ((p_payload) && (type_name_len == 1) && (*p_type_name == 'U')) { 265 /* Check if URI prefix abrieviation matches */ 266 if ((payload_len > 1) && 267 (p_payload[0] == p_cb->p_ndef_handler[i]->uri_id)) { 268 /* URI prefix abrieviation matches */ 269 /* If handler does not specify an absolute URI, then match found. */ 270 /* If absolute URI, then compare URI for match (skip over uri_id in 271 * ndef payload) */ 272 if ((p_cb->p_ndef_handler[i]->uri_id != NFA_NDEF_URI_ID_ABSOLUTE) || 273 (memcmp(&p_payload[1], p_cb->p_ndef_handler[i]->name, 274 p_cb->p_ndef_handler[i]->name_len) == 0)) { 275 /* Handler found. */ 276 break; 277 } 278 } 279 /* Check if handler is absolute URI but NDEF is using prefix 280 abrieviation */ 281 else if ((p_cb->p_ndef_handler[i]->uri_id == 282 NFA_NDEF_URI_ID_ABSOLUTE) && 283 (p_payload[0] != NFA_NDEF_URI_ID_ABSOLUTE)) { 284 /* Handler is absolute URI but NDEF is using prefix abrieviation. 285 * Compare URI prefix */ 286 if ((p_payload[0] < NFA_DM_NDEF_WKT_URI_STR_TBL_SIZE) && 287 (memcmp(p_cb->p_ndef_handler[i]->name, 288 (char*)nfa_dm_ndef_wkt_uri_str_tbl[p_payload[0]], 289 p_cb->p_ndef_handler[i]->name_len) == 0)) { 290 /* Handler found. */ 291 break; 292 } 293 } 294 /* Check if handler is using prefix abrieviation, but NDEF is using 295 absolute URI */ 296 else if ((p_cb->p_ndef_handler[i]->uri_id != 297 NFA_NDEF_URI_ID_ABSOLUTE) && 298 (p_payload[0] == NFA_NDEF_URI_ID_ABSOLUTE)) { 299 /* Handler is using prefix abrieviation, but NDEF is using absolute 300 * URI. Compare URI prefix */ 301 if ((p_cb->p_ndef_handler[i]->uri_id < 302 NFA_DM_NDEF_WKT_URI_STR_TBL_SIZE) && 303 (memcmp(&p_payload[1], 304 nfa_dm_ndef_wkt_uri_str_tbl[p_cb->p_ndef_handler[i] 305 ->uri_id], 306 strlen((const char*)nfa_dm_ndef_wkt_uri_str_tbl 307 [p_cb->p_ndef_handler[i]->uri_id])) == 0)) { 308 /* Handler found. */ 309 break; 310 } 311 } 312 } 313 } 314 /* Not looking for specific URI. Check if type_name for this handler 315 matches the NDEF record's type_name */ 316 else if (p_cb->p_ndef_handler[i]->name_len == type_name_len) { 317 if ((type_name_len == 0) || (memcmp(p_cb->p_ndef_handler[i]->name, 318 p_type_name, type_name_len) == 0)) { 319 /* Handler found */ 320 break; 321 } 322 } 323 } 324 } 325 326 if (i < NFA_NDEF_MAX_HANDLERS) 327 return (p_cb->p_ndef_handler[i]); 328 else 329 return (NULL); 330 } 331 332 /******************************************************************************* 333 ** 334 ** Function nfa_dm_ndef_clear_notified_flag 335 ** 336 ** Description Clear 'whole_message_notified' flag for all the handlers 337 ** (flag used to indicate that this handler has already 338 ** handled the entire incoming NDEF message) 339 ** 340 ** Returns void 341 ** 342 *******************************************************************************/ 343 void nfa_dm_ndef_clear_notified_flag(void) { 344 tNFA_DM_CB* p_cb = &nfa_dm_cb; 345 uint8_t i; 346 347 for (i = 0; i < NFA_NDEF_MAX_HANDLERS; i++) { 348 if (p_cb->p_ndef_handler[i]) { 349 p_cb->p_ndef_handler[i]->flags &= ~NFA_NDEF_FLAGS_WHOLE_MESSAGE_NOTIFIED; 350 } 351 } 352 } 353 354 /******************************************************************************* 355 ** 356 ** Function nfa_dm_ndef_handle_message 357 ** 358 ** Description Handle incoming ndef message 359 ** 360 ** Returns void 361 ** 362 *******************************************************************************/ 363 void nfa_dm_ndef_handle_message(tNFA_STATUS status, uint8_t* p_msg_buf, 364 uint32_t len) { 365 tNFA_DM_CB* p_cb = &nfa_dm_cb; 366 tNDEF_STATUS ndef_status; 367 uint8_t *p_rec, *p_ndef_start, *p_type, *p_payload, *p_rec_end; 368 uint32_t payload_len; 369 uint8_t tnf, type_len, rec_hdr_flags, id_len; 370 tNFA_DM_API_REG_NDEF_HDLR* p_handler; 371 tNFA_NDEF_DATA ndef_data; 372 uint8_t rec_count = 0; 373 bool record_handled, entire_message_handled; 374 375 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 376 "nfa_dm_ndef_handle_message status=%i, len=%i", status, len); 377 378 if (status != NFA_STATUS_OK) { 379 /* If problem reading NDEF message, then exit (no action required) */ 380 return; 381 } 382 383 /* If in exclusive RF mode is activer, then route NDEF message callback 384 * registered with NFA_StartExclusiveRfControl */ 385 if ((p_cb->flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) && 386 (p_cb->p_excl_ndef_cback)) { 387 /* No ndef-handler handle, since this callback is not from 388 * RegisterNDefHandler */ 389 ndef_data.ndef_type_handle = 0; 390 ndef_data.p_data = p_msg_buf; 391 ndef_data.len = len; 392 tNFA_NDEF_EVT_DATA nfa_ndef_evt_data; 393 nfa_ndef_evt_data.ndef_data = ndef_data; 394 (*p_cb->p_excl_ndef_cback)(NFA_NDEF_DATA_EVT, &nfa_ndef_evt_data); 395 return; 396 } 397 398 /* Handle zero length - notify default handler */ 399 if (len == 0) { 400 p_handler = p_cb->p_ndef_handler[NFA_NDEF_DEFAULT_HANDLER_IDX]; 401 if (p_handler != NULL) { 402 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 403 "Notifying default handler of zero-length NDEF message..."); 404 ndef_data.ndef_type_handle = p_handler->ndef_type_handle; 405 ndef_data.p_data = NULL; /* Start of record */ 406 ndef_data.len = 0; 407 tNFA_NDEF_EVT_DATA nfa_ndef_evt_data; 408 nfa_ndef_evt_data.ndef_data = ndef_data; 409 (*p_handler->p_ndef_cback)(NFA_NDEF_DATA_EVT, &nfa_ndef_evt_data); 410 } 411 return; 412 } 413 414 /* Validate the NDEF message */ 415 ndef_status = NDEF_MsgValidate(p_msg_buf, len, true); 416 if (ndef_status != NDEF_OK) { 417 LOG(ERROR) << StringPrintf( 418 "Received invalid NDEF message. NDEF status=0x%x", ndef_status); 419 return; 420 } 421 422 /* NDEF message received from backgound polling. Pass the NDEF message to the 423 * NDEF handlers */ 424 425 /* New NDEF message. Clear 'notified' flag for all the handlers */ 426 nfa_dm_ndef_clear_notified_flag(); 427 428 /* Indicate that no handler has handled this entire NDEF message (e.g. 429 * connection-handover handler *) */ 430 entire_message_handled = false; 431 432 /* Get first record in message */ 433 p_rec = p_ndef_start = p_msg_buf; 434 435 /* Check each record in the NDEF message */ 436 while (p_rec != NULL) { 437 /* Get record type */ 438 p_type = NDEF_RecGetType(p_rec, &tnf, &type_len); 439 440 /* Indicate record not handled yet */ 441 record_handled = false; 442 443 /* Get pointer to record payload */ 444 p_payload = NDEF_RecGetPayload(p_rec, &payload_len); 445 446 /* Find first handler for this type */ 447 p_handler = nfa_dm_ndef_find_next_handler(NULL, tnf, p_type, type_len, 448 p_payload, payload_len); 449 if (p_handler == NULL) { 450 /* Not a registered NDEF type. Use default handler */ 451 p_handler = p_cb->p_ndef_handler[NFA_NDEF_DEFAULT_HANDLER_IDX]; 452 if (p_handler != NULL) { 453 DLOG_IF(INFO, nfc_debug_enabled) 454 << StringPrintf("No handler found. Using default handler..."); 455 } 456 } 457 458 while (p_handler) { 459 /* If handler is for whole NDEF message, and it has already been notified, 460 * then skip notification */ 461 if (p_handler->flags & NFA_NDEF_FLAGS_WHOLE_MESSAGE_NOTIFIED) { 462 /* Look for next handler */ 463 p_handler = nfa_dm_ndef_find_next_handler( 464 p_handler, tnf, p_type, type_len, p_payload, payload_len); 465 continue; 466 } 467 468 /* Get pointer to record payload */ 469 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 470 "Calling ndef type handler (%x)", p_handler->ndef_type_handle); 471 472 ndef_data.ndef_type_handle = p_handler->ndef_type_handle; 473 ndef_data.p_data = p_rec; /* Start of record */ 474 475 /* Calculate length of NDEF record */ 476 if (p_payload != NULL) 477 ndef_data.len = payload_len + (uint32_t)(p_payload - p_rec); 478 else { 479 /* If no payload, calculate length of ndef record header */ 480 p_rec_end = p_rec; 481 482 /* First byte is the header flags */ 483 rec_hdr_flags = *p_rec_end++; 484 485 /* Next byte is the type field length */ 486 type_len = *p_rec_end++; 487 488 /* Next is the payload length (1 or 4 bytes) */ 489 if (rec_hdr_flags & NDEF_SR_MASK) { 490 p_rec_end++; 491 } else { 492 p_rec_end += 4; 493 } 494 495 /* ID field Length */ 496 if (rec_hdr_flags & NDEF_IL_MASK) 497 id_len = *p_rec_end++; 498 else 499 id_len = 0; 500 p_rec_end += id_len; 501 502 ndef_data.len = (uint32_t)(p_rec_end - p_rec); 503 } 504 505 /* If handler wants entire ndef message, then pass pointer to start of 506 * message and */ 507 /* set 'notified' flag so handler won't get notified on subsequent records 508 * for this */ 509 /* NDEF message. */ 510 if (p_handler->flags & NFA_NDEF_FLAGS_HANDLE_WHOLE_MESSAGE) { 511 ndef_data.p_data = p_ndef_start; /* Start of NDEF message */ 512 ndef_data.len = len; 513 p_handler->flags |= NFA_NDEF_FLAGS_WHOLE_MESSAGE_NOTIFIED; 514 515 /* Indicate that at least one handler has received entire NDEF message 516 */ 517 entire_message_handled = true; 518 } 519 520 /* Notify NDEF type handler */ 521 tNFA_NDEF_EVT_DATA nfa_ndef_evt_data; 522 nfa_ndef_evt_data.ndef_data = ndef_data; 523 (*p_handler->p_ndef_cback)(NFA_NDEF_DATA_EVT, &nfa_ndef_evt_data); 524 525 /* Indicate that at lease one handler has received this record */ 526 record_handled = true; 527 528 /* Look for next handler */ 529 p_handler = nfa_dm_ndef_find_next_handler( 530 p_handler, tnf, p_type, type_len, p_payload, payload_len); 531 } 532 533 /* Check if at least one handler was notified of this record (only happens 534 * if no default handler was register) */ 535 if ((!record_handled) && (!entire_message_handled)) { 536 /* Unregistered NDEF record type; no default handler */ 537 LOG(WARNING) << StringPrintf("Unhandled NDEF record (#%i)", rec_count); 538 } 539 540 rec_count++; 541 p_rec = NDEF_MsgGetNextRec(p_rec); 542 } 543 } 544