Fix for Klockwork issues
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / cainterfacecontroller.c
1 /******************************************************************
2  *
3  * Copyright 2014 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************/
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <inttypes.h>
25
26 #include "logger.h"
27 #include "oic_malloc.h"
28 #include "caadapterutils.h"
29 #include "canetworkconfigurator.h"
30 #include "cainterfacecontroller.h"
31 #include "caedradapter.h"
32 #include "caleadapter.h"
33 #include "canfcadapter.h"
34 #include "caremotehandler.h"
35 #include "cathreadpool.h"
36 #include "caipadapter.h"
37 #include "cainterface.h"
38
39 #ifdef RA_ADAPTER
40 #include "caraadapter.h"
41 #endif
42
43 #ifdef TCP_ADAPTER
44 #include "catcpadapter.h"
45 #endif
46
47 #define TAG "OIC_CA_INF_CTR"
48
49 #define CA_MEMORY_ALLOC_CHECK(arg) {if (arg == NULL) \
50     {OIC_LOG(ERROR, TAG, "memory error");goto memory_error_exit;} }
51
52
53
54 static CAConnectivityHandler_t *g_adapterHandler = NULL;
55
56 static uint32_t g_numberOfAdapters = 0;
57
58 static CANetworkPacketReceivedCallback g_networkPacketReceivedCallback = NULL;
59
60 static CANetworkChangeCallback g_networkChangeCallback = NULL;
61
62 static CAErrorHandleCallback g_errorHandleCallback = NULL;
63
64 static int CAGetAdapterIndex(CATransportAdapter_t cType)
65 {
66     for (uint32_t index=0 ; index < g_numberOfAdapters ; index++)
67     {
68         if (cType == g_adapterHandler[index].cType )
69          {
70              return index;
71          }
72     }
73     return -1;
74 }
75
76 static void CARegisterCallback(CAConnectivityHandler_t handler)
77 {
78     if(handler.startAdapter == NULL ||
79         handler.startListenServer == NULL ||
80         handler.stopListenServer == NULL ||
81         handler.startDiscoveryServer == NULL ||
82         handler.sendData == NULL ||
83         handler.sendDataToAll == NULL ||
84         handler.GetnetInfo == NULL ||
85         handler.readData == NULL ||
86         handler.stopAdapter == NULL ||
87         handler.terminate == NULL)
88     {
89         OIC_LOG(ERROR, TAG, "connectivity handler is not enough to be used!");
90         return;
91     }
92     uint32_t numberofAdapters = g_numberOfAdapters + 1;
93     CAConnectivityHandler_t *adapterHandler = OICRealloc(g_adapterHandler,
94                                    (numberofAdapters) * sizeof(*adapterHandler));
95     if (NULL == adapterHandler)
96     {
97         OIC_LOG(ERROR, TAG, "Memory allocation failed during registration");
98         return;
99     }
100     g_adapterHandler = adapterHandler;
101     g_numberOfAdapters = numberofAdapters;
102     g_adapterHandler[g_numberOfAdapters-1] = handler;
103
104     OIC_LOG_V(DEBUG, TAG, "%d type adapter, register complete!", handler.cType);
105 }
106
107 #ifdef RA_ADAPTER
108 CAResult_t CASetAdapterRAInfo(const CARAInfo_t *caraInfo)
109 {
110     return CASetRAInfo(caraInfo);
111 }
112 #endif
113
114 static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep,
115                                      const void *data, uint32_t dataLen)
116 {
117     if (g_networkPacketReceivedCallback != NULL)
118     {
119         g_networkPacketReceivedCallback(sep, data, dataLen);
120     }
121     else
122     {
123         OIC_LOG(ERROR, TAG, "network packet received callback is NULL!");
124     }
125 }
126
127 static void CANetworkChangedCallback(const CAEndpoint_t *info, CANetworkStatus_t status)
128 {
129     // Call the callback.
130     if (g_networkChangeCallback != NULL)
131     {
132         g_networkChangeCallback(info, status);
133     }
134 }
135
136 static void CAAdapterErrorHandleCallback(const CAEndpoint_t *endpoint,
137                                          const void *data, uint32_t dataLen,
138                                          CAResult_t result)
139 {
140     OIC_LOG(DEBUG, TAG, "received error from adapter in interfacecontroller");
141
142     // Call the callback.
143     if (g_errorHandleCallback != NULL)
144     {
145         g_errorHandleCallback(endpoint, data, dataLen, result);
146     }
147 }
148
149 void CAInitializeAdapters(ca_thread_pool_t handle)
150 {
151     OIC_LOG(DEBUG, TAG, "initialize adapters..");
152
153     // Initialize adapters and register callback.
154 #ifdef IP_ADAPTER
155     CAInitializeIP(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
156                    CAAdapterErrorHandleCallback, handle);
157 #endif /* IP_ADAPTER */
158
159 #ifdef EDR_ADAPTER
160     CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
161                     CAAdapterErrorHandleCallback, handle);
162 #endif /* EDR_ADAPTER */
163
164 #ifdef LE_ADAPTER
165     CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
166                    CAAdapterErrorHandleCallback, handle);
167 #endif /* LE_ADAPTER */
168
169 #ifdef RA_ADAPTER
170     CAInitializeRA(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
171                    handle);
172 #endif /* RA_ADAPTER */
173
174 #ifdef TCP_ADAPTER
175     CAInitializeTCP(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
176                     CAAdapterErrorHandleCallback, handle);
177 #endif /* TCP_ADAPTER */
178
179 #ifdef NFC_ADAPTER
180     CAInitializeNFC(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
181                     CAAdapterErrorHandleCallback, handle);
182 #endif /* NFC_ADAPTER */
183 }
184
185 void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback)
186 {
187     OIC_LOG(DEBUG, TAG, "Set Receiver handle callback");
188
189     g_networkPacketReceivedCallback = callback;
190 }
191
192 void CASetNetworkChangeCallback(CANetworkChangeCallback callback)
193 {
194     OIC_LOG(DEBUG, TAG, "Set network handle callback");
195
196     g_networkChangeCallback = callback;
197 }
198
199 void CASetErrorHandleCallback(CAErrorHandleCallback errorCallback)
200 {
201     OIC_LOG(DEBUG, TAG, "Set error handle callback");
202     g_errorHandleCallback = errorCallback;
203 }
204
205 CAResult_t CAStartAdapter(CATransportAdapter_t transportType)
206 {
207     OIC_LOG_V(DEBUG, TAG, "Start the adapter of CAConnectivityType[%d]", transportType);
208
209     int index = CAGetAdapterIndex(transportType);
210     if (0 > index)
211     {
212         OIC_LOG(ERROR, TAG, "unknown connectivity type!");
213         return CA_STATUS_FAILED;
214     }
215
216     CAResult_t res = CA_STATUS_FAILED;
217     if (g_adapterHandler[index].startAdapter != NULL)
218     {
219         res = g_adapterHandler[index].startAdapter();
220     }
221
222     return res;
223 }
224
225 void CAStopAdapter(CATransportAdapter_t transportType)
226 {
227     OIC_LOG_V(DEBUG, TAG, "Stop the adapter of CATransportType[%d]", transportType);
228
229     int index = CAGetAdapterIndex(transportType);
230     if (0 > index)
231     {
232         OIC_LOG(ERROR, TAG, "unknown transport type!");
233         return;
234     }
235
236     if (g_adapterHandler[index].stopAdapter != NULL)
237     {
238         g_adapterHandler[index].stopAdapter();
239     }
240 }
241
242 CAResult_t CAGetNetworkInfo(CAEndpoint_t **info, uint32_t *size)
243 {
244     if (info == NULL || size == NULL)
245     {
246         return CA_STATUS_INVALID_PARAM;
247     }
248
249     CAEndpoint_t **tempInfo = (CAEndpoint_t**) OICCalloc(g_numberOfAdapters, sizeof(*tempInfo));
250     if (!tempInfo)
251     {
252         OIC_LOG(ERROR, TAG, "Out of memory!");
253         return CA_MEMORY_ALLOC_FAILED;
254     }
255     uint32_t *tempSize =(uint32_t*) OICCalloc(g_numberOfAdapters, sizeof(*tempSize));
256     if (!tempSize)
257     {
258         OIC_LOG(ERROR, TAG, "Out of memory!");
259         OICFree(tempInfo);
260         return CA_MEMORY_ALLOC_FAILED;
261     }
262
263     CAResult_t res = CA_STATUS_FAILED;
264     size_t resSize = 0;
265     for (uint32_t index = 0; index < g_numberOfAdapters; index++)
266     {
267         if (g_adapterHandler[index].GetnetInfo != NULL)
268         {
269             // #1. get information for each adapter
270             res = g_adapterHandler[index].GetnetInfo(&tempInfo[index],
271                                                      &tempSize[index]);
272
273             // #2. total size
274             if (res == CA_STATUS_OK)
275             {
276                 resSize += tempSize[index];
277             }
278
279             OIC_LOG_V(DEBUG,
280                       TAG,
281                       "%zu adapter network info size is %" PRIu32 " res:%d",
282                       index,
283                       tempSize[index],
284                       res);
285         }
286     }
287
288     OIC_LOG_V(DEBUG, TAG, "network info total size is %zu!", resSize);
289
290     if (resSize == 0)
291     {
292         OICFree(tempInfo);
293         OICFree(tempSize);
294         if (res == CA_ADAPTER_NOT_ENABLED || res == CA_NOT_SUPPORTED)
295         {
296             return res;
297         }
298         return CA_STATUS_FAILED;
299     }
300
301     // #3. add data into result
302     // memory allocation
303     CAEndpoint_t *resInfo = (CAEndpoint_t *) OICCalloc(resSize, sizeof (*resInfo));
304     CA_MEMORY_ALLOC_CHECK(resInfo);
305
306     // #4. save data
307     *info = resInfo;
308     *size = resSize;
309
310     for (uint32_t index = 0; index < g_numberOfAdapters; index++)
311     {
312         // check information
313         if (tempSize[index] == 0)
314         {
315             continue;
316         }
317
318         memcpy(resInfo,
319                tempInfo[index],
320                sizeof(*resInfo) * tempSize[index]);
321
322         resInfo += tempSize[index];
323
324         // free adapter data
325         OICFree(tempInfo[index]);
326         tempInfo[index] = NULL;
327     }
328     OICFree(tempInfo);
329     OICFree(tempSize);
330
331     OIC_LOG(DEBUG, TAG, "each network info save success!");
332     return CA_STATUS_OK;
333
334     // memory error label.
335 memory_error_exit:
336
337     for (uint32_t index = 0; index < g_numberOfAdapters; index++)
338     {
339         OICFree(tempInfo[index]);
340         tempInfo[index] = NULL;
341     }
342     OICFree(tempInfo);
343     OICFree(tempSize);
344
345     return CA_MEMORY_ALLOC_FAILED;
346 }
347
348 CAResult_t CASendUnicastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length)
349 {
350     if (endpoint == NULL)
351     {
352         OIC_LOG(DEBUG, TAG, "Invalid endpoint");
353         return CA_STATUS_INVALID_PARAM;
354     }
355
356
357     u_arraylist_t *list = CAGetSelectedNetworkList();
358     if (!list)
359     {
360         OIC_LOG(ERROR, TAG, "No selected network");
361         return CA_SEND_FAILED;
362     }
363     CATransportAdapter_t requestedAdapter = endpoint->adapter ? endpoint->adapter : CA_ALL_ADAPTERS;
364
365     for (uint32_t i = 0; i < u_arraylist_length(list); i++)
366     {
367         void* ptrType = u_arraylist_get(list, i);
368
369         if (NULL == ptrType)
370         {
371             continue;
372         }
373
374         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
375         if (0 == (connType & requestedAdapter))
376         {
377             continue;
378         }
379
380         int index = CAGetAdapterIndex(connType);
381
382         if (-1 == index)
383         {
384             OIC_LOG(ERROR, TAG, "unknown transport type!");
385             return CA_STATUS_INVALID_PARAM;
386         }
387
388         int32_t sentDataLen = 0;
389
390         if (NULL != g_adapterHandler[index].sendData)
391         {
392             OIC_LOG(DEBUG, TAG, "unicast message to adapter");
393             sentDataLen = g_adapterHandler[index].sendData(endpoint, data, length);
394         }
395
396         if (sentDataLen != (int32_t)length)
397         {
398             OIC_LOG(ERROR, TAG, "error in sending data. Error will be reported in adapter");
399 #ifdef SINGLE_THREAD
400             //in case of single thread, no error handler. Report error immediately
401             return CA_SEND_FAILED;
402 #endif
403         }
404
405     }
406
407     return CA_STATUS_OK;
408 }
409
410 CAResult_t CASendMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length)
411 {
412     u_arraylist_t *list = CAGetSelectedNetworkList();
413     if (!list)
414     {
415         OIC_LOG(DEBUG, TAG, "No selected network");
416         return CA_SEND_FAILED;
417     }
418
419     CATransportAdapter_t requestedAdapter = endpoint->adapter ? endpoint->adapter : CA_ALL_ADAPTERS;
420     size_t selectedLength = u_arraylist_length(list);
421     for (size_t i = 0; i < selectedLength; i++)
422     {
423         void* ptrType = u_arraylist_get(list, i);
424
425         if(NULL == ptrType)
426         {
427             continue;
428         }
429
430         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
431         if (0 == (connType & requestedAdapter))
432         {
433             continue;
434         }
435
436         int index = CAGetAdapterIndex(connType);
437         if (0 > index)
438         if (-1 == index)
439         {
440             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
441             continue;
442         }
443
444         uint32_t sentDataLen = 0;
445
446         if (NULL != g_adapterHandler[index].sendDataToAll)
447         {
448             void *payload = (void *) OICMalloc(length);
449             if (!payload)
450             {
451                 OIC_LOG(ERROR, TAG, "Out of memory!");
452                 return CA_MEMORY_ALLOC_FAILED;
453             }
454             memcpy(payload, data, length);
455             sentDataLen = g_adapterHandler[index].sendDataToAll(endpoint, payload, length);
456             OICFree(payload);
457         }
458
459         if (sentDataLen != length)
460         {
461             OIC_LOG(ERROR, TAG, "sendDataToAll failed! Error will be reported from adapter");
462 #ifdef SINGLE_THREAD
463             //in case of single thread, no error handler. Report error immediately
464             return CA_SEND_FAILED;
465 #endif
466         }
467     }
468
469     return CA_STATUS_OK;
470 }
471
472 CAResult_t CAStartListeningServerAdapters()
473 {
474     CAResult_t result = CA_STATUS_FAILED;
475
476     u_arraylist_t *list = CAGetSelectedNetworkList();
477     if (!list)
478     {
479         OIC_LOG(ERROR, TAG, "No selected network");
480         return result;
481     }
482
483     size_t length = u_arraylist_length(list);
484     for (size_t i = 0; i < length; i++)
485     {
486         void* ptrType = u_arraylist_get(list, i);
487
488         if(ptrType == NULL)
489         {
490             continue;
491         }
492
493         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
494
495         int index = CAGetAdapterIndex(connType);
496         if (0 > index)
497         {
498             OIC_LOG(ERROR, TAG, "unknown connectivity type!");
499             continue;
500         }
501
502         if (g_adapterHandler[index].startListenServer != NULL)
503         {
504             const CAResult_t tmp =
505                 g_adapterHandler[index].startListenServer();
506
507             // Successful listen if at least one adapter started.
508             if (CA_STATUS_OK == tmp)
509             {
510                 result = tmp;
511             }
512         }
513     }
514
515     return result;
516 }
517
518 CAResult_t CAStopListeningServerAdapters()
519 {
520     u_arraylist_t *list = CAGetSelectedNetworkList();
521     if (!list)
522     {
523         OIC_LOG(ERROR, TAG, "No selected network");
524         return CA_STATUS_FAILED;
525     }
526
527     size_t length = u_arraylist_length(list);
528     for (size_t i = 0; i < length; i++)
529     {
530         void* ptrType = u_arraylist_get(list, i);
531         if(ptrType == NULL)
532         {
533             continue;
534         }
535
536         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
537
538         int index = CAGetAdapterIndex(connType);
539         if (0 > index)
540         {
541             OIC_LOG(ERROR, TAG, "unknown connectivity type!");
542             continue;
543         }
544
545         if (g_adapterHandler[index].stopListenServer != NULL)
546         {
547             g_adapterHandler[index].stopListenServer();
548         }
549     }
550
551     return CA_STATUS_OK;
552 }
553
554 CAResult_t CAStartDiscoveryServerAdapters()
555 {
556     CAResult_t result = CA_STATUS_FAILED;
557
558     u_arraylist_t *list = CAGetSelectedNetworkList();
559
560     if (!list)
561     {
562         OIC_LOG(ERROR, TAG, "No selected network");
563         return result;
564     }
565
566     size_t length = u_arraylist_length(list);
567     for (size_t i = 0; i < length; i++)
568     {
569         void* ptrType = u_arraylist_get(list, i);
570
571         if(ptrType == NULL)
572         {
573             continue;
574         }
575
576         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
577
578         int index = CAGetAdapterIndex(connType);
579         if (0 > index)
580         {
581             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
582             continue;
583         }
584
585         if (g_adapterHandler[index].startDiscoveryServer != NULL)
586         {
587             const CAResult_t tmp =
588                 g_adapterHandler[index].startDiscoveryServer();
589
590             // Successful discovery if at least one adapter started.
591             if (CA_STATUS_OK == tmp)
592             {
593                 result = tmp;
594             }
595         }
596     }
597
598     return result;
599 }
600
601 void CATerminateAdapters()
602 {
603     for (uint32_t index = 0; index < g_numberOfAdapters; index++)
604     {
605         if (g_adapterHandler[index].terminate != NULL)
606         {
607             g_adapterHandler[index].terminate();
608         }
609     }
610
611     OICFree(g_adapterHandler);
612     g_adapterHandler = NULL;
613     g_numberOfAdapters = 0;
614 }
615
616 #ifdef SINGLE_THREAD
617 CAResult_t CAReadData()
618 {
619     u_arraylist_t *list = CAGetSelectedNetworkList();
620
621     if (!list)
622     {
623         return CA_STATUS_FAILED;
624     }
625
626     uint8_t i = 0;
627     for (i = 0; i < u_arraylist_length(list); i++)
628     {
629         void *ptrType = u_arraylist_get(list, i);
630         if (NULL == ptrType)
631         {
632             OIC_LOG(ERROR, TAG, "get list fail");
633             return CA_STATUS_FAILED;
634         }
635
636         CATransportAdapter_t connType = *(CATransportAdapter_t *) ptrType;
637
638         int index = CAGetAdapterIndex(connType);
639         if (0 > index)
640         {
641             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
642             continue;
643         }
644
645         if (g_adapterHandler[index].readData != NULL)
646         {
647             g_adapterHandler[index].readData();
648         }
649     }
650
651     return CA_STATUS_OK;
652 }
653 #endif
654