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