Initialize Tizen 2.3
[adaptation/devices/nfc-plugin-nxp.git] / src / phFriNfc_LlcpMacNfcip.c
1 /*
2  * Copyright (C) 2010 NXP Semiconductors
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 /**
19  * \file  phFriNfc_LlcpMacNfcip.c
20  * \brief NFC LLCP MAC Mappings For Different RF Technologies.
21  *
22  * Project: NFC-FRI
23  *
24  */
25
26
27 /*include files*/
28 #include <phFriNfc_LlcpMac.h>
29 #include <phLibNfcStatus.h>
30 #include <phLibNfc.h>
31 #include <phLibNfc_Internal.h>
32 #include <stdio.h>
33 #include <string.h>
34
35 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t               *LlcpMac,
36                                              phNfc_sData_t                    *psData,
37                                              phFriNfc_LlcpMac_Send_CB_t       LlcpMacSend_Cb,
38                                              void                             *pContext);
39
40
41 static void phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(phFriNfc_LlcpMac_t  *LlcpMac,
42                                                  NFCSTATUS           status)
43 {
44    phFriNfc_LlcpMac_Reveive_CB_t pfReceiveCB;
45    void                          *pReceiveContext;
46
47    if (LlcpMac->MacReceive_Cb != NULL)
48    {
49       /* Save callback params */
50       pfReceiveCB = LlcpMac->MacReceive_Cb;
51       pReceiveContext = LlcpMac->MacReceive_Context;
52
53       /* Reset the pointer to the Receive Callback and Context*/
54       LlcpMac->MacReceive_Cb = NULL;
55       LlcpMac->MacReceive_Context = NULL;
56
57       /* Call the receive callback */
58       pfReceiveCB(pReceiveContext, status, LlcpMac->psReceiveBuffer);
59    }
60 }
61
62 static void phFriNfc_LlcpMac_Nfcip_TriggerSendCb(phFriNfc_LlcpMac_t  *LlcpMac,
63                                                  NFCSTATUS           status)
64 {
65    phFriNfc_LlcpMac_Send_CB_t pfSendCB;
66    void                       *pSendContext;
67
68    if (LlcpMac->MacSend_Cb != NULL)
69    {
70       /* Save context in local variables */
71       pfSendCB     = LlcpMac->MacSend_Cb;
72       pSendContext = LlcpMac->MacSend_Context;
73
74       /* Reset the pointer to the Send Callback */
75       LlcpMac->MacSend_Cb = NULL;
76       LlcpMac->MacSend_Context = NULL;
77
78       /* Call Send callback */
79       pfSendCB(pSendContext, status);
80    }
81 }
82
83 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Chk(phFriNfc_LlcpMac_t                   *LlcpMac,
84                                             phFriNfc_LlcpMac_Chk_CB_t            ChkLlcpMac_Cb,
85                                             void                                 *pContext)
86 {
87    int ret;
88    NFCSTATUS status = NFCSTATUS_SUCCESS;
89    uint8_t Llcp_Magic_Number[] = {0x46,0x66,0x6D};
90
91    if(NULL == LlcpMac || NULL == ChkLlcpMac_Cb || NULL == pContext)
92    {
93       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
94    }
95    else
96    {
97       ret = memcmp(Llcp_Magic_Number,LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo,3);
98       if(!ret)
99       {
100          LlcpMac->sConfigParam.buffer = &LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo[3] ;
101          LlcpMac->sConfigParam.length = (LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length - 3);
102          status = NFCSTATUS_SUCCESS;
103       }
104       else
105       {
106          status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_FAILED);
107       }
108    }
109
110    ChkLlcpMac_Cb(pContext,status);
111    return status;
112 }
113
114 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Activate (phFriNfc_LlcpMac_t   *LlcpMac)
115 {
116    NFCSTATUS status  = NFCSTATUS_SUCCESS;
117
118    if(LlcpMac == NULL)
119    {
120       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
121    }
122    else
123    {
124       LlcpMac->LinkState = phFriNfc_LlcpMac_eLinkActivated;
125       LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context,
126                              LlcpMac->LinkState,
127                              &LlcpMac->sConfigParam,
128                              LlcpMac->PeerRemoteDevType);
129    }
130
131    return status;
132 }
133
134 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Deactivate (phFriNfc_LlcpMac_t   *LlcpMac)
135 {
136    NFCSTATUS status  = NFCSTATUS_SUCCESS;
137
138    if(NULL == LlcpMac)
139    {
140       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
141    }
142    else
143    {
144       /* Set the flag of LinkStatus to deactivate */
145       LlcpMac->LinkState = phFriNfc_LlcpMac_eLinkDeactivated;
146    }
147
148    if (LlcpMac->SendPending)
149    {
150       /* Reset Flag */
151       LlcpMac->SendPending = FALSE;
152
153       phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, NFCSTATUS_FAILED);
154    }
155
156    if (LlcpMac->RecvPending)
157    {
158       /* Reset Flag */
159       LlcpMac->RecvPending = FALSE;
160
161       phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, NFCSTATUS_FAILED);
162    }
163
164    LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context,
165                           LlcpMac->LinkState,
166                           NULL,
167                           LlcpMac->PeerRemoteDevType);
168
169    return status;
170 }
171
172 static void phFriNfc_LlcpMac_Nfcip_Send_Cb(void       *pContext,
173                                            NFCSTATUS   Status)
174 {
175    phFriNfc_LlcpMac_t            *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
176
177 #ifdef LLCP_CHANGES
178    if(gpphLibContext->LibNfcState.next_state
179                                == eLibNfcHalStateShutdown)
180    {
181       phLibNfc_Pending_Shutdown();
182       Status = NFCSTATUS_SHUTDOWN;
183    }
184 #endif /* #ifdef LLCP_CHANGES */
185
186    /* Reset Send and Receive Flag */
187    LlcpMac->SendPending = FALSE;
188    LlcpMac->RecvPending = FALSE;
189
190    phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, Status);
191
192 }
193
194 static void phFriNfc_LlcpMac_Nfcip_Receive_Cb(void       *pContext,
195                                               NFCSTATUS   Status)
196 {
197    phFriNfc_LlcpMac_t               *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
198 #ifdef LLCP_CHANGES
199
200    phFriNfc_LlcpMac_Send_CB_t       pfSendCB;
201    void                             *pSendContext;
202
203
204    if(gpphLibContext->LibNfcState.next_state
205                                == eLibNfcHalStateShutdown)
206    {
207       phLibNfc_Pending_Shutdown();
208       Status = NFCSTATUS_SHUTDOWN;
209    }
210
211    if (NFCSTATUS_SHUTDOWN == Status)
212    {
213       /* Save context in local variables */
214       pfSendCB = LlcpMac->MacSend_Cb;
215       pSendContext = LlcpMac->MacSend_Context;
216
217       /* Reset the pointer to the Send Callback */
218       LlcpMac->MacSend_Cb = NULL;
219       LlcpMac->MacSend_Context = NULL;
220
221       /* Reset Send and Receive Flag */
222       LlcpMac->SendPending = FALSE;
223       LlcpMac->RecvPending = FALSE;
224    }
225
226 #endif /* #ifdef LLCP_CHANGES */
227
228    phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, Status);
229
230 #ifdef LLCP_CHANGES
231
232    if (NFCSTATUS_SHUTDOWN == Status)
233    {
234        if ((LlcpMac->SendPending) && (NULL != pfSendCB))
235        {
236            pfSendCB(pSendContext, Status);
237       }
238    }
239    else
240
241 #endif /* #ifdef LLCP_CHANGES */
242    {
243    /* Test if a send is pending */
244    if(LlcpMac->SendPending)
245    {
246       Status = phFriNfc_LlcpMac_Nfcip_Send(LlcpMac,LlcpMac->psSendBuffer,LlcpMac->MacSend_Cb,LlcpMac->MacSend_Context);
247    }
248 }
249 }
250
251 static void phFriNfc_LlcpMac_Nfcip_Transceive_Cb(void       *pContext,
252                                                  NFCSTATUS   Status)
253 {
254    phFriNfc_LlcpMac_t               *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
255
256 #ifdef LLCP_CHANGES
257    if(gpphLibContext->LibNfcState.next_state
258                                == eLibNfcHalStateShutdown)
259    {
260       phLibNfc_Pending_Shutdown();
261       Status = NFCSTATUS_SHUTDOWN;
262    }
263 #endif /* #ifdef LLCP_CHANGES */
264
265    /* Reset Send and Receive Flag */
266    LlcpMac->SendPending = FALSE;
267    LlcpMac->RecvPending = FALSE;
268
269    /* Call the callbacks */
270    phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, Status);
271    phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, Status);
272 }
273
274 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t               *LlcpMac,
275                                              phNfc_sData_t                    *psData,
276                                              phFriNfc_LlcpMac_Send_CB_t       LlcpMacSend_Cb,
277                                              void                             *pContext)
278 {
279    NFCSTATUS status = NFCSTATUS_SUCCESS;
280
281    if(NULL == LlcpMac || NULL == psData || NULL == LlcpMacSend_Cb || NULL == pContext)
282    {
283       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
284    }
285    else if(LlcpMac->MacSend_Cb != NULL && LlcpMac->PeerRemoteDevType == phFriNfc_LlcpMac_ePeerTypeInitiator)
286    {
287       /*Previous callback is pending */
288       status = NFCSTATUS_REJECTED;
289    }
290    else
291    {
292       /* Save the LlcpMacSend_Cb */
293       LlcpMac->MacSend_Cb = LlcpMacSend_Cb;
294       LlcpMac->MacSend_Context = pContext;
295
296       switch(LlcpMac->PeerRemoteDevType)
297       {
298       case phFriNfc_LlcpMac_ePeerTypeInitiator:
299          {
300             if(LlcpMac->RecvPending)
301             {
302                /*set the completion routines for the LLCP Transceive function*/
303                 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb;
304                 LlcpMac->MacCompletionInfo.Context = LlcpMac;
305
306                 /* set the command type*/
307                 LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw;
308
309                 /* set the Additional Info*/
310                 LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
311                 LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0;
312                 LlcpMac->SendPending = TRUE;
313
314                 status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice,
315                                                     &LlcpMac->MacCompletionInfo,
316                                                     LlcpMac->psRemoteDevInfo,
317                                                     LlcpMac->Cmd,
318                                                     &LlcpMac->psDepAdditionalInfo,
319                                                     psData->buffer,
320                                                     (uint16_t)psData->length,
321                                                     LlcpMac->psReceiveBuffer->buffer,
322                                                     (uint16_t*)&LlcpMac->psReceiveBuffer->length);
323             }
324             else
325             {
326                LlcpMac->SendPending = TRUE;
327                LlcpMac->psSendBuffer = psData;
328                return status = NFCSTATUS_PENDING;
329             }
330          }break;
331       case phFriNfc_LlcpMac_ePeerTypeTarget:
332          {
333             if(!LlcpMac->RecvPending)
334             {
335                LlcpMac->SendPending = TRUE;
336                LlcpMac->psSendBuffer = psData;
337                return status = NFCSTATUS_PENDING;
338             }
339             else
340             {
341                /*set the completion routines for the LLCP Send function*/
342                LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Send_Cb;
343                LlcpMac->MacCompletionInfo.Context = LlcpMac;
344                status = phFriNfc_OvrHal_Send(LlcpMac->LowerDevice,
345                                              &LlcpMac->MacCompletionInfo,
346                                              LlcpMac->psRemoteDevInfo,
347                                              psData->buffer,
348                                              (uint16_t)psData->length);
349             }
350          }break;
351       default:
352          {
353             status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_DEVICE);
354          }break;
355       }
356    }
357    return status;
358 }
359
360 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Receive(phFriNfc_LlcpMac_t               *LlcpMac,
361                                                 phNfc_sData_t                    *psData,
362                                                 phFriNfc_LlcpMac_Reveive_CB_t    LlcpMacReceive_Cb,
363                                                 void                             *pContext)
364 {
365    NFCSTATUS status = NFCSTATUS_SUCCESS;
366    if(NULL == LlcpMac || NULL==psData || NULL == LlcpMacReceive_Cb || NULL == pContext)
367    {
368       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
369    }
370    else if(LlcpMac->MacReceive_Cb != NULL)
371    {
372       /*Previous callback is pending */
373       status = NFCSTATUS_REJECTED;
374    }
375    else
376    {
377       /* Save the LlcpMacReceive_Cb */
378       LlcpMac->MacReceive_Cb = LlcpMacReceive_Cb;
379       LlcpMac->MacReceive_Context = pContext;
380
381       /* Save the pointer to the receive buffer */
382       LlcpMac->psReceiveBuffer= psData;
383
384       switch(LlcpMac->PeerRemoteDevType)
385       {
386       case phFriNfc_LlcpMac_ePeerTypeInitiator:
387          {
388             if(LlcpMac->SendPending)
389             {
390                /*set the completion routines for the LLCP Transceive function*/
391                LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb;
392                LlcpMac->MacCompletionInfo.Context = LlcpMac;
393                /* set the command type*/
394                LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw;
395                /* set the Additional Info*/
396                LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
397                LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0;
398                LlcpMac->RecvPending = TRUE;
399
400                status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice,
401                                                    &LlcpMac->MacCompletionInfo,
402                                                    LlcpMac->psRemoteDevInfo,
403                                                    LlcpMac->Cmd,
404                                                    &LlcpMac->psDepAdditionalInfo,
405                                                    LlcpMac->psSendBuffer->buffer,
406                                                    (uint16_t)LlcpMac->psSendBuffer->length,
407                                                    psData->buffer,
408                                                    (uint16_t*)&psData->length);
409             }
410             else
411             {
412                LlcpMac->RecvPending = TRUE;
413                return status = NFCSTATUS_PENDING;
414             }
415          }break;
416       case phFriNfc_LlcpMac_ePeerTypeTarget:
417          {
418              /*set the completion routines for the LLCP Receive function*/
419             LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Receive_Cb;
420             /* save the context of LlcpMacNfcip */
421             LlcpMac->MacCompletionInfo.Context = LlcpMac;
422             LlcpMac->RecvPending = TRUE;
423
424             status = phFriNfc_OvrHal_Receive(LlcpMac->LowerDevice,
425                                              &LlcpMac->MacCompletionInfo,
426                                              LlcpMac->psRemoteDevInfo,
427                                              LlcpMac->psReceiveBuffer->buffer,
428                                              (uint16_t*)&LlcpMac->psReceiveBuffer->length);
429          }break;
430       default:
431          {
432             status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_DEVICE);
433          }break;
434       }
435    }
436    return status;
437 }
438
439
440 NFCSTATUS phFriNfc_LlcpMac_Nfcip_Register (phFriNfc_LlcpMac_t *LlcpMac)
441 {
442    NFCSTATUS status = NFCSTATUS_SUCCESS;
443
444    if(NULL != LlcpMac)
445    {
446       LlcpMac->LlcpMacInterface.chk = phFriNfc_LlcpMac_Nfcip_Chk;
447       LlcpMac->LlcpMacInterface.activate   = phFriNfc_LlcpMac_Nfcip_Activate;
448       LlcpMac->LlcpMacInterface.deactivate = phFriNfc_LlcpMac_Nfcip_Deactivate;
449       LlcpMac->LlcpMacInterface.send = phFriNfc_LlcpMac_Nfcip_Send;
450       LlcpMac->LlcpMacInterface.receive = phFriNfc_LlcpMac_Nfcip_Receive;
451
452       return NFCSTATUS_SUCCESS;
453    }
454    else
455    {
456       return status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_FAILED);
457    }
458 }