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