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" 23extern "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*******************************************************************************/ 38NfcTag::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*******************************************************************************/ 65NfcTag& 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*******************************************************************************/ 82void 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*******************************************************************************/ 103void 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*******************************************************************************/ 119NfcTag::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*******************************************************************************/ 135void 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*******************************************************************************/ 155void 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*******************************************************************************/ 173tNFC_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*******************************************************************************/ 187UINT32 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*******************************************************************************/ 217bool 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*******************************************************************************/ 270void 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*******************************************************************************/ 382void 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 473TheEnd: 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*******************************************************************************/ 490void 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 549TheEnd: 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*******************************************************************************/ 567void 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 620void 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*******************************************************************************/ 646void 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*******************************************************************************/ 766void 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*******************************************************************************/ 907void 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*******************************************************************************/ 986bool 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*******************************************************************************/ 1015void 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*******************************************************************************/ 1065void 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*******************************************************************************/ 1086void 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*******************************************************************************/ 1117int 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*******************************************************************************/ 1140void 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*******************************************************************************/ 1177bool 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*******************************************************************************/ 1228bool 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*******************************************************************************/ 1254bool 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*******************************************************************************/ 1271void 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