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 "iotivity_config.h"
22 #include "caadapterutils.h"
26 #include "oic_string.h"
27 #include "oic_malloc.h"
30 #ifdef HAVE_WS2TCPIP_H
33 #ifdef HAVE_SYS_SOCKET_H
34 #include <sys/socket.h>
36 #ifdef HAVE_NETINET_IN_H
37 #include <netinet/in.h>
39 #if defined(HAVE_WINSOCK2_H) && defined(HAVE_WS2TCPIP_H)
51 #define CA_ADAPTER_UTILS_TAG "OIC_CA_ADAP_UTILS"
56 * @brief pointer to store JavaVM
58 static JavaVM *g_jvm = NULL;
62 * @brief pointer to store context for android callback interface
64 static jobject g_Context = NULL;
65 static jobject g_Activity = NULL;
69 CAResult_t CAParseIPv4AddressInternal(const char *ipAddrStr, uint8_t *ipAddr,
70 size_t ipAddrLen, uint16_t *port)
72 if (!ipAddr || !isdigit(ipAddrStr[0]) || !port)
74 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "invalid param");
75 return CA_STATUS_INVALID_PARAM;
85 if (isdigit(*ipAddrStr))
87 if(index >= ipAddrLen)
89 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "invalid param");
90 return CA_STATUS_INVALID_PARAM;
93 ipAddr[index] += *ipAddrStr - '0';
95 else if (*ipAddrStr == '.')
108 if (*ipAddrStr == ':')
113 if (isdigit(*ipAddrStr))
116 *port += *ipAddrStr - '0';
130 return CA_STATUS_FAILED;
133 #else // not with_arduino
135 * These two conversion functions return void because errors can't happen
136 * (because of NI_NUMERIC), and there's nothing to do if they do happen.
138 void CAConvertAddrToName(const struct sockaddr_storage *sockAddr, socklen_t sockAddrLen,
139 char *host, uint16_t *port)
141 VERIFY_NON_NULL_VOID(sockAddr, CA_ADAPTER_UTILS_TAG, "sockAddr is null");
142 VERIFY_NON_NULL_VOID(host, CA_ADAPTER_UTILS_TAG, "host is null");
143 VERIFY_NON_NULL_VOID(port, CA_ADAPTER_UTILS_TAG, "port is null");
145 int r = getnameinfo((struct sockaddr *)sockAddr,
147 host, MAX_ADDR_STR_SIZE_CA,
149 NI_NUMERICHOST|NI_NUMERICSERV);
152 #if defined(EAI_SYSTEM)
155 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
156 "getnameinfo failed: errno %s", strerror(errno));
160 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
161 "getnameinfo failed: %s", gai_strerror(r));
163 #elif defined(_WIN32)
164 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
165 "getnameinfo failed: errno %i", WSAGetLastError());
167 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
168 "getnameinfo failed: %s", gai_strerror(r));
172 *port = ntohs(((struct sockaddr_in *)sockAddr)->sin_port); // IPv4 and IPv6
175 void CAConvertNameToAddr(const char *host, uint16_t port, struct sockaddr_storage *sockaddr)
177 VERIFY_NON_NULL_VOID(host, CA_ADAPTER_UTILS_TAG, "host is null");
178 VERIFY_NON_NULL_VOID(sockaddr, CA_ADAPTER_UTILS_TAG, "sockaddr is null");
180 struct addrinfo *addrs = NULL;
181 struct addrinfo hints = { .ai_family = AF_UNSPEC,
182 .ai_socktype = SOCK_DGRAM,
183 .ai_flags = AI_NUMERICHOST };
185 int r = getaddrinfo(host, NULL, &hints, &addrs);
192 #if defined(EAI_SYSTEM)
195 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
196 "getaddrinfo failed: errno %s", strerror(errno));
200 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
201 "getaddrinfo failed: %s", gai_strerror(r));
203 #elif defined(_WIN32)
204 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
205 "getaddrinfo failed: errno %i", WSAGetLastError());
207 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG,
208 "getaddrinfo failed: %s", gai_strerror(r));
212 // assumption: in this case, getaddrinfo will only return one addrinfo
213 // or first is the one we want.
214 if (addrs[0].ai_family == AF_INET6)
216 memcpy(sockaddr, addrs[0].ai_addr, sizeof (struct sockaddr_in6));
217 ((struct sockaddr_in6 *)sockaddr)->sin6_port = htons(port);
221 memcpy(sockaddr, addrs[0].ai_addr, sizeof (struct sockaddr_in));
222 ((struct sockaddr_in *)sockaddr)->sin_port = htons(port);
226 #endif // WITH_ARDUINO
229 void CANativeJNISetContext(JNIEnv *env, jobject context)
231 OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "CANativeJNISetContext");
235 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "context is null");
241 g_Context = (*env)->NewGlobalRef(env, context);
245 OIC_LOG(INFO, CA_ADAPTER_UTILS_TAG, "context is already set");
249 void CANativeJNISetJavaVM(JavaVM *jvm)
251 OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "CANativeJNISetJavaVM");
255 jobject CANativeJNIGetContext()
260 JavaVM *CANativeJNIGetJavaVM()
265 void CANativeSetActivity(JNIEnv *env, jobject activity)
267 OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "CANativeSetActivity");
271 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "activity is null");
277 g_Activity = (*env)->NewGlobalRef(env, activity);
281 OIC_LOG(INFO, CA_ADAPTER_UTILS_TAG, "activity is already set");
285 jobject *CANativeGetActivity()
290 jmethodID CAGetJNIMethodID(JNIEnv *env, const char* className,
291 const char* methodName,
292 const char* methodFormat)
294 VERIFY_NON_NULL_RET(env, CA_ADAPTER_UTILS_TAG, "env", NULL);
295 VERIFY_NON_NULL_RET(className, CA_ADAPTER_UTILS_TAG, "className", NULL);
296 VERIFY_NON_NULL_RET(methodName, CA_ADAPTER_UTILS_TAG, "methodName", NULL);
297 VERIFY_NON_NULL_RET(methodFormat, CA_ADAPTER_UTILS_TAG, "methodFormat", NULL);
299 jclass jni_cid = (*env)->FindClass(env, className);
302 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "jni_cid [%s] is null", className);
303 CACheckJNIException(env);
307 jmethodID jni_midID = (*env)->GetMethodID(env, jni_cid, methodName, methodFormat);
310 OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "jni_midID [%s] is null", methodName);
311 CACheckJNIException(env);
312 (*env)->DeleteLocalRef(env, jni_cid);
316 (*env)->DeleteLocalRef(env, jni_cid);
320 bool CACheckJNIException(JNIEnv *env)
322 if ((*env)->ExceptionCheck(env))
324 (*env)->ExceptionDescribe(env);
325 (*env)->ExceptionClear(env);
331 void CADeleteGlobalReferences(JNIEnv *env)
335 (*env)->DeleteGlobalRef(env, g_Context);
341 (*env)->DeleteGlobalRef(env, g_Activity);
348 void CALogAdapterStateInfo(CATransportAdapter_t adapter, CANetworkStatus_t state)
350 OIC_LOG(DEBUG, CA_ADAPTER_UTILS_TAG, "CALogAdapterStateInfo");
351 OIC_LOG(DEBUG, ANALYZER_TAG, "=================================================");
352 CALogAdapterTypeInfo(adapter);
353 if (CA_INTERFACE_UP == state)
355 OIC_LOG(INFO, ANALYZER_TAG, "adapter status is changed to CA_INTERFACE_UP");
359 OIC_LOG(INFO, ANALYZER_TAG, "adapter status is changed to CA_INTERFACE_DOWN");
361 OIC_LOG(DEBUG, ANALYZER_TAG, "=================================================");
364 void CALogSendStateInfo(CATransportAdapter_t adapter,
365 const char *addr, uint16_t port, ssize_t sentLen,
366 bool isSuccess, const char* message)
368 OIC_LOG(DEBUG, CA_ADAPTER_UTILS_TAG, "CALogSendStateInfo");
369 OIC_LOG(DEBUG, ANALYZER_TAG, "=================================================");
371 if (true == isSuccess)
373 OIC_LOG_V(INFO, ANALYZER_TAG, "Send Success, sent length = [%zd]", sentLen);
377 OIC_LOG_V(INFO, ANALYZER_TAG, "Send Failure, error message = [%s]",
378 message != NULL ? message : "no message");
381 CALogAdapterTypeInfo(adapter);
382 OIC_LOG_V(INFO, ANALYZER_TAG, "Address = [%s]:[%d]", addr, port);
383 OIC_LOG(DEBUG, ANALYZER_TAG, "=================================================");
386 if (true == isSuccess)
388 OIC_LOG_V(INFO, CA_ADAPTER_UTILS_TAG, "| Analyzer(Retail) | %02x", 1);
392 OIC_LOG_V(INFO, CA_ADAPTER_UTILS_TAG, "| Analyzer(Retail) | %02x", 0);
396 void CALogAdapterTypeInfo(CATransportAdapter_t adapter)
401 OIC_LOG(INFO, ANALYZER_TAG, "Transport Type = [OC_ADAPTER_IP]");
404 OIC_LOG(INFO, ANALYZER_TAG, "Transport Type = [OC_ADAPTER_TCP]");
406 case CA_ADAPTER_GATT_BTLE:
407 OIC_LOG(INFO, ANALYZER_TAG, "Transport Type = [OC_ADAPTER_GATT_BTLE]");
409 case CA_ADAPTER_RFCOMM_BTEDR:
410 OIC_LOG(INFO, ANALYZER_TAG, "Transport Type = [OC_ADAPTER_RFCOMM_BTEDR]");
413 OIC_LOG_V(INFO, ANALYZER_TAG, "Transport Type = [%d]", adapter);