1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <nfc_api.h>
18#include <rw_api.h>
19#include <phNfcCompId.h>
20#include <phNxpLog.h>
21#include <phNxpExtns_MifareStd.h>
22
23phNxpExtns_Context_t       gphNxpExtns_Context;
24phNciNfc_TransceiveInfo_t  tNciTranscvInfo;
25phFriNfc_sNdefSmtCrdFmt_t  *NdefSmtCrdFmt = NULL;
26phFriNfc_NdefMap_t         *NdefMap = NULL;
27phLibNfc_NdefInfo_t        NdefInfo;
28#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
29pthread_mutex_t SharedDataMutex = PTHREAD_MUTEX_INITIALIZER;
30#endif
31UINT8 current_key[6]={0};
32phNci_mfc_auth_cmd_t       gAuthCmdBuf;
33STATIC NFCSTATUS phNciNfc_SendMfReq(phNciNfc_TransceiveInfo_t tTranscvInfo,
34                                    uint8_t *buff, uint16_t *buffSz);
35STATIC NFCSTATUS phLibNfc_SendRawCmd(phNfc_sTransceiveInfo_t*    pTransceiveInfo,
36                                    pphNciNfc_TransceiveInfo_t   pMappedTranscvIf);
37STATIC NFCSTATUS phLibNfc_SendWrt16Cmd(phNfc_sTransceiveInfo_t*    pTransceiveInfo,
38                                    pphNciNfc_TransceiveInfo_t   pMappedTranscvIf);
39STATIC NFCSTATUS phLibNfc_SendAuthCmd(phNfc_sTransceiveInfo_t *pTransceiveInfo,
40                                      phNciNfc_TransceiveInfo_t  *tNciTranscvInfo) __attribute__((unused));
41STATIC NFCSTATUS phLibNfc_MapCmds(phNciNfc_RFDevType_t         RemDevType,
42                                    phNfc_sTransceiveInfo_t*  pTransceiveInfo,
43                                    pphNciNfc_TransceiveInfo_t   pMappedTranscvIf);
44STATIC NFCSTATUS phLibNfc_MifareMap(phNfc_sTransceiveInfo_t*    pTransceiveInfo,
45                                    pphNciNfc_TransceiveInfo_t   pMappedTranscvIf);
46STATIC NFCSTATUS phLibNfc_ChkAuthCmdMFC(phNfc_sTransceiveInfo_t* pTransceiveInfo,
47                                    uint8_t *bKey);
48STATIC NFCSTATUS phLibNfc_GetKeyNumberMFC(uint8_t *buffer,uint8_t *bKey);
49STATIC void phLibNfc_CalSectorAddress(uint8_t *Sector_Address);
50STATIC NFCSTATUS  phNciNfc_MfCreateAuthCmdHdr(phNciNfc_TransceiveInfo_t tTranscvInfo,
51                                    uint8_t    bBlockAddr,
52                                    uint8_t    *buff,
53                                    uint16_t    *buffSz);
54STATIC NFCSTATUS phNciNfc_MfCreateXchgDataHdr(phNciNfc_TransceiveInfo_t tTranscvInfo,
55                                    uint8_t *buff, uint16_t *buffSz);
56STATIC NFCSTATUS phLibNfc_SendWrt16CmdPayload(phNfc_sTransceiveInfo_t*    pTransceiveInfo,
57                                    pphNciNfc_TransceiveInfo_t   pMappedTranscvIf);
58STATIC NFCSTATUS phNciNfc_RecvMfResp(phNciNfc_Buff_t* RspBuffInfo, NFCSTATUS wStatus);
59STATIC NFCSTATUS nativeNfcExtns_doTransceive(uint8_t *buff, uint16_t buffSz);
60STATIC NFCSTATUS phFriNfc_NdefSmtCrd_Reset__(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt,
61                                    uint8_t    *SendRecvBuffer,
62                                    uint16_t   *SendRecvBuffLen);
63STATIC NFCSTATUS phFriNfc_ValidateParams(uint8_t  *PacketData,
64                                    uint32_t   *PacketDataLength,
65                                    uint8_t     Offset,
66                                    phFriNfc_NdefMap_t  *pNdefMap,
67                                    uint8_t     bNdefReq);
68STATIC void Mfc_FormatNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status);
69STATIC void Mfc_WriteNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status);
70STATIC void Mfc_ReadNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status);
71STATIC void Mfc_CheckNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status);
72
73/*******************************************************************************
74**
75** Function         phNxpExtns_MfcModuleDeInit
76**
77** Description      It Deinitializes the Mifare module.
78**
79**                  Frees all the memory occupied by Mifare module
80**
81** Returns:
82**                  NFCSTATUS_SUCCESS - if successfully deinitialize
83**                  NFCSTATUS_FAILED  - otherwise
84**
85*******************************************************************************/
86NFCSTATUS phNxpExtns_MfcModuleDeInit(void)
87{
88    NFCSTATUS status = NFCSTATUS_FAILED;
89
90    if(NdefMap != NULL)
91    {
92        if( NdefMap->psRemoteDevInfo != NULL )
93        {
94            free(NdefMap->psRemoteDevInfo);
95            NdefMap->psRemoteDevInfo = NULL;
96        }
97        if( NdefMap->SendRecvBuf != NULL )
98        {
99            free(NdefMap->SendRecvBuf);
100            NdefMap->SendRecvBuf = NULL;
101        }
102        if( NdefMap->SendRecvLength != NULL )
103        {
104            free(NdefMap->SendRecvLength);
105            NdefMap->SendRecvLength = NULL;
106        }
107        if( NdefMap->DataCount != NULL )
108        {
109            free(NdefMap->DataCount);
110            NdefMap->DataCount = NULL;
111        }
112        if( NdefMap->pTransceiveInfo != NULL )
113        {
114            if( NdefMap->pTransceiveInfo->sSendData.buffer != NULL )
115            {
116                free(NdefMap->pTransceiveInfo->sSendData.buffer);
117                NdefMap->pTransceiveInfo->sSendData.buffer = NULL;
118            }
119            if( NdefMap->pTransceiveInfo->sRecvData.buffer != NULL )
120            {
121                free(NdefMap->pTransceiveInfo->sRecvData.buffer);
122                NdefMap->pTransceiveInfo->sRecvData.buffer = NULL;
123            }
124            free(NdefMap->pTransceiveInfo);
125            NdefMap->pTransceiveInfo = NULL;
126        }
127
128        free(NdefMap);
129        NdefMap = NULL;
130    }
131
132    if( tNciTranscvInfo.tSendData.pBuff != NULL )
133    {
134        free(tNciTranscvInfo.tSendData.pBuff);
135        tNciTranscvInfo.tSendData.pBuff = NULL;
136    }
137
138    if( NdefSmtCrdFmt != NULL )
139    {
140        free(NdefSmtCrdFmt);
141        NdefSmtCrdFmt = NULL;
142    }
143#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
144    pthread_mutex_lock(&SharedDataMutex);
145#endif
146    if ( NULL != NdefInfo.psUpperNdefMsg )
147    {
148        if ( NdefInfo.psUpperNdefMsg->buffer != NULL )
149        {
150            free(NdefInfo.psUpperNdefMsg->buffer);
151            NdefInfo.psUpperNdefMsg->buffer = NULL;
152        }
153        free(NdefInfo.psUpperNdefMsg);
154        NdefInfo.psUpperNdefMsg = NULL;
155    }
156#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
157    pthread_mutex_unlock(&SharedDataMutex);
158#endif
159    if (NULL != gAuthCmdBuf.pauth_cmd)
160    {
161        if (NULL != gAuthCmdBuf.pauth_cmd->buffer)
162        {
163            free(gAuthCmdBuf.pauth_cmd->buffer);
164            gAuthCmdBuf.pauth_cmd->buffer = NULL;
165        }
166        free(gAuthCmdBuf.pauth_cmd);
167        gAuthCmdBuf.pauth_cmd = NULL;
168    }
169    status = NFCSTATUS_SUCCESS;
170    return status;
171}
172
173/*******************************************************************************
174**
175** Function         phNxpExtns_MfcModuleInit
176**
177** Description      It Initializes the memroy and global variables related
178**                  to Mifare module.
179**
180**                  Reset all the global variables and allocate memory for Mifare module
181**
182** Returns:
183**                  NFCSTATUS_SUCCESS - if successfully deinitialize
184**                  NFCSTATUS_FAILED  - otherwise
185**
186*******************************************************************************/
187NFCSTATUS phNxpExtns_MfcModuleInit(void)
188{
189    NFCSTATUS status = NFCSTATUS_FAILED;
190    gphNxpExtns_Context.writecmdFlag = FALSE;
191    gphNxpExtns_Context.RawWriteCallBack = FALSE;
192    gphNxpExtns_Context.CallBackCtxt   = NULL;
193    gphNxpExtns_Context.CallBackMifare = NULL;
194    gphNxpExtns_Context.ExtnsConnect = FALSE;
195    gphNxpExtns_Context.ExtnsDeactivate = FALSE;
196    gphNxpExtns_Context.ExtnsCallBack = FALSE;
197
198    NdefMap = malloc(sizeof(phFriNfc_NdefMap_t));
199    if( NULL == NdefMap )
200    {
201        goto clean_and_return;
202    }
203    memset(NdefMap,0,sizeof(phFriNfc_NdefMap_t));
204
205    NdefMap->psRemoteDevInfo = malloc(sizeof(phLibNfc_sRemoteDevInformation_t));
206    if( NULL == NdefMap->psRemoteDevInfo )
207    {
208        goto clean_and_return;
209    }
210    memset(NdefMap->psRemoteDevInfo, 0, sizeof(phLibNfc_sRemoteDevInformation_t));
211
212    NdefMap->SendRecvBuf = malloc((uint32_t)(MAX_BUFF_SIZE * 2));
213    if( NULL == NdefMap->SendRecvBuf )
214    {
215        goto clean_and_return;
216    }
217    memset(NdefMap->SendRecvBuf, 0, (MAX_BUFF_SIZE * 2));
218
219    NdefMap->SendRecvLength  = malloc(sizeof(uint16_t));
220    if( NULL ==  NdefMap->SendRecvLength )
221    {
222        goto clean_and_return;
223    }
224    memset(NdefMap->SendRecvLength, 0, sizeof(uint16_t));
225
226    NdefMap->DataCount = malloc(sizeof(uint16_t));
227    if( NULL == NdefMap->DataCount )
228    {
229        goto clean_and_return;
230    }
231    memset(NdefMap->DataCount, 0, sizeof(uint16_t));
232
233    NdefMap->pTransceiveInfo = malloc(sizeof(phNfc_sTransceiveInfo_t));
234    if(NULL == NdefMap->pTransceiveInfo)
235    {
236        goto clean_and_return;
237    }
238    memset(NdefMap->pTransceiveInfo, 0, sizeof(phNfc_sTransceiveInfo_t));
239
240    tNciTranscvInfo.tSendData.pBuff = (uint8_t *)malloc((uint32_t)MAX_BUFF_SIZE);
241    if(NULL == tNciTranscvInfo.tSendData.pBuff)
242    {
243        goto clean_and_return;
244    }
245    memset(tNciTranscvInfo.tSendData.pBuff, 0, MAX_BUFF_SIZE);
246
247    NdefMap->pTransceiveInfo->sSendData.buffer = (uint8_t *)malloc((uint32_t)MAX_BUFF_SIZE);
248    if( NdefMap->pTransceiveInfo->sSendData.buffer == NULL )
249    {
250        goto clean_and_return;
251    }
252    memset( NdefMap->pTransceiveInfo->sSendData.buffer, 0, MAX_BUFF_SIZE );
253    NdefMap->pTransceiveInfo->sSendData.length = MAX_BUFF_SIZE;
254
255    NdefMap->pTransceiveInfo->sRecvData.buffer = (uint8_t *)malloc((uint32_t)MAX_BUFF_SIZE); /* size should be same as sRecvData */
256    if( NdefMap->pTransceiveInfo->sRecvData.buffer == NULL )
257    {
258        goto clean_and_return;
259    }
260    memset( NdefMap->pTransceiveInfo->sRecvData.buffer, 0, MAX_BUFF_SIZE );
261    NdefMap->pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE;
262
263    NdefSmtCrdFmt = malloc( sizeof(phFriNfc_sNdefSmtCrdFmt_t) );
264    if( NdefSmtCrdFmt == NULL )
265    {
266        goto clean_and_return;
267    }
268    memset( NdefSmtCrdFmt , 0, sizeof(phFriNfc_sNdefSmtCrdFmt_t) );
269#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
270    pthread_mutex_lock(&SharedDataMutex);
271#endif
272    NdefInfo.psUpperNdefMsg = malloc(sizeof(phNfc_sData_t));
273    if ( NULL == NdefInfo.psUpperNdefMsg )
274    {
275        goto clean_and_return;
276    }
277    memset( NdefInfo.psUpperNdefMsg, 0, sizeof(phNfc_sData_t) );
278    memset (&gAuthCmdBuf, 0, sizeof(phNci_mfc_auth_cmd_t));
279    gAuthCmdBuf.pauth_cmd = malloc(sizeof(phNfc_sData_t));
280    if (NULL == gAuthCmdBuf.pauth_cmd)
281    {
282        goto clean_and_return;
283    }
284    gAuthCmdBuf.pauth_cmd->buffer = malloc((uint32_t)NCI_MAX_DATA_LEN);
285    if (NULL == gAuthCmdBuf.pauth_cmd->buffer)
286    {
287        goto clean_and_return;
288    }
289    status = NFCSTATUS_SUCCESS;
290
291clean_and_return:
292#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
293    pthread_mutex_unlock(&SharedDataMutex);
294#endif
295    if(status != NFCSTATUS_SUCCESS)
296    {
297        NXPLOG_EXTNS_E("CRIT: Memory Allocation failed for MFC!");
298        phNxpExtns_MfcModuleDeInit();
299    }
300    return status;
301}
302
303/*******************************************************************************
304**
305** Function         Mfc_CheckNdef
306**
307** Description      It triggers NDEF detection for Mifare Classic Tag.
308**
309**
310** Returns          NFCSTATUS_SUCCESS - if successfully initiated
311**                  NFCSTATUS_FAILED  - otherwise
312**
313*******************************************************************************/
314NFCSTATUS Mfc_CheckNdef(void)
315{
316    NFCSTATUS status = NFCSTATUS_FAILED;
317
318    EXTNS_SetCallBackFlag(FALSE);
319    /* Set Completion Routine for CheckNdef */
320    NdefMap->CompletionRoutine[0].CompletionRoutine = Mfc_CheckNdef_Completion_Routine;
321
322    gphNxpExtns_Context.CallBackMifare = phFriNfc_MifareStdMap_Process;
323    gphNxpExtns_Context.CallBackCtxt   = NdefMap;
324    status = phFriNfc_MifareStdMap_H_Reset(NdefMap);
325    if ( NFCSTATUS_SUCCESS == status)
326    {
327        status = phFriNfc_MifareStdMap_ChkNdef(NdefMap);
328        if ( status == NFCSTATUS_PENDING )
329        {
330            status = NFCSTATUS_SUCCESS;
331        }
332    }
333    if( status != NFCSTATUS_SUCCESS )
334    {
335        status = NFCSTATUS_FAILED;
336    }
337
338    return status;
339}
340
341/*******************************************************************************
342**
343** Function         Mfc_CheckNdef_Completion_Routine
344**
345** Description      Notify NDEF detection for Mifare Classic Tag to JNI
346**
347**                  Upon completion of NDEF detection, a
348**                  NFA_NDEF_DETECT_EVT will be sent, to notify the application
349**                  of the NDEF attributes (NDEF total memory size, current
350**                  size, etc.).
351**
352** Returns:         void
353**
354*******************************************************************************/
355STATIC void Mfc_CheckNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status)
356{
357    (void)NdefCtxt;
358    tNFA_CONN_EVT_DATA conn_evt_data;
359
360    conn_evt_data.ndef_detect.status = status;
361    if(NFCSTATUS_SUCCESS == status)
362    {
363        /* NDef Tag Detected */
364        conn_evt_data.ndef_detect.protocol   = NFA_PROTOCOL_MIFARE;
365        phFrinfc_MifareClassic_GetContainerSize(NdefMap,
366                                                (uint32_t *)&(conn_evt_data.ndef_detect.max_size),
367                                                (uint32_t *)&(conn_evt_data.ndef_detect.cur_size));
368        NdefInfo.NdefLength  = conn_evt_data.ndef_detect.max_size;
369        /* update local flags */
370        NdefInfo.is_ndef = 1;
371        NdefInfo.NdefActualSize = conn_evt_data.ndef_detect.cur_size;
372        if ( PH_NDEFMAP_CARD_STATE_READ_ONLY == NdefMap->CardState )
373        {
374            NXPLOG_EXTNS_D("Mfc_CheckNdef_Completion_Routine : READ_ONLY_CARD");
375            conn_evt_data.ndef_detect.flags = RW_NDEF_FL_READ_ONLY;
376        }
377        else
378        {
379            conn_evt_data.ndef_detect.flags = RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED;
380        }
381    }
382    else
383    {
384        /* NDEF Detection failed for other reasons */
385        conn_evt_data.ndef_detect.cur_size = 0;
386        conn_evt_data.ndef_detect.max_size = 0;
387        conn_evt_data.ndef_detect.flags    = RW_NDEF_FL_UNKNOWN;
388
389        /* update local flags */
390        NdefInfo.is_ndef = 0;
391        NdefInfo.NdefActualSize = conn_evt_data.ndef_detect.cur_size;
392    }
393    (*gphNxpExtns_Context.p_conn_cback) (NFA_NDEF_DETECT_EVT, &conn_evt_data);
394
395    return;
396}
397/*******************************************************************************
398**
399** Function         Mfc_ReadNdef_Completion_Routine
400**
401** Description      Notify NDEF read completion for Mifare Classic Tag to JNI
402**
403**                  Upon completion of NDEF read, a
404**                  NFA_READ_CPLT_EVT will be sent, to notify the application
405**                  with the NDEF data and status
406**
407** Returns:         void
408**
409*******************************************************************************/
410STATIC void Mfc_ReadNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status)
411{
412    (void)NdefCtxt;
413    tNFA_CONN_EVT_DATA conn_evt_data;
414    tNFA_NDEF_EVT_DATA p_data;
415
416    conn_evt_data.status = status;
417#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
418    pthread_mutex_lock(&SharedDataMutex);
419#endif
420    if(NFCSTATUS_SUCCESS == status)
421    {
422        p_data.ndef_data.len    = NdefInfo.psUpperNdefMsg->length;
423        p_data.ndef_data.p_data = NdefInfo.psUpperNdefMsg->buffer;
424        (*gphNxpExtns_Context.p_ndef_cback) (NFA_NDEF_DATA_EVT, &p_data);
425    }
426    else
427    {
428    }
429
430    (*gphNxpExtns_Context.p_conn_cback) (NFA_READ_CPLT_EVT, &conn_evt_data);
431
432    if( NdefInfo.psUpperNdefMsg->buffer != NULL)
433    {
434        free (NdefInfo.psUpperNdefMsg->buffer);
435        NdefInfo.psUpperNdefMsg->buffer = NULL;
436    }
437#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
438    pthread_mutex_unlock(&SharedDataMutex);
439#endif
440    return;
441}
442
443/*******************************************************************************
444**
445** Function         Mfc_WriteNdef_Completion_Routine
446**
447** Description      Notify NDEF write completion for Mifare Classic Tag to JNI
448**
449**                  Upon completion of NDEF write, a
450**                  NFA_WRITE_CPLT_EVT will be sent along with status
451**
452** Returns:         void
453**
454*******************************************************************************/
455STATIC void Mfc_WriteNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status)
456{
457    (void)NdefCtxt;
458    tNFA_CONN_EVT_DATA conn_evt_data;
459
460    conn_evt_data.status = status;
461    (*gphNxpExtns_Context.p_conn_cback) (NFA_WRITE_CPLT_EVT, &conn_evt_data);
462
463    return;
464}
465
466/*******************************************************************************
467**
468** Function         Mfc_FormatNdef_Completion_Routine
469**
470** Description      Notify NDEF format completion for Mifare Classic Tag to JNI
471**
472**                  Upon completion of NDEF format, a
473**                  NFA_FORMAT_CPLT_EVT will be sent along with status
474**
475** Returns:         void
476**
477*******************************************************************************/
478STATIC void Mfc_FormatNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status)
479{
480    (void)NdefCtxt;
481    tNFA_CONN_EVT_DATA conn_evt_data;
482
483    conn_evt_data.status = status;
484    (*gphNxpExtns_Context.p_conn_cback) (NFA_FORMAT_CPLT_EVT, &conn_evt_data);
485
486    return;
487}
488
489/*******************************************************************************
490**
491** Function          phFriNfc_ValidateParams
492**
493** Description      This function is a common function which validates NdefRd
494**                  and NdefWr parameters.
495**
496** Returns          NFCSTATUS_SUCCESS  - All the params are valid
497**                  NFCSTATUS_FAILED   - otherwise
498**
499*******************************************************************************/
500STATIC NFCSTATUS phFriNfc_ValidateParams(uint8_t             *PacketData,
501                                    uint32_t            *PacketDataLength,
502                                    uint8_t             Offset,
503                                    phFriNfc_NdefMap_t  *pNdefMap,
504                                    uint8_t             bNdefReq)
505{
506
507    if( (pNdefMap == NULL) || (PacketData == NULL)
508        || (PacketDataLength == NULL) )
509    {
510        return NFCSTATUS_FAILED;
511    }
512
513    if( pNdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID )
514    {
515        return NFCSTATUS_FAILED;
516    }
517
518    if( bNdefReq == PH_FRINFC_NDEF_READ_REQ )
519    {
520        if( (Offset != PH_FRINFC_NDEFMAP_SEEK_CUR) && (Offset != PH_FRINFC_NDEFMAP_SEEK_BEGIN) )
521        {
522            return NFCSTATUS_FAILED;
523        }
524        if( pNdefMap->CardState == PH_NDEFMAP_CARD_STATE_INITIALIZED )
525        {
526            pNdefMap->NumOfBytesRead  = PacketDataLength;
527            *pNdefMap->NumOfBytesRead = 0;
528            return NFCSTATUS_EOF_NDEF_CONTAINER_REACHED;
529        }
530        if( (pNdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE) &&
531            (Offset != PH_FRINFC_NDEFMAP_SEEK_BEGIN) )
532        {
533            return NFCSTATUS_FAILED; /* return INVALID_DEVICE_REQUEST */
534        }
535        if( Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN )
536        {
537            pNdefMap->ApduBuffIndex = 0;
538            *pNdefMap->DataCount    = 0;
539        }
540        else if ( (pNdefMap->bPrevReadMode == PH_FRINFC_NDEFMAP_SEEK_BEGIN) ||
541                  (pNdefMap->bPrevReadMode == PH_FRINFC_NDEFMAP_SEEK_CUR) )
542        {
543
544        }
545        else
546        {
547            return NFCSTATUS_FAILED;
548        }
549    }
550    else if( bNdefReq == PH_FRINFC_NDEF_WRITE_REQ )
551    {
552        if( pNdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY )
553        {
554            pNdefMap->WrNdefPacketLength  = PacketDataLength;
555            *pNdefMap->WrNdefPacketLength = 0x00;
556            return NFCSTATUS_NOT_ALLOWED;
557        }
558    }
559
560    return NFCSTATUS_SUCCESS;
561}
562
563/*******************************************************************************
564**
565** Function         Mfc_SetRdOnly_Completion_Routine
566**
567** Description      Notify NDEF read only completion for Mifare Classic Tag to JNI
568**
569**                  Upon completion of NDEF format, a
570**                  NFA_SET_TAG_RO_EVT will be sent along with status
571**
572** Returns:         void
573**
574*******************************************************************************/
575STATIC void Mfc_SetRdOnly_Completion_Routine(void *NdefCtxt, NFCSTATUS status)
576{
577    (void)NdefCtxt;
578    tNFA_CONN_EVT_DATA conn_evt_data;
579    ALOGE("Mfc_SetRdOnly_Completion_Routine status = 0x%x", status);
580    conn_evt_data.status = status;
581    (*gphNxpExtns_Context.p_conn_cback) (NFA_SET_TAG_RO_EVT, &conn_evt_data);
582
583    return;
584}
585
586/*******************************************************************************
587**
588** Function        Mfc_SetReadOnly
589**
590**
591** Description:    It triggers ConvertToReadOnly  for Mifare Classic Tag.
592**
593** Returns:
594**                  NFCSTATUS_SUCCESS if successfully initiated
595**                  NFCSTATUS_FAILED otherwise
596**
597*******************************************************************************/
598NFCSTATUS Mfc_SetReadOnly(uint8_t *secrtkey, uint8_t len)
599{
600    NXPLOG_EXTNS_D("%s Entering ", __FUNCTION__);
601    NFCSTATUS status = NFCSTATUS_FAILED;
602    uint8_t mif_secrete_key[6] = {0};
603    uint8_t id = 0;
604    EXTNS_SetCallBackFlag(FALSE);
605    memcpy(mif_secrete_key,secrtkey,len);
606    gphNxpExtns_Context.CallBackMifare = phFriNfc_MifareStdMap_Process;
607    gphNxpExtns_Context.CallBackCtxt   = NdefMap;
608    for (id = 0; id < len; id++)
609    {
610        ALOGD("secrtkey[%d] = 0x%x", id, secrtkey[id]);
611        ALOGD("mif_secrete_key[%d] = 0x%x", id, mif_secrete_key[id]);
612    }
613    /* Set Completion Routine for ReadNdef */
614    NdefMap->CompletionRoutine[0].CompletionRoutine = Mfc_SetRdOnly_Completion_Routine;
615    if(NdefInfo.is_ndef == 0)
616    {
617        status = NFCSTATUS_NON_NDEF_COMPLIANT;
618        goto Mfc_SetRdOnly;
619    }
620    else if( (NdefInfo.is_ndef == 1) && (NdefInfo.NdefActualSize == 0) )
621    {
622#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
623        pthread_mutex_lock(&SharedDataMutex);
624#endif
625        NdefInfo.psUpperNdefMsg->length = NdefInfo.NdefActualSize;
626#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
627        pthread_mutex_unlock(&SharedDataMutex);
628#endif
629        status = NFCSTATUS_SUCCESS;
630        goto Mfc_SetRdOnly;
631    }
632    else
633    {
634        status = phFriNfc_MifareStdMap_ConvertToReadOnly(NdefMap, mif_secrete_key);
635    }
636    if ( NFCSTATUS_PENDING == status )
637    {
638        status = NFCSTATUS_SUCCESS;
639    }
640
641Mfc_SetRdOnly:
642    return status;
643}
644
645/*******************************************************************************
646**
647** Function         Mfc_ReadNdef
648**
649** Description      It triggers receiving of the NDEF message from Mifare Classic Tag.
650**
651**
652** Returns:
653**                  NFCSTATUS_SUCCESS - if successfully initiated
654**                  NFCSTATUS_FAILED  - otherwise
655**
656*******************************************************************************/
657NFCSTATUS Mfc_ReadNdef(void)
658{
659    NFCSTATUS status = NFCSTATUS_FAILED;
660    uint8_t            *PacketData = NULL;
661    uint32_t           *PacketDataLength = NULL;
662    phLibNfc_Ndef_EOffset_t Offset;
663
664    EXTNS_SetCallBackFlag(FALSE);
665
666    Offset = phLibNfc_Ndef_EBegin;
667
668    gphNxpExtns_Context.CallBackMifare = phFriNfc_MifareStdMap_Process;
669    gphNxpExtns_Context.CallBackCtxt   = NdefMap;
670#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
671    pthread_mutex_lock(&SharedDataMutex);
672#endif
673    if(NdefInfo.is_ndef == 0)
674    {
675        status = NFCSTATUS_NON_NDEF_COMPLIANT;
676        goto Mfc_RdNdefEnd;
677    }
678    else if( (NdefInfo.is_ndef == 1) && (NdefInfo.NdefActualSize == 0) )
679    {
680        NdefInfo.psUpperNdefMsg->length = NdefInfo.NdefActualSize;
681        status = NFCSTATUS_SUCCESS;
682        goto Mfc_RdNdefEnd;
683    }
684    else
685    {
686        NdefInfo.psUpperNdefMsg->buffer = malloc(NdefInfo.NdefActualSize);
687        if ( NULL == NdefInfo.psUpperNdefMsg->buffer)
688        {
689           goto Mfc_RdNdefEnd;
690        }
691        NdefInfo.psUpperNdefMsg->length = NdefInfo.NdefActualSize;
692
693        /* Set Completion Routine for ReadNdef */
694        NdefMap->CompletionRoutine[1].CompletionRoutine = Mfc_ReadNdef_Completion_Routine;
695        NdefInfo.NdefContinueRead = (uint8_t) ((phLibNfc_Ndef_EBegin==Offset) ?
696                                                        PH_FRINFC_NDEFMAP_SEEK_BEGIN :
697                                                        PH_FRINFC_NDEFMAP_SEEK_CUR);
698    }
699
700    PacketData             = NdefInfo.psUpperNdefMsg->buffer;
701    PacketDataLength       = (uint32_t*)&(NdefInfo.psUpperNdefMsg->length);
702    NdefMap->bCurrReadMode = Offset;
703    status = phFriNfc_ValidateParams (PacketData, PacketDataLength, Offset, NdefMap, PH_FRINFC_NDEF_READ_REQ);
704    if( status != NFCSTATUS_SUCCESS )
705    {
706        goto Mfc_RdNdefEnd;
707    }
708
709    status = phFriNfc_MifareStdMap_RdNdef(NdefMap, PacketData, PacketDataLength, Offset);
710
711    if(NFCSTATUS_INSUFFICIENT_STORAGE == status)
712    {
713        NdefInfo.psUpperNdefMsg->length = 0x00;
714        status = NFCSTATUS_SUCCESS;
715    }
716
717    if ( NFCSTATUS_PENDING == status )
718    {
719        status = NFCSTATUS_SUCCESS;
720    }
721
722Mfc_RdNdefEnd:
723    if( status != NFCSTATUS_SUCCESS )
724    {
725        if ( NULL != NdefInfo.psUpperNdefMsg->buffer )
726        {
727            free(NdefInfo.psUpperNdefMsg->buffer);
728            NdefInfo.psUpperNdefMsg->buffer = NULL;
729        }
730        status = NFCSTATUS_FAILED;
731    }
732#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
733    pthread_mutex_unlock(&SharedDataMutex);
734#endif
735    return status;
736
737}
738/*******************************************************************************
739**
740** Function         Mfc_PresenceCheck
741**
742** Description      It triggers receiving of the NDEF message from Mifare Classic Tag.
743**
744**
745** Returns:
746**                  NFCSTATUS_SUCCESS - if successfully initiated
747**                  NFCSTATUS_FAILED  - otherwise
748**
749*******************************************************************************/
750NFCSTATUS Mfc_PresenceCheck(void)
751{
752    NFCSTATUS status = NFCSTATUS_SUCCESS;
753
754    if (gAuthCmdBuf.auth_status == TRUE)
755    {
756        EXTNS_SetCallBackFlag(FALSE);
757        status = nativeNfcExtns_doTransceive(gAuthCmdBuf.pauth_cmd->buffer,
758             gAuthCmdBuf.pauth_cmd->length);
759        if (status != NFCSTATUS_PENDING)
760        {
761            gAuthCmdBuf.auth_sent = FALSE;
762            status = NFCSTATUS_FAILED;
763        }
764        else
765        {
766            gAuthCmdBuf.auth_sent = TRUE;
767            status = NFCSTATUS_SUCCESS;
768        }
769    }
770    else
771    {
772        status = NFCSTATUS_NOT_ALLOWED;
773    }
774    NXPLOG_EXTNS_D("%s status = 0x%x", __FUNCTION__, status);
775    return status;
776}
777/*******************************************************************************
778**
779** Function         Mfc_WriteNdef
780**
781** Description      It triggers the NDEF data write to Mifare Classic Tag.
782**
783**
784** Returns:
785**                  NFCSTATUS_SUCCESS - if successfully initiated
786**                  NFCSTATUS_FAILED  - otherwise
787**
788*******************************************************************************/
789NFCSTATUS Mfc_WriteNdef(uint8_t *p_data, uint32_t len)
790{
791    NFCSTATUS status = NFCSTATUS_SUCCESS;
792    uint8_t            *PacketData = NULL;
793    uint32_t           *PacketDataLength = NULL;
794
795    if( p_data == NULL || len == 0 )
796    {
797        NXPLOG_EXTNS_E("MFC Error: Invalid Parameters to Ndef Write");
798        status = NFCSTATUS_FAILED;
799        goto Mfc_WrNdefEnd;
800    }
801
802    EXTNS_SetCallBackFlag(FALSE);
803    gphNxpExtns_Context.CallBackMifare = phFriNfc_MifareStdMap_Process;
804    gphNxpExtns_Context.CallBackCtxt   = NdefMap;
805#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
806    pthread_mutex_lock(&SharedDataMutex);
807#endif
808    if( NdefInfo.is_ndef == PH_LIBNFC_INTERNAL_CHK_NDEF_NOT_DONE )
809    {
810        status = NFCSTATUS_REJECTED;
811        goto Mfc_WrNdefEnd;
812    }
813    else if( NdefInfo.is_ndef == 0 )
814    {
815        status = NFCSTATUS_NON_NDEF_COMPLIANT;
816        goto Mfc_WrNdefEnd;
817    }
818    else if( len > NdefInfo.NdefLength )
819    {
820        status = NFCSTATUS_NOT_ENOUGH_MEMORY;
821        goto Mfc_WrNdefEnd;
822    }
823    else
824    {
825        NdefInfo.psUpperNdefMsg->buffer = p_data;
826        NdefInfo.psUpperNdefMsg->length = len;
827
828        NdefInfo.AppWrLength    = len;
829        NdefMap->CompletionRoutine[2].CompletionRoutine = Mfc_WriteNdef_Completion_Routine;
830        if( 0 == len )
831        {
832            /* TODO: Erase the Tag */
833        }
834        else
835        {
836            NdefMap->ApduBuffIndex = 0x00;
837            *NdefMap->DataCount    = 0x00;
838            PacketData             = NdefInfo.psUpperNdefMsg->buffer;
839            PacketDataLength       = &(NdefInfo.dwWrLength);
840            NdefMap->WrNdefPacketLength = PacketDataLength;
841            NdefInfo.dwWrLength = len;
842
843            status = phFriNfc_ValidateParams (PacketData, PacketDataLength, 0, NdefMap, PH_FRINFC_NDEF_WRITE_REQ);
844            if( status != NFCSTATUS_SUCCESS )
845            {
846                goto Mfc_WrNdefEnd;
847            }
848
849            status = phFriNfc_MifareStdMap_WrNdef(NdefMap, PacketData, PacketDataLength, PH_FRINFC_NDEFMAP_SEEK_BEGIN);
850
851            if ( status == NFCSTATUS_PENDING )
852            {
853                status = NFCSTATUS_SUCCESS;
854            }
855        }
856    }
857
858Mfc_WrNdefEnd:
859#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
860    pthread_mutex_unlock(&SharedDataMutex);
861#endif
862    if( status != NFCSTATUS_SUCCESS )
863    {
864        status = NFCSTATUS_FAILED;
865    }
866    return status;
867}
868/*******************************************************************************
869**
870** Function          phFriNfc_NdefSmtCrd_Reset__
871**
872** Description      This function Resets the component instance to the initial
873**                  state and initializes the internal variables.
874**
875** Returns          NFCSTATUS_SUCCESS
876**
877*******************************************************************************/
878STATIC NFCSTATUS phFriNfc_NdefSmtCrd_Reset__(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt,
879                                      uint8_t *SendRecvBuffer,
880                                      uint16_t *SendRecvBuffLen)
881{
882//    NFCSTATUS status = NFCSTATUS_FAILED;                      /*commented to eliminate unused variable warning*/
883    uint8_t     index;
884
885    /* Initialize the state to Init */
886    NdefSmtCrdFmt->State = PH_FRINFC_SMTCRDFMT_STATE_RESET_INIT;
887
888    for(index = 0;index<PH_FRINFC_SMTCRDFMT_CR;index++)
889    {
890        /* Initialize the NdefMap Completion Routine to Null */
891        NdefSmtCrdFmt->CompletionRoutine[index].CompletionRoutine = NULL;
892        /* Initialize the NdefMap Completion Routine context to Null  */
893        NdefSmtCrdFmt->CompletionRoutine[index].Context = NULL;
894    }
895
896    /* Trx Buffer registered */
897    NdefSmtCrdFmt->SendRecvBuf = SendRecvBuffer;
898
899    /* Trx Buffer Size */
900    NdefSmtCrdFmt->SendRecvLength = SendRecvBuffLen;
901
902    /* Register Transfer Buffer Length */
903    NdefSmtCrdFmt->SendLength = 0;
904
905    /* Initialize the Format status flag*/
906    NdefSmtCrdFmt->FmtProcStatus = 0;
907
908    /* Reset the Card Type */
909    NdefSmtCrdFmt->CardType = 0;
910
911    /* Reset MapCompletion Info*/
912    NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine = NULL;
913    NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = NULL;
914
915    phFriNfc_MfStd_Reset(NdefSmtCrdFmt);
916
917    return NFCSTATUS_SUCCESS;
918}
919
920/*******************************************************************************
921**
922** Function         Mfc_FormatNdef
923**
924** Description      It triggers the NDEF format of Mifare Classic Tag.
925**
926**
927** Returns:
928**                  NFCSTATUS_SUCCESS - if successfully initiated
929**                  NFCSTATUS_FAILED  - otherwise
930**
931*******************************************************************************/
932NFCSTATUS Mfc_FormatNdef(uint8_t *secretkey, uint8_t len)
933{
934    NFCSTATUS status = NFCSTATUS_FAILED;
935    uint8_t   mif_std_key[6] = {0};
936//    static uint8_t   Index;                                               /*commented to eliminate unused variable warning*/
937    uint8_t     sak = 0;
938
939    EXTNS_SetCallBackFlag(FALSE);
940
941    memcpy(mif_std_key,secretkey,len);
942    memcpy(current_key,secretkey,len);
943
944    if( NULL == NdefSmtCrdFmt ||
945        NULL == NdefMap || NULL == NdefMap->SendRecvBuf )
946    {
947        goto Mfc_FormatEnd;
948    }
949    NdefSmtCrdFmt->pTransceiveInfo = NdefMap->pTransceiveInfo;
950
951    gphNxpExtns_Context.CallBackMifare = phFriNfc_MfStd_Process;
952    gphNxpExtns_Context.CallBackCtxt   = NdefSmtCrdFmt;
953
954    NdefInfo.NdefSendRecvLen = NDEF_SENDRCV_BUF_LEN;
955    phFriNfc_NdefSmtCrd_Reset__(NdefSmtCrdFmt, NdefMap->SendRecvBuf, &(NdefInfo.NdefSendRecvLen));
956
957    /* Register Callbacks */
958    NdefSmtCrdFmt->CompletionRoutine[0].CompletionRoutine = Mfc_FormatNdef_Completion_Routine;
959    NdefSmtCrdFmt->CompletionRoutine[1].CompletionRoutine = Mfc_FormatNdef_Completion_Routine;
960    NdefSmtCrdFmt->psRemoteDevInfo = NdefMap->psRemoteDevInfo;
961    sak = NdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak;
962
963    if((0x08 == (sak & 0x18)) || (0x18 == (sak & 0x18)) ||
964       (0x01 == sak))
965    {
966        NdefSmtCrdFmt->CardType = (uint8_t) (((sak & 0x18) == 0x08)?
967                        PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD:(((sak & 0x19) == 0x19)?
968                        PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD:
969                        PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD));
970        status = phFriNfc_MfStd_Format( NdefSmtCrdFmt, mif_std_key);
971    }
972
973    if( NFCSTATUS_PENDING == status )
974    {
975        status = NFCSTATUS_SUCCESS;
976    }
977
978Mfc_FormatEnd:
979    if( status != NFCSTATUS_SUCCESS )
980    {
981        status = NFCSTATUS_FAILED;
982    }
983
984    return status;
985}
986
987/*******************************************************************************
988**
989** Function         phNxNciExtns_MifareStd_Reconnect
990**
991** Description      This function sends the deactivate command to NFCC for Mifare
992**
993**
994** Returns:
995**                  NFCSTATUS_PENDING - if successfully initiated
996**                  NFCSTATUS_FAILED  - otherwise
997**
998*******************************************************************************/
999NFCSTATUS phNxNciExtns_MifareStd_Reconnect(void)
1000{
1001    tNFA_STATUS status;
1002
1003    EXTNS_SetDeactivateFlag(TRUE);
1004    if (NFA_STATUS_OK != (status = NFA_Deactivate (TRUE))) /* deactivate to sleep state */
1005    {
1006        NXPLOG_EXTNS_E ("%s: deactivate failed, status = %d", __FUNCTION__, status);
1007        return NFCSTATUS_FAILED;
1008    }
1009
1010    return NFCSTATUS_PENDING;
1011
1012}
1013
1014/*******************************************************************************
1015**
1016** Function         Mfc_DeactivateCbackSelect
1017**
1018** Description      This function select the Mifare tag
1019**
1020**
1021** Returns:         void
1022**
1023*******************************************************************************/
1024void Mfc_DeactivateCbackSelect(void)
1025{
1026    tNFA_STATUS status;
1027
1028    EXTNS_SetConnectFlag(TRUE);
1029    if (NFA_STATUS_OK != (status = NFA_Select (0x01, phNciNfc_e_RfProtocolsMifCProtocol,
1030                                                     phNciNfc_e_RfInterfacesTagCmd_RF)))
1031    {
1032        NXPLOG_EXTNS_E ("%s: NFA_Select failed, status = %d", __FUNCTION__, status);
1033    }
1034
1035    return;
1036}
1037
1038/*******************************************************************************
1039**
1040** Function         Mfc_ActivateCback
1041**
1042** Description      This function invoke the callback when receive the response
1043**
1044**
1045** Returns:         void
1046**
1047**
1048*******************************************************************************/
1049void Mfc_ActivateCback(void)
1050{
1051    gphNxpExtns_Context.CallBackMifare(gphNxpExtns_Context.CallBackCtxt, NFCSTATUS_SUCCESS);
1052    return;
1053}
1054
1055/*******************************************************************************
1056**
1057** Function         Mfc_Transceive
1058**
1059** Description      Sends raw frame to Mifare Classic Tag.
1060**
1061** Returns          NFCSTATUS_SUCCESS - if successfully initiated
1062**                  NFCSTATUS_FAILED  - otherwise
1063**
1064*******************************************************************************/
1065NFCSTATUS Mfc_Transceive(uint8_t *p_data, uint32_t len)
1066{
1067    NFCSTATUS status = NFCSTATUS_FAILED;
1068    uint8_t i = 0x00;
1069
1070    gphNxpExtns_Context.RawWriteCallBack = FALSE;
1071    gphNxpExtns_Context.CallBackMifare = NULL;
1072    gphNxpExtns_Context.CallBackCtxt   = NdefMap;
1073
1074    EXTNS_SetCallBackFlag(TRUE);
1075    if( p_data[0] == 0x60 || p_data[0] == 0x61 )
1076    {
1077
1078        NdefMap->Cmd.MfCmd = p_data[0];
1079
1080        NdefMap->SendRecvBuf[i++] = p_data[1];
1081
1082        NdefMap->SendRecvBuf[i++] = p_data[6]; /* TODO, handle 7 byte UID */
1083        NdefMap->SendRecvBuf[i++] = p_data[7];
1084        NdefMap->SendRecvBuf[i++] = p_data[8];
1085        NdefMap->SendRecvBuf[i++] = p_data[9];
1086        NdefMap->SendRecvBuf[i++] = p_data[10];
1087        NdefMap->SendRecvBuf[i++] = p_data[11];
1088
1089        status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo,
1090                              NdefMap->Cmd,
1091                              NdefMap->SendRecvBuf,
1092                              NdefMap->SendLength,
1093                              NdefMap->SendRecvLength);
1094    }
1095    else if( p_data[0] == 0xA0 )
1096    {
1097        EXTNS_SetCallBackFlag(FALSE);
1098        NdefMap->Cmd.MfCmd = phNfc_eMifareWrite16;
1099        gphNxpExtns_Context.RawWriteCallBack = TRUE;
1100
1101        memcpy(NdefMap->SendRecvBuf, &p_data[1], len-1);
1102        NdefMap->SendLength = len-1;
1103        status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo,
1104                              NdefMap->Cmd,
1105                              NdefMap->SendRecvBuf,
1106                              NdefMap->SendLength,
1107                              NdefMap->SendRecvLength);
1108    }
1109    else if( (p_data[0] == phNfc_eMifareInc) || (p_data[0] == phNfc_eMifareDec) )
1110    {
1111
1112        EXTNS_SetCallBackFlag(FALSE);
1113        NdefMap->Cmd.MfCmd = p_data[0];
1114        gphNxpExtns_Context.RawWriteCallBack = TRUE;
1115
1116        memcpy(NdefMap->SendRecvBuf, &p_data[1], len-1);
1117        NdefMap->SendLength = len - 1;
1118        status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo,
1119                              NdefMap->Cmd,
1120                              NdefMap->SendRecvBuf,
1121                              NdefMap->SendLength,
1122                              NdefMap->SendRecvLength);
1123    }
1124    else if( ((p_data[0] == phNfc_eMifareTransfer) || (p_data[0] == phNfc_eMifareRestore)) && (len == 2) )
1125    {
1126        NdefMap->Cmd.MfCmd = p_data[0];
1127        if (p_data[0] == phNfc_eMifareRestore)
1128        {
1129            EXTNS_SetCallBackFlag(FALSE);
1130            gphNxpExtns_Context.RawWriteCallBack = TRUE;
1131            memcpy(NdefMap->SendRecvBuf, &p_data[1], len -1);
1132            NdefMap->SendLength = len - 1;
1133        }
1134        else
1135        {
1136            memcpy(NdefMap->SendRecvBuf, p_data, len);
1137            NdefMap->SendLength = len;
1138        }
1139        status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo,
1140                              NdefMap->Cmd,
1141                              NdefMap->SendRecvBuf,
1142                              NdefMap->SendLength,
1143                              NdefMap->SendRecvLength);
1144
1145    }
1146    else
1147    {
1148        NdefMap->Cmd.MfCmd = phNfc_eMifareRaw;
1149
1150        memcpy(NdefMap->SendRecvBuf, p_data, len);
1151        NdefMap->SendLength = len;
1152        status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo,
1153                              NdefMap->Cmd,
1154                              NdefMap->SendRecvBuf,
1155                              NdefMap->SendLength,
1156                              NdefMap->SendRecvLength);
1157    }
1158    if (NFCSTATUS_PENDING == status)
1159    {
1160        status = NFCSTATUS_SUCCESS;
1161    }
1162    else
1163    {
1164        NXPLOG_EXTNS_E("ERROR: Mfc_Transceive = 0x%x", status);
1165    }
1166
1167    return status;
1168}
1169
1170/*******************************************************************************
1171**
1172** Function         nativeNfcExtns_doTransceive
1173**
1174** Description      Sends raw frame to BCM stack.
1175**
1176** Returns          NFCSTATUS_PENDING - if successfully initiated
1177**                  NFCSTATUS_FAILED  - otherwise
1178**
1179*******************************************************************************/
1180STATIC NFCSTATUS nativeNfcExtns_doTransceive(uint8_t *buff, uint16_t buffSz)
1181{
1182    NFCSTATUS wStatus = NFCSTATUS_PENDING;
1183    tNFA_STATUS status = NFA_SendRawFrame (buff, buffSz, NFA_DM_DEFAULT_PRESENCE_CHECK_START_DELAY);
1184
1185    if (status != NFA_STATUS_OK)
1186    {
1187        NXPLOG_EXTNS_E ("%s: fail send; error=%d", __FUNCTION__, status);
1188        wStatus = NFCSTATUS_FAILED;
1189    }
1190
1191    return wStatus;
1192}
1193
1194/*******************************************************************************
1195**
1196** Function          phNciNfc_RecvMfResp
1197**
1198** Description      This function shall be invoked as part of ReaderMgmt data
1199**                  exchange sequence handler on receiving response/data from NFCC
1200**
1201** Returns          NFCSTATUS_SUCCESS - Data Reception is successful
1202**                  NFCSTATUS_FAILED  - Data Reception failed
1203**
1204*******************************************************************************/
1205STATIC NFCSTATUS
1206phNciNfc_RecvMfResp(phNciNfc_Buff_t* RspBuffInfo,
1207                        NFCSTATUS          wStatus
1208                       )
1209{
1210    NFCSTATUS               status = NFCSTATUS_SUCCESS;
1211    uint16_t                wPldDataSize = 0;
1212    phNciNfc_ExtnRespId_t   RecvdExtnRspId = phNciNfc_e_InvalidRsp;
1213    uint16_t                wRecvDataSz = 0;
1214
1215    if(NULL == RspBuffInfo)
1216    {
1217      status = NFCSTATUS_FAILED;
1218    }
1219    else
1220    {
1221        if((0 == (RspBuffInfo->wLen))
1222                || (PH_NCINFC_STATUS_OK != wStatus)
1223                || (NULL == (RspBuffInfo->pBuff))
1224                )
1225        {
1226            status = NFCSTATUS_FAILED;
1227        }
1228        else
1229        {
1230            RecvdExtnRspId = (phNciNfc_ExtnRespId_t)RspBuffInfo->pBuff[0];
1231
1232            switch(RecvdExtnRspId)
1233            {
1234                case phNciNfc_e_MfXchgDataRsp:
1235                {
1236                        /* check the status byte */
1237                    if( PH_NCINFC_STATUS_OK == RspBuffInfo->pBuff[RspBuffInfo->wLen-1] )
1238                    {
1239                        status = NFCSTATUS_SUCCESS;
1240
1241                        /* DataLen = TotalRecvdLen - (sizeof(RspId) + sizeof(Status)) */
1242                        wPldDataSize = ((RspBuffInfo->wLen) -
1243                            (PHNCINFC_EXTNID_SIZE + PHNCINFC_EXTNSTATUS_SIZE));
1244                        wRecvDataSz = NCI_MAX_DATA_LEN;
1245
1246                        /* wPldDataSize = wPldDataSize-1; ==> ignoring the last status byte appended with data */
1247                        if((wPldDataSize) <= wRecvDataSz)
1248                        {
1249                            /* Extract the data part from pBuff[2] & fill it to be sent to upper layer */
1250                            memcpy(NdefMap->SendRecvBuf, &(RspBuffInfo->pBuff[1]),(wPldDataSize));
1251                            /* update the number of bytes received from lower layer,excluding the status byte */
1252                            *(NdefMap->SendRecvLength) = wPldDataSize;
1253                        }
1254                        else
1255                        {
1256                            //TODO:- Map some status for remaining extra data received to be sent back to caller??
1257                            status = NFCSTATUS_FAILED;
1258                        }
1259                    }
1260                    else
1261                    {
1262                        status = NFCSTATUS_FAILED;
1263                    }
1264                }
1265                break;
1266
1267                case phNciNfc_e_MfcAuthRsp:
1268                {
1269                    /* check the status byte */
1270                    if(PH_NCINFC_STATUS_OK == RspBuffInfo->pBuff[1])
1271                    {
1272                        if (gAuthCmdBuf.auth_sent ==  TRUE)
1273                        {
1274                            MfcPresenceCheckResult(NFCSTATUS_SUCCESS);
1275                            return NFCSTATUS_SUCCESS;
1276                        }
1277                        gAuthCmdBuf.auth_status = TRUE;
1278                        status = NFCSTATUS_SUCCESS;
1279
1280                        /* DataLen = TotalRecvdLen - (sizeof(RspId) + sizeof(Status)) */
1281                        wPldDataSize = ((RspBuffInfo->wLen) -
1282                            (PHNCINFC_EXTNID_SIZE + PHNCINFC_EXTNSTATUS_SIZE));
1283
1284                        /* Extract the data part from pBuff[2] & fill it to be sent to upper layer */
1285                        memcpy(NdefMap->SendRecvBuf, &(RspBuffInfo->pBuff[2]),wPldDataSize);
1286                        /* update the number of bytes received from lower layer,excluding the status byte */
1287                        *(NdefMap->SendRecvLength) = wPldDataSize;
1288                    }
1289                    else
1290                    {
1291                        if (gAuthCmdBuf.auth_sent ==  TRUE)
1292                        {
1293                            gAuthCmdBuf.auth_status = FALSE;
1294                            MfcPresenceCheckResult(NFCSTATUS_FAILED);
1295                            return NFCSTATUS_SUCCESS;
1296                        }
1297                        else
1298                        {
1299                            /* Reset the stored auth command buffer */
1300                            memset(gAuthCmdBuf.pauth_cmd->buffer, 0 , NCI_MAX_DATA_LEN);
1301                            gAuthCmdBuf.pauth_cmd->length = 0;
1302                            gAuthCmdBuf.auth_status = FALSE;
1303                        }
1304                        status = NFCSTATUS_FAILED;
1305                    }
1306                }
1307                break;
1308
1309                default:
1310                {
1311                    status = NFCSTATUS_FAILED;
1312                }
1313                break;
1314            }
1315        }
1316    }
1317
1318    return status;
1319}
1320
1321/*******************************************************************************
1322**
1323** Function         phLibNfc_SendWrt16CmdPayload
1324**
1325** Description      This function map the raw write cmd
1326**
1327** Returns          NFCSTATUS_SUCCESS            - Command framing done
1328**                  NFCSTATUS_INVALID_PARAMETER  - Otherwise
1329**
1330*******************************************************************************/
1331STATIC NFCSTATUS phLibNfc_SendWrt16CmdPayload(phNfc_sTransceiveInfo_t*    pTransceiveInfo,
1332                                    pphNciNfc_TransceiveInfo_t   pMappedTranscvIf)
1333{
1334    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
1335
1336    if( (NULL != pTransceiveInfo->sSendData.buffer) &&
1337        (0 != (pTransceiveInfo->sSendData.length)))
1338    {
1339        memcpy(pMappedTranscvIf->tSendData.pBuff, pTransceiveInfo->sSendData.buffer,
1340                              (pTransceiveInfo->sSendData.length));
1341        pMappedTranscvIf->tSendData.wLen              = pTransceiveInfo->sSendData.length;
1342        pMappedTranscvIf->uCmd.T2TCmd                 = phNciNfc_eT2TRaw;
1343    }
1344    else
1345    {
1346        wStatus = NFCSTATUS_INVALID_PARAMETER;
1347    }
1348
1349    if ( gphNxpExtns_Context.RawWriteCallBack == TRUE )
1350    {
1351        EXTNS_SetCallBackFlag(TRUE);
1352        gphNxpExtns_Context.RawWriteCallBack = FALSE;
1353    }
1354
1355    return wStatus;
1356}
1357
1358/*******************************************************************************
1359**
1360** Function         phLibNfc_SendIncDecCmdPayload
1361**
1362** Description      This function prepares the Increment/Decrement Value to be
1363**                  sent. This is called after sending the Increment/Decrement
1364**                  command is already sent and successfull
1365**
1366** Returns          NFCSTATUS_SUCCESS            - Payload framing done
1367**                  NFCSTATUS_INVALID_PARAMETER  - Otherwise
1368**
1369*******************************************************************************/
1370STATIC NFCSTATUS phLibNfc_SendIncDecCmdPayload(phNfc_sTransceiveInfo_t*    pTransceiveInfo,
1371                                    pphNciNfc_TransceiveInfo_t   pMappedTranscvIf)
1372{
1373    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
1374
1375    if( (NULL != pTransceiveInfo->sSendData.buffer) &&
1376        (0 != (pTransceiveInfo->sSendData.length)))
1377    {
1378        memcpy(pMappedTranscvIf->tSendData.pBuff, pTransceiveInfo->sSendData.buffer,
1379                              (pTransceiveInfo->sSendData.length));
1380        pMappedTranscvIf->tSendData.wLen              = pTransceiveInfo->sSendData.length;
1381        pMappedTranscvIf->uCmd.T2TCmd                 = phNciNfc_eT2TRaw;
1382    }
1383    else
1384    {
1385        wStatus = NFCSTATUS_INVALID_PARAMETER;
1386    }
1387
1388    if ( gphNxpExtns_Context.RawWriteCallBack == TRUE )
1389    {
1390        EXTNS_SetCallBackFlag(TRUE);
1391        gphNxpExtns_Context.RawWriteCallBack = FALSE;
1392    }
1393
1394    return wStatus;
1395}
1396
1397/*******************************************************************************
1398**
1399** Function         Mfc_RecvPacket
1400**
1401** Description      Decodes Mifare Classic Tag Response
1402**                  This is called from NFA_SendRaw Callback
1403**
1404** Returns:
1405**                  NFCSTATUS_SUCCESS - if successfully initiated
1406**                  NFCSTATUS_FAILED  - otherwise
1407**
1408*******************************************************************************/
1409NFCSTATUS Mfc_RecvPacket(uint8_t *buff, uint8_t buffSz)
1410{
1411    NFCSTATUS    status = NFCSTATUS_SUCCESS;
1412    phNciNfc_Buff_t         RspBuff;
1413    uint8_t *pcmd_buff;
1414    uint16_t buffSize;
1415
1416    RspBuff.pBuff = buff;
1417    RspBuff.wLen  = buffSz;
1418    status = phNciNfc_RecvMfResp(&RspBuff, status);
1419    if (TRUE == gAuthCmdBuf.auth_sent)
1420    {
1421        ALOGD("%s Mfc Check Presnece in progress", __FUNCTION__);
1422        gAuthCmdBuf.auth_sent = FALSE;
1423        return status;
1424    }
1425    if( TRUE == gphNxpExtns_Context.writecmdFlag && (NFCSTATUS_SUCCESS == status ))
1426    {
1427        pcmd_buff = (uint8_t *)malloc((uint32_t)MAX_BUFF_SIZE);
1428        if( NULL == pcmd_buff )
1429        {
1430            return NFCSTATUS_FAILED;
1431        }
1432        buffSize = MAX_BUFF_SIZE;
1433        gphNxpExtns_Context.writecmdFlag = FALSE;
1434        phLibNfc_SendWrt16CmdPayload(NdefMap->pTransceiveInfo, &tNciTranscvInfo);
1435        status = phNciNfc_SendMfReq(tNciTranscvInfo, pcmd_buff, &buffSize);
1436        if ( NFCSTATUS_PENDING != status )
1437        {
1438            NXPLOG_EXTNS_E("ERROR : Mfc_RecvPacket: 0x%x", status);
1439        }
1440        else
1441        {
1442            status = NFCSTATUS_SUCCESS;
1443        }
1444        if( pcmd_buff != NULL )
1445        {
1446            free(pcmd_buff);
1447            pcmd_buff = NULL;
1448        }
1449    }
1450    else if( TRUE == gphNxpExtns_Context.incrdecflag && (NFCSTATUS_SUCCESS == status ))
1451    {
1452        pcmd_buff = (uint8_t *)malloc((uint32_t)MAX_BUFF_SIZE);
1453        if( NULL == pcmd_buff )
1454        {
1455            return NFCSTATUS_FAILED;
1456        }
1457        buffSize = MAX_BUFF_SIZE;
1458        gphNxpExtns_Context.incrdecflag = FALSE;
1459        phLibNfc_SendIncDecCmdPayload(NdefMap->pTransceiveInfo, &tNciTranscvInfo);
1460        status = phNciNfc_SendMfReq(tNciTranscvInfo, pcmd_buff, &buffSize);
1461        if ( NFCSTATUS_PENDING != status )
1462        {
1463            NXPLOG_EXTNS_E("ERROR : Mfc_RecvPacket: 0x%x", status);
1464        }
1465        else
1466        {
1467            status = NFCSTATUS_SUCCESS;
1468        }
1469        gphNxpExtns_Context.incrdecstatusflag = TRUE;
1470        if( pcmd_buff != NULL )
1471        {
1472            free(pcmd_buff);
1473            pcmd_buff = NULL;
1474        }
1475
1476    }
1477    else
1478    {
1479        if( gphNxpExtns_Context.CallBackMifare != NULL )
1480        {
1481            if( (gphNxpExtns_Context.incrdecstatusflag == TRUE) && status == 0xB2 )
1482            {
1483                gphNxpExtns_Context.incrdecstatusflag = FALSE;
1484                status = NFCSTATUS_SUCCESS;
1485            }
1486            gphNxpExtns_Context.CallBackMifare(gphNxpExtns_Context.CallBackCtxt, status);
1487        }
1488    }
1489
1490    return status;
1491}
1492
1493/*******************************************************************************
1494**
1495** Function         phNciNfc_MfCreateXchgDataHdr
1496**
1497** Description      This function builds the payload header for mifare XchgData
1498**                  request to be sent to NFCC.
1499**
1500** Returns          NFCSTATUS_PENDING            - Command framing done
1501**                  NFCSTATUS_FAILED             - Otherwise
1502**
1503*******************************************************************************/
1504STATIC
1505NFCSTATUS
1506phNciNfc_MfCreateXchgDataHdr(phNciNfc_TransceiveInfo_t tTranscvInfo,
1507                             uint8_t *buff, uint16_t *buffSz)
1508
1509{
1510    NFCSTATUS   status = NFCSTATUS_SUCCESS;
1511    uint8_t     i = 0;
1512
1513    buff[i++] = phNciNfc_e_MfRawDataXchgHdr;
1514    memcpy(&buff[i],tTranscvInfo.tSendData.pBuff,tTranscvInfo.tSendData.wLen);
1515    *buffSz = i + tTranscvInfo.tSendData.wLen;
1516
1517    status = nativeNfcExtns_doTransceive(buff, (uint16_t) *buffSz);
1518
1519    return status;
1520}
1521
1522/*******************************************************************************
1523**
1524** Function         phNciNfc_MfCreateAuthCmdHdr
1525**
1526** Description      This function builds the payload header for mifare
1527**                  classic Authenticate command to be sent to NFCC.
1528**
1529** Returns          NFCSTATUS_PENDING            - Command framing done
1530**                  NFCSTATUS_FAILED             - Otherwise
1531**
1532*******************************************************************************/
1533STATIC
1534NFCSTATUS
1535phNciNfc_MfCreateAuthCmdHdr(phNciNfc_TransceiveInfo_t tTranscvInfo,
1536                            uint8_t    bBlockAddr,
1537                            uint8_t    *buff,
1538                            uint16_t    *buffSz)
1539{
1540    NFCSTATUS               status = NFCSTATUS_SUCCESS;
1541//    pphNciNfc_RemoteDevInformation_t  pActivDev = NULL;           /*commented to eliminate unused variable warning*/
1542    uint8_t bKey = 0x00;
1543
1544    /*No need to check range of block address*/
1545    /*To check for Authenticate A or Authenticate B type command*/
1546    if(PHNCINFC_AUTHENTICATION_KEYB ==
1547       tTranscvInfo.tSendData.pBuff[0] )
1548    {
1549        bKey = bKey | PHNCINFC_ENABLE_KEY_B;
1550    }
1551
1552    /*TO Do last 4 bits of Key to be set based of firmware implementation*/
1553    /*this value is hardcoded but based on firmware implementation change this value*/
1554    bKey = (bKey | PHNCINFC_AUTHENTICATION_KEY);
1555
1556    bKey |= tTranscvInfo.tSendData.pBuff[2];
1557
1558    /*For authentication extension no need to copy tSendData buffer of tTranscvInfo */
1559    tTranscvInfo.tSendData.wLen = 0x00;
1560
1561    buff[0] = phNciNfc_e_MfcAuthReq;
1562    buff[1] = bBlockAddr;
1563    buff[2] = bKey;
1564
1565    *buffSz = 0x03;
1566    if (bKey & PH_NCINFC_MIFARECLASSIC_EMBEDDED_KEY)
1567    {
1568        memcpy(&buff[3],&tTranscvInfo.tSendData.pBuff[3], PHLIBNFC_MFC_AUTHKEYLEN);
1569        *buffSz += PHLIBNFC_MFC_AUTHKEYLEN;
1570    }
1571    /* Store the auth command buffer to use further for presence check */
1572    if (gAuthCmdBuf.pauth_cmd != NULL)
1573    {
1574        memset(gAuthCmdBuf.pauth_cmd->buffer, 0, NCI_MAX_DATA_LEN);
1575        gAuthCmdBuf.pauth_cmd->length = *buffSz;
1576        memcpy(gAuthCmdBuf.pauth_cmd->buffer, buff, *buffSz);
1577    }
1578    status = nativeNfcExtns_doTransceive(buff,(uint16_t) *buffSz);
1579
1580    return status;
1581}
1582
1583/*******************************************************************************
1584**
1585** Function         phNciNfc_SendMfReq
1586**
1587** Description      This function shall be invoked as part of ReaderMgmt data
1588**                  exchange sequence handler.
1589**                  It shall send the request packet to NFCC.
1590**
1591** Returns          NFCSTATUS_PENDING  - Send request is Pending
1592**                  NFCSTATUS_FAILED   - otherwise
1593**
1594*******************************************************************************/
1595STATIC NFCSTATUS
1596phNciNfc_SendMfReq(phNciNfc_TransceiveInfo_t tTranscvInfo, uint8_t *buff, uint16_t *buffSz)
1597{
1598    NFCSTATUS status = NFCSTATUS_SUCCESS;
1599
1600    switch(tTranscvInfo.uCmd.T2TCmd)
1601    {
1602        case phNciNfc_eT2TRaw:
1603        {
1604            status = phNciNfc_MfCreateXchgDataHdr(tTranscvInfo, buff, buffSz);
1605        }
1606        break;
1607        case phNciNfc_eT2TAuth:
1608        {
1609            status = phNciNfc_MfCreateAuthCmdHdr(tTranscvInfo,
1610                (tTranscvInfo.bAddr), buff, buffSz);
1611        }
1612        break;
1613        default:
1614        {
1615            status = NFCSTATUS_FAILED;
1616            break;
1617        }
1618    }
1619
1620    return status;
1621}
1622
1623/*******************************************************************************
1624**
1625** Function         phLibNfc_CalSectorAddress
1626**
1627** Description      This function update the sector address for Mifare classic
1628**
1629** Returns          none
1630**
1631*******************************************************************************/
1632STATIC void phLibNfc_CalSectorAddress(uint8_t *Sector_Address)
1633{
1634    uint8_t BlockNumber = 0x00;
1635
1636    if(NULL != Sector_Address)
1637    {
1638        BlockNumber = *Sector_Address;
1639        if(BlockNumber >= PHLIBNFC_MIFARESTD4K_BLK128)
1640        {
1641            *Sector_Address = (uint8_t)(PHLIBNFC_MIFARESTD_SECTOR_NO32 +
1642                              ((BlockNumber - PHLIBNFC_MIFARESTD4K_BLK128)/
1643                               PHLIBNFC_MIFARESTD_BLOCK_BYTES));
1644        }
1645        else
1646        {
1647            *Sector_Address = BlockNumber/PHLIBNFC_NO_OF_BLKPERSECTOR;
1648        }
1649     }
1650    else
1651    {
1652    }
1653
1654    return;
1655}
1656
1657/*******************************************************************************
1658**
1659** Function         phLibNfc_GetKeyNumberMFC
1660**
1661** Description      This function find key number based on authentication command
1662**
1663** Returns          NFCSTATUS_SUCCESS  - If found the key number
1664**                  NFCSTATUS_FAILED   - otherwise
1665**
1666*******************************************************************************/
1667STATIC NFCSTATUS phLibNfc_GetKeyNumberMFC(uint8_t *buffer,uint8_t *bKey)
1668{
1669    int32_t sdwStat   = 0X00;
1670    NFCSTATUS wStatus = NFCSTATUS_INVALID_PARAMETER;
1671
1672    /*Key Configuration
1673    uint8_t NdefKey[PHLIBNFC_MFC_AUTHKEYLEN] = {0xD3,0XF7,0xD3,0XF7,0xD3,0XF7};
1674    uint8_t RawKey[PHLIBNFC_MFC_AUTHKEYLEN] = {0xFF,0XFF,0xFF,0XFF,0xFF,0XFF};
1675    uint8_t MadKey[PHLIBNFC_MFC_AUTHKEYLEN] = {0xA0,0XA1,0xA2,0XA3,0xA4,0XA5};
1676    uint8_t Key[PHLIBNFC_MFC_AUTHKEYLEN] = {0x00,0x00,0x00,0x00,0x00,0x00}; */ /*Key used during ndef format*/
1677
1678    uint8_t bIndex = 0x00;
1679    uint8_t bNoOfKeys = 0x00;
1680
1681#if PHLIBNFC_NXPETENSION_CONFIGURE_MFKEYS
1682    uint8_t aMfc_keys[NXP_NUMBER_OF_MFC_KEYS][NXP_MFC_KEY_SIZE] = NXP_MFC_KEYS;
1683#else
1684    uint8_t aMfc_keys[1][1] = {{0x00}};
1685#endif
1686
1687    if(NULL != bKey &&
1688       NULL != buffer )
1689    {
1690       bNoOfKeys = sizeof(aMfc_keys)/NXP_MFC_KEY_SIZE;
1691        /* Traverse through the keys stored to determine whether keys is preloaded key */
1692       for(bIndex = 0; bIndex < bNoOfKeys; bIndex++)
1693       {
1694           /* Check passed key is NDEF key */
1695           sdwStat = memcmp(&buffer[PHLIBNFC_MFCUIDLEN_INAUTHCMD],
1696                                  aMfc_keys[bIndex], PHLIBNFC_MFC_AUTHKEYLEN);
1697           if(!sdwStat)
1698           {
1699               NXPLOG_EXTNS_E("Mifare : phLibNfc_GetKeyNumberMFC Key found");
1700               *bKey = bIndex;
1701               wStatus = NFCSTATUS_SUCCESS;
1702               break;
1703           }
1704        }
1705       NXPLOG_EXTNS_E("Mifare : phLibNfc_GetKeyNumberMFC returning = 0x%x Key = 0x%x", wStatus, *bKey);
1706    }
1707    else
1708    {
1709        wStatus = NFCSTATUS_FAILED;
1710        NXPLOG_EXTNS_E("Mifare : phLibNfc_GetKeyNumberMFC returning = 0x%x", wStatus);
1711    }
1712
1713    return wStatus;
1714}
1715
1716/*******************************************************************************
1717**
1718** Function         phLibNfc_ChkAuthCmdMFC
1719**
1720** Description      This function Check Authentication command send is proper or not
1721**
1722** Returns          NFCSTATUS_SUCCESS  - Authenticate command is proper
1723**                  NFCSTATUS_FAILED   - otherwise
1724**
1725*******************************************************************************/
1726STATIC NFCSTATUS phLibNfc_ChkAuthCmdMFC(phNfc_sTransceiveInfo_t* pTransceiveInfo,
1727                                 uint8_t *bKey)
1728{
1729    NFCSTATUS wStatus  = NFCSTATUS_SUCCESS;
1730
1731    if(NULL != pTransceiveInfo &&
1732       NULL != pTransceiveInfo->sSendData.buffer &&
1733       0 != pTransceiveInfo->sSendData.length &&
1734       NULL != bKey)
1735    {
1736        if((pTransceiveInfo->cmd.MfCmd == phNfc_eMifareAuthentA ||
1737           pTransceiveInfo->cmd.MfCmd == phNfc_eMifareAuthentB ))
1738        {
1739            wStatus = phLibNfc_GetKeyNumberMFC(pTransceiveInfo->sSendData.buffer,bKey);
1740        }
1741        else
1742        {
1743            wStatus = NFCSTATUS_FAILED;
1744        }
1745    }else
1746    {
1747        wStatus = NFCSTATUS_FAILED;
1748    }
1749    return wStatus;
1750}
1751
1752/*******************************************************************************
1753**
1754** Function         phLibNfc_MifareMap
1755**
1756** Description      Mifare Mapping Utility function
1757**
1758** Returns          NFCSTATUS_SUCCESS             - Mapping is proper
1759**                  NFCSTATUS_INVALID_PARAMETER   - otherwise
1760**
1761*******************************************************************************/
1762STATIC NFCSTATUS phLibNfc_MifareMap(phNfc_sTransceiveInfo_t*    pTransceiveInfo,
1763                                    pphNciNfc_TransceiveInfo_t   pMappedTranscvIf)
1764{
1765    NFCSTATUS status = NFCSTATUS_SUCCESS;
1766    uint8_t bBuffIdx = 0;
1767    uint8_t bSectorNumber;
1768    uint8_t bKey = 0;
1769
1770    switch(pTransceiveInfo->cmd.MfCmd)
1771    {
1772        case phNfc_eMifareRead16:
1773        {
1774            if( (NULL != pTransceiveInfo->sRecvData.buffer) &&
1775                (0 != (pTransceiveInfo->sRecvData.length)))
1776            {
1777                pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = phNfc_eMifareRead16;
1778                pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = pTransceiveInfo->addr;
1779                pMappedTranscvIf->tSendData.wLen              = bBuffIdx;
1780                pMappedTranscvIf->uCmd.T2TCmd                 = phNciNfc_eT2TRaw;
1781            }
1782            else
1783            {
1784                status = NFCSTATUS_INVALID_PARAMETER;
1785            }
1786        }
1787        break;
1788
1789        case phNfc_eMifareWrite16:
1790        {
1791            if( (NULL != pTransceiveInfo->sSendData.buffer) &&
1792                (0 != (pTransceiveInfo->sSendData.length)))
1793            {
1794                pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = phNfc_eMifareWrite16;
1795                pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = pTransceiveInfo->addr;
1796                memcpy(&(pMappedTranscvIf->tSendData.pBuff[bBuffIdx]),pTransceiveInfo->sSendData.buffer,
1797                                      (pTransceiveInfo->sSendData.length));
1798                pMappedTranscvIf->tSendData.wLen              = bBuffIdx + pTransceiveInfo->sSendData.length;
1799                pMappedTranscvIf->uCmd.T2TCmd                 = phNciNfc_eT2TRaw;
1800            }
1801            else
1802            {
1803                status = NFCSTATUS_INVALID_PARAMETER;
1804            }
1805        }
1806        break;
1807
1808        case phNfc_eMifareAuthentA:
1809        case phNfc_eMifareAuthentB:
1810        {
1811            if( (NULL != pTransceiveInfo->sSendData.buffer) &&
1812                (0 != (pTransceiveInfo->sSendData.length)) &&
1813                (NULL != pTransceiveInfo->sRecvData.buffer) &&
1814                (0 != (pTransceiveInfo->sRecvData.length))
1815                )
1816            {
1817                status = phLibNfc_ChkAuthCmdMFC(pTransceiveInfo, &bKey);
1818                if(NFCSTATUS_FAILED != status )
1819                {
1820                    bSectorNumber = pTransceiveInfo->addr;
1821                    phLibNfc_CalSectorAddress(&bSectorNumber);
1822                    /*For creating extension command header pTransceiveInfo's MfCmd get used*/
1823                    pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = pTransceiveInfo->cmd.MfCmd;
1824                    pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = bSectorNumber;
1825                    pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TAuth;
1826                    pMappedTranscvIf->bAddr = bSectorNumber;
1827                    pMappedTranscvIf->bNumBlock = pTransceiveInfo->NumBlock;
1828                    if(NFCSTATUS_SUCCESS == status)
1829                    {
1830                        pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = bKey;
1831                        (pMappedTranscvIf->tSendData.wLen) = (uint16_t)(bBuffIdx);
1832
1833                    }
1834                    else if(NFCSTATUS_INVALID_PARAMETER == status)
1835                    {
1836                        bKey = bKey | PH_NCINFC_MIFARECLASSIC_EMBEDDED_KEY;
1837                        pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = bKey;
1838                        memcpy(&pMappedTranscvIf->tSendData.pBuff[bBuffIdx],
1839                                &pTransceiveInfo->sSendData.buffer[PHLIBNFC_MFCUIDLEN_INAUTHCMD], PHLIBNFC_MFC_AUTHKEYLEN);
1840
1841                        (pMappedTranscvIf->tSendData.wLen) = (uint16_t)(bBuffIdx + PHLIBNFC_MFC_AUTHKEYLEN);
1842                        status = NFCSTATUS_SUCCESS;
1843                    }
1844                    else
1845                    {
1846                        /* do nothing */
1847                    }
1848                }
1849            }
1850            else
1851            {
1852                status = NFCSTATUS_INVALID_PARAMETER;
1853            }
1854        }
1855        break;
1856
1857        case phNfc_eMifareRaw:
1858        {
1859
1860        }
1861        break;
1862
1863        default:
1864        {
1865            status = NFCSTATUS_INVALID_PARAMETER;
1866            break;
1867        }
1868    }
1869
1870    return status;
1871}
1872
1873/*******************************************************************************
1874**
1875** Function         phLibNfc_MapCmds
1876**
1877** Description      This function maps the command request from libnfc level to nci level
1878**
1879** Returns          NFCSTATUS_SUCCESS           - Mapping of command is successful
1880**                  NFCSTATUS_INVALID_PARAMETER - One or more of the supplied
1881**                  parameters could not be interpreted properly
1882**
1883*******************************************************************************/
1884STATIC NFCSTATUS phLibNfc_MapCmds(phNciNfc_RFDevType_t         RemDevType,
1885                           phNfc_sTransceiveInfo_t*  pTransceiveInfo,
1886                           pphNciNfc_TransceiveInfo_t   pMappedTranscvIf)
1887{
1888
1889    NFCSTATUS status = NFCSTATUS_SUCCESS;
1890
1891    if((NULL == pTransceiveInfo) || (NULL == pMappedTranscvIf))
1892    {
1893        return NFCSTATUS_FAILED;
1894    }
1895    switch(RemDevType)
1896    {
1897        case phNciNfc_eMifare1k_PICC:
1898        case phNciNfc_eMifare4k_PICC:
1899        {
1900            status = phLibNfc_MifareMap(pTransceiveInfo,pMappedTranscvIf);
1901            break;
1902        }
1903        default:
1904        {
1905            break;
1906        }
1907    }
1908
1909    return status;
1910}
1911
1912/*******************************************************************************
1913**
1914** Function         phLibNfc_SendAuthCmd
1915**
1916** Description      This function Send authentication command to NFCC
1917**
1918** Returns          NFCSTATUS_SUCCESS           - Parameters are proper
1919**                  NFCSTATUS_INVALID_PARAMETER - Otherwise
1920**
1921*******************************************************************************/
1922STATIC NFCSTATUS phLibNfc_SendAuthCmd(phNfc_sTransceiveInfo_t *pTransceiveInfo,
1923                                      phNciNfc_TransceiveInfo_t  *tNciTranscvInfo)
1924{
1925    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
1926
1927    wStatus = phLibNfc_MapCmds(phNciNfc_eMifare1k_PICC, pTransceiveInfo, tNciTranscvInfo);
1928
1929    return wStatus;
1930}
1931
1932/*******************************************************************************
1933**
1934** Function         phLibNfc_SendWrt16Cmd
1935**
1936** Description      This function maps Mifarewirte16 commands
1937**
1938** Returns          NFCSTATUS_SUCCESS           - Parameters are mapped
1939**                  NFCSTATUS_INVALID_PARAMETER - Otherwise
1940**
1941*******************************************************************************/
1942STATIC NFCSTATUS phLibNfc_SendWrt16Cmd(phNfc_sTransceiveInfo_t*    pTransceiveInfo,
1943                                    pphNciNfc_TransceiveInfo_t   pMappedTranscvIf)
1944{
1945    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
1946    uint8_t bBuffIdx = 0x00;
1947
1948    if( (NULL != pTransceiveInfo->sSendData.buffer) &&
1949        (0 != (pTransceiveInfo->sSendData.length)))
1950    {
1951        pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = phNfc_eMifareWrite16;
1952        pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = pTransceiveInfo->addr;
1953        pMappedTranscvIf->tSendData.wLen              = bBuffIdx;
1954        pMappedTranscvIf->uCmd.T2TCmd                 = phNciNfc_eT2TRaw;
1955    }
1956    else
1957    {
1958        wStatus = NFCSTATUS_INVALID_PARAMETER;
1959    }
1960
1961    return wStatus;
1962}
1963
1964/*******************************************************************************
1965**
1966** Function         phLibNfc_SendIncDecCmd
1967**
1968** Description      This function prepares the Increment/Decrement command
1969**                  to be sent, increment/decrement value is sent separately
1970**
1971** Returns          NFCSTATUS_SUCCESS           - Params are mapped
1972**                  NFCSTATUS_INVALID_PARAMETER - Otherwise
1973**
1974*******************************************************************************/
1975STATIC NFCSTATUS phLibNfc_SendIncDecCmd(phNfc_sTransceiveInfo_t*    pTransceiveInfo,
1976                                    pphNciNfc_TransceiveInfo_t   pMappedTranscvIf,
1977                                    uint8_t IncDecCmd)
1978{
1979    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
1980    uint8_t bBuffIdx = 0x00;
1981
1982    if( (NULL != pTransceiveInfo->sSendData.buffer) &&
1983        (0 != (pTransceiveInfo->sSendData.length)))
1984    {
1985        pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = IncDecCmd;
1986        pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = pTransceiveInfo->addr;
1987        pMappedTranscvIf->tSendData.wLen              = bBuffIdx;
1988        pMappedTranscvIf->uCmd.T2TCmd                 = phNciNfc_eT2TRaw;
1989    }
1990    else
1991    {
1992        wStatus = NFCSTATUS_INVALID_PARAMETER;
1993    }
1994
1995    return wStatus;
1996}
1997
1998/*******************************************************************************
1999**
2000** Function         phLibNfc_SendRawCmd
2001**
2002** Description      This function maps Mifare raw command
2003**
2004** Returns          NFCSTATUS_SUCCESS           - Parameters are mapped
2005**                  NFCSTATUS_INVALID_PARAMETER - Otherwise
2006**
2007*******************************************************************************/
2008STATIC NFCSTATUS phLibNfc_SendRawCmd(phNfc_sTransceiveInfo_t*    pTransceiveInfo,
2009                                    pphNciNfc_TransceiveInfo_t   pMappedTranscvIf)
2010{
2011    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
2012//    uint8_t bBuffIdx = 0x00;                                  /*commented to eliminate unused variable warning*/
2013
2014    if( (NULL != pTransceiveInfo->sSendData.buffer) &&
2015        (0 != (pTransceiveInfo->sSendData.length)))
2016    {
2017        memcpy(pMappedTranscvIf->tSendData.pBuff, pTransceiveInfo->sSendData.buffer,
2018                              (pTransceiveInfo->sSendData.length));
2019        pMappedTranscvIf->tSendData.wLen              = pTransceiveInfo->sSendData.length;
2020        pMappedTranscvIf->uCmd.T2TCmd                 = phNciNfc_eT2TRaw;
2021    }
2022    else
2023    {
2024        wStatus = NFCSTATUS_INVALID_PARAMETER;
2025    }
2026
2027    return wStatus;
2028}
2029
2030/*******************************************************************************
2031**
2032** Function         phFriNfc_ExtnsTransceive
2033**
2034** Description      This function maps Mifare raw command and send it to NFCC
2035**
2036** Returns          NFCSTATUS_PENDING           - Operation successful
2037**                  NFCSTATUS_INVALID_PARAMETER - Otherwise
2038**
2039*******************************************************************************/
2040NFCSTATUS phFriNfc_ExtnsTransceive(phNfc_sTransceiveInfo_t *pTransceiveInfo,
2041                                   phNfc_uCmdList_t Cmd,
2042                                   uint8_t *SendRecvBuf,
2043                                   uint16_t SendLength,
2044                                   uint16_t *SendRecvLength)
2045{
2046    (void)SendRecvLength;
2047    NFCSTATUS status = NFCSTATUS_FAILED;
2048    uint8_t *buff=NULL;
2049    uint16_t buffSz=0;
2050    uint8_t i = 0;
2051    uint32_t length = SendLength;
2052    uint8_t restore_payload[]={0x00, 0x00, 0x00, 0x00,};
2053
2054    buff = (uint8_t *)malloc((uint32_t)MAX_BUFF_SIZE);
2055    if( NULL == buff )
2056    {
2057        return status;
2058    }
2059
2060    pTransceiveInfo->cmd = Cmd;
2061
2062    if( (Cmd.MfCmd == phNfc_eMifareAuthentA) ||
2063        (Cmd.MfCmd == phNfc_eMifareAuthentB) )
2064    {
2065        pTransceiveInfo->addr = SendRecvBuf[i++];
2066        pTransceiveInfo->sSendData.buffer[4] = SendRecvBuf[i++];
2067        pTransceiveInfo->sSendData.buffer[5] = SendRecvBuf[i++];
2068        pTransceiveInfo->sSendData.buffer[6] = SendRecvBuf[i++];
2069        pTransceiveInfo->sSendData.buffer[7] = SendRecvBuf[i++];
2070        pTransceiveInfo->sSendData.buffer[8] = SendRecvBuf[i++];
2071        pTransceiveInfo->sSendData.buffer[9] = SendRecvBuf[i++];
2072
2073        pTransceiveInfo->cmd.MfCmd = Cmd.MfCmd;
2074
2075        pTransceiveInfo->sSendData.length = length;
2076        pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE;
2077        status = phLibNfc_MifareMap(pTransceiveInfo, &tNciTranscvInfo);
2078    }
2079    else if( Cmd.MfCmd == phNfc_eMifareWrite16 )
2080    {
2081        pTransceiveInfo->addr = SendRecvBuf[i++];
2082        length = SendLength - i;
2083        memcpy(pTransceiveInfo->sSendData.buffer, &SendRecvBuf[i], length);
2084        pTransceiveInfo->sSendData.length = length;
2085        pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE;
2086
2087        gphNxpExtns_Context.writecmdFlag = TRUE;
2088
2089        status = phLibNfc_SendWrt16Cmd(pTransceiveInfo, &tNciTranscvInfo);
2090    }
2091    else if( (Cmd.MfCmd == phNfc_eMifareInc) || (Cmd.MfCmd == phNfc_eMifareDec) )
2092    {
2093        pTransceiveInfo->addr = SendRecvBuf[i++];
2094        length = SendLength - i;
2095        memcpy(pTransceiveInfo->sSendData.buffer, &SendRecvBuf[i], length);
2096        pTransceiveInfo->sSendData.length = length;
2097        pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE;
2098
2099        gphNxpExtns_Context.incrdecflag = TRUE;
2100
2101        status = phLibNfc_SendIncDecCmd(pTransceiveInfo, &tNciTranscvInfo, Cmd.MfCmd);
2102
2103    }
2104    else if(Cmd.MfCmd == phNfc_eMifareRestore)
2105    {
2106        pTransceiveInfo->addr = SendRecvBuf[i++];
2107        length = SendLength - i;
2108        memcpy(pTransceiveInfo->sSendData.buffer, &restore_payload[0], sizeof(restore_payload));
2109        pTransceiveInfo->sSendData.length = length + sizeof(restore_payload);
2110        pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE;
2111
2112        gphNxpExtns_Context.incrdecflag = TRUE;
2113
2114        status = phLibNfc_SendIncDecCmd(pTransceiveInfo, &tNciTranscvInfo, Cmd.MfCmd);
2115
2116    }
2117    else if ((Cmd.MfCmd == phNfc_eMifareRaw) || (Cmd.MfCmd == phNfc_eMifareTransfer ))
2118    {
2119        pTransceiveInfo->cmd.MfCmd = (phNfc_eMifareCmdList_t) phNciNfc_eT2TRaw;
2120        memcpy(pTransceiveInfo->sSendData.buffer, SendRecvBuf, length);
2121        pTransceiveInfo->sSendData.length = length;
2122        pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE;
2123        status = phLibNfc_SendRawCmd(pTransceiveInfo, &tNciTranscvInfo);
2124    }
2125    else
2126    {
2127        pTransceiveInfo->addr = SendRecvBuf[i++];
2128        length = SendLength - i;
2129        memcpy(pTransceiveInfo->sSendData.buffer, &SendRecvBuf[i], length);
2130        pTransceiveInfo->sSendData.length = length;
2131        pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE;
2132        status = phLibNfc_MifareMap(pTransceiveInfo, &tNciTranscvInfo);
2133    }
2134
2135    if (NFCSTATUS_SUCCESS == status )
2136    {
2137        status = phNciNfc_SendMfReq(tNciTranscvInfo, buff, &buffSz);
2138        if (NFCSTATUS_PENDING != status)
2139        {
2140            NXPLOG_EXTNS_E("ERROR : phNciNfc_SendMfReq()");
2141        }
2142    }
2143    else
2144    {
2145        NXPLOG_EXTNS_E (" ERROR : Sending phNciNfc_SendMfReq");
2146    }
2147    if( buff != NULL )
2148    {
2149        free(buff);
2150        buff = NULL;
2151    }
2152
2153    return status;
2154}
2155