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 /*
18  * Smart Card Completion Routing component
19  */
20 
21 #include <phFriNfc.h>
22 #include <phFriNfc_MifStdFormat.h>
23 #include <phFriNfc_SmtCrdFmt.h>
24 #include <phNfcCompId.h>
25 #include <phNfcTypes.h>
26 
27 /*******************************************************************************
28 **
29 ** Function         phFriNfc_SmtCrdFmt_HCrHandler
30 **
31 ** Description      This function is called to complete Completion Routine when
32 *gets error.
33 **
34 ** Returns          none.
35 **
36 *******************************************************************************/
phFriNfc_SmtCrdFmt_HCrHandler(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt,NFCSTATUS Status)37 void phFriNfc_SmtCrdFmt_HCrHandler(phFriNfc_sNdefSmtCrdFmt_t* NdefSmtCrdFmt,
38                                    NFCSTATUS Status) {
39   /* set the state back to the Reset_Init state*/
40   NdefSmtCrdFmt->State = PH_FRINFC_SMTCRDFMT_STATE_RESET_INIT;
41 
42   /* set the completion routine*/
43   NdefSmtCrdFmt->CompletionRoutine[PH_FRINFC_SMTCRDFMT_CR_FORMAT]
44       .CompletionRoutine(NdefSmtCrdFmt->CompletionRoutine->Context, Status);
45 
46   return;
47 }
48 
49 /*******************************************************************************
50 **
51 ** Function         phFriNfc_NdefSmtCrd_Reset
52 **
53 ** Description      Resets the component instance to the initial state and
54 *initializes the
55 **                  internal variables.
56 **                  This function has to be called at the beginning, after
57 *creating an instance of
58 **                  phFriNfc_sNdefSmtCrdFmt_t.  Use this function to reset the
59 *instance and/or to switch
60 **                  to a different underlying card types.
61 **
62 ** Returns          NFCSTATUS_SUCCESS if operation successful.
63 **                  NFCSTATUS_INVALID_PARAMETER if at least one parameter of the
64 *function is invalid.
65 **
66 *******************************************************************************/
67 NFCSTATUS
phFriNfc_NdefSmtCrd_Reset(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt,void * LowerDevice,phHal_sRemoteDevInformation_t * psRemoteDevInfo,uint8_t * SendRecvBuffer,uint16_t * SendRecvBuffLen)68 phFriNfc_NdefSmtCrd_Reset(phFriNfc_sNdefSmtCrdFmt_t* NdefSmtCrdFmt,
69                           void* LowerDevice,
70                           phHal_sRemoteDevInformation_t* psRemoteDevInfo,
71                           uint8_t* SendRecvBuffer, uint16_t* SendRecvBuffLen) {
72   NFCSTATUS result = NFCSTATUS_SUCCESS;
73   uint8_t index;
74   if ((SendRecvBuffLen == NULL) || (NdefSmtCrdFmt == NULL) ||
75       (psRemoteDevInfo == NULL) || (SendRecvBuffer == NULL) ||
76       (LowerDevice == NULL) || (*SendRecvBuffLen == 0) ||
77       (*SendRecvBuffLen < PH_FRINFC_SMTCRDFMT_MAX_SEND_RECV_BUF_SIZE)) {
78     result =
79         PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_PARAMETER);
80   } else {
81     /* Initialize the state to Init */
82     NdefSmtCrdFmt->State = PH_FRINFC_SMTCRDFMT_STATE_RESET_INIT;
83 
84     for (index = 0; index < PH_FRINFC_SMTCRDFMT_CR; index++) {
85       /* Initialize the NdefMap Completion Routine to Null */
86       NdefSmtCrdFmt->CompletionRoutine[index].CompletionRoutine = NULL;
87       /* Initialize the NdefMap Completion Routine context to Null  */
88       NdefSmtCrdFmt->CompletionRoutine[index].Context = NULL;
89     }
90 
91     /* Lower Device(Always Overlapped HAL Struct initialized in application
92      * is registered in NdefMap Lower Device)
93      */
94     NdefSmtCrdFmt->pTransceiveInfo = (phNfc_sTransceiveInfo*)LowerDevice;
95 
96     /* Remote Device info received from Manual Device Discovery is registered
97      * here */
98     NdefSmtCrdFmt->psRemoteDevInfo = psRemoteDevInfo;
99 
100     /* Trx Buffer registered */
101     NdefSmtCrdFmt->SendRecvBuf = SendRecvBuffer;
102 
103     /* Trx Buffer Size */
104     NdefSmtCrdFmt->SendRecvLength = SendRecvBuffLen;
105 
106     /* Register Transfer Buffer Length */
107     NdefSmtCrdFmt->SendLength = 0;
108 
109     /* Initialize the Format status flag*/
110     NdefSmtCrdFmt->FmtProcStatus = 0;
111 
112     /* Reset the Card Type */
113     NdefSmtCrdFmt->CardType = 0;
114 
115     /* Reset MapCompletion Info*/
116     NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine = NULL;
117     NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = NULL;
118 
119     /* Reset Mifare Standard Container elements*/
120     phFriNfc_MfStd_Reset(NdefSmtCrdFmt);
121   }
122 
123   return (result);
124 }
125 
126 /*******************************************************************************
127 **
128 ** Function         phFriNfc_NdefSmtCrd_SetCR
129 **
130 ** Description      This function allows the caller to set a Completion Routine
131 *(notifier).
132 **
133 ** Returns          NFCSTATUS_SUCCESS if operation successful.
134 **                  NFCSTATUS_INVALID_PARAMETER if at least one parameter of the
135 *function is invalid.
136 **
137 *******************************************************************************/
phFriNfc_NdefSmtCrd_SetCR(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt,uint8_t FunctionID,pphFriNfc_Cr_t CompletionRoutine,void * CompletionRoutineContext)138 NFCSTATUS phFriNfc_NdefSmtCrd_SetCR(phFriNfc_sNdefSmtCrdFmt_t* NdefSmtCrdFmt,
139                                     uint8_t FunctionID,
140                                     pphFriNfc_Cr_t CompletionRoutine,
141                                     void* CompletionRoutineContext) {
142   NFCSTATUS status = NFCSTATUS_SUCCESS;
143   if ((NdefSmtCrdFmt == NULL) || (FunctionID >= PH_FRINFC_SMTCRDFMT_CR) ||
144       (CompletionRoutine == NULL) || (CompletionRoutineContext == NULL)) {
145     status =
146         PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_PARAMETER);
147   } else {
148     /* Register the application callback with the NdefMap Completion Routine */
149     NdefSmtCrdFmt->CompletionRoutine[FunctionID].CompletionRoutine =
150         CompletionRoutine;
151 
152     /* Register the application context with the NdefMap Completion Routine
153      * context */
154     NdefSmtCrdFmt->CompletionRoutine[FunctionID].Context =
155         CompletionRoutineContext;
156   }
157   return status;
158 }
159 
160 /*******************************************************************************
161 **
162 ** Function         phFriNfc_NdefSmtCrd_Process
163 **
164 ** Description      This function is called by the lower layer (OVR HAL)
165 **                  when an I/O operation has finished. The internal state
166 *machine decides
167 **                  whether to call into the lower device again or to complete
168 *the process
169 **                  by calling into the upper layer's completion routine, stored
170 *within this
171 **                  component's context (phFriNfc_sNdefSmtCrdFmt_t).
172 **
173 ** Returns          none.
174 **
175 *******************************************************************************/
phFriNfc_NdefSmtCrd_Process(void * Context,NFCSTATUS Status)176 void phFriNfc_NdefSmtCrd_Process(void* Context, NFCSTATUS Status) {
177   if (Context != NULL) {
178     phFriNfc_sNdefSmtCrdFmt_t* NdefSmtCrdFmt =
179         (phFriNfc_sNdefSmtCrdFmt_t*)Context;
180 
181     switch (NdefSmtCrdFmt->psRemoteDevInfo->RemDevType) {
182       case phNfc_eMifare_PICC:
183       case phNfc_eISO14443_3A_PICC:
184         if ((NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD) ||
185             (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD) ||
186             (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD)) {
187           /* Remote device is Mifare Standard card */
188           phFriNfc_MfStd_Process(NdefSmtCrdFmt, Status);
189 
190         } else {
191           Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
192                               NFCSTATUS_INVALID_REMOTE_DEVICE);
193         }
194         break;
195       default:
196         /* Remote device opmode not recognized.
197          * Probably not NDEF compliant
198          */
199         Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
200                             NFCSTATUS_INVALID_REMOTE_DEVICE);
201         /* set the state back to the Reset_Init state*/
202         NdefSmtCrdFmt->State = PH_FRINFC_SMTCRDFMT_STATE_RESET_INIT;
203 
204         /* set the completion routine*/
205         NdefSmtCrdFmt->CompletionRoutine[PH_FRINFC_SMTCRDFMT_CR_INVALID_OPE]
206             .CompletionRoutine(NdefSmtCrdFmt->CompletionRoutine->Context,
207                                Status);
208         break;
209     }
210   } else {
211     Status =
212         PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_PARAMETER);
213     /* The control should not come here. As Context itself is NULL ,
214      * Can't call the CR
215      */
216   }
217 
218   return;
219 }
220