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