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