00001
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <glib.h>
00030 #include <net/ethernet.h>
00031 #include <linux/socket.h>
00032 #include <gconf/gconf-client.h>
00033 #include <osso-ic-dbus.h>
00034
00035 #define DBUS_API_SUBJECT_TO_CHANGE
00036 #include <dbus/dbus.h>
00037 #include <eap-dbus.h>
00038 #include <wlancond-dbus.h>
00039 #ifdef USE_MCE_MODE
00040 #include <mce/dbus-names.h>
00041 #endif
00042 #include "log.h"
00043 #include "dbus.h"
00044 #include "dbus-helper.h"
00045 #include "dbus-handler.h"
00046 #include "common.h"
00047 #include "wpa.h"
00048
00049 #define WLANCOND_SHUTDOWN_DELAY 4 //4s
00050 #define WLANCOND_CONNECT_TIMEOUT 10 //10s
00051 #define WLANCOND_SCAN_TIMEOUT 8 //8s
00052 #define WLANCOND_RESCAN_DELAY 1
00053
00054
00055 static char *scan_name_cache = NULL;
00056 static char *connect_name_cache = NULL;
00057
00058 static int wlan_socket = -1;
00059
00060 struct wlan_status_t wlan_status;
00061
00062 static gboolean _flight_mode = FALSE;
00063 static gboolean power_down_after_scan = FALSE;
00064 static dbus_bool_t saved_inactivity = FALSE;
00065
00066
00067 static guint wlan_if_down_timer_id = 0;
00068 static guint wlan_connect_timer_id = 0;
00069
00070
00071 static guint powersave = WLANCOND_SHORT_CAM;
00072
00073 #define WLAN_PREFIX_STR "wlan"
00074
00078 int socket_open(void)
00079 {
00080 if (wlan_socket > 0)
00081 return wlan_socket;
00082
00083 wlan_socket = socket(AF_INET, SOCK_DGRAM, 0);
00084
00085 if (wlan_socket < 0)
00086 die("socket() failed");
00087
00088 return wlan_socket;
00089 }
00093 void init_iwreq(struct iwreq* req)
00094 {
00095 memset(req, 0, sizeof(struct iwreq));
00096 strncpy(req->ifr_name, wlan_status.ifname, IFNAMSIZ);
00097 }
00101 static int get_own_mac(void)
00102 {
00103 struct ifreq req;
00104
00105 memset(&req , 0, sizeof(req));
00106 memcpy(req.ifr_name, wlan_status.ifname, IFNAMSIZ);
00107
00108 if (ioctl(socket_open(), SIOCGIFHWADDR, &req) < 0)
00109 {
00110 return -1;
00111 }
00112
00113 memcpy(wlan_status.own_mac, req.ifr_hwaddr.sa_data, ETH_ALEN);
00114
00115 return 0;
00116 }
00117
00123 static gint get_gconf_int(const gchar* path)
00124 {
00125 GConfClient *client;
00126 GConfValue *gconf_value;
00127 GError *error = NULL;
00128 gint value = -1;
00129
00130 client = gconf_client_get_default();
00131 if (client == NULL) {
00132 return -1;
00133 }
00134
00135 gconf_value = gconf_client_get(client, path, &error);
00136
00137 g_object_unref(client);
00138
00139 if (error != NULL) {
00140 DLOG_ERR("Could not get setting:%s, error:%s", path,
00141 error->message);
00142
00143 g_clear_error(&error);
00144 return -1;
00145 }
00146
00147 if (gconf_value == NULL) {
00148 return -1;
00149 }
00150 if (gconf_value->type == GCONF_VALUE_INT) {
00151 value = gconf_value_get_int(gconf_value);
00152 DLOG_DEBUG("User selected value: %d", value);
00153 }
00154
00155 gconf_value_free(gconf_value);
00156 return value;
00157 }
00163 void update_own_ie(unsigned char* wpa_ie, guint wpa_ie_len)
00164 {
00165 g_free(wlan_status.wpa_ie.ie);
00166 wlan_status.wpa_ie.ie = wpa_ie;
00167 wlan_status.wpa_ie.ie_len = wpa_ie_len;
00168 }
00173 guint get_encryption_info(void)
00174 {
00175 guint auth_status = 0;
00176
00177 if (wlan_status.pairwise_cipher & CIPHER_SUITE_CCMP) {
00178 auth_status |= WLANCOND_WPA_AES;
00179 } else if (wlan_status.pairwise_cipher & CIPHER_SUITE_TKIP) {
00180 auth_status |= WLANCOND_WPA_TKIP;
00181 } else if (wlan_status.pairwise_cipher & CIPHER_SUITE_WEP40 ||
00182 wlan_status.pairwise_cipher & CIPHER_SUITE_WEP104) {
00183 auth_status |= WLANCOND_WEP;
00184 } else {
00185 auth_status |= WLANCOND_OPEN;
00186 }
00187 return auth_status;
00188 }
00189
00193 int init_dbus_handler(void)
00194 {
00195 if (get_own_mac() < 0) {
00196 DLOG_ERR("Could not get own MAC address");
00197 return -1;
00198 }
00199
00200 return 0;
00201 }
00205 int clean_dbus_handler(void)
00206 {
00207 if (wlan_socket > 0)
00208 close(wlan_socket);
00209 return 0;
00210 }
00215 void mode_change(const char *mode) {
00216
00217 DLOG_DEBUG("WLAN flight mode changed to \"%s\"", mode);
00218
00219 if (g_str_equal(mode, "flight")) {
00220 set_wlan_state(WLAN_NOT_INITIALIZED, DISCONNECTED_SIGNAL, FORCE_YES);
00221 _flight_mode = TRUE;
00222 }
00223 else if (g_str_equal(mode, "normal")) {
00224 _flight_mode = FALSE;
00225 }
00226 else {
00227 DLOG_ERR("Invalid mode \"%s\" passed to mode_change()", mode);
00228 }
00229 }
00234 #ifdef USE_MCE_MODE
00235 static DBusHandlerResult mode_change_dbus(DBusMessage *message) {
00236
00237 char *mode;
00238
00239 if (!dbus_message_get_args(message, NULL,
00240 DBUS_TYPE_STRING, &mode,
00241 DBUS_TYPE_INVALID)) {
00242 DLOG_ERR("Invalid arguments for device_mode_ind signal");
00243 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00244 }
00245
00246 mode_change(mode);
00247
00248 return DBUS_HANDLER_RESULT_HANDLED;
00249 }
00250 #ifdef ACTIVITY_CHECK
00251 static DBusHandlerResult activity_check_dbus(DBusMessage *message) {
00252
00253 if (!dbus_message_get_args(message, NULL,
00254 DBUS_TYPE_BOOLEAN, &saved_inactivity,
00255 DBUS_TYPE_INVALID)) {
00256 DLOG_ERR("Invalid arguments for device_activity signal");
00257 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00258 }
00259 activity_check(saved_inactivity);
00260
00261 return DBUS_HANDLER_RESULT_HANDLED;
00262 }
00263 #endif
00264 #endif
00265
00266 #ifdef ACTIVITY_CHECK
00267
00270 void activity_check(dbus_bool_t inactivity) {
00271
00272 int sock;
00273
00274 if (get_wlan_state() != WLAN_CONNECTED) {
00275 return;
00276 }
00277
00278 sock = socket_open();
00279
00280 if (inactivity == FALSE) {
00281
00282 } else {
00283
00284 }
00285
00286 set_power_state(powersave, sock);
00287 }
00288
00292 static gboolean get_inactivity_status(void)
00293 {
00294 return saved_inactivity;
00295 }
00296 #endif
00297
00302 static DBusHandlerResult icd_check_signal_dbus(DBusMessage *message) {
00303
00304 char *icd_name;
00305 char *icd_type;
00306 char *icd_state;
00307 char *icd_disconnect_reason;
00308 DBusError dbus_error;
00309
00310 if ((get_wlan_state() != WLAN_CONNECTED &&
00311 get_wlan_state() != WLAN_NO_ADDRESS) ||
00312 get_mode() != WLANCOND_INFRA) {
00313 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00314 }
00315
00316 dbus_error_init(&dbus_error);
00317 if (!dbus_message_get_args(message, &dbus_error,
00318 DBUS_TYPE_STRING, &icd_name,
00319 DBUS_TYPE_STRING, &icd_type,
00320 DBUS_TYPE_STRING, &icd_state,
00321 DBUS_TYPE_STRING, &icd_disconnect_reason,
00322 DBUS_TYPE_INVALID ) )
00323 {
00324 DLOG_ERR("Could not get args from signal, '%s'",
00325 dbus_error.message);
00326 dbus_error_free(&dbus_error);
00327 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00328 }
00329
00330 if (icd_state != NULL && strncmp(icd_state, "CONNECTED", 9) == 0) {
00331
00332 set_wlan_state(WLAN_CONNECTED, NO_SIGNAL, FORCE_NO);
00333
00334 DLOG_DEBUG("Going to power save");
00335
00336 if (set_power_state(powersave, socket_open()) == FALSE) {
00337 DLOG_ERR("Failed to set power save");
00338 }
00339
00340 }
00341
00342
00343
00344 return DBUS_HANDLER_RESULT_HANDLED;
00345 }
00346
00347 static gboolean in_flight_mode(void) {
00348 return _flight_mode;
00349 }
00350
00351 void set_wlan_signal(gboolean high_or_low)
00352 {
00353 if (high_or_low == WLANCOND_HIGH) {
00354 wlan_status.signal = WLANCOND_HIGH;
00355 remove_roam_scan_timer();
00356 } else {
00357 wlan_status.signal = WLANCOND_LOW;
00358 }
00359 }
00360
00361 void remove_roam_scan_timer(void)
00362 {
00363 if (wlan_status.roam_scan_id) {
00364 g_source_remove(wlan_status.roam_scan_id);
00365 wlan_status.roam_scan_id = 0;
00366 }
00367 }
00368
00369 void remove_connect_timer(void)
00370 {
00371 if (wlan_connect_timer_id) {
00372 g_source_remove(wlan_connect_timer_id);
00373 wlan_connect_timer_id = 0;
00374 }
00375 }
00376
00377 static void remove_wlan_if_timer(void)
00378 {
00379
00380 if (wlan_if_down_timer_id) {
00381 g_source_remove(wlan_if_down_timer_id);
00382 wlan_if_down_timer_id = 0;
00383 }
00384 }
00385
00386 void remove_scan_timer(void)
00387 {
00388 if (wlan_status.scan_id) {
00389 g_source_remove(wlan_status.scan_id);
00390 wlan_status.scan_id = 0;
00391 }
00392 }
00393
00399 static gboolean wlan_connect_timer_cb(void* data)
00400 {
00401 if (wlan_connect_timer_id && get_wlan_state() ==
00402 WLAN_INITIALIZED_FOR_CONNECTION) {
00403
00404 wlan_connect_timer_id = 0;
00405
00406 DLOG_DEBUG("Association timeout, try: %d",
00407 wlan_status.retry_count);
00408
00409
00410 remove_from_roam_cache(wlan_status.conn.bssid);
00411
00412
00413 memset(wlan_status.conn.bssid, 0, ETH_ALEN);
00414
00415 if (find_connection_and_associate(wlan_status.roam_cache,
00416 FALSE, FALSE) == 0)
00417 return FALSE;
00418
00419
00420 if (++wlan_status.retry_count < WLANCOND_MAX_SCAN_TRIES) {
00421 if (scan(wlan_status.conn.ssid,
00422 wlan_status.conn.ssid_len, FALSE) == 0) {
00423 return FALSE;
00424 }
00425 }
00426
00427 set_wlan_state(WLAN_NOT_INITIALIZED, DISCONNECTED_SIGNAL,
00428 FORCE_YES);
00429 return FALSE;
00430 }
00431
00432 wlan_connect_timer_id = 0;
00433
00434
00435
00436 return FALSE;
00437 }
00443 static gboolean wlan_scan_cb(void* data)
00444 {
00445
00446 wlan_status.scan_id = 0;
00447
00448 DLOG_ERR("Scan failed, should not happen!");
00449
00450 set_scan_state(SCAN_NOT_ACTIVE);
00451
00452 if (get_wlan_state() == WLAN_INITIALIZED_FOR_CONNECTION) {
00453 set_wlan_state(WLAN_NOT_INITIALIZED, DISCONNECTED_SIGNAL,
00454 FORCE_YES);
00455 }
00456
00457 return FALSE;
00458 }
00464 static gboolean wlan_if_down_cb(void* data)
00465 {
00466
00467 wlan_if_down_timer_id = 0;
00468
00469 if (get_wlan_state() == WLAN_NOT_INITIALIZED) {
00470 DLOG_DEBUG("Delayed shutdown occurred");
00471 set_wlan_state(WLAN_NOT_INITIALIZED, NO_SIGNAL, FORCE_YES);
00472 return FALSE;
00473 }
00474
00475
00476
00477 return FALSE;
00478 }
00486 int mlme_command(guchar* addr, guint16 cmd, guint16 reason_code)
00487 {
00488 struct iwreq req;
00489 struct iw_mlme mlme;
00490
00491 init_iwreq(&req);
00492
00493 DLOG_DEBUG("%s", cmd==IW_MLME_DEAUTH?"Deauthenticating":
00494 "Disassociating");
00495
00496 memset(&mlme, 0, sizeof(mlme));
00497
00498 mlme.cmd = cmd;
00499 mlme.reason_code = reason_code;
00500 mlme.addr.sa_family = ARPHRD_ETHER;
00501 memcpy(mlme.addr.sa_data, addr, ETH_ALEN);
00502
00503 req.u.data.pointer = (caddr_t) &mlme;
00504 req.u.data.length = sizeof(mlme);
00505
00506 if (ioctl(socket_open(), SIOCSIWMLME, &req) < 0) {
00507 DLOG_ERR("Failed to run MLME command");
00508 return -1;
00509 }
00510
00511 return 0;
00512 }
00516 static int set_mode(guint32 mode)
00517 {
00518 struct iwreq req;
00519
00520 init_iwreq(&req);
00521
00522 switch (mode) {
00523 case WLANCOND_ADHOC:
00524 req.u.mode = IW_MODE_ADHOC;
00525 DLOG_DEBUG("Setting mode: adhoc");
00526 break;
00527 case WLANCOND_INFRA:
00528 req.u.mode = IW_MODE_INFRA;
00529 DLOG_DEBUG("Setting mode: infra");
00530 break;
00531 default:
00532 DLOG_ERR("Operating mode undefined\n");
00533 return -1;
00534 }
00535
00536 if (ioctl(socket_open(), SIOCSIWMODE, &req) < 0) {
00537 DLOG_ERR("Operating mode setting failed\n");
00538 return -1;
00539 }
00540 return 0;
00541 }
00547 static int set_wep_keys(struct connect_params_t *conn)
00548 {
00549 struct iwreq req;
00550 guint nbr_of_keys = 0;
00551 int sock;
00552 guint i;
00553
00554 sock = socket_open();
00555
00556
00557 for (i=0;i<4;i++) {
00558 if(conn->key_len[i] == 0) {
00559 continue;
00560 } else {
00561 if (conn->key_len[i] < WLANCOND_MIN_KEY_LEN ||
00562 conn->key_len[i] > WLANCOND_MAX_KEY_LEN) {
00563 return -1;
00564 }
00565
00566 init_iwreq(&req);
00567 req.u.data.length = conn->key_len[i];
00568 req.u.data.pointer = (caddr_t) &conn->key[i][0];
00569 req.u.data.flags |= IW_ENCODE_RESTRICTED;
00570 req.u.encoding.flags = i+1;
00571 nbr_of_keys++;
00572 }
00573 #define DEBUG_KEY
00574 #ifdef DEBUG_KEY
00575 int k;
00576 unsigned char* p = &conn->key[i][0];
00577 for (k=0;k<conn->key_len[i];k++) {
00578 DLOG_DEBUG("Key %d, 0x%02x\n", i, *(p+k));
00579 }
00580 #endif
00581 if (ioctl(sock, SIOCSIWENCODE, &req) < 0) {
00582 DLOG_ERR("Set encode failed\n");
00583 return -1;
00584 }
00585
00586 }
00587
00588 if (nbr_of_keys) {
00589
00590 DLOG_DEBUG("Default key: %d\n", conn->default_key);
00591
00592 init_iwreq(&req);
00593
00594
00595 req.u.encoding.flags = conn->default_key;
00596
00597 if (ioctl(sock, SIOCSIWENCODE, &req) < 0) {
00598 DLOG_ERR("Set encode failed\n");
00599 return -1;
00600 }
00601 }
00602
00603 return 0;
00604 }
00605
00612 int set_essid(char* essid, int essid_len)
00613 {
00614 struct iwreq req;
00615
00616 DLOG_DEBUG("Setting SSID: %s", essid);
00617
00618 init_iwreq(&req);
00619
00620 req.u.essid.pointer = (caddr_t)essid;
00621 req.u.essid.length = essid_len -1;
00622 req.u.essid.flags = 1;
00623
00624 if (ioctl(socket_open(), SIOCSIWESSID, &req) < 0) {
00625 DLOG_ERR("set ESSID failed");
00626 return -1;
00627 }
00628 return 0;
00629 }
00635 int set_bssid(unsigned char *bssid)
00636 {
00637 struct iwreq req;
00638
00639 print_mac("Setting BSSID", bssid);
00640
00641 init_iwreq(&req);
00642
00643 req.u.ap_addr.sa_family = ARPHRD_ETHER;
00644
00645 memcpy(req.u.ap_addr.sa_data, bssid, ETH_ALEN);
00646
00647 if (ioctl(socket_open(), SIOCSIWAP, &req) < 0) {
00648 DLOG_ERR("Failed to set BSSID");
00649 return -1;
00650 }
00651 return 0;
00652 }
00653
00660 void set_wlan_state(int new_state, int send_signal, force_t force)
00661 {
00662 const char *status_table[] =
00663 {
00664 (char*)"WLAN_NOT_INITIALIZED",
00665 (char*)"WLAN_INITIALIZED",
00666 (char*)"WLAN_INITIALIZED_FOR_SCAN",
00667 (char*)"WLAN_INITIALIZED_FOR_CONNECTION",
00668 (char*)"WLAN_NO_ADDRESS",
00669 (char*)"WLAN_CONNECTED"
00670 };
00671
00672 switch (new_state) {
00673
00674 case WLAN_NOT_INITIALIZED:
00675
00676 if (wlan_status.state == WLAN_CONNECTED ||
00677 wlan_status.state == WLAN_NO_ADDRESS) {
00678
00679 mlme_command(wlan_status.conn.bssid,
00680 IW_MLME_DEAUTH,
00681 WLANCOND_REASON_LEAVING);
00682 set_bssid(NULL_BSSID);
00683 set_essid((char*)"", 1);
00684 }
00685
00686 set_scan_state(SCAN_NOT_ACTIVE);
00687
00688 if (get_wlan_state() != WLAN_NOT_INITIALIZED &&
00689 get_wlan_state() != WLAN_INITIALIZED_FOR_SCAN)
00690 clear_wpa_mode();
00691
00692 wlan_status.retry_count = 0;
00693 wlan_status.roam_scan = WLANCOND_MIN_ROAM_SCAN_INTERVAL;
00694 wlan_status.ip_ok = FALSE;
00695
00696
00697 remove_connect_timer();
00698
00699
00700 remove_scan_timer();
00701
00702 set_wlan_signal(WLANCOND_HIGH);
00703
00704
00705 remove_wlan_if_timer();
00706
00707 if (force == FORCE_YES) {
00708
00709 clean_roam_cache();
00710
00711 if (set_interface_state(socket_open(), CLEAR,
00712 IFF_UP)<0) {
00713 DLOG_ERR("Could not set interface down");
00714 return;
00715 }
00716
00717 } else {
00718
00719 DLOG_DEBUG("Delaying interface shutdown");
00720
00721
00722
00723
00724
00725 wlan_if_down_timer_id = g_timeout_add_seconds(
00726 WLANCOND_SHUTDOWN_DELAY,
00727 wlan_if_down_cb,
00728 NULL);
00729
00730 }
00731
00732 if (send_signal == DISCONNECTED_SIGNAL)
00733 disconnected_signal();
00734
00735 break;
00736 case WLAN_INITIALIZED_FOR_CONNECTION:
00737
00738
00739
00740
00741 memset(wlan_status.conn.bssid, 0, ETH_ALEN);
00742
00743
00744 remove_connect_timer();
00745 break;
00746 case WLAN_CONNECTED:
00747 wlan_status.ip_ok = TRUE;
00748 break;
00749 default:
00750 break;
00751 }
00752 DLOG_DEBUG("Wlancond state change, old_state: %s, new_state: %s",
00753 status_table[wlan_status.state], status_table[new_state]);
00754 wlan_status.state = new_state;
00755 }
00756
00761 guint get_wlan_state(void)
00762 {
00763 return wlan_status.state;
00764 }
00765
00770 void set_scan_state(guint new_state)
00771 {
00772 if (wlan_status.scan == new_state) {
00773 return;
00774 }
00775 if (new_state == SCAN_NOT_ACTIVE && wlan_status.scan == SCAN_ACTIVE &&
00776 scan_name_cache != NULL) {
00777 remove_scan_timer();
00778 DLOG_DEBUG("Sending empty results");
00779 send_dbus_scan_results(NULL, scan_name_cache, 0);
00780 g_free(scan_name_cache);
00781 scan_name_cache = NULL;
00782 }
00783
00784 DLOG_DEBUG("Wlancond scan change, old_state: %s, new_state: %s",
00785 wlan_status.scan==SCAN_NOT_ACTIVE ? "SCAN_IDLE":"SCANNING",
00786 new_state == SCAN_NOT_ACTIVE ? "SCAN_IDLE":"SCANNING");
00787 wlan_status.scan = new_state;
00788 }
00789
00794 guint get_scan_state(void)
00795 {
00796 return wlan_status.scan;
00797 }
00802 guint get_mode(void)
00803 {
00804 return wlan_status.conn.mode;
00805 }
00806
00813 gboolean set_power_state(guint new_state, int sock)
00814 {
00815 struct iwreq req;
00816 gint sleep_timeout;
00817
00818 if (new_state == WLANCOND_SHORT_CAM && get_inactivity_status() == TRUE)
00819 new_state = WLANCOND_VERY_SHORT_CAM;
00820
00821 if (wlan_status.power == new_state) {
00822 return TRUE;
00823 }
00824
00825 init_iwreq(&req);
00826
00827 switch (new_state) {
00828 case WLANCOND_POWER_ON:
00829 req.u.power.disabled = 1;
00830 break;
00831 case WLANCOND_LONG_CAM:
00832 req.u.power.flags = IW_POWER_TIMEOUT | IW_POWER_ALL_R;
00833 req.u.power.value = WLANCOND_LONG_CAM_TIMEOUT;
00834 break;
00835 case WLANCOND_SHORT_CAM:
00836 req.u.power.flags = IW_POWER_TIMEOUT | IW_POWER_ALL_R;
00837 sleep_timeout = get_gconf_int(SLEEP_GCONF_PATH);
00838 if (sleep_timeout < 0)
00839 sleep_timeout = WLANCOND_DEFAULT_SLEEP_TIMEOUT;
00840 req.u.power.value = sleep_timeout;
00841 break;
00842 case WLANCOND_VERY_SHORT_CAM:
00843 req.u.power.flags = IW_POWER_TIMEOUT | IW_POWER_ALL_R ;
00844 sleep_timeout = get_gconf_int(INACTIVE_SLEEP_GCONF_PATH);
00845 if (sleep_timeout < 0)
00846 sleep_timeout = WLANCOND_VERY_SHORT_CAM_TIMEOUT;
00847 req.u.power.value = sleep_timeout;
00848 break;
00849 default:
00850 req.u.power.flags = IW_POWER_ALL_R;
00851 break;
00852 }
00853
00854 if (ioctl(sock, SIOCSIWPOWER, &req) < 0) {
00855 DLOG_ERR("set power failed, state:%d", new_state);
00856 return FALSE;
00857 }
00858
00859 if (req.u.power.value) {
00860 DLOG_DEBUG("CAM timeout: %d ms", req.u.power.value / 1000);
00861 }
00862
00863 wlan_status.power = new_state;
00864
00865 return TRUE;
00866 }
00867
00868
00874 static int init_if(int sock)
00875 {
00876 int previous_state = get_wlan_state();
00877
00878 if (previous_state == WLAN_NOT_INITIALIZED) {
00879
00880 if (wlan_if_down_timer_id == 0) {
00881 if (set_interface_state(sock, SET,
00882 IFF_UP | IFF_RUNNING) < 0) {
00883 return -1;
00884 }
00885 }
00886 set_power_state(WLANCOND_POWER_ON, sock);
00887 set_wlan_state(WLAN_INITIALIZED, NO_SIGNAL, FORCE_YES);
00888 }
00889
00890 return previous_state;
00891 }
00892
00901 static int set_we_name(int sock, char *name, char *args[], int count)
00902 {
00903 struct iwreq req;
00904
00905 memset(&req, 0, sizeof(req));
00906 strncpy(req.ifr_name, name, IFNAMSIZ);
00907
00908 if (ioctl(sock, SIOCGIWNAME, &req) < 0) {
00909
00910 } else {
00911
00912 if (g_str_has_prefix(name, WLAN_PREFIX_STR)) {
00913 DLOG_DEBUG("Found WLAN interface %s", name);
00914 memcpy(&wlan_status.ifname, name, IFNAMSIZ);
00915 wlan_status.ifname[IFNAMSIZ] = '\0';
00916 }
00917 }
00918
00919 return 0;
00920 }
00926 int get_we_device_name(void)
00927 {
00928 memset(&wlan_status, 0, sizeof(wlan_status));
00929
00930 iw_enum_devices(socket_open(), &set_we_name, NULL, 0);
00931
00932 if (strnlen(wlan_status.ifname, IFNAMSIZ) < 2)
00933 return -1;
00934
00935 return 0;
00936 }
00944 int set_interface_state(int sock, int dir, short flags)
00945 {
00946 struct ifreq ifr;
00947
00948 memset(&ifr, 0, sizeof(ifr));
00949
00950 strncpy(ifr.ifr_name, wlan_status.ifname, IFNAMSIZ);
00951
00952 if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
00953 DLOG_ERR("Could not get interface %s flags\n",
00954 wlan_status.ifname);
00955 return -1;
00956 }
00957 if (dir == SET) {
00958 ifr.ifr_flags |= flags;
00959 } else {
00960 ifr.ifr_flags &= ~flags;
00961 }
00962
00963 if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
00964 DLOG_ERR("Could not set interface %s flags\n",
00965 wlan_status.ifname);
00966 return -1;
00967 }
00968
00969 DLOG_DEBUG("%s is %s", wlan_status.ifname, dir == SET ? "UP":"DOWN");
00970
00971 return 0;
00972 }
00973
00980 static gboolean set_tx_power(guint power, int sock)
00981 {
00982 struct iwreq req;
00983 init_iwreq(&req);
00984
00985 req.u.txpower.fixed = 1;
00986 req.u.txpower.disabled = 0;
00987 req.u.txpower.flags = IW_TXPOW_DBM;
00988
00989 if (power == WLANCOND_TX_POWER10) {
00990 req.u.txpower.value = WLANCOND_TX_POWER10DBM;
00991 } else if (power == WLANCOND_TX_POWER100) {
00992 req.u.txpower.value = WLANCOND_TX_POWER100DBM;
00993 } else {
00994 return FALSE;
00995 }
00996
00997 if (ioctl(sock, SIOCSIWTXPOW, &req) < 0) {
00998 DLOG_ERR("set power failed\n");
00999 return FALSE;
01000 }
01001 return TRUE;
01002
01003 }
01009 static int update_algorithms(guint32 encryption)
01010 {
01011 wlan_status.group_cipher = 0;
01012 wlan_status.pairwise_cipher = 0;
01013
01014
01015 if ((encryption & WLANCOND_ENCRYPT_METHOD_MASK) == WLANCOND_OPEN) {
01016 DLOG_DEBUG("Open mode");
01017 wlan_status.pairwise_cipher = CIPHER_SUITE_NONE;
01018 return 0;
01019 }
01020
01021
01022 if ((encryption & WLANCOND_ENCRYPT_METHOD_MASK) == WLANCOND_WEP) {
01023 DLOG_DEBUG("WEP enabled");
01024 wlan_status.pairwise_cipher = CIPHER_SUITE_WEP40;
01025 return 0;
01026 }
01027
01028
01029 if ((encryption & WLANCOND_ENCRYPT_ALG_MASK)
01030 == WLANCOND_WPA_TKIP) {
01031 DLOG_DEBUG("TKIP Selected for unicast");
01032 wlan_status.pairwise_cipher = CIPHER_SUITE_TKIP;
01033 } else if ((encryption & WLANCOND_ENCRYPT_ALG_MASK) ==
01034 WLANCOND_WPA_AES) {
01035 DLOG_DEBUG("AES selected for unicast");
01036 wlan_status.pairwise_cipher = CIPHER_SUITE_CCMP;
01037
01038 } else {
01039 DLOG_ERR("Not supported encryption %08x", encryption);
01040 return -1;
01041 }
01042
01043 if ((encryption & WLANCOND_ENCRYPT_GROUP_ALG_MASK) ==
01044 WLANCOND_WPA_TKIP_GROUP) {
01045 DLOG_DEBUG("TKIP Selected for multicast");
01046 wlan_status.group_cipher = CIPHER_SUITE_TKIP;
01047 } else if ((encryption & WLANCOND_ENCRYPT_GROUP_ALG_MASK) ==
01048 (unsigned int)WLANCOND_WPA_AES_GROUP) {
01049 DLOG_DEBUG("AES Selected for multicast");
01050 wlan_status.group_cipher = CIPHER_SUITE_CCMP;
01051 } else {
01052 DLOG_ERR("Not supported encryption %08x", encryption);
01053 return -1;
01054 }
01055
01056 return 0;
01057 }
01061 void clean_roam_cache(void)
01062 {
01063 clean_scan_results(&wlan_status.roam_cache);
01064 }
01068 void clear_wpa_mode(void)
01069 {
01070 g_free(wlan_status.wpa_ie.ie);
01071 wlan_status.wpa_ie.ie_len = 0;
01072 wlan_status.wpa_ie.ie = NULL;
01073
01074 wlan_status.pairwise_cipher = CIPHER_SUITE_NONE;
01075 wlan_status.group_cipher = CIPHER_SUITE_NONE;
01076
01077
01078 clear_wpa_keys(NULL);
01079
01080 g_slist_foreach(wlan_status.pmk_cache, (GFunc)g_free, NULL);
01081 g_slist_free(wlan_status.pmk_cache);
01082 wlan_status.pmk_cache = NULL;
01083 }
01088 gboolean get_wpa_mode(void)
01089 {
01090 if (wlan_status.pairwise_cipher & CIPHER_SUITE_TKIP ||
01091 wlan_status.pairwise_cipher & CIPHER_SUITE_CCMP) {
01092 return TRUE;
01093 }
01094 return FALSE;
01095 }
01096
01097 static gint compare_pmk_entry(gconstpointer a, gconstpointer b)
01098 {
01099 const struct pmksa_cache_t *pmk_cache = a;
01100
01101 return memcmp(pmk_cache->mac, b, ETH_ALEN);
01102 }
01103
01109 static void add_to_pmksa_cache(unsigned char* pmkid, unsigned char* mac)
01110 {
01111 guint i = 0;
01112 GSList *list;
01113 gboolean entry_found = FALSE;
01114
01115 for (list = wlan_status.pmk_cache; list != NULL && entry_found == FALSE; list = list->next) {
01116 struct pmksa_cache_t *pmk_cache = list->data;
01117
01118 if (memcmp(pmk_cache->mac, mac, ETH_ALEN) == 0) {
01119 DLOG_DEBUG("Found old entry: %i", i);
01120
01121 wlan_status.pmk_cache = g_slist_remove(wlan_status.pmk_cache, pmk_cache);
01122 g_free(pmk_cache);
01123
01124 entry_found = TRUE;
01125 } else {
01126 i++;
01127 }
01128 }
01129
01130 if (i == PMK_CACHE_SIZE) {
01131 DLOG_DEBUG("Cache full, remove oldest");
01132 GSList *last_entry = g_slist_last(wlan_status.pmk_cache);
01133 wlan_status.pmk_cache = g_slist_remove(wlan_status.pmk_cache, last_entry->data);
01134 g_free(last_entry->data);
01135 }
01136 print_mac("Adding new entry:", mac);
01137
01138 struct pmksa_cache_t *new_entry = g_malloc(sizeof(*new_entry));
01139 memcpy(new_entry->mac, mac, ETH_ALEN);
01140 memcpy(new_entry->pmkid, pmkid, IW_PMKID_LEN);
01141
01142 wlan_status.pmk_cache = g_slist_prepend(wlan_status.pmk_cache, new_entry);
01143 return;
01144 }
01150 unsigned char* find_pmkid_from_pmk_cache(unsigned char* mac)
01151 {
01152 GSList *list;
01153
01154 list = g_slist_find_custom(wlan_status.pmk_cache, mac, &compare_pmk_entry);
01155 if (list != NULL) {
01156 struct pmksa_cache_t *pmk_cache = list->data;
01157 print_mac("Found PMKSA entry for:", mac);
01158 return pmk_cache->pmkid;
01159 }
01160 return NULL;
01161 }
01162
01169 int scan(gchar *ssid, int ssid_len, gboolean add_timer)
01170 {
01171 struct iwreq req;
01172 struct iw_scan_req scan_req;
01173
01174 if (get_scan_state() == SCAN_ACTIVE)
01175 return 0;
01176
01177 set_scan_state(SCAN_ACTIVE);
01178
01179 init_iwreq(&req);
01180
01181 memset(&scan_req, 0, sizeof(scan_req));
01182
01183 if (ssid_len > 1 && ssid != NULL) {
01184
01185 scan_req.essid_len = ssid_len -1;
01186 scan_req.bssid.sa_family = ARPHRD_ETHER;
01187 memset(scan_req.bssid.sa_data, 0xff, ETH_ALEN);
01188 memcpy(scan_req.essid, ssid, ssid_len -1);
01189 req.u.data.pointer = (caddr_t) &scan_req;
01190 req.u.data.length = sizeof(scan_req);
01191 req.u.data.flags = IW_SCAN_THIS_ESSID;
01192 }
01193
01194 if (ioctl(socket_open(), SIOCSIWSCAN, &req) < 0) {
01195 DLOG_ERR("Scan failed");
01196 return -1;
01197 }
01198
01199 if (add_timer == TRUE) {
01200 wlan_status.scan_id = g_timeout_add_seconds(
01201 WLANCOND_SCAN_TIMEOUT,
01202 wlan_scan_cb,
01203 NULL);
01204 }
01205
01206 DLOG_DEBUG("Scan issued");
01207
01208 return 0;
01209 }
01215 static int set_freq(int channel)
01216 {
01217 struct iwreq req;
01218
01219 DLOG_DEBUG("Setting channel: %d", channel);
01220
01221 init_iwreq(&req);
01222
01223 req.u.freq.m = channel;
01224
01225 if (ioctl(socket_open(), SIOCSIWFREQ, &req) < 0) {
01226 DLOG_ERR("Freq failed");
01227 return -1;
01228 }
01229
01230 return 0;
01231 }
01232 static void init_conn_params(struct connect_params_t *conn_params)
01233 {
01234 memset(conn_params, 0, sizeof(*conn_params));
01235 }
01240 void clear_wpa_keys(unsigned char* bssid)
01241 {
01242 struct iwreq req;
01243 struct iw_encode_ext ext;
01244 int sock;
01245 guint i;
01246
01247 init_iwreq(&req);
01248
01249 sock = socket_open();
01250
01251 for (i=0;i<4;i++) {
01252
01253 memset(&ext, 0, sizeof(ext));
01254
01255 req.u.encoding.flags = i + 1;
01256 req.u.encoding.flags |= IW_ENCODE_DISABLED;
01257 req.u.encoding.pointer = (caddr_t) &ext;
01258 req.u.encoding.length = sizeof(ext);
01259
01260 ext.ext_flags |= IW_ENCODE_EXT_GROUP_KEY;
01261 ext.addr.sa_family = ARPHRD_ETHER;
01262
01263 memset(ext.addr.sa_data, 0xff, ETH_ALEN);
01264 ext.alg = IW_ENCODE_ALG_NONE;
01265
01266 if (ioctl(sock, SIOCSIWENCODEEXT, &req) < 0) {
01267 DLOG_ERR("Key clearing failed");
01268 }
01269 }
01270 if (bssid != NULL) {
01271
01272 memset(&ext, 0, sizeof(ext));
01273
01274 req.u.encoding.flags = 1;
01275 req.u.encoding.flags |= IW_ENCODE_DISABLED;
01276 req.u.encoding.pointer = (caddr_t) &ext;
01277 req.u.encoding.length = sizeof(ext);
01278
01279 ext.addr.sa_family = ARPHRD_ETHER;
01280
01281 memcpy(ext.addr.sa_data, bssid, ETH_ALEN);
01282 ext.alg = IW_ENCODE_ALG_NONE;
01283
01284 if (ioctl(sock, SIOCSIWENCODEEXT, &req) < 0) {
01285 DLOG_ERR("Key clearing failed");
01286 }
01287 }
01288
01289 return;
01290 }
01298 static int check_connect_arguments(struct connect_params_t *conn, char* ssid,
01299 unsigned char** key)
01300 {
01301 guint i;
01302
01303 if (conn->flags & WLANCOND_DISABLE_POWERSAVE) {
01304 DLOG_DEBUG("Powersave disabled");
01305 powersave = WLANCOND_POWER_ON;
01306 } else if (conn->flags & WLANCOND_MINIMUM_POWERSAVE) {
01307 DLOG_DEBUG("Powersave minimum");
01308 powersave = WLANCOND_LONG_CAM;
01309 } else if (conn->flags & WLANCOND_MAXIMUM_POWERSAVE) {
01310 DLOG_DEBUG("Powersave maximum");
01311 powersave = WLANCOND_SHORT_CAM;
01312 } else {
01313 powersave = WLANCOND_SHORT_CAM;
01314 }
01315
01316 if (conn->power_level != WLANCOND_TX_POWER10 &&
01317 conn->power_level != WLANCOND_TX_POWER100) {
01318 DLOG_ERR("Invalid power level");
01319 return -1;
01320 }
01321
01322 switch (conn->mode) {
01323 case WLANCOND_ADHOC:
01324 case WLANCOND_INFRA:
01325 break;
01326 default:
01327 DLOG_ERR("Operating mode undefined\n");
01328 return -1;
01329 }
01330
01331 guint32 wpa2_mode = conn->encryption & WLANCOND_ENCRYPT_WPA2_MASK;
01332
01333 DLOG_DEBUG("Encryption setting: %08x", conn->encryption);
01334
01335 switch (conn->encryption & WLANCOND_ENCRYPT_METHOD_MASK) {
01336 case WLANCOND_OPEN:
01337 break;
01338 case WLANCOND_WEP:
01339 break;
01340 case WLANCOND_WPA_PSK:
01341 DLOG_DEBUG("%s PSK selected", wpa2_mode!=0?"WPA2":"WPA");
01342 if (wpa2_mode != 0)
01343 conn->authentication_type = EAP_AUTH_TYPE_WPA2_PSK;
01344 else
01345 conn->authentication_type = EAP_AUTH_TYPE_WPA_PSK;
01346 break;
01347 case WLANCOND_WPA_EAP:
01348 DLOG_DEBUG("%s EAP selected", wpa2_mode!=0?"WPA2":"WPA");
01349 if (wpa2_mode != 0)
01350 conn->authentication_type = EAP_AUTH_TYPE_WPA2_EAP;
01351 else
01352 conn->authentication_type = EAP_AUTH_TYPE_WPA_EAP;
01353 break;
01354 default:
01355 DLOG_DEBUG("Unsupported encryption mode");
01356 return -1;
01357 }
01358 if ((conn->encryption & WLANCOND_WPS_MASK) != 0) {
01359 DLOG_DEBUG("WPS selected");
01360 conn->authentication_type = EAP_AUTH_TYPE_WFA_SC;
01361 }
01362
01363 if (!ssid || conn->ssid_len == 0 ||
01364 conn->ssid_len > WLANCOND_MAX_SSID_SIZE + 1) {
01365 DLOG_DEBUG("Invalid SSID");
01366 return -1;
01367 }
01368 for (i=0;i<4;i++) {
01369 if (conn->key_len[i] != 0) {
01370 DLOG_DEBUG("Found key %d", i);
01371 memcpy(&conn->key[i][0], key[i], conn->key_len[i]);
01372 }
01373 }
01374 return 0;
01375 }
01376
01383 static DBusHandlerResult settings_and_connect_request(
01384 DBusMessage *message,
01385 DBusConnection *connection) {
01386
01387 DBusMessage *reply = NULL;
01388 DBusError derror;
01389 struct connect_params_t *conn;
01390 char *ssid;
01391 unsigned char* key[4];
01392 dbus_int32_t old_mode;
01393
01394 dbus_error_init(&derror);
01395
01396 if (in_flight_mode()) {
01397 reply = new_dbus_error(message, WLANCOND_ERROR_WLAN_DISABLED);
01398 send_and_unref(connection, reply);
01399 return DBUS_HANDLER_RESULT_HANDLED;
01400 }
01401
01402 remove_wlan_if_timer();
01403
01404 conn = &wlan_status.conn;
01405
01406 old_mode = conn->mode;
01407 init_conn_params(conn);
01408
01409 if (dbus_message_get_args(
01410 message, NULL,
01411 DBUS_TYPE_INT32, &conn->power_level,
01412 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &ssid, &conn->ssid_len,
01413 DBUS_TYPE_INT32, &conn->mode,
01414 DBUS_TYPE_INT32, &conn->encryption,
01415 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &key[0], &conn->key_len[0],
01416 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &key[1], &conn->key_len[1],
01417 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &key[2], &conn->key_len[2],
01418 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &key[3], &conn->key_len[3],
01419 DBUS_TYPE_INT32, &conn->default_key,
01420 DBUS_TYPE_UINT32, &conn->adhoc_channel,
01421 DBUS_TYPE_UINT32, &conn->flags,
01422 DBUS_TYPE_INVALID) == FALSE)
01423 {
01424
01425 if (dbus_message_get_args(
01426 message, &derror,
01427 DBUS_TYPE_INT32, &conn->power_level,
01428 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &ssid,
01429 &conn->ssid_len,
01430 DBUS_TYPE_INT32, &conn->mode,
01431 DBUS_TYPE_INT32, &conn->encryption,
01432 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
01433 &key[0], &conn->key_len[0],
01434 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
01435 &key[1], &conn->key_len[1],
01436 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
01437 &key[2], &conn->key_len[2],
01438 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
01439 &key[3], &conn->key_len[3],
01440 DBUS_TYPE_INT32, &conn->default_key,
01441 DBUS_TYPE_UINT32, &conn->adhoc_channel,
01442 DBUS_TYPE_INVALID) == FALSE) {
01443
01444 DLOG_ERR("Failed to parse setting_and_connect: %s",
01445 derror.message);
01446 dbus_error_free(&derror);
01447 goto param_err;
01448 }
01449 }
01450
01451 if (check_connect_arguments(conn, ssid, key) < 0)
01452 goto param_err;
01453
01454 set_power_state(WLANCOND_POWER_ON, socket_open());
01455
01456
01457
01458
01459
01460 if (old_mode != conn->mode ||
01461 conn->encryption & WLANCOND_WPS_PUSH_BUTTON) {
01462 set_wlan_state(WLAN_NOT_INITIALIZED, NO_SIGNAL, FORCE_YES);
01463 }
01464
01465
01466 if (set_mode(conn->mode) < 0) {
01467 goto param_err;
01468 }
01469
01470 if (init_if(socket_open()) < 0) {
01471 reply = new_dbus_error(message, WLANCOND_ERROR_INIT_FAILED);
01472 goto param_err;
01473 }
01474
01475 if (set_tx_power(conn->power_level, socket_open()) != TRUE) {
01476 reply = new_dbus_error(message, WLANCOND_ERROR_IOCTL_FAILED);
01477 goto param_err;
01478 }
01479
01480 memcpy(conn->ssid, ssid, conn->ssid_len);
01481
01482 set_scan_state(SCAN_NOT_ACTIVE);
01483 set_wlan_state(WLAN_INITIALIZED_FOR_CONNECTION, NO_SIGNAL, FORCE_NO);
01484
01485
01486 if (conn->encryption & WLANCOND_WPS_PUSH_BUTTON) {
01487 DLOG_DEBUG("Broadcast scan for WPS");
01488 if (scan(NULL, 0, TRUE) < 0) {
01489 goto param_err;
01490 }
01491 } else {
01492
01493 if (find_connection_and_associate(wlan_status.roam_cache,
01494 FALSE, FALSE) != 0) {
01495
01496 DLOG_DEBUG("Checking mac80211 cache...");
01497
01498 GSList *scan_results = NULL;
01499 scan_results_ioctl(0, &scan_results);
01500
01501 if (find_connection_and_associate(scan_results, TRUE,
01502 FALSE) != 0) {
01503 clean_scan_results(&scan_results);
01504 if (scan(conn->ssid, conn->ssid_len, TRUE) < 0) {
01505 goto param_err;
01506 }
01507 } else {
01508 clean_scan_results(&scan_results);
01509 }
01510 }
01511 }
01512
01513 g_free(connect_name_cache);
01514 connect_name_cache = g_strdup(dbus_message_get_sender(message));
01515
01516 reply = new_dbus_method_return(message);
01517
01518 gchar* ifname = wlan_status.ifname;
01519
01520 append_dbus_args(reply,
01521 DBUS_TYPE_STRING, &ifname,
01522 DBUS_TYPE_INVALID);
01523
01524 send_and_unref(connection, reply);
01525
01526 return DBUS_HANDLER_RESULT_HANDLED;
01527
01528 param_err:
01529 if (reply == NULL) {
01530 DLOG_DEBUG("Parameter error in settings_and_connect\n");
01531 reply = new_dbus_error(message, DBUS_ERROR_INVALID_ARGS);
01532 }
01533 send_and_unref(connection, reply);
01534 return DBUS_HANDLER_RESULT_HANDLED;
01535 }
01541 int associate(struct scan_results_t *scan_results)
01542 {
01543 struct connect_params_t *conn = &wlan_status.conn;
01544
01545 DLOG_DEBUG("Starting associate...");
01546
01547 if (memcmp(conn->bssid, "\0\0\0\0\0\0", ETH_ALEN)) {
01548 clear_wpa_keys(conn->bssid);
01549 }
01550
01551 if (update_algorithms(conn->encryption) < 0) {
01552 return -1;
01553 }
01554
01555
01556 if ((conn->encryption & WLANCOND_ENCRYPT_METHOD_MASK) == WLANCOND_WEP){
01557 if (set_wep_keys(conn) < 0) {
01558 return -1;
01559 }
01560 }
01561
01562 memcpy(conn->bssid, scan_results->bssid, ETH_ALEN);
01563
01564 if (set_encryption_method(conn->encryption, &wlan_status) == FALSE) {
01565 return -1;
01566 }
01567
01568 if (get_wpa_mode() == TRUE ||
01569 conn->authentication_type == EAP_AUTH_TYPE_WFA_SC) {
01570
01571
01572 if (wpa_ie_push(scan_results->bssid,
01573 scan_results->wpa_ie,
01574 scan_results->wpa_ie_len,
01575 scan_results->ssid,
01576 scan_results->ssid_len -1,
01577 conn->authentication_type) < 0)
01578 return -1;
01579 }
01580
01581
01582
01583 if (conn->adhoc_channel != 0 && (conn->mode & WLANCOND_ADHOC)) {
01584 if (conn->adhoc_channel < WLANCOND_MIN_WLAN_CHANNEL ||
01585 conn->adhoc_channel > WLANCOND_MAX_WLAN_CHANNEL) {
01586 DLOG_ERR("Invalid ad-hoc channel: %d",
01587 conn->adhoc_channel);
01588 return -1;
01589 }
01590
01591 scan_results->channel = conn->adhoc_channel;
01592 }
01593
01594 set_freq(scan_results->channel);
01595
01596
01597 if (conn->mode != WLANCOND_ADHOC &&
01598 memcmp(scan_results->bssid, "\0\0\0\0\0\0", ETH_ALEN)) {
01599 if (set_bssid(scan_results->bssid) < 0) {
01600 return -1;
01601 }
01602 }
01603
01604 if (set_essid(conn->ssid, conn->ssid_len) < 0) {
01605 return -1;
01606 }
01607
01608
01609 wlan_connect_timer_id = g_timeout_add_seconds(
01610 WLANCOND_CONNECT_TIMEOUT,
01611 wlan_connect_timer_cb, NULL);
01612
01613 return 0;
01614 }
01615
01622 static DBusHandlerResult scan_request(DBusMessage *message,
01623 DBusConnection *connection) {
01624
01625 DBusMessage *reply = NULL;
01626 DBusMessageIter iter, array_iter;
01627 char *ssid;
01628 const char* sender;
01629 dbus_int32_t power_level;
01630 dbus_int32_t flags;
01631 gint previous_state = 0;
01632
01633 if (in_flight_mode()) {
01634 reply = new_dbus_error(message, WLANCOND_ERROR_WLAN_DISABLED);
01635 send_and_unref(connection, reply);
01636 return DBUS_HANDLER_RESULT_HANDLED;
01637 }
01638
01639 sender = dbus_message_get_sender(message);
01640 if (sender == NULL) {
01641 goto param_err;
01642 }
01643
01644 DLOG_DEBUG("Got scan request from %s", sender);
01645
01646
01647 if (get_scan_state() == SCAN_ACTIVE || wlan_connect_timer_id != 0) {
01648 reply = new_dbus_error(message, WLANCOND_ERROR_ALREADY_ACTIVE);
01649 send_and_unref(connection, reply);
01650 return DBUS_HANDLER_RESULT_HANDLED;
01651 }
01652
01653 if ((previous_state = init_if(socket_open())) < 0) {
01654 reply = new_dbus_error(message, WLANCOND_ERROR_INIT_FAILED);
01655 goto param_err;
01656 }
01657 if (previous_state == WLAN_NOT_INITIALIZED) {
01658 set_wlan_state(WLAN_INITIALIZED_FOR_SCAN, NO_SIGNAL, FORCE_NO);
01659 }
01660
01661 dbus_message_iter_init(message, &iter);
01662
01663 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32)
01664 goto param_err;
01665 dbus_message_iter_get_basic(&iter, &power_level);
01666
01667 dbus_message_iter_next(&iter);
01668
01669 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
01670 dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_BYTE)
01671 goto param_err;
01672 dbus_message_iter_recurse(&iter, &array_iter);
01673 dbus_message_iter_get_fixed_array(&array_iter, &ssid,
01674 &wlan_status.scan_ssid_len);
01675
01676 if (wlan_status.scan_ssid_len > WLANCOND_MAX_SSID_SIZE+1)
01677 goto param_err;
01678
01679 dbus_message_iter_next(&iter);
01680
01681 power_down_after_scan = FALSE;
01682
01683 if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_UINT32) {
01684 dbus_message_iter_get_basic(&iter, &flags);
01685 DLOG_DEBUG("Found flags: %08x", flags);
01686
01687 if (flags & WLANCOND_NO_DELAYED_SHUTDOWN)
01688 power_down_after_scan = TRUE;
01689 }
01690
01691 if (power_level != WLANCOND_TX_POWER10 &&
01692 power_level != WLANCOND_TX_POWER100) {
01693 DLOG_ERR("Invalid power level");
01694 goto param_err;
01695 }
01696
01697 if (set_tx_power(power_level, socket_open()) != TRUE) {
01698 reply = new_dbus_error(message, WLANCOND_ERROR_IOCTL_FAILED);
01699 goto param_err;
01700 }
01701
01702 memset(wlan_status.scan_ssid, 0, sizeof(wlan_status.scan_ssid));
01703
01704 if (ssid != NULL && wlan_status.scan_ssid_len > 1) {
01705 memcpy(wlan_status.scan_ssid, ssid, wlan_status.scan_ssid_len);
01706 }
01707
01708 if (scan(wlan_status.scan_ssid, wlan_status.scan_ssid_len, TRUE) < 0) {
01709 reply = new_dbus_error(message, WLANCOND_ERROR_IOCTL_FAILED);
01710 goto param_err;
01711 }
01712
01713 g_free(scan_name_cache);
01714 scan_name_cache = g_strdup(sender);
01715
01716 reply = new_dbus_method_return(message);
01717 send_and_unref(connection, reply);
01718
01719 return DBUS_HANDLER_RESULT_HANDLED;
01720
01721 param_err:
01722 if (get_wlan_state() == WLAN_INITIALIZED_FOR_SCAN) {
01723 set_wlan_state(WLAN_NOT_INITIALIZED, NO_SIGNAL, FORCE_YES);
01724 }
01725 if (reply == NULL) {
01726 DLOG_DEBUG("Parameter error in scan request");
01727 reply = new_dbus_error(message, DBUS_ERROR_INVALID_ARGS);
01728 }
01729 send_and_unref(connection, reply);
01730 return DBUS_HANDLER_RESULT_HANDLED;
01731 }
01738 static int network_compare(gconstpointer a, gconstpointer b)
01739 {
01740 const struct scan_results_t *results_a = a;
01741 const struct scan_results_t *results_b = b;
01742
01743 if (wlan_status.scan_ssid_len > 1) {
01744
01745
01746
01747 gint a_eq = strncmp(wlan_status.scan_ssid, results_a->ssid, WLANCOND_MAX_SSID_SIZE);
01748 gint b_eq = strncmp(wlan_status.scan_ssid, results_b->ssid, WLANCOND_MAX_SSID_SIZE);
01749
01750 if (!a_eq && !b_eq) {
01751
01752 return 0;
01753 }
01754
01755 if (!a_eq && b_eq) {
01756
01757 return -1;
01758 }
01759
01760 if (a_eq && !b_eq) {
01761
01762
01763 return 1;
01764 }
01765
01766 }
01767
01768
01769 return (results_a->rssi > results_b->rssi) ? -1 : (results_a->rssi < results_b->rssi) ? 1 : 0;
01770 }
01771
01772 static gint compare_scan_entry(gconstpointer a, gconstpointer b)
01773 {
01774 const struct scan_results_t *scan_entry = a;
01775 return memcmp(scan_entry->bssid, b, ETH_ALEN);
01776 }
01781 static void add_to_roam_cache(struct scan_results_t *scan_results)
01782 {
01783 GSList *list;
01784
01785 list = g_slist_find_custom(wlan_status.roam_cache, scan_results->bssid,
01786 &compare_scan_entry);
01787
01788 if (list != NULL) {
01789 struct scan_results_t *roam_cache_entry = list->data;
01790 print_mac("Found old entry for:", scan_results->bssid);
01791
01792
01793 wlan_status.roam_cache = g_slist_remove(
01794 wlan_status.roam_cache, roam_cache_entry);
01795
01796 clean_scan_results_item(roam_cache_entry, NULL);
01797 }
01798
01799 print_mac("New AP to roam cache:", scan_results->bssid);
01800
01801 struct scan_results_t *results_to_list = g_slice_dup(struct scan_results_t, scan_results);
01802 results_to_list->wpa_ie = g_memdup(scan_results->wpa_ie,
01803 scan_results->wpa_ie_len);
01804 wlan_status.roam_cache = g_slist_prepend(wlan_status.roam_cache,
01805 results_to_list);
01806
01807 return;
01808 }
01814 gboolean remove_from_roam_cache(unsigned char *bssid)
01815 {
01816 GSList *list;
01817
01818 list = g_slist_find_custom(wlan_status.roam_cache, bssid,
01819 &compare_scan_entry);
01820
01821 if (list != NULL) {
01822 struct scan_results_t *roam_cache_entry = list->data;
01823 print_mac("Found entry to be removed:", bssid);
01824
01825 wlan_status.roam_cache = g_slist_remove(
01826 wlan_status.roam_cache, roam_cache_entry);
01827
01828 clean_scan_results_item(roam_cache_entry, NULL);
01829
01830 return TRUE;
01831 }
01832
01833 return FALSE;
01834 }
01835
01841 gboolean decrease_signal_in_roam_cache(unsigned char *bssid)
01842 {
01843 GSList *list;
01844
01845 list = g_slist_find_custom(wlan_status.roam_cache, bssid,
01846 &compare_scan_entry);
01847
01848 if (list != NULL) {
01849 struct scan_results_t *roam_cache_entry = list->data;
01850 print_mac("Found entry to be decreased:", bssid);
01851
01852 roam_cache_entry->rssi -= WLANCOND_RSSI_PENALTY;
01853
01854 return TRUE;
01855 }
01856
01857 return FALSE;
01858 }
01865 static int check_group_cipher(guint32 c1, guint32 c2)
01866 {
01867 guint32 m1 = (c1 & WLANCOND_ENCRYPT_GROUP_ALG_MASK);
01868 guint32 m2 = (c2 & WLANCOND_ENCRYPT_GROUP_ALG_MASK);
01869
01870 if (m1 == m2)
01871 return 1;
01872 if (m2 == WLANCOND_WPA_TKIP_GROUP && (m1 & WLANCOND_WPA_TKIP_GROUP))
01873 return 1;
01874 if (m2 == (unsigned int)WLANCOND_WPA_AES_GROUP &&
01875 (m1 & WLANCOND_WPA_AES_GROUP))
01876 return 1;
01877
01878 DLOG_DEBUG("Group ciphers don't match");
01879
01880 return -1;
01881 }
01888 static int check_ciphers(guint32 c1, guint32 c2)
01889 {
01890 guint32 u1 = (c1 & WLANCOND_ENCRYPT_ALG_MASK);
01891 guint32 u2 = (c2 & WLANCOND_ENCRYPT_ALG_MASK);
01892
01893 if (check_group_cipher(c1, c2) < 0)
01894 return -1;
01895
01896 if (u1 == u2)
01897 return 1;
01898 if (u2 == WLANCOND_WPA_TKIP && (u1 & WLANCOND_WPA_TKIP))
01899 return 1;
01900 if (u2 == WLANCOND_WPA_AES && (u1 & WLANCOND_WPA_AES))
01901 return 1;
01902
01903 DLOG_DEBUG("Unicast ciphers don't match");
01904
01905 return -1;
01906 }
01907 static gboolean wlan_roam_scan_cb(void* data)
01908 {
01909 wlan_status.roam_scan_id = 0;
01910
01911 if (wlan_status.signal == WLANCOND_LOW &&
01912 get_wlan_state() == WLAN_CONNECTED) {
01913
01914 DLOG_DEBUG("Roam scan timeout, initiating new scan");
01915
01916
01917 scan(wlan_status.conn.ssid, wlan_status.conn.ssid_len, FALSE);
01918 }
01919
01920 return FALSE;
01921 }
01922
01927 void schedule_scan(guint seconds) {
01928
01929
01930 remove_roam_scan_timer();
01931 wlan_status.roam_scan_id = g_timeout_add_seconds(
01932 seconds,
01933 wlan_roam_scan_cb,
01934 NULL);
01935 }
01936
01940 static void reschedule_scan(void)
01941 {
01942
01943
01944
01945
01946 if (get_inactivity_status() == TRUE) {
01947 wlan_status.roam_scan = WLANCOND_MIN_ROAM_SCAN_INTERVAL;
01948 } else {
01949 if (wlan_status.roam_scan <= WLANCOND_MIN_ROAM_SCAN_INTERVAL) {
01950 wlan_status.roam_scan = WLANCOND_MIN_ROAM_SCAN_INTERVAL;
01951 } else if (wlan_status.roam_scan >= WLANCOND_MAX_ROAM_SCAN_INTERVAL) {
01952 wlan_status.roam_scan = WLANCOND_MAX_ROAM_SCAN_INTERVAL;
01953 } else {
01954 wlan_status.roam_scan = wlan_status.roam_scan * 2;
01955 }
01956 }
01957
01958 schedule_scan(wlan_status.roam_scan);
01959 }
01960
01967 static gboolean check_capabilities(struct scan_results_t *scan_results,
01968 struct connect_params_t *conn)
01969 {
01970
01971 if ((scan_results->cap_bits & WLANCOND_MODE_MASK) != (guint32)conn->mode)
01972 return FALSE;
01973 if ((scan_results->cap_bits & WLANCOND_ENCRYPT_METHOD_MASK) != (guint32)(conn->encryption & WLANCOND_ENCRYPT_METHOD_MASK))
01974 return FALSE;
01975 if ((scan_results->cap_bits & WLANCOND_ENCRYPT_WPA2_MASK) != (guint32)(conn->encryption & WLANCOND_ENCRYPT_WPA2_MASK))
01976 return FALSE;
01977 if (check_ciphers(scan_results->cap_bits, conn->encryption) < 0)
01978 return FALSE;
01979
01980 return TRUE;
01981 }
01982
01990 struct scan_results_t* find_connection(
01991 GSList* ap_list, struct connect_params_t *conn,
01992 gboolean update_roam_cache)
01993 {
01994 GSList *list;
01995 struct scan_results_t *best_connection = NULL;
01996 gint current_rssi = 0;
01997
01998
01999 if (update_roam_cache == TRUE)
02000 clean_roam_cache();
02001
02002 for (list = ap_list; list != NULL; list = list->next) {
02003 struct scan_results_t *scan_results = list->data;
02004 if (memcmp(scan_results->ssid, conn->ssid, scan_results->ssid_len) == 0) {
02005 print_mac("Found AP:", scan_results->bssid);
02006
02007
02008 if (memcmp(scan_results->bssid, wlan_status.conn.bssid,
02009 ETH_ALEN) == 0) {
02010 current_rssi = scan_results->rssi;
02011 DLOG_DEBUG("Current AP: %d", current_rssi);
02012 }
02013
02014 if (check_capabilities(scan_results, conn) ==
02015 FALSE)
02016 continue;
02017
02018 if (is_ap_in_black_list(scan_results->bssid) == TRUE) {
02019 DLOG_DEBUG("AP is in black list, discarded");
02020 continue;
02021 }
02022
02023
02024
02025
02026 if (update_roam_cache == TRUE) {
02027 add_to_roam_cache(scan_results);
02028 }
02029
02030 if (best_connection == NULL ||
02031 best_connection->rssi < scan_results->rssi) {
02032 DLOG_DEBUG("Best connection: %d (old %d)",
02033 scan_results->rssi,
02034 best_connection == NULL ?
02035 WLANCOND_MINIMUM_SIGNAL:
02036 best_connection->rssi);
02037 best_connection = scan_results;
02038 }
02039 }
02040 }
02041
02042
02043 if (best_connection == NULL)
02044 return NULL;
02045
02046
02047
02048
02049 if (current_rssi != 0) {
02050 if (best_connection->rssi < current_rssi +
02051 WLANCOND_ROAM_THRESHOLD) {
02052 DLOG_DEBUG("Best connection not good enough");
02053 return NULL;
02054 }
02055 }
02056
02057
02058 if (best_connection->rssi < WLANCOND_MINIMUM_SIGNAL)
02059 return NULL;
02060
02061 return best_connection;
02062 }
02068 static dbus_uint32_t find_adhoc_channel(GSList *ap_list) {
02069
02070 dbus_uint32_t used_channel_list = 0;
02071 dbus_uint32_t selected_channel = 0;
02072 GSList* list;
02073 guint32 i;
02074
02075
02076 for (list = ap_list; list != NULL; list = list->next) {
02077 struct scan_results_t *scan_results = list->data;
02078 used_channel_list |= 1 << scan_results->channel;
02079 }
02080
02081 for (i = 1; i <= 11; i++) {
02082 if (!(used_channel_list & (1 << i))) {
02083 selected_channel = i;
02084 break;
02085 }
02086 }
02087
02088 if (selected_channel == 0) {
02089
02090
02091 selected_channel = g_random_int_range(1, 12);
02092 }
02093
02094
02095
02096 return selected_channel;
02097 }
02103 int find_connection_and_associate(GSList *scan_results,
02104 gboolean update_roam_cache,
02105 gboolean create_new_adhoc)
02106 {
02107 struct scan_results_t adhoc;
02108 struct connect_params_t *conn = &wlan_status.conn;
02109 guint wps_pbc_registrars = 0;
02110 GSList* list;
02111
02112
02113
02114 if (conn->encryption & WLANCOND_WPS_PUSH_BUTTON) {
02115 for (list = scan_results; list != NULL; list = list->next) {
02116 struct scan_results_t *scan_results = list->data;
02117
02118 if (scan_results->cap_bits & WLANCOND_WPS_PUSH_BUTTON
02119 &&
02120 scan_results->cap_bits & WLANCOND_WPS_CONFIGURED) {
02121 if (++wps_pbc_registrars > 1) {
02122 DLOG_ERR("Too many WPS PBC registrars");
02123 return ETOOMANYREGISTRARS;
02124 }
02125 }
02126 }
02127 }
02128
02129 struct scan_results_t *connection = find_connection(
02130 scan_results, &wlan_status.conn, update_roam_cache);
02131
02132 if (connection == NULL && conn->mode == WLANCOND_ADHOC &&
02133 create_new_adhoc == TRUE) {
02134 DLOG_DEBUG("No existing adhoc connection");
02135 memset(&adhoc, 0, sizeof(adhoc));
02136 connection = &adhoc;
02137 memcpy(connection->ssid, conn->ssid, conn->ssid_len);
02138 connection->channel = find_adhoc_channel(scan_results);
02139 }
02140
02141 if (connection) {
02142 int ret = associate(connection);
02143 if (ret < 0)
02144 memset(wlan_status.conn.bssid, 0, ETH_ALEN);
02145 return ret;
02146 }
02147 return -1;
02148 }
02152 static void registrar_error_signal(void)
02153 {
02154 DBusMessage *registrar_error;
02155
02156 registrar_error = new_dbus_signal(
02157 WLANCOND_SIG_PATH,
02158 WLANCOND_SIG_INTERFACE,
02159 WLANCOND_REGISTRAR_ERROR_SIG,
02160 NULL);
02161
02162 send_and_unref(get_dbus_connection(), registrar_error);
02163 }
02167 static gboolean rescan(void* data)
02168 {
02169 if (get_wlan_state() == WLAN_INITIALIZED_FOR_CONNECTION) {
02170
02171 scan(wlan_status.conn.ssid, wlan_status.conn.ssid_len, FALSE);
02172 }
02173 return FALSE;
02174 }
02179 static void connect_from_scan_results(GSList *scan_results)
02180 {
02181 int status = find_connection_and_associate(scan_results, TRUE, TRUE);
02182
02183 clean_scan_results(&scan_results);
02184
02185 if (status == 0)
02186 return;
02187
02188 DLOG_DEBUG("Could not find suitable network");
02189
02190 if (get_wlan_state() == WLAN_INITIALIZED_FOR_CONNECTION) {
02191
02192 if (++wlan_status.retry_count <= WLANCOND_MAX_SCAN_TRIES) {
02193 DLOG_DEBUG("Rescanning");
02194 g_timeout_add_seconds(
02195 WLANCOND_RESCAN_DELAY,
02196 rescan,
02197 NULL);
02198 } else {
02199
02200
02201
02202 if (status == ETOOMANYREGISTRARS) {
02203 set_wlan_state(WLAN_NOT_INITIALIZED,
02204 NO_SIGNAL, FORCE_YES);
02205 registrar_error_signal();
02206 } else {
02207 set_wlan_state(WLAN_NOT_INITIALIZED,
02208 DISCONNECTED_SIGNAL, FORCE_YES);
02209 }
02210 }
02211 return;
02212 }
02213
02214
02215 reschedule_scan();
02216 }
02223 int scan_results_ioctl(int ifindex, GSList** scan_results_save)
02224 {
02225 struct iwreq req;
02226 char *buffer;
02227 unsigned int buflen = IW_SCAN_MAX_DATA*2;
02228 int sock;
02229 unsigned int counter = 3;
02230
02231
02232
02233 init_iwreq(&req);
02234
02235 sock = socket_open();
02236
02237 buffer = g_malloc(buflen);
02238
02239 try_again:
02240
02241
02242 req.u.data.pointer = buffer;
02243 req.u.data.flags = 0;
02244 req.u.data.length = buflen;
02245
02246 if (ioctl(sock, SIOCGIWSCAN, &req) < 0) {
02247
02248
02249 if (errno == E2BIG && buflen != G_MAXUINT16) {
02250 DLOG_DEBUG("Too much data for buffer length %d "
02251 "needed %d\n", buflen, req.u.data.length);
02252
02253 char* new_buffer = NULL;
02254 buflen = (req.u.data.length > buflen ?
02255 req.u.data.length : buflen * 2);
02256
02257
02258 if (buflen > G_MAXUINT16)
02259 buflen = G_MAXUINT16;
02260 new_buffer = g_realloc(buffer, buflen);
02261
02262 buffer = new_buffer;
02263 goto try_again;
02264 }
02265
02266
02267 if (errno == EAGAIN)
02268 {
02269 DLOG_DEBUG("Not yet ready...");
02270 if (counter-- > 0) {
02271 sleep(1);
02272 goto try_again;
02273 }
02274 }
02275
02276 DLOG_ERR("Get scan results failed");
02277
02278 g_free(buffer);
02279 return -1;
02280 }
02281
02282 if (req.u.data.length)
02283 {
02284 struct iw_event iwe;
02285 struct stream_descr stream;
02286 struct scan_results_t *scan_results;
02287 struct wireless_iface *wireless_if;
02288 int ret;
02289 gboolean wap_handled = FALSE;
02290 int we_version;
02291
02292 scan_results = g_slice_new0(struct scan_results_t);
02293 memset(&iwe, 0, sizeof(iwe));
02294
02295 if (ifindex != 0) {
02296 wireless_if = get_interface_data(ifindex);
02297 we_version = wireless_if->range.we_version_compiled;
02298 } else {
02299 struct iw_range range;
02300 if (iw_get_range_info(socket_open(),
02301 wlan_status.ifname,
02302 &range)<0)
02303 memset(&range, 0, sizeof(range));
02304 we_version = range.we_version_compiled;
02305 }
02306
02307 iw_init_event_stream(&stream, buffer, req.u.data.length);
02308 do
02309 {
02310
02311 ret = iw_extract_event_stream(
02312 &stream, &iwe,
02313 we_version);
02314 if (ret > 0) {
02315
02316
02317
02318
02319 if (iwe.cmd == SIOCGIWAP) {
02320
02321
02322
02323 if (wap_handled == TRUE) {
02324 *scan_results_save = save_scan_results(scan_results, *scan_results_save);
02325 scan_results = g_slice_new0(struct scan_results_t);
02326 } else {
02327 wap_handled = TRUE;
02328 }
02329 }
02330 print_event_token(&iwe, scan_results, ifindex,
02331 TRUE);
02332 }
02333
02334 }
02335 while (ret > 0);
02336
02337
02338
02339 if (wap_handled == TRUE) {
02340 *scan_results_save = save_scan_results(
02341 scan_results,
02342 *scan_results_save);
02343 } else {
02344
02345 g_slice_free(struct scan_results_t, scan_results);
02346 }
02347 }
02348
02349 g_free(buffer);
02350
02351 return 0;
02352 }
02353
02354
02360 gboolean ask_scan_results(int ifindex)
02361 {
02362 GSList *scan_results_save = NULL;
02363 dbus_int32_t number_of_results;
02364
02365 if (scan_results_ioctl(ifindex, &scan_results_save) < 0)
02366 return FALSE;
02367
02368
02369 if (scan_name_cache != NULL) {
02370 number_of_results = g_slist_length(scan_results_save);
02371
02372
02373
02374 if (number_of_results > WLANCOND_MAX_NETWORKS)
02375 scan_results_save = g_slist_sort(scan_results_save,
02376 network_compare);
02377
02378 send_dbus_scan_results(scan_results_save, scan_name_cache,
02379 number_of_results);
02380 g_free(scan_name_cache);
02381 scan_name_cache = NULL;
02382 }
02383
02384
02385
02386 if ((get_wlan_state() == WLAN_INITIALIZED_FOR_CONNECTION ||
02387 wlan_status.signal == WLANCOND_LOW) &&
02388 get_scan_state() == SCAN_ACTIVE) {
02389
02390 DLOG_DEBUG("Connect from scan");
02391
02392 set_scan_state(SCAN_NOT_ACTIVE);
02393
02394 connect_from_scan_results(scan_results_save);
02395
02396 return TRUE;
02397 }
02398
02399 set_scan_state(SCAN_NOT_ACTIVE);
02400
02401 if (get_wlan_state() == WLAN_INITIALIZED_FOR_SCAN &&
02402 power_down_after_scan == TRUE) {
02403 set_interface_state(socket_open(), CLEAR, IFF_UP);
02404 }
02405
02406 if (get_wlan_state() == WLAN_INITIALIZED_FOR_SCAN) {
02407
02408 if (wlan_status.roam_cache) {
02409 clean_roam_cache();
02410 }
02411 wlan_status.roam_cache = scan_results_save;
02412 set_wlan_state(WLAN_NOT_INITIALIZED, NO_SIGNAL, FORCE_NO);
02413 } else {
02414 clean_scan_results(&scan_results_save);
02415 }
02416
02417 return TRUE;
02418 }
02419
02426 static DBusHandlerResult disconnect_request(DBusMessage *message,
02427 DBusConnection *connection) {
02428 DBusMessage *reply;
02429
02430 set_scan_state(SCAN_NOT_ACTIVE);
02431
02432
02433 set_wlan_state(WLAN_NOT_INITIALIZED, DISCONNECTED_SIGNAL, FORCE_YES);
02434
02435 reply = new_dbus_method_return(message);
02436 send_and_unref(connection, reply);
02437
02438 return DBUS_HANDLER_RESULT_HANDLED;
02439 }
02446 static DBusHandlerResult disassociate_request(DBusMessage *message,
02447 DBusConnection *connection) {
02448 DBusMessage *reply;
02449
02450 if (get_wlan_state() != WLAN_CONNECTED &&
02451 get_wlan_state() != WLAN_NO_ADDRESS) {
02452 DLOG_ERR("Not in correct state for disassociation");
02453
02454 reply = new_dbus_method_return(message);
02455 send_and_unref(connection, reply);
02456 return DBUS_HANDLER_RESULT_HANDLED;
02457 }
02458
02459 if (get_wpa_mode() == TRUE) {
02460 clear_wpa_keys(wlan_status.conn.bssid);
02461 }
02462
02463 mlme_command(wlan_status.conn.bssid, IW_MLME_DISASSOC,
02464 WLANCOND_REASON_LEAVING);
02465
02466 set_wlan_state(WLAN_INITIALIZED_FOR_CONNECTION, NO_SIGNAL, FORCE_NO);
02467
02468 DLOG_DEBUG("Disassociated, trying to find a new connection");
02469
02470 if (scan(wlan_status.conn.ssid, wlan_status.conn.ssid_len, TRUE) < 0) {
02471
02472 set_wlan_state(WLAN_NOT_INITIALIZED, DISCONNECTED_SIGNAL,
02473 FORCE_YES);
02474 }
02475
02476 reply = new_dbus_method_return(message);
02477 send_and_unref(connection, reply);
02478
02479 return DBUS_HANDLER_RESULT_HANDLED;
02480 }
02487 static DBusHandlerResult status_request(DBusMessage *message,
02488 DBusConnection *connection) {
02489 DBusMessage *reply = NULL;
02490 struct iwreq req;
02491 struct iw_range range;
02492 char *essid = NULL;
02493 int essid_len;
02494 dbus_uint32_t sens = 0;
02495 dbus_uint32_t security = 0;
02496 dbus_uint32_t capability = 0;
02497 dbus_uint32_t channel = 0;
02498 unsigned char *bssid = NULL;
02499
02500 int sock;
02501
02502 if (get_wlan_state() != WLAN_CONNECTED &&
02503 get_wlan_state() != WLAN_NO_ADDRESS &&
02504 get_mode() != WLANCOND_ADHOC) {
02505 reply = new_dbus_error(message, WLANCOND_ERROR_IOCTL_FAILED);
02506 send_and_unref(connection, reply);
02507 return DBUS_HANDLER_RESULT_HANDLED;
02508 }
02509
02510 sock = socket_open();
02511
02512 init_iwreq(&req);
02513
02514 essid = g_malloc0(IW_ESSID_MAX_SIZE+1);
02515 req.u.essid.pointer = (caddr_t)essid;
02516 req.u.essid.length = IW_ESSID_MAX_SIZE;
02517 req.u.essid.flags = 0;
02518
02519
02520 if (ioctl(sock, SIOCGIWESSID, &req) < 0) {
02521 DLOG_ERR("Could not get ESSID");
02522 reply = new_dbus_error(message, WLANCOND_ERROR_IOCTL_FAILED);
02523 goto param_err;
02524 }
02525 essid_len = req.u.essid.length;
02526
02527
02528 if (essid_len == 0 || essid_len == 32)
02529 essid_len++;
02530
02531 init_iwreq(&req);
02532
02533
02534 if (ioctl(sock, SIOCGIWAP, &req) < 0) {
02535 DLOG_ERR("Could not get BSSID");
02536 reply = new_dbus_error(message, WLANCOND_ERROR_IOCTL_FAILED);
02537 goto param_err;
02538 }
02539 bssid = g_malloc(ETH_ALEN);
02540 memcpy(bssid, &req.u.ap_addr.sa_data, ETH_ALEN);
02541
02542 init_iwreq(&req);
02543 struct iw_statistics stats;
02544 memset(&stats, 0, sizeof(struct iw_statistics));
02545
02546 req.u.data.pointer = (caddr_t) &stats;
02547 req.u.data.length = sizeof(struct iw_statistics);
02548 req.u.data.flags = 1;
02549
02550
02551 if (ioctl(sock, SIOCGIWSTATS, &req) < 0) {
02552 DLOG_ERR("Could not get statistics");
02553 reply = new_dbus_error(message, WLANCOND_ERROR_IOCTL_FAILED);
02554 goto param_err;
02555 }
02556 sens = stats.qual.level - 0x100;
02557
02558
02559 init_iwreq(&req);
02560
02561 if (ioctl(sock, SIOCGIWFREQ, &req) < 0) {
02562 DLOG_DEBUG("Could not get channel");
02563 reply = new_dbus_error(message, WLANCOND_ERROR_IOCTL_FAILED);
02564 goto param_err;
02565 }
02566
02567 if (iw_get_range_info(sock, wlan_status.ifname, &range) >= 0) {
02568 double freq = iw_freq2float(&(req.u.freq));
02569 channel = iw_freq_to_channel(freq, &range);
02570 }
02571
02572 if (channel < WLANCOND_MIN_WLAN_CHANNEL ||
02573 channel > WLANCOND_MAX_WLAN_CHANNEL) {
02574 channel = 0;
02575 DLOG_DEBUG("Got invalid channel\n");
02576 }
02577
02578
02579 init_iwreq(&req);
02580
02581 if (ioctl(sock, SIOCGIWMODE, &req) < 0) {
02582 DLOG_ERR("Could not get operating mode");
02583 reply = new_dbus_error(message, WLANCOND_ERROR_IOCTL_FAILED);
02584 goto param_err;
02585 }
02586
02587 if (req.u.mode == IW_MODE_ADHOC) {
02588 capability |= WLANCOND_ADHOC;
02589 } else if (req.u.mode == IW_MODE_INFRA) {
02590 capability |= WLANCOND_INFRA;
02591 }
02592
02593 init_iwreq(&req);
02594
02595
02596 security = wlan_status.conn.encryption;
02597
02598 #if 0
02599 key = g_malloc(IW_ENCODING_TOKEN_MAX);
02600 req.u.data.pointer = (caddr_t) key;
02601 req.u.data.length = IW_ENCODING_TOKEN_MAX;
02602 req.u.data.flags = 0;
02603
02604 if (ioctl(sock, SIOCGIWENCODE, &req) < 0) {
02605 reply = new_dbus_error(message, WLANCOND_ERROR_IOCTL_FAILED);
02606 goto param_err;
02607 }
02608
02609 if (req.u.data.flags & IW_ENCODE_OPEN)
02610 security |= WLANCOND_OPEN;
02611
02612 if (req.u.data.flags & IW_ENCODE_RESTRICTED)
02613 security |= WLANCOND_WEP;
02614
02615
02616 if (req.u.data.flags & IW_ENCODE_TKIP)
02617 security |= WLANCOND_WPA_PSK & WLANCOND_WPA_EAP &
02618 WLANCOND_WPA_TKIP;
02619
02620 if (req.u.data.flags & IW_ENCODE_AES)
02621 security |= WLANCOND_WPA_PSK & WLANCOND_WPA_EAP &
02622 WLANCOND_WPA_AES;
02623
02624 g_free(key);
02625 #endif
02626 init_iwreq(&req);
02627
02628
02629 if (ioctl(sock, SIOCGIWRATE, &req) < 0) {
02630 DLOG_ERR("Could not get the rate");
02631 }
02632 capability |= req.u.bitrate.value;
02633
02634 reply = new_dbus_method_return(message);
02635
02636 gchar* ifname = wlan_status.ifname;
02637
02638 append_dbus_args(reply,
02639 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
02640 &essid, essid_len,
02641 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &bssid, ETH_ALEN,
02642 DBUS_TYPE_UINT32, &sens,
02643 DBUS_TYPE_UINT32, &channel,
02644 DBUS_TYPE_UINT32, &capability,
02645 DBUS_TYPE_UINT32, &security,
02646 DBUS_TYPE_STRING, &ifname,
02647 DBUS_TYPE_INVALID);
02648
02649 send_and_unref(connection, reply);
02650
02651 g_free(essid);
02652 g_free(bssid);
02653
02654 return DBUS_HANDLER_RESULT_HANDLED;
02655
02656 param_err:
02657 g_free(essid);
02658 g_free(bssid);
02659
02660 if (reply == NULL) {
02661 DLOG_DEBUG("Parameter error in status request");
02662 reply = new_dbus_error(message, DBUS_ERROR_INVALID_ARGS);
02663 }
02664 send_and_unref(connection, reply);
02665 return DBUS_HANDLER_RESULT_HANDLED;
02666 }
02667
02674 static DBusHandlerResult interface_request(DBusMessage *message,
02675 DBusConnection *connection) {
02676 DBusMessage *reply;
02677 gchar* ifname = wlan_status.ifname;
02678
02679 reply = new_dbus_method_return(message);
02680
02681 append_dbus_args(reply,
02682 DBUS_TYPE_STRING, &ifname,
02683 DBUS_TYPE_INVALID);
02684
02685 send_and_unref(connection, reply);
02686
02687 return DBUS_HANDLER_RESULT_HANDLED;
02688 }
02689
02696 static DBusHandlerResult connection_status_request(
02697 DBusMessage *message,
02698 DBusConnection *connection) {
02699
02700 DBusMessage *reply;
02701 dbus_bool_t state = FALSE;
02702
02703 guint state_v = get_wlan_state();
02704
02705 if (state_v == WLAN_INITIALIZED ||
02706 state_v == WLAN_NO_ADDRESS ||
02707 state_v == WLAN_CONNECTED)
02708 state = TRUE;
02709
02710 reply = new_dbus_method_return(message);
02711
02712 append_dbus_args(reply,
02713 DBUS_TYPE_BOOLEAN, &state,
02714 DBUS_TYPE_INVALID);
02715
02716 send_and_unref(connection, reply);
02717
02718 return DBUS_HANDLER_RESULT_HANDLED;
02719 }
02726 static DBusHandlerResult set_pmksa_request(DBusMessage *message,
02727 DBusConnection *connection) {
02728
02729 DBusMessage *reply = NULL;
02730 unsigned int pmkid_len, mac_len;
02731 unsigned char *pmkid;
02732 unsigned char *mac;
02733 dbus_uint32_t action;
02734 DBusError derror;
02735
02736 dbus_error_init(&derror);
02737
02738 if (dbus_message_get_args(
02739 message, &derror,
02740 DBUS_TYPE_UINT32, &action,
02741 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &pmkid, &pmkid_len,
02742 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &mac, &mac_len,
02743 DBUS_TYPE_INVALID) == FALSE)
02744 {
02745 DLOG_ERR("Failed to parse set_pmksa request: %s",
02746 derror.message);
02747 dbus_error_free(&derror);
02748 goto param_err;
02749 }
02750
02751 if (action != IW_PMKSA_ADD) {
02752 DLOG_ERR("Invalid action");
02753 goto param_err;
02754 }
02755
02756 if (pmkid == NULL || pmkid_len != WLANCOND_PMKID_LEN || mac == NULL
02757 || mac_len != ETH_ALEN) {
02758 DLOG_ERR("Invalid arguments");
02759 goto param_err;
02760 }
02761
02762 add_to_pmksa_cache(pmkid, mac);
02763
02764 print_mac("PMKSA added successfully for address:", mac);
02765
02766 reply = new_dbus_method_return(message);
02767 send_and_unref(connection, reply);
02768
02769 return DBUS_HANDLER_RESULT_HANDLED;
02770
02771 param_err:
02772 if (reply == NULL) {
02773 DLOG_DEBUG("Parameter error in set_pmksa");
02774 reply = new_dbus_error(message, DBUS_ERROR_INVALID_ARGS);
02775 }
02776 send_and_unref(connection, reply);
02777 return DBUS_HANDLER_RESULT_HANDLED;
02778 }
02779
02786 static DBusHandlerResult set_powersave_request(DBusMessage *message,
02787 DBusConnection *connection) {
02788
02789 DBusMessage *reply = NULL;
02790 int sock;
02791 DBusError error;
02792 dbus_bool_t onoff;
02793
02794 sock = socket_open();
02795
02796 dbus_error_init(&error);
02797
02798 if (dbus_message_get_args(message, &error,
02799 DBUS_TYPE_BOOLEAN, &onoff,
02800 DBUS_TYPE_INVALID) == FALSE) {
02801 DLOG_ERR("Failed to parse message: %s",
02802 error.message);
02803 dbus_error_free(&error);
02804
02805 send_invalid_args(connection, message);
02806 return DBUS_HANDLER_RESULT_HANDLED;
02807 }
02808
02809
02810
02811
02812 if (onoff == TRUE) {
02813 if (get_wlan_state() == WLAN_NOT_INITIALIZED) {
02814 set_wlan_state(WLAN_NOT_INITIALIZED, NO_SIGNAL, FORCE_YES);
02815 } else if (get_wlan_state() != WLAN_NO_ADDRESS ||
02816 (connect_name_cache != NULL &&
02817 strcmp(dbus_message_get_sender(message),
02818 connect_name_cache) == 0)) {
02819 if (set_power_state(powersave, sock) == FALSE) {
02820 DLOG_ERR("Setting powersave failed");
02821
02822 }
02823 }
02824 } else {
02825
02826 if (set_power_state(WLANCOND_POWER_ON, sock) == FALSE) {
02827 DLOG_ERR("Setting powersave failed");
02828
02829 }
02830 }
02831
02832 DLOG_DEBUG("WLAN powersave %s", onoff==TRUE?"on":"off");
02833
02834 reply = new_dbus_method_return(message);
02835 send_and_unref(connection, reply);
02836
02837 return DBUS_HANDLER_RESULT_HANDLED;
02838 }
02839
02846 static void wpa_ie_push_cb(DBusPendingCall *pending,
02847 void *user_data)
02848 {
02849 DBusMessage *reply;
02850 DBusError error;
02851
02852
02853
02854 dbus_error_init (&error);
02855
02856 reply = dbus_pending_call_steal_reply(pending);
02857
02858 if (dbus_set_error_from_message(&error, reply)) {
02859
02860 DLOG_DEBUG("EAP WPA IE push call result:%s", error.name);
02861
02862 dbus_error_free(&error);
02863
02864 set_wlan_state(WLAN_NOT_INITIALIZED,
02865 DISCONNECTED_SIGNAL,
02866 FORCE_YES);
02867 }
02868
02869 if (reply)
02870 dbus_message_unref(reply);
02871 dbus_pending_call_unref(pending);
02872 }
02873
02882 int wpa_ie_push(unsigned char* ap_mac_addr, unsigned char* ap_wpa_ie,
02883 int ap_wpa_ie_len, char* ssid, int ssid_len,
02884 unsigned int authentication_type) {
02885
02886 DBusMessage *msg;
02887 DBusPendingCall *pending;
02888
02889 if (authentication_type != EAP_AUTH_TYPE_WFA_SC) {
02890 if (wlan_status.wpa_ie.ie_len == 0 || ap_wpa_ie == NULL ||
02891 ssid == NULL) {
02892 DLOG_ERR("WPA IE / SSID (%s) not valid", ssid);
02893 return -1;
02894 }
02895 }
02896
02897 msg = dbus_message_new_method_call(
02898 EAP_SERVICE,
02899 EAP_REQ_PATH,
02900 EAP_REQ_INTERFACE,
02901 EAP_WPA_IE_PUSH_REQ);
02902
02903 if (msg == NULL) {
02904 return -1;
02905 }
02906
02907 append_dbus_args(
02908 msg,
02909 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
02910 &wlan_status.wpa_ie.ie, wlan_status.wpa_ie.ie_len,
02911 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &ap_wpa_ie,
02912 ap_wpa_ie_len,
02913 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
02914 &ssid, ssid_len,
02915 DBUS_TYPE_UINT32, &wlan_status.pairwise_cipher,
02916 DBUS_TYPE_UINT32, &wlan_status.group_cipher,
02917 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
02918 &ap_mac_addr, ETH_ALEN,
02919 DBUS_TYPE_UINT32, &authentication_type,
02920 DBUS_TYPE_INVALID);
02921
02922 if (!dbus_connection_send_with_reply(get_dbus_connection(),
02923 msg, &pending, -1))
02924 die("Out of memory");
02925
02926 if (!dbus_pending_call_set_notify (pending, wpa_ie_push_cb, NULL, NULL))
02927 die("Out of memory");
02928
02929 dbus_message_unref(msg);
02930
02931 return 0;
02932 }
02939 int wpa_mic_failure_event(dbus_bool_t key_type, dbus_bool_t is_fatal) {
02940 DBusMessage *msg;
02941 DBusMessage *reply;
02942 DBusError derr;
02943
02944 msg = dbus_message_new_method_call(
02945 EAP_SERVICE,
02946 EAP_REQ_PATH,
02947 EAP_REQ_INTERFACE,
02948 EAP_WPA_MIC_FAILURE_REQ);
02949
02950 if (msg == NULL) {
02951 return -1;
02952 }
02953
02954 append_dbus_args(msg,
02955 DBUS_TYPE_BOOLEAN, &key_type,
02956 DBUS_TYPE_BOOLEAN, &is_fatal,
02957 DBUS_TYPE_INVALID);
02958
02959 dbus_error_init(&derr);
02960
02961 reply = dbus_connection_send_with_reply_and_block(
02962 get_dbus_connection(), msg, -1, &derr);
02963
02964 dbus_message_unref(msg);
02965
02966 if (dbus_error_is_set(&derr)) {
02967 DLOG_ERR("EAP returned error: %s", derr.name);
02968
02969 dbus_error_free(&derr);
02970 if (reply)
02971 dbus_message_unref(reply);
02972 return -1;
02973 }
02974
02975 dbus_message_unref(reply);
02976
02977 return 0;
02978 }
02983 int associate_supplicant(void) {
02984 DBusMessage *msg;
02985 DBusMessage *reply;
02986 DBusError derr;
02987
02988 msg = dbus_message_new_method_call(
02989 EAP_SERVICE,
02990 EAP_REQ_PATH,
02991 EAP_REQ_INTERFACE,
02992 EAP_ASSOCIATE_REQ);
02993
02994 if (msg == NULL) {
02995 return -1;
02996 }
02997
02998 dbus_error_init(&derr);
02999
03000 reply = dbus_connection_send_with_reply_and_block(
03001 get_dbus_connection(), msg, -1, &derr);
03002
03003 dbus_message_unref(msg);
03004
03005 if (dbus_error_is_set(&derr)) {
03006 DLOG_ERR("EAP returned error: %s", derr.name);
03007
03008 dbus_error_free(&derr);
03009 if (reply)
03010 dbus_message_unref(reply);
03011 return -1;
03012 }
03013
03014 dbus_message_unref(reply);
03015
03016 return 0;
03017 }
03024 static void disassociate_cb(DBusPendingCall *pending,
03025 void *user_data)
03026 {
03027 DBusMessage *reply;
03028 DBusError error;
03029
03030 dbus_error_init (&error);
03031
03032 reply = dbus_pending_call_steal_reply(pending);
03033
03034 if (dbus_set_error_from_message(&error, reply)) {
03035
03036 DLOG_DEBUG("EAP disassociate call result:%s", error.name);
03037
03038 dbus_error_free(&error);
03039 }
03040
03041 if (reply)
03042 dbus_message_unref(reply);
03043 dbus_pending_call_unref(pending);
03044 }
03045
03050 int disassociate_eap(void) {
03051 DBusMessage *msg;
03052 DBusPendingCall *pending;
03053
03054 msg = dbus_message_new_method_call(
03055 EAP_SERVICE,
03056 EAP_REQ_PATH,
03057 EAP_REQ_INTERFACE,
03058 EAP_DISASSOCIATE_REQ);
03059
03060 if (msg == NULL) {
03061 return -1;
03062 }
03063
03064 if (!dbus_connection_send_with_reply(get_dbus_connection(),
03065 msg, &pending, -1))
03066 die("Out of memory");
03067
03068 if (!dbus_pending_call_set_notify (pending, disassociate_cb, NULL,
03069 NULL))
03070 die("Out of memory");
03071
03072 dbus_message_unref(msg);
03073
03074 return 0;
03075 }
03076
03077 typedef DBusHandlerResult (*handler_func)(DBusMessage *message,
03078 DBusConnection *connection);
03079
03080 typedef struct {
03081 const char *interface;
03082 const char *name;
03083 handler_func func;
03084 } method_handler_t;
03085
03086 static method_handler_t handlers[] = {
03087 { WLANCOND_REQ_INTERFACE, WLANCOND_SETTINGS_AND_CONNECT_REQ, settings_and_connect_request},
03088 { WLANCOND_REQ_INTERFACE, WLANCOND_SCAN_REQ, scan_request},
03089 { WLANCOND_REQ_INTERFACE, WLANCOND_STATUS_REQ, status_request},
03090 { WLANCOND_REQ_INTERFACE, WLANCOND_INTERFACE_REQ, interface_request},
03091 { WLANCOND_REQ_INTERFACE, WLANCOND_CONNECTION_STATUS_REQ, connection_status_request},
03092 { WLANCOND_REQ_INTERFACE, WLANCOND_SET_PMKSA_REQ, set_pmksa_request},
03093 { WLANCOND_REQ_INTERFACE, WLANCOND_SET_POWERSAVE_REQ, set_powersave_request},
03094 { WLANCOND_REQ_INTERFACE, WLANCOND_DISCONNECT_REQ, disconnect_request},
03095 { WLANCOND_REQ_INTERFACE, WLANCOND_DISASSOCIATE_REQ, disassociate_request},
03096 { NULL }
03097 };
03098
03105 DBusHandlerResult wlancond_req_handler(DBusConnection *connection,
03106 DBusMessage *message,
03107 void *user_data) {
03108 method_handler_t *handler;
03109
03110
03111
03112
03113
03114
03115 #ifdef USE_MCE_MODE
03116 if (dbus_message_is_signal(message,
03117 MCE_SIGNAL_IF,
03118 MCE_DEVICE_MODE_SIG)) {
03119 return mode_change_dbus(message);
03120 }
03121 #ifdef ACTIVITY_CHECK
03122 if (dbus_message_is_signal(message,
03123 MCE_SIGNAL_IF,
03124 MCE_INACTIVITY_SIG)) {
03125 return activity_check_dbus(message);
03126 }
03127 #endif
03128 #endif
03129 if (dbus_message_is_signal(message,
03130 ICD_DBUS_INTERFACE,
03131 ICD_STATUS_CHANGED_SIG))
03132 return icd_check_signal_dbus(message);
03133
03134
03135 if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_METHOD_CALL) {
03136 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
03137 }
03138
03139 for (handler = handlers; handler->interface != NULL; handler++) {
03140 if (dbus_message_is_method_call(message,
03141 handler->interface,
03142 handler->name)) {
03143 DLOG_DEBUG("Received %s", handler->name);
03144 return handler->func(message, connection);
03145 }
03146 }
03147 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
03148 }
03149
03150 static DBusObjectPathVTable wlancond_req_vtable = {
03151 .message_function = wlancond_req_handler,
03152 .unregister_function = NULL
03153 };
03154
03155
03160 void init_dbus_handlers(DBusConnection *connection) {
03161 dbus_bool_t ret;
03162 ret = dbus_connection_register_object_path(connection,
03163 WLANCOND_REQ_PATH,
03164 &wlancond_req_vtable,
03165 NULL);
03166 if (ret == FALSE) {
03167 DLOG_ERR("dbus_connection_register_object_path failed");
03168 }
03169 #ifdef USE_MCE_MODE
03170 if (!add_mode_listener(connection)) {
03171 DLOG_ERR("Adding mode listener failed");
03172 }
03173 #endif
03174 if (!add_icd_listener(connection)) {
03175 DLOG_ERR("Adding icd listener failed");
03176 }
03177 }
03178
03183 void destroy_dbus_handlers(DBusConnection *connection) {
03184 dbus_connection_unregister_object_path(connection, WLANCOND_REQ_PATH);
03185 }