nfc_worker.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. #include "nfc_worker_i.h"
  2. #include <api-hal.h>
  3. NfcWorker* nfc_worker_alloc(osMessageQueueId_t message_queue) {
  4. NfcWorker* nfc_worker = furi_alloc(sizeof(NfcWorker));
  5. nfc_worker->message_queue = message_queue;
  6. // Worker thread attributes
  7. nfc_worker->thread_attr.name = "nfc_worker";
  8. nfc_worker->thread_attr.stack_size = 2048;
  9. // Initialize rfal
  10. rfalAnalogConfigInitialize();
  11. nfc_worker->error = rfalNfcInitialize();
  12. if(nfc_worker->error == ERR_NONE) {
  13. rfalLowPowerModeStart();
  14. nfc_worker_change_state(nfc_worker, NfcWorkerStateReady);
  15. } else {
  16. nfc_worker_change_state(nfc_worker, NfcWorkerStateBroken);
  17. }
  18. return nfc_worker;
  19. }
  20. NfcWorkerState nfc_worker_get_state(NfcWorker* nfc_worker) {
  21. return nfc_worker->state;
  22. }
  23. ReturnCode nfc_worker_get_error(NfcWorker* nfc_worker) {
  24. return nfc_worker->error;
  25. }
  26. void nfc_worker_free(NfcWorker* nfc_worker) {
  27. furi_assert(nfc_worker);
  28. }
  29. void nfc_worker_start(NfcWorker* nfc_worker, NfcWorkerState state) {
  30. furi_assert(nfc_worker);
  31. furi_assert(nfc_worker->state == NfcWorkerStateReady);
  32. nfc_worker_change_state(nfc_worker, state);
  33. nfc_worker->thread = osThreadNew(nfc_worker_task, nfc_worker, &nfc_worker->thread_attr);
  34. }
  35. void nfc_worker_stop(NfcWorker* nfc_worker) {
  36. furi_assert(nfc_worker);
  37. if(nfc_worker->state == NfcWorkerStateBroken) {
  38. return;
  39. }
  40. nfc_worker_change_state(nfc_worker, NfcWorkerStateStop);
  41. }
  42. void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state) {
  43. nfc_worker->state = state;
  44. }
  45. void nfc_worker_task(void* context) {
  46. NfcWorker* nfc_worker = context;
  47. api_hal_power_insomnia_enter();
  48. rfalLowPowerModeStop();
  49. if(nfc_worker->state == NfcWorkerStatePoll) {
  50. nfc_worker_poll(nfc_worker);
  51. } else if(nfc_worker->state == NfcWorkerStateEmulate) {
  52. nfc_worker_emulate(nfc_worker);
  53. } else if(nfc_worker->state == NfcWorkerStateField) {
  54. nfc_worker_field(nfc_worker);
  55. }
  56. rfalLowPowerModeStart();
  57. nfc_worker_change_state(nfc_worker, NfcWorkerStateReady);
  58. api_hal_power_insomnia_exit();
  59. osThreadExit();
  60. }
  61. void nfc_worker_poll(NfcWorker* nfc_worker) {
  62. while(nfc_worker->state == NfcWorkerStatePoll) {
  63. bool is_found = false;
  64. is_found |= nfc_worker_nfca_poll(nfc_worker);
  65. is_found |= nfc_worker_nfcb_poll(nfc_worker);
  66. is_found |= nfc_worker_nfcf_poll(nfc_worker);
  67. is_found |= nfc_worker_nfcv_poll(nfc_worker);
  68. rfalFieldOff();
  69. if(!is_found) {
  70. NfcMessage message;
  71. message.type = NfcMessageTypeDeviceNotFound;
  72. furi_check(
  73. osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK);
  74. }
  75. platformDelay(333);
  76. }
  77. }
  78. bool nfc_worker_nfca_poll(NfcWorker* nfc_worker) {
  79. ReturnCode ret;
  80. rfalNfcaSensRes sense_res;
  81. rfalNfcaPollerInitialize();
  82. rfalFieldOnAndStartGT();
  83. ret = rfalNfcaPollerTechnologyDetection(RFAL_COMPLIANCE_MODE_NFC, &sense_res);
  84. if(ret != ERR_NONE) {
  85. return false;
  86. }
  87. uint8_t dev_cnt;
  88. rfalNfcaListenDevice device;
  89. ret = rfalNfcaPollerFullCollisionResolution(RFAL_COMPLIANCE_MODE_NFC, 1, &device, &dev_cnt);
  90. if(ret != ERR_NONE) {
  91. return false;
  92. }
  93. if(dev_cnt) {
  94. rfalNfcaPollerSleep();
  95. NfcMessage message;
  96. message.type = NfcMessageTypeDeviceFound;
  97. message.device.type = NfcDeviceTypeNfca;
  98. message.device.nfca = device;
  99. furi_check(
  100. osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK);
  101. return true;
  102. }
  103. return false;
  104. }
  105. bool nfc_worker_nfcb_poll(NfcWorker* nfc_worker) {
  106. ReturnCode ret;
  107. rfalNfcbPollerInitialize();
  108. rfalFieldOnAndStartGT();
  109. rfalNfcbSensbRes sensb_res;
  110. uint8_t sensb_res_len;
  111. ret = rfalNfcbPollerTechnologyDetection(RFAL_COMPLIANCE_MODE_NFC, &sensb_res, &sensb_res_len);
  112. if(ret != ERR_NONE) {
  113. return false;
  114. }
  115. uint8_t dev_cnt;
  116. rfalNfcbListenDevice device;
  117. ret = rfalNfcbPollerCollisionResolution(RFAL_COMPLIANCE_MODE_NFC, 1, &device, &dev_cnt);
  118. if(ret != ERR_NONE) {
  119. return false;
  120. }
  121. if(dev_cnt) {
  122. rfalNfcbPollerSleep(device.sensbRes.nfcid0);
  123. NfcMessage message;
  124. message.type = NfcMessageTypeDeviceFound;
  125. message.device.type = NfcDeviceTypeNfcb;
  126. message.device.nfcb = device;
  127. furi_check(
  128. osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK);
  129. return true;
  130. }
  131. return false;
  132. }
  133. bool nfc_worker_nfcf_poll(NfcWorker* nfc_worker) {
  134. ReturnCode ret;
  135. rfalNfcfPollerInitialize(RFAL_BR_212);
  136. rfalFieldOnAndStartGT();
  137. ret = rfalNfcfPollerCheckPresence();
  138. if(ret != ERR_NONE) {
  139. return false;
  140. }
  141. uint8_t dev_cnt;
  142. rfalNfcfListenDevice device;
  143. ret = rfalNfcfPollerCollisionResolution(RFAL_COMPLIANCE_MODE_NFC, 1, &device, &dev_cnt);
  144. if(ret != ERR_NONE) {
  145. return false;
  146. }
  147. if(dev_cnt) {
  148. NfcMessage message;
  149. message.type = NfcMessageTypeDeviceFound;
  150. message.device.type = NfcDeviceTypeNfcf;
  151. message.device.nfcf = device;
  152. furi_check(
  153. osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK);
  154. return true;
  155. }
  156. return false;
  157. }
  158. bool nfc_worker_nfcv_poll(NfcWorker* nfc_worker) {
  159. ReturnCode ret;
  160. rfalNfcvInventoryRes invRes;
  161. rfalNfcvPollerInitialize();
  162. rfalFieldOnAndStartGT();
  163. ret = rfalNfcvPollerCheckPresence(&invRes);
  164. if(ret != ERR_NONE) {
  165. return false;
  166. }
  167. uint8_t dev_cnt;
  168. rfalNfcvListenDevice device;
  169. ret = rfalNfcvPollerCollisionResolution(RFAL_COMPLIANCE_MODE_NFC, 1, &device, &dev_cnt);
  170. if(ret != ERR_NONE) {
  171. return false;
  172. }
  173. if(dev_cnt) {
  174. rfalNfcvPollerSleep(RFAL_NFCV_REQ_FLAG_DEFAULT, device.InvRes.UID);
  175. NfcMessage message;
  176. message.type = NfcMessageTypeDeviceFound;
  177. message.device.type = NfcDeviceTypeNfcv;
  178. message.device.nfcv = device;
  179. furi_check(
  180. osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK);
  181. return true;
  182. }
  183. return false;
  184. }
  185. void nfc_worker_state_callback(rfalNfcState st) {
  186. (void)st;
  187. }
  188. ReturnCode nfc_worker_trx(
  189. uint8_t* txBuf,
  190. uint16_t txBufSize,
  191. uint8_t** rxData,
  192. uint16_t** rcvLen,
  193. uint32_t fwt) {
  194. ReturnCode err;
  195. err = rfalNfcDataExchangeStart(txBuf, txBufSize, rxData, rcvLen, fwt);
  196. if(err == ERR_NONE) {
  197. do {
  198. rfalNfcWorker();
  199. err = rfalNfcDataExchangeGetStatus();
  200. } while(err == ERR_BUSY);
  201. }
  202. return err;
  203. }
  204. void nfc_worker_exchange(NfcWorker* nfc_worker, rfalNfcDevice* nfc_device) {
  205. ReturnCode err;
  206. uint8_t* rxData;
  207. uint16_t* rcvLen;
  208. uint8_t txBuf[100];
  209. uint16_t txLen;
  210. do {
  211. rfalNfcWorker();
  212. switch(rfalNfcGetState()) {
  213. case RFAL_NFC_STATE_ACTIVATED:
  214. err = nfc_worker_trx(NULL, 0, &rxData, &rcvLen, 0);
  215. break;
  216. case RFAL_NFC_STATE_DATAEXCHANGE:
  217. case RFAL_NFC_STATE_DATAEXCHANGE_DONE:
  218. // Not supported
  219. txBuf[0] = ((char)0x68);
  220. txBuf[1] = ((char)0x00);
  221. txLen = 2;
  222. err = nfc_worker_trx(txBuf, txLen, &rxData, &rcvLen, RFAL_FWT_NONE);
  223. break;
  224. case RFAL_NFC_STATE_START_DISCOVERY:
  225. return;
  226. case RFAL_NFC_STATE_LISTEN_SLEEP:
  227. default:
  228. break;
  229. }
  230. } while((err == ERR_NONE) || (err == ERR_SLEEP_REQ));
  231. }
  232. void nfc_worker_emulate(NfcWorker* nfc_worker) {
  233. rfalNfcDiscoverParam params;
  234. params.compMode = RFAL_COMPLIANCE_MODE_NFC;
  235. params.techs2Find = RFAL_NFC_LISTEN_TECH_A;
  236. params.totalDuration = 1000U;
  237. params.devLimit = 1;
  238. params.wakeupEnabled = false;
  239. params.wakeupConfigDefault = true;
  240. params.nfcfBR = RFAL_BR_212;
  241. params.ap2pBR = RFAL_BR_424;
  242. params.maxBR = RFAL_BR_KEEP;
  243. params.GBLen = RFAL_NFCDEP_GB_MAX_LEN;
  244. params.notifyCb = nfc_worker_state_callback;
  245. params.lmConfigPA.nfcidLen = RFAL_LM_NFCID_LEN_07;
  246. params.lmConfigPA.nfcid[0] = 0x00;
  247. params.lmConfigPA.nfcid[1] = 0x01;
  248. params.lmConfigPA.nfcid[2] = 0x02;
  249. params.lmConfigPA.nfcid[3] = 0x03;
  250. params.lmConfigPA.nfcid[4] = 0x04;
  251. params.lmConfigPA.nfcid[5] = 0x05;
  252. params.lmConfigPA.nfcid[6] = 0x06;
  253. params.lmConfigPA.SENS_RES[0] = 0x44;
  254. params.lmConfigPA.SENS_RES[1] = 0x00;
  255. params.lmConfigPA.SEL_RES = 0x00;
  256. ReturnCode ret;
  257. ret = rfalNfcDiscover(&params);
  258. if(ret != ERR_NONE) {
  259. asm("bkpt 1");
  260. return;
  261. }
  262. rfalNfcDevice* nfc_device;
  263. while(nfc_worker->state == NfcWorkerStateEmulate) {
  264. rfalNfcWorker();
  265. if(rfalNfcIsDevActivated(rfalNfcGetState())) {
  266. rfalNfcGetActiveDevice(&nfc_device);
  267. nfc_worker_exchange(nfc_worker, nfc_device);
  268. }
  269. osDelay(10);
  270. }
  271. rfalNfcDeactivate(false);
  272. }
  273. void nfc_worker_field(NfcWorker* nfc_worker) {
  274. st25r3916TxRxOn();
  275. while(nfc_worker->state == NfcWorkerStateField) {
  276. osDelay(50);
  277. }
  278. st25r3916TxRxOff();
  279. }