Imported Upstream version 1.1.0
[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         else
299         {
300             return CA_STATUS_FAILED;
301         }
302     }
303
304     // #3. add data into result
305     // memory allocation
306     CAEndpoint_t *resInfo = (CAEndpoint_t *) OICCalloc(resSize, sizeof (*resInfo));
307     CA_MEMORY_ALLOC_CHECK(resInfo);
308
309     // #4. save data
310     *info = resInfo;
311     *size = resSize;
312
313     for (uint32_t index = 0; index < g_numberOfAdapters; index++)
314     {
315         // check information
316         if (tempSize[index] == 0)
317         {
318             continue;
319         }
320
321         memcpy(resInfo,
322                tempInfo[index],
323                sizeof(*resInfo) * tempSize[index]);
324
325         resInfo += tempSize[index];
326
327         // free adapter data
328         OICFree(tempInfo[index]);
329         tempInfo[index] = NULL;
330     }
331     OICFree(tempInfo);
332     OICFree(tempSize);
333
334     OIC_LOG(DEBUG, TAG, "each network info save success!");
335     return CA_STATUS_OK;
336
337     // memory error label.
338 memory_error_exit:
339
340     for (uint32_t index = 0; index < g_numberOfAdapters; index++)
341     {
342         OICFree(tempInfo[index]);
343         tempInfo[index] = NULL;
344     }
345     OICFree(tempInfo);
346     OICFree(tempSize);
347
348     return CA_MEMORY_ALLOC_FAILED;
349 }
350
351 CAResult_t CASendUnicastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length)
352 {
353     if (endpoint == NULL)
354     {
355         OIC_LOG(DEBUG, TAG, "Invalid endpoint");
356         return CA_STATUS_INVALID_PARAM;
357     }
358
359
360     u_arraylist_t *list = CAGetSelectedNetworkList();
361     if (!list)
362     {
363         OIC_LOG(ERROR, TAG, "No selected network");
364         return CA_SEND_FAILED;
365     }
366     CATransportAdapter_t requestedAdapter = endpoint->adapter ? endpoint->adapter : CA_ALL_ADAPTERS;
367
368     for (uint32_t i = 0; i < u_arraylist_length(list); i++)
369     {
370         void* ptrType = u_arraylist_get(list, i);
371
372         if (NULL == ptrType)
373         {
374             continue;
375         }
376
377         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
378         if (0 == (connType & requestedAdapter))
379         {
380             continue;
381         }
382
383         int index = CAGetAdapterIndex(connType);
384
385         if (-1 == index)
386         {
387             OIC_LOG(ERROR, TAG, "unknown transport type!");
388             return CA_STATUS_INVALID_PARAM;
389         }
390
391         int32_t sentDataLen = 0;
392
393         if (NULL != g_adapterHandler[index].sendData)
394         {
395             OIC_LOG(DEBUG, TAG, "unicast message to adapter");
396             sentDataLen = g_adapterHandler[index].sendData(endpoint, data, length);
397         }
398
399         if (sentDataLen != (int32_t)length)
400         {
401             OIC_LOG(ERROR, TAG, "error in sending data. Error will be reported in adapter");
402 #ifdef SINGLE_THREAD
403             //in case of single thread, no error handler. Report error immediately
404             return CA_SEND_FAILED;
405 #endif
406         }
407
408     }
409
410     return CA_STATUS_OK;
411 }
412
413 CAResult_t CASendMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length)
414 {
415     u_arraylist_t *list = CAGetSelectedNetworkList();
416     if (!list)
417     {
418         OIC_LOG(DEBUG, TAG, "No selected network");
419         return CA_SEND_FAILED;
420     }
421
422     CATransportAdapter_t requestedAdapter = endpoint->adapter ? endpoint->adapter : CA_ALL_ADAPTERS;
423     size_t selectedLength = u_arraylist_length(list);
424     for (size_t i = 0; i < selectedLength; i++)
425     {
426         void* ptrType = u_arraylist_get(list, i);
427
428         if(NULL == ptrType)
429         {
430             continue;
431         }
432
433         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
434         if (0 == (connType & requestedAdapter))
435         {
436             continue;
437         }
438
439         int index = CAGetAdapterIndex(connType);
440         if (0 > index)
441         if (-1 == index)
442         {
443             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
444             continue;
445         }
446
447         uint32_t sentDataLen = 0;
448
449         if (NULL != g_adapterHandler[index].sendDataToAll)
450         {
451             void *payload = (void *) OICMalloc(length);
452             if (!payload)
453             {
454                 OIC_LOG(ERROR, TAG, "Out of memory!");
455                 return CA_MEMORY_ALLOC_FAILED;
456             }
457             memcpy(payload, data, length);
458             sentDataLen = g_adapterHandler[index].sendDataToAll(endpoint, payload, length);
459             OICFree(payload);
460         }
461
462         if (sentDataLen != length)
463         {
464             OIC_LOG(ERROR, TAG, "sendDataToAll failed! Error will be reported from adapter");
465 #ifdef SINGLE_THREAD
466             //in case of single thread, no error handler. Report error immediately
467             return CA_SEND_FAILED;
468 #endif
469         }
470     }
471
472     return CA_STATUS_OK;
473 }
474
475 CAResult_t CAStartListeningServerAdapters()
476 {
477     CAResult_t result = CA_STATUS_FAILED;
478
479     u_arraylist_t *list = CAGetSelectedNetworkList();
480     if (!list)
481     {
482         OIC_LOG(ERROR, TAG, "No selected network");
483         return result;
484     }
485
486     size_t length = u_arraylist_length(list);
487     for (size_t i = 0; i < length; i++)
488     {
489         void* ptrType = u_arraylist_get(list, i);
490
491         if(ptrType == NULL)
492         {
493             continue;
494         }
495
496         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
497
498         int index = CAGetAdapterIndex(connType);
499         if (0 > index)
500         {
501             OIC_LOG(ERROR, TAG, "unknown connectivity type!");
502             continue;
503         }
504
505         if (g_adapterHandler[index].startListenServer != NULL)
506         {
507             const CAResult_t tmp =
508                 g_adapterHandler[index].startListenServer();
509
510             // Successful listen if at least one adapter started.
511             if (CA_STATUS_OK == tmp)
512             {
513                 result = tmp;
514             }
515         }
516     }
517
518     return result;
519 }
520
521 CAResult_t CAStopListeningServerAdapters()
522 {
523     u_arraylist_t *list = CAGetSelectedNetworkList();
524     if (!list)
525     {
526         OIC_LOG(ERROR, TAG, "No selected network");
527         return CA_STATUS_FAILED;
528     }
529
530     size_t length = u_arraylist_length(list);
531     for (size_t i = 0; i < length; i++)
532     {
533         void* ptrType = u_arraylist_get(list, i);
534         if(ptrType == NULL)
535         {
536             continue;
537         }
538
539         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
540
541         int index = CAGetAdapterIndex(connType);
542         if (0 > index)
543         {
544             OIC_LOG(ERROR, TAG, "unknown connectivity type!");
545             continue;
546         }
547
548         if (g_adapterHandler[index].stopListenServer != NULL)
549         {
550             g_adapterHandler[index].stopListenServer();
551         }
552     }
553
554     return CA_STATUS_OK;
555 }
556
557 CAResult_t CAStartDiscoveryServerAdapters()
558 {
559     CAResult_t result = CA_STATUS_FAILED;
560
561     u_arraylist_t *list = CAGetSelectedNetworkList();
562
563     if (!list)
564     {
565         OIC_LOG(ERROR, TAG, "No selected network");
566         return result;
567     }
568
569     size_t length = u_arraylist_length(list);
570     for (size_t i = 0; i < length; i++)
571     {
572         void* ptrType = u_arraylist_get(list, i);
573
574         if(ptrType == NULL)
575         {
576             continue;
577         }
578
579         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
580
581         int index = CAGetAdapterIndex(connType);
582         if (0 > index)
583         {
584             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
585             continue;
586         }
587
588         if (g_adapterHandler[index].startDiscoveryServer != NULL)
589         {
590             const CAResult_t tmp =
591                 g_adapterHandler[index].startDiscoveryServer();
592
593             // Successful discovery if at least one adapter started.
594             if (CA_STATUS_OK == tmp)
595             {
596                 result = tmp;
597             }
598         }
599     }
600
601     return result;
602 }
603
604 void CATerminateAdapters()
605 {
606     for (uint32_t index = 0; index < g_numberOfAdapters; index++)
607     {
608         if (g_adapterHandler[index].terminate != NULL)
609         {
610             g_adapterHandler[index].terminate();
611         }
612     }
613
614     OICFree(g_adapterHandler);
615     g_adapterHandler = NULL;
616     g_numberOfAdapters = 0;
617 }
618
619 #ifdef SINGLE_THREAD
620 CAResult_t CAReadData()
621 {
622     u_arraylist_t *list = CAGetSelectedNetworkList();
623
624     if (!list)
625     {
626         return CA_STATUS_FAILED;
627     }
628
629     uint8_t i = 0;
630     for (i = 0; i < u_arraylist_length(list); i++)
631     {
632         void *ptrType = u_arraylist_get(list, i);
633         if (NULL == ptrType)
634         {
635             OIC_LOG(ERROR, TAG, "get list fail");
636             return CA_STATUS_FAILED;
637         }
638
639         CATransportAdapter_t connType = *(CATransportAdapter_t *) ptrType;
640
641         int index = CAGetAdapterIndex(connType);
642         if (0 > index)
643         {
644             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
645             continue;
646         }
647
648         if (g_adapterHandler[index].readData != NULL)
649         {
650             g_adapterHandler[index].readData();
651         }
652     }
653
654     return CA_STATUS_OK;
655 }
656 #endif
657