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