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 "cawifiinterface.h"
24 //#include <ifaddrs.h>
25 #include <arpa/inet.h>
29 #include "caadapterutils.h"
32 #include "oic_malloc.h"
33 #include "com_iotivity_jar_CAWiFiInterface.h"
35 #define WIFI_MONITOR_TAG "WIFI_MONITOR"
38 * @var nwConnectivityStatus
39 * @brief Maintains network status.
41 static CANetworkStatus_t nwConnectivityStatus;
44 * @var gWifiNetInfoMutex
45 * @brief Mutex for synchronizing access to cached interface and IP address information.
47 static u_mutex gWifiNetInfoMutex = NULL;
50 * @var gWifiInterfaceName
51 * @brief Maintains interface name.
53 static char *gWifiInterfaceName = NULL;
57 * @brief Maintains interface IP address.
59 static char *gWifiIPAddress = NULL;
63 * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter
65 static u_thread_pool_t gThreadPool = NULL;
68 * @var gStopNetworkMonitor
69 * @brief Flag to control the Network Monitor Thread
71 static bool gStopNetworkMonitor = false;
75 * @brief pointer to store JavaVM
77 static JavaVM *g_jvm = NULL;
81 * @brief pointer to store Application Context
83 static jobject g_context = NULL;
86 * @var gNetworkChangeCb
87 * @brief Maintains network connection state change callback.
89 static CAWiFiConnectionStateChangeCallback gNetworkChangeCb = NULL;
92 * @fn CAWiFiGetInterfaceInformation
93 * @brief Gets local interface name and IP address information.
95 static void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress);
98 * @fn CACreateWiFiJNIInterfaceObject
99 * @brief creates new instance of CAWiFiInterface through JNI
101 static void CACreateWiFiJNIInterfaceObject(jobject context);
104 * @fn CASendNetworkChangeCallback
105 * @brief updates network status to wifi adapter
107 void CASendNetworkChangeCallback(CANetworkStatus_t currNetworkStatus);
109 CAResult_t CAWiFiInitializeNetworkMonitor(const u_thread_pool_t threadPool)
111 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
113 gThreadPool = threadPool;
115 if (!gWifiNetInfoMutex)
117 gWifiNetInfoMutex = u_mutex_new();
120 CACreateWiFiJNIInterfaceObject(g_context);
122 u_mutex_lock(gWifiNetInfoMutex);
123 CAWiFiGetInterfaceInformation(&gWifiInterfaceName, &gWifiIPAddress);
124 u_mutex_unlock(gWifiNetInfoMutex);
126 nwConnectivityStatus = (gWifiIPAddress) ? CA_INTERFACE_UP : CA_INTERFACE_DOWN;
128 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
132 void CAWiFiTerminateNetworkMonitor(void)
134 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
138 if (gWifiInterfaceName)
140 OICFree(gWifiInterfaceName);
141 gWifiInterfaceName = NULL;
146 OICFree(gWifiIPAddress);
147 gWifiIPAddress = NULL;
150 if (gWifiNetInfoMutex)
152 u_mutex_free(gWifiNetInfoMutex);
153 gWifiNetInfoMutex = NULL;
156 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
159 CAResult_t CAWiFiStartNetworkMonitor(void)
161 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
163 u_mutex_lock(gWifiNetInfoMutex);
164 gStopNetworkMonitor = false;
165 u_mutex_unlock(gWifiNetInfoMutex);
167 if (gStopNetworkMonitor)
169 OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Network Monitor Thread is already running!");
170 return CA_SERVER_STARTED_ALREADY;
173 OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
177 CAResult_t CAWiFiStopNetworkMonitor(void)
179 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
181 if (gStopNetworkMonitor)
183 OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "CAWiFiStopNetworkMonitor, already stopped");
188 u_mutex_lock(gWifiNetInfoMutex);
189 gStopNetworkMonitor = true;
190 u_mutex_unlock(gWifiNetInfoMutex);
192 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
196 CAResult_t CAWiFiGetInterfaceInfo(char **interfaceName, char **ipAddress)
198 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
200 u_mutex_lock(gWifiNetInfoMutex);
202 if (gWifiInterfaceName && strlen(gWifiInterfaceName))
204 *interfaceName = (gWifiInterfaceName) ? strndup(gWifiInterfaceName, strlen(gWifiInterfaceName)) :
208 if (gWifiIPAddress && strlen(gWifiIPAddress))
210 *ipAddress = (gWifiIPAddress) ? strndup(gWifiIPAddress, strlen(gWifiIPAddress)) :
214 u_mutex_unlock(gWifiNetInfoMutex);
216 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
220 bool CAWiFiIsConnected(void)
222 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
224 if (nwConnectivityStatus == CA_INTERFACE_DOWN)
230 void CAWiFiSetConnectionStateChangeCallback(CAWiFiConnectionStateChangeCallback callback)
232 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
234 gNetworkChangeCb = callback;
237 void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress)
239 char buf[1024] = { 0, };
247 /* Get a socket handle. */
248 sck = socket(AF_INET, SOCK_DGRAM, 0);
254 /* Query available interfaces. */
255 ifc.ifc_len = sizeof(buf);
258 if (ioctl(sck, SIOCGIFCONF, &ifc) < 0)
264 /* Iterate through the list of interfaces. */
266 interfaces = ifc.ifc_len / sizeof(struct ifreq);
268 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "CAWiFiGetInterfaceInformation : %d", interfaces);
270 for (i = 0; i < interfaces; i++)
272 struct ifreq temp_ifr;
273 struct ifreq* item = &ifr[i];
275 memset(&temp_ifr, 0, sizeof(temp_ifr));
276 strcpy(temp_ifr.ifr_name, item->ifr_name);
278 if (ioctl((int)sck, SIOCGIFFLAGS, &temp_ifr))
280 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "CAWiFiGetInterfaceInformation, SIOCGIFFLAGS Failed");
284 if (!((temp_ifr.ifr_flags & IFF_UP) && (temp_ifr.ifr_flags & IFF_RUNNING)))
289 if(((struct sockaddr_in*) &item->ifr_addr)->sin_family != AF_INET)
294 char* ip = inet_ntoa(((struct sockaddr_in*) &item->ifr_addr)->sin_addr);
296 if(strcmp(ip, "127.0.0.1") == 0)
301 // set interface name
302 *interfaceName = strndup(item->ifr_name, strlen(item->ifr_name));
304 // set local ip address
305 *ipAddress = strndup(ip, strlen(ip));
307 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "ipAddress : %s, interfaceName : %s", *ipAddress, *interfaceName);
315 void CAWiFiJniInit(JavaVM* jvm)
317 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WIFICore] CAWiFiJniInit");
321 void CAJniSetContext(jobject context)
323 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "caWifiSetObject");
327 void CACreateWiFiJNIInterfaceObject(jobject context)
330 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WIFICore] CACreateWiFiJNIInterfaceObject");
332 if ((*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
334 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WIFICore] Could not get JNIEnv pointer");
338 //getApplicationContext
339 jclass contextClass = (*env)->FindClass(env, "android/content/Context");
340 if (contextClass == 0)
342 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WIFICore] Could not get context object class");
346 jmethodID getApplicationContextMethod = (*env)->GetMethodID(env, contextClass,
347 "getApplicationContext", "()Landroid/content/Context;");
348 if (getApplicationContextMethod == 0)
350 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WIFICore] Could not get getApplicationContext method");
354 jobject gApplicationContext = (*env)->CallObjectMethod(env, context, getApplicationContextMethod);
355 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WIFICore] Saving Android application context object %p", gApplicationContext);
357 //Create WiFiInterface instance
358 jclass WiFiJniInterface = (*env)->FindClass(env, "com/iotivity/jar/CAWiFiInterface");
359 if (!WiFiJniInterface)
361 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WIFICore] Could not get CAWiFiInterface class");
365 jmethodID WiFiInterfaceConstructorMethod = (*env)->GetMethodID(env,
366 WiFiJniInterface, "<init>", "(Landroid/content/Context;)V");
367 if (!WiFiInterfaceConstructorMethod)
369 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WIFICore] Could not get CAWiFiInterface constructor method");
373 (*env)->NewObject(env, WiFiJniInterface, WiFiInterfaceConstructorMethod, gApplicationContext);
374 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WIFICore]Create CAWiFiInterface instance");
375 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WIFICore] NewObject Successs");
379 void CASendNetworkChangeCallback(CANetworkStatus_t currNetworkStatus)
381 // Get network information
382 char *interfaceName = NULL;
383 char *ipAddress = NULL;
385 if (gStopNetworkMonitor)
387 OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "Stop Network Monitor Thread is called");
391 if(NULL == gNetworkChangeCb)
393 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WiFiCore] gNetworkChangeCb is NULL");
397 // if network status is changed
398 if (currNetworkStatus != nwConnectivityStatus)
400 CAWiFiGetInterfaceInformation(&interfaceName, &ipAddress);
402 // set current network information
403 u_mutex_lock(gWifiNetInfoMutex);
405 nwConnectivityStatus = currNetworkStatus;
407 gWifiInterfaceName = (interfaceName) ? strndup(interfaceName, strlen(interfaceName)) : NULL;
408 gWifiIPAddress = (ipAddress) ? strndup(ipAddress, strlen(ipAddress)) : NULL;
410 u_mutex_unlock(gWifiNetInfoMutex);
412 gNetworkChangeCb(gWifiIPAddress, nwConnectivityStatus);
414 OICFree(interfaceName);
418 JNIEXPORT void JNICALL Java_com_iotivity_jar_CAWiFiInterface_CAWiFiStateEnabled
419 (JNIEnv *env, jclass class)
421 CALocalConnectivity_t info;
423 CANetworkStatus_t currNetworkStatus = CA_INTERFACE_UP;
424 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WiFiCore] CAWiFiStateEnabled");
426 CASendNetworkChangeCallback(currNetworkStatus);
431 JNIEXPORT void JNICALL Java_com_iotivity_jar_CAWiFiInterface_CAWiFiStateDisabled
432 (JNIEnv *env, jclass class)
434 CALocalConnectivity_t info;
436 CANetworkStatus_t currNetworkStatus = CA_INTERFACE_DOWN;
437 OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WiFiCore] CAWiFiStateDisabled");
439 CASendNetworkChangeCallback(currNetworkStatus);