Integrated WIFI/ETHERNET adapters to single IPAdapter.
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / adapter_util / caadapterutils.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 "caadapterutils.h"
22
23 #include <string.h>
24 #include <ctype.h>
25
26 #include "oic_malloc.h"
27 #include "oic_string.h"
28
29 #define CA_ADAPTER_UTILS_TAG "CA_ADAPTER_UTILS"
30
31 void CALogPDUData(coap_pdu_t *pdu)
32 {
33     VERIFY_NON_NULL_VOID(pdu, CA_ADAPTER_UTILS_TAG, "pdu");
34     OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - payload : %s", pdu->data);
35
36     OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - type : %d", pdu->hdr->type);
37
38     OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - code : %d", pdu->hdr->code);
39
40     OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - id : %d", pdu->hdr->id);
41
42     OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - token : %s", pdu->hdr->token);
43 }
44
45 CALocalConnectivity_t *CAAdapterCreateLocalEndpoint(CATransportType_t type, const char *address)
46 {
47     CALocalConnectivity_t *info = (CALocalConnectivity_t *)
48                                   OICCalloc(1, sizeof(CALocalConnectivity_t));
49     if (NULL == info)
50     {
51         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
52         return NULL;
53     }
54
55     info->type = type;
56     if (address && strlen(address))
57     {
58         if (CA_EDR == type)
59         {
60             strncpy(info->addressInfo.BT.btMacAddress, address, CA_MACADDR_SIZE - 1);
61             info->addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0';
62         }
63         else if (CA_LE == type)
64         {
65             strncpy(info->addressInfo.LE.leMacAddress, address, CA_MACADDR_SIZE - 1);
66             info->addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0';
67         }
68         else if (CA_IPV4 == type)
69         {
70             strncpy(info->addressInfo.IP.ipAddress, address, CA_IPADDR_SIZE - 1);
71             info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0';
72         }
73         else if (CA_IPV6 == type)
74         {
75             OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Currently IPV6 is not supported");
76             OICFree(info);
77             return NULL;
78         }
79         else
80         {
81             OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "type is not matched with any transport!");
82             OICFree(info);
83             return NULL;
84         }
85     }
86
87     return info;
88 }
89
90 CALocalConnectivity_t *CAAdapterCopyLocalEndpoint(const CALocalConnectivity_t *connectivity)
91 {
92     VERIFY_NON_NULL_RET(connectivity, CA_ADAPTER_UTILS_TAG, "connectivity is NULL", NULL);
93
94     CALocalConnectivity_t *info = (CALocalConnectivity_t *)
95                                   OICCalloc(1, sizeof(CALocalConnectivity_t));
96     if (NULL == info)
97     {
98         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
99         return NULL;
100     }
101
102     info->type = connectivity->type;
103     if (CA_EDR == info->type && strlen(connectivity->addressInfo.BT.btMacAddress))
104     {
105         strncpy(info->addressInfo.BT.btMacAddress, connectivity->addressInfo.BT.btMacAddress,
106                 CA_MACADDR_SIZE - 1);
107         info->addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0';
108     }
109     else if (CA_LE == info->type && strlen(connectivity->addressInfo.LE.leMacAddress))
110     {
111         strncpy(info->addressInfo.LE.leMacAddress, connectivity->addressInfo.LE.leMacAddress,
112                 CA_MACADDR_SIZE - 1);
113         info->addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0';
114     }
115     else if ((CA_IPV4 == info->type)
116
117             && strlen(connectivity->addressInfo.IP.ipAddress))
118     {
119         strncpy(info->addressInfo.IP.ipAddress, connectivity->addressInfo.IP.ipAddress,
120                 CA_IPADDR_SIZE - 1);
121         info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0';
122         info->addressInfo.IP.port = connectivity->addressInfo.IP.port;
123     }
124     else if (CA_IPV6 == info->type)
125     {
126         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Currently IPV6 is not supported");
127         OICFree(info);
128         return NULL;
129     }
130     else
131     {
132         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "type is not matched with any transport!");
133         OICFree(info);
134         return NULL;
135     }
136
137     info->isSecured = connectivity->isSecured;
138     return info;
139 }
140
141 void CAAdapterFreeLocalEndpoint(CALocalConnectivity_t *localEndpoint)
142 {
143     OICFree(localEndpoint);
144 }
145
146 CARemoteEndpoint_t *CAAdapterCreateRemoteEndpoint(CATransportType_t type, const char *address,
147                                                   const char *resourceUri)
148 {
149     CARemoteEndpoint_t *info = (CARemoteEndpoint_t *)
150                                OICCalloc(1, sizeof(CARemoteEndpoint_t));
151     if (NULL == info)
152     {
153         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
154         return NULL;
155     }
156
157     info->transportType = type;
158     if (address && strlen(address))
159     {
160         if (CA_EDR == type)
161         {
162             strncpy(info->addressInfo.BT.btMacAddress, address, CA_MACADDR_SIZE - 1);
163             info->addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0';
164         }
165         else if (CA_LE == type)
166         {
167             strncpy(info->addressInfo.LE.leMacAddress, address, CA_MACADDR_SIZE - 1);
168             info->addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0';
169         }
170         else if (CA_IPV4 == type)
171         {
172             strncpy(info->addressInfo.IP.ipAddress, address, CA_IPADDR_SIZE - 1);
173             info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0';
174         }
175         else if (CA_IPV6 == type)
176         {
177             OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Currently IPV6 is not supported");
178             OICFree(info);
179             return NULL;
180         }
181         else
182         {
183             OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "type is not matched with any transport!");
184             OICFree(info);
185             return NULL;
186         }
187     }
188
189     if (resourceUri && strlen(resourceUri))
190     {
191         info->resourceUri = OICStrdup(resourceUri);
192     }
193
194     return info;
195 }
196
197 CARemoteEndpoint_t *CAAdapterCopyRemoteEndpoint(const CARemoteEndpoint_t *remoteEndpoint)
198 {
199     VERIFY_NON_NULL_RET(remoteEndpoint, CA_ADAPTER_UTILS_TAG, "Remote endpoint is NULL", NULL);
200
201     CARemoteEndpoint_t *info = (CARemoteEndpoint_t *)
202                                OICCalloc(1, sizeof(CARemoteEndpoint_t));
203     if (NULL == info)
204     {
205         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
206         return NULL;
207     }
208
209     info->transportType = remoteEndpoint->transportType;
210     if (CA_EDR == info->transportType && ('\0' != remoteEndpoint->addressInfo.BT.btMacAddress[0]))
211     {
212         strncpy(info->addressInfo.BT.btMacAddress, remoteEndpoint->addressInfo.BT.btMacAddress,
213                 CA_MACADDR_SIZE - 1);
214         info->addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0';
215     }
216     else if (CA_LE == info->transportType
217              && ('\0' != remoteEndpoint->addressInfo.LE.leMacAddress[0]))
218     {
219         strncpy(info->addressInfo.LE.leMacAddress, remoteEndpoint->addressInfo.LE.leMacAddress,
220                 CA_MACADDR_SIZE - 1);
221         info->addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0';
222     }
223     else if ((CA_IPV4 == info->transportType)
224             && ('\0' != remoteEndpoint->addressInfo.IP.ipAddress[0]))
225     {
226         strncpy(info->addressInfo.IP.ipAddress, remoteEndpoint->addressInfo.IP.ipAddress,
227                 CA_IPADDR_SIZE - 1);
228         info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0';
229         info->addressInfo.IP.port = remoteEndpoint->addressInfo.IP.port;
230     }
231     else if (CA_IPV6 == info->transportType)
232     {
233         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Currently IPV6 is not supported");
234     }
235     else
236     {
237         OIC_LOG(DEBUG, CA_ADAPTER_UTILS_TAG, "Its not matching. May be multicast.");
238     }
239
240     //For Multicast, remote address will be null while resourceUri will have the service UUID
241
242     if (remoteEndpoint->resourceUri && strlen(remoteEndpoint->resourceUri))
243     {
244         info->resourceUri = OICStrdup(remoteEndpoint->resourceUri);
245     }
246
247     info->isSecured = remoteEndpoint->isSecured;
248     return info;
249 }
250
251 void CAAdapterFreeRemoteEndpoint(CARemoteEndpoint_t *remoteEndpoint)
252 {
253     if (remoteEndpoint)
254     {
255         OICFree(remoteEndpoint->resourceUri);
256         OICFree(remoteEndpoint);
257     }
258 }
259
260 CAResult_t CAParseIPv4AddressInternal(const char *ipAddrStr, uint8_t *ipAddr,
261                                    size_t ipAddrLen, uint16_t *port)
262 {
263     if (!ipAddr || !isdigit(ipAddrStr[0]) || !port)
264     {
265         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "invalid param");
266         return CA_STATUS_INVALID_PARAM;
267     }
268
269     size_t index = 0;
270     uint8_t dotCount = 0;
271
272     ipAddr[index] = 0;
273     *port = 0;
274     while (*ipAddrStr)
275     {
276         if (isdigit(*ipAddrStr))
277         {
278             if(index >= ipAddrLen)
279             {
280                 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "invalid param");
281                 return CA_STATUS_INVALID_PARAM;
282             }
283             ipAddr[index] *= 10;
284             ipAddr[index] += *ipAddrStr - '0';
285         }
286         else if (*ipAddrStr == '.')
287         {
288             index++;
289             dotCount++;
290             ipAddr[index] = 0;
291         }
292         else
293         {
294             break;
295         }
296         ipAddrStr++;
297     }
298
299     if (*ipAddrStr == ':')
300     {
301         ipAddrStr++;
302         while (*ipAddrStr)
303         {
304             if (isdigit(*ipAddrStr))
305             {
306                 *port *= 10;
307                 *port += *ipAddrStr - '0';
308             }
309             else
310             {
311                 break;
312             }
313             ipAddrStr++;
314         }
315     }
316
317     if (dotCount == 3)
318     {
319         return CA_STATUS_OK;
320     }
321     return CA_STATUS_FAILED;
322 }
323
324 bool CAAdapterIsSameSubnet(const char *ipAddress1, const char *ipAddress2, const char *netMask)
325 {
326     VERIFY_NON_NULL_RET(ipAddress1, CA_ADAPTER_UTILS_TAG, "First address", false);
327     VERIFY_NON_NULL_RET(ipAddress2, CA_ADAPTER_UTILS_TAG, "Second address", false);
328     VERIFY_NON_NULL_RET(netMask, CA_ADAPTER_UTILS_TAG, "netMask", false);
329
330     uint8_t ipList1[IPV4_ADDR_ONE_OCTECT_LEN] = { 0 };
331     uint8_t ipList2[IPV4_ADDR_ONE_OCTECT_LEN] = { 0 };
332     uint8_t maskList[IPV4_ADDR_ONE_OCTECT_LEN] = { 0 };
333     CAResult_t ret = CA_STATUS_OK;
334
335     /* Local Loopback Address */
336     if (0 == strncmp(ipAddress1, "127.", 4) || 0 == strncmp(ipAddress2, "127.", 4))
337     {
338         return true;
339     }
340
341     uint16_t parsedPort = 0;
342     ret = CAParseIPv4AddressInternal(ipAddress1, ipList1, sizeof(ipList1), &parsedPort);
343     if (ret != CA_STATUS_OK)
344     {
345         OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "First ip address parse fail %d", ret);
346         return false;
347     }
348
349     ret = CAParseIPv4AddressInternal(ipAddress2, ipList2, sizeof(ipList2), &parsedPort);
350     if (ret != CA_STATUS_OK)
351     {
352         OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "Second ip address parse fail %d", ret);
353         return false;
354     }
355
356     ret = CAParseIPv4AddressInternal(netMask, maskList, sizeof(maskList), &parsedPort);
357     if (ret != CA_STATUS_OK)
358     {
359         OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "Net mask parse fail %d", ret);
360         return false;
361     }
362
363     return ((ipList1[0] & maskList[0]) == (ipList2[0] & maskList[0])) && ((ipList1[1] & maskList[1])
364             == (ipList2[1] & maskList[1]))
365            && ((ipList1[2] & maskList[2]) == (ipList2[2] & maskList[2]))
366            && ((ipList1[3] & maskList[3]) == (ipList2[3] & maskList[3]));
367 }
368
369
370 bool CAIsMulticastServerStarted(const u_arraylist_t *serverInfoList, const char *ipAddress,
371                                 const char *multicastAddress, uint16_t port)
372 {
373     VERIFY_NON_NULL_RET(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null", false);
374     VERIFY_NON_NULL_RET(ipAddress, CA_ADAPTER_UTILS_TAG, "ipAddress is null", false);
375     VERIFY_NON_NULL_RET(multicastAddress, CA_ADAPTER_UTILS_TAG, "multicastAddress is null", false);
376
377     uint32_t listLength = u_arraylist_length(serverInfoList);
378     for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
379     {
380         CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
381         if (!info)
382         {
383             OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Info is NULL");
384             return false;
385         }
386
387         if (info->isMulticastServer && (strncmp(info->ipAddress, multicastAddress,
388                                                 strlen(multicastAddress) == 0))
389             && (info->port == port) && (strncmp(info->ifAddr, ipAddress, strlen(ipAddress)) == 0))
390         {
391             return info->isServerStarted;
392         }
393     }
394     return false;
395 }
396
397 bool CAIsUnicastServerStarted(const u_arraylist_t *serverInfoList, const char *ipAddress,
398                               uint16_t port)
399 {
400     VERIFY_NON_NULL_RET(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null", false);
401     VERIFY_NON_NULL_RET(ipAddress, CA_ADAPTER_UTILS_TAG, "ipAddress is null", false);
402
403     uint32_t listLength = u_arraylist_length(serverInfoList);
404     for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
405     {
406         CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
407         if (!info)
408         {
409             continue;
410         }
411
412         if (!info->isMulticastServer && (strncmp(info->ipAddress, ipAddress,
413                                                  strlen(ipAddress)) == 0)
414             && (info->port == port))
415         {
416             return info->isServerStarted;
417         }
418     }
419     return false;
420 }
421
422 uint16_t CAGetServerPort(const u_arraylist_t *serverInfoList, const char *ipAddress, bool isSecured)
423 {
424     VERIFY_NON_NULL_RET(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null", 0);
425     VERIFY_NON_NULL_RET(ipAddress, CA_ADAPTER_UTILS_TAG, "ipAddress is null", 0);
426
427     uint32_t listLength = u_arraylist_length(serverInfoList);
428     for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
429     {
430         CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
431         if (!info)
432         {
433             continue;
434         }
435         if ((strncmp(info->ipAddress, ipAddress, strlen(ipAddress)) == 0) &&
436                     (info->isSecured == isSecured))
437         {
438             return info->port;
439         }
440     }
441
442     return 0;
443 }
444
445 int CAGetSocketFdForUnicastServer(const u_arraylist_t *serverInfoList, const char *ipAddress,
446                                   bool isSecured, bool isMulticast, CATransportType_t type)
447 {
448     VERIFY_NON_NULL_RET(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null", -1);
449     VERIFY_NON_NULL_RET(ipAddress, CA_ADAPTER_UTILS_TAG, "ipAddress is null", -1);
450
451     uint32_t listLength = u_arraylist_length(serverInfoList);
452
453     for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
454     {
455         CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
456         if (!info)
457         {
458             continue;
459         }
460
461         if (!CAAdapterIsSameSubnet(info->ipAddress, ipAddress, info->subNetMask))
462         {
463             continue;
464         }
465
466         if (!info->isMulticastServer && (info->isSecured == isSecured))
467         {
468             OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG,
469                       "CAGetSocketFdForServer found socket [%d]", info->socketFd);
470             return info->socketFd;
471         }
472
473     }
474
475     OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG,
476             "CAGetSocketFdForServer socket fd is not found");
477     return -1;
478 }
479
480 CAResult_t CAAddServerInfo(u_arraylist_t *serverInfoList, CAServerInfo_t *info)
481 {
482     VERIFY_NON_NULL(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null");
483     VERIFY_NON_NULL(info, CA_ADAPTER_UTILS_TAG, "info is null");
484
485     CAResult_t result = u_arraylist_add(serverInfoList, (void *) info);
486     if (CA_STATUS_OK != result)
487     {
488         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "u_arraylist_add failed!");
489     }
490     return result;
491 }
492
493 void CARemoveServerInfo(u_arraylist_t *serverInfoList, int sockFd)
494 {
495     VERIFY_NON_NULL_VOID(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null");
496
497     uint32_t listLength = u_arraylist_length(serverInfoList);
498     for (uint32_t listIndex = 0; listIndex < listLength;)
499     {
500         CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
501         if (!info)
502         {
503             listIndex++;
504             continue;
505         }
506
507         if (info->socketFd == sockFd)
508         {
509             if (u_arraylist_remove(serverInfoList, listIndex))
510             {
511                 OICFree(info);
512                 listLength--;
513             }
514             else
515             {
516                 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "u_arraylist_remove failed!");
517                 break;
518             }
519         }
520         else
521         {
522             listIndex++;
523         }
524     }
525 }
526
527 void CAClearNetInterfaceInfoList(u_arraylist_t *infoList)
528 {
529     uint32_t listLength = u_arraylist_length(infoList);
530     for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
531     {
532         CANetInfo_t *netInfo = (CANetInfo_t *) u_arraylist_get(infoList, listIndex);
533         if (!netInfo)
534         {
535             continue;
536         }
537         OICFree(netInfo);
538     }
539     u_arraylist_free(&infoList);
540 }
541
542 void CAClearServerInfoList(u_arraylist_t *serverInfoList)
543 {
544     uint32_t listLength = u_arraylist_length(serverInfoList);
545     for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
546     {
547         CAServerInfo_t *serverInfo = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
548         if (!serverInfo)
549         {
550             continue;
551         }
552         OICFree(serverInfo);
553     }
554     u_arraylist_free(&serverInfoList);
555 }