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