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