1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 18 * Tag-reading, tag-writing operations. 19 */ 20 #include "OverrideLog.h" 21 #include "NfcTag.h" 22 #include "JavaClassConstants.h" 23 #include "config.h" 24 #include <ScopedLocalRef.h> 25 #include <ScopedPrimitiveArray.h> 26 27 extern "C" 28 { 29 #include "rw_int.h" 30 #include "nfc_brcm_defs.h" 31 #include "phNxpExtns.h" 32 } 33 34 35 /******************************************************************************* 36 ** 37 ** Function: NfcTag 38 ** 39 ** Description: Initialize member variables. 40 ** 41 ** Returns: None 42 ** 43 *******************************************************************************/ 44 NfcTag::NfcTag () 45 : mNumTechList (0), 46 mTechnologyTimeoutsTable (MAX_NUM_TECHNOLOGY), 47 mNativeData (NULL), 48 mIsActivated (false), 49 mActivationState (Idle), 50 mProtocol(NFC_PROTOCOL_UNKNOWN), 51 mtT1tMaxMessageSize (0), 52 mReadCompletedStatus (NFA_STATUS_OK), 53 mLastKovioUidLen (0), 54 mNdefDetectionTimedOut (false), 55 mIsDynamicTagId (false), 56 mPresenceCheckAlgorithm (NFA_RW_PRES_CHK_DEFAULT), 57 mIsFelicaLite(false) 58 { 59 memset (mTechList, 0, sizeof(mTechList)); 60 memset (mTechHandles, 0, sizeof(mTechHandles)); 61 memset (mTechLibNfcTypes, 0, sizeof(mTechLibNfcTypes)); 62 memset (mTechParams, 0, sizeof(mTechParams)); 63 memset(mLastKovioUid, 0, NFC_KOVIO_MAX_LEN); 64 } 65 66 67 /******************************************************************************* 68 ** 69 ** Function: getInstance 70 ** 71 ** Description: Get a reference to the singleton NfcTag object. 72 ** 73 ** Returns: Reference to NfcTag object. 74 ** 75 *******************************************************************************/ 76 NfcTag& NfcTag::getInstance () 77 { 78 static NfcTag tag; 79 return tag; 80 } 81 82 83 /******************************************************************************* 84 ** 85 ** Function: initialize 86 ** 87 ** Description: Reset member variables. 88 ** native: Native data. 89 ** 90 ** Returns: None 91 ** 92 *******************************************************************************/ 93 void NfcTag::initialize (nfc_jni_native_data* native) 94 { 95 long num = 0; 96 97 mNativeData = native; 98 mIsActivated = false; 99 mActivationState = Idle; 100 mProtocol = NFC_PROTOCOL_UNKNOWN; 101 mNumTechList = 0; 102 mtT1tMaxMessageSize = 0; 103 mReadCompletedStatus = NFA_STATUS_OK; 104 resetTechnologies (); 105 if (GetNumValue(NAME_PRESENCE_CHECK_ALGORITHM, &num, sizeof(num))) 106 mPresenceCheckAlgorithm = num; 107 } 108 109 110 /******************************************************************************* 111 ** 112 ** Function: abort 113 ** 114 ** Description: Unblock all operations. 115 ** 116 ** Returns: None 117 ** 118 *******************************************************************************/ 119 void NfcTag::abort () 120 { 121 SyncEventGuard g (mReadCompleteEvent); 122 mReadCompleteEvent.notifyOne (); 123 } 124 125 126 /******************************************************************************* 127 ** 128 ** Function: getActivationState 129 ** 130 ** Description: What is the current state: Idle, Sleep, or Activated. 131 ** 132 ** Returns: Idle, Sleep, or Activated. 133 ** 134 *******************************************************************************/ 135 NfcTag::ActivationState NfcTag::getActivationState () 136 { 137 return mActivationState; 138 } 139 140 141 /******************************************************************************* 142 ** 143 ** Function: setDeactivationState 144 ** 145 ** Description: Set the current state: Idle or Sleep. 146 ** deactivated: state of deactivation. 147 ** 148 ** Returns: None. 149 ** 150 *******************************************************************************/ 151 void NfcTag::setDeactivationState (tNFA_DEACTIVATED& deactivated) 152 { 153 static const char fn [] = "NfcTag::setDeactivationState"; 154 mActivationState = Idle; 155 mNdefDetectionTimedOut = false; 156 if (deactivated.type == NFA_DEACTIVATE_TYPE_SLEEP) 157 mActivationState = Sleep; 158 ALOGD ("%s: state=%u", fn, mActivationState); 159 } 160 161 162 /******************************************************************************* 163 ** 164 ** Function: setActivationState 165 ** 166 ** Description: Set the current state to Active. 167 ** 168 ** Returns: None. 169 ** 170 *******************************************************************************/ 171 void NfcTag::setActivationState () 172 { 173 static const char fn [] = "NfcTag::setActivationState"; 174 mNdefDetectionTimedOut = false; 175 mActivationState = Active; 176 ALOGD ("%s: state=%u", fn, mActivationState); 177 } 178 179 /******************************************************************************* 180 ** 181 ** Function: isActivated 182 ** 183 ** Description: Is tag activated? 184 ** 185 ** Returns: True if tag is activated. 186 ** 187 *******************************************************************************/ 188 bool NfcTag::isActivated () 189 { 190 return mIsActivated; 191 } 192 193 194 /******************************************************************************* 195 ** 196 ** Function: getProtocol 197 ** 198 ** Description: Get the protocol of the current tag. 199 ** 200 ** Returns: Protocol number. 201 ** 202 *******************************************************************************/ 203 tNFC_PROTOCOL NfcTag::getProtocol() 204 { 205 return mProtocol; 206 } 207 208 /******************************************************************************* 209 ** 210 ** Function TimeDiff 211 ** 212 ** Description Computes time difference in milliseconds. 213 ** 214 ** Returns Time difference in milliseconds 215 ** 216 *******************************************************************************/ 217 UINT32 TimeDiff(timespec start, timespec end) 218 { 219 timespec temp; 220 if ((end.tv_nsec-start.tv_nsec)<0) 221 { 222 temp.tv_sec = end.tv_sec-start.tv_sec-1; 223 temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; 224 } 225 else 226 { 227 temp.tv_sec = end.tv_sec-start.tv_sec; 228 temp.tv_nsec = end.tv_nsec-start.tv_nsec; 229 } 230 231 return (temp.tv_sec * 1000) + (temp.tv_nsec / 1000000); 232 } 233 234 /******************************************************************************* 235 ** 236 ** Function: IsSameKovio 237 ** 238 ** Description: Checks if tag activate is the same (UID) Kovio tag previously 239 ** activated. This is needed due to a problem with some Kovio 240 ** tags re-activating multiple times. 241 ** activationData: data from activation. 242 ** 243 ** Returns: true if the activation is from the same tag previously 244 ** activated, false otherwise 245 ** 246 *******************************************************************************/ 247 bool NfcTag::IsSameKovio(tNFA_ACTIVATED& activationData) 248 { 249 static const char fn [] = "NfcTag::IsSameKovio"; 250 ALOGD ("%s: enter", fn); 251 tNFC_ACTIVATE_DEVT& rfDetail = activationData.activate_ntf; 252 253 if (rfDetail.protocol != NFC_PROTOCOL_KOVIO) 254 return false; 255 256 memcpy (&(mTechParams[0]), &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param)); 257 if (mTechParams [0].mode != NFC_DISCOVERY_TYPE_POLL_KOVIO) 258 return false; 259 260 struct timespec now; 261 clock_gettime(CLOCK_REALTIME, &now); 262 263 bool rVal = false; 264 if (mTechParams[0].param.pk.uid_len == mLastKovioUidLen) 265 { 266 if (memcmp(mLastKovioUid, &mTechParams [0].param.pk.uid, mTechParams[0].param.pk.uid_len) == 0) 267 { 268 //same tag 269 if (TimeDiff(mLastKovioTime, now) < 500) 270 { 271 // same tag within 500 ms, ignore activation 272 rVal = true; 273 } 274 } 275 } 276 277 // save Kovio tag info 278 if (!rVal) 279 { 280 if ((mLastKovioUidLen = mTechParams[0].param.pk.uid_len) > NFC_KOVIO_MAX_LEN) 281 mLastKovioUidLen = NFC_KOVIO_MAX_LEN; 282 memcpy(mLastKovioUid, mTechParams[0].param.pk.uid, mLastKovioUidLen); 283 } 284 mLastKovioTime = now; 285 ALOGD ("%s: exit, is same Kovio=%d", fn, rVal); 286 return rVal; 287 } 288 289 /******************************************************************************* 290 ** 291 ** Function: discoverTechnologies 292 ** 293 ** Description: Discover the technologies that NFC service needs by interpreting 294 ** the data structures from the stack. 295 ** activationData: data from activation. 296 ** 297 ** Returns: None 298 ** 299 *******************************************************************************/ 300 void NfcTag::discoverTechnologies (tNFA_ACTIVATED& activationData) 301 { 302 static const char fn [] = "NfcTag::discoverTechnologies (activation)"; 303 ALOGD ("%s: enter", fn); 304 tNFC_ACTIVATE_DEVT& rfDetail = activationData.activate_ntf; 305 306 mNumTechList = 0; 307 mTechHandles [mNumTechList] = rfDetail.rf_disc_id; 308 mTechLibNfcTypes [mNumTechList] = rfDetail.protocol; 309 310 //save the stack's data structure for interpretation later 311 memcpy (&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param)); 312 313 if (NFC_PROTOCOL_T1T == rfDetail.protocol) 314 { 315 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; //is TagTechnology.NFC_A by Java API 316 } 317 else if (NFC_PROTOCOL_T2T == rfDetail.protocol) 318 { 319 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; //is TagTechnology.NFC_A by Java API 320 // could be MifFare UL or Classic or Kovio 321 { 322 // need to look at first byte of uid to find Manufacture Byte 323 tNFC_RF_TECH_PARAMS tech_params; 324 memcpy (&tech_params, &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param)); 325 326 if ((tech_params.param.pa.nfcid1[0] == 0x04 && rfDetail.rf_tech_param.param.pa.sel_rsp == 0) || 327 rfDetail.rf_tech_param.param.pa.sel_rsp == 0x18 || 328 rfDetail.rf_tech_param.param.pa.sel_rsp == 0x08) 329 { 330 if (rfDetail.rf_tech_param.param.pa.sel_rsp == 0) 331 { 332 mNumTechList++; 333 mTechHandles [mNumTechList] = rfDetail.rf_disc_id; 334 mTechLibNfcTypes [mNumTechList] = rfDetail.protocol; 335 //save the stack's data structure for interpretation later 336 memcpy (&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param)); 337 mTechList [mNumTechList] = TARGET_TYPE_MIFARE_UL; //is TagTechnology.MIFARE_ULTRALIGHT by Java API 338 } 339 } 340 } 341 } 342 else if (NFC_PROTOCOL_T3T == rfDetail.protocol) 343 { 344 UINT8 xx = 0; 345 346 mTechList [mNumTechList] = TARGET_TYPE_FELICA; 347 348 //see if it is Felica Lite. 349 while (xx < activationData.params.t3t.num_system_codes) 350 { 351 if (activationData.params.t3t.p_system_codes[xx++] == T3T_SYSTEM_CODE_FELICA_LITE) 352 { 353 mIsFelicaLite = true; 354 break; 355 } 356 } 357 } 358 else if (NFC_PROTOCOL_ISO_DEP == rfDetail.protocol) 359 { 360 //type-4 tag uses technology ISO-DEP and technology A or B 361 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_4; //is TagTechnology.ISO_DEP by Java API 362 if ( (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) || 363 (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) || 364 (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A) || 365 (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE) ) 366 { 367 mNumTechList++; 368 mTechHandles [mNumTechList] = rfDetail.rf_disc_id; 369 mTechLibNfcTypes [mNumTechList] = rfDetail.protocol; 370 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; //is TagTechnology.NFC_A by Java API 371 //save the stack's data structure for interpretation later 372 memcpy (&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param)); 373 } 374 else if ( (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B) || 375 (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B_PRIME) || 376 (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_B) || 377 (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) ) 378 { 379 mNumTechList++; 380 mTechHandles [mNumTechList] = rfDetail.rf_disc_id; 381 mTechLibNfcTypes [mNumTechList] = rfDetail.protocol; 382 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3B; //is TagTechnology.NFC_B by Java API 383 //save the stack's data structure for interpretation later 384 memcpy (&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param)); 385 } 386 } 387 else if (NFC_PROTOCOL_15693 == rfDetail.protocol) 388 { 389 //is TagTechnology.NFC_V by Java API 390 mTechList [mNumTechList] = TARGET_TYPE_ISO15693; 391 } 392 else if (NFC_PROTOCOL_KOVIO == rfDetail.protocol) 393 { 394 ALOGD ("%s: Kovio", fn); 395 mTechList [mNumTechList] = TARGET_TYPE_KOVIO_BARCODE; 396 } 397 else if (NFC_PROTOCOL_MIFARE == rfDetail.protocol) 398 { 399 ALOGD ("%s: Mifare Classic", fn); 400 EXTNS_MfcInit (activationData); 401 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; //is TagTechnology.NFC_A by Java API 402 mNumTechList++; 403 mTechHandles [mNumTechList] = rfDetail.rf_disc_id; 404 mTechLibNfcTypes [mNumTechList] = rfDetail.protocol; 405 //save the stack's data structure for interpretation later 406 memcpy (&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param)); 407 mTechList [mNumTechList] = TARGET_TYPE_MIFARE_CLASSIC; //is TagTechnology.MIFARE_CLASSIC by Java API 408 } 409 else 410 { 411 ALOGE ("%s: unknown protocol ????", fn); 412 mTechList [mNumTechList] = TARGET_TYPE_UNKNOWN; 413 } 414 415 mNumTechList++; 416 for (int i=0; i < mNumTechList; i++) 417 { 418 ALOGD ("%s: index=%d; tech=%d; handle=%d; nfc type=%d", fn, 419 i, mTechList[i], mTechHandles[i], mTechLibNfcTypes[i]); 420 } 421 ALOGD ("%s: exit", fn); 422 } 423 424 425 /******************************************************************************* 426 ** 427 ** Function: discoverTechnologies 428 ** 429 ** Description: Discover the technologies that NFC service needs by interpreting 430 ** the data structures from the stack. 431 ** discoveryData: data from discovery events(s). 432 ** 433 ** Returns: None 434 ** 435 *******************************************************************************/ 436 void NfcTag::discoverTechnologies (tNFA_DISC_RESULT& discoveryData) 437 { 438 static const char fn [] = "NfcTag::discoverTechnologies (discovery)"; 439 tNFC_RESULT_DEVT& discovery_ntf = discoveryData.discovery_ntf; 440 441 ALOGD ("%s: enter: rf disc. id=%u; protocol=%u, mNumTechList=%u", fn, discovery_ntf.rf_disc_id, discovery_ntf.protocol, mNumTechList); 442 if (mNumTechList >= MAX_NUM_TECHNOLOGY) 443 { 444 ALOGE ("%s: exceed max=%d", fn, MAX_NUM_TECHNOLOGY); 445 goto TheEnd; 446 } 447 mTechHandles [mNumTechList] = discovery_ntf.rf_disc_id; 448 mTechLibNfcTypes [mNumTechList] = discovery_ntf.protocol; 449 450 //save the stack's data structure for interpretation later 451 memcpy (&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param), sizeof(discovery_ntf.rf_tech_param)); 452 453 if (NFC_PROTOCOL_T1T == discovery_ntf.protocol) 454 { 455 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; //is TagTechnology.NFC_A by Java API 456 } 457 else if (NFC_PROTOCOL_T2T == discovery_ntf.protocol) 458 { 459 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; //is TagTechnology.NFC_A by Java API 460 //type-2 tags are identical to Mifare Ultralight, so Ultralight is also discovered 461 if ((discovery_ntf.rf_tech_param.param.pa.sel_rsp == 0) && 462 (mNumTechList < (MAX_NUM_TECHNOLOGY-1))) 463 { 464 // Mifare Ultralight 465 mNumTechList++; 466 mTechHandles [mNumTechList] = discovery_ntf.rf_disc_id; 467 mTechLibNfcTypes [mNumTechList] = discovery_ntf.protocol; 468 mTechList [mNumTechList] = TARGET_TYPE_MIFARE_UL; //is TagTechnology.MIFARE_ULTRALIGHT by Java API 469 } 470 471 //save the stack's data structure for interpretation later 472 memcpy (&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param), sizeof(discovery_ntf.rf_tech_param)); 473 } 474 else if (NFC_PROTOCOL_T3T == discovery_ntf.protocol) 475 { 476 mTechList [mNumTechList] = TARGET_TYPE_FELICA; 477 } 478 else if (NFC_PROTOCOL_ISO_DEP == discovery_ntf.protocol) 479 { 480 //type-4 tag uses technology ISO-DEP and technology A or B 481 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_4; //is TagTechnology.ISO_DEP by Java API 482 if ( (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) || 483 (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) || 484 (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A) || 485 (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE) ) 486 { 487 if (mNumTechList < (MAX_NUM_TECHNOLOGY-1)) 488 { 489 mNumTechList++; 490 mTechHandles [mNumTechList] = discovery_ntf.rf_disc_id; 491 mTechLibNfcTypes [mNumTechList] = discovery_ntf.protocol; 492 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; //is TagTechnology.NFC_A by Java API 493 //save the stack's data structure for interpretation later 494 memcpy (&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param), sizeof(discovery_ntf.rf_tech_param)); 495 } 496 } 497 else if ( (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B) || 498 (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B_PRIME) || 499 (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_B) || 500 (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) ) 501 { 502 if (mNumTechList < (MAX_NUM_TECHNOLOGY-1)) 503 { 504 mNumTechList++; 505 mTechHandles [mNumTechList] = discovery_ntf.rf_disc_id; 506 mTechLibNfcTypes [mNumTechList] = discovery_ntf.protocol; 507 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3B; //is TagTechnology.NFC_B by Java API 508 //save the stack's data structure for interpretation later 509 memcpy (&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param), sizeof(discovery_ntf.rf_tech_param)); 510 } 511 } 512 } 513 else if (NFC_PROTOCOL_15693 == discovery_ntf.protocol) 514 { 515 //is TagTechnology.NFC_V by Java API 516 mTechList [mNumTechList] = TARGET_TYPE_ISO15693; 517 } 518 else if (NFC_PROTOCOL_MIFARE == discovery_ntf.protocol) 519 { 520 mTechList [mNumTechList] = TARGET_TYPE_MIFARE_CLASSIC; 521 if (mNumTechList < (MAX_NUM_TECHNOLOGY-1)) 522 { 523 mNumTechList++; 524 mTechHandles [mNumTechList] = discovery_ntf.rf_disc_id; 525 mTechLibNfcTypes [mNumTechList] = discovery_ntf.protocol; 526 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; 527 //save the stack's data structure for interpretation later 528 memcpy (&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param), sizeof(discovery_ntf.rf_tech_param)); 529 } 530 } 531 else 532 { 533 ALOGE ("%s: unknown protocol ????", fn); 534 mTechList [mNumTechList] = TARGET_TYPE_UNKNOWN; 535 } 536 537 mNumTechList++; 538 if (discovery_ntf.more != NCI_DISCOVER_NTF_MORE) 539 { 540 for (int i=0; i < mNumTechList; i++) 541 { 542 ALOGD ("%s: index=%d; tech=%d; handle=%d; nfc type=%d", fn, 543 i, mTechList[i], mTechHandles[i], mTechLibNfcTypes[i]); 544 } 545 } 546 547 TheEnd: 548 ALOGD ("%s: exit", fn); 549 } 550 551 552 /******************************************************************************* 553 ** 554 ** Function: createNativeNfcTag 555 ** 556 ** Description: Create a brand new Java NativeNfcTag object; 557 ** fill the objects's member variables with data; 558 ** notify NFC service; 559 ** activationData: data from activation. 560 ** 561 ** Returns: None 562 ** 563 *******************************************************************************/ 564 void NfcTag::createNativeNfcTag (tNFA_ACTIVATED& activationData) 565 { 566 static const char fn [] = "NfcTag::createNativeNfcTag"; 567 ALOGD ("%s: enter", fn); 568 569 JNIEnv* e = NULL; 570 ScopedAttach attach(mNativeData->vm, &e); 571 if (e == NULL) 572 { 573 ALOGE("%s: jni env is null", fn); 574 return; 575 } 576 577 ScopedLocalRef<jclass> tag_cls(e, e->GetObjectClass(mNativeData->cached_NfcTag)); 578 if (e->ExceptionCheck()) 579 { 580 e->ExceptionClear(); 581 ALOGE("%s: failed to get class", fn); 582 return; 583 } 584 585 //create a new Java NativeNfcTag object 586 jmethodID ctor = e->GetMethodID(tag_cls.get(), "<init>", "()V"); 587 ScopedLocalRef<jobject> tag(e, e->NewObject(tag_cls.get(), ctor)); 588 589 //fill NativeNfcTag's mProtocols, mTechList, mTechHandles, mTechLibNfcTypes 590 fillNativeNfcTagMembers1(e, tag_cls.get(), tag.get()); 591 592 //fill NativeNfcTag's members: mHandle, mConnectedTechnology 593 fillNativeNfcTagMembers2(e, tag_cls.get(), tag.get(), activationData); 594 595 //fill NativeNfcTag's members: mTechPollBytes 596 fillNativeNfcTagMembers3(e, tag_cls.get(), tag.get(), activationData); 597 598 //fill NativeNfcTag's members: mTechActBytes 599 fillNativeNfcTagMembers4(e, tag_cls.get(), tag.get(), activationData); 600 601 //fill NativeNfcTag's members: mUid 602 fillNativeNfcTagMembers5(e, tag_cls.get(), tag.get(), activationData); 603 604 if (mNativeData->tag != NULL) 605 { 606 e->DeleteGlobalRef(mNativeData->tag); 607 } 608 mNativeData->tag = e->NewGlobalRef(tag.get()); 609 610 //notify NFC service about this new tag 611 ALOGD ("%s: try notify nfc service", fn); 612 e->CallVoidMethod(mNativeData->manager, android::gCachedNfcManagerNotifyNdefMessageListeners, tag.get()); 613 if (e->ExceptionCheck()) 614 { 615 e->ExceptionClear(); 616 ALOGE ("%s: fail notify nfc service", fn); 617 } 618 619 ALOGD ("%s: exit", fn); 620 } 621 622 623 /******************************************************************************* 624 ** 625 ** Function: fillNativeNfcTagMembers1 626 ** 627 ** Description: Fill NativeNfcTag's members: mProtocols, mTechList, mTechHandles, mTechLibNfcTypes. 628 ** e: JVM environment. 629 ** tag_cls: Java NativeNfcTag class. 630 ** tag: Java NativeNfcTag object. 631 ** 632 ** Returns: None 633 ** 634 *******************************************************************************/ 635 void NfcTag::fillNativeNfcTagMembers1 (JNIEnv* e, jclass tag_cls, jobject tag) 636 { 637 static const char fn [] = "NfcTag::fillNativeNfcTagMembers1"; 638 ALOGD ("%s", fn); 639 640 //create objects that represent NativeNfcTag's member variables 641 ScopedLocalRef<jintArray> techList(e, e->NewIntArray(mNumTechList)); 642 ScopedLocalRef<jintArray> handleList(e, e->NewIntArray(mNumTechList)); 643 ScopedLocalRef<jintArray> typeList(e, e->NewIntArray(mNumTechList)); 644 645 { 646 ScopedIntArrayRW technologies(e, techList.get()); 647 ScopedIntArrayRW handles(e, handleList.get()); 648 ScopedIntArrayRW types(e, typeList.get()); 649 for (int i = 0; i < mNumTechList; i++) { 650 mNativeData->tProtocols [i] = mTechLibNfcTypes [i]; 651 mNativeData->handles [i] = mTechHandles [i]; 652 technologies [i] = mTechList [i]; 653 handles [i] = mTechHandles [i]; 654 types [i] = mTechLibNfcTypes [i]; 655 } 656 } 657 658 jfieldID f = NULL; 659 660 f = e->GetFieldID(tag_cls, "mTechList", "[I"); 661 e->SetObjectField(tag, f, techList.get()); 662 663 f = e->GetFieldID(tag_cls, "mTechHandles", "[I"); 664 e->SetObjectField(tag, f, handleList.get()); 665 666 f = e->GetFieldID(tag_cls, "mTechLibNfcTypes", "[I"); 667 e->SetObjectField(tag, f, typeList.get()); 668 } 669 670 671 /******************************************************************************* 672 ** 673 ** Function: fillNativeNfcTagMembers2 674 ** 675 ** Description: Fill NativeNfcTag's members: mConnectedTechIndex or mConnectedTechnology. 676 ** The original Google's implementation is in set_target_pollBytes( 677 ** in com_android_nfc_NativeNfcTag.cpp; 678 ** e: JVM environment. 679 ** tag_cls: Java NativeNfcTag class. 680 ** tag: Java NativeNfcTag object. 681 ** activationData: data from activation. 682 ** 683 ** Returns: None 684 ** 685 *******************************************************************************/ 686 void NfcTag::fillNativeNfcTagMembers2 (JNIEnv* e, jclass tag_cls, jobject tag, tNFA_ACTIVATED& /*activationData*/) 687 { 688 static const char fn [] = "NfcTag::fillNativeNfcTagMembers2"; 689 ALOGD ("%s", fn); 690 jfieldID f = e->GetFieldID(tag_cls, "mConnectedTechIndex", "I"); 691 e->SetIntField(tag, f, (jint) 0); 692 } 693 694 695 /******************************************************************************* 696 ** 697 ** Function: fillNativeNfcTagMembers3 698 ** 699 ** Description: Fill NativeNfcTag's members: mTechPollBytes. 700 ** The original Google's implementation is in set_target_pollBytes( 701 ** in com_android_nfc_NativeNfcTag.cpp; 702 ** e: JVM environment. 703 ** tag_cls: Java NativeNfcTag class. 704 ** tag: Java NativeNfcTag object. 705 ** activationData: data from activation. 706 ** 707 ** Returns: None 708 ** 709 *******************************************************************************/ 710 void NfcTag::fillNativeNfcTagMembers3 (JNIEnv* e, jclass tag_cls, jobject tag, tNFA_ACTIVATED& activationData) 711 { 712 static const char fn [] = "NfcTag::fillNativeNfcTagMembers3"; 713 ScopedLocalRef<jbyteArray> pollBytes(e, e->NewByteArray(0)); 714 ScopedLocalRef<jclass> byteArrayClass(e, e->GetObjectClass(pollBytes.get())); 715 ScopedLocalRef<jobjectArray> techPollBytes(e, e->NewObjectArray(mNumTechList, byteArrayClass.get(), 0)); 716 int len = 0; 717 718 for (int i = 0; i < mNumTechList; i++) 719 { 720 ALOGD ("%s: index=%d; rf tech params mode=%u", fn, i, mTechParams [i].mode); 721 if (NFC_DISCOVERY_TYPE_POLL_A == mTechParams [i].mode 722 || NFC_DISCOVERY_TYPE_POLL_A_ACTIVE == mTechParams [i].mode 723 || NFC_DISCOVERY_TYPE_LISTEN_A == mTechParams [i].mode 724 || NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE == mTechParams [i].mode) 725 { 726 ALOGD ("%s: tech A", fn); 727 pollBytes.reset(e->NewByteArray(2)); 728 e->SetByteArrayRegion(pollBytes.get(), 0, 2, (jbyte*) mTechParams [i].param.pa.sens_res); 729 } 730 else if (NFC_DISCOVERY_TYPE_POLL_B == mTechParams [i].mode 731 || NFC_DISCOVERY_TYPE_POLL_B_PRIME == mTechParams [i].mode 732 || NFC_DISCOVERY_TYPE_LISTEN_B == mTechParams [i].mode 733 || NFC_DISCOVERY_TYPE_LISTEN_B_PRIME == mTechParams [i].mode) 734 { 735 if (mTechList [i] == TARGET_TYPE_ISO14443_3B) //is TagTechnology.NFC_B by Java API 736 { 737 /***************** 738 see NFC Forum Digital Protocol specification; section 5.6.2; 739 in SENSB_RES response, byte 6 through 9 is Application Data, byte 10-12 or 13 is Protocol Info; 740 used by public API: NfcB.getApplicationData(), NfcB.getProtocolInfo(); 741 *****************/ 742 ALOGD ("%s: tech B; TARGET_TYPE_ISO14443_3B", fn); 743 len = mTechParams [i].param.pb.sensb_res_len; 744 len = len - 4; //subtract 4 bytes for NFCID0 at byte 2 through 5 745 pollBytes.reset(e->NewByteArray(len)); 746 e->SetByteArrayRegion(pollBytes.get(), 0, len, (jbyte*) (mTechParams [i].param.pb.sensb_res+4)); 747 } 748 else 749 { 750 pollBytes.reset(e->NewByteArray(0)); 751 } 752 } 753 else if (NFC_DISCOVERY_TYPE_POLL_F == mTechParams [i].mode 754 || NFC_DISCOVERY_TYPE_POLL_F_ACTIVE == mTechParams [i].mode 755 || NFC_DISCOVERY_TYPE_LISTEN_F == mTechParams [i].mode 756 || NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE == mTechParams [i].mode) 757 { 758 /**************** 759 see NFC Forum Type 3 Tag Operation Specification; sections 2.3.2, 2.3.1.2; 760 see NFC Forum Digital Protocol Specification; sections 6.6.2; 761 PMm: manufacture parameter; 8 bytes; 762 System Code: 2 bytes; 763 ****************/ 764 ALOGD ("%s: tech F", fn); 765 UINT8 result [10]; //return result to NFC service 766 memset (result, 0, sizeof(result)); 767 len = 10; 768 769 /**** 770 for (int ii = 0; ii < mTechParams [i].param.pf.sensf_res_len; ii++) 771 { 772 ALOGD ("%s: tech F, sendf_res[%d]=%d (0x%x)", 773 fn, ii, mTechParams [i].param.pf.sensf_res[ii],mTechParams [i].param.pf.sensf_res[ii]); 774 } 775 ***/ 776 memcpy (result, mTechParams [i].param.pf.sensf_res + 8, 8); //copy PMm 777 if (activationData.params.t3t.num_system_codes > 0) //copy the first System Code 778 { 779 UINT16 systemCode = *(activationData.params.t3t.p_system_codes); 780 result [8] = (UINT8) (systemCode >> 8); 781 result [9] = (UINT8) systemCode; 782 ALOGD ("%s: tech F; sys code=0x%X 0x%X", fn, result [8], result [9]); 783 } 784 pollBytes.reset(e->NewByteArray(len)); 785 e->SetByteArrayRegion(pollBytes.get(), 0, len, (jbyte*) result); 786 } 787 else if (NFC_DISCOVERY_TYPE_POLL_ISO15693 == mTechParams [i].mode 788 || NFC_DISCOVERY_TYPE_LISTEN_ISO15693 == mTechParams [i].mode) 789 { 790 ALOGD ("%s: tech iso 15693", fn); 791 //iso 15693 response flags: 1 octet 792 //iso 15693 Data Structure Format Identifier (DSF ID): 1 octet 793 //used by public API: NfcV.getDsfId(), NfcV.getResponseFlags(); 794 uint8_t data [2]= {activationData.params.i93.afi, activationData.params.i93.dsfid}; 795 pollBytes.reset(e->NewByteArray(2)); 796 e->SetByteArrayRegion(pollBytes.get(), 0, 2, (jbyte *) data); 797 } 798 else 799 { 800 ALOGE ("%s: tech unknown ????", fn); 801 pollBytes.reset(e->NewByteArray(0)); 802 } //switch: every type of technology 803 e->SetObjectArrayElement(techPollBytes.get(), i, pollBytes.get()); 804 } //for: every technology in the array 805 jfieldID f = e->GetFieldID(tag_cls, "mTechPollBytes", "[[B"); 806 e->SetObjectField(tag, f, techPollBytes.get()); 807 } 808 809 810 /******************************************************************************* 811 ** 812 ** Function: fillNativeNfcTagMembers4 813 ** 814 ** Description: Fill NativeNfcTag's members: mTechActBytes. 815 ** The original Google's implementation is in set_target_activationBytes() 816 ** in com_android_nfc_NativeNfcTag.cpp; 817 ** e: JVM environment. 818 ** tag_cls: Java NativeNfcTag class. 819 ** tag: Java NativeNfcTag object. 820 ** activationData: data from activation. 821 ** 822 ** Returns: None 823 ** 824 *******************************************************************************/ 825 void NfcTag::fillNativeNfcTagMembers4 (JNIEnv* e, jclass tag_cls, jobject tag, tNFA_ACTIVATED& activationData) 826 { 827 static const char fn [] = "NfcTag::fillNativeNfcTagMembers4"; 828 ScopedLocalRef<jbyteArray> actBytes(e, e->NewByteArray(0)); 829 ScopedLocalRef<jclass> byteArrayClass(e, e->GetObjectClass(actBytes.get())); 830 ScopedLocalRef<jobjectArray> techActBytes(e, e->NewObjectArray(mNumTechList, byteArrayClass.get(), 0)); 831 832 for (int i = 0; i < mNumTechList; i++) 833 { 834 ALOGD ("%s: index=%d", fn, i); 835 if (NFC_PROTOCOL_T1T == mTechLibNfcTypes[i] || NFC_PROTOCOL_T2T == mTechLibNfcTypes[i]) 836 { 837 if (mTechLibNfcTypes[i] == NFC_PROTOCOL_T1T) 838 ALOGD ("%s: T1T; tech A", fn); 839 else if (mTechLibNfcTypes[i] == NFC_PROTOCOL_T2T) 840 ALOGD ("%s: T2T; tech A", fn); 841 actBytes.reset(e->NewByteArray(1)); 842 e->SetByteArrayRegion(actBytes.get(), 0, 1, (jbyte*) &mTechParams [i].param.pa.sel_rsp); 843 } 844 else if (NFC_PROTOCOL_T3T == mTechLibNfcTypes[i]) 845 { 846 //felica 847 ALOGD ("%s: T3T; felica; tech F", fn); 848 //really, there is no data 849 actBytes.reset(e->NewByteArray(0)); 850 } 851 else if (NFC_PROTOCOL_MIFARE == mTechLibNfcTypes[i]) 852 { 853 ALOGD ("%s: Mifare Classic; tech A", fn); 854 actBytes.reset (e->NewByteArray(1)); 855 e->SetByteArrayRegion (actBytes.get(), 0, 1, 856 (jbyte*) &mTechParams [i].param.pa.sel_rsp); 857 } 858 else if (NFC_PROTOCOL_ISO_DEP == mTechLibNfcTypes[i]) 859 { 860 //t4t 861 if (mTechList [i] == TARGET_TYPE_ISO14443_4) //is TagTechnology.ISO_DEP by Java API 862 { 863 if ( (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) || 864 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) || 865 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_A) || 866 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE) ) 867 { 868 //see NFC Forum Digital Protocol specification, section 11.6.2, "RATS Response"; search for "historical bytes"; 869 //copy historical bytes into Java object; 870 //the public API, IsoDep.getHistoricalBytes(), returns this data; 871 if (activationData.activate_ntf.intf_param.type == NFC_INTERFACE_ISO_DEP) 872 { 873 tNFC_INTF_PA_ISO_DEP& pa_iso = activationData.activate_ntf.intf_param.intf_param.pa_iso; 874 ALOGD ("%s: T4T; ISO_DEP for tech A; copy historical bytes; len=%u", fn, pa_iso.his_byte_len); 875 actBytes.reset(e->NewByteArray(pa_iso.his_byte_len)); 876 if (pa_iso.his_byte_len > 0) 877 e->SetByteArrayRegion(actBytes.get(), 0, pa_iso.his_byte_len, (jbyte*) (pa_iso.his_byte)); 878 } 879 else 880 { 881 ALOGE ("%s: T4T; ISO_DEP for tech A; wrong interface=%u", fn, activationData.activate_ntf.intf_param.type); 882 actBytes.reset(e->NewByteArray(0)); 883 } 884 } 885 else if ( (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_B) || 886 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_B_PRIME) || 887 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_B) || 888 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) ) 889 { 890 //see NFC Forum Digital Protocol specification, section 12.6.2, "ATTRIB Response"; 891 //copy higher-layer response bytes into Java object; 892 //the public API, IsoDep.getHiLayerResponse(), returns this data; 893 if (activationData.activate_ntf.intf_param.type == NFC_INTERFACE_ISO_DEP) 894 { 895 tNFC_INTF_PB_ISO_DEP& pb_iso = activationData.activate_ntf.intf_param.intf_param.pb_iso; 896 ALOGD ("%s: T4T; ISO_DEP for tech B; copy response bytes; len=%u", fn, pb_iso.hi_info_len); 897 actBytes.reset(e->NewByteArray(pb_iso.hi_info_len)); 898 if (pb_iso.hi_info_len > 0) 899 e->SetByteArrayRegion(actBytes.get(), 0, pb_iso.hi_info_len, (jbyte*) (pb_iso.hi_info)); 900 } 901 else 902 { 903 ALOGE ("%s: T4T; ISO_DEP for tech B; wrong interface=%u", fn, activationData.activate_ntf.intf_param.type); 904 actBytes.reset(e->NewByteArray(0)); 905 } 906 } 907 } 908 else if (mTechList [i] == TARGET_TYPE_ISO14443_3A) //is TagTechnology.NFC_A by Java API 909 { 910 ALOGD ("%s: T4T; tech A", fn); 911 actBytes.reset(e->NewByteArray(1)); 912 e->SetByteArrayRegion(actBytes.get(), 0, 1, (jbyte*) &mTechParams [i].param.pa.sel_rsp); 913 } 914 else 915 { 916 actBytes.reset(e->NewByteArray(0)); 917 } 918 } //case NFC_PROTOCOL_ISO_DEP: //t4t 919 else if (NFC_PROTOCOL_15693 == mTechLibNfcTypes[i]) 920 { 921 ALOGD ("%s: tech iso 15693", fn); 922 //iso 15693 response flags: 1 octet 923 //iso 15693 Data Structure Format Identifier (DSF ID): 1 octet 924 //used by public API: NfcV.getDsfId(), NfcV.getResponseFlags(); 925 uint8_t data [2]= {activationData.params.i93.afi, activationData.params.i93.dsfid}; 926 actBytes.reset(e->NewByteArray(2)); 927 e->SetByteArrayRegion(actBytes.get(), 0, 2, (jbyte *) data); 928 } 929 else 930 { 931 ALOGD ("%s: tech unknown ????", fn); 932 actBytes.reset(e->NewByteArray(0)); 933 } 934 e->SetObjectArrayElement(techActBytes.get(), i, actBytes.get()); 935 } //for: every technology in the array 936 jfieldID f = e->GetFieldID (tag_cls, "mTechActBytes", "[[B"); 937 e->SetObjectField(tag, f, techActBytes.get()); 938 } 939 940 941 /******************************************************************************* 942 ** 943 ** Function: fillNativeNfcTagMembers5 944 ** 945 ** Description: Fill NativeNfcTag's members: mUid. 946 ** The original Google's implementation is in nfc_jni_Discovery_notification_callback() 947 ** in com_android_nfc_NativeNfcManager.cpp; 948 ** e: JVM environment. 949 ** tag_cls: Java NativeNfcTag class. 950 ** tag: Java NativeNfcTag object. 951 ** activationData: data from activation. 952 ** 953 ** Returns: None 954 ** 955 *******************************************************************************/ 956 void NfcTag::fillNativeNfcTagMembers5 (JNIEnv* e, jclass tag_cls, jobject tag, tNFA_ACTIVATED& activationData) 957 { 958 static const char fn [] = "NfcTag::fillNativeNfcTagMembers5"; 959 int len = 0; 960 ScopedLocalRef<jbyteArray> uid(e, NULL); 961 962 if (NFC_DISCOVERY_TYPE_POLL_KOVIO == mTechParams [0].mode) 963 { 964 ALOGD ("%s: Kovio", fn); 965 len = mTechParams [0].param.pk.uid_len; 966 uid.reset(e->NewByteArray(len)); 967 e->SetByteArrayRegion(uid.get(), 0, len, 968 (jbyte*) &mTechParams [0].param.pk.uid); 969 } 970 else if (NFC_DISCOVERY_TYPE_POLL_A == mTechParams [0].mode 971 || NFC_DISCOVERY_TYPE_POLL_A_ACTIVE == mTechParams [0].mode 972 || NFC_DISCOVERY_TYPE_LISTEN_A == mTechParams [0].mode 973 || NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE == mTechParams [0].mode) 974 { 975 ALOGD ("%s: tech A", fn); 976 len = mTechParams [0].param.pa.nfcid1_len; 977 uid.reset(e->NewByteArray(len)); 978 e->SetByteArrayRegion(uid.get(), 0, len, 979 (jbyte*) &mTechParams [0].param.pa.nfcid1); 980 //a tag's NFCID1 can change dynamically at each activation; 981 //only the first byte (0x08) is constant; a dynamic NFCID1's length 982 //must be 4 bytes (see NFC Digitial Protocol, 983 //section 4.7.2 SDD_RES Response, Requirements 20). 984 mIsDynamicTagId = (mTechParams [0].param.pa.nfcid1_len == 4) && 985 (mTechParams [0].param.pa.nfcid1 [0] == 0x08); 986 } 987 else if (NFC_DISCOVERY_TYPE_POLL_B == mTechParams [0].mode 988 || NFC_DISCOVERY_TYPE_POLL_B_PRIME == mTechParams [0].mode 989 || NFC_DISCOVERY_TYPE_LISTEN_B == mTechParams [0].mode 990 || NFC_DISCOVERY_TYPE_LISTEN_B_PRIME == mTechParams [0].mode) 991 { 992 ALOGD ("%s: tech B", fn); 993 uid.reset(e->NewByteArray(NFC_NFCID0_MAX_LEN)); 994 e->SetByteArrayRegion(uid.get(), 0, NFC_NFCID0_MAX_LEN, 995 (jbyte*) &mTechParams [0].param.pb.nfcid0); 996 } 997 else if (NFC_DISCOVERY_TYPE_POLL_F == mTechParams [0].mode 998 || NFC_DISCOVERY_TYPE_POLL_F_ACTIVE == mTechParams [0].mode 999 || NFC_DISCOVERY_TYPE_LISTEN_F == mTechParams [0].mode 1000 || NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE == mTechParams [0].mode) 1001 { 1002 uid.reset(e->NewByteArray(NFC_NFCID2_LEN)); 1003 e->SetByteArrayRegion(uid.get(), 0, NFC_NFCID2_LEN, 1004 (jbyte*) &mTechParams [0].param.pf.nfcid2); 1005 ALOGD ("%s: tech F", fn); 1006 } 1007 else if (NFC_DISCOVERY_TYPE_POLL_ISO15693 == mTechParams [0].mode 1008 || NFC_DISCOVERY_TYPE_LISTEN_ISO15693 == mTechParams [0].mode) 1009 { 1010 ALOGD ("%s: tech iso 15693", fn); 1011 jbyte data [I93_UID_BYTE_LEN]; //8 bytes 1012 for (int i=0; i<I93_UID_BYTE_LEN; ++i) //reverse the ID 1013 data[i] = activationData.params.i93.uid [I93_UID_BYTE_LEN - i - 1]; 1014 uid.reset(e->NewByteArray(I93_UID_BYTE_LEN)); 1015 e->SetByteArrayRegion(uid.get(), 0, I93_UID_BYTE_LEN, data); 1016 } 1017 else 1018 { 1019 ALOGE ("%s: tech unknown ????", fn); 1020 uid.reset(e->NewByteArray(0)); 1021 } 1022 jfieldID f = e->GetFieldID(tag_cls, "mUid", "[B"); 1023 e->SetObjectField(tag, f, uid.get()); 1024 } 1025 1026 1027 /******************************************************************************* 1028 ** 1029 ** Function: isP2pDiscovered 1030 ** 1031 ** Description: Does the peer support P2P? 1032 ** 1033 ** Returns: True if the peer supports P2P. 1034 ** 1035 *******************************************************************************/ 1036 bool NfcTag::isP2pDiscovered () 1037 { 1038 static const char fn [] = "NfcTag::isP2pDiscovered"; 1039 bool retval = false; 1040 1041 for (int i = 0; i < mNumTechList; i++) 1042 { 1043 if (mTechLibNfcTypes[i] == NFA_PROTOCOL_NFC_DEP) 1044 { 1045 //if remote device supports P2P 1046 ALOGD ("%s: discovered P2P", fn); 1047 retval = true; 1048 break; 1049 } 1050 } 1051 ALOGD ("%s: return=%u", fn, retval); 1052 return retval; 1053 } 1054 1055 1056 /******************************************************************************* 1057 ** 1058 ** Function: selectP2p 1059 ** 1060 ** Description: Select the preferred P2P technology if there is a choice. 1061 ** 1062 ** Returns: None 1063 ** 1064 *******************************************************************************/ 1065 void NfcTag::selectP2p() 1066 { 1067 static const char fn [] = "NfcTag::selectP2p"; 1068 UINT8 rfDiscoveryId = 0; 1069 1070 for (int i = 0; i < mNumTechList; i++) 1071 { 1072 //if remote device does not support P2P, just skip it 1073 if (mTechLibNfcTypes[i] != NFA_PROTOCOL_NFC_DEP) 1074 continue; 1075 1076 //if remote device supports tech F; 1077 //tech F is preferred because it is faster than tech A 1078 if ( (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_F) || 1079 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_F_ACTIVE) ) 1080 { 1081 rfDiscoveryId = mTechHandles[i]; 1082 break; //no need to search further 1083 } 1084 else if ( (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) || 1085 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) ) 1086 { 1087 //only choose tech A if tech F is unavailable 1088 if (rfDiscoveryId == 0) 1089 rfDiscoveryId = mTechHandles[i]; 1090 } 1091 } 1092 1093 if (rfDiscoveryId > 0) 1094 { 1095 ALOGD ("%s: select P2P; target rf discov id=0x%X", fn, rfDiscoveryId); 1096 tNFA_STATUS stat = NFA_Select (rfDiscoveryId, NFA_PROTOCOL_NFC_DEP, NFA_INTERFACE_NFC_DEP); 1097 if (stat != NFA_STATUS_OK) 1098 ALOGE ("%s: fail select P2P; error=0x%X", fn, stat); 1099 } 1100 else 1101 ALOGE ("%s: cannot find P2P", fn); 1102 resetTechnologies (); 1103 } 1104 1105 1106 /******************************************************************************* 1107 ** 1108 ** Function: resetTechnologies 1109 ** 1110 ** Description: Clear all data related to the technology, protocol of the tag. 1111 ** 1112 ** Returns: None 1113 ** 1114 *******************************************************************************/ 1115 void NfcTag::resetTechnologies () 1116 { 1117 static const char fn [] = "NfcTag::resetTechnologies"; 1118 ALOGD ("%s", fn); 1119 mNumTechList = 0; 1120 memset (mTechList, 0, sizeof(mTechList)); 1121 memset (mTechHandles, 0, sizeof(mTechHandles)); 1122 memset (mTechLibNfcTypes, 0, sizeof(mTechLibNfcTypes)); 1123 memset (mTechParams, 0, sizeof(mTechParams)); 1124 mIsDynamicTagId = false; 1125 mIsFelicaLite = false; 1126 resetAllTransceiveTimeouts (); 1127 } 1128 1129 1130 /******************************************************************************* 1131 ** 1132 ** Function: selectFirstTag 1133 ** 1134 ** Description: When multiple tags are discovered, just select the first one to activate. 1135 ** 1136 ** Returns: None 1137 ** 1138 *******************************************************************************/ 1139 void NfcTag::selectFirstTag () 1140 { 1141 static const char fn [] = "NfcTag::selectFirstTag"; 1142 int foundIdx = -1; 1143 tNFA_INTF_TYPE rf_intf = NFA_INTERFACE_FRAME; 1144 1145 for (int i = 0; i < mNumTechList; i++) 1146 { 1147 ALOGD ("%s: nfa target idx=%d h=0x%X; protocol=0x%X", 1148 fn, i, mTechHandles [i], mTechLibNfcTypes [i]); 1149 if (mTechLibNfcTypes[i] != NFA_PROTOCOL_NFC_DEP) 1150 { 1151 foundIdx = i; 1152 break; 1153 } 1154 } 1155 1156 if (foundIdx != -1) 1157 { 1158 if (mTechLibNfcTypes [foundIdx] == NFA_PROTOCOL_ISO_DEP) 1159 { 1160 rf_intf = NFA_INTERFACE_ISO_DEP; 1161 } 1162 else if (mTechLibNfcTypes [foundIdx] == NFA_PROTOCOL_MIFARE) 1163 { 1164 rf_intf = NFA_INTERFACE_MIFARE; 1165 } 1166 else 1167 rf_intf = NFA_INTERFACE_FRAME; 1168 1169 tNFA_STATUS stat = NFA_Select (mTechHandles [foundIdx], mTechLibNfcTypes [foundIdx], rf_intf); 1170 if (stat != NFA_STATUS_OK) 1171 ALOGE ("%s: fail select; error=0x%X", fn, stat); 1172 } 1173 else 1174 ALOGE ("%s: only found NFC-DEP technology.", fn); 1175 } 1176 1177 1178 /******************************************************************************* 1179 ** 1180 ** Function: getT1tMaxMessageSize 1181 ** 1182 ** Description: Get the maximum size (octet) that a T1T can store. 1183 ** 1184 ** Returns: Maximum size in octets. 1185 ** 1186 *******************************************************************************/ 1187 int NfcTag::getT1tMaxMessageSize () 1188 { 1189 static const char fn [] = "NfcTag::getT1tMaxMessageSize"; 1190 1191 if (mProtocol != NFC_PROTOCOL_T1T) 1192 { 1193 ALOGE ("%s: wrong protocol %u", fn, mProtocol); 1194 return 0; 1195 } 1196 return mtT1tMaxMessageSize; 1197 } 1198 1199 1200 /******************************************************************************* 1201 ** 1202 ** Function: calculateT1tMaxMessageSize 1203 ** 1204 ** Description: Calculate type-1 tag's max message size based on header ROM bytes. 1205 ** activate: reference to activation data. 1206 ** 1207 ** Returns: None 1208 ** 1209 *******************************************************************************/ 1210 void NfcTag::calculateT1tMaxMessageSize (tNFA_ACTIVATED& activate) 1211 { 1212 static const char fn [] = "NfcTag::calculateT1tMaxMessageSize"; 1213 1214 //make sure the tag is type-1 1215 if (activate.activate_ntf.protocol != NFC_PROTOCOL_T1T) 1216 { 1217 mtT1tMaxMessageSize = 0; 1218 return; 1219 } 1220 1221 //examine the first byte of header ROM bytes 1222 switch (activate.params.t1t.hr[0]) 1223 { 1224 case RW_T1T_IS_TOPAZ96: 1225 mtT1tMaxMessageSize = 90; 1226 break; 1227 case RW_T1T_IS_TOPAZ512: 1228 mtT1tMaxMessageSize = 462; 1229 break; 1230 default: 1231 ALOGE ("%s: unknown T1T HR0=%u", fn, activate.params.t1t.hr[0]); 1232 mtT1tMaxMessageSize = 0; 1233 break; 1234 } 1235 } 1236 1237 1238 /******************************************************************************* 1239 ** 1240 ** Function: isMifareUltralight 1241 ** 1242 ** Description: Whether the currently activated tag is Mifare Ultralight. 1243 ** 1244 ** Returns: True if tag is Mifare Ultralight. 1245 ** 1246 *******************************************************************************/ 1247 bool NfcTag::isMifareUltralight () 1248 { 1249 static const char fn [] = "NfcTag::isMifareUltralight"; 1250 bool retval = false; 1251 1252 for (int i =0; i < mNumTechList; i++) 1253 { 1254 if (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) 1255 { 1256 //see NFC Digital Protocol, section 4.6.3 (SENS_RES); section 4.8.2 (SEL_RES). 1257 //see "MF0ICU1 Functional specification MIFARE Ultralight", Rev. 3.4 - 4 February 2008, 1258 //section 6.7. 1259 if ( (mTechParams[i].param.pa.sens_res[0] == 0x44) && 1260 (mTechParams[i].param.pa.sens_res[1] == 0) && 1261 ( (mTechParams[i].param.pa.sel_rsp == 0) || (mTechParams[i].param.pa.sel_rsp == 0x04) ) && 1262 (mTechParams[i].param.pa.nfcid1[0] == 0x04) ) 1263 { 1264 retval = true; 1265 } 1266 break; 1267 } 1268 } 1269 ALOGD ("%s: return=%u", fn, retval); 1270 return retval; 1271 } 1272 1273 1274 /******************************************************************************* 1275 ** 1276 ** Function: isMifareDESFire 1277 ** 1278 ** Description: Whether the currently activated tag is Mifare DESFire. 1279 ** 1280 ** Returns: True if tag is Mifare DESFire. 1281 ** 1282 *******************************************************************************/ 1283 bool NfcTag::isMifareDESFire () 1284 { 1285 static const char fn [] = "NfcTag::isMifareDESFire"; 1286 bool retval = false; 1287 1288 for (int i =0; i < mNumTechList; i++) 1289 { 1290 if ( (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) || 1291 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_A) || 1292 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE) ) 1293 { 1294 /* DESfire has one sak byte and 2 ATQA bytes */ 1295 if ( (mTechParams[i].param.pa.sens_res[0] == 0x44) && 1296 (mTechParams[i].param.pa.sens_res[1] == 0x03) && 1297 (mTechParams[i].param.pa.sel_rsp == 0x20) ) 1298 { 1299 retval = true; 1300 } 1301 break; 1302 } 1303 } 1304 1305 ALOGD ("%s: return=%u", fn, retval); 1306 return retval; 1307 } 1308 1309 1310 /******************************************************************************* 1311 ** 1312 ** Function: isFelicaLite 1313 ** 1314 ** Description: Whether the currently activated tag is Felica Lite. 1315 ** 1316 ** Returns: True if tag is Felica Lite. 1317 ** 1318 *******************************************************************************/ 1319 1320 bool NfcTag::isFelicaLite () 1321 { 1322 return mIsFelicaLite; 1323 } 1324 1325 1326 /******************************************************************************* 1327 ** 1328 ** Function: isT2tNackResponse 1329 ** 1330 ** Description: Whether the response is a T2T NACK response. 1331 ** See NFC Digital Protocol Technical Specification (2010-11-17). 1332 ** Chapter 9 (Type 2 Tag Platform), section 9.6 (READ). 1333 ** response: buffer contains T2T response. 1334 ** responseLen: length of the response. 1335 ** 1336 ** Returns: True if the response is NACK 1337 ** 1338 *******************************************************************************/ 1339 bool NfcTag::isT2tNackResponse (const UINT8* response, UINT32 responseLen) 1340 { 1341 static const char fn [] = "NfcTag::isT2tNackResponse"; 1342 bool isNack = false; 1343 1344 if (responseLen == 1) 1345 { 1346 if (response[0] == 0xA) 1347 isNack = false; //an ACK response, so definitely not a NACK 1348 else 1349 isNack = true; //assume every value is a NACK 1350 } 1351 ALOGD ("%s: return %u", fn, isNack); 1352 return isNack; 1353 } 1354 1355 1356 /******************************************************************************* 1357 ** 1358 ** Function: isNdefDetectionTimedOut 1359 ** 1360 ** Description: Whether NDEF-detection algorithm timed out. 1361 ** 1362 ** Returns: True if NDEF-detection algorithm timed out. 1363 ** 1364 *******************************************************************************/ 1365 bool NfcTag::isNdefDetectionTimedOut () 1366 { 1367 return mNdefDetectionTimedOut; 1368 } 1369 1370 1371 /******************************************************************************* 1372 ** 1373 ** Function: connectionEventHandler 1374 ** 1375 ** Description: Handle connection-related events. 1376 ** event: event code. 1377 ** data: pointer to event data. 1378 ** 1379 ** Returns: None 1380 ** 1381 *******************************************************************************/ 1382 void NfcTag::connectionEventHandler (UINT8 event, tNFA_CONN_EVT_DATA* data) 1383 { 1384 static const char fn [] = "NfcTag::connectionEventHandler"; 1385 1386 switch (event) 1387 { 1388 case NFA_DISC_RESULT_EVT: 1389 { 1390 tNFA_DISC_RESULT& disc_result = data->disc_result; 1391 if (disc_result.status == NFA_STATUS_OK) 1392 { 1393 discoverTechnologies (disc_result); 1394 } 1395 } 1396 break; 1397 1398 case NFA_ACTIVATED_EVT: 1399 // Only do tag detection if we are polling and it is not 'EE Direct RF' activation 1400 // (which may happen when we are activated as a tag). 1401 if (data->activated.activate_ntf.rf_tech_param.mode < NCI_DISCOVERY_TYPE_LISTEN_A 1402 && data->activated.activate_ntf.intf_param.type != NFC_INTERFACE_EE_DIRECT_RF) 1403 { 1404 tNFA_ACTIVATED& activated = data->activated; 1405 if (IsSameKovio(activated)) 1406 break; 1407 mIsActivated = true; 1408 mProtocol = activated.activate_ntf.protocol; 1409 calculateT1tMaxMessageSize (activated); 1410 discoverTechnologies (activated); 1411 createNativeNfcTag (activated); 1412 } 1413 break; 1414 1415 case NFA_DEACTIVATED_EVT: 1416 mIsActivated = false; 1417 mProtocol = NFC_PROTOCOL_UNKNOWN; 1418 resetTechnologies (); 1419 break; 1420 1421 case NFA_READ_CPLT_EVT: 1422 { 1423 SyncEventGuard g (mReadCompleteEvent); 1424 mReadCompletedStatus = data->status; 1425 mReadCompleteEvent.notifyOne (); 1426 } 1427 break; 1428 1429 case NFA_NDEF_DETECT_EVT: 1430 { 1431 tNFA_NDEF_DETECT& ndef_detect = data->ndef_detect; 1432 mNdefDetectionTimedOut = ndef_detect.status == NFA_STATUS_TIMEOUT; 1433 if (mNdefDetectionTimedOut) 1434 ALOGE ("%s: NDEF detection timed out", fn); 1435 } 1436 } 1437 } 1438 1439 1440 /******************************************************************************* 1441 ** 1442 ** Function setActive 1443 ** 1444 ** Description Sets the active state for the object 1445 ** 1446 ** Returns None. 1447 ** 1448 *******************************************************************************/ 1449 void NfcTag::setActive(bool active) 1450 { 1451 mIsActivated = active; 1452 } 1453 1454 1455 /******************************************************************************* 1456 ** 1457 ** Function: isDynamicTagId 1458 ** 1459 ** Description: Whether a tag has a dynamic tag ID. 1460 ** 1461 ** Returns: True if ID is dynamic. 1462 ** 1463 *******************************************************************************/ 1464 bool NfcTag::isDynamicTagId () 1465 { 1466 return mIsDynamicTagId && 1467 (mTechList [0] == TARGET_TYPE_ISO14443_4) && //type-4 tag 1468 (mTechList [1] == TARGET_TYPE_ISO14443_3A); //tech A 1469 } 1470 1471 1472 /******************************************************************************* 1473 ** 1474 ** Function: resetAllTransceiveTimeouts 1475 ** 1476 ** Description: Reset all timeouts for all technologies to default values. 1477 ** 1478 ** Returns: none 1479 ** 1480 *******************************************************************************/ 1481 void NfcTag::resetAllTransceiveTimeouts () 1482 { 1483 mTechnologyTimeoutsTable [TARGET_TYPE_ISO14443_3A] = 618; //NfcA 1484 mTechnologyTimeoutsTable [TARGET_TYPE_ISO14443_3B] = 1000; //NfcB 1485 mTechnologyTimeoutsTable [TARGET_TYPE_ISO14443_4] = 618; //ISO-DEP 1486 mTechnologyTimeoutsTable [TARGET_TYPE_FELICA] = 255; //Felica 1487 mTechnologyTimeoutsTable [TARGET_TYPE_ISO15693] = 1000;//NfcV 1488 mTechnologyTimeoutsTable [TARGET_TYPE_NDEF] = 1000; 1489 mTechnologyTimeoutsTable [TARGET_TYPE_NDEF_FORMATABLE] = 1000; 1490 mTechnologyTimeoutsTable [TARGET_TYPE_MIFARE_CLASSIC] = 618; //MifareClassic 1491 mTechnologyTimeoutsTable [TARGET_TYPE_MIFARE_UL] = 618; //MifareUltralight 1492 mTechnologyTimeoutsTable [TARGET_TYPE_KOVIO_BARCODE] = 1000; //NfcBarcode 1493 } 1494 1495 /******************************************************************************* 1496 ** 1497 ** Function: getTransceiveTimeout 1498 ** 1499 ** Description: Get the timeout value for one technology. 1500 ** techId: one of the values in TARGET_TYPE_* defined in NfcJniUtil.h 1501 ** 1502 ** Returns: Timeout value in millisecond. 1503 ** 1504 *******************************************************************************/ 1505 int NfcTag::getTransceiveTimeout (int techId) 1506 { 1507 static const char fn [] = "NfcTag::getTransceiveTimeout"; 1508 int retval = 1000; 1509 if ((techId > 0) && (techId < (int) mTechnologyTimeoutsTable.size())) 1510 retval = mTechnologyTimeoutsTable [techId]; 1511 else 1512 ALOGE ("%s: invalid tech=%d", fn, techId); 1513 return retval; 1514 } 1515 1516 1517 /******************************************************************************* 1518 ** 1519 ** Function: setTransceiveTimeout 1520 ** 1521 ** Description: Set the timeout value for one technology. 1522 ** techId: one of the values in TARGET_TYPE_* defined in NfcJniUtil.h 1523 ** timeout: timeout value in millisecond. 1524 ** 1525 ** Returns: Timeout value. 1526 ** 1527 *******************************************************************************/ 1528 void NfcTag::setTransceiveTimeout (int techId, int timeout) 1529 { 1530 static const char fn [] = "NfcTag::setTransceiveTimeout"; 1531 if ((techId >= 0) && (techId < (int) mTechnologyTimeoutsTable.size())) 1532 mTechnologyTimeoutsTable [techId] = timeout; 1533 else 1534 ALOGE ("%s: invalid tech=%d", fn, techId); 1535 } 1536 1537 1538 /******************************************************************************* 1539 ** 1540 ** Function: getPresenceCheckAlgorithm 1541 ** 1542 ** Description: Get presence-check algorithm from .conf file. 1543 ** 1544 ** Returns: Presence-check algorithm. 1545 ** 1546 *******************************************************************************/ 1547 tNFA_RW_PRES_CHK_OPTION NfcTag::getPresenceCheckAlgorithm () 1548 { 1549 return mPresenceCheckAlgorithm; 1550 } 1551 1552 1553 /******************************************************************************* 1554 ** 1555 ** Function: isInfineonMyDMove 1556 ** 1557 ** Description: Whether the currently activated tag is Infineon My-D Move. 1558 ** 1559 ** Returns: True if tag is Infineon My-D Move. 1560 ** 1561 *******************************************************************************/ 1562 bool NfcTag::isInfineonMyDMove () 1563 { 1564 static const char fn [] = "NfcTag::isInfineonMyDMove"; 1565 bool retval = false; 1566 1567 for (int i =0; i < mNumTechList; i++) 1568 { 1569 if (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) 1570 { 1571 //see Infineon my-d move, my-d move NFC, SLE 66R01P, SLE 66R01PN, 1572 //Short Product Information, 2011-11-24, section 3.5 1573 if (mTechParams[i].param.pa.nfcid1[0] == 0x05) 1574 { 1575 UINT8 highNibble = mTechParams[i].param.pa.nfcid1[1] & 0xF0; 1576 if (highNibble == 0x30) 1577 retval = true; 1578 } 1579 break; 1580 } 1581 } 1582 ALOGD ("%s: return=%u", fn, retval); 1583 return retval; 1584 } 1585 1586 1587 /******************************************************************************* 1588 ** 1589 ** Function: isKovioType2Tag 1590 ** 1591 ** Description: Whether the currently activated tag is Kovio Type-2 tag. 1592 ** 1593 ** Returns: True if tag is Kovio Type-2 tag. 1594 ** 1595 *******************************************************************************/ 1596 bool NfcTag::isKovioType2Tag () 1597 { 1598 static const char fn [] = "NfcTag::isKovioType2Tag"; 1599 bool retval = false; 1600 1601 for (int i =0; i < mNumTechList; i++) 1602 { 1603 if (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) 1604 { 1605 //Kovio 2Kb RFID Tag, Functional Specification, 1606 //March 2, 2012, v2.0, section 8.3. 1607 if (mTechParams[i].param.pa.nfcid1[0] == 0x37) 1608 retval = true; 1609 break; 1610 } 1611 } 1612 ALOGD ("%s: return=%u", fn, retval); 1613 return retval; 1614 } 1615