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