Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
isodep_target.c
00001 /* 00002 * Copyright (c) 2015-2018, ARM Limited, All Rights Reserved 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00006 * not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 /** 00018 * \file isodep_target.c 00019 * \copyright Copyright (c) ARM Ltd 2015 00020 * \author Donatien Garnier 00021 */ 00022 00023 #define __DEBUG__ 0 00024 #ifndef __MODULE__ 00025 #define __MODULE__ "isodep_target.c" 00026 #endif 00027 00028 #include "isodep_target.h" 00029 00030 #include "stack/nfc_errors.h" 00031 #include "transceiver/transceiver.h" 00032 00033 //Private defines 00034 #define RATS 0xE0 00035 #define FSDI_TO_FSD(x) (((x)<5)?(((x)<<3) + 16):((x)<8)?(((x)<<5)-96):256) 00036 #define FSC_TO_FSCI(x) (((x)<=48)?(((x)-16)>>3):((x)<=128)?(((x)+96)>>5):8) //returns the closest lower or equal value 00037 #define DID(x) ((x) & 0x0F) 00038 #define FSDI(x) (((x) >> 4) & 0x0F) 00039 00040 #define FSCI_TO_FSC(x) FSDI_TO_FSD(x) 00041 #define FSD_TO_FSDI(x) FSC_TO_FSCI(x) 00042 00043 //#define DI_TO_D(x) (1 << (x)) 00044 #define DI_TO_BITRATE(x) ((RF_BITRATE)((x) + RF_BITRATE_106K)) 00045 00046 00047 #define GET_FRAME_TYPE(pcb) ((((pcb) & 0xF0) == 0xD0)?PPS_FRAME:(((pcb) & 0xC0) == (0x00 << 6))?I_FRAME:((((pcb) & 0xC0) == (0x2 << 6))?R_FRAME:S_FRAME)) 00048 00049 #define I_BLOCK_PCB 0 00050 #define R_BLOCK_PCB 2 00051 #define S_BLOCK_PCB 3 00052 00053 #define PCB_TYPE(pcb) (((pcb)>>6)&0x03) 00054 00055 #define BUILD_I_BLOCK_PCB(chaining, cid, nad, block_toggle) ( (0x0 << 6) | (((chaining)?1:0) << 4) \ 00056 | (((cid)?1:0) << 3) | (((nad)?1:0) << 2) | (1 << 1) | (((block_toggle)?1:0)) ) 00057 #define BUILD_S_BLOCK_PCB(cid, wtx_n_deselect) ( (0x3 << 6) | (((wtx_n_deselect)?0x3:0) << 4) \ 00058 | (((cid)?1:0) << 3) | (1 << 1) ) 00059 #define BUILD_R_BLOCK_PCB(cid, block_toggle, nak) ( (0x2 << 6) | (1 <<5) | (((nak)?1:0) << 4) \ 00060 | (((cid)?1:0) << 3) | (1 << 1) | (((block_toggle)?1:0)) ) 00061 00062 #define PCB_IS_CID(pcb) (((pcb) & (1 << 3))?true:false) 00063 #define PCB_BLOCK_TOGGLE(pcb) (((pcb) & 1)?true:false) 00064 #define PCB_CHAINING(pcb) (((pcb) & 0x10)?true:false) 00065 #define PCB_NACK(pcb) (((pcb) & 0x10)?true:false) 00066 #define PCB_WTX(pcb) (((pcb)&0x30)==0x30) 00067 00068 #define WTXM_DEFAULT 10 00069 00070 //Parameters 00071 #define FSC 256 //Maximum frame size the PICC (us) can receive -- TODO should be a parameter at some point -- linked to PN512 buffer 00072 #define SFGI 2 //Guard time ~ 1.2ms 00073 //#define FWI 6 //Max time before answer is ~ 19.3ms 00074 #define FWI 14 //Max time before answer is ~ 19.3ms 00075 00076 typedef enum __dep_type dep_type_t; 00077 enum __dep_type { 00078 dep_type_information, 00079 dep_type_response, 00080 dep_type_supervisory, 00081 }; 00082 00083 //Local functions 00084 static void dep_init(nfc_tech_isodep_target_t *pIsodepTarget); 00085 static bool dep_ready(nfc_tech_isodep_target_t *pIsodepTarget); 00086 00087 static void dep_req_information(nfc_tech_isodep_target_t *pIsodepTarget, ac_buffer_t *pReq, bool moreInformation, uint8_t blockNumber); 00088 static void dep_req_response(nfc_tech_isodep_target_t *pIsodepTarget, bool ack, uint8_t blockNumber); 00089 static void dep_req_supervisory(nfc_tech_isodep_target_t *pIsodepTarget, bool wtxNDeselect, uint8_t wtxm); 00090 00091 static dep_type_t dep_res_type(nfc_tech_isodep_target_t *pIsodepTarget); 00092 static void dep_res_information(nfc_tech_isodep_target_t *pIsodepTarget, size_t maxLength, ac_buffer_t **ppRes, bool *pMoreInformation, uint8_t *pBlockNumber); 00093 static void dep_res_response(nfc_tech_isodep_target_t *pIsodepTarget, bool *pAck, uint8_t *pBlockNumber); 00094 static void dep_res_supervisory(nfc_tech_isodep_target_t *pIsodepTarget, bool *pWtxNDeselect, uint8_t *pWtxm); 00095 00096 static void dep_disconnected(nfc_tech_isodep_target_t *pIsodepTarget, bool deselected); 00097 00098 static void command_init(nfc_tech_isodep_target_t *pIsodepTarget); 00099 00100 static nfc_err_t command_ats_req(nfc_tech_isodep_target_t *pIsodepTarget); 00101 static nfc_err_t command_dep_req(nfc_tech_isodep_target_t *pIsodepTarget); 00102 00103 static nfc_err_t command_ats_res(nfc_tech_isodep_target_t *pIsodepTarget); 00104 static nfc_err_t command_dep_res(nfc_tech_isodep_target_t *pIsodepTarget); 00105 00106 static void command_reply(nfc_tech_isodep_target_t *pIsodepTarget, bool depWait); 00107 static void command_transceiver_cb(nfc_transceiver_t *pTransceiver, nfc_err_t ret, void *pUserData); 00108 00109 //High-level Target functions 00110 void nfc_tech_isodep_target_init(nfc_tech_isodep_target_t *pIsodepTarget, nfc_transceiver_t *pTransceiver, 00111 ac_buffer_t *pHist, nfc_tech_isodep_disconnected_cb disconnectedCb, void *pUserData) 00112 { 00113 pIsodepTarget->pTransceiver = pTransceiver; 00114 00115 pIsodepTarget->pHist = pHist; 00116 00117 pIsodepTarget->disconnectedCb = disconnectedCb; 00118 pIsodepTarget->pUserData = pUserData; 00119 00120 dep_init(pIsodepTarget); 00121 command_init(pIsodepTarget); 00122 } 00123 00124 nfc_err_t nfc_tech_isodep_target_connect(nfc_tech_isodep_target_t *pIsodepTarget) 00125 { 00126 NFC_DBG("Connecting"); 00127 pIsodepTarget->commands.state = ISO_DEP_TARGET_COMMANDS_CONNECTING; 00128 00129 transceiver_set_crc(pIsodepTarget->pTransceiver, true, true); 00130 command_transceiver_cb(pIsodepTarget->pTransceiver, NFC_OK, pIsodepTarget); 00131 00132 return NFC_OK; 00133 } 00134 00135 void nfc_tech_isodep_target_disconnect(nfc_tech_isodep_target_t *pIsodepTarget) 00136 { 00137 // This should not be called within a callback 00138 00139 transceiver_abort(pIsodepTarget->pTransceiver); 00140 00141 dep_disconnected(pIsodepTarget, false); 00142 } 00143 00144 nfc_err_t nfc_tech_isodep_target_transmit(nfc_tech_isodep_target_t *pIsodepTarget, ac_istream_t *pStream, nfc_tech_isodep_cb_t cb, void *pUserData) 00145 { 00146 if (pIsodepTarget->dep.pReqStream != NULL) { 00147 return NFC_ERR_BUSY; 00148 } 00149 00150 pIsodepTarget->dep.pResStream = pStream; 00151 pIsodepTarget->dep.resCb = cb; 00152 pIsodepTarget->dep.pResUserData = pUserData; 00153 00154 //Do we need to start transceiving? 00155 if (pIsodepTarget->commands.state == ISO_DEP_TARGET_COMMANDS_DEP_REQ_RECVD) { 00156 command_reply(pIsodepTarget, false); //Force reply 00157 } 00158 00159 return NFC_OK; 00160 } 00161 00162 nfc_err_t nfc_tech_isodep_target_receive(nfc_tech_isodep_target_t *pIsodepTarget, ac_ostream_t *pStream, nfc_tech_isodep_cb_t cb, void *pUserData) 00163 { 00164 if (pIsodepTarget->dep.pResStream != NULL) { 00165 return NFC_ERR_BUSY; 00166 } 00167 00168 pIsodepTarget->dep.pReqStream = pStream; 00169 pIsodepTarget->dep.reqCb = cb; 00170 pIsodepTarget->dep.pReqUserData = pUserData; 00171 00172 return NFC_OK; 00173 } 00174 00175 //DEP Layer 00176 void dep_init(nfc_tech_isodep_target_t *pIsodepTarget) 00177 { 00178 //ac_buffer_init(&pIsodepTarget->dep.res, NULL, 0); 00179 pIsodepTarget->dep.pReqStream = NULL; 00180 pIsodepTarget->dep.pResStream = NULL; 00181 00182 pIsodepTarget->dep.reqCb = NULL; 00183 pIsodepTarget->dep.pReqUserData = NULL; 00184 00185 pIsodepTarget->dep.resCb = NULL; 00186 pIsodepTarget->dep.pResUserData = NULL; 00187 00188 pIsodepTarget->dep.blockNumber = 1; //Rule C 00189 00190 //pIsodepTarget->dep.pduState = ISO_DEP_TARGET_DEP_PDU_IDLE; 00191 pIsodepTarget->dep.chaining = false; 00192 pIsodepTarget->dep.frameState = ISO_DEP_TARGET_DEP_FRAME_IDLE; 00193 } 00194 00195 bool dep_ready(nfc_tech_isodep_target_t *pIsodepTarget) 00196 { 00197 //Anything to send back? 00198 if (pIsodepTarget->dep.frameState != ISO_DEP_TARGET_DEP_FRAME_INFORMATION_RECEIVED) { 00199 return true; 00200 } 00201 00202 if ((pIsodepTarget->dep.pResStream != NULL)) { 00203 return true; 00204 } else { 00205 return false; 00206 } 00207 } 00208 00209 void dep_req_information(nfc_tech_isodep_target_t *pIsodepTarget, ac_buffer_t *pReq, bool moreInformation, uint8_t blockNumber) 00210 { 00211 (void) blockNumber; 00212 00213 pIsodepTarget->dep.blockNumber++; 00214 pIsodepTarget->dep.blockNumber %= 2; 00215 00216 // Note: callbacks can call nfc_tech_isodep_target_transmit() - however we must make sure that we wait AFTER this routine has been processed to actually transmit 00217 // To do so, reset state to ATS_RES_SENT state 00218 pIsodepTarget->commands.state = ISO_DEP_TARGET_COMMANDS_ATS_RES_SENT; 00219 00220 if (!pIsodepTarget->dep.chaining 00221 && (pIsodepTarget->dep.pResStream != NULL)) { 00222 //Sent the full frame 00223 pIsodepTarget->dep.pResStream = NULL; 00224 pIsodepTarget->dep.resCb((nfc_tech_isodep_t *)pIsodepTarget, NFC_OK, pIsodepTarget->dep.pResUserData); 00225 } 00226 if (pIsodepTarget->dep.pReqStream != NULL) { 00227 // Pull more 00228 ac_ostream_push(pIsodepTarget->dep.pReqStream, pReq, !moreInformation); 00229 if (!moreInformation) { 00230 //Got the full frame 00231 pIsodepTarget->dep.pReqStream = NULL; 00232 pIsodepTarget->dep.reqCb((nfc_tech_isodep_t *)pIsodepTarget, NFC_OK, pIsodepTarget->dep.pReqUserData); 00233 } 00234 } 00235 00236 // Update state 00237 pIsodepTarget->dep.frameState = ISO_DEP_TARGET_DEP_FRAME_INFORMATION_RECEIVED; 00238 pIsodepTarget->dep.chaining = moreInformation; 00239 } 00240 00241 void dep_req_response(nfc_tech_isodep_target_t *pIsodepTarget, bool ack, uint8_t blockNumber) 00242 { 00243 if (blockNumber != pIsodepTarget->dep.blockNumber) { 00244 //Should be NACK 00245 pIsodepTarget->dep.frameState = ISO_DEP_TARGET_DEP_FRAME_NACK_DIFF_BLOCK_NUMBER_RECEIVED; 00246 } else { 00247 if (ack) { 00248 pIsodepTarget->dep.frameState = ISO_DEP_TARGET_DEP_FRAME_ACK_RECEIVED; 00249 } else { 00250 pIsodepTarget->dep.frameState = ISO_DEP_TARGET_DEP_FRAME_NACK_RECEIVED; 00251 } 00252 } 00253 } 00254 00255 void dep_req_supervisory(nfc_tech_isodep_target_t *pIsodepTarget, bool wtxNDeselect, uint8_t wtxm) 00256 { 00257 (void) wtxm; 00258 00259 if (wtxNDeselect) { 00260 if ((pIsodepTarget->dep.frameState != ISO_DEP_TARGET_DEP_FRAME_WTX_SENT)) { 00261 NFC_WARN("Unexpected WTX frame"); 00262 } 00263 pIsodepTarget->dep.frameState = ISO_DEP_TARGET_DEP_FRAME_WTX_RECEIVED; 00264 } else { 00265 pIsodepTarget->dep.frameState = ISO_DEP_TARGET_DEP_FRAME_DESELECT_RECEIVED; 00266 } 00267 } 00268 00269 dep_type_t dep_res_type(nfc_tech_isodep_target_t *pIsodepTarget) 00270 { 00271 dep_type_t depType; 00272 switch (pIsodepTarget->dep.frameState) { 00273 case ISO_DEP_TARGET_DEP_FRAME_DESELECT_RECEIVED: 00274 depType = dep_type_supervisory; //Deselect 00275 break; 00276 case ISO_DEP_TARGET_DEP_FRAME_INFORMATION_RECEIVED: 00277 case ISO_DEP_TARGET_DEP_FRAME_WTX_RECEIVED: 00278 if (pIsodepTarget->dep.chaining) { //Need to ack? 00279 depType = dep_type_response; 00280 } else if (pIsodepTarget->dep.pResStream != NULL) { //Anything to send back? 00281 depType = dep_type_information; 00282 } else { 00283 depType = dep_type_supervisory; //WTX 00284 } 00285 break; 00286 case ISO_DEP_TARGET_DEP_FRAME_ACK_RECEIVED: 00287 if ((pIsodepTarget->dep.pResStream != NULL) && (pIsodepTarget->dep.chaining)) { 00288 depType = dep_type_information; 00289 } else { 00290 depType = dep_type_supervisory; //WTX 00291 } 00292 break; 00293 case ISO_DEP_TARGET_DEP_FRAME_NACK_DIFF_BLOCK_NUMBER_RECEIVED: 00294 depType = dep_type_response; //Should send ACK 00295 break; 00296 case ISO_DEP_TARGET_DEP_FRAME_NACK_RECEIVED: 00297 depType = dep_type_information; 00298 break; 00299 default: 00300 depType = dep_type_supervisory; //ATN 00301 break; 00302 } 00303 return depType; 00304 } 00305 00306 void dep_res_information(nfc_tech_isodep_target_t *pIsodepTarget, size_t maxLength, ac_buffer_t **ppRes, bool *pMoreInformation, uint8_t *pBlockNumber) 00307 { 00308 *pBlockNumber = pIsodepTarget->dep.blockNumber; 00309 if (pIsodepTarget->dep.frameState != ISO_DEP_TARGET_DEP_FRAME_NACK_RECEIVED) { 00310 if (pIsodepTarget->dep.pResStream != NULL) { 00311 bool lastFrame = true; 00312 ac_istream_pull(pIsodepTarget->dep.pResStream, &pIsodepTarget->dep.res, &lastFrame, maxLength); 00313 pIsodepTarget->dep.chaining = !lastFrame; 00314 } 00315 } else { 00316 //Retransmit previous frame (leave it as it is) 00317 } 00318 *ppRes = &pIsodepTarget->dep.res; 00319 *pMoreInformation = pIsodepTarget->dep.chaining; 00320 pIsodepTarget->dep.frameState = ISO_DEP_TARGET_DEP_FRAME_INFORMATION_SENT; 00321 } 00322 00323 void dep_res_response(nfc_tech_isodep_target_t *pIsodepTarget, bool *pAck, uint8_t *pBlockNumber) 00324 { 00325 //Continue chaining or send ACK 00326 *pAck = true; 00327 *pBlockNumber = pIsodepTarget->dep.blockNumber; 00328 pIsodepTarget->dep.frameState = ISO_DEP_TARGET_DEP_FRAME_ACK_SENT; 00329 } 00330 00331 void dep_res_supervisory(nfc_tech_isodep_target_t *pIsodepTarget, bool *pWtxNDeselect, uint8_t *pWtxm) 00332 { 00333 if (pIsodepTarget->dep.frameState == ISO_DEP_TARGET_DEP_FRAME_DESELECT_RECEIVED) { 00334 *pWtxNDeselect = false; 00335 pIsodepTarget->dep.frameState = ISO_DEP_TARGET_DEP_FRAME_DESELECT_SENT; 00336 } else { 00337 *pWtxNDeselect = true; 00338 *pWtxm = WTXM_DEFAULT; 00339 pIsodepTarget->dep.frameState = ISO_DEP_TARGET_DEP_FRAME_WTX_SENT; 00340 } 00341 } 00342 00343 void dep_disconnected(nfc_tech_isodep_target_t *pIsodepTarget, bool deselected) 00344 { 00345 //Call callbacks if needed 00346 if (pIsodepTarget->dep.pReqStream != NULL) { 00347 pIsodepTarget->dep.reqCb((nfc_tech_isodep_t *)pIsodepTarget, NFC_ERR_DISCONNECTED, pIsodepTarget->dep.pReqUserData); 00348 pIsodepTarget->dep.pReqStream = NULL; 00349 } 00350 if (pIsodepTarget->dep.pReqStream != NULL) { 00351 pIsodepTarget->dep.resCb((nfc_tech_isodep_t *)pIsodepTarget, NFC_ERR_DISCONNECTED, pIsodepTarget->dep.pResUserData); 00352 pIsodepTarget->dep.pResStream = NULL; 00353 } 00354 if (pIsodepTarget->commands.state != ISO_DEP_TARGET_COMMANDS_DISCONNECTED) { 00355 pIsodepTarget->commands.state = ISO_DEP_TARGET_COMMANDS_DISCONNECTED; 00356 pIsodepTarget->disconnectedCb((nfc_tech_isodep_t *)pIsodepTarget, deselected, pIsodepTarget->pUserData); 00357 } 00358 } 00359 00360 //Commands Layer 00361 void command_init(nfc_tech_isodep_target_t *pIsodepTarget) 00362 { 00363 ac_buffer_builder_init(&pIsodepTarget->commands.respBldr, pIsodepTarget->commands.respBuf, sizeof(pIsodepTarget->commands.respBuf)); 00364 pIsodepTarget->commands.pReq = NULL; 00365 // Update if/when we support DIDs 00366 //pIsodepTarget->commands.did = 0; 00367 //pIsodepTarget->commands.didUsed = false; 00368 pIsodepTarget->commands.state = ISO_DEP_TARGET_COMMANDS_DISCONNECTED; 00369 pIsodepTarget->commands.inPayloadSize = 0; 00370 } 00371 00372 nfc_err_t command_ats_req(nfc_tech_isodep_target_t *pIsodepTarget) 00373 { 00374 //Check we are in a correct state -- this should be the first command received 00375 if (pIsodepTarget->commands.state != ISO_DEP_TARGET_COMMANDS_CONNECTING) { 00376 return NFC_ERR_PROTOCOL; 00377 } 00378 00379 if (ac_buffer_reader_readable(pIsodepTarget->commands.pReq) < 2) { 00380 NFC_ERR("Payload too short"); 00381 return NFC_ERR_PROTOCOL; 00382 } 00383 00384 ac_buffer_read_n_skip(pIsodepTarget->commands.pReq, 1); 00385 00386 uint8_t b = ac_buffer_read_nu8(pIsodepTarget->commands.pReq); 00387 00388 //Save DID -- not supported for now 00389 //pIsodepTarget->commands.did = DID(b); 00390 00391 uint8_t fsdi = FSDI(b); 00392 pIsodepTarget->commands.inPayloadSize = FSDI_TO_FSD(fsdi); 00393 00394 pIsodepTarget->commands.state = ISO_DEP_TARGET_COMMANDS_ATS_REQ_RECVD; 00395 00396 return NFC_OK; 00397 } 00398 00399 nfc_err_t command_dep_req(nfc_tech_isodep_target_t *pIsodepTarget) 00400 { 00401 if (pIsodepTarget->commands.state < ISO_DEP_TARGET_COMMANDS_ATS_RES_SENT) { 00402 return NFC_ERR_PROTOCOL; 00403 } 00404 00405 if (ac_buffer_reader_readable(pIsodepTarget->commands.pReq) < 1) { 00406 NFC_ERR("Payload too short"); 00407 return NFC_ERR_PROTOCOL; 00408 } 00409 00410 uint8_t pcb = ac_buffer_read_nu8(pIsodepTarget->commands.pReq); 00411 00412 // Udpate if/when we support DIDs 00413 /* 00414 if( pfb & PFB_DID ) 00415 { 00416 uint8_t did = ac_buffer_read_nu8(pIsodepTarget->commands.pReq); 00417 if( pIsodepTarget->commands.did != did ) 00418 { 00419 //Not for us 00420 return NFC_ERR_PROTOCOL; 00421 } 00422 pIsodepTarget->commands.didUsed = true; 00423 } 00424 else 00425 { 00426 pIsodepTarget->commands.didUsed = false; 00427 } 00428 00429 if( pfb & PFB_NAD ) 00430 { 00431 ac_buffer_read_nu8(pIsodepTarget->commands.pReq); //Skip NAD 00432 } 00433 */ 00434 00435 uint8_t wtxm = 0; 00436 switch (PCB_TYPE(pcb)) { 00437 case I_BLOCK_PCB: 00438 dep_req_information(pIsodepTarget, pIsodepTarget->commands.pReq, PCB_CHAINING(pcb), PCB_BLOCK_TOGGLE(pcb)); 00439 break; 00440 case R_BLOCK_PCB: 00441 dep_req_response(pIsodepTarget, !PCB_NACK(pcb), PCB_BLOCK_TOGGLE(pcb)); 00442 break; 00443 case S_BLOCK_PCB: 00444 if (PCB_WTX(pcb)) { 00445 if (ac_buffer_reader_readable(pIsodepTarget->commands.pReq) < 1) { 00446 NFC_ERR("Payload too short"); 00447 return NFC_ERR_PROTOCOL; 00448 } 00449 wtxm = ac_buffer_read_nu8(pIsodepTarget->commands.pReq); 00450 } 00451 dep_req_supervisory(pIsodepTarget, PCB_WTX(pcb), wtxm); 00452 break; 00453 default: 00454 NFC_ERR("PCB is invalid"); 00455 return NFC_ERR_PROTOCOL; 00456 } 00457 00458 pIsodepTarget->commands.state = ISO_DEP_TARGET_COMMANDS_DEP_REQ_RECVD; 00459 00460 return NFC_OK; 00461 } 00462 00463 nfc_err_t command_ats_res(nfc_tech_isodep_target_t *pIsodepTarget) 00464 { 00465 //Send ATS back 00466 if (ac_buffer_builder_writable(&pIsodepTarget->commands.respBldr) < 5) { 00467 return NFC_ERR_BUFFER_TOO_SMALL; 00468 } 00469 00470 ac_buffer_builder_write_nu8(&pIsodepTarget->commands.respBldr, (5 + ac_buffer_size(pIsodepTarget->pHist)) & 0xFF); 00471 00472 //T0 00473 ac_buffer_builder_write_nu8(&pIsodepTarget->commands.respBldr, (0x7 << 4) | FSC_TO_FSCI(FSC)); //TA(1), TB(1) and TC(1) are transmitted 00474 00475 //TA(1) 00476 //For now only 106kbps supported 00477 ac_buffer_builder_write_nu8(&pIsodepTarget->commands.respBldr, (1 << 7) | (0x0 << 4) | 0x0); 00478 00479 //TODO when supporting other bitrates 00480 //ac_buffer_builder_write_nu8(&pIsodepTarget->commands.respBldr, (0 << 7) | (0x3 << 4) | 0x3); //106, 212, 414 kbps bitrates 00481 00482 //TB(1) 00483 ac_buffer_builder_write_nu8(&pIsodepTarget->commands.respBldr, (FWI << 4) | SFGI); //Specify guard-time and time between frames 00484 00485 //TC(1) 00486 ac_buffer_builder_write_nu8(&pIsodepTarget->commands.respBldr, (0 << 1) | 0); //DID not supported, NAD not supported 00487 00488 ac_buffer_set_next(ac_buffer_builder_buffer(&pIsodepTarget->commands.respBldr), pIsodepTarget->pHist); //Queue general bytes 00489 00490 pIsodepTarget->commands.state = ISO_DEP_TARGET_COMMANDS_ATS_RES_SENT; 00491 00492 //TODO PPS 00493 00494 return NFC_OK; 00495 } 00496 00497 nfc_err_t command_dep_res(nfc_tech_isodep_target_t *pIsodepTarget) 00498 { 00499 uint8_t pcb = 0; 00500 00501 // If/when supporting DIDs 00502 /* 00503 if( pIsodepTarget->commands.didUsed ) 00504 { 00505 pcb |= PFB_DID; 00506 }*/ 00507 00508 ac_buffer_t *pDepBuf = NULL; 00509 bool moreInformation = false; 00510 bool ack = false; 00511 bool wtxNDeselect = false; 00512 uint8_t wtxm = 0; 00513 uint8_t blockNumber = 0; 00514 00515 size_t maxLength = pIsodepTarget->commands.inPayloadSize - 1; 00516 00517 switch (dep_res_type(pIsodepTarget)) { 00518 case dep_type_information: 00519 dep_res_information(pIsodepTarget, maxLength, &pDepBuf, &moreInformation, &blockNumber); 00520 pcb = BUILD_I_BLOCK_PCB(moreInformation, false, false, blockNumber); 00521 break; 00522 case dep_type_response: 00523 dep_res_response(pIsodepTarget, &ack, &blockNumber); 00524 pcb = BUILD_R_BLOCK_PCB(0, blockNumber, !ack); 00525 break; 00526 case dep_type_supervisory: 00527 dep_res_supervisory(pIsodepTarget, &wtxNDeselect, &wtxm); 00528 pcb = BUILD_S_BLOCK_PCB(0, wtxNDeselect); 00529 break; 00530 } 00531 00532 ac_buffer_builder_write_nu8(&pIsodepTarget->commands.respBldr, pcb); 00533 /* 00534 if( pIsodepTarget->commands.didUsed ) 00535 { 00536 ac_buffer_builder_write_nu8(&pIsodepTarget->commands.respBldr, pIsodepTarget->commands.did); 00537 } 00538 */ 00539 if (pDepBuf != NULL) { 00540 ac_buffer_set_next(ac_buffer_builder_buffer(&pIsodepTarget->commands.respBldr), pDepBuf); 00541 } else if (wtxNDeselect) { 00542 ac_buffer_builder_write_nu8(&pIsodepTarget->commands.respBldr, wtxm); 00543 } 00544 00545 pIsodepTarget->commands.state = ISO_DEP_TARGET_COMMANDS_DEP_RES_SENT; 00546 00547 return NFC_OK; 00548 } 00549 00550 void command_reply(nfc_tech_isodep_target_t *pIsodepTarget, bool depWait) 00551 { 00552 nfc_err_t ret; 00553 00554 //Check whether we want to reply or wait for the higher layer to send us something 00555 if ((pIsodepTarget->commands.state == ISO_DEP_TARGET_COMMANDS_DEP_REQ_RECVD) && depWait && !dep_ready(pIsodepTarget)) { 00556 return; 00557 } 00558 00559 //Reply 00560 ac_buffer_builder_reset(&pIsodepTarget->commands.respBldr); 00561 00562 switch (pIsodepTarget->commands.state) { 00563 case ISO_DEP_TARGET_COMMANDS_ATS_REQ_RECVD: 00564 ret = command_ats_res(pIsodepTarget); 00565 break; 00566 case ISO_DEP_TARGET_COMMANDS_DEP_REQ_RECVD: 00567 ret = command_dep_res(pIsodepTarget); 00568 break; 00569 default: 00570 NFC_ERR("Unknown state %d", pIsodepTarget->commands.state); 00571 //Go back to receive mode 00572 nfc_transceiver_transceive(pIsodepTarget->pTransceiver, command_transceiver_cb, pIsodepTarget); 00573 return; 00574 } 00575 00576 if (ret) { 00577 NFC_ERR("Error %d", ret); 00578 //Go back to receive mode 00579 nfc_transceiver_transceive(pIsodepTarget->pTransceiver, command_transceiver_cb, pIsodepTarget); 00580 return; 00581 } 00582 00583 NFC_DBG("Transceive"); 00584 00585 if (pIsodepTarget->dep.frameState == ISO_DEP_TARGET_DEP_FRAME_DESELECT_SENT) { 00586 transceiver_set_transceive_options(pIsodepTarget->pTransceiver, true, false, true); 00587 } else { 00588 transceiver_set_transceive_options(pIsodepTarget->pTransceiver, true, true, false); 00589 } 00590 00591 NFC_DBG_BLOCK(ac_buffer_dump(ac_buffer_builder_buffer(&pIsodepTarget->commands.respBldr));) 00592 00593 //Send next frame 00594 transceiver_set_write(pIsodepTarget->pTransceiver, ac_buffer_builder_buffer(&pIsodepTarget->commands.respBldr)); 00595 nfc_transceiver_transceive(pIsodepTarget->pTransceiver, command_transceiver_cb, pIsodepTarget); 00596 00597 NFC_DBG("Processed"); 00598 } 00599 00600 void command_transceiver_cb(nfc_transceiver_t *pTransceiver, nfc_err_t ret, void *pUserData) 00601 { 00602 nfc_tech_isodep_target_t *pIsodepTarget = (nfc_tech_isodep_target_t *) pUserData; 00603 00604 if (ret == NFC_ERR_ABORTED) { 00605 // Just return 00606 return; 00607 } 00608 00609 if (pIsodepTarget->dep.frameState == ISO_DEP_TARGET_DEP_FRAME_DESELECT_SENT) { 00610 NFC_DBG("Deselect sent and re-polled: %u", ret); 00611 //We are now disconnected (deselected) 00612 //Reset status 00613 dep_init(pIsodepTarget); 00614 command_init(pIsodepTarget); 00615 00616 transceiver_set_crc(pIsodepTarget->pTransceiver, true, true); 00617 pIsodepTarget->commands.state = ISO_DEP_TARGET_COMMANDS_CONNECTING; 00618 00619 //Call so that we can reinit higher layer 00620 dep_disconnected(pIsodepTarget, true); //This will call us again 00621 return; 00622 } 00623 00624 //Prepare default empty reply 00625 transceiver_set_write(pTransceiver, NULL); 00626 transceiver_set_transceive_options(pTransceiver, false, true, false); 00627 00628 if (ret == NFC_ERR_FIELD) { 00629 NFC_WARN("Lost initiator"); 00630 dep_disconnected(pIsodepTarget, false); 00631 return; 00632 } else if (ret) { 00633 //We should ignore this error and wait for another frame 00634 NFC_WARN("Got invalid frame (error %d)", ret); 00635 00636 nfc_transceiver_transceive(pTransceiver, command_transceiver_cb, pIsodepTarget); 00637 return; 00638 } 00639 00640 NFC_DBG("Reading data from initiator"); 00641 ac_buffer_t *pDataInitiator = transceiver_get_read(pTransceiver); //In buffer 00642 00643 NFC_DBG_BLOCK(ac_buffer_dump(pDataInitiator);) 00644 00645 //Framing is handled by transceiver 00646 if ((ac_buffer_reader_readable(pDataInitiator) < 1)) { 00647 NFC_ERR("Empty initiator message"); 00648 00649 //Go back to receive mode 00650 nfc_transceiver_transceive(pTransceiver, command_transceiver_cb, pIsodepTarget); 00651 return; 00652 } 00653 00654 pIsodepTarget->commands.pReq = pDataInitiator; 00655 00656 //Duplicate to peek on req 00657 ac_buffer_t dataInitiatorDup; 00658 ac_buffer_dup(&dataInitiatorDup, pDataInitiator); 00659 uint8_t req = ac_buffer_read_nu8(&dataInitiatorDup); 00660 00661 switch (req) { 00662 case RATS: 00663 ret = command_ats_req(pIsodepTarget); 00664 break; 00665 default: 00666 ret = command_dep_req(pIsodepTarget); 00667 break; 00668 } 00669 00670 if (ret) { 00671 NFC_ERR("Error %d", ret); 00672 00673 //Go back to receive mode 00674 nfc_transceiver_transceive(pTransceiver, command_transceiver_cb, pIsodepTarget); 00675 return; 00676 } 00677 00678 NFC_DBG("Reply"); 00679 00680 //Reply 00681 command_reply(pIsodepTarget, true); //Make sure we send a WTX frame if we cannot respond straight away 00682 } 00683 00684 00685
Generated on Tue Jul 12 2022 13:54:25 by
1.7.2