| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741 |
- /******************************************************************************
- * \attention
- *
- * <h2><center>© COPYRIGHT 2020 STMicroelectronics</center></h2>
- *
- * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
- * You may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * www.st.com/myliberty
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
- * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************************/
- /*
- * PROJECT: NFCC firmware
- * LANGUAGE: ISO C99
- */
- /*! \file rfal_nfcDep.c
- *
- * \author Gustavo Patricio
- *
- * \brief Implementation of NFC-DEP protocol
- *
- * NFC-DEP is also known as NFCIP - Near Field Communication
- * Interface and Protocol
- *
- * This implementation was based on the following specs:
- * - NFC Forum Digital 1.1
- * - ECMA 340 3rd Edition 2013
- *
- */
- /*
- ******************************************************************************
- * INCLUDES
- ******************************************************************************
- */
- #include "../include/rfal_nfcDep.h"
- #include "../include/rfal_nfcf.h"
- #include "../utils.h"
- /*
- ******************************************************************************
- * ENABLE SWITCH
- ******************************************************************************
- */
- #if RFAL_FEATURE_NFC_DEP
- /* Check for valid Block/Payload length Digital 2.0 Table 90*/
- #if((RFAL_FEATURE_NFC_DEP_BLOCK_MAX_LEN != 64) && (RFAL_FEATURE_NFC_DEP_BLOCK_MAX_LEN != 128) && \
- (RFAL_FEATURE_NFC_DEP_BLOCK_MAX_LEN != 192) && (RFAL_FEATURE_NFC_DEP_BLOCK_MAX_LEN != 254))
- #error \
- " RFAL: Invalid NFC-DEP Block Max length. Please change RFAL_FEATURE_NFC_DEP_BLOCK_MAX_LEN. "
- #endif
- /* Check for valid PDU length */
- #if((RFAL_FEATURE_NFC_DEP_PDU_MAX_LEN < RFAL_FEATURE_NFC_DEP_BLOCK_MAX_LEN))
- #error " RFAL: Invalid NFC-DEP PDU Max length. Please change RFAL_FEATURE_NFC_DEP_PDU_MAX_LEN. "
- #endif
- /*
- ******************************************************************************
- * DEFINES
- ******************************************************************************
- */
- #define NFCIP_ATR_RETRY_MAX 2U /*!< Max consecutive retrys of an ATR REQ with transm error*/
- #define NFCIP_PSLPAY_LEN (2U) /*!< PSL Payload length (BRS + FSL) */
- #define NFCIP_PSLREQ_LEN \
- (3U + RFAL_NFCDEP_LEN_LEN) /*!< PSL REQ length (incl LEN) */
- #define NFCIP_PSLRES_LEN \
- (3U + RFAL_NFCDEP_LEN_LEN) /*!< PSL RES length (incl LEN) */
- #define NFCIP_ATRREQ_BUF_LEN \
- (RFAL_NFCDEP_ATRREQ_MAX_LEN + RFAL_NFCDEP_LEN_LEN) /*!< ATR REQ max length (incl LEN) */
- #define NFCIP_ATRRES_BUF_LEN \
- (RFAL_NFCDEP_ATRRES_MAX_LEN + RFAL_NFCDEP_LEN_LEN) /*!< ATR RES max length (incl LEN) */
- #define NFCIP_RLSREQ_LEN \
- (3U + RFAL_NFCDEP_LEN_LEN) /*!< RLS REQ length (incl LEN) */
- #define NFCIP_RLSRES_LEN \
- (3U + RFAL_NFCDEP_LEN_LEN) /*!< RSL RES length (incl LEN) */
- #define NFCIP_RLSRES_MIN \
- (2U + RFAL_NFCDEP_LEN_LEN) /*!< Minimum length for a RLS RES (incl LEN) */
- #define NFCIP_DSLREQ_LEN \
- (3U + RFAL_NFCDEP_LEN_LEN) /*!< DSL REQ length (incl LEN) */
- #define NFCIP_DSLRES_LEN \
- (3U + RFAL_NFCDEP_LEN_LEN) /*!< DSL RES length (incl LEN) */
- #define NFCIP_DSLRES_MIN \
- (2U + RFAL_NFCDEP_LEN_LEN) /*!< Minimum length for a DSL RES (incl LEN) */
- #define NFCIP_DSLRES_MAX_LEN \
- (3U + RFAL_NFCDEP_LEN_LEN) /*!< Maximum length for a DSL RES (incl LEN) */
- #define NFCIP_RLSRES_MAX_LEN \
- (3U + RFAL_NFCDEP_LEN_LEN) /*!< Minimum length for a RLS RES (incl LEN) */
- #define NFCIP_TARGET_RES_MAX \
- (MAX(NFCIP_RLSRES_MAX_LEN, NFCIP_DSLRES_MAX_LEN)) /*!< Max target control res length */
- #define NFCIP_NO_FWT RFAL_FWT_NONE /*!< No FWT value - Target Mode */
- #define NFCIP_INIT_MIN_RTOX 1U /*!< Minimum RTOX value Digital 1.0 14.8.4.1 */
- #define NFCIP_INIT_MAX_RTOX 59U /*!< Maximum RTOX value Digital 1.0 14.8.4.1 */
- #define NFCIP_TARG_MIN_RTOX 1U /*!< Minimum target RTOX value Digital 1.0 14.8.4.1 */
- #define NFCIP_TARG_MAX_RTOX 59U /*!< Maximum target RTOX value Digital 1.0 14.8.4.1 */
- #define NFCIP_TRECOV 1280U /*!< Digital 1.0 A.10 Trecov */
- #define NFCIP_TIMEOUT_ADJUSTMENT \
- 3072U /*!< Timeout Adjustment to compensate timing from end of Tx to end of frame */
- #define NFCIP_RWT_ACTIVATION \
- (0x1000001U + \
- NFCIP_TIMEOUT_ADJUSTMENT) /*!< Digital 2.2 B.11 RWT ACTIVATION 2^24 + RWT Delta + Adjustment*/
- #define NFCIP_RWT_ACM_ACTIVATION \
- (0x200001U + \
- NFCIP_TIMEOUT_ADJUSTMENT) /*!< Digital 2.2 B.11 RWT ACTIVATION 2^21 + RWT Delta + Adjustment*/
- #define RFAL_NFCDEP_HEADER_PAD \
- (RFAL_NFCDEP_DEPREQ_HEADER_LEN - \
- RFAL_NFCDEP_LEN_MIN) /*!< Difference between expected rcvd header len and max foreseen */
- #ifndef RFAL_NFCDEP_MAX_TX_RETRYS
- #define RFAL_NFCDEP_MAX_TX_RETRYS \
- (uint8_t)3U /*!< Number of retransmit retyrs */
- #endif /* RFAL_NFCDEP_MAX_TX_RETRYS */
- #ifndef RFAL_NFCDEP_TO_RETRYS
- #define RFAL_NFCDEP_TO_RETRYS \
- (uint8_t)3U /*!< Number of retrys for Timeout */
- #endif /* RFAL_NFCDEP_TO_RETRYS */
- #ifndef RFAL_NFCDEP_MAX_RTOX_RETRYS
- #define RFAL_NFCDEP_MAX_RTOX_RETRYS \
- (uint8_t)10U /*!< Number of retrys for RTOX Digital 2.0 17.12.4.3 */
- #endif /* RFAL_NFCDEP_MAX_RTOX_RETRYS */
- #ifndef RFAL_NFCDEP_MAX_NACK_RETRYS
- #define RFAL_NFCDEP_MAX_NACK_RETRYS \
- (uint8_t)3U /*!< Number of retrys for NACK */
- #endif /* RFAL_NFCDEP_MAX_NACK_RETRYS */
- #ifndef RFAL_NFCDEP_MAX_ATN_RETRYS
- #define RFAL_NFCDEP_MAX_ATN_RETRYS \
- (uint8_t)3U /*!< Number of retrys for ATN */
- #endif /* RFAL_NFCDEP_MAX_ATN_RETRYS */
- #define NFCIP_MIN_TXERROR_LEN \
- 4U /*!< Minimum frame length with error to be ignored Digital 1.0 14.12.5.4 */
- #define NFCIP_REQ (uint8_t)0xD4U /*!<NFCIP REQuest code */
- #define NFCIP_RES (uint8_t)0xD5U /*!<NFCIP RESponce code */
- #define NFCIP_BS_MASK 0x0FU /*!< Bit mask for BS value on a ATR REQ/RES */
- #define NFCIP_BR_MASK NFCIP_BS_MASK /*!< Bit mask for BR value on a ATR REQ/RES */
- #define NFCIP_PP_GB_MASK 0x02U /*!< Bit mask for GB value in PP byte on a ATR REQ/RES */
- #define NFCIP_PP_NAD_MASK 0x01U /*!< Bit mask for NAD value in PP byte on a ATR REQ/RES */
- #define NFCIP_PFB_xPDU_MASK 0xE0U /*!< Bit mask for PDU type */
- #define NFCIP_PFB_IPDU 0x00U /*!< Bit mask indicating a Information PDU */
- #define NFCIP_PFB_RPDU 0x40U /*!< Bit mask indicating a Response PDU */
- #define NFCIP_PFB_SPDU 0x80U /*!< Bit mask indicating a Supervisory PDU */
- #define NFCIP_PFB_MI_BIT 0x10U /*!< Bit mask for the chaining bit (MI) of PFB */
- #define NFCIP_PFB_DID_BIT 0x04U /*!< Bit mask for the DID presence bit of PFB */
- #define NFCIP_PFB_NAD_BIT 0x08U /*!< Bit mask for the NAD presence bit of PFB */
- #define NFCIP_PFB_PNI_MASK 0x03U /*!< Bit mask for the Packet Number Information */
- #define NFCIP_PFB_Rx_MASK 0x10U /*!< Bit mask for the R-PDU type */
- #define NFCIP_PFB_ACK 0x00U /*!< Bit mask for R-PDU indicating ACK */
- #define NFCIP_PFB_NACK 0x10U /*!< Bit mask for R-PDU indicating NAK */
- #define NFCIP_PFB_Sx_MASK 0x10U /*!< Bit mask for the R-PDU type */
- #define NFCIP_PFB_ATN 0x00U /*!< Bit mask for R-PDU indicating ACK */
- #define NFCIP_PFB_TO 0x10U /*!< Bit mask for R-PDU indicating NAK */
- #define NFCIP_PFB_INVALID 0xFFU /*!< Invalid PFB value */
- /*
- ******************************************************************************
- * MACROS
- ******************************************************************************
- */
- #define nfcipIsTransmissionError(e) \
- (((e) == ERR_CRC) || ((e) == ERR_FRAMING) || \
- ((e) == ERR_PAR)) /*!< Checks if is a Trasmission error */
- #define nfcipConv1FcToMs(v) \
- (rfalConv1fcToMs((v)) + 1U) /*!< Converts value v 1fc into milliseconds (fc=13.56) */
- #define nfcipCmdIsReq(cmd) \
- (((uint8_t)(cmd) % 2U) == 0U) /*!< Checks if the nfcip cmd is a REQ */
- #define nfcip_PFBhasDID(pfb) \
- (((pfb) & NFCIP_PFB_DID_BIT) == \
- NFCIP_PFB_DID_BIT) /*!< Checks if pfb is signalling DID */
- #define nfcip_PFBhasNAD(pfb) \
- (((pfb) & NFCIP_PFB_NAD_BIT) == \
- NFCIP_PFB_NAD_BIT) /*!< Checks if pfb is signalling NAD */
- #define nfcip_PFBisIPDU(pfb) \
- (((pfb) & NFCIP_PFB_xPDU_MASK) == \
- NFCIP_PFB_IPDU) /*!< Checks if pfb is a Information PDU */
- #define nfcip_PFBisRPDU(pfb) \
- (((pfb) & NFCIP_PFB_xPDU_MASK) == \
- NFCIP_PFB_RPDU) /*!< Checks if pfb is Response PDU */
- #define nfcip_PFBisSPDU(pfb) \
- (((pfb) & NFCIP_PFB_xPDU_MASK) == \
- NFCIP_PFB_SPDU) /*!< Checks if pfb is a Supervisory PDU */
- #define nfcip_PFBisIMI(pfb) \
- (nfcip_PFBisIPDU(pfb) && \
- (((pfb) & NFCIP_PFB_MI_BIT) == \
- NFCIP_PFB_MI_BIT)) /*!< Checks if pfb is a Information PDU indicating MI chaining */
- #define nfcip_PFBisRNACK(pfb) \
- (nfcip_PFBisRPDU(pfb) && (((pfb) & NFCIP_PFB_Rx_MASK) == \
- NFCIP_PFB_NACK)) /*!< Checks if pfb is a R-PDU indicating NACK */
- #define nfcip_PFBisRACK(pfb) \
- (nfcip_PFBisRPDU(pfb) && (((pfb) & NFCIP_PFB_Rx_MASK) == \
- NFCIP_PFB_ACK)) /*!< Checks if pfb is a R-PDU indicating ACK */
- #define nfcip_PFBisSATN(pfb) \
- (nfcip_PFBisSPDU(pfb) && (((pfb) & NFCIP_PFB_Sx_MASK) == \
- NFCIP_PFB_ATN)) /*!< Checks if pfb is a R-PDU indicating ATN */
- #define nfcip_PFBisSTO(pfb) \
- (nfcip_PFBisSPDU(pfb) && (((pfb) & NFCIP_PFB_Sx_MASK) == \
- NFCIP_PFB_TO)) /*!< Checks if pfb is a R-PDU indicating TO */
- #define nfcip_PFBIPDU(pni) \
- ((uint8_t)(0x00U | NFCIP_PFB_IPDU | \
- ((pni) & \
- NFCIP_PFB_PNI_MASK))) /*!< Returns a PFB I-PDU with the given packet number (pni) */
- #define nfcip_PFBIPDU_MI(pni) \
- ((uint8_t)(isoDep_PCBIBlock(pni) | \
- NFCIP_PFB_MI_BIT)) /*!< Returns a PFB I-PDU with the given packet number (pni) indicating chaing */
- #define nfcip_PFBRPDU(pni) \
- ((uint8_t)(0x00U | NFCIP_PFB_RPDU | \
- ((pni) & \
- NFCIP_PFB_PNI_MASK))) /*!< Returns a PFB R-PDU with the given packet number (pni) */
- #define nfcip_PFBRPDU_NACK(pni) \
- ((uint8_t)(nfcip_PFBRPDU(pni) | \
- NFCIP_PFB_NACK)) /*!< Returns a PFB R-PDU with the given packet number (pni) indicating NACK */
- #define nfcip_PFBRPDU_ACK(pni) \
- ((uint8_t)(nfcip_PFBRPDU(pni) | \
- NFCIP_PFB_ACK)) /*!< Returns a PFB R-PDU with the given packet number (pni) indicating ACK */
- #define nfcip_PFBSPDU() \
- ((uint8_t)(0x00U | \
- NFCIP_PFB_SPDU)) /*!< Returns a PFB S-PDU */
- #define nfcip_PFBSPDU_ATN() \
- ((uint8_t)(nfcip_PFBSPDU() | \
- NFCIP_PFB_ATN)) /*!< Returns a PFB S-PDU indicating ATN */
- #define nfcip_PFBSPDU_TO() \
- ((uint8_t)(nfcip_PFBSPDU() | \
- NFCIP_PFB_TO)) /*!< Returns a PFB S-PDU indicating TO */
- #define nfcip_PNIInc(pni) \
- ((uint8_t)(((pni) + 1U) & \
- NFCIP_PFB_PNI_MASK)) /*!< Returns a incremented PNI from the given (pni) */
- #define nfcip_PNIDec(pni) \
- ((uint8_t)(((pni)-1U) & \
- NFCIP_PFB_PNI_MASK)) /*!< Returns a decremented PNI from the given (pni) */
- #define nfcip_PBF_PNI(pfb) \
- ((uint8_t)((pfb) & \
- NFCIP_PFB_PNI_MASK)) /*!< Returns the Packet Number Information (pni) */
- #define nfcip_PPwGB(lr) \
- (rfalNfcDepLR2PP(lr) | \
- NFCIP_PP_GB_MASK) /*!< Returns a PP byte containing the given PP value indicating GB */
- #define nfcip_DIDMax(did) \
- (MIN( \
- (did), \
- RFAL_NFCDEP_DID_MAX)) /*!< Ensures that the given did has proper value Digital 14.6.2.3 DID [0 14] */
- #define nfcip_RTOXTargMax(wt) \
- (uint8_t)(MIN( \
- (RFAL_NFCDEP_RWT_TRG_MAX / rfalNfcDepWT2RWT(wt)), \
- NFCIP_TARG_MAX_RTOX)) /*!< Calculates the Maximum RTOX value for the given wt as a Target */
- #define nfcipIsInitiator(st) \
- (((st) >= NFCIP_ST_INIT_IDLE) && \
- ((st) <= \
- NFCIP_ST_INIT_RLS)) /*!< Checks if module is set as Initiator */
- #define nfcipIsTarget(st) \
- (!nfcipIsInitiator( \
- st)) /*!< Checks if module is set as Target */
- #define nfcipIsBRAllowed(br, mBR) \
- (((1U << (br)) & (mBR)) != \
- 0U) /*!< Checks bit rate is allowed by given mask */
- #define nfcipIsEmptyDEPEnabled(op) \
- (!nfcipIsEmptyDEPDisabled( \
- op)) /*!< Checks if empty payload is allowed by operation config NCI 1.0 Table 81 */
- #define nfcipIsEmptyDEPDisabled(op) \
- (((op) & RFAL_NFCDEP_OPER_EMPTY_DEP_DIS) != \
- 0U) /*!< Checks if empty payload is not allowed by operation config NCI 1.0 Table 81 */
- #define nfcipIsRTOXReqEnabled(op) \
- (!nfcipIsRTOXReqDisabled( \
- op)) /*!< Checks if send a RTOX_REQ is allowed by operation config NCI 1.0 Table 81 */
- #define nfcipIsRTOXReqDisabled(op) \
- (((op) & RFAL_NFCDEP_OPER_RTOX_REQ_DIS) != \
- 0U) /*!< Checks if send a RTOX_REQ is not allowed by operation config NCI 1.0 Table 81 */
- /*! Checks if isDeactivating callback is set and calls it, otherwise returns false */
- #define nfcipIsDeactivationPending() \
- ((gNfcip.isDeactivating == NULL) ? false : gNfcip.isDeactivating())
- /*! Returns the RWT Activation according to the current communication mode */
- #define nfcipRWTActivation() \
- ((gNfcip.cfg.commMode == RFAL_NFCDEP_COMM_ACTIVE) ? NFCIP_RWT_ACM_ACTIVATION : \
- NFCIP_RWT_ACTIVATION)
- #define nfcipRTOXAdjust(v) \
- ((v) - ((v) >> 3)) /*!< Adjust RTOX timer value to a percentage of the total, current 88% */
- /*******************************************************************************/
- // timerPollTimeoutValue is necessary after timerCalculateTimeout so that system will wake up upon timer timeout.
- #define nfcipTimerStart(timer, time_ms) \
- do { \
- platformTimerDestroy(timer); \
- (timer) = platformTimerCreate((uint16_t)(time_ms)); \
- } while(0) /*!< Configures and starts the RTOX timer */
- #define nfcipTimerisExpired(timer) \
- platformTimerIsExpired(timer) /*!< Checks RTOX timer has expired */
- #define nfcipTimerDestroy(timer) \
- platformTimerDestroy(timer) /*!< Destroys RTOX timer */
- #define nfcipLogE(...) /*!< Macro for the error log method */
- #define nfcipLogW(...) /*!< Macro for the warning log method */
- #define nfcipLogI(...) /*!< Macro for the info log method */
- #define nfcipLogD(...) /*!< Macro for the debug log method */
- /*! Digital 1.1 - 16.12.5.2 The Target SHALL NOT attempt any error recovery and remains in Rx mode upon Transmission or a Protocol Error */
- #define nfcDepReEnableRx(rxB, rxBL, rxL) \
- rfalTransceiveBlockingTx( \
- NULL, \
- 0, \
- (rxB), \
- (rxBL), \
- (rxL), \
- (RFAL_TXRX_FLAGS_DEFAULT | (uint32_t)RFAL_TXRX_FLAGS_NFCIP1_ON), \
- RFAL_FWT_NONE)
- /*
- ******************************************************************************
- * LOCAL DATA TYPES
- ******************************************************************************
- */
- /*! Struct that holds all DEP parameters/configs for the following communications */
- typedef struct {
- uint8_t did; /*!< Device ID (DID) to be used */
- uint8_t* txBuf; /*!< Pointer to the Tx buffer to be sent */
- uint16_t txBufLen; /*!< Length of the data in the txBuf */
- uint8_t txBufPaylPos; /*!< Position inside txBuf where data starts */
- bool txChaining; /*!< Flag indicating chaining on transmission */
- uint8_t* rxBuf; /*!< Pointer to the Rx buffer for incoming data */
- uint16_t rxBufLen; /*!< Length of the data in the rxBuf */
- uint8_t rxBufPaylPos; /*!< Position inside rxBuf where data is to be placed*/
- uint32_t fwt; /*!< Frame Waiting Time (FWT) to be used */
- uint32_t dFwt; /*!< Delta Frame Waiting Time (dFWT) to be used */
- uint16_t fsc; /*!< Frame Size (FSC) to be used */
- } rfalNfcDepDEPParams;
- /*! NFCIP module states */
- typedef enum {
- NFCIP_ST_IDLE,
- NFCIP_ST_INIT_IDLE,
- NFCIP_ST_INIT_ATR,
- NFCIP_ST_INIT_PSL,
- NFCIP_ST_INIT_DEP_IDLE,
- NFCIP_ST_INIT_DEP_TX,
- NFCIP_ST_INIT_DEP_RX,
- NFCIP_ST_INIT_DEP_ATN,
- NFCIP_ST_INIT_DSL,
- NFCIP_ST_INIT_RLS,
- NFCIP_ST_TARG_WAIT_ATR,
- NFCIP_ST_TARG_WAIT_ACTV,
- NFCIP_ST_TARG_DEP_IDLE,
- NFCIP_ST_TARG_DEP_RX,
- NFCIP_ST_TARG_DEP_RTOX,
- NFCIP_ST_TARG_DEP_TX,
- NFCIP_ST_TARG_DEP_SLEEP
- } rfalNfcDepState;
- /*! NFCIP commands (Request, Response) */
- typedef enum {
- NFCIP_CMD_ATR_REQ = 0x00,
- NFCIP_CMD_ATR_RES = 0x01,
- NFCIP_CMD_WUP_REQ = 0x02,
- NFCIP_CMD_WUP_RES = 0x03,
- NFCIP_CMD_PSL_REQ = 0x04,
- NFCIP_CMD_PSL_RES = 0x05,
- NFCIP_CMD_DEP_REQ = 0x06,
- NFCIP_CMD_DEP_RES = 0x07,
- NFCIP_CMD_DSL_REQ = 0x08,
- NFCIP_CMD_DSL_RES = 0x09,
- NFCIP_CMD_RLS_REQ = 0x0A,
- NFCIP_CMD_RLS_RES = 0x0B
- } rfalNfcDepCmd;
- /*! Struct that holds all NFCIP data */
- typedef struct {
- rfalNfcDepConfigs cfg; /*!< Holds the current configuration to be used */
- rfalNfcDepState state; /*!< Current state of the NFCIP module */
- uint8_t pni; /*!< Packet Number Information (PNI) counter */
- uint8_t lastCmd; /*!< Last command sent */
- uint8_t lastPFB; /*!< Last PFB sent */
- uint8_t lastPFBnATN; /*!< Last PFB sent (excluding ATN) */
- uint8_t lastRTOX; /*!< Last RTOX value sent */
- uint8_t cntTxRetrys; /*!< Retransmissions counter */
- uint8_t cntTORetrys; /*!< Timeouts counter */
- uint8_t cntRTOXRetrys; /*!< RTOX counter */
- uint8_t cntNACKRetrys; /*!< NACK counter */
- uint8_t cntATNRetrys; /*!< Attention (ATN) counter */
- uint16_t fsc; /*!< Current Frame Size (FSC) to be used */
- bool isTxChaining; /*!< Flag for chaining on Transmission */
- bool isRxChaining; /*!< Flag for chaining on Reception */
- uint8_t* txBuf; /*!< Pointer to the Tx buffer to be sent */
- uint8_t* rxBuf; /*!< Pointer to the Rx buffer for incoming data */
- uint16_t txBufLen; /*!< Length of the data in the txBuf */
- uint16_t rxBufLen; /*!< Length of rxBuf buffer */
- uint16_t* rxRcvdLen; /*!< Length of the data in the rxBuf */
- uint8_t txBufPaylPos; /*!< Position in txBuf where data starts */
- uint8_t rxBufPaylPos; /*!< Position in rxBuf where data is to be placed */
- bool* isChaining; /*!< Flag for chaining on Reception */
- rfalNfcDepDevice* nfcDepDev; /*!< Pointer to NFC-DEP device info */
- uint32_t RTOXTimer; /*!< Timer used for RTOX */
- rfalNfcDepDeactCallback isDeactivating; /*!< Deactivating flag check callback */
- bool isReqPending; /*!< Flag pending REQ from Target activation */
- bool isTxPending; /*!< Flag pending DEP Block while waiting RTOX Ack */
- bool isWait4RTOX; /*!< Flag for waiting RTOX Ack */
- rfalNfcDepPduTxRxParam PDUParam; /*!< PDU TxRx params */
- uint16_t PDUTxPos; /*!< PDU Tx position */
- uint16_t PDURxPos; /*!< PDU Rx position */
- bool isPDURxChaining; /*!< PDU Transceive chaining flag */
- } rfalNfcDep;
- /*
- ******************************************************************************
- * LOCAL VARIABLES
- ******************************************************************************
- */
- static rfalNfcDep gNfcip; /*!< NFCIP module instance */
- /*
- ******************************************************************************
- * LOCAL FUNCTION PROTOTYPES
- ******************************************************************************
- */
- static ReturnCode nfcipTxRx(
- rfalNfcDepCmd cmd,
- uint8_t* txBuf,
- uint32_t fwt,
- uint8_t* paylBuf,
- uint8_t paylBufLen,
- uint8_t* rxBuf,
- uint16_t rxBufLen,
- uint16_t* rxActLen);
- static ReturnCode nfcipTx(
- rfalNfcDepCmd cmd,
- uint8_t* txBuf,
- uint8_t* paylBuf,
- uint16_t paylLen,
- uint8_t pfbData,
- uint32_t fwt);
- static ReturnCode nfcipDEPControlMsg(uint8_t pfb, uint8_t RTOX);
- static ReturnCode nfcipInitiatorHandleDEP(
- ReturnCode rxRes,
- uint16_t rxLen,
- uint16_t* outActRxLen,
- bool* outIsChaining);
- static ReturnCode
- nfcipTargetHandleRX(ReturnCode rxRes, uint16_t* outActRxLen, bool* outIsChaining);
- static ReturnCode nfcipTargetHandleActivation(rfalNfcDepDevice* nfcDepDev, uint8_t* outBRS);
- /*!
- ******************************************************************************
- * \brief NFCIP Configure
- *
- * Configures the nfcip layer with the given configurations
- *
- * \param[in] cfg : nfcip configuration for following communication
- ******************************************************************************
- */
- static void nfcipConfig(const rfalNfcDepConfigs* cfg);
- /*!
- ******************************************************************************
- * \brief Set DEP parameters
- *
- * This method sets the parameters/configs for following Data Exchange
- * Sets the nfcip module state according to the role it is configured
- *
- *
- * \warning To be used only after proper Initiator/Target activation:
- * nfcipTargetHandleActivation() or nfcipInitiatorActivate() has
- * returned success
- *
- * This must be called before nfcipRun() in case of Target to pass
- * rxBuffer
- *
- * Everytime some data needs to be transmitted call this to set it and
- * call nfcipRun() until done or error
- *
- * \param[in] DEPParams : the parameters to be used during Data Exchange
- ******************************************************************************
- */
- static void nfcipSetDEPParams(const rfalNfcDepDEPParams* DEPParams);
- /*!
- ******************************************************************************
- * \brief NFCIP run protocol
- *
- * This method handles all the nfcip protocol during Data Exchange (DEP
- * requests and responses).
- *
- * A data exchange cycle is considered a DEP REQ and a DEP RES.
- *
- * In case of Tx chaining(MI) must signal it with nfcipSetDEPParams()
- * In case of Rx chaining(MI) outIsChaining will be set to true and the
- * current data returned
- *
- * \param[out] outActRxLen : data received length
- * \param[out] outIsChaining : true if other peer is performing chaining(MI)
- *
- * \return ERR_NONE : Data exchange cycle completed successfully
- * \return ERR_TIMEOUT : Timeout occurred
- * \return ERR_PROTO : Protocol error occurred
- * \return ERR_AGAIN : Other peer is doing chaining(MI), current block
- * was received successfully call again until complete
- *
- ******************************************************************************
- */
- static ReturnCode nfcipRun(uint16_t* outActRxLen, bool* outIsChaining);
- /*!
- ******************************************************************************
- * \brief Transmission method
- *
- * This method checks if the current communication is Active or Passive
- * and performs the necessary procedures for each communication type
- *
- * Transmits the data hold in txBuf
- *
- * \param[in] txBuf : buffer to transmit
- * \param[in] txBufLen : txBuffer capacity
- * \param[in] fwt : fwt for current Tx
- *
- * \return ERR_NONE : No error
- ******************************************************************************
- */
- static ReturnCode nfcipDataTx(uint8_t* txBuf, uint16_t txBufLen, uint32_t fwt);
- /*!
- ******************************************************************************
- * \brief Reception method
- *
- * This method checks if the current communication is Active or Passive
- * and calls the appropriate reception method
- *
- * Copies incoming data to rxBuf
- *
- * \param[in] blocking : reception is to be done blocking or non-blocking
- *
- * \return ERR_BUSY : Busy
- * \return ERR_NONE : No error
- ******************************************************************************
- */
- static ReturnCode nfcipDataRx(bool blocking);
- /*
- ******************************************************************************
- * LOCAL FUNCTIONS
- ******************************************************************************
- */
- /*******************************************************************************/
- /*******************************************************************************/
- static bool nfcipDxIsSupported(uint8_t Dx, uint8_t BRx, uint8_t BSx) {
- uint8_t Bx;
- /* Take the min of the possible bit rates, we'll use one for both directions */
- Bx = MIN(BRx, BSx);
- /* Lower bit rates must be supported for P2P */
- if((Dx <= (uint8_t)RFAL_NFCDEP_Dx_04_424)) {
- return true;
- }
- if((Dx == (uint8_t)RFAL_NFCDEP_Dx_08_848) && (Bx >= (uint8_t)RFAL_NFCDEP_Bx_08_848)) {
- return true;
- }
- return false;
- }
- /*******************************************************************************/
- static ReturnCode nfcipTxRx(
- rfalNfcDepCmd cmd,
- uint8_t* txBuf,
- uint32_t fwt,
- uint8_t* paylBuf,
- uint8_t paylBufLen,
- uint8_t* rxBuf,
- uint16_t rxBufLen,
- uint16_t* rxActLen) {
- ReturnCode ret;
- if((cmd == NFCIP_CMD_DEP_REQ) ||
- (cmd == NFCIP_CMD_DEP_RES)) /* this method cannot be used for DEPs */
- {
- return ERR_PARAM;
- }
- /* Assign the global params for this TxRx */
- gNfcip.rxBuf = rxBuf;
- gNfcip.rxBufLen = rxBufLen;
- gNfcip.rxRcvdLen = rxActLen;
- /*******************************************************************************/
- /* Transmission */
- /*******************************************************************************/
- if(txBuf != NULL) /* if nothing to Tx, just do Rx */
- {
- EXIT_ON_ERR(ret, nfcipTx(cmd, txBuf, paylBuf, paylBufLen, 0, fwt));
- }
- /*******************************************************************************/
- /* Reception */
- /*******************************************************************************/
- ret = nfcipDataRx(true);
- if(ret != ERR_NONE) {
- return ret;
- }
- /*******************************************************************************/
- *rxActLen = *rxBuf; /* Use LEN byte instead due to with/without CRC modes */
- return ERR_NONE; /* Tx and Rx completed successfully */
- }
- /*******************************************************************************/
- static ReturnCode nfcipDEPControlMsg(uint8_t pfb, uint8_t RTOX) {
- uint8_t ctrlMsg[20];
- rfalNfcDepCmd depCmd;
- uint32_t fwt;
- /*******************************************************************************/
- /* Calculate Cmd and fwt to be used */
- /*******************************************************************************/
- depCmd =
- ((gNfcip.cfg.role == RFAL_NFCDEP_ROLE_TARGET) ? NFCIP_CMD_DEP_RES : NFCIP_CMD_DEP_REQ);
- fwt =
- ((gNfcip.cfg.role == RFAL_NFCDEP_ROLE_TARGET) ?
- NFCIP_NO_FWT :
- (nfcip_PFBisSTO(pfb) ? ((RTOX * gNfcip.cfg.fwt) + gNfcip.cfg.dFwt) :
- (gNfcip.cfg.fwt + gNfcip.cfg.dFwt)));
- if(nfcip_PFBisSTO(pfb)) {
- ctrlMsg[RFAL_NFCDEP_DEPREQ_HEADER_LEN] = RTOX;
- return nfcipTx(
- depCmd, ctrlMsg, &ctrlMsg[RFAL_NFCDEP_DEPREQ_HEADER_LEN], sizeof(uint8_t), pfb, fwt);
- } else {
- return nfcipTx(depCmd, ctrlMsg, NULL, 0, pfb, fwt);
- }
- }
- /*******************************************************************************/
- static void nfcipClearCounters(void) {
- gNfcip.cntATNRetrys = 0;
- gNfcip.cntNACKRetrys = 0;
- gNfcip.cntTORetrys = 0;
- gNfcip.cntTxRetrys = 0;
- gNfcip.cntRTOXRetrys = 0;
- }
- /*******************************************************************************/
- static ReturnCode nfcipInitiatorHandleDEP(
- ReturnCode rxRes,
- uint16_t rxLen,
- uint16_t* outActRxLen,
- bool* outIsChaining) {
- ReturnCode ret;
- uint8_t nfcDepLen;
- uint8_t rxMsgIt;
- uint8_t rxPFB;
- uint8_t rxRTOX;
- uint8_t optHdrLen;
- ret = ERR_INTERNAL;
- rxMsgIt = 0;
- optHdrLen = 0;
- *outActRxLen = 0;
- *outIsChaining = false;
- /*******************************************************************************/
- /* Handle reception errors */
- /*******************************************************************************/
- switch(rxRes) {
- /*******************************************************************************/
- /* Timeout -> Digital 1.0 14.15.5.6 */
- case ERR_TIMEOUT:
- nfcipLogI(" NFCIP(I) TIMEOUT TORetrys:%d \r\n", gNfcip.cntTORetrys);
- /* Digital 1.0 14.15.5.6 - If nTO >= Max raise protocol error */
- if(gNfcip.cntTORetrys++ >= RFAL_NFCDEP_TO_RETRYS) {
- return ERR_PROTO;
- }
- /*******************************************************************************/
- /* Upon Timeout error, if Deactivation is pending, no more error recovery
- * will be done #54.
- * This is used to address the issue some devices that havea big TO.
- * Normally LLCP layer has timeout already, and NFCIP layer is still
- * running error handling, retrying ATN/NACKs */
- /*******************************************************************************/
- if(nfcipIsDeactivationPending()) {
- nfcipLogI(" skipping error recovery due deactivation pending \r\n");
- return ERR_TIMEOUT;
- }
- /* Digital 1.0 14.15.5.6 1) If last PDU was NACK */
- if(nfcip_PFBisRNACK(gNfcip.lastPFB)) {
- /* Digital 1.0 14.15.5.6 2) if NACKs failed raise protocol error */
- if(gNfcip.cntNACKRetrys++ >= RFAL_NFCDEP_MAX_NACK_RETRYS) {
- return ERR_PROTO;
- }
- /* Send NACK */
- nfcipLogI(" NFCIP(I) Sending NACK retry: %d \r\n", gNfcip.cntNACKRetrys);
- EXIT_ON_ERR(ret, nfcipDEPControlMsg(nfcip_PFBRPDU_NACK(gNfcip.pni), 0));
- return ERR_BUSY;
- }
- nfcipLogI(" NFCIP(I) Checking if to send ATN ATNRetrys: %d \r\n", gNfcip.cntATNRetrys);
- /* Digital 1.0 14.15.5.6 3) Otherwise send ATN */
- if(gNfcip.cntATNRetrys++ >= RFAL_NFCDEP_MAX_NACK_RETRYS) {
- return ERR_PROTO;
- }
- /* Send ATN */
- nfcipLogI(" NFCIP(I) Sending ATN \r\n");
- EXIT_ON_ERR(ret, nfcipDEPControlMsg(nfcip_PFBSPDU_ATN(), 0));
- return ERR_BUSY;
- /*******************************************************************************/
- /* Data rcvd with error -> Digital 1.0 14.12.5.4 */
- case ERR_CRC:
- case ERR_PAR:
- case ERR_FRAMING:
- case ERR_RF_COLLISION:
- nfcipLogI(" NFCIP(I) rx Error: %d \r\n", rxRes);
- /* Digital 1.0 14.12.5.4 Tx Error with data, ignore */
- if(rxLen < NFCIP_MIN_TXERROR_LEN) {
- nfcipLogI(" NFCIP(I) Transmission error w data \r\n");
- #if 0
- if(gNfcip.cfg.commMode == RFAL_NFCDEP_COMM_PASSIVE)
- {
- nfcipLogI( " NFCIP(I) Transmission error w data -> reEnabling Rx \r\n" );
- nfcipReEnableRxTout( NFCIP_TRECOV );
- return ERR_BUSY;
- }
- #endif /* 0 */
- }
- /* Digital 1.1 16.12.5.4 if NACKs failed raise Transmission error */
- if(gNfcip.cntNACKRetrys++ >= RFAL_NFCDEP_MAX_NACK_RETRYS) {
- return ERR_FRAMING;
- }
- /* Send NACK */
- nfcipLogI(" NFCIP(I) Sending NACK \r\n");
- EXIT_ON_ERR(ret, nfcipDEPControlMsg(nfcip_PFBRPDU_NACK(gNfcip.pni), 0));
- return ERR_BUSY;
- case ERR_NONE:
- break;
- case ERR_BUSY:
- return ERR_BUSY; /* Debug purposes */
- default:
- nfcipLogW(" NFCIP(I) Error: %d \r\n", rxRes);
- return rxRes;
- }
- /*******************************************************************************/
- /* Rx OK check if valid DEP PDU */
- /*******************************************************************************/
- /* Due to different modes on ST25R391x (with/without CRC) use NFC-DEP LEN instead of bytes retrieved */
- nfcDepLen = gNfcip.rxBuf[rxMsgIt++];
- nfcipLogD(" NFCIP(I) rx OK: %d bytes \r\n", nfcDepLen);
- /* Digital 1.0 14.15.5.5 Protocol Error */
- if(gNfcip.rxBuf[rxMsgIt++] != NFCIP_RES) {
- nfcipLogW(" NFCIP(I) error %02X instead of %02X \r\n", gNfcip.rxBuf[--rxMsgIt], NFCIP_RES);
- return ERR_PROTO;
- }
- /* Digital 1.0 14.15.5.5 Protocol Error */
- if(gNfcip.rxBuf[rxMsgIt++] != (uint8_t)NFCIP_CMD_DEP_RES) {
- nfcipLogW(
- " NFCIP(I) error %02X instead of %02X \r\n",
- gNfcip.rxBuf[--rxMsgIt],
- NFCIP_CMD_DEP_RES);
- return ERR_PROTO;
- }
- rxPFB = gNfcip.rxBuf[rxMsgIt++];
- /*******************************************************************************/
- /* Check for valid PFB type */
- if(!(nfcip_PFBisSPDU(rxPFB) || nfcip_PFBisRPDU(rxPFB) || nfcip_PFBisIPDU(rxPFB))) {
- return ERR_PROTO;
- }
- /*******************************************************************************/
- /* Digital 1.0 14.8.2.1 check if DID is expected and match -> Protocol Error */
- if(gNfcip.cfg.did != RFAL_NFCDEP_DID_NO) {
- if((gNfcip.rxBuf[rxMsgIt++] != gNfcip.cfg.did) || !nfcip_PFBhasDID(rxPFB)) {
- return ERR_PROTO;
- }
- optHdrLen++; /* Inc header optional field cnt*/
- } else if(nfcip_PFBhasDID(rxPFB)) /* DID not expected but rcv */
- {
- return ERR_PROTO;
- } else {
- /* MISRA 15.7 - Empty else */
- }
- /*******************************************************************************/
- /* Digital 1.0 14.6.2.8 & 14.6.3.11 NAD must not be used */
- if(gNfcip.cfg.nad != RFAL_NFCDEP_NAD_NO) {
- if((gNfcip.rxBuf[rxMsgIt++] != gNfcip.cfg.nad) || !nfcip_PFBhasNAD(rxPFB)) {
- return ERR_PROTO;
- }
- optHdrLen++; /* Inc header optional field cnt*/
- } else if(nfcip_PFBhasNAD(rxPFB)) /* NAD not expected but rcv */
- {
- return ERR_PROTO;
- } else {
- /* MISRA 15.7 - Empty else */
- }
- /*******************************************************************************/
- /* Process R-PDU */
- /*******************************************************************************/
- if(nfcip_PFBisRPDU(rxPFB)) {
- /*******************************************************************************/
- /* R ACK */
- /*******************************************************************************/
- if(nfcip_PFBisRACK(rxPFB)) {
- nfcipLogI(" NFCIP(I) Rcvd ACK \r\n");
- if(gNfcip.pni == nfcip_PBF_PNI(rxPFB)) {
- /* 14.12.3.3 R-ACK with correct PNI -> Increment */
- gNfcip.pni = nfcip_PNIInc(gNfcip.pni);
- /* R-ACK while not performing chaining -> Protocol error*/
- if(!gNfcip.isTxChaining) {
- return ERR_PROTO;
- }
- nfcipClearCounters();
- gNfcip.state = NFCIP_ST_INIT_DEP_IDLE;
- return ERR_NONE; /* This block has been transmitted */
- } else /* Digital 1.0 14.12.4.5 ACK with wrong PNI Initiator may retransmit */
- {
- if(gNfcip.cntTxRetrys++ >= RFAL_NFCDEP_MAX_TX_RETRYS) {
- return ERR_PROTO;
- }
- /* Extended the MAY in Digital 1.0 14.12.4.5 to only reTransmit if the ACK
- * is for the previous DEP, otherwise raise Protocol immediately
- * If the PNI difference is more than 1 it is worthless to reTransmit 3x
- * and after raise the error */
- if(nfcip_PNIDec(gNfcip.pni) == nfcip_PBF_PNI(rxPFB)) {
- /* ReTransmit */
- nfcipLogI(" NFCIP(I) Rcvd ACK prev PNI -> reTx \r\n");
- gNfcip.state = NFCIP_ST_INIT_DEP_TX;
- return ERR_BUSY;
- }
- nfcipLogI(" NFCIP(I) Rcvd ACK unexpected far PNI -> Error \r\n");
- return ERR_PROTO;
- }
- } else /* Digital 1.0 - 14.12.5.2 Target must never send NACK */
- {
- return ERR_PROTO;
- }
- }
- /*******************************************************************************/
- /* Process S-PDU */
- /*******************************************************************************/
- if(nfcip_PFBisSPDU(rxPFB)) {
- nfcipLogI(" NFCIP(I) Rcvd S-PDU \r\n");
- /*******************************************************************************/
- /* S ATN */
- /*******************************************************************************/
- if(nfcip_PFBisSATN(rxPFB)) /* If is a S-ATN */
- {
- nfcipLogI(" NFCIP(I) Rcvd ATN \r\n");
- if(nfcip_PFBisSATN(gNfcip.lastPFB)) /* Check if is expected */
- {
- gNfcip.cntATNRetrys = 0; /* Clear ATN counter */
- /* Although spec is not clear NFC Forum Digital test is expecting to
- * retransmit upon receiving ATN_RES */
- if(nfcip_PFBisSTO(gNfcip.lastPFBnATN)) {
- nfcipLogI(" NFCIP(I) Rcvd ATN -> reTx RTOX_RES \r\n");
- EXIT_ON_ERR(ret, nfcipDEPControlMsg(nfcip_PFBSPDU_TO(), gNfcip.lastRTOX));
- } else {
- /* ReTransmit ? */
- if(gNfcip.cntTxRetrys++ >= RFAL_NFCDEP_MAX_TX_RETRYS) {
- return ERR_PROTO;
- }
- nfcipLogI(" NFCIP(I) Rcvd ATN -> reTx PNI: %d \r\n", gNfcip.pni);
- gNfcip.state = NFCIP_ST_INIT_DEP_TX;
- }
- return ERR_BUSY;
- } else /* Digital 1.0 14.12.4.4 & 14.12.4.8 */
- {
- return ERR_PROTO;
- }
- }
- /*******************************************************************************/
- /* S TO */
- /*******************************************************************************/
- else if(nfcip_PFBisSTO(rxPFB)) /* If is a S-TO (RTOX) */
- {
- nfcipLogI(" NFCIP(I) Rcvd TO \r\n");
- rxRTOX = gNfcip.rxBuf[rxMsgIt++];
- /* Digital 1.1 16.12.4.3 - Initiator MAY stop accepting subsequent RTOX Req *
- * - RTOX request to an ATN -> Protocol error */
- if((gNfcip.cntRTOXRetrys++ > RFAL_NFCDEP_MAX_RTOX_RETRYS) ||
- nfcip_PFBisSATN(gNfcip.lastPFB)) {
- return ERR_PROTO;
- }
- /* Digital 1.1 16.8.4.1 RTOX must be between [1,59] */
- if((rxRTOX < NFCIP_INIT_MIN_RTOX) || (rxRTOX > NFCIP_INIT_MAX_RTOX)) {
- return ERR_PROTO;
- }
- EXIT_ON_ERR(ret, nfcipDEPControlMsg(nfcip_PFBSPDU_TO(), rxRTOX));
- gNfcip.lastRTOX = rxRTOX;
- return ERR_BUSY;
- } else {
- /* Unexpected S-PDU */
- return ERR_PROTO; /* PRQA S 2880 # MISRA 2.1 - Guard code to prevent unexpected behavior */
- }
- }
- /*******************************************************************************/
- /* Process I-PDU */
- /*******************************************************************************/
- if(nfcip_PFBisIPDU(rxPFB)) {
- if(gNfcip.pni != nfcip_PBF_PNI(rxPFB)) {
- nfcipLogI(
- " NFCIP(I) Rcvd IPDU wrong PNI curPNI: %d rxPNI: %d \r\n",
- gNfcip.pni,
- nfcip_PBF_PNI(rxPFB));
- return ERR_PROTO;
- }
- nfcipLogD(" NFCIP(I) Rcvd IPDU OK PNI: %d \r\n", gNfcip.pni);
- /* 14.12.3.3 I-PDU with correct PNI -> Increment */
- gNfcip.pni = nfcip_PNIInc(gNfcip.pni);
- /* Successful data Exchange */
- nfcipClearCounters();
- *outActRxLen = ((uint16_t)nfcDepLen - RFAL_NFCDEP_DEP_HEADER - (uint16_t)optHdrLen);
- if((&gNfcip.rxBuf[gNfcip.rxBufPaylPos] !=
- &gNfcip.rxBuf[RFAL_NFCDEP_DEP_HEADER + optHdrLen]) &&
- (*outActRxLen > 0U)) {
- ST_MEMMOVE(
- &gNfcip.rxBuf[gNfcip.rxBufPaylPos],
- &gNfcip.rxBuf[RFAL_NFCDEP_DEP_HEADER + optHdrLen],
- *outActRxLen);
- }
- /*******************************************************************************/
- /* Check if target is indicating chaining MI */
- /*******************************************************************************/
- if(nfcip_PFBisIMI(rxPFB)) {
- gNfcip.isRxChaining = true;
- *outIsChaining = true;
- nfcipLogD(" NFCIP(I) Rcvd IPDU OK w MI -> ACK \r\n");
- EXIT_ON_ERR(
- ret, nfcipDEPControlMsg(nfcip_PFBRPDU_ACK(gNfcip.pni), gNfcip.rxBuf[rxMsgIt++]));
- return ERR_AGAIN; /* Send Again signalling to run again, but some chaining data has arrived*/
- } else {
- gNfcip.isRxChaining = false;
- gNfcip.state = NFCIP_ST_INIT_DEP_IDLE;
- ret = ERR_NONE; /* Data exchange done */
- }
- }
- return ret;
- }
- /*******************************************************************************/
- static ReturnCode
- nfcipTargetHandleRX(ReturnCode rxRes, uint16_t* outActRxLen, bool* outIsChaining) {
- ReturnCode ret;
- uint8_t nfcDepLen;
- uint8_t rxMsgIt;
- uint8_t rxPFB;
- uint8_t optHdrLen;
- uint8_t resBuf[RFAL_NFCDEP_HEADER_PAD + NFCIP_TARGET_RES_MAX];
- ret = ERR_INTERNAL;
- rxMsgIt = 0;
- optHdrLen = 0;
- *outActRxLen = 0;
- *outIsChaining = false;
- /*******************************************************************************/
- /* Handle reception errors */
- /*******************************************************************************/
- switch(rxRes) {
- /*******************************************************************************/
- case ERR_NONE:
- break;
- case ERR_LINK_LOSS:
- nfcipLogW(" NFCIP(T) Error: %d \r\n", rxRes);
- return rxRes;
- case ERR_BUSY:
- return ERR_BUSY; /* Debug purposes */
- case ERR_TIMEOUT:
- case ERR_CRC:
- case ERR_PAR:
- case ERR_FRAMING:
- case ERR_PROTO:
- default:
- /* Digital 1.1 16.12.5.2 The Target MUST NOT attempt any error recovery. *
- * The Target MUST always stay in receive mode when a *
- * Transmission Error or a Protocol Error occurs. *
- * *
- * Do not push Transmission/Protocol Errors to upper layer in Listen Mode #766 */
- nfcDepReEnableRx(gNfcip.rxBuf, gNfcip.rxBufLen, gNfcip.rxRcvdLen);
- return ERR_BUSY;
- }
- /*******************************************************************************/
- /* Rx OK check if valid DEP PDU */
- /*******************************************************************************/
- /* Due to different modes on ST25R391x (with/without CRC) use NFC-DEP LEN instead of bytes retrieved */
- nfcDepLen = gNfcip.rxBuf[rxMsgIt++];
- nfcipLogD(" NFCIP(T) rx OK: %d bytes \r\n", nfcDepLen);
- if(gNfcip.rxBuf[rxMsgIt++] != NFCIP_REQ) {
- nfcDepReEnableRx(gNfcip.rxBuf, gNfcip.rxBufLen, gNfcip.rxRcvdLen);
- return ERR_BUSY; /* ERR_PROTO - Ignore bad request */
- }
- /*******************************************************************************/
- /* Check whether target rcvd a normal DEP or deactivation request */
- /*******************************************************************************/
- switch(gNfcip.rxBuf[rxMsgIt++]) {
- /*******************************************************************************/
- case(uint8_t)NFCIP_CMD_DEP_REQ:
- break; /* Continue to normal DEP processing */
- /*******************************************************************************/
- case(uint8_t)NFCIP_CMD_DSL_REQ:
- nfcipLogI(" NFCIP(T) rx DSL \r\n");
- /* Digital 1.0 14.9.1.2 If DID is used and incorrect ignore it */
- /* [Digital 1.0, 16.9.1.2]: If DID == 0, Target SHALL ignore DSL_REQ with DID */
- if((((gNfcip.rxBuf[rxMsgIt++] != gNfcip.cfg.did) ||
- (nfcDepLen != RFAL_NFCDEP_DSL_RLS_LEN_DID)) &&
- (gNfcip.cfg.did != RFAL_NFCDEP_DID_NO)) ||
- ((gNfcip.cfg.did == RFAL_NFCDEP_DID_NO) &&
- (nfcDepLen != RFAL_NFCDEP_DSL_RLS_LEN_NO_DID))) {
- nfcipLogI(" NFCIP(T) DSL wrong DID, ignoring \r\n");
- return ERR_BUSY;
- }
- nfcipTx(NFCIP_CMD_DSL_RES, resBuf, NULL, 0, 0, NFCIP_NO_FWT);
- gNfcip.state = NFCIP_ST_TARG_DEP_SLEEP;
- return ERR_SLEEP_REQ;
- /*******************************************************************************/
- case(uint8_t)NFCIP_CMD_RLS_REQ:
- nfcipLogI(" NFCIP(T) rx RLS \r\n");
- /* Digital 1.0 14.10.1.2 If DID is used and incorrect ignore it */
- /* [Digital 1.0, 16.10.2.2]: If DID == 0, Target SHALL ignore DSL_REQ with DID */
- if((((gNfcip.rxBuf[rxMsgIt++] != gNfcip.cfg.did) ||
- (nfcDepLen != RFAL_NFCDEP_DSL_RLS_LEN_DID)) &&
- (gNfcip.cfg.did != RFAL_NFCDEP_DID_NO)) ||
- ((gNfcip.cfg.did == RFAL_NFCDEP_DID_NO) &&
- (nfcDepLen > RFAL_NFCDEP_DSL_RLS_LEN_NO_DID))) {
- nfcipLogI(" NFCIP(T) RLS wrong DID, ignoring \r\n");
- return ERR_BUSY;
- }
- nfcipTx(NFCIP_CMD_RLS_RES, resBuf, NULL, 0, 0, NFCIP_NO_FWT);
- gNfcip.state = NFCIP_ST_TARG_DEP_IDLE;
- return ERR_RELEASE_REQ;
- /*******************************************************************************/
- /*case NFCIP_CMD_PSL_REQ: PSL must be handled in Activation only */
- /*case NFCIP_CMD_WUP_REQ: WUP not in NFC Forum Digital 1.0 */
- default:
- /* Don't go to NFCIP_ST_TARG_DEP_IDLE state as it needs to ignore this *
- * invalid frame, and keep waiting for more frames */
- nfcDepReEnableRx(gNfcip.rxBuf, gNfcip.rxBufLen, gNfcip.rxRcvdLen);
- return ERR_BUSY; /* ERR_PROTO - Ignore bad frame */
- }
- /*******************************************************************************/
- rxPFB = gNfcip.rxBuf[rxMsgIt++]; /* Store rcvd PFB */
- /*******************************************************************************/
- /* Check for valid PFB type */
- if(!(nfcip_PFBisSPDU(rxPFB) || nfcip_PFBisRPDU(rxPFB) || nfcip_PFBisIPDU(rxPFB))) {
- nfcDepReEnableRx(gNfcip.rxBuf, gNfcip.rxBufLen, gNfcip.rxRcvdLen);
- return ERR_BUSY; /* ERR_PROTO - Ignore invalid PFB */
- }
- /*******************************************************************************/
- if(gNfcip.cfg.did != RFAL_NFCDEP_DID_NO) {
- if(!nfcip_PFBhasDID(rxPFB)) {
- nfcDepReEnableRx(gNfcip.rxBuf, gNfcip.rxBufLen, gNfcip.rxRcvdLen);
- return ERR_BUSY; /* ERR_PROTO - Ignore bad/missing DID */
- }
- if(gNfcip.rxBuf[rxMsgIt++] != gNfcip.cfg.did) /* MISRA 13.5 */
- {
- nfcDepReEnableRx(gNfcip.rxBuf, gNfcip.rxBufLen, gNfcip.rxRcvdLen);
- return ERR_BUSY; /* ERR_PROTO - Ignore bad/missing DID */
- }
- optHdrLen++; /* Inc header optional field cnt*/
- } else if(nfcip_PFBhasDID(rxPFB)) /* DID not expected but rcv */
- {
- nfcDepReEnableRx(gNfcip.rxBuf, gNfcip.rxBufLen, gNfcip.rxRcvdLen);
- return ERR_BUSY; /* ERR_PROTO - Ignore unexpected DID */
- } else {
- /* MISRA 15.7 - Empty else */
- }
- /*******************************************************************************/
- if(gNfcip.cfg.nad != RFAL_NFCDEP_NAD_NO) {
- if((gNfcip.rxBuf[rxMsgIt++] != gNfcip.cfg.did) || !nfcip_PFBhasDID(rxPFB)) {
- nfcDepReEnableRx(gNfcip.rxBuf, gNfcip.rxBufLen, gNfcip.rxRcvdLen);
- return ERR_BUSY; /* ERR_PROTO - Ignore bad/missing DID */
- }
- optHdrLen++; /* Inc header optional field cnt*/
- } else if(nfcip_PFBhasNAD(rxPFB)) /* NAD not expected but rcv */
- {
- nfcDepReEnableRx(gNfcip.rxBuf, gNfcip.rxBufLen, gNfcip.rxRcvdLen);
- return ERR_BUSY; /* ERR_PROTO - Ignore unexpected NAD */
- } else {
- /* MISRA 15.7 - Empty else */
- }
- /*******************************************************************************/
- /* Process R-PDU */
- /*******************************************************************************/
- if(nfcip_PFBisRPDU(rxPFB)) {
- nfcipLogD(" NFCIP(T) Rcvd R-PDU \r\n");
- /*******************************************************************************/
- /* R ACK */
- /*******************************************************************************/
- if(nfcip_PFBisRACK(rxPFB)) {
- nfcipLogI(" NFCIP(T) Rcvd ACK \r\n");
- if(gNfcip.pni == nfcip_PBF_PNI(rxPFB)) {
- /* R-ACK while not performing chaining -> Protocol error */
- if(!gNfcip.isTxChaining) {
- nfcDepReEnableRx(gNfcip.rxBuf, gNfcip.rxBufLen, gNfcip.rxRcvdLen);
- return ERR_BUSY; /* ERR_PROTO - Ignore unexpected ACK */
- }
- /* This block has been transmitted and acknowledged, perform RTOX until next data is provided */
- /* Digital 1.1 16.12.4.7 - If ACK rcvd continue with chaining or an RTOX */
- nfcipTimerStart(
- gNfcip.RTOXTimer,
- nfcipRTOXAdjust(nfcipConv1FcToMs(rfalNfcDepWT2RWT(gNfcip.cfg.to))));
- gNfcip.state = NFCIP_ST_TARG_DEP_RTOX;
- return ERR_NONE; /* This block has been transmitted */
- }
- /* Digital 1.0 14.12.3.4 - If last send was ATN and rx PNI is minus 1 */
- else if(
- nfcip_PFBisSATN(gNfcip.lastPFB) &&
- (nfcip_PNIDec(gNfcip.pni) == nfcip_PBF_PNI(rxPFB))) {
- nfcipLogI(" NFCIP(T) wrong PNI, last was ATN reTx \r\n");
- /* Spec says to leave current PNI as is, but will be Inc after Tx, remaining the same */
- gNfcip.pni = nfcip_PNIDec(gNfcip.pni);
- gNfcip.state = NFCIP_ST_TARG_DEP_TX;
- return ERR_BUSY;
- } else {
- /* MISRA 15.7 - Empty else */
- }
- }
- /*******************************************************************************/
- /* R NACK */
- /*******************************************************************************/
- /* ISO 18092 12.6.1.3.3 When rcv NACK if PNI = prev PNI sent -> reTx */
- else if(nfcip_PFBisRNACK(rxPFB) && (nfcip_PNIDec(gNfcip.pni) == nfcip_PBF_PNI(rxPFB))) {
- nfcipLogI(" NFCIP(T) Rcvd NACK \r\n");
- gNfcip.pni = nfcip_PNIDec(gNfcip.pni); /* Dec so that has the prev PNI */
- gNfcip.state = NFCIP_ST_TARG_DEP_TX;
- return ERR_BUSY;
- } else {
- nfcipLogI(" NFCIP(T) Unexpected R-PDU \r\n");
- nfcDepReEnableRx(gNfcip.rxBuf, gNfcip.rxBufLen, gNfcip.rxRcvdLen);
- return ERR_BUSY; /* ERR_PROTO - Ignore unexpected R-PDU */
- }
- }
- /*******************************************************************************/
- /* Process S-PDU */
- /*******************************************************************************/
- if(nfcip_PFBisSPDU(rxPFB)) {
- nfcipLogD(" NFCIP(T) Rcvd S-PDU \r\n");
- /*******************************************************************************/
- /* S ATN */
- /*******************************************************************************/
- /* ISO 18092 12.6.3 Attention */
- if(nfcip_PFBisSATN(rxPFB)) /* If is a S-ATN */
- {
- nfcipLogI(" NFCIP(T) Rcvd ATN curPNI: %d \r\n", gNfcip.pni);
- EXIT_ON_ERR(ret, nfcipDEPControlMsg(nfcip_PFBSPDU_ATN(), 0));
- return ERR_BUSY;
- }
- /*******************************************************************************/
- /* S TO */
- /*******************************************************************************/
- else if(nfcip_PFBisSTO(rxPFB)) /* If is a S-TO (RTOX) */
- {
- if(nfcip_PFBisSTO(gNfcip.lastPFBnATN)) {
- nfcipLogI(" NFCIP(T) Rcvd TO \r\n");
- /* Digital 1.1 16.8.4.6 RTOX value in RES different that in REQ -> Protocol Error */
- if(gNfcip.lastRTOX != gNfcip.rxBuf[rxMsgIt++]) {
- nfcipLogI(" NFCIP(T) Mismatched RTOX value \r\n");
- nfcDepReEnableRx(gNfcip.rxBuf, gNfcip.rxBufLen, gNfcip.rxRcvdLen);
- return ERR_BUSY; /* ERR_PROTO - Ignore unexpected RTOX value */
- }
- /* Clear waiting for RTOX Ack Flag */
- gNfcip.isWait4RTOX = false;
- /* Check if a Tx is already pending */
- if(gNfcip.isTxPending) {
- nfcipLogW(" NFCIP(T) Tx pending, go immediately to TX \r\n");
- gNfcip.state = NFCIP_ST_TARG_DEP_TX;
- return ERR_BUSY;
- }
- /* Start RTOX timer and change to check state */
- nfcipTimerStart(
- gNfcip.RTOXTimer,
- nfcipRTOXAdjust(
- nfcipConv1FcToMs(gNfcip.lastRTOX * rfalNfcDepWT2RWT(gNfcip.cfg.to))));
- gNfcip.state = NFCIP_ST_TARG_DEP_RTOX;
- return ERR_BUSY;
- }
- } else {
- /* Unexpected S-PDU */
- nfcipLogI(
- " NFCIP(T) Unexpected S-PDU \r\n"); /* PRQA S 2880 # MISRA 2.1 - Guard code to prevent unexpected behavior */
- nfcDepReEnableRx(gNfcip.rxBuf, gNfcip.rxBufLen, gNfcip.rxRcvdLen);
- return ERR_BUSY; /* ERR_PROTO - Ignore unexpected S-PDU */
- }
- }
- /*******************************************************************************/
- /* Process I-PDU */
- /*******************************************************************************/
- if(nfcip_PFBisIPDU(rxPFB)) {
- if(gNfcip.pni != nfcip_PBF_PNI(rxPFB)) {
- nfcipLogI(
- " NFCIP(T) Rcvd IPDU wrong PNI curPNI: %d rxPNI: %d \r\n",
- gNfcip.pni,
- nfcip_PBF_PNI(rxPFB));
- /* Digital 1.1 16.12.3.4 - If last send was ATN and rx PNI is minus 1 */
- if(nfcip_PFBisSATN(gNfcip.lastPFB) &&
- (nfcip_PNIDec(gNfcip.pni) == nfcip_PBF_PNI(rxPFB))) {
- /* Spec says to leave current PNI as is, but will be Inc after Data Tx, remaining the same */
- gNfcip.pni = nfcip_PNIDec(gNfcip.pni);
- if(nfcip_PFBisIMI(rxPFB)) {
- nfcipLogI(
- " NFCIP(T) PNI = prevPNI && ATN before && chaining -> send ACK \r\n");
- EXIT_ON_ERR(
- ret,
- nfcipDEPControlMsg(nfcip_PFBRPDU_ACK(gNfcip.pni), gNfcip.rxBuf[rxMsgIt++]));
- /* Digital 1.1 16.12.3.4 (...) leave the current PNI unchanged afterwards */
- gNfcip.pni = nfcip_PNIInc(gNfcip.pni);
- } else {
- nfcipLogI(" NFCIP(T) PNI = prevPNI && ATN before -> reTx last I-PDU \r\n");
- gNfcip.state = NFCIP_ST_TARG_DEP_TX;
- }
- return ERR_BUSY;
- }
- nfcDepReEnableRx(gNfcip.rxBuf, gNfcip.rxBufLen, gNfcip.rxRcvdLen);
- return ERR_BUSY; /* ERR_PROTO - Ignore bad PNI value */
- }
- nfcipLogD(" NFCIP(T) Rcvd IPDU OK PNI: %d \r\n", gNfcip.pni);
- /*******************************************************************************/
- /* Successful data exchange */
- /*******************************************************************************/
- *outActRxLen = ((uint16_t)nfcDepLen - RFAL_NFCDEP_DEP_HEADER - (uint16_t)optHdrLen);
- nfcipClearCounters();
- if((&gNfcip.rxBuf[gNfcip.rxBufPaylPos] !=
- &gNfcip.rxBuf[RFAL_NFCDEP_DEP_HEADER + optHdrLen]) &&
- (*outActRxLen > 0U)) {
- ST_MEMMOVE(
- &gNfcip.rxBuf[gNfcip.rxBufPaylPos],
- &gNfcip.rxBuf[RFAL_NFCDEP_DEP_HEADER + optHdrLen],
- *outActRxLen);
- }
- /*******************************************************************************/
- /* Check if Initiator is indicating chaining MI */
- /*******************************************************************************/
- if(nfcip_PFBisIMI(rxPFB)) {
- gNfcip.isRxChaining = true;
- *outIsChaining = true;
- nfcipLogD(" NFCIP(T) Rcvd IPDU OK w MI -> ACK \r\n");
- EXIT_ON_ERR(
- ret, nfcipDEPControlMsg(nfcip_PFBRPDU_ACK(gNfcip.pni), gNfcip.rxBuf[rxMsgIt++]));
- gNfcip.pni = nfcip_PNIInc(gNfcip.pni);
- return ERR_AGAIN; /* Send Again signalling to run again, but some chaining data has arrived*/
- } else {
- if(gNfcip.isRxChaining) {
- nfcipLogI(" NFCIP(T) Rcvd last IPDU chaining finished \r\n");
- }
- /*******************************************************************************/
- /* Reception done, send to DH and start RTOX timer */
- /*******************************************************************************/
- nfcipTimerStart(
- gNfcip.RTOXTimer,
- nfcipRTOXAdjust(nfcipConv1FcToMs(rfalNfcDepWT2RWT(gNfcip.cfg.to))));
- gNfcip.state = NFCIP_ST_TARG_DEP_RTOX;
- gNfcip.isRxChaining = false;
- ret = ERR_NONE; /* Data exchange done */
- }
- }
- return ret;
- }
- /*******************************************************************************/
- static ReturnCode nfcipTx(
- rfalNfcDepCmd cmd,
- uint8_t* txBuf,
- uint8_t* paylBuf,
- uint16_t paylLen,
- uint8_t pfbData,
- uint32_t fwt) {
- uint16_t txBufIt;
- uint8_t* txBlock;
- uint8_t* payloadBuf;
- uint8_t pfb;
- if(txBuf == NULL) {
- return ERR_PARAM;
- }
- payloadBuf = paylBuf; /* MISRA 17.8: Use intermediate variable */
- if((paylLen == 0U) || (payloadBuf == NULL)) {
- payloadBuf = (uint8_t*)&txBuf
- [RFAL_NFCDEP_DEPREQ_HEADER_LEN]; /* If not a DEP (no Data) ensure enough space for header */
- }
- txBufIt = 0;
- pfb = pfbData; /* MISRA 17.8: Use intermediate variable */
- txBlock = payloadBuf; /* Point to beginning of the Data, and go backwards */
- gNfcip.lastCmd = (uint8_t)cmd; /* Store last cmd sent */
- gNfcip.lastPFB = NFCIP_PFB_INVALID; /* Reset last pfb sent */
- /*******************************************************************************/
- /* Compute outgoing NFCIP message */
- /*******************************************************************************/
- switch(cmd) {
- /*******************************************************************************/
- case NFCIP_CMD_ATR_RES:
- case NFCIP_CMD_ATR_REQ:
- rfalNfcDepSetNFCID(payloadBuf, gNfcip.cfg.nfcid, gNfcip.cfg.nfcidLen); /* NFCID */
- txBufIt += RFAL_NFCDEP_NFCID3_LEN;
- payloadBuf[txBufIt++] = gNfcip.cfg.did; /* DID */
- payloadBuf[txBufIt++] = gNfcip.cfg.bs; /* BS */
- payloadBuf[txBufIt++] = gNfcip.cfg.br; /* BR */
- if(cmd == NFCIP_CMD_ATR_RES) {
- payloadBuf[txBufIt++] = gNfcip.cfg.to; /* ATR_RES[ TO ] */
- }
- if(gNfcip.cfg.gbLen > 0U) {
- payloadBuf[txBufIt++] = nfcip_PPwGB(gNfcip.cfg.lr); /* PP signalling GB */
- ST_MEMCPY(
- &payloadBuf[txBufIt], gNfcip.cfg.gb, gNfcip.cfg.gbLen); /* set General Bytes */
- txBufIt += gNfcip.cfg.gbLen;
- } else {
- payloadBuf[txBufIt++] = rfalNfcDepLR2PP(gNfcip.cfg.lr); /* PP without GB */
- }
- if((txBufIt + RFAL_NFCDEP_CMDTYPE_LEN + RFAL_NFCDEP_CMD_LEN) >
- RFAL_NFCDEP_ATRREQ_MAX_LEN) /* Check max ATR length (ATR_REQ = ATR_RES)*/
- {
- return ERR_PARAM;
- }
- break;
- /*******************************************************************************/
- case NFCIP_CMD_WUP_REQ: /* ISO 18092 - 12.5.2.1 */
- rfalNfcDepSetNFCID((payloadBuf), gNfcip.cfg.nfcid, gNfcip.cfg.nfcidLen); /* NFCID */
- txBufIt += RFAL_NFCDEP_NFCID3_LEN;
- *(--txBlock) = gNfcip.cfg.did; /* DID */
- break;
- /*******************************************************************************/
- case NFCIP_CMD_WUP_RES: /* ISO 18092 - 12.5.2.2 */
- case NFCIP_CMD_PSL_REQ:
- case NFCIP_CMD_PSL_RES:
- *(--txBlock) = gNfcip.cfg.did; /* DID */
- break;
- /*******************************************************************************/
- case NFCIP_CMD_RLS_REQ:
- case NFCIP_CMD_RLS_RES:
- case NFCIP_CMD_DSL_REQ:
- case NFCIP_CMD_DSL_RES:
- /* Digital 1.0 - 14.8.1.1 & 14.9.1.1 & 14.10.1.1 Only add DID if not 0 */
- if(gNfcip.cfg.did != RFAL_NFCDEP_DID_NO) {
- *(--txBlock) = gNfcip.cfg.did; /* DID */
- }
- break;
- /*******************************************************************************/
- case NFCIP_CMD_DEP_REQ:
- case NFCIP_CMD_DEP_RES:
- /* Compute optional PFB bits */
- if(gNfcip.cfg.did != RFAL_NFCDEP_DID_NO) {
- pfb |= NFCIP_PFB_DID_BIT;
- }
- if(gNfcip.cfg.nad != RFAL_NFCDEP_NAD_NO) {
- pfb |= NFCIP_PFB_NAD_BIT;
- }
- if((gNfcip.isTxChaining) && (nfcip_PFBisIPDU(pfb))) {
- pfb |= NFCIP_PFB_MI_BIT;
- }
- /* Store PFB for future handling */
- gNfcip.lastPFB = pfb; /* store PFB sent */
- if(!nfcip_PFBisSATN(pfb)) {
- gNfcip.lastPFBnATN = pfb; /* store last PFB different then ATN */
- }
- /* Add NAD if it is to be supported */
- if(gNfcip.cfg.nad != RFAL_NFCDEP_NAD_NO) {
- *(--txBlock) = gNfcip.cfg.nad; /* NAD */
- }
- /* Digital 1.0 - 14.8.1.1 & 14.8.1.1 Only add DID if not 0 */
- if(gNfcip.cfg.did != RFAL_NFCDEP_DID_NO) {
- *(--txBlock) = gNfcip.cfg.did; /* DID */
- }
- *(--txBlock) = pfb; /* PFB */
- /* NCI 1.0 - Check if Empty frames are allowed */
- if((paylLen == 0U) && nfcipIsEmptyDEPDisabled(gNfcip.cfg.oper) && nfcip_PFBisIPDU(pfb)) {
- return ERR_PARAM;
- }
- break;
- /*******************************************************************************/
- default:
- return ERR_PARAM;
- }
- /*******************************************************************************/
- /* Prepend Header */
- /*******************************************************************************/
- *(--txBlock) = (uint8_t)cmd; /* CMD */
- *(--txBlock) = (uint8_t)(nfcipCmdIsReq(cmd) ? NFCIP_REQ : NFCIP_RES); /* CMDType */
- txBufIt += paylLen + (uint16_t)((uint32_t)payloadBuf -
- (uint32_t)txBlock); /* Calculate overall buffer size */
- if(txBufIt > gNfcip.fsc) /* Check if msg length violates the maximum payload size FSC */
- {
- return ERR_NOTSUPP;
- }
- /*******************************************************************************/
- return nfcipDataTx(txBlock, txBufIt, fwt);
- }
- /*
- ******************************************************************************
- * GLOBAL FUNCTIONS
- ******************************************************************************
- */
- /*******************************************************************************/
- static void nfcipConfig(const rfalNfcDepConfigs* cfg) {
- if(cfg == NULL) {
- return;
- }
- ST_MEMCPY(&gNfcip.cfg, cfg, sizeof(rfalNfcDepConfigs)); /* Copy given config to local */
- gNfcip.cfg.to =
- MIN(RFAL_NFCDEP_WT_TRG_MAX, gNfcip.cfg.to); /* Ensure proper WT value */
- gNfcip.cfg.did = nfcip_DIDMax(gNfcip.cfg.did); /* Ensure proper DID value */
- gNfcip.fsc = rfalNfcDepLR2FS(gNfcip.cfg.lr); /* Calculate FSC based on given LR */
- gNfcip.state =
- ((gNfcip.cfg.role == RFAL_NFCDEP_ROLE_TARGET) ? NFCIP_ST_TARG_WAIT_ATR :
- NFCIP_ST_INIT_IDLE);
- }
- /*******************************************************************************/
- static ReturnCode nfcipRun(uint16_t* outActRxLen, bool* outIsChaining) {
- ReturnCode ret;
- ret = ERR_SYNTAX;
- nfcipLogD(" NFCIP Run() state: %d \r\n", gNfcip.state);
- switch(gNfcip.state) {
- /*******************************************************************************/
- case NFCIP_ST_IDLE:
- case NFCIP_ST_INIT_DEP_IDLE:
- case NFCIP_ST_TARG_DEP_IDLE:
- case NFCIP_ST_TARG_DEP_SLEEP:
- return ERR_NONE;
- /*******************************************************************************/
- case NFCIP_ST_INIT_DEP_TX:
- nfcipLogD(" NFCIP(I) Tx PNI: %d txLen: %d \r\n", gNfcip.pni, gNfcip.txBufLen);
- ret = nfcipTx(
- NFCIP_CMD_DEP_REQ,
- gNfcip.txBuf,
- &gNfcip.txBuf[gNfcip.txBufPaylPos],
- gNfcip.txBufLen,
- nfcip_PFBIPDU(gNfcip.pni),
- (gNfcip.cfg.fwt + gNfcip.cfg.dFwt));
- switch(ret) {
- case ERR_NONE:
- gNfcip.state = NFCIP_ST_INIT_DEP_RX;
- break;
- case ERR_PARAM:
- default:
- gNfcip.state = NFCIP_ST_INIT_DEP_IDLE;
- return ret;
- }
- /* fall through */
- /*******************************************************************************/
- case NFCIP_ST_INIT_DEP_RX: /* PRQA S 2003 # MISRA 16.3 - Intentional fall through */
- ret = nfcipDataRx(false);
- if(ret != ERR_BUSY) {
- ret = nfcipInitiatorHandleDEP(ret, *gNfcip.rxRcvdLen, outActRxLen, outIsChaining);
- }
- break;
- /*******************************************************************************/
- case NFCIP_ST_TARG_DEP_RTOX:
- if(!nfcipTimerisExpired(gNfcip.RTOXTimer)) /* Do nothing until RTOX timer has expired */
- {
- return ERR_BUSY;
- }
- /* If we cannot send a RTOX raise a Timeout error so that we do not
- * hold the field On forever in AP2P */
- if(nfcipIsRTOXReqDisabled(gNfcip.cfg.oper)) {
- /* We should reEnable Rx, and measure time between our field Off to
- * either report link loss or recover #287 */
- nfcipLogI(" NFCIP(T) RTOX not sent due to config, NOT reenabling Rx \r\n");
- return ERR_TIMEOUT;
- }
- if(gNfcip.cntRTOXRetrys++ >
- RFAL_NFCDEP_MAX_RTOX_RETRYS) /* Check maximum consecutive RTOX requests */
- {
- return ERR_PROTO;
- }
- nfcipLogI(" NFCIP(T) RTOX sent \r\n");
- gNfcip.lastRTOX =
- nfcip_RTOXTargMax(gNfcip.cfg.to); /* Calculate requested RTOX value, and send it */
- EXIT_ON_ERR(ret, nfcipDEPControlMsg(nfcip_PFBSPDU_TO(), gNfcip.lastRTOX));
- /* Set waiting for RTOX Ack Flag */
- gNfcip.isWait4RTOX = true;
- gNfcip.state = NFCIP_ST_TARG_DEP_RX; /* Go back to Rx to process RTOX ack */
- return ERR_BUSY;
- /*******************************************************************************/
- case NFCIP_ST_TARG_DEP_TX:
- nfcipLogD(" NFCIP(T) Tx PNI: %d txLen: %d \r\n", gNfcip.pni, gNfcip.txBufLen);
- ret = nfcipTx(
- NFCIP_CMD_DEP_RES,
- gNfcip.txBuf,
- &gNfcip.txBuf[gNfcip.txBufPaylPos],
- gNfcip.txBufLen,
- nfcip_PFBIPDU(gNfcip.pni),
- NFCIP_NO_FWT);
- /* Clear flags */
- gNfcip.isTxPending = false;
- gNfcip.isWait4RTOX = false;
- /* Digital 1.0 14.12.3.4 Increment the current PNI after Tx */
- gNfcip.pni = nfcip_PNIInc(gNfcip.pni);
- switch(ret) {
- case ERR_NONE:
- gNfcip.state = NFCIP_ST_TARG_DEP_RX; /* All OK, goto Rx state */
- break;
- case ERR_PARAM:
- default:
- gNfcip.state = NFCIP_ST_TARG_DEP_IDLE; /* Upon Tx error, goto IDLE state */
- return ret;
- }
- /* fall through */
- /*******************************************************************************/
- case NFCIP_ST_TARG_DEP_RX: /* PRQA S 2003 # MISRA 16.3 - Intentional fall through */
- if(gNfcip.isReqPending) /* if already has Data should be from a DEP from nfcipTargetHandleActivation() */
- {
- nfcipLogD(" NFCIP(T) Skipping Rx Using DEP from Activation \r\n");
- gNfcip.isReqPending = false;
- ret = ERR_NONE;
- } else {
- ret = nfcipDataRx(false);
- }
- if(ret != ERR_BUSY) {
- ret = nfcipTargetHandleRX(ret, outActRxLen, outIsChaining);
- }
- break;
- /*******************************************************************************/
- default:
- /* MISRA 16.4: no empty default statement (a comment being enough) */
- break;
- }
- return ret;
- }
- /*******************************************************************************/
- void rfalNfcDepSetDeactivatingCallback(rfalNfcDepDeactCallback pFunc) {
- gNfcip.isDeactivating = pFunc;
- }
- /*******************************************************************************/
- void rfalNfcDepInitialize(void) {
- nfcipLogD(" NFCIP Ini() \r\n");
- gNfcip.state = NFCIP_ST_IDLE;
- gNfcip.isDeactivating = NULL;
- gNfcip.isTxPending = false;
- gNfcip.isWait4RTOX = false;
- gNfcip.isReqPending = false;
- gNfcip.cfg.oper =
- (RFAL_NFCDEP_OPER_FULL_MI_DIS | RFAL_NFCDEP_OPER_EMPTY_DEP_EN | RFAL_NFCDEP_OPER_ATN_EN |
- RFAL_NFCDEP_OPER_RTOX_REQ_EN);
- gNfcip.cfg.did = RFAL_NFCDEP_DID_NO;
- gNfcip.cfg.nad = RFAL_NFCDEP_NAD_NO;
- gNfcip.cfg.br = RFAL_NFCDEP_Bx_NO_HIGH_BR;
- gNfcip.cfg.bs = RFAL_NFCDEP_Bx_NO_HIGH_BR;
- gNfcip.cfg.lr = RFAL_NFCDEP_LR_254;
- gNfcip.fsc = rfalNfcDepLR2FS(gNfcip.cfg.lr);
- gNfcip.cfg.gbLen = 0;
- gNfcip.cfg.fwt = RFAL_NFCDEP_MAX_FWT;
- gNfcip.cfg.dFwt = RFAL_NFCDEP_MAX_FWT;
- gNfcip.pni = 0;
- /* Destroy any ongoing RTOX timer*/
- nfcipTimerDestroy(gNfcip.RTOXTimer);
- gNfcip.RTOXTimer = 0U;
- gNfcip.PDUTxPos = 0;
- gNfcip.PDURxPos = 0;
- gNfcip.PDUParam.rxLen = NULL;
- gNfcip.PDUParam.rxBuf = NULL;
- gNfcip.PDUParam.txBuf = NULL;
- nfcipClearCounters();
- }
- /*******************************************************************************/
- static void nfcipSetDEPParams(const rfalNfcDepDEPParams* DEPParams) {
- nfcipLogD(" NFCIP SetDEP() txLen: %d \r\n", DEPParams->txBufLen);
- gNfcip.isTxChaining = DEPParams->txChaining;
- gNfcip.txBuf = DEPParams->txBuf;
- gNfcip.rxBuf = DEPParams->rxBuf;
- gNfcip.txBufLen = DEPParams->txBufLen;
- gNfcip.rxBufLen = DEPParams->rxBufLen;
- gNfcip.txBufPaylPos = DEPParams->txBufPaylPos;
- gNfcip.rxBufPaylPos = DEPParams->rxBufPaylPos;
- if(DEPParams->did != RFAL_NFCDEP_DID_KEEP) {
- gNfcip.cfg.did = nfcip_DIDMax(DEPParams->did);
- }
- gNfcip.cfg.fwt = DEPParams->fwt;
- gNfcip.cfg.dFwt = DEPParams->dFwt;
- gNfcip.fsc = DEPParams->fsc;
- if(gNfcip.cfg.role == RFAL_NFCDEP_ROLE_TARGET) {
- /* If there's any data to be sent go for Tx */
- if(DEPParams->txBufLen > 0U) {
- /* Ensure that an RTOX Ack is not being expected at moment */
- if(!gNfcip.isWait4RTOX) {
- gNfcip.state = NFCIP_ST_TARG_DEP_TX;
- return;
- } else {
- /* If RTOX Ack is expected, signal a pending Tx to be transmitted right after */
- gNfcip.isTxPending = true;
- nfcipLogW(" NFCIP(T) Waiting RTOX, queueing outgoing DEP Block \r\n");
- }
- }
- /*Digital 1.0 14.12.4.1 In target mode the first PDU MUST be sent by the Initiator */
- gNfcip.state = NFCIP_ST_TARG_DEP_RX;
- return;
- }
- /* New data TxRx request clear previous error counters for consecutive TxRx without reseting communication/protocol layer*/
- nfcipClearCounters();
- gNfcip.state = NFCIP_ST_INIT_DEP_TX;
- }
- /*******************************************************************************/
- bool rfalNfcDepTargetRcvdATR(void) {
- return (
- (gNfcip.cfg.role == RFAL_NFCDEP_ROLE_TARGET) && nfcipIsTarget(gNfcip.state) &&
- (gNfcip.state > NFCIP_ST_TARG_WAIT_ATR));
- }
- /*******************************************************************************/
- bool rfalNfcDepIsAtrReq(const uint8_t* buf, uint16_t bufLen, uint8_t* nfcid3) {
- uint8_t msgIt;
- msgIt = 0;
- if((bufLen < RFAL_NFCDEP_ATRREQ_MIN_LEN) || (bufLen > RFAL_NFCDEP_ATRREQ_MAX_LEN)) {
- return false;
- }
- if(buf[msgIt++] != NFCIP_REQ) {
- return false;
- }
- if(buf[msgIt++] != (uint8_t)NFCIP_CMD_ATR_REQ) {
- return false;
- }
- /* Output NFID3 if requested */
- if(nfcid3 != NULL) {
- ST_MEMCPY(nfcid3, &buf[RFAL_NFCDEP_ATR_REQ_NFCID3_POS], RFAL_NFCDEP_NFCID3_LEN);
- }
- return true;
- }
- /*******************************************************************************/
- static ReturnCode nfcipTargetHandleActivation(rfalNfcDepDevice* nfcDepDev, uint8_t* outBRS) {
- ReturnCode ret;
- uint8_t msgIt;
- uint8_t txBuf[RFAL_NFCDEP_HEADER_PAD + NFCIP_PSLRES_LEN];
- /*******************************************************************************/
- /* Check if we are in correct state */
- /*******************************************************************************/
- if(gNfcip.state != NFCIP_ST_TARG_WAIT_ACTV) {
- return ERR_WRONG_STATE;
- }
- /*******************************************************************************/
- /* Check required parameters */
- /*******************************************************************************/
- if(outBRS == NULL) {
- return ERR_PARAM;
- }
- /*******************************************************************************/
- /* Wait and process incoming cmd (PSL / DEP) */
- /*******************************************************************************/
- ret = nfcipDataRx(false);
- if(ret != ERR_NONE) {
- return ret;
- }
- msgIt = 0;
- *outBRS = RFAL_NFCDEP_BRS_MAINTAIN; /* set out BRS to be maintained */
- msgIt++; /* Skip LEN byte */
- if(gNfcip.rxBuf[msgIt++] != NFCIP_REQ) {
- return ERR_PROTO;
- }
- if(gNfcip.rxBuf[msgIt] == (uint8_t)NFCIP_CMD_PSL_REQ) {
- msgIt++;
- if(gNfcip.rxBuf[msgIt++] != gNfcip.cfg.did) /* Checking DID */
- {
- return ERR_PROTO;
- }
- nfcipLogI(" NFCIP(T) PSL REQ rcvd \r\n");
- *outBRS = gNfcip.rxBuf[msgIt++]; /* assign output BRS value */
- /* Store FSL(LR) and update current config */
- gNfcip.cfg.lr = (gNfcip.rxBuf[msgIt++] & RFAL_NFCDEP_LR_VAL_MASK);
- gNfcip.fsc = rfalNfcDepLR2FS(gNfcip.cfg.lr);
- /*******************************************************************************/
- /* Update NFC-DDE Device info */
- if(nfcDepDev != NULL) {
- /* Update Bitrate info */
- /* PRQA S 4342 2 # MISRA 10.5 - Layout of enum rfalBitRate and definition of rfalNfcDepBRS2DSI guarantee no invalid enum values to be created */
- nfcDepDev->info.DSI = (rfalBitRate)rfalNfcDepBRS2DSI(
- *outBRS); /* DSI codes the bit rate from Initiator to Target */
- nfcDepDev->info.DRI = (rfalBitRate)rfalNfcDepBRS2DRI(
- *outBRS); /* DRI codes the bit rate from Target to Initiator */
- /* Update Length Reduction and Frame Size */
- nfcDepDev->info.LR = gNfcip.cfg.lr;
- nfcDepDev->info.FS = gNfcip.fsc;
- /* Update PPi byte */
- nfcDepDev->activation.Initiator.ATR_REQ.PPi &= ~RFAL_NFCDEP_PP_LR_MASK;
- nfcDepDev->activation.Initiator.ATR_REQ.PPi |= rfalNfcDepLR2PP(gNfcip.cfg.lr);
- }
- rfalSetBitRate(RFAL_BR_KEEP, gNfcip.nfcDepDev->info.DSI);
- EXIT_ON_ERR(ret, nfcipTx(NFCIP_CMD_PSL_RES, txBuf, NULL, 0, 0, NFCIP_NO_FWT));
- } else {
- if(gNfcip.rxBuf[msgIt] == (uint8_t)NFCIP_CMD_DEP_REQ) {
- msgIt++;
- /*******************************************************************************/
- /* Digital 1.0 14.12.3.1 PNI must be initialized to 0 */
- if(nfcip_PBF_PNI(gNfcip.rxBuf[msgIt]) != 0U) {
- return ERR_PROTO;
- }
- /*******************************************************************************/
- /* Digital 1.0 14.8.2.1 check if DID is expected and match -> Protocol Error */
- if(nfcip_PFBhasDID(gNfcip.rxBuf[msgIt])) {
- if(gNfcip.rxBuf[++msgIt] != gNfcip.cfg.did) {
- return ERR_PROTO;
- }
- } else if(gNfcip.cfg.did != RFAL_NFCDEP_DID_NO) /* DID expected but not rcv */
- {
- return ERR_PROTO;
- } else {
- /* MISRA 15.7 - Empty else */
- }
- }
- /* Signal Request pending to be digested on normal Handling (DEP_REQ, DSL_REQ, RLS_REQ) */
- gNfcip.isReqPending = true;
- }
- gNfcip.state = NFCIP_ST_TARG_DEP_RX;
- return ERR_NONE;
- }
- /*******************************************************************************/
- ReturnCode
- rfalNfcDepATR(const rfalNfcDepAtrParam* param, rfalNfcDepAtrRes* atrRes, uint8_t* atrResLen) {
- ReturnCode ret;
- rfalNfcDepConfigs cfg;
- uint16_t rxLen;
- uint8_t msgIt;
- uint8_t txBuf[RFAL_NFCDEP_ATRREQ_MAX_LEN];
- uint8_t rxBuf[NFCIP_ATRRES_BUF_LEN];
- if((param == NULL) || (atrRes == NULL) || (atrResLen == NULL)) {
- return ERR_PARAM;
- }
- /*******************************************************************************/
- /* Configure NFC-DEP layer */
- /*******************************************************************************/
- cfg.did = param->DID;
- cfg.nad = param->NAD;
- cfg.fwt = RFAL_NFCDEP_MAX_FWT;
- cfg.dFwt = RFAL_NFCDEP_MAX_FWT;
- cfg.br = param->BR;
- cfg.bs = param->BS;
- cfg.lr = param->LR;
- cfg.to = RFAL_NFCDEP_WT_TRG_MAX; /* Not used in Initiator mode */
- cfg.gbLen = param->GBLen;
- if(cfg.gbLen > 0U) /* MISRA 21.18 */
- {
- ST_MEMCPY(cfg.gb, param->GB, cfg.gbLen);
- }
- cfg.nfcidLen = param->nfcidLen;
- if(cfg.nfcidLen > 0U) /* MISRA 21.18 */
- {
- ST_MEMCPY(cfg.nfcid, param->nfcid, cfg.nfcidLen);
- }
- cfg.role = RFAL_NFCDEP_ROLE_INITIATOR;
- cfg.oper = param->operParam;
- cfg.commMode = param->commMode;
- rfalNfcDepInitialize();
- nfcipConfig(&cfg);
- /*******************************************************************************/
- /* Send ATR_REQ */
- /*******************************************************************************/
- EXIT_ON_ERR(
- ret,
- nfcipTxRx(
- NFCIP_CMD_ATR_REQ,
- txBuf,
- nfcipRWTActivation(),
- NULL,
- 0,
- rxBuf,
- NFCIP_ATRRES_BUF_LEN,
- &rxLen));
- /*******************************************************************************/
- /* ATR sent, check response */
- /*******************************************************************************/
- msgIt = 0;
- rxLen = ((uint16_t)rxBuf[msgIt++] - RFAL_NFCDEP_LEN_LEN); /* use LEN byte */
- if((rxLen < RFAL_NFCDEP_ATRRES_MIN_LEN) ||
- (rxLen > RFAL_NFCDEP_ATRRES_MAX_LEN)) /* Checking length: ATR_RES */
- {
- return ERR_PROTO;
- }
- if(rxBuf[msgIt++] != NFCIP_RES) /* Checking if is a response*/
- {
- return ERR_PROTO;
- }
- if(rxBuf[msgIt++] != (uint8_t)NFCIP_CMD_ATR_RES) /* Checking if is a ATR RES */
- {
- return ERR_PROTO;
- }
- ST_MEMCPY((uint8_t*)atrRes, (rxBuf + RFAL_NFCDEP_LEN_LEN), rxLen);
- *atrResLen = (uint8_t)rxLen;
- return ERR_NONE;
- }
- /*******************************************************************************/
- ReturnCode rfalNfcDepPSL(uint8_t BRS, uint8_t FSL) {
- ReturnCode ret;
- uint16_t rxLen;
- uint8_t msgIt;
- uint8_t txBuf[NFCIP_PSLREQ_LEN + NFCIP_PSLPAY_LEN];
- uint8_t rxBuf[NFCIP_PSLRES_LEN];
- msgIt = NFCIP_PSLREQ_LEN;
- txBuf[msgIt++] = BRS;
- txBuf[msgIt++] = FSL;
- /*******************************************************************************/
- /* Send PSL REQ and wait for response */
- /*******************************************************************************/
- EXIT_ON_ERR(
- ret,
- nfcipTxRx(
- NFCIP_CMD_PSL_REQ,
- txBuf,
- nfcipRWTActivation(),
- &txBuf[NFCIP_PSLREQ_LEN],
- (msgIt - NFCIP_PSLREQ_LEN),
- rxBuf,
- NFCIP_PSLRES_LEN,
- &rxLen));
- /*******************************************************************************/
- /* PSL sent, check response */
- /*******************************************************************************/
- msgIt = 0;
- rxLen = (uint16_t)(rxBuf[msgIt++]); /* use LEN byte */
- if(rxLen < NFCIP_PSLRES_LEN) /* Checking length: LEN + RLS_RES */
- {
- return ERR_PROTO;
- }
- if(rxBuf[msgIt++] != NFCIP_RES) /* Checking if is a response */
- {
- return ERR_PROTO;
- }
- if(rxBuf[msgIt++] != (uint8_t)NFCIP_CMD_PSL_RES) /* Checking if is a PSL RES */
- {
- return ERR_PROTO;
- }
- if(rxBuf[msgIt++] != gNfcip.cfg.did) /* Checking DID */
- {
- return ERR_PROTO;
- }
- return ERR_NONE;
- }
- /*******************************************************************************/
- ReturnCode rfalNfcDepDSL(void) {
- ReturnCode ret;
- uint8_t txBuf[RFAL_NFCDEP_HEADER_PAD + NFCIP_DSLREQ_LEN];
- uint8_t rxBuf[NFCIP_DSLRES_LEN];
- uint8_t rxMsgIt;
- uint16_t rxLen = 0;
- if(gNfcip.cfg.role == RFAL_NFCDEP_ROLE_TARGET) {
- return ERR_NONE; /* Target has no deselect procedure */
- }
- /* Repeating a DSL REQ is optional, not doing it */
- EXIT_ON_ERR(
- ret,
- nfcipTxRx(
- NFCIP_CMD_DSL_REQ,
- txBuf,
- nfcipRWTActivation(),
- NULL,
- 0,
- rxBuf,
- (uint16_t)sizeof(rxBuf),
- &rxLen));
- /*******************************************************************************/
- rxMsgIt = 0;
- if(rxBuf[rxMsgIt++] < NFCIP_DSLRES_MIN) /* Checking length: LEN + DSL_RES */
- {
- return ERR_PROTO;
- }
- if(rxBuf[rxMsgIt++] != NFCIP_RES) /* Checking if is a response */
- {
- return ERR_PROTO;
- }
- if(rxBuf[rxMsgIt++] != (uint8_t)NFCIP_CMD_DSL_RES) /* Checking if is DSL RES */
- {
- return ERR_PROTO;
- }
- if(gNfcip.cfg.did != RFAL_NFCDEP_DID_NO) {
- if(rxBuf[rxMsgIt++] != gNfcip.cfg.did) {
- return ERR_PROTO;
- }
- }
- return ERR_NONE;
- }
- /*******************************************************************************/
- ReturnCode rfalNfcDepRLS(void) {
- ReturnCode ret;
- uint8_t txBuf[RFAL_NFCDEP_HEADER_PAD + NFCIP_RLSREQ_LEN];
- uint8_t rxBuf[NFCIP_RLSRES_LEN];
- uint8_t rxMsgIt;
- uint16_t rxLen = 0;
- if(gNfcip.cfg.role == RFAL_NFCDEP_ROLE_TARGET) /* Target has no release procedure */
- {
- return ERR_NONE;
- }
- /* Repeating a RLS REQ is optional, not doing it */
- EXIT_ON_ERR(
- ret,
- nfcipTxRx(
- NFCIP_CMD_RLS_REQ,
- txBuf,
- nfcipRWTActivation(),
- NULL,
- 0,
- rxBuf,
- (uint16_t)sizeof(rxBuf),
- &rxLen));
- /*******************************************************************************/
- rxMsgIt = 0;
- if(rxBuf[rxMsgIt++] < NFCIP_RLSRES_MIN) /* Checking length: LEN + RLS_RES */
- {
- return ERR_PROTO;
- }
- if(rxBuf[rxMsgIt++] != NFCIP_RES) /* Checking if is a response */
- {
- return ERR_PROTO;
- }
- if(rxBuf[rxMsgIt++] != (uint8_t)NFCIP_CMD_RLS_RES) /* Checking if is RLS RES */
- {
- return ERR_PROTO;
- }
- if(gNfcip.cfg.did != RFAL_NFCDEP_DID_NO) {
- if(rxBuf[rxMsgIt++] != gNfcip.cfg.did) {
- return ERR_PROTO;
- }
- }
- return ERR_NONE;
- }
- /*******************************************************************************/
- ReturnCode rfalNfcDepInitiatorHandleActivation(
- rfalNfcDepAtrParam* param,
- rfalBitRate desiredBR,
- rfalNfcDepDevice* nfcDepDev) {
- ReturnCode ret;
- uint8_t maxRetyrs;
- uint8_t PSL_BRS;
- uint8_t PSL_FSL;
- bool sendPSL;
- if((param == NULL) || (nfcDepDev == NULL)) {
- return ERR_PARAM;
- }
- param->NAD = RFAL_NFCDEP_NAD_NO; /* Digital 1.1 16.6.2.9 Initiator SHALL NOT use NAD */
- maxRetyrs = NFCIP_ATR_RETRY_MAX;
- /*******************************************************************************/
- /* Send ATR REQ and wait for response */
- /*******************************************************************************/
- do { /* Upon transmission error ATR REQ should be retried */
- ret = rfalNfcDepATR(
- param,
- &nfcDepDev->activation.Target.ATR_RES,
- &nfcDepDev->activation.Target.ATR_RESLen);
- if(nfcipIsTransmissionError(ret)) {
- continue;
- }
- break;
- } while((maxRetyrs--) != 0U);
- if(ret != ERR_NONE) {
- return ret;
- }
- /*******************************************************************************/
- /* Compute NFC-DEP device with ATR_RES */
- /*******************************************************************************/
- nfcDepDev->info.GBLen = (nfcDepDev->activation.Target.ATR_RESLen - RFAL_NFCDEP_ATRRES_MIN_LEN);
- nfcDepDev->info.DID = nfcDepDev->activation.Target.ATR_RES.DID;
- nfcDepDev->info.NAD =
- RFAL_NFCDEP_NAD_NO; /* Digital 1.1 16.6.3.11 Initiator SHALL ignore b1 of PPt */
- nfcDepDev->info.LR = rfalNfcDepPP2LR(nfcDepDev->activation.Target.ATR_RES.PPt);
- nfcDepDev->info.FS = rfalNfcDepLR2FS(nfcDepDev->info.LR);
- nfcDepDev->info.WT = (nfcDepDev->activation.Target.ATR_RES.TO & RFAL_NFCDEP_WT_MASK);
- nfcDepDev->info.FWT = rfalNfcDepCalculateRWT(nfcDepDev->info.WT);
- nfcDepDev->info.dFWT = RFAL_NFCDEP_WT_DELTA;
- rfalGetBitRate(&nfcDepDev->info.DSI, &nfcDepDev->info.DRI);
- /*******************************************************************************/
- /* Check if a PSL needs to be sent */
- /*******************************************************************************/
- sendPSL = false;
- PSL_BRS = rfalNfcDepDx2BRS(
- nfcDepDev->info.DSI); /* Set current bit rate divisor on both directions */
- PSL_FSL = nfcDepDev->info.LR; /* Set current Frame Size */
- /* Activity 1.0 9.4.4.15 & 9.4.6.3 NFC-DEP Activation PSL
- * Activity 2.0 9.4.4.17 & 9.4.6.6 NFC-DEP Activation PSL
- *
- * PSL_REQ shall only be sent if desired bit rate is different from current (Activity 1.0)
- * PSL_REQ shall be sent to update LR or bit rate (Activity 2.0)
- * */
- #if 0 /* PSL due to LR is disabled, can be enabled if desired*/
- /*******************************************************************************/
- /* Check Frame Size */
- /*******************************************************************************/
- if( gNfcip.cfg.lr < nfcDepDev->info.LR ) /* If our Length reduction is smaller */
- {
- sendPSL = true;
-
- nfcDepDev->info.LR = MIN( nfcDepDev->info.LR, gNfcip.cfg.lr );
-
- gNfcip.cfg.lr = nfcDepDev->info.LR; /* Update nfcip LR to be used */
- gNfcip.fsc = rfalNfcDepLR2FS( gNfcip.cfg.lr ); /* Update nfcip FSC to be used */
-
- PSL_FSL = gNfcip.cfg.lr; /* Set LR to be sent */
-
- nfcipLogI( " NFCIP(I) Frame Size differ, PSL new fsc: %d \r\n", gNfcip.fsc );
- }
- #endif
- /*******************************************************************************/
- /* Check Baud rates */
- /*******************************************************************************/
- if((nfcDepDev->info.DSI != desiredBR) &&
- (desiredBR != RFAL_BR_KEEP)) /* if desired BR is different */
- {
- if(nfcipDxIsSupported(
- (uint8_t)desiredBR,
- nfcDepDev->activation.Target.ATR_RES.BRt,
- nfcDepDev->activation.Target.ATR_RES
- .BSt)) /* if desired BR is supported */ /* MISRA 13.5 */
- {
- sendPSL = true;
- PSL_BRS = rfalNfcDepDx2BRS(desiredBR);
- nfcipLogI(" NFCIP(I) BR differ, PSL BR: 0x%02X \r\n", PSL_BRS);
- }
- }
- /*******************************************************************************/
- if(sendPSL) {
- /*******************************************************************************/
- /* Send PSL REQ and wait for response */
- /*******************************************************************************/
- EXIT_ON_ERR(ret, rfalNfcDepPSL(PSL_BRS, PSL_FSL));
- /* Check if bit rate has been changed */
- if(nfcDepDev->info.DSI != desiredBR) {
- /* Check if device was in Passive NFC-A and went to higher bit rates, use NFC-F */
- if((nfcDepDev->info.DSI == RFAL_BR_106) &&
- (gNfcip.cfg.commMode == RFAL_NFCDEP_COMM_PASSIVE)) {
- #if RFAL_FEATURE_NFCF
- /* If Passive initialize NFC-F module */
- rfalNfcfPollerInitialize(desiredBR);
- #else /* RFAL_FEATURE_NFCF */
- return ERR_NOTSUPP;
- #endif /* RFAL_FEATURE_NFCF */
- }
- nfcDepDev->info.DRI = desiredBR; /* DSI Bit Rate coding from Initiator to Target */
- nfcDepDev->info.DSI = desiredBR; /* DRI Bit Rate coding from Target to Initiator */
- rfalSetBitRate(nfcDepDev->info.DSI, nfcDepDev->info.DRI);
- }
- return ERR_NONE; /* PSL has been sent */
- }
- return ERR_NONE; /* No PSL has been sent */
- }
- /*******************************************************************************/
- uint32_t rfalNfcDepCalculateRWT(uint8_t wt) {
- /* Digital 1.0 14.6.3.8 & Digital 1.1 16.6.3.9 */
- /* Digital 1.1 16.6.3.9 treat all RFU values as WT=14 */
- uint8_t responseWaitTime = MIN(RFAL_NFCDEP_WT_INI_MAX, wt);
- return (uint32_t)rfalNfcDepWT2RWT(responseWaitTime);
- }
- /*******************************************************************************/
- static ReturnCode nfcipDataTx(uint8_t* txBuf, uint16_t txBufLen, uint32_t fwt) {
- return rfalTransceiveBlockingTx(
- txBuf,
- txBufLen,
- gNfcip.rxBuf,
- gNfcip.rxBufLen,
- gNfcip.rxRcvdLen,
- (RFAL_TXRX_FLAGS_DEFAULT | (uint32_t)RFAL_TXRX_FLAGS_NFCIP1_ON),
- ((fwt == NFCIP_NO_FWT) ? RFAL_FWT_NONE : fwt));
- }
- /*******************************************************************************/
- static ReturnCode nfcipDataRx(bool blocking) {
- ReturnCode ret;
- /* Perform Rx either blocking or non-blocking */
- if(blocking) {
- ret = rfalTransceiveBlockingRx();
- } else {
- ret = rfalGetTransceiveStatus();
- }
- if(ret != ERR_BUSY) {
- if(gNfcip.rxRcvdLen != NULL) {
- (*gNfcip.rxRcvdLen) = rfalConvBitsToBytes(*gNfcip.rxRcvdLen);
- if((ret == ERR_NONE) && (gNfcip.rxBuf != NULL)) {
- /* Digital 1.1 16.4.1.3 - Length byte LEN SHALL have a value between 3 and 255 -> otherwise treat as Transmission Error *
- * - Ensure that actual received and frame length do match, otherwise treat as Transmission error */
- if((*gNfcip.rxRcvdLen != (uint16_t)*gNfcip.rxBuf) ||
- (*gNfcip.rxRcvdLen < RFAL_NFCDEP_LEN_MIN) ||
- (*gNfcip.rxRcvdLen > RFAL_NFCDEP_LEN_MAX)) {
- return ERR_FRAMING;
- }
- }
- }
- }
- return ret;
- }
- /*******************************************************************************/
- ReturnCode rfalNfcDepListenStartActivation(
- const rfalNfcDepTargetParam* param,
- const uint8_t* atrReq,
- uint16_t atrReqLength,
- rfalNfcDepListenActvParam rxParam) {
- ReturnCode ret;
- rfalNfcDepConfigs cfg;
- if((param == NULL) || (atrReq == NULL) || (rxParam.rxLen == NULL)) {
- return ERR_PARAM;
- }
- /*******************************************************************************/
- /* Check whether is a valid ATR_REQ Compute NFC-DEP device */
- if(!rfalNfcDepIsAtrReq(atrReq, atrReqLength, NULL)) {
- return ERR_PARAM;
- }
- rxParam.nfcDepDev->activation.Initiator.ATR_REQLen =
- (uint8_t)atrReqLength; /* nfcipIsAtrReq() is already checking Min and Max buffer lengths */
- if(atrReqLength > 0U) /* MISRA 21.18 */
- {
- ST_MEMCPY(
- (uint8_t*)&rxParam.nfcDepDev->activation.Initiator.ATR_REQ, atrReq, atrReqLength);
- }
- rxParam.nfcDepDev->info.GBLen = (uint8_t)(atrReqLength - RFAL_NFCDEP_ATRREQ_MIN_LEN);
- rxParam.nfcDepDev->info.DID = rxParam.nfcDepDev->activation.Initiator.ATR_REQ.DID;
- rxParam.nfcDepDev->info.NAD =
- RFAL_NFCDEP_NAD_NO; /* Digital 1.1 16.6.2.9 Initiator SHALL NOT use NAD */
- rxParam.nfcDepDev->info.LR =
- rfalNfcDepPP2LR(rxParam.nfcDepDev->activation.Initiator.ATR_REQ.PPi);
- rxParam.nfcDepDev->info.FS = rfalNfcDepLR2FS(rxParam.nfcDepDev->info.LR);
- rxParam.nfcDepDev->info.WT = 0;
- rxParam.nfcDepDev->info.FWT = NFCIP_NO_FWT;
- rxParam.nfcDepDev->info.dFWT = NFCIP_NO_FWT;
- rfalGetBitRate(&rxParam.nfcDepDev->info.DSI, &rxParam.nfcDepDev->info.DRI);
- /* Store Device Info location, updated upon a PSL */
- gNfcip.nfcDepDev = rxParam.nfcDepDev;
- /*******************************************************************************/
- cfg.did = rxParam.nfcDepDev->activation.Initiator.ATR_REQ.DID;
- cfg.nad = RFAL_NFCDEP_NAD_NO;
- cfg.fwt = RFAL_NFCDEP_MAX_FWT;
- cfg.dFwt = RFAL_NFCDEP_MAX_FWT;
- cfg.br = param->brt;
- cfg.bs = param->bst;
- cfg.lr = rfalNfcDepPP2LR(param->ppt);
- cfg.gbLen = param->GBtLen;
- if(cfg.gbLen > 0U) /* MISRA 21.18 */
- {
- ST_MEMCPY(cfg.gb, param->GBt, cfg.gbLen);
- }
- cfg.nfcidLen = RFAL_NFCDEP_NFCID3_LEN;
- ST_MEMCPY(cfg.nfcid, param->nfcid3, RFAL_NFCDEP_NFCID3_LEN);
- cfg.to = param->to;
- cfg.role = RFAL_NFCDEP_ROLE_TARGET;
- cfg.oper = param->operParam;
- cfg.commMode = param->commMode;
- rfalNfcDepInitialize();
- nfcipConfig(&cfg);
- /*******************************************************************************/
- /* Reply with ATR RES to Initiator */
- /*******************************************************************************/
- gNfcip.rxBuf = (uint8_t*)rxParam.rxBuf;
- gNfcip.rxBufLen = sizeof(rfalNfcDepBufFormat);
- gNfcip.rxRcvdLen = rxParam.rxLen;
- gNfcip.rxBufPaylPos = RFAL_NFCDEP_DEPREQ_HEADER_LEN;
- gNfcip.isChaining = rxParam.isRxChaining;
- gNfcip.txBufPaylPos = RFAL_NFCDEP_DEPREQ_HEADER_LEN;
- EXIT_ON_ERR(ret, nfcipTx(NFCIP_CMD_ATR_RES, (uint8_t*)gNfcip.rxBuf, NULL, 0, 0, NFCIP_NO_FWT));
- gNfcip.state = NFCIP_ST_TARG_WAIT_ACTV;
- return ERR_NONE;
- }
- /*******************************************************************************/
- ReturnCode rfalNfcDepListenGetActivationStatus(void) {
- ReturnCode err;
- uint8_t BRS;
- BRS = RFAL_NFCDEP_BRS_MAINTAIN;
- err = nfcipTargetHandleActivation(gNfcip.nfcDepDev, &BRS);
- switch(err) {
- case ERR_NONE:
- if(BRS != RFAL_NFCDEP_BRS_MAINTAIN) {
- /* DSI codes the bit rate from Initiator to Target */
- /* DRI codes the bit rate from Target to Initiator */
- if(gNfcip.cfg.commMode == RFAL_NFCDEP_COMM_ACTIVE) {
- EXIT_ON_ERR(
- err,
- rfalSetMode(
- RFAL_MODE_LISTEN_ACTIVE_P2P,
- gNfcip.nfcDepDev->info.DRI,
- gNfcip.nfcDepDev->info.DSI));
- } else {
- EXIT_ON_ERR(
- err,
- rfalSetMode(
- ((RFAL_BR_106 == gNfcip.nfcDepDev->info.DRI) ? RFAL_MODE_LISTEN_NFCA :
- RFAL_MODE_LISTEN_NFCF),
- gNfcip.nfcDepDev->info.DRI,
- gNfcip.nfcDepDev->info.DSI));
- }
- }
- break;
- case ERR_BUSY:
- // do nothing
- break;
- case ERR_PROTO:
- default:
- // re-enable receiving of data
- nfcDepReEnableRx(gNfcip.rxBuf, gNfcip.rxBufLen, gNfcip.rxRcvdLen);
- break;
- }
- return err;
- }
- /*******************************************************************************/
- ReturnCode rfalNfcDepStartTransceive(const rfalNfcDepTxRxParam* param) {
- rfalNfcDepDEPParams nfcDepParams;
- nfcDepParams.txBuf = (uint8_t*)param->txBuf;
- nfcDepParams.txBufLen = param->txBufLen;
- nfcDepParams.txChaining = param->isTxChaining;
- nfcDepParams.txBufPaylPos =
- RFAL_NFCDEP_DEPREQ_HEADER_LEN; /* position in txBuf where actual outgoing data is located */
- nfcDepParams.did = RFAL_NFCDEP_DID_KEEP;
- nfcDepParams.rxBufPaylPos = RFAL_NFCDEP_DEPREQ_HEADER_LEN;
- nfcDepParams.rxBuf = (uint8_t*)param->rxBuf;
- nfcDepParams.rxBufLen = sizeof(rfalNfcDepBufFormat);
- nfcDepParams.fsc = param->FSx;
- nfcDepParams.fwt = param->FWT;
- nfcDepParams.dFwt = param->dFWT;
- gNfcip.rxRcvdLen = param->rxLen;
- gNfcip.isChaining = param->isRxChaining;
- nfcipSetDEPParams(&nfcDepParams);
- return ERR_NONE;
- }
- /*******************************************************************************/
- ReturnCode rfalNfcDepGetTransceiveStatus(void) {
- return nfcipRun(gNfcip.rxRcvdLen, gNfcip.isChaining);
- }
- /*******************************************************************************/
- static void rfalNfcDepPdu2BLockParam(
- rfalNfcDepPduTxRxParam pduParam,
- rfalNfcDepTxRxParam* blockParam,
- uint16_t txPos,
- uint16_t rxPos) {
- uint16_t maxInfLen;
- NO_WARNING(rxPos); /* Keep this param for future use */
- blockParam->DID = pduParam.DID;
- blockParam->FSx = pduParam.FSx;
- blockParam->FWT = pduParam.FWT;
- blockParam->dFWT = pduParam.dFWT;
- /* Calculate max INF/Payload to be sent to other device */
- maxInfLen = (blockParam->FSx - (RFAL_NFCDEP_HEADER + RFAL_NFCDEP_DEP_PFB_LEN));
- maxInfLen += ((blockParam->DID != RFAL_NFCDEP_DID_NO) ? RFAL_NFCDEP_DID_LEN : 0U);
- if((pduParam.txBufLen - txPos) > maxInfLen) {
- blockParam->isTxChaining = true;
- blockParam->txBufLen = maxInfLen;
- } else {
- blockParam->isTxChaining = false;
- blockParam->txBufLen = (pduParam.txBufLen - txPos);
- }
- /* TxBuf is moved to the beginning for every Block */
- blockParam->txBuf =
- (rfalNfcDepBufFormat*)pduParam
- .txBuf; /* PRQA S 0310 # MISRA 11.3 - Intentional safe cast to avoiding large buffer duplication */
- blockParam->rxBuf =
- pduParam
- .tmpBuf; /* Simply using the pdu buffer is not possible because of current ACK handling */
- blockParam->isRxChaining = &gNfcip.isPDURxChaining;
- blockParam->rxLen = pduParam.rxLen;
- }
- /*******************************************************************************/
- ReturnCode rfalNfcDepStartPduTransceive(rfalNfcDepPduTxRxParam param) {
- rfalNfcDepTxRxParam txRxParam;
- /* Initialize and store APDU context */
- gNfcip.PDUParam = param;
- gNfcip.PDUTxPos = 0;
- gNfcip.PDURxPos = 0;
- /* Convert PDU TxRxParams to Block TxRxParams */
- rfalNfcDepPdu2BLockParam(gNfcip.PDUParam, &txRxParam, gNfcip.PDUTxPos, gNfcip.PDURxPos);
- return rfalNfcDepStartTransceive(&txRxParam);
- }
- /*******************************************************************************/
- ReturnCode rfalNfcDepGetPduTransceiveStatus(void) {
- ReturnCode ret;
- rfalNfcDepTxRxParam txRxParam;
- ret = rfalNfcDepGetTransceiveStatus();
- switch(ret) {
- /*******************************************************************************/
- case ERR_NONE:
- /* Check if we are still doing chaining on Tx */
- if(gNfcip.isTxChaining) {
- /* Add already Tx bytes */
- gNfcip.PDUTxPos += gNfcip.txBufLen;
- /* Convert APDU TxRxParams to I-Block TxRxParams */
- rfalNfcDepPdu2BLockParam(
- gNfcip.PDUParam, &txRxParam, gNfcip.PDUTxPos, gNfcip.PDURxPos);
- if(txRxParam.txBufLen > 0U) /* MISRA 21.18 */
- {
- /* Move next Block to beginning of APDU Tx buffer */
- ST_MEMCPY(
- gNfcip.PDUParam.txBuf->pdu,
- &gNfcip.PDUParam.txBuf->pdu[gNfcip.PDUTxPos],
- txRxParam.txBufLen);
- }
- EXIT_ON_ERR(ret, rfalNfcDepStartTransceive(&txRxParam));
- return ERR_BUSY;
- }
- /* PDU TxRx is done */
- /* fall through */
- /*******************************************************************************/
- case ERR_AGAIN: /* PRQA S 2003 # MISRA 16.3 - Intentional fall through */
- /* Check if no PDU transceive has been started before (data from rfalNfcDepListenStartActivation) */
- if(gNfcip.PDUParam.rxLen == NULL) {
- /* In Listen mode first chained packet cannot be retrieved via APDU interface */
- if(ret == ERR_AGAIN) {
- return ERR_NOTSUPP;
- }
- /* TxRx is complete and full data is already available */
- return ERR_NONE;
- }
- if((*gNfcip.PDUParam.rxLen) > 0U) /* MISRA 21.18 */
- {
- /* Ensure that data in tmpBuf still fits into PDU buffer */
- if((uint16_t)((uint16_t)gNfcip.PDURxPos + (*gNfcip.PDUParam.rxLen)) >
- RFAL_FEATURE_NFC_DEP_PDU_MAX_LEN) {
- return ERR_NOMEM;
- }
- /* Copy chained packet from tmp buffer to PDU buffer */
- ST_MEMCPY(
- &gNfcip.PDUParam.rxBuf->pdu[gNfcip.PDURxPos],
- gNfcip.PDUParam.tmpBuf->inf,
- *gNfcip.PDUParam.rxLen);
- gNfcip.PDURxPos += *gNfcip.PDUParam.rxLen;
- }
- /* Update output param rxLen */
- *gNfcip.PDUParam.rxLen = gNfcip.PDURxPos;
- /* Wait for following Block or PDU TxRx is done */
- return ((ret == ERR_AGAIN) ? ERR_BUSY : ERR_NONE);
- /*******************************************************************************/
- default:
- /* MISRA 16.4: no empty default statement (a comment being enough) */
- break;
- }
- return ret;
- }
- #endif /* RFAL_FEATURE_NFC_DEP */
|