Merge "Merge branch 'master' into easysetup" into easysetup
[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
137 void CANFCPacketReceivedCB(const CASecureEndpoint_t *sep, const void *data, uint32_t dataLength)
138 {
139     OIC_LOG(DEBUG, TAG, "IN");
140
141     VERIFY_NON_NULL_VOID(sep, TAG, "endpoint is NULL");
142     VERIFY_NON_NULL_VOID(data, TAG, "data is NULL");
143
144     if (0 == dataLength)
145     {
146         OIC_LOG(ERROR, TAG, "Invalid call, data length is 0");
147         return;
148     }
149
150     OIC_LOG_V(DEBUG, TAG, "Address: %s, port:%d", sep->endpoint.addr, sep->endpoint.port);
151
152     if (g_packetReceivedCallback)
153     {
154         g_packetReceivedCallback(sep, data, dataLength);
155     }
156
157     OIC_LOG(DEBUG, TAG, "OUT");
158 }
159
160 void CANFCErrorHandler(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength,
161                        CAResult_t result)
162 {
163     OIC_LOG(DEBUG, TAG, "IN");
164
165     VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint is NULL");
166
167     VERIFY_NON_NULL_VOID(data, TAG, "data is NULL");
168     if (g_errorCallback)
169     {
170         g_errorCallback(endpoint, data, dataLength, result);
171     }
172     OIC_LOG(DEBUG, TAG, "OUT");
173 }
174
175 CAResult_t CAInitializeNFC(CARegisterConnectivityCallback registerCallback,
176                            CANetworkPacketReceivedCallback packetReceivedCallback,
177                            CANetworkChangeCallback connectionStateCallback,
178                            CAErrorHandleCallback errorCallback, ca_thread_pool_t handle)
179 {
180     OIC_LOG(DEBUG, TAG, "IN");
181     VERIFY_NON_NULL(registerCallback, TAG, "registerCallback");
182     VERIFY_NON_NULL(packetReceivedCallback, TAG, "packetReceivedCallback");
183     VERIFY_NON_NULL(connectionStateCallback, TAG, "connectionStateCallback");
184     VERIFY_NON_NULL(handle, TAG, "thread pool handle");
185
186     g_connectionStateCallback = connectionStateCallback;
187     g_packetReceivedCallback = packetReceivedCallback;
188     g_errorCallback = errorCallback;
189
190     g_nfcThreadPool = handle;
191
192     CAResult_t result = CAInitializeNfcServer();
193     if (CA_STATUS_OK != result)
194     {
195         OIC_LOG(ERROR, TAG, "CAInitializeNfcServer failed");
196         return result;
197     }
198
199     CANFCSetPacketReceiveCallback(CANFCPacketReceivedCB);
200     static const CAConnectivityHandler_t nfcHandler =
201         {
202             .startAdapter = CAStartNFC,
203             .stopAdapter = CAStopNFC,
204             .startListenServer = CAStartNFCListeningServer,
205             .stopListenServer = CAStopNFCListeningServer,
206             .startDiscoveryServer = CAStartNFCDiscoveryServer,
207             .sendData = CASendNFCUnicastData,
208             .sendDataToAll = CASendNFCMulticastData,
209             .GetnetInfo = CAGetNFCInterfaceInformation,
210             .readData = CAReadNFCData,
211             .terminate = CATerminateNFC,
212             .cType = CA_ADAPTER_NFC
213         };
214     registerCallback(nfcHandler);
215
216     OIC_LOG(INFO, TAG, "OUT Intialize NFC is Success");
217     return CA_STATUS_OK;
218 }
219
220 CAResult_t CAStartNFC()
221 {
222
223     OIC_LOG(DEBUG, TAG, "IN");
224     CAResult_t res = CANFCInitializeQueueHandles();
225
226     if (CA_STATUS_OK != res)
227     {
228         OIC_LOG(ERROR, TAG, "Failed to Initialize Queue Handle");
229         return res;
230     }
231
232     res = CAQueueingThreadStart(g_sendQueueHandle);
233     // Start send queue thread
234     if (CA_STATUS_OK != res)
235     {
236         OIC_LOG(ERROR, TAG, "Failed to Start Send Data Thread");
237         return res;
238     }
239
240     OIC_LOG(DEBUG, TAG, "OUT");
241     return CA_STATUS_OK;
242 }
243
244 CAResult_t CAStartNFCListeningServer()
245 {
246     OIC_LOG(DEBUG, TAG, "IN");
247
248     CAResult_t ret = CANFCStartServer();
249     if (CA_STATUS_OK != ret)
250     {
251         OIC_LOG_V(ERROR, TAG, "Failed to start server![%d]", ret);
252         return ret;
253     }
254
255     OIC_LOG(DEBUG, TAG, "OUT");
256     return CA_STATUS_OK;
257 }
258
259 CAResult_t CAStopNFCListeningServer()
260 {
261     CANFCStopServer();
262     return CA_STATUS_OK;
263 }
264
265 CAResult_t CAStartNFCDiscoveryServer()
266 {
267     return CAStartNFCListeningServer();
268 }
269
270 static int32_t CAQueueNFCData(const CAEndpoint_t *endpoint, const void *data,
271                               uint32_t dataLength)
272 {
273     OIC_LOG(DEBUG, TAG, "IN");
274
275     VERIFY_NON_NULL_RET(endpoint, TAG, "remoteEndpoint", -1);
276     VERIFY_NON_NULL_RET(data, TAG, "data", -1);
277
278     if (0 == dataLength)
279     {
280         OIC_LOG(ERROR, TAG, "Invalid Data Length");
281         return -1;
282     }
283
284     VERIFY_NON_NULL_RET(g_sendQueueHandle, TAG, "sendQueueHandle", -1);
285     // Create NFCData to add to queue
286     CANFCData *nfcData = CACreateNFCData(endpoint, data, dataLength);
287     if (!nfcData)
288     {
289         OIC_LOG(ERROR, TAG, "Failed to create ipData!");
290         return -1;
291     }
292     // Add message to send queue
293     CAQueueingThreadAddData(g_sendQueueHandle, nfcData, sizeof(CANFCData));
294
295     OIC_LOG(DEBUG, TAG, "OUT");
296     return dataLength;
297
298 }
299
300 int32_t CASendNFCUnicastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength)
301 {
302     return CAQueueNFCData(endpoint, data, dataLength);
303 }
304
305 int32_t CASendNFCMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength)
306 {
307     return CAQueueNFCData(endpoint, data, dataLength);
308 }
309
310 CAResult_t CAReadNFCData()
311 {
312 #if 0
313     OIC_LOG(DEBUG, TAG, "IN");
314     CANFCPullData();
315     OIC_LOG(DEBUG, TAG, "OUT");
316 #endif
317     return CA_STATUS_OK;
318 }
319
320 CAResult_t CAStopNFC()
321 {
322     OIC_LOG(DEBUG, TAG, "IN");
323
324     if (g_sendQueueHandle && g_sendQueueHandle->threadMutex)
325     {
326         CAQueueingThreadStop(g_sendQueueHandle);
327     }
328
329     CANFCDeinitializeQueueHandles();
330
331     CANFCStopServer();
332
333     OIC_LOG(DEBUG, TAG, "OUT");
334
335     return CA_STATUS_OK;
336 }
337
338 void CATerminateNFC()
339 {
340
341     OIC_LOG(DEBUG, TAG, "IN");
342     CANFCSetPacketReceiveCallback(NULL);
343     CANFCDeinitializeQueueHandles();
344
345     OIC_LOG(DEBUG, TAG, "OUT");
346 }
347
348 void CANFCSendDataThread(void *threadData)
349 {
350     OIC_LOG(DEBUG, TAG, "IN");
351     CANFCData *nfcData = (CANFCData *) threadData;
352     if (!nfcData)
353     {
354         OIC_LOG(ERROR, TAG, "Invalid ip data!");
355         return;
356     }
357
358     CANFCSendData(nfcData->remoteEndpoint, nfcData->data, nfcData->dataLen);
359     OIC_LOG(DEBUG, TAG, "OUT");
360 }
361
362 CANFCData *CACreateNFCData(const CAEndpoint_t *remoteEndpoint, const void *data,
363                            uint32_t dataLength)
364 {
365     VERIFY_NON_NULL_RET(data, TAG, "NFCData is NULL", NULL);
366
367     CANFCData *nfcData = (CANFCData *) OICCalloc(1,sizeof(*nfcData));
368     if (!nfcData)
369     {
370         OIC_LOG(ERROR, TAG, "Memory allocation failed!");
371         return NULL;
372     }
373
374     nfcData->remoteEndpoint = CACloneEndpoint(remoteEndpoint);
375     nfcData->data = (void *) OICMalloc(dataLength);
376     if (!nfcData->data)
377     {
378         OIC_LOG(ERROR, TAG, "Memory allocation failed!");
379         CAFreeNFCData(nfcData);
380         return NULL;
381     }
382
383     memcpy(nfcData->data, data, dataLength);
384     nfcData->dataLen = dataLength;
385
386     return nfcData;
387
388 }
389
390 void CAFreeNFCData(CANFCData *nfcData)
391 {
392     if (nfcData)
393     {
394         CAFreeEndpoint(nfcData->remoteEndpoint);
395         OICFree(nfcData->data);
396         OICFree(nfcData);
397     }
398 }
399
400 void CANFCDataDestroyer(void *data, uint32_t size)
401 {
402     CANFCData *nfcData = (CANFCData *) data;
403
404     CAFreeNFCData(nfcData);
405 }
406
407 CAResult_t CAGetNFCInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
408 {
409     OIC_LOG(DEBUG, TAG, "CAGetNFCInterfaceInformation not supported");
410     if (!info || !size)
411     {
412         OIC_LOG(ERROR, TAG, "CAGetNFCInterfaceInformation : Invalid Input");
413         return CA_STATUS_FAILED;
414     }
415
416     return CA_STATUS_OK;
417 }