[Win32] Change libcoap bitfield structure to use ushort
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / nfc_adapter / canfcadapter.c
1 /* *****************************************************************
2  * Copyright 2015 Samsung Electronics All Rights Reserved.
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 "canfcadapter.h"
18
19 #include "canfcinterface.h"
20 #include "caqueueingthread.h"
21 #include "caadapterutils.h"
22 #include "camutex.h"
23 #include "uarraylist.h"
24 #include "caremotehandler.h"
25 #include "logger.h"
26 #include "oic_malloc.h"
27 #include "oic_string.h"
28
29 /**
30  * Logging tag for module name
31  */
32 #define TAG "NFC_ADAP"
33
34 /**
35  * Holds inter thread nfc data information.
36  */
37
38 typedef struct
39 {
40     CAEndpoint_t *remoteEndpoint;
41     void *data;
42     uint32_t dataLen;
43 } CANFCData;
44
45 /**
46  * Reference to threadpool.
47  */
48 static ca_thread_pool_t g_nfcThreadPool = NULL;
49
50 /**
51  * Queue handle for Send Data
52  */
53 static CAQueueingThread_t *g_sendQueueHandle = NULL;
54
55 /**
56  * Network Packet Received Callback to CA
57  */
58 static CANetworkPacketReceivedCallback g_packetReceivedCallback = NULL;
59
60 /**
61  *  Network Changed Callback to CA
62  */
63 static CANetworkChangeCallback g_connectionStateCallback = NULL;
64
65 /**
66  * error Callback to CA adapter
67  */
68 static CAErrorHandleCallback g_errorCallback = NULL;
69
70 static void CANFCPacketReceivedCB(const CASecureEndpoint_t *endpoint, const void *data,
71                                   uint32_t dataLength);
72 #ifndef SINGLE_THREAD
73
74 static CAResult_t CANFCInitializeQueueHandles();
75
76 static void CANFCDeinitializeQueueHandles();
77
78 static void CANFCSendDataThread(void *threadData);
79
80 CANFCData *CACreateNFCData(const CAEndpoint_t *remoteEndpoint, const void *data,
81                            uint32_t dataLength);
82
83 void CAFreeNFCData(CANFCData *ipData);
84
85 static void CANFCDataDestroyer(void *data, uint32_t size);
86
87 CAResult_t CANFCInitializeQueueHandles()
88 {
89     OIC_LOG(DEBUG, TAG, "IN");
90
91     // Check if the message queue is already initialized
92     if (g_sendQueueHandle)
93     {
94         OIC_LOG(DEBUG, TAG, "send queue handle is already initialized!");
95         return CA_STATUS_OK;
96     }
97
98     // Create send message queue
99     g_sendQueueHandle = OICCalloc(1, sizeof(*g_sendQueueHandle));
100     if (!g_sendQueueHandle)
101     {
102         OIC_LOG(ERROR, TAG, "Memory allocation failed!");
103         return CA_MEMORY_ALLOC_FAILED;
104     }
105
106     if (CA_STATUS_OK
107         != CAQueueingThreadInitialize(g_sendQueueHandle, (const ca_thread_pool_t) g_nfcThreadPool,
108                                       CANFCSendDataThread, CANFCDataDestroyer))
109     {
110         OIC_LOG(ERROR, TAG, "Failed to Initialize send queue thread");
111         OICFree(g_sendQueueHandle);
112         g_sendQueueHandle = NULL;
113         return CA_STATUS_FAILED;
114     }
115
116     OIC_LOG(DEBUG, TAG, "OUT");
117     return CA_STATUS_OK;
118 }
119
120 void CANFCDeinitializeQueueHandles()
121 {
122     OIC_LOG(DEBUG, TAG, "IN");
123
124     CAQueueingThreadDestroy(g_sendQueueHandle);
125     OICFree(g_sendQueueHandle);
126     g_sendQueueHandle = NULL;
127
128     OIC_LOG(DEBUG, TAG, "OUT");
129 }
130
131 #endif // SINGLE_THREAD
132 void CANFCConnectionStateCB(const char *nfcAddress, CANetworkStatus_t status)
133 {
134     OIC_LOG(DEBUG, TAG, "Currently Not Supported");
135
136     (void)nfcAddress;
137     (void)status;
138 }
139
140 void CANFCPacketReceivedCB(const CASecureEndpoint_t *sep, const void *data, uint32_t dataLength)
141 {
142     OIC_LOG(DEBUG, TAG, "IN");
143
144     VERIFY_NON_NULL_VOID(sep, TAG, "endpoint is NULL");
145     VERIFY_NON_NULL_VOID(data, TAG, "data is NULL");
146
147     if (0 == dataLength)
148     {
149         OIC_LOG(ERROR, TAG, "Invalid call, data length is 0");
150         return;
151     }
152
153     OIC_LOG_V(DEBUG, TAG, "Address: %s, port:%d", sep->endpoint.addr, sep->endpoint.port);
154
155     if (g_packetReceivedCallback)
156     {
157         g_packetReceivedCallback(sep, data, dataLength);
158     }
159
160     OIC_LOG(DEBUG, TAG, "OUT");
161 }
162
163 void CANFCErrorHandler(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength,
164                        CAResult_t result)
165 {
166     OIC_LOG(DEBUG, TAG, "IN");
167
168     VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint is NULL");
169
170     VERIFY_NON_NULL_VOID(data, TAG, "data is NULL");
171     if (g_errorCallback)
172     {
173         g_errorCallback(endpoint, data, dataLength, result);
174     }
175     OIC_LOG(DEBUG, TAG, "OUT");
176 }
177
178 CAResult_t CAInitializeNFC(CARegisterConnectivityCallback registerCallback,
179                            CANetworkPacketReceivedCallback packetReceivedCallback,
180                            CANetworkChangeCallback connectionStateCallback,
181                            CAErrorHandleCallback errorCallback, ca_thread_pool_t handle)
182 {
183     OIC_LOG(DEBUG, TAG, "IN");
184     VERIFY_NON_NULL(registerCallback, TAG, "registerCallback");
185     VERIFY_NON_NULL(packetReceivedCallback, TAG, "packetReceivedCallback");
186     VERIFY_NON_NULL(connectionStateCallback, TAG, "connectionStateCallback");
187     VERIFY_NON_NULL(handle, TAG, "thread pool handle");
188
189     g_connectionStateCallback = connectionStateCallback;
190     g_packetReceivedCallback = packetReceivedCallback;
191     g_errorCallback = errorCallback;
192
193     g_nfcThreadPool = handle;
194
195     CAResult_t result = CAInitializeNfcServer();
196     if (CA_STATUS_OK != result)
197     {
198         OIC_LOG(ERROR, TAG, "CAInitializeNfcServer failed");
199         return result;
200     }
201
202     CANFCSetPacketReceiveCallback(CANFCPacketReceivedCB);
203     static const CAConnectivityHandler_t nfcHandler =
204         {
205             .startAdapter = CAStartNFC,
206             .stopAdapter = CAStopNFC,
207             .startListenServer = CAStartNFCListeningServer,
208             .stopListenServer = CAStopNFCListeningServer,
209             .startDiscoveryServer = CAStartNFCDiscoveryServer,
210             .sendData = CASendNFCUnicastData,
211             .sendDataToAll = CASendNFCMulticastData,
212             .GetnetInfo = CAGetNFCInterfaceInformation,
213             .readData = CAReadNFCData,
214             .terminate = CATerminateNFC,
215             .cType = CA_ADAPTER_NFC
216         };
217     registerCallback(nfcHandler);
218
219     OIC_LOG(INFO, TAG, "OUT Intialize NFC is Success");
220     return CA_STATUS_OK;
221 }
222
223 CAResult_t CAStartNFC()
224 {
225
226     OIC_LOG(DEBUG, TAG, "IN");
227     CAResult_t res = CANFCInitializeQueueHandles();
228
229     if (CA_STATUS_OK != res)
230     {
231         OIC_LOG(ERROR, TAG, "Failed to Initialize Queue Handle");
232         return res;
233     }
234
235     res = CAQueueingThreadStart(g_sendQueueHandle);
236     // Start send queue thread
237     if (CA_STATUS_OK != res)
238     {
239         OIC_LOG(ERROR, TAG, "Failed to Start Send Data Thread");
240         return res;
241     }
242
243     OIC_LOG(DEBUG, TAG, "OUT");
244     return CA_STATUS_OK;
245 }
246
247 CAResult_t CAStartNFCListeningServer()
248 {
249     OIC_LOG(DEBUG, TAG, "IN");
250
251     CAResult_t ret = CANFCStartServer();
252     if (CA_STATUS_OK != ret)
253     {
254         OIC_LOG_V(ERROR, TAG, "Failed to start server![%d]", ret);
255         return ret;
256     }
257
258     OIC_LOG(DEBUG, TAG, "OUT");
259     return CA_STATUS_OK;
260 }
261
262 CAResult_t CAStopNFCListeningServer()
263 {
264     CANFCStopServer();
265     return CA_STATUS_OK;
266 }
267
268 CAResult_t CAStartNFCDiscoveryServer()
269 {
270     return CAStartNFCListeningServer();
271 }
272
273 static int32_t CAQueueNFCData(const CAEndpoint_t *endpoint, const void *data,
274                               uint32_t dataLength)
275 {
276     OIC_LOG(DEBUG, TAG, "IN");
277
278     VERIFY_NON_NULL_RET(endpoint, TAG, "remoteEndpoint", -1);
279     VERIFY_NON_NULL_RET(data, TAG, "data", -1);
280
281     if (0 == dataLength)
282     {
283         OIC_LOG(ERROR, TAG, "Invalid Data Length");
284         return -1;
285     }
286
287     VERIFY_NON_NULL_RET(g_sendQueueHandle, TAG, "sendQueueHandle", -1);
288     // Create NFCData to add to queue
289     CANFCData *nfcData = CACreateNFCData(endpoint, data, dataLength);
290     if (!nfcData)
291     {
292         OIC_LOG(ERROR, TAG, "Failed to create ipData!");
293         return -1;
294     }
295     // Add message to send queue
296     CAQueueingThreadAddData(g_sendQueueHandle, nfcData, sizeof(CANFCData));
297
298     OIC_LOG(DEBUG, TAG, "OUT");
299     return dataLength;
300
301 }
302
303 int32_t CASendNFCUnicastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength)
304 {
305     return CAQueueNFCData(endpoint, data, dataLength);
306 }
307
308 int32_t CASendNFCMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength)
309 {
310     return CAQueueNFCData(endpoint, data, dataLength);
311 }
312
313 CAResult_t CAReadNFCData()
314 {
315 #if 0
316     OIC_LOG(DEBUG, TAG, "IN");
317     CANFCPullData();
318     OIC_LOG(DEBUG, TAG, "OUT");
319 #endif
320     return CA_STATUS_OK;
321 }
322
323 CAResult_t CAStopNFC()
324 {
325     OIC_LOG(DEBUG, TAG, "IN");
326
327     if (g_sendQueueHandle && g_sendQueueHandle->threadMutex)
328     {
329         CAQueueingThreadStop(g_sendQueueHandle);
330     }
331
332     CANFCDeinitializeQueueHandles();
333
334     CANFCStopServer();
335
336     OIC_LOG(DEBUG, TAG, "OUT");
337
338     return CA_STATUS_OK;
339 }
340
341 void CATerminateNFC()
342 {
343
344     OIC_LOG(DEBUG, TAG, "IN");
345     CANFCSetPacketReceiveCallback(NULL);
346     CANFCDeinitializeQueueHandles();
347
348     OIC_LOG(DEBUG, TAG, "OUT");
349 }
350
351 void CANFCSendDataThread(void *threadData)
352 {
353     OIC_LOG(DEBUG, TAG, "IN");
354     CANFCData *nfcData = (CANFCData *) threadData;
355     if (!nfcData)
356     {
357         OIC_LOG(ERROR, TAG, "Invalid ip data!");
358         return;
359     }
360
361     CANFCSendData(nfcData->remoteEndpoint, nfcData->data, nfcData->dataLen);
362     OIC_LOG(DEBUG, TAG, "OUT");
363 }
364
365 CANFCData *CACreateNFCData(const CAEndpoint_t *remoteEndpoint, const void *data,
366                            uint32_t dataLength)
367 {
368     VERIFY_NON_NULL_RET(data, TAG, "NFCData is NULL", NULL);
369
370     CANFCData *nfcData = (CANFCData *) OICCalloc(1,sizeof(*nfcData));
371     if (!nfcData)
372     {
373         OIC_LOG(ERROR, TAG, "Memory allocation failed!");
374         return NULL;
375     }
376
377     nfcData->remoteEndpoint = CACloneEndpoint(remoteEndpoint);
378     nfcData->data = (void *) OICMalloc(dataLength);
379     if (!nfcData->data)
380     {
381         OIC_LOG(ERROR, TAG, "Memory allocation failed!");
382         CAFreeNFCData(nfcData);
383         return NULL;
384     }
385
386     memcpy(nfcData->data, data, dataLength);
387     nfcData->dataLen = dataLength;
388
389     return nfcData;
390
391 }
392
393 void CAFreeNFCData(CANFCData *nfcData)
394 {
395     if (nfcData)
396     {
397         CAFreeEndpoint(nfcData->remoteEndpoint);
398         OICFree(nfcData->data);
399         OICFree(nfcData);
400     }
401 }
402
403 void CANFCDataDestroyer(void *data, uint32_t size)
404 {
405     CANFCData *nfcData = (CANFCData *) data;
406
407     CAFreeNFCData(nfcData);
408     (void)size;
409 }
410
411 CAResult_t CAGetNFCInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
412 {
413     OIC_LOG(DEBUG, TAG, "CAGetNFCInterfaceInformation not supported");
414     if (!info || !size)
415     {
416         OIC_LOG(ERROR, TAG, "CAGetNFCInterfaceInformation : Invalid Input");
417         return CA_STATUS_FAILED;
418     }
419
420     return CA_STATUS_OK;
421 }