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 */ 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 */ 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 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 */ 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 */ 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 */ 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