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