Adding Error handling from CA to RI
[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 "cainterfacecontroller.h"
27 #include "caipadapter.h"
28 #include "caedradapter.h"
29 #include "caleadapter.h"
30 #include "canetworkconfigurator.h"
31 #include "caremotehandler.h"
32 #include "oic_malloc.h"
33 #include "logger.h"
34 #include "cathreadpool.h"
35
36 #define TAG PCF("CA")
37
38 #define CA_MEMORY_ALLOC_CHECK(arg) {if (arg == NULL) \
39     {OIC_LOG(ERROR, TAG, "memory error");goto memory_error_exit;} }
40
41 #define CA_TRANSPORT_TYPE_NUM   4
42
43 static CAConnectivityHandler_t g_adapterHandler[CA_TRANSPORT_TYPE_NUM];
44
45 static CANetworkPacketReceivedCallback g_networkPacketReceivedCallback = NULL;
46
47 static CANetworkChangeCallback g_networkChangeCallback = NULL;
48
49 static CAErrorHandleCallback g_errorHandleCallback = NULL;
50
51 static int CAGetAdapterIndex(CATransportType_t cType)
52 {
53     switch (cType)
54     {
55         case CA_IPV4:
56             return 0;
57         case CA_IPV6:
58             return 1;
59         case CA_EDR:
60             return 2;
61         case CA_LE:
62             return 3;
63     }
64
65     OIC_LOG(DEBUG, TAG, "CA_TRANSPORT_TYPE_NUM is not 4");
66
67     return -1;
68 }
69
70 static void CARegisterCallback(CAConnectivityHandler_t handler, CATransportType_t cType)
71 {
72     OIC_LOG(DEBUG, TAG, "CARegisterCallback - Entry");
73
74     if(handler.startAdapter == NULL ||
75         handler.startListenServer == NULL ||
76         handler.startDiscoveryServer == NULL ||
77         handler.sendData == NULL ||
78         handler.sendDataToAll == NULL ||
79         handler.GetnetInfo == NULL ||
80         handler.readData == NULL ||
81         handler.stopAdapter == NULL ||
82         handler.terminate == NULL)
83     {
84         OIC_LOG(ERROR, TAG, "connectivity handler is not enough to be used!");
85         return;
86     }
87
88     int index = CAGetAdapterIndex(cType);
89
90     if (index == -1)
91     {
92         OIC_LOG(ERROR, TAG, "unknown connectivity type!");
93         return;
94     }
95
96     memcpy(&g_adapterHandler[index], &handler, sizeof(CAConnectivityHandler_t));
97
98     OIC_LOG_V(DEBUG, TAG, "%d type adapter, register complete!", cType);
99 }
100
101 static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data,
102                                      uint32_t dataLen)
103 {
104     OIC_LOG(DEBUG, TAG, "receivedPacketCallback in interface controller");
105
106     // Call the callback.
107     if (g_networkPacketReceivedCallback != NULL)
108     {
109         g_networkPacketReceivedCallback(endpoint, data, dataLen);
110     }
111     else
112     {
113         OICFree(endpoint);
114         endpoint = NULL;
115         OICFree(data);
116         data = NULL;
117
118         OIC_LOG(ERROR, TAG, "network packet received callback is NULL!");
119     }
120 }
121
122 static void CANetworkChangedCallback(CALocalConnectivity_t *info,
123                                      CANetworkStatus_t status)
124 {
125     OIC_LOG(DEBUG, TAG, "Network Changed callback");
126
127     // Call the callback.
128     if (g_networkChangeCallback != NULL)
129     {
130         g_networkChangeCallback(info, status);
131     }
132 }
133
134 static void CAAdapterErrorHandleCallback(const CARemoteEndpoint_t *endpoint, const void *data,
135                                          uint32_t dataLen, CAResult_t result)
136 {
137     OIC_LOG(DEBUG, TAG, "received error from adapter in interfacecontroller");
138
139     // Call the callback.
140     if (g_errorHandleCallback != NULL)
141     {
142         g_errorHandleCallback(endpoint, data, dataLen, result);
143     }
144 }
145
146 void CAInitializeAdapters(ca_thread_pool_t handle)
147 {
148     OIC_LOG(DEBUG, TAG, "initialize adapters..");
149
150     memset(g_adapterHandler, 0, sizeof(CAConnectivityHandler_t) * CA_TRANSPORT_TYPE_NUM);
151
152     // Initialize adapters and register callback.
153 #ifdef IP_ADAPTER
154     CAInitializeIP(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
155                          handle);
156 #endif /* IP_ADAPTER */
157
158 #ifdef EDR_ADAPTER
159     CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
160                     handle);
161 #endif /* EDR_ADAPTER */
162
163 #ifdef LE_ADAPTER
164     CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
165                    handle);
166 #endif /* LE_ADAPTER */
167
168 }
169
170 void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback)
171 {
172     OIC_LOG(DEBUG, TAG, "Set packet received callback");
173
174     g_networkPacketReceivedCallback = callback;
175 }
176
177 void CASetNetworkChangeCallback(CANetworkChangeCallback callback)
178 {
179     OIC_LOG(DEBUG, TAG, "Set network change callback");
180
181     g_networkChangeCallback = callback;
182 }
183
184 void CASetErrorHandleCallback(CAErrorHandleCallback errorCallback)
185 {
186     OIC_LOG(DEBUG, TAG, "Set error handle callback");
187     g_errorHandleCallback = errorCallback;
188 }
189
190 CAResult_t CAStartAdapter(CATransportType_t transportType)
191 {
192     OIC_LOG_V(DEBUG, TAG, "Start the adapter of CAConnectivityType[%d]", transportType);
193
194     int index = CAGetAdapterIndex(transportType);
195
196     if (index == -1)
197     {
198         OIC_LOG(ERROR, TAG, "unknown connectivity type!");
199         return CA_STATUS_FAILED;
200     }
201
202     if (g_adapterHandler[index].startAdapter != NULL)
203     {
204         g_adapterHandler[index].startAdapter();
205     }
206
207     return CA_STATUS_OK;
208 }
209
210 void CAStopAdapter(CATransportType_t transportType)
211 {
212     OIC_LOG_V(DEBUG, TAG, "Stop the adapter of CATransportType[%d]", transportType);
213
214     int index = CAGetAdapterIndex(transportType);
215
216     if (index == -1)
217     {
218         OIC_LOG(ERROR, TAG, "unknown transport type!");
219         return;
220     }
221
222     if (g_adapterHandler[index].stopAdapter != NULL)
223     {
224         g_adapterHandler[index].stopAdapter();
225     }
226 }
227
228 CAResult_t CAGetNetworkInfo(CALocalConnectivity_t **info, uint32_t *size)
229 {
230     if (info == NULL || size == NULL)
231     {
232         return CA_STATUS_INVALID_PARAM;
233     }
234
235     CALocalConnectivity_t *tempInfo[CA_TRANSPORT_TYPE_NUM] = { 0 };
236     uint32_t tempSize[CA_TRANSPORT_TYPE_NUM] = { 0 };
237
238     CAResult_t res = CA_STATUS_FAILED;
239     uint32_t resSize = 0;
240     for (int index = 0; index < CA_TRANSPORT_TYPE_NUM; index++)
241     {
242         if (g_adapterHandler[index].GetnetInfo != NULL)
243         {
244             // #1. get information for each adapter
245             res = g_adapterHandler[index].GetnetInfo(&tempInfo[index],
246                                                      &tempSize[index]);
247
248             // #2. total size
249             if (res == CA_STATUS_OK)
250             {
251                 resSize += tempSize[index];
252             }
253
254             OIC_LOG_V(DEBUG,
255                       TAG,
256                       "%d adapter network info size is %" PRIu32 " res:%d",
257                       index,
258                       tempSize[index],
259                       res);
260         }
261     }
262
263     OIC_LOG_V(DEBUG, TAG, "network info total size is %d!", resSize);
264
265     if (resSize == 0)
266     {
267         if (res == CA_ADAPTER_NOT_ENABLED || res == CA_NOT_SUPPORTED)
268         {
269             return res;
270         }
271         return CA_STATUS_FAILED;
272     }
273
274     // #3. add data into result
275     // memory allocation
276
277     CALocalConnectivity_t *resInfo = (CALocalConnectivity_t *)
278                                      OICCalloc(resSize, sizeof(CALocalConnectivity_t));
279     CA_MEMORY_ALLOC_CHECK(resInfo);
280
281     // #4. save data
282     *info = resInfo;
283     *size = resSize;
284
285     for (int index = 0; index < CA_TRANSPORT_TYPE_NUM; index++)
286     {
287         // check information
288         if (tempSize[index] == 0)
289         {
290             continue;
291         }
292
293         memcpy(resInfo,
294                tempInfo[index],
295                sizeof(*resInfo) * tempSize[index]);
296
297         resInfo += tempSize[index];
298
299         // free adapter data
300         OICFree(tempInfo[index]);
301         tempInfo[index] = NULL;
302     }
303
304     OIC_LOG(DEBUG, TAG, "each network info save success!");
305     return CA_STATUS_OK;
306
307     // memory error label.
308 memory_error_exit:
309
310     for (int index = 0; index < CA_TRANSPORT_TYPE_NUM; index++)
311     {
312
313         OICFree(tempInfo[index]);
314         tempInfo[index] = NULL;
315     }
316
317     return CA_MEMORY_ALLOC_FAILED;
318 }
319
320 CAResult_t CASendUnicastData(const CARemoteEndpoint_t *endpoint, const void *data, uint32_t length)
321 {
322     OIC_LOG(DEBUG, TAG, "Send unicast data to enabled interface..");
323
324     CAResult_t res = CA_STATUS_FAILED;
325
326     if (endpoint == NULL)
327     {
328         OIC_LOG(DEBUG, TAG, "Invalid endpoint");
329         return CA_STATUS_INVALID_PARAM;
330     }
331
332     CATransportType_t type = endpoint->transportType;
333
334     int index = CAGetAdapterIndex(type);
335
336     if (index == -1)
337     {
338         OIC_LOG(ERROR, TAG, "unknown transport type!");
339         return CA_STATUS_INVALID_PARAM;
340     }
341
342     uint32_t sentDataLen = 0;
343
344     if (g_adapterHandler[index].sendData != NULL)
345     {
346         sentDataLen = g_adapterHandler[index].sendData(endpoint, data, length);
347     }
348
349     if (sentDataLen != -1)
350     {
351         res = CA_STATUS_OK;
352     }
353     return res;
354 }
355
356 CAResult_t CASendMulticastData(const void *data, uint32_t length)
357 {
358     OIC_LOG(DEBUG, TAG, "Send multicast data to enabled interface..");
359
360     CAResult_t res = CA_SEND_FAILED;
361     u_arraylist_t *list = CAGetSelectedNetworkList();
362
363     if (!list)
364     {
365         OIC_LOG(DEBUG, TAG, "No selected network");
366         return CA_SEND_FAILED;
367     }
368
369     int i = 0;
370     for (i = 0; i < u_arraylist_length(list); i++)
371     {
372         void* ptrType = u_arraylist_get(list, i);
373
374         if(ptrType == NULL)
375         {
376             continue;
377         }
378
379         CATransportType_t connType = *(CATransportType_t *) ptrType;
380
381         int index = CAGetAdapterIndex(connType);
382
383         if (index == -1)
384         {
385             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
386             continue;
387         }
388
389         uint32_t sentDataLen = 0;
390
391         if (g_adapterHandler[index].sendDataToAll != NULL)
392         {
393             void *payload = (void *) OICMalloc(length);
394             if (!payload)
395             {
396                 OIC_LOG(ERROR, TAG, "Out of memory!");
397                 return CA_MEMORY_ALLOC_FAILED;
398             }
399             memcpy(payload, data, length);
400             sentDataLen = g_adapterHandler[index].sendDataToAll(payload, length);
401             OICFree(payload);
402         }
403
404         if (sentDataLen == length)
405         {
406            res = CA_STATUS_OK;
407         }
408         else
409         {
410             OIC_LOG(ERROR, TAG, "sendDataToAll failed!");
411         }
412     }
413
414     return res;
415 }
416
417 CAResult_t CAStartListeningServerAdapters()
418 {
419     OIC_LOG(DEBUG, TAG, "Start listening server from adapters..");
420
421     u_arraylist_t *list = CAGetSelectedNetworkList();
422     if (!list)
423     {
424         OIC_LOG(ERROR, TAG, "No selected network");
425         return CA_STATUS_FAILED;
426     }
427
428     int i = 0;
429     for (i = 0; i < u_arraylist_length(list); i++)
430     {
431         void* ptrType = u_arraylist_get(list, i);
432
433         if(ptrType == NULL)
434         {
435             continue;
436         }
437
438         CATransportType_t connType = *(CATransportType_t *) ptrType;
439
440         int index = CAGetAdapterIndex(connType);
441         if (index == -1)
442         {
443             OIC_LOG(ERROR, TAG, "unknown connectivity type!");
444             continue;
445         }
446
447         if (g_adapterHandler[index].startListenServer != NULL)
448         {
449             g_adapterHandler[index].startListenServer();
450         }
451     }
452
453     return CA_STATUS_OK;
454 }
455
456 CAResult_t CAStartDiscoveryServerAdapters()
457 {
458     OIC_LOG(DEBUG, TAG, "Start discovery server from adapters..");
459
460     u_arraylist_t *list = CAGetSelectedNetworkList();
461
462     if (!list)
463     {
464         OIC_LOG(ERROR, TAG, "No selected network");
465         return CA_STATUS_FAILED;
466     }
467
468     int i = 0;
469     for (i = 0; i < u_arraylist_length(list); i++)
470     {
471         void* ptrType = u_arraylist_get(list, i);
472
473         if(ptrType == NULL)
474         {
475             continue;
476         }
477
478         CATransportType_t connType = *(CATransportType_t *) ptrType;
479
480         int index = CAGetAdapterIndex(connType);
481
482         if (index == -1)
483         {
484             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
485             continue;
486         }
487
488         if (g_adapterHandler[index].startDiscoveryServer != NULL)
489         {
490             g_adapterHandler[index].startDiscoveryServer();
491         }
492     }
493
494     return CA_STATUS_OK;
495 }
496
497 void CATerminateAdapters()
498 {
499     OIC_LOG(DEBUG, TAG, "terminate all adapters..");
500
501     uint32_t index;
502     for (index = 0; index < CA_TRANSPORT_TYPE_NUM; index++)
503     {
504         if (g_adapterHandler[index].terminate != NULL)
505         {
506             g_adapterHandler[index].terminate();
507         }
508     }
509 }