wifi: Add capability to set regulatory domain through device's interface
[framework/connectivity/connman.git] / plugins / wifi.c
index 205fb95..0a842f9 100644 (file)
@@ -134,6 +134,9 @@ static void wifi_newlink(unsigned flags, unsigned change, void *user_data)
        struct connman_device *device = user_data;
        struct wifi_data *wifi = connman_device_get_data(device);
 
+       if (wifi == NULL)
+               return;
+
        DBG("index %d flags %d change %d", wifi->index, flags, change);
 
        if (!change)
@@ -402,6 +405,9 @@ static int throw_wifi_scan(struct connman_device *device,
        struct wifi_data *wifi = connman_device_get_data(device);
        int ret;
 
+       if (wifi == NULL)
+               return -ENODEV;
+
        DBG("device %p %p", device, wifi->interface);
 
        if (wifi->tethering == TRUE)
@@ -438,7 +444,7 @@ static void scan_callback(int result, GSupplicantInterface *interface,
        struct connman_device *device = user_data;
        struct wifi_data *wifi = connman_device_get_data(device);
 
-       DBG("result %d", result);
+       DBG("result %d wifi %p", result, wifi);
 
        if (wifi != NULL && wifi->hidden != NULL) {
                connman_network_clear_hidden(wifi->hidden->user_data);
@@ -461,7 +467,10 @@ static void scan_callback_hidden(int result,
        struct wifi_data *wifi = connman_device_get_data(device);
        int driver_max_ssids;
 
-       DBG("result %d", result);
+       DBG("result %d wifi %p", result, wifi);
+
+       if (wifi == NULL)
+               goto out;
 
        /*
         * Scan hidden networks so that we can autoconnect to them.
@@ -492,8 +501,7 @@ static void scan_callback_hidden(int result,
        }
 
 out:
-       connman_device_set_scanning(device, FALSE);
-       connman_device_unref(device);
+       scan_callback(result, interface, user_data);
 }
 
 static gboolean autoscan_timeout(gpointer data)
@@ -503,6 +511,9 @@ static gboolean autoscan_timeout(gpointer data)
        struct autoscan_params *autoscan;
        int interval;
 
+       if (wifi == NULL)
+               return FALSE;
+
        autoscan = wifi->autoscan;
 
        if (autoscan->interval <= 0) {
@@ -637,6 +648,9 @@ static int wifi_enable(struct connman_device *device)
 
        DBG("device %p %p", device, wifi);
 
+       if (wifi == NULL)
+               return -ENODEV;
+
        ret = g_supplicant_interface_create(interface, driver, NULL,
                                                interface_create_callback,
                                                        wifi);
@@ -651,7 +665,10 @@ static int wifi_disable(struct connman_device *device)
        struct wifi_data *wifi = connman_device_get_data(device);
        int ret;
 
-       DBG("device %p", device);
+       DBG("device %p wifi %p", device, wifi);
+
+       if (wifi == NULL)
+               return -ENODEV;
 
        wifi->connected = FALSE;
        wifi->disconnecting = FALSE;
@@ -819,6 +836,9 @@ static int wifi_scan_fast(struct connman_device *device)
        int ret;
        int driver_max_ssids = 0;
 
+       if (wifi == NULL)
+               return -ENODEV;
+
        DBG("device %p %p", device, wifi->interface);
 
        if (wifi->tethering == TRUE)
@@ -873,6 +893,9 @@ static int wifi_scan_hidden(struct connman_device *device,
        struct hidden_params *hidden;
        int ret;
 
+       if (wifi == NULL)
+               return -ENODEV;
+
        DBG("hidden SSID %s", ssid);
 
        if (wifi->tethering == TRUE || wifi->hidden != NULL)
@@ -930,6 +953,36 @@ static int wifi_scan_hidden(struct connman_device *device,
        return ret;
 }
 
+static void wifi_regdom_callback(int result,
+                                       const char *alpha2,
+                                               void *user_data)
+{
+       struct connman_device *device = user_data;
+
+       connman_device_regdom_notify(device, result, alpha2);
+
+       connman_device_unref(device);
+}
+
+static int wifi_set_regdom(struct connman_device *device, const char *alpha2)
+{
+       struct wifi_data *wifi = connman_device_get_data(device);
+       int ret;
+
+       if (wifi == NULL)
+               return -EINVAL;
+
+       connman_device_ref(device);
+
+       ret = g_supplicant_interface_set_country(wifi->interface,
+                                               wifi_regdom_callback,
+                                                       alpha2, device);
+       if (ret != 0)
+               connman_device_unref(device);
+
+       return ret;
+}
+
 static struct connman_device_driver wifi_ng_driver = {
        .name           = "wifi",
        .type           = CONNMAN_DEVICE_TYPE_WIFI,
@@ -941,6 +994,7 @@ static struct connman_device_driver wifi_ng_driver = {
        .scan           = wifi_scan,
        .scan_fast      = wifi_scan_fast,
        .scan_hidden    = wifi_scan_hidden,
+       .set_regdom     = wifi_set_regdom,
 };
 
 static void system_ready(void)
@@ -1857,21 +1911,22 @@ static int tech_set_tethering(struct connman_technology *technology,
        return -EOPNOTSUPP;
 }
 
-static void regdom_callback(void *user_data)
+static void regdom_callback(int result, const char *alpha2, void *user_data)
 {
-       char *alpha2 = user_data;
-
        DBG("");
 
        if (wifi_technology == NULL)
                return;
 
+       if (result != 0)
+               alpha2 = NULL;
+
        connman_technology_regdom_notify(wifi_technology, alpha2);
 }
 
 static int tech_set_regdom(struct connman_technology *technology, const char *alpha2)
 {
-       return g_supplicant_set_country(alpha2, regdom_callback, alpha2);
+       return g_supplicant_set_country(alpha2, regdom_callback, NULL);
 }
 
 static struct connman_technology_driver tech_driver = {