Separated transmission logic for data on Both Mode.
[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 static CAConnectivityHandler_t *g_adapterHandler = NULL;
53
54 static uint32_t g_numberOfAdapters = 0;
55
56 static CANetworkPacketReceivedCallback g_networkPacketReceivedCallback = NULL;
57
58 static CAAdapterChangeCallback g_adapterChangeCallback = NULL;
59
60 static CAConnectionChangeCallback g_connChangeCallback = 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 CAAdapterChangedCallback(CATransportAdapter_t adapter, CANetworkStatus_t status)
128 {
129     // Call the callback.
130     if (g_adapterChangeCallback != NULL)
131     {
132         g_adapterChangeCallback(adapter, status);
133     }
134     OIC_LOG_V(DEBUG, TAG, "[%d]adapter status is changed to [%d]", adapter, status);
135 }
136
137 static void CAConnectionChangedCallback(const CAEndpoint_t *info, bool isConnected)
138 {
139     // Call the callback.
140     if (g_connChangeCallback != NULL)
141     {
142         g_connChangeCallback(info, isConnected);
143     }
144     OIC_LOG_V(DEBUG, TAG, "[%s] connection status is changed to [%d]", info->addr, isConnected);
145 }
146
147 static void CAAdapterErrorHandleCallback(const CAEndpoint_t *endpoint,
148                                          const void *data, uint32_t dataLen,
149                                          CAResult_t result)
150 {
151     OIC_LOG(DEBUG, TAG, "received error from adapter in interfacecontroller");
152
153     // Call the callback.
154     if (g_errorHandleCallback != NULL)
155     {
156         g_errorHandleCallback(endpoint, data, dataLen, result);
157     }
158 }
159
160 void CAInitializeAdapters(ca_thread_pool_t handle)
161 {
162     OIC_LOG(DEBUG, TAG, "initialize adapters..");
163
164     // Initialize adapters and register callback.
165 #ifdef IP_ADAPTER
166     CAInitializeIP(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
167                    CAAdapterErrorHandleCallback, handle);
168 #endif /* IP_ADAPTER */
169
170 #ifdef EDR_ADAPTER
171     CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
172                     CAConnectionChangedCallback, CAAdapterErrorHandleCallback, handle);
173 #endif /* EDR_ADAPTER */
174
175 #ifdef LE_ADAPTER
176     CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
177                    CAConnectionChangedCallback, CAAdapterErrorHandleCallback, handle);
178 #endif /* LE_ADAPTER */
179
180 #ifdef RA_ADAPTER
181     CAInitializeRA(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
182                    handle);
183 #endif /* RA_ADAPTER */
184
185 #ifdef TCP_ADAPTER
186     CAInitializeTCP(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
187                     CAConnectionChangedCallback, CAAdapterErrorHandleCallback, handle);
188 #endif /* TCP_ADAPTER */
189
190 #ifdef NFC_ADAPTER
191     CAInitializeNFC(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
192                     CAAdapterErrorHandleCallback, handle);
193 #endif /* NFC_ADAPTER */
194 }
195
196 void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback)
197 {
198     OIC_LOG(DEBUG, TAG, "Set Receiver handle callback");
199
200     g_networkPacketReceivedCallback = callback;
201 }
202
203 void CASetNetworkMonitorCallbacks(CAAdapterChangeCallback adapterCB,
204                                   CAConnectionChangeCallback connCB)
205 {
206     OIC_LOG(DEBUG, TAG, "Set network monitoring callback");
207
208     g_adapterChangeCallback = adapterCB;
209     g_connChangeCallback = connCB;
210 }
211
212 void CASetErrorHandleCallback(CAErrorHandleCallback errorCallback)
213 {
214     OIC_LOG(DEBUG, TAG, "Set error handle callback");
215     g_errorHandleCallback = errorCallback;
216 }
217
218 CAResult_t CAStartAdapter(CATransportAdapter_t transportType)
219 {
220     OIC_LOG_V(DEBUG, TAG, "Start the adapter of CAConnectivityType[%d]", transportType);
221
222     int index = CAGetAdapterIndex(transportType);
223     if (0 > index)
224     {
225         OIC_LOG(ERROR, TAG, "unknown connectivity type!");
226         return CA_STATUS_FAILED;
227     }
228
229     CAResult_t res = CA_STATUS_FAILED;
230     if (g_adapterHandler[index].startAdapter != NULL)
231     {
232         res = g_adapterHandler[index].startAdapter();
233     }
234
235     return res;
236 }
237
238 void CAStopAdapter(CATransportAdapter_t transportType)
239 {
240     OIC_LOG_V(DEBUG, TAG, "Stop the adapter of CATransportType[%d]", transportType);
241
242     int index = CAGetAdapterIndex(transportType);
243     if (0 > index)
244     {
245         OIC_LOG(ERROR, TAG, "unknown transport type!");
246         return;
247     }
248
249     if (g_adapterHandler[index].stopAdapter != NULL)
250     {
251         g_adapterHandler[index].stopAdapter();
252     }
253 }
254
255 CAResult_t CAGetNetworkInfo(CAEndpoint_t **info, uint32_t *size)
256 {
257     if (info == NULL || size == NULL)
258     {
259         return CA_STATUS_INVALID_PARAM;
260     }
261
262     CAEndpoint_t **tempInfo = (CAEndpoint_t**) OICCalloc(g_numberOfAdapters, sizeof(*tempInfo));
263     if (!tempInfo)
264     {
265         OIC_LOG(ERROR, TAG, "Out of memory!");
266         return CA_MEMORY_ALLOC_FAILED;
267     }
268     uint32_t *tempSize =(uint32_t*) OICCalloc(g_numberOfAdapters, sizeof(*tempSize));
269     if (!tempSize)
270     {
271         OIC_LOG(ERROR, TAG, "Out of memory!");
272         OICFree(tempInfo);
273         return CA_MEMORY_ALLOC_FAILED;
274     }
275
276     CAResult_t res = CA_STATUS_FAILED;
277     size_t resSize = 0;
278     for (uint32_t index = 0; index < g_numberOfAdapters; index++)
279     {
280         if (g_adapterHandler[index].GetnetInfo != NULL)
281         {
282             // #1. get information for each adapter
283             res = g_adapterHandler[index].GetnetInfo(&tempInfo[index],
284                                                      &tempSize[index]);
285
286             // #2. total size
287             if (res == CA_STATUS_OK)
288             {
289                 resSize += tempSize[index];
290             }
291
292             OIC_LOG_V(DEBUG,
293                       TAG,
294                       "%zu adapter network info size is %" PRIu32 " res:%d",
295                       index,
296                       tempSize[index],
297                       res);
298         }
299     }
300
301     OIC_LOG_V(DEBUG, TAG, "network info total size is %zu!", resSize);
302
303     if (resSize == 0)
304     {
305         OICFree(tempInfo);
306         OICFree(tempSize);
307         if (res == CA_ADAPTER_NOT_ENABLED || res == CA_NOT_SUPPORTED)
308         {
309             return res;
310         }
311         else
312         {
313             return CA_STATUS_FAILED;
314         }
315     }
316
317     // #3. add data into result
318     // memory allocation
319     CAEndpoint_t *resInfo = (CAEndpoint_t *) OICCalloc(resSize, sizeof (*resInfo));
320     CA_MEMORY_ALLOC_CHECK(resInfo);
321
322     // #4. save data
323     *info = resInfo;
324     *size = resSize;
325
326     for (uint32_t index = 0; index < g_numberOfAdapters; index++)
327     {
328         // check information
329         if (tempSize[index] == 0)
330         {
331             continue;
332         }
333
334         memcpy(resInfo,
335                tempInfo[index],
336                sizeof(*resInfo) * tempSize[index]);
337
338         resInfo += tempSize[index];
339
340         // free adapter data
341         OICFree(tempInfo[index]);
342         tempInfo[index] = NULL;
343     }
344     OICFree(tempInfo);
345     OICFree(tempSize);
346
347     OIC_LOG(DEBUG, TAG, "each network info save success!");
348     return CA_STATUS_OK;
349
350     // memory error label.
351 memory_error_exit:
352
353     for (uint32_t index = 0; index < g_numberOfAdapters; index++)
354     {
355         OICFree(tempInfo[index]);
356         tempInfo[index] = NULL;
357     }
358     OICFree(tempInfo);
359     OICFree(tempSize);
360
361     return CA_MEMORY_ALLOC_FAILED;
362 }
363
364 CAResult_t CASendUnicastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length,
365                              CADataType_t dataType)
366 {
367     if (endpoint == NULL)
368     {
369         OIC_LOG(DEBUG, TAG, "Invalid endpoint");
370         return CA_STATUS_INVALID_PARAM;
371     }
372
373
374     u_arraylist_t *list = CAGetSelectedNetworkList();
375     if (!list)
376     {
377         OIC_LOG(ERROR, TAG, "No selected network");
378         return CA_SEND_FAILED;
379     }
380     CATransportAdapter_t requestedAdapter = endpoint->adapter ? endpoint->adapter : CA_ALL_ADAPTERS;
381
382     for (uint32_t i = 0; i < u_arraylist_length(list); i++)
383     {
384         void* ptrType = u_arraylist_get(list, i);
385
386         if (NULL == ptrType)
387         {
388             continue;
389         }
390
391         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
392         if (0 == (connType & requestedAdapter))
393         {
394             continue;
395         }
396
397         int index = CAGetAdapterIndex(connType);
398
399         if (-1 == index)
400         {
401             OIC_LOG(ERROR, TAG, "unknown transport type!");
402             return CA_STATUS_INVALID_PARAM;
403         }
404
405         int32_t sentDataLen = 0;
406
407         if (NULL != g_adapterHandler[index].sendData)
408         {
409             OIC_LOG(DEBUG, TAG, "unicast message to adapter");
410             sentDataLen = g_adapterHandler[index].sendData(endpoint, data, length, dataType);
411         }
412
413         if (sentDataLen != (int32_t)length)
414         {
415             OIC_LOG(ERROR, TAG, "error in sending data. Error will be reported in adapter");
416 #ifdef SINGLE_THREAD
417             //in case of single thread, no error handler. Report error immediately
418             return CA_SEND_FAILED;
419 #endif
420         }
421
422     }
423
424     return CA_STATUS_OK;
425 }
426
427 CAResult_t CASendMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length,
428                                CADataType_t dataType)
429 {
430     u_arraylist_t *list = CAGetSelectedNetworkList();
431     if (!list)
432     {
433         OIC_LOG(DEBUG, TAG, "No selected network");
434         return CA_SEND_FAILED;
435     }
436
437     CATransportAdapter_t requestedAdapter = endpoint->adapter ? endpoint->adapter : CA_ALL_ADAPTERS;
438     size_t selectedLength = u_arraylist_length(list);
439     for (size_t i = 0; i < selectedLength; i++)
440     {
441         void* ptrType = u_arraylist_get(list, i);
442
443         if (NULL == ptrType)
444         {
445             continue;
446         }
447
448         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
449         if (0 == (connType & requestedAdapter))
450         {
451             continue;
452         }
453
454         int index = CAGetAdapterIndex(connType);
455         if (0 > index)
456         {
457             OIC_LOG(ERROR, TAG, "unknown connectivity type!");
458             continue;
459         }
460
461         uint32_t sentDataLen = 0;
462
463         if (NULL != g_adapterHandler[index].sendDataToAll)
464         {
465             void *payload = (void *) OICMalloc(length);
466             if (!payload)
467             {
468                 OIC_LOG(ERROR, TAG, "Out of memory!");
469                 return CA_MEMORY_ALLOC_FAILED;
470             }
471             memcpy(payload, data, length);
472             sentDataLen = g_adapterHandler[index].sendDataToAll(endpoint, payload, length, dataType);
473             OICFree(payload);
474         }
475
476         if (sentDataLen != length)
477         {
478             OIC_LOG(ERROR, TAG, "sendDataToAll failed! Error will be reported from adapter");
479 #ifdef SINGLE_THREAD
480             //in case of single thread, no error handler. Report error immediately
481             return CA_SEND_FAILED;
482 #endif
483         }
484     }
485
486     return CA_STATUS_OK;
487 }
488
489 CAResult_t CAStartListeningServerAdapters()
490 {
491     CAResult_t result = CA_STATUS_FAILED;
492
493     u_arraylist_t *list = CAGetSelectedNetworkList();
494     if (!list)
495     {
496         OIC_LOG(ERROR, TAG, "No selected network");
497         return result;
498     }
499
500     size_t length = u_arraylist_length(list);
501     for (size_t i = 0; i < length; i++)
502     {
503         void* ptrType = u_arraylist_get(list, i);
504
505         if(ptrType == NULL)
506         {
507             continue;
508         }
509
510         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
511
512         int index = CAGetAdapterIndex(connType);
513         if (0 > index)
514         {
515             OIC_LOG(ERROR, TAG, "unknown connectivity type!");
516             continue;
517         }
518
519         if (g_adapterHandler[index].startListenServer != NULL)
520         {
521             const CAResult_t tmp =
522                 g_adapterHandler[index].startListenServer();
523
524             // Successful listen if at least one adapter started.
525             if (CA_STATUS_OK == tmp)
526             {
527                 result = tmp;
528             }
529         }
530     }
531
532     return result;
533 }
534
535 CAResult_t CAStopListeningServerAdapters()
536 {
537     u_arraylist_t *list = CAGetSelectedNetworkList();
538     if (!list)
539     {
540         OIC_LOG(ERROR, TAG, "No selected network");
541         return CA_STATUS_FAILED;
542     }
543
544     size_t length = u_arraylist_length(list);
545     for (size_t i = 0; i < length; i++)
546     {
547         void* ptrType = u_arraylist_get(list, i);
548         if(ptrType == NULL)
549         {
550             continue;
551         }
552
553         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
554
555         int index = CAGetAdapterIndex(connType);
556         if (0 > index)
557         {
558             OIC_LOG(ERROR, TAG, "unknown connectivity type!");
559             continue;
560         }
561
562         if (g_adapterHandler[index].stopListenServer != NULL)
563         {
564             g_adapterHandler[index].stopListenServer();
565         }
566     }
567
568     return CA_STATUS_OK;
569 }
570
571 CAResult_t CAStartDiscoveryServerAdapters()
572 {
573     CAResult_t result = CA_STATUS_FAILED;
574
575     u_arraylist_t *list = CAGetSelectedNetworkList();
576
577     if (!list)
578     {
579         OIC_LOG(ERROR, TAG, "No selected network");
580         return result;
581     }
582
583     size_t length = u_arraylist_length(list);
584     for (size_t i = 0; i < length; i++)
585     {
586         void* ptrType = u_arraylist_get(list, i);
587
588         if(ptrType == NULL)
589         {
590             continue;
591         }
592
593         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
594
595         int index = CAGetAdapterIndex(connType);
596         if (0 > index)
597         {
598             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
599             continue;
600         }
601
602         if (g_adapterHandler[index].startDiscoveryServer != NULL)
603         {
604             const CAResult_t tmp =
605                 g_adapterHandler[index].startDiscoveryServer();
606
607             // Successful discovery if at least one adapter started.
608             if (CA_STATUS_OK == tmp)
609             {
610                 result = tmp;
611             }
612         }
613     }
614
615     return result;
616 }
617
618 void CATerminateAdapters()
619 {
620     for (uint32_t index = 0; index < g_numberOfAdapters; index++)
621     {
622         if (g_adapterHandler[index].terminate != NULL)
623         {
624             g_adapterHandler[index].terminate();
625         }
626     }
627
628     OICFree(g_adapterHandler);
629     g_adapterHandler = NULL;
630     g_numberOfAdapters = 0;
631 }
632
633 #ifdef SINGLE_THREAD
634 CAResult_t CAReadData()
635 {
636     u_arraylist_t *list = CAGetSelectedNetworkList();
637
638     if (!list)
639     {
640         return CA_STATUS_FAILED;
641     }
642
643     uint8_t i = 0;
644     for (i = 0; i < u_arraylist_length(list); i++)
645     {
646         void *ptrType = u_arraylist_get(list, i);
647         if (NULL == ptrType)
648         {
649             OIC_LOG(ERROR, TAG, "get list fail");
650             return CA_STATUS_FAILED;
651         }
652
653         CATransportAdapter_t connType = *(CATransportAdapter_t *) ptrType;
654
655         int index = CAGetAdapterIndex(connType);
656         if (0 > index)
657         {
658             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
659             continue;
660         }
661
662         if (g_adapterHandler[index].readData != NULL)
663         {
664             g_adapterHandler[index].readData();
665         }
666     }
667
668     return CA_STATUS_OK;
669 }
670 #endif
671