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"
29 #ifdef HAVE_WS2TCPIP_H
32 #ifdef HAVE_SYS_SOCKET_H
33 #include <sys/socket.h>
35 #ifdef HAVE_NETINET_IN_H
36 #include <netinet/in.h>
38 #if defined(HAVE_WINSOCK2_H) && defined(HAVE_WS2TCPIP_H)
50 #define CA_ADAPTER_UTILS_TAG "OIC_CA_ADAP_UTILS"
55 * @brief pointer to store JavaVM
57 static JavaVM *g_jvm = NULL;
61 * @brief pointer to store context for android callback interface
63 static jobject g_Context = NULL;
64 static jobject g_Activity = NULL;
68 CAResult_t CAParseIPv4AddressInternal(const char *ipAddrStr, uint8_t *ipAddr,
69 size_t ipAddrLen, uint16_t *port)
71 if (!ipAddr || !isdigit(ipAddrStr[0]) || !port)
73 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "invalid param");
74 return CA_STATUS_INVALID_PARAM;
84 if (isdigit(*ipAddrStr))
86 if(index >= ipAddrLen)
88 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "invalid param");
89 return CA_STATUS_INVALID_PARAM;
92 ipAddr[index] += *ipAddrStr - '0';
94 else if (*ipAddrStr == '.')
107 if (*ipAddrStr == ':')
112 if (isdigit(*ipAddrStr))
115 *port += *ipAddrStr - '0';
129 return CA_STATUS_FAILED;
132 #else // not with_arduino
134 * These two conversion functions return void because errors can't happen
135 * (because of NI_NUMERIC), and there's nothing to do if they do happen.
137 void CAConvertAddrToName(const struct sockaddr_storage *sockAddr, socklen_t sockAddrLen,
138 char *host, uint16_t *port)
140 VERIFY_NON_NULL_VOID(sockAddr, CA_ADAPTER_UTILS_TAG, "sockAddr is null");
141 VERIFY_NON_NULL_VOID(host, CA_ADAPTER_UTILS_TAG, "host is null");
142 VERIFY_NON_NULL_VOID(port, CA_ADAPTER_UTILS_TAG, "port is null");
144 int r = getnameinfo((struct sockaddr *)sockAddr,
146 host, MAX_ADDR_STR_SIZE_CA,
148 NI_NUMERICHOST|NI_NUMERICSERV);
151 #if defined(EAI_SYSTEM)
154 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
155 "getnameinfo failed: errno %s", strerror(errno));
159 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
160 "getnameinfo failed: %s", gai_strerror(r));
162 #elif defined(_WIN32)
163 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
164 "getnameinfo failed: errno %i", WSAGetLastError());
166 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
167 "getnameinfo failed: %s", gai_strerror(r));
171 *port = ntohs(((struct sockaddr_in *)sockAddr)->sin_port); // IPv4 and IPv6
174 void CAConvertNameToAddr(const char *host, uint16_t port, struct sockaddr_storage *sockaddr)
176 VERIFY_NON_NULL_VOID(host, CA_ADAPTER_UTILS_TAG, "host is null");
177 VERIFY_NON_NULL_VOID(sockaddr, CA_ADAPTER_UTILS_TAG, "sockaddr is null");
179 struct addrinfo *addrs = NULL;
180 struct addrinfo hints = { .ai_family = AF_UNSPEC,
181 .ai_socktype = SOCK_DGRAM,
182 .ai_flags = AI_NUMERICHOST };
184 int r = getaddrinfo(host, NULL, &hints, &addrs);
187 #if defined(EAI_SYSTEM)
190 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
191 "getaddrinfo failed: errno %s", strerror(errno));
195 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
196 "getaddrinfo failed: %s", gai_strerror(r));
198 #elif defined(_WIN32)
199 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
200 "getaddrinfo failed: errno %i", WSAGetLastError());
202 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
203 "getaddrinfo failed: %s", gai_strerror(r));
207 // assumption: in this case, getaddrinfo will only return one addrinfo
208 // or first is the one we want.
209 if (addrs[0].ai_family == AF_INET6)
211 memcpy(sockaddr, addrs[0].ai_addr, sizeof (struct sockaddr_in6));
212 ((struct sockaddr_in6 *)sockaddr)->sin6_port = htons(port);
216 memcpy(sockaddr, addrs[0].ai_addr, sizeof (struct sockaddr_in));
217 ((struct sockaddr_in *)sockaddr)->sin_port = htons(port);
221 #endif // WITH_ARDUINO
224 void CANativeJNISetContext(JNIEnv *env, jobject context)
226 OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "CANativeJNISetContext");
230 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "context is null");
236 g_Context = (*env)->NewGlobalRef(env, context);
240 OIC_LOG(INFO, CA_ADAPTER_UTILS_TAG, "context is already set");
244 void CANativeJNISetJavaVM(JavaVM *jvm)
246 OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "CANativeJNISetJavaVM");
250 jobject CANativeJNIGetContext()
255 JavaVM *CANativeJNIGetJavaVM()
260 void CANativeSetActivity(JNIEnv *env, jobject activity)
262 OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "CANativeSetActivity");
266 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "activity is null");
272 g_Activity = (*env)->NewGlobalRef(env, activity);
276 OIC_LOG(INFO, CA_ADAPTER_UTILS_TAG, "activity is already set");
280 jobject *CANativeGetActivity()
285 jmethodID CAGetJNIMethodID(JNIEnv *env, const char* className,
286 const char* methodName,
287 const char* methodFormat)
289 VERIFY_NON_NULL_RET(env, CA_ADAPTER_UTILS_TAG, "env", NULL);
290 VERIFY_NON_NULL_RET(className, CA_ADAPTER_UTILS_TAG, "className", NULL);
291 VERIFY_NON_NULL_RET(methodName, CA_ADAPTER_UTILS_TAG, "methodName", NULL);
292 VERIFY_NON_NULL_RET(methodFormat, CA_ADAPTER_UTILS_TAG, "methodFormat", NULL);
294 jclass jni_cid = (*env)->FindClass(env, className);
297 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "jni_cid [%s] is null", className);
301 jmethodID jni_midID = (*env)->GetMethodID(env, jni_cid, methodName, methodFormat);
304 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "jni_midID [%s] is null", methodName);
305 (*env)->DeleteLocalRef(env, jni_cid);
309 (*env)->DeleteLocalRef(env, jni_cid);
313 void CADeleteGlobalReferences(JNIEnv *env)
317 (*env)->DeleteGlobalRef(env, g_Context);
323 (*env)->DeleteGlobalRef(env, g_Activity);