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 * \file phFriNfc_LlcpTransport_Connectionless.c
19 * \brief
20 *
21 * Project: NFC-FRI
22 *
23 */
24 /*include files*/
25 #include <phOsalNfc.h>
26 #include <phLibNfcStatus.h>
27 #include <phLibNfc.h>
28 #include <phNfcLlcpTypes.h>
29 #include <phFriNfc_LlcpTransport.h>
30 #include <phFriNfc_Llcp.h>
31
32 /* TODO: comment function Handle_Connectionless_IncommingFrame */
Handle_Connectionless_IncommingFrame(phFriNfc_LlcpTransport_t * pLlcpTransport,phNfc_sData_t * psData,uint8_t dsap,uint8_t ssap)33 void Handle_Connectionless_IncommingFrame(phFriNfc_LlcpTransport_t *pLlcpTransport,
34 phNfc_sData_t *psData,
35 uint8_t dsap,
36 uint8_t ssap)
37 {
38 uint8_t i=0;
39
40 for(i=0;i<PHFRINFC_LLCP_NB_SOCKET_MAX;i++)
41 {
42 /* Test if a socket is registered to get this packet */
43 if(pLlcpTransport->pSocketTable[i].socket_sSap == dsap && pLlcpTransport->pSocketTable[i].bSocketRecvPending == TRUE)
44 {
45 /* Reset the RecvPending variable */
46 pLlcpTransport->pSocketTable[i].bSocketRecvPending = FALSE;
47
48 /* Copy the received buffer into the receive buffer */
49 memcpy(pLlcpTransport->pSocketTable[i].sSocketRecvBuffer->buffer,psData->buffer,psData->length);
50
51 /* Update the received length */
52 *pLlcpTransport->pSocketTable[i].receivedLength = psData->length;
53
54 /* call the Recv callback */
55 pLlcpTransport->pSocketTable[i].pfSocketRecvFrom_Cb(pLlcpTransport->pSocketTable[i].pRecvContext,ssap,NFCSTATUS_SUCCESS);
56 break;
57 }
58 }
59 }
60
61 /* TODO: comment function phFriNfc_LlcpTransport_Connectionless_SendTo_CB */
phFriNfc_LlcpTransport_Connectionless_SendTo_CB(void * pContext,NFCSTATUS status)62 static void phFriNfc_LlcpTransport_Connectionless_SendTo_CB(void* pContext,
63 NFCSTATUS status)
64 {
65 phFriNfc_LlcpTransport_Socket_t *pLlcpSocket = (phFriNfc_LlcpTransport_Socket_t*)pContext;
66
67 /* Reset the SendPending variable */
68 pLlcpSocket->bSocketSendPending = FALSE;
69
70 /* Call the send callback */
71 pLlcpSocket->pfSocketSend_Cb(pLlcpSocket->pSendContext,status);
72
73 }
74
phFriNfc_LlcpTransport_Connectionless_Abort(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket)75 static void phFriNfc_LlcpTransport_Connectionless_Abort(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket)
76 {
77 if (pLlcpSocket->pfSocketSend_Cb != NULL)
78 {
79 pLlcpSocket->pfSocketSend_Cb(pLlcpSocket->pSendContext, NFCSTATUS_ABORTED);
80 pLlcpSocket->pSendContext = NULL;
81 pLlcpSocket->pfSocketSend_Cb = NULL;
82 }
83 if (pLlcpSocket->pfSocketRecvFrom_Cb != NULL)
84 {
85 pLlcpSocket->pfSocketRecvFrom_Cb(pLlcpSocket->pRecvContext, 0, NFCSTATUS_ABORTED);
86 pLlcpSocket->pRecvContext = NULL;
87 pLlcpSocket->pfSocketRecvFrom_Cb = NULL;
88 pLlcpSocket->pfSocketRecv_Cb = NULL;
89 }
90 pLlcpSocket->pAcceptContext = NULL;
91 pLlcpSocket->pfSocketAccept_Cb = NULL;
92 pLlcpSocket->pListenContext = NULL;
93 pLlcpSocket->pfSocketListen_Cb = NULL;
94 pLlcpSocket->pConnectContext = NULL;
95 pLlcpSocket->pfSocketConnect_Cb = NULL;
96 pLlcpSocket->pDisonnectContext = NULL;
97 pLlcpSocket->pfSocketDisconnect_Cb = NULL;
98 }
99
100 /**
101 * \ingroup grp_fri_nfc
102 * \brief <b>Close a socket on a LLCP-connectionless device</b>.
103 *
104 * This function closes a LLCP socket previously created using phFriNfc_LlcpTransport_Socket.
105 *
106 * \param[in] pLlcpSocket A pointer to a phFriNfc_LlcpTransport_Socket_t.
107
108 * \retval NFCSTATUS_SUCCESS Operation successful.
109 * \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
110 * could not be properly interpreted.
111 * \retval NFCSTATUS_FAILED Operation failed.
112 */
phFriNfc_LlcpTransport_Connectionless_Close(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket)113 NFCSTATUS phFriNfc_LlcpTransport_Connectionless_Close(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket)
114 {
115 /* Reset the pointer to the socket closed */
116 pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDefault;
117 pLlcpSocket->eSocket_Type = phFriNfc_LlcpTransport_eDefaultType;
118 pLlcpSocket->pContext = NULL;
119 pLlcpSocket->pSocketErrCb = NULL;
120 pLlcpSocket->socket_sSap = PHFRINFC_LLCP_SAP_DEFAULT;
121 pLlcpSocket->socket_dSap = PHFRINFC_LLCP_SAP_DEFAULT;
122 pLlcpSocket->bSocketRecvPending = FALSE;
123 pLlcpSocket->bSocketSendPending = FALSE;
124 pLlcpSocket->bSocketListenPending = FALSE;
125 pLlcpSocket->bSocketDiscPending = FALSE;
126 pLlcpSocket->RemoteBusyConditionInfo = FALSE;
127 pLlcpSocket->ReceiverBusyCondition = FALSE;
128 pLlcpSocket->socket_VS = 0;
129 pLlcpSocket->socket_VSA = 0;
130 pLlcpSocket->socket_VR = 0;
131 pLlcpSocket->socket_VRA = 0;
132
133 phFriNfc_LlcpTransport_Connectionless_Abort(pLlcpSocket);
134
135 memset(&pLlcpSocket->sSocketOption, 0x00, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t));
136
137 if (pLlcpSocket->sServiceName.buffer != NULL) {
138 phOsalNfc_FreeMemory(pLlcpSocket->sServiceName.buffer);
139 }
140 pLlcpSocket->sServiceName.buffer = NULL;
141 pLlcpSocket->sServiceName.length = 0;
142
143 return NFCSTATUS_SUCCESS;
144 }
145
146 /**
147 * \ingroup grp_fri_nfc
148 * \brief <b>Send data on a socket to a given destination SAP</b>.
149 *
150 * This function is used to write data on a socket to a given destination SAP.
151 * This function can only be called on a connectionless socket.
152 *
153 *
154 * \param[in] pLlcpSocket A pointer to a LlcpSocket created.
155 * \param[in] nSap The destination SAP.
156 * \param[in] psBuffer The buffer containing the data to send.
157 * \param[in] pSend_RspCb The callback to be called when the
158 * operation is completed.
159 * \param[in] pContext Upper layer context to be returned in
160 * the callback.
161 *
162 * \retval NFCSTATUS_SUCCESS Operation successful.
163 * \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
164 * could not be properly interpreted.
165 * \retval NFCSTATUS_PENDING Reception operation is in progress,
166 * pSend_RspCb will be called upon completion.
167 * \retval NFCSTATUS_INVALID_STATE The socket is not in a valid state, or not of
168 * a valid type to perform the requsted operation.
169 * \retval NFCSTATUS_NOT_INITIALISED Indicates stack is not yet initialized.
170 * \retval NFCSTATUS_SHUTDOWN Shutdown in progress.
171 * \retval NFCSTATUS_FAILED Operation failed.
172 */
phFriNfc_LlcpTransport_Connectionless_SendTo(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket,uint8_t nSap,phNfc_sData_t * psBuffer,pphFriNfc_LlcpTransportSocketSendCb_t pSend_RspCb,void * pContext)173 NFCSTATUS phFriNfc_LlcpTransport_Connectionless_SendTo(phFriNfc_LlcpTransport_Socket_t *pLlcpSocket,
174 uint8_t nSap,
175 phNfc_sData_t* psBuffer,
176 pphFriNfc_LlcpTransportSocketSendCb_t pSend_RspCb,
177 void* pContext)
178 {
179 NFCSTATUS status = NFCSTATUS_SUCCESS;
180
181 /* Store send callback and context*/
182 pLlcpSocket->pfSocketSend_Cb = pSend_RspCb;
183 pLlcpSocket->pSendContext = pContext;
184
185 /* Test if a send is pending with this socket */
186 if(pLlcpSocket->bSocketSendPending == TRUE)
187 {
188 status = NFCSTATUS_FAILED;
189 pLlcpSocket->pfSocketSend_Cb(pLlcpSocket->pSendContext,status);
190 }
191 else
192 {
193 /* Fill the psLlcpHeader stuture with the DSAP,PTYPE and the SSAP */
194 pLlcpSocket->sLlcpHeader.dsap = nSap;
195 pLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_UI;
196 pLlcpSocket->sLlcpHeader.ssap = pLlcpSocket->socket_sSap;
197
198 pLlcpSocket->bSocketSendPending = TRUE;
199
200 /* Send to data to the approiate socket */
201 status = phFriNfc_Llcp_Send(pLlcpSocket->psTransport->pLlcp,
202 &pLlcpSocket->sLlcpHeader,
203 NULL,
204 psBuffer,
205 phFriNfc_LlcpTransport_Connectionless_SendTo_CB,
206 pLlcpSocket);
207 }
208
209 return status;
210 }
211
212
213 /**
214 * \ingroup grp_lib_nfc
215 * \brief <b>Read data on a socket and get the source SAP</b>.
216 *
217 * This function is the same as phLibNfc_Llcp_Recv, except that the callback includes
218 * the source SAP. This functions can only be called on a connectionless socket.
219 *
220 *
221 * \param[in] pLlcpSocket A pointer to a LlcpSocket created.
222 * \param[in] psBuffer The buffer receiving the data.
223 * \param[in] pRecv_RspCb The callback to be called when the
224 * operation is completed.
225 * \param[in] pContext Upper layer context to be returned in
226 * the callback.
227 *
228 * \retval NFCSTATUS_SUCCESS Operation successful.
229 * \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
230 * could not be properly interpreted.
231 * \retval NFCSTATUS_PENDING Reception operation is in progress,
232 * pRecv_RspCb will be called upon completion.
233 * \retval NFCSTATUS_INVALID_STATE The socket is not in a valid state, or not of
234 * a valid type to perform the requsted operation.
235 * \retval NFCSTATUS_NOT_INITIALISED Indicates stack is not yet initialized.
236 * \retval NFCSTATUS_SHUTDOWN Shutdown in progress.
237 * \retval NFCSTATUS_FAILED Operation failed.
238 */
phLibNfc_LlcpTransport_Connectionless_RecvFrom(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket,phNfc_sData_t * psBuffer,pphFriNfc_LlcpTransportSocketRecvFromCb_t pRecv_Cb,void * pContext)239 NFCSTATUS phLibNfc_LlcpTransport_Connectionless_RecvFrom(phFriNfc_LlcpTransport_Socket_t *pLlcpSocket,
240 phNfc_sData_t* psBuffer,
241 pphFriNfc_LlcpTransportSocketRecvFromCb_t pRecv_Cb,
242 void *pContext)
243 {
244 NFCSTATUS status = NFCSTATUS_PENDING;
245
246 if(pLlcpSocket->bSocketRecvPending)
247 {
248 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_REJECTED);
249 }
250 else
251 {
252 /* Store the callback and context*/
253 pLlcpSocket->pfSocketRecvFrom_Cb = pRecv_Cb;
254 pLlcpSocket->pRecvContext = pContext;
255
256 /* Store the pointer to the receive buffer */
257 pLlcpSocket->sSocketRecvBuffer = psBuffer;
258 pLlcpSocket->receivedLength = &psBuffer->length;
259
260 /* Set RecvPending to TRUE */
261 pLlcpSocket->bSocketRecvPending = TRUE;
262 }
263 return status;
264 }
265