1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 ******************************************************************/
21 #include "caadapterutils.h"
25 #include "oic_string.h"
26 #include "oic_malloc.h"
30 #include <sys/socket.h>
31 #include <netinet/in.h>
39 #define CA_ADAPTER_UTILS_TAG "CA_ADAPTER_UTILS"
44 * @brief pointer to store JavaVM
46 static JavaVM *g_jvm = NULL;
50 * @brief pointer to store context for android callback interface
52 static jobject g_Context = NULL;
55 void CALogPDUData(coap_pdu_t *pdu)
57 VERIFY_NON_NULL_VOID(pdu, CA_ADAPTER_UTILS_TAG, "pdu");
58 OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - payload : %s", pdu->data);
60 OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - type : %d", pdu->hdr->type);
62 OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - code : %d", pdu->hdr->code);
64 OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - id : %d", pdu->hdr->id);
66 OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - token : %s", pdu->hdr->token);
68 CAEndpoint_t *CAAdapterCreateEndpoint(CATransportFlags_t flags,
69 CATransportAdapter_t adapter,
73 VERIFY_NON_NULL_RET(address, CA_ADAPTER_UTILS_TAG, "Endpoint is NULL", NULL);
74 CAEndpoint_t *info = (CAEndpoint_t *)OICCalloc(1, sizeof(CAEndpoint_t));
77 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
81 OICStrcpy(info->addr, sizeof(info->addr), address);
82 info->addr[MAX_ADDR_STR_SIZE_CA - 1] = '\0';
84 info->adapter = adapter;
90 CAEndpoint_t *CAAdapterCreateLocalEndpoint(CATransportFlags_t flags,
91 CATransportAdapter_t adapter, const char *address)
93 return CAAdapterCreateEndpoint(flags, adapter, address, 0);
96 CAResult_t CACreateEndpoint(CATransportFlags_t flags,
97 CATransportAdapter_t adapter,
100 CAEndpoint_t **object)
102 VERIFY_NON_NULL_RET(object, CA_ADAPTER_UTILS_TAG, "Endpoint is NULL", CA_STATUS_INVALID_PARAM);
103 CAEndpoint_t *endpoint = CAAdapterCreateEndpoint(flags, adapter, uri, port);
106 return CA_STATUS_FAILED;
113 CAEndpoint_t *CAAdapterCloneEndpoint(const CAEndpoint_t *endpoint)
115 VERIFY_NON_NULL_RET(endpoint, CA_ADAPTER_UTILS_TAG, "endpoint is NULL", NULL);
117 CAEndpoint_t *info = (CAEndpoint_t *)OICCalloc(1, sizeof (CAEndpoint_t));
120 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
128 void CAAdapterFreeEndpoint(CAEndpoint_t *remoteEndpoint)
130 OICFree(remoteEndpoint);
133 CAResult_t CAParseIPv4AddressInternal(const char *ipAddrStr, uint8_t *ipAddr,
134 size_t ipAddrLen, uint16_t *port)
136 if (!ipAddr || !isdigit(ipAddrStr[0]) || !port)
138 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "invalid param");
139 return CA_STATUS_INVALID_PARAM;
143 uint8_t dotCount = 0;
149 if (isdigit(*ipAddrStr))
151 if(index >= ipAddrLen)
153 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "invalid param");
154 return CA_STATUS_INVALID_PARAM;
157 ipAddr[index] += *ipAddrStr - '0';
159 else if (*ipAddrStr == '.')
172 if (*ipAddrStr == ':')
177 if (isdigit(*ipAddrStr))
180 *port += *ipAddrStr - '0';
194 return CA_STATUS_FAILED;
197 bool CAAdapterIsSameSubnet(const char *ipAddress1, const char *ipAddress2, const char *netMask)
199 VERIFY_NON_NULL_RET(ipAddress1, CA_ADAPTER_UTILS_TAG, "First address", false);
200 VERIFY_NON_NULL_RET(ipAddress2, CA_ADAPTER_UTILS_TAG, "Second address", false);
201 VERIFY_NON_NULL_RET(netMask, CA_ADAPTER_UTILS_TAG, "netMask", false);
203 uint8_t ipList1[IPV4_ADDR_ONE_OCTECT_LEN] = { 0 };
204 uint8_t ipList2[IPV4_ADDR_ONE_OCTECT_LEN] = { 0 };
205 uint8_t maskList[IPV4_ADDR_ONE_OCTECT_LEN] = { 0 };
206 CAResult_t ret = CA_STATUS_OK;
208 /* Local Loopback Address */
209 if (0 == strncmp(ipAddress1, "127.", 4) || 0 == strncmp(ipAddress2, "127.", 4))
214 uint16_t parsedPort = 0;
215 ret = CAParseIPv4AddressInternal(ipAddress1, ipList1, sizeof(ipList1), &parsedPort);
216 if (ret != CA_STATUS_OK)
218 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "First ip address parse fail %d", ret);
222 ret = CAParseIPv4AddressInternal(ipAddress2, ipList2, sizeof(ipList2), &parsedPort);
223 if (ret != CA_STATUS_OK)
225 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "Second ip address parse fail %d", ret);
229 ret = CAParseIPv4AddressInternal(netMask, maskList, sizeof(maskList), &parsedPort);
230 if (ret != CA_STATUS_OK)
232 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "Net mask parse fail %d", ret);
236 return ((ipList1[0] & maskList[0]) == (ipList2[0] & maskList[0])) && ((ipList1[1] & maskList[1])
237 == (ipList2[1] & maskList[1]))
238 && ((ipList1[2] & maskList[2]) == (ipList2[2] & maskList[2]))
239 && ((ipList1[3] & maskList[3]) == (ipList2[3] & maskList[3]));
242 bool CAIsMulticastServerStarted(const u_arraylist_t *serverInfoList, const char *ipAddress,
243 const char *multicastAddress, uint16_t port)
245 VERIFY_NON_NULL_RET(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null", false);
246 VERIFY_NON_NULL_RET(ipAddress, CA_ADAPTER_UTILS_TAG, "ipAddress is null", false);
247 VERIFY_NON_NULL_RET(multicastAddress, CA_ADAPTER_UTILS_TAG, "multicastAddress is null", false);
249 uint32_t listLength = u_arraylist_length(serverInfoList);
250 for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
252 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
255 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Info is NULL");
259 if (info->isMulticastServer && (strncmp(info->endpoint.addr, multicastAddress,
260 strlen(multicastAddress)) == 0)
261 && (info->endpoint.port == port) && (strncmp(info->ifAddr, ipAddress, strlen(ipAddress)) == 0))
263 return info->isServerStarted;
269 bool CAIsUnicastServerStarted(const u_arraylist_t *serverInfoList, const char *ipAddress,
272 VERIFY_NON_NULL_RET(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null", false);
273 VERIFY_NON_NULL_RET(ipAddress, CA_ADAPTER_UTILS_TAG, "ipAddress is null", false);
275 uint32_t listLength = u_arraylist_length(serverInfoList);
276 for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
278 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
284 if (!info->isMulticastServer && (strncmp(info->endpoint.addr, ipAddress,
285 strlen(ipAddress)) == 0)
286 && (info->endpoint.port == port))
288 return info->isServerStarted;
294 uint16_t CAGetServerPort(const u_arraylist_t *serverInfoList, const char *ipAddress, bool isSecured)
296 VERIFY_NON_NULL_RET(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null", 0);
297 VERIFY_NON_NULL_RET(ipAddress, CA_ADAPTER_UTILS_TAG, "ipAddress is null", 0);
299 uint32_t listLength = u_arraylist_length(serverInfoList);
300 for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
302 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
307 bool ifSecured = info->endpoint.flags & CA_SECURE;
308 if ((strncmp(info->endpoint.addr, ipAddress, strlen(ipAddress)) == 0) &&
309 (ifSecured == isSecured))
311 return info->endpoint.port;
318 int CAGetSocketFdForUnicastServer(const u_arraylist_t *serverInfoList,
319 bool isMulticast, const CAEndpoint_t *endpoint)
321 VERIFY_NON_NULL_RET(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null", -1);
322 VERIFY_NON_NULL_RET(endpoint, CA_ADAPTER_UTILS_TAG, "endpoint is null", -1);
324 bool isSecured = (endpoint->flags & CA_SECURE) != 0;
326 uint32_t listLength = u_arraylist_length(serverInfoList);
328 for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
330 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
336 if (!CAAdapterIsSameSubnet(info->endpoint.addr, endpoint->addr, info->subNetMask))
341 bool ifSecured = info->endpoint.flags & CA_SECURE;
342 if (!info->isMulticastServer && (ifSecured == isSecured))
344 OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG,
345 "CAGetSocketFdForServer found socket [%d]", info->socketFd);
346 return info->socketFd;
351 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG,
352 "CAGetSocketFdForServer socket fd is not found");
356 CAResult_t CAAddServerInfo(u_arraylist_t *serverInfoList, CAServerInfo_t *info)
358 VERIFY_NON_NULL(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null");
359 VERIFY_NON_NULL(info, CA_ADAPTER_UTILS_TAG, "info is null");
361 CAResult_t result = u_arraylist_add(serverInfoList, (void *) info);
362 if (CA_STATUS_OK != result)
364 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "u_arraylist_add failed!");
369 void CARemoveServerInfo(u_arraylist_t *serverInfoList, int sockFd)
371 VERIFY_NON_NULL_VOID(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null");
373 uint32_t listLength = u_arraylist_length(serverInfoList);
374 for (uint32_t listIndex = 0; listIndex < listLength;)
376 CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
383 if (info->socketFd == sockFd)
385 if (u_arraylist_remove(serverInfoList, listIndex))
392 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "u_arraylist_remove failed!");
403 void CAClearNetInterfaceInfoList(u_arraylist_t *infoList)
405 uint32_t listLength = u_arraylist_length(infoList);
406 for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
408 CANetInfo_t *netInfo = (CANetInfo_t *) u_arraylist_get(infoList, listIndex);
415 u_arraylist_free(&infoList);
418 void CAClearServerInfoList(u_arraylist_t *serverInfoList)
420 uint32_t listLength = u_arraylist_length(serverInfoList);
421 for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
423 CAServerInfo_t *serverInfo = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
430 u_arraylist_free(&serverInfoList);
435 * These two conversion functions return void because errors can't happen
436 * (because of NI_NUMERIC), and there's nothing to do if they do happen.
438 void CAConvertAddrToName(const struct sockaddr_storage *sockAddr, char *host, uint16_t *port)
440 VERIFY_NON_NULL_VOID(sockAddr, CA_ADAPTER_UTILS_TAG, "sockAddr is null");
441 VERIFY_NON_NULL_VOID(host, CA_ADAPTER_UTILS_TAG, "host is null");
442 VERIFY_NON_NULL_VOID(port, CA_ADAPTER_UTILS_TAG, "port is null");
444 int r = getnameinfo((struct sockaddr *)sockAddr,
445 sizeof (struct sockaddr_storage),
446 host, CA_IPADDR_SIZE,
448 NI_NUMERICHOST|NI_NUMERICSERV);
453 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
454 "getaddrinfo failed: errno %s", strerror(errno));
458 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
459 "getaddrinfo failed: %s", gai_strerror(r));
463 *port = ntohs(((struct sockaddr_in *)sockAddr)->sin_port); // IPv4 and IPv6
466 void CAConvertNameToAddr(const char *host, uint16_t port, struct sockaddr_storage *sockaddr)
468 VERIFY_NON_NULL_VOID(host, CA_ADAPTER_UTILS_TAG, "host is null");
469 VERIFY_NON_NULL_VOID(sockaddr, CA_ADAPTER_UTILS_TAG, "sockaddr is null");
471 struct addrinfo *addrs;
472 struct addrinfo hints = { 0 };
473 hints.ai_family = AF_UNSPEC;
474 hints.ai_socktype = SOCK_DGRAM;
475 hints.ai_flags = AI_NUMERICHOST;
477 int r = getaddrinfo(host, NULL, &hints, &addrs);
482 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
483 "getaddrinfo failed: errno %s", strerror(errno));
487 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
488 "getaddrinfo failed: %s", gai_strerror(r));
492 // assumption: in this case, getaddrinfo will only return one addrinfo
493 // or first is the one we want.
494 if (addrs[0].ai_family == AF_INET6)
496 memcpy(sockaddr, addrs[0].ai_addr, sizeof (struct sockaddr_in6));
497 ((struct sockaddr_in6 *)sockaddr)->sin6_port = htons(port);
501 memcpy(sockaddr, addrs[0].ai_addr, sizeof (struct sockaddr_in));
502 ((struct sockaddr_in *)sockaddr)->sin_port = htons(port);
506 #endif // WITH_ARDUINO
509 void CANativeJNISetContext(JNIEnv *env, jobject context)
511 OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "CANativeJNISetContext");
515 OIC_LOG(DEBUG, CA_ADAPTER_UTILS_TAG, "context is null");
519 g_Context = (*env)->NewGlobalRef(env, context);
522 void CANativeJNISetJavaVM(JavaVM *jvm)
524 OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "CANativeJNISetJavaVM");
528 jobject CANativeJNIGetContext()
533 JavaVM *CANativeJNIGetJavaVM()