GUIで無線LANを有効にする

Android の画面上で無線LANを有効にするには…?

このページは、無線LANを有効にするからの続きのページです。

wpa_supplicant のクライアントとして Android を認識させる wrapper の役割になります。

下記を編集…
$ANDROID_SRC/hardware/libhardware_legacy/wifi/wifi.c
する…、のだが…、
これをとりあえず動くようにするだけで…、結構かかりました。。。

しかも、ソースコードはデバッグ情報出力でズタボロ。。。
Android の一次情報をしっかり読んでいれば分かるんでしょうが、
エラー&トライのような感じで。。。Androidの wext がドライバに要求するコマンドを
実ドライバにバイパスしないといけないのだが、面倒なので無視する事にした。

後で、wext の要求を見てどうするか考える。

そうして出来たのが下記コード…。もう、きっちり型変換はしてないし、
usleepはいい加減な値だし、driver の有効化の部分は一応チェックは入れたがまだ甘いし。
本来は Android.mk で指定しなければならない、定数などはハードコーディングしているし…。
文字列ポインタや文字数は少なければ安全だろうと…いうことで。

本ページサイトの情報は全て無保証であるがままです。
かなり不安定ですので、そのまま実用には耐えません。
それなりに使えるようになっています、デバッグでは無いときはlog出力コメントアウトするのがオススメ。
Ver.0.0.2α 初期公開から更新しました。 2010/12/31 13:20)
Ver.0.0.3α_20110101_00 若干、安定化させました (2011/01/01 02:18)
無効化しているコマンドですが、本来的には reply ポインタに文字列を返さなければいけません。
そこに、len=0にしてリターンしていますが、上位層及び下位層の影響範囲を調べていません。
  • 無線LANアクセスポイントの新規追加できません。(1.6の時に接続していた先は大丈夫と思います)
  • データ通信速度取得できません。
  • 無線LAN RSSI 取得出来ません。
Ver.0.0.4α_20110105_00 IS01向けwpa_supplicant GPLソースマージ。コマンド無視部分をコメントアウト (2011/01/05 19:05)
IS01向けGPLソースの external/wpa_supplicant/driver_wext.c を利用する事で、下記コードの wifi_send_command() からswitch文をごっそり削除できます。RSSIの取得には対応してないようなので、後で検討します。下記コードはIS01向けGPLソースの external/wpa_supplicant/driver_wext.c をマージした場合の wifi.c になります。マージしてない場合は、switch文部分のコメント一連のコメントを外してして下さい。
fi01氏よりの情報にてGUIにおいてもRSSIの取得が可能になりました。
  • 無線LANアクセスポイントの新規追加、検証していません。
  • データ通信速度取得できるようになりました。
  • 無線LAN RSSI 取得できるようになりました。
/*
 * Copyright 2008, The Android Open Source Project
 * Copyright 2011, RO178 is01rebuid
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

#include "hardware_legacy/wifi.h"
#include "libwpa_client/wpa_ctrl.h"

#define LOG_TAG "WifiHW"
#include "cutils/log.h"
#include "cutils/memory.h"
#include "cutils/misc.h"
#include "cutils/properties.h"
#include "private/android_filesystem_config.h"
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
#include <sys/_system_properties.h>
#endif

static struct wpa_ctrl *ctrl_conn;
static struct wpa_ctrl *monitor_conn;

extern int do_dhcp();
extern int ifc_init();
extern void ifc_close();
extern char *dhcp_lasterror();
extern void get_dhcp_info();
extern int init_module(void *, unsigned long, const char *);
extern int delete_module(const char *, unsigned int);

static char iface[PROPERTY_VALUE_MAX];
// TODO: use new ANDROID_SOCKET mechanism, once support for multiple
// sockets is in

#ifndef WIFI_DRIVER_MODULE_PATH
#define WIFI_DRIVER_MODULE_PATH         "/system/lib/modules/wlan.ko"
#endif
#ifndef WIFI_DRIVER_MODULE_NAME
#define WIFI_DRIVER_MODULE_NAME         "wlan"
#endif
#ifndef WIFI_DRIVER_MODULE_ARG
#define WIFI_DRIVER_MODULE_ARG          ""
#endif
#ifndef WIFI_FIRMWARE_LOADER
#define WIFI_FIRMWARE_LOADER		""
#endif
#define WIFI_TEST_INTERFACE		"sta"

#define WIFI_DRIVER_LOADER_DELAY	2000000
static const char WLAN0_DEVICE[]         = "/sys/devices/platform/msm_sdcc.1/mmc_host/mmc1/mmc1:0001/mmc1:0001:1/net/wlan0/wireless/status"; // "/sys/class/net/wlan0";

static const char IFACE_DIR[]           = "/data/misc/wifi/sockets"; //"/data/system/wpa_supplicant";
static const char DRIVER_MODULE_NAME[]  = "unifi_sdio.ko"; //WIFI_DRIVER_MODULE_NAME;
static const char DRIVER_MODULE_TAG[]   = "unifi_sdio.ko"; // WIFI_DRIVER_MODULE_NAME;
static const char DRIVER_MODULE_PATH[]  = "/system/lib/modules/unifi_sdio.ko"; //WIFI_DRIVER_MODULE_PATH;
static const char DRIVER_MODULE_ARG[]   = ""; //WIFI_DRIVER_MODULE_ARG;
static const char FIRMWARE_LOADER[]     = ""; //WIFI_FIRMWARE_LOADER;
static const char DRIVER_PROP_NAME[]    = "wlan.driver.status";
static const char SUPPLICANT_NAME[]     = "wpa_supplicant";
static const char SUPP_PROP_NAME[]      = "init.svc.wpa_supplicant";
static const char SUPP_CONFIG_TEMPLATE[]= "/system/etc/wifi/wpa_supplicant.conf";
static const char SUPP_CONFIG_FILE[]    = "/data/misc/wifi/wpa_supplicant.conf";
static const char MODULE_FILE[]         = "/proc/modules";



static int insmod(const char *filename, const char *args)
{
  LOGD( "wifi: %s(): function in", __FUNCTION__ );
  /*    void *module;
    unsigned int size;
    int ret;

    module = load_file(filename, &size);
    if (!module)
        return -1;

    ret = init_module(module, size, args);

    free(module);

    return ret;
  */
  int ret;

  char command[]="echo 1 > /sys/devices/platform/bwpm/wifi";
  char command2[]="echo 1 > /sys/bus/platform/drivers/msm_sdcc/msm_sdcc.1/polling";

  property_set( "ctl.stop"   , "dhcpcd" );
  sched_yield();
  //property_set( "ctl.stop "  , "wpa_supplicant" );
  //sched_yield();

  ret=system(command);
  LOGD( "wifi: %s(): %s  ret=%d" , __FUNCTION__ , command ,ret);
  sched_yield();
  usleep(100000);
  ret=system(command2);
  sched_yield();
  LOGD( "wifi: %s(): %s  ret=%d" , __FUNCTION__ , command2 , ret );
  int maxtry = 10;
  char text[256];

  while (maxtry-- > 0) {
    if (access( WLAN0_DEVICE , R_OK ) == 0) {
      FILE *fp;
      if ((fp = fopen( WLAN0_DEVICE , "r")) != NULL ) {
         fgets(text, 256, fp);
         LOGV( "wifi: %s(): wlan0 status=%s" , __FUNCTION__ , text );
         if ( strncmp( text , "0x0" , 3 ) == 0) {
              LOGD( "wifi: %s(): wlan0 enabled!" , __FUNCTION__  );
              return 0;
         }
         fclose(fp);
      }
    }  
    else
      LOGV( "wifi: %s(): wait for enable wlan0 ...." , __FUNCTION__ );

    usleep(500000);
  }
  
  return -1;
}

static int rmmod(const char *modname)
{
  LOGD( "wifi: %s(): function in", __FUNCTION__ );
  /*    int ret = -1;
    int maxtry = 10;

    while (maxtry-- > 0) {
        ret = delete_module(modname, O_NONBLOCK | O_EXCL);
        if (ret < 0 && errno == EAGAIN)
            usleep(500000);
        else
            break;
    }

  */

  int ret=-1;
  char command[]="echo 0 > /sys/devices/platform/bwpm/wifi";
  char command2[]="echo 0 > /sys/bus/platform/drivers/msm_sdcc/msm_sdcc.1/polling";

  ret=system(command);
  LOGD( "wifi: %s(): %s  ret=%d" , __FUNCTION__ , command ,ret);
  usleep(200000);
  ret=system(command2);
  LOGD( "wifi: %s(): %s  ret=%d" , __FUNCTION__ , command2 , ret );

  int maxtry = 50;
  while (maxtry-- > 0) {
    if ( (ret=access( WLAN0_DEVICE , R_OK )) == 0) {
      LOGD( "wifi: %s(): wait for disable wlan0 ...." , __FUNCTION__ );
      usleep(100000);
    }  
    else {
      LOGD("wifi: %s(): wlan0 driver Disabled! return " , __FUNCTION__ );
      return 0;
    }
  }

  if (ret == 0)
    LOGE("wifi: %s(): Unable to disable wlan0 driver return 0;", __FUNCTION__);

  return -1;
}

int do_dhcp_request(int *ipaddr, int *gateway, int *mask,
                    int *dns1, int *dns2, int *server, int *lease) {
  LOGD( "wifi: %s(): function in", __FUNCTION__ );

    /* For test driver, always report success */
   if (strcmp(iface, WIFI_TEST_INTERFACE) == 0)
     return 0;

    if (ifc_init() < 0)
        return -1;

    LOGD( "wifi: %s(): sleep 1sec...." , __FUNCTION__ );
    usleep(1000000);
   
    if (do_dhcp(iface) < 0) {
        ifc_close();
        return -1;
    }
    ifc_close();
    get_dhcp_info(ipaddr, gateway, mask, dns1, dns2, server, lease);
    return 0;
}

const char *get_dhcp_error_string() {
  LOGD( "wifi: %s(): function in", __FUNCTION__ );
    return dhcp_lasterror();
}

static int check_driver_loaded() {
    char driver_status[PROPERTY_VALUE_MAX];
    FILE *proc;
    char line[sizeof(DRIVER_MODULE_TAG)+10];

      LOGD( "wifi: %s(): function in", __FUNCTION__ );
    if (!property_get(DRIVER_PROP_NAME, driver_status, NULL)
            || strcmp(driver_status, "ok") != 0) {
      LOGD( "wifi: %s(): driver not loaded.", __FUNCTION__ );
        return 0;  /* driver not loaded */
    }

    /*
     * If the property says the driver is loaded, check to
     * make sure that the property setting isn't just left
     * over from a previous manual shutdown or a runtime
     * crash.
     */
    if ((proc = fopen(MODULE_FILE, "r")) == NULL) {
      LOGW("wifi: %s(): Could not open %s: %s", __FUNCTION__ , MODULE_FILE, strerror(errno));
      LOGW("wifi: %s(): property_set( \"%s\" , \"unloaded\");", __FUNCTION__  , DRIVER_PROP_NAME );
      property_set(DRIVER_PROP_NAME, "unloaded");
        return 0;
    }
    while ((fgets(line, sizeof(line), proc)) != NULL) {
        if (strncmp(line, DRIVER_MODULE_TAG, strlen(DRIVER_MODULE_TAG)) == 0) {
            fclose(proc);
	    LOGD( "wifi: %s(): driver loaded", __FUNCTION__ );
            return 1;
        }
    }
    fclose(proc);
    LOGD( "wifi: %s(): property_set( \"%s\" , \"unloaded\");",__FUNCTION__ , DRIVER_PROP_NAME );
    property_set(DRIVER_PROP_NAME, "unloaded");
    return 0;
}

int wifi_load_driver()
{
  LOGD( "wifi: %s(): function in", __FUNCTION__ );

    char driver_status[PROPERTY_VALUE_MAX];
    int count = 100; /* wait at most 20 seconds for completion */

    if (check_driver_loaded()) {
        return 0;
    }
    LOGD( "wifi: %s(): check driver .... true.",__FUNCTION__);
    if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0) {
      LOGE( "wifi: %s(): try insmod %s %s ....false,",__FUNCTION__,DRIVER_MODULE_PATH, DRIVER_MODULE_ARG);
        return -1;
    }
    LOGD( "wifi: %s(): try insmod %s %s ....true.",__FUNCTION__,DRIVER_MODULE_PATH, DRIVER_MODULE_ARG);

    if (strcmp(FIRMWARE_LOADER,"") == 0) {
      LOGD( "wifi: %s(): none FIRMWARE_LOADER." , __FUNCTION__);
      LOGD( "wifi: %s(): sleep %dusec...." , __FUNCTION__ , WIFI_DRIVER_LOADER_DELAY );
      usleep(WIFI_DRIVER_LOADER_DELAY);
      LOGD( "wifi: %s(): property_set( \"%s\", \"ok\" ) ." , DRIVER_PROP_NAME ,__FUNCTION__);
      property_set(DRIVER_PROP_NAME, "ok");
    }
    else {
      LOGD( "wifi: %s(): property_set( ctl.start, %s )",__FUNCTION__  , FIRMWARE_LOADER );
      property_set("ctl.start", FIRMWARE_LOADER);
    }
    sched_yield();
    while (count-- > 0) {
        usleep(200000);
        if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) {
            if (strcmp(driver_status, "ok") == 0) {
	      LOGD( "wifi: %s(): driver status ... true",__FUNCTION__);
	      return 0;
            }
            else if (strcmp(DRIVER_PROP_NAME, "failed") == 0) {
	      wifi_unload_driver();
	      LOGD( "wifi: %s(): call driver unload",__FUNCTION__);
	      return -1;
            }
        }
    }
    property_set(DRIVER_PROP_NAME, "timeout");
    wifi_unload_driver();
    return -1;
}

int wifi_unload_driver()
{
  LOGD( "wifi: %s(): function in", __FUNCTION__ );
    int count = 20; /* wait at most 10 seconds for completion */

    if (rmmod(DRIVER_MODULE_NAME) == 0) {
	while (count-- > 0) {
	    if (!check_driver_loaded())
		break;
    	    usleep(500000);
	}
	if (count) {
    	    return 0;
	}
	return -1;
    } else
        return -1;

    return 0;
}

int ensure_config_file_exists()
{
  LOGD( "wifi: %s(): function in", __FUNCTION__ );
    char buf[2048];
    int srcfd, destfd;
    int nread;

    if (access(SUPP_CONFIG_FILE, R_OK|W_OK) == 0) {
        return 0;
    } else if (errno != ENOENT) {
      LOGE("wifi: %s(): Cannot access \"%s\": %s", __FUNCTION__ , SUPP_CONFIG_FILE, strerror(errno));
        return -1;
    }

    srcfd = open(SUPP_CONFIG_TEMPLATE, O_RDONLY);
    if (srcfd < 0) {
      LOGE("wifi: %s(): Cannot open \"%s\": %s", __FUNCTION__ , SUPP_CONFIG_TEMPLATE, strerror(errno));
        return -1;
    }

    destfd = open(SUPP_CONFIG_FILE, O_CREAT|O_WRONLY, 0660);
    if (destfd < 0) {
        close(srcfd);
        LOGE("wifi: %s(): Cannot create \"%s\": %s", __FUNCTION__ , SUPP_CONFIG_FILE, strerror(errno));
        return -1;
    }

    while ((nread = read(srcfd, buf, sizeof(buf))) != 0) {
        if (nread < 0) {
            LOGE("wifi: %s(): Error reading \"%s\": %s", __FUNCTION__ , SUPP_CONFIG_TEMPLATE, strerror(errno));
            close(srcfd);
            close(destfd);
            unlink(SUPP_CONFIG_FILE);
            return -1;
        }
        write(destfd, buf, nread);
    }

    close(destfd);
    close(srcfd);

    if (chown(SUPP_CONFIG_FILE, AID_SYSTEM, AID_WIFI) < 0) {
        LOGE("wifi: %s(): Error changing group ownership of %s to %d: %s",
             __FUNCTION__ , SUPP_CONFIG_FILE, AID_WIFI, strerror(errno));
        unlink(SUPP_CONFIG_FILE);
        return -1;
    }
    return 0;
}

int wifi_start_supplicant()
{
    char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
    int count = 200; /* wait at most 20 seconds for completion */
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
    const prop_info *pi;
    unsigned serial = 0;
#endif
    LOGD("wifi:%s():function in" , __FUNCTION__  );

    /* Check whether already running */
    if (property_get(SUPP_PROP_NAME, supp_status, NULL)
            && strcmp(supp_status, "running") == 0) {

      LOGD("wifi:%s():wpa supplicant running" , __FUNCTION__  );
        return 0;
    }

      property_set("ctl.start", "wpa_supplicant");
      return 0;

    /* Before starting the daemon, make sure its config file exists */
   if (ensure_config_file_exists() < 0) {
      LOGE("wifi: %s(): Wi-Fi will not be enabled", __FUNCTION__ );
        return -1;
	}

    /* Clear out any stale socket files that might be left over. */
    wpa_ctrl_cleanup();

#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
    /*
     * Get a reference to the status property, so we can distinguish
     * the case where it goes stopped => running => stopped (i.e.,
     * it start up, but fails right away) from the case in which
     * it starts in the stopped state and never manages to start
     * running at all.
     */
    pi = __system_property_find(SUPP_PROP_NAME);
    if (pi != NULL) {
        serial = pi->serial;
    }
#endif
    property_set("ctl.start", SUPPLICANT_NAME);
    LOGD("wifi: %s(): property_set(\"ctl.start\", %s );" , __FUNCTION__ , SUPPLICANT_NAME );
    sched_yield();
    while (count-- > 0) {
        usleep(100000);
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
        if (pi == NULL) {
            pi = __system_property_find(SUPP_PROP_NAME);
        }
        if (pi != NULL) {
            __system_property_read(pi, NULL, supp_status);
            if (strcmp(supp_status, "running") == 0) {
                return 0;
            } else if (pi->serial != serial &&
                    strcmp(supp_status, "stopped") == 0) {
                return -1;
            }
        }
#else
        if (property_get(SUPP_PROP_NAME, supp_status, NULL)) {
	  if (strcmp(supp_status, "running") == 0) {
	    LOGD("wifi: %s(): wpa supplicant running" , __FUNCTION__  );
	    return 0;
	  }
        }
#endif
    }

    LOGE("wifi: %s(): timeout!" , __FUNCTION__ );
    return -1;
}

int wifi_stop_supplicant()
{
    char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
    int count = 50; /* wait at most 5 seconds for completion */

    /* Check whether supplicant already stopped */
    if (property_get(SUPP_PROP_NAME, supp_status, NULL)
        && strcmp(supp_status, "stopped") == 0) {
        return 0;
    }

    LOGD( "wifi: %s(): stop wpa_supplicant...", __FUNCTION__ );
    property_set("ctl.stop", SUPPLICANT_NAME);
    sched_yield();
    while (count-- > 0) {
        usleep(100000);
        if (property_get(SUPP_PROP_NAME, supp_status, NULL)) {
            if (strcmp(supp_status, "stopped") == 0)
                return 0;
        }
    }
    return -1;
}

int wifi_connect_to_supplicant()
{
    char ifname[256];
    char supp_status[PROPERTY_VALUE_MAX] = {'\0'};

    LOGD( "wifi: %s(): function in", __FUNCTION__ );

    /* Make sure supplicant is running */
    if (!property_get(SUPP_PROP_NAME, supp_status, NULL)
            || strcmp(supp_status, "running") != 0) {
      LOGE("wifi: %s(): Supplicant not running, cannot connect", __FUNCTION__);
        return -1;
    }

    property_get("wifi.interface", iface, WIFI_TEST_INTERFACE);
    LOGD("wifi: %s(): property_get(\"wifi.interface\", iface, WIFI_TEST_INTERFACE);" , __FUNCTION__ );
    LOGD("wifi: %s():        iface=%s", __FUNCTION__ , iface );

    LOGD("wifi: %s(): IFACE_DIR=%s", __FUNCTION__  , IFACE_DIR );
        if (access(IFACE_DIR, F_OK) == 0) {
      LOGD("wifi: %s(): IFACE_DIR ok", __FUNCTION__ );
        snprintf(ifname, sizeof(ifname), "%s/%s", IFACE_DIR, iface);
    } else {
      LOGE("wifi: %s(): IFACE_DIR NG", __FUNCTION__ );
      LOGE("wifi: %s(): IFACE_DIR check error=%s", __FUNCTION__ , strerror(errno) );

    strlcpy(ifname, iface, sizeof(ifname));
    }

    LOGD("wifi: %s():        ifname=%s", __FUNCTION__ , ifname );

    LOGD("wifi: %s(): wpa_ctrl_open(%s);", __FUNCTION__ , ifname);

    ctrl_conn = wpa_ctrl_open(ifname);
    if (ctrl_conn == NULL) {
        LOGE("wifi: %s(): Unable to open connection to supplicant on \"%s\": %s",
             __FUNCTION__ , ifname, strerror(errno));
        return -1;
    }
    monitor_conn = wpa_ctrl_open(ifname);
    if (monitor_conn == NULL) {
        wpa_ctrl_close(ctrl_conn);
        ctrl_conn = NULL;
        return -1;
    }
    if (wpa_ctrl_attach(monitor_conn) != 0) {
        wpa_ctrl_close(monitor_conn);
        wpa_ctrl_close(ctrl_conn);
        ctrl_conn = monitor_conn = NULL;
        return -1;
    }
    return 0;
}

int wifi_send_command(struct wpa_ctrl *ctrl, const char *cmd, char *reply, size_t *reply_len)
{
  static const char *zero="";
    int ret;
    char text[256];

    LOGD( "wifi: %s(): function in command=%s", __FUNCTION__ , cmd );

    if (ctrl_conn == NULL) {
      LOGV("wifi: %s(): Not connected to wpa_supplicant - \"%s\" command dropped.\n", __FUNCTION__ , cmd);
        return -1;
    }

    /* switch(cmd[0]) {
    case 'B':
      if( strncmp(cmd , "BLACKLIST" , 9 ) == 0 ) {
	LOGW( "wifi: %s(): function     command=%s comannd ignored! return 0;",
	      __FUNCTION__  , cmd );
	*reply_len=0;
	return 0;
     }
     break;

   case 'D':
     if( strncmp(cmd , "DRIVER RSSI-APPROX" , 18) == 0 ) {
	LOGW( "wifi: %s(): function     command=%s comannd ignored! return 0;",
	      __FUNCTION__ , cmd );
	reply="";
	*reply_len=0;
	return 0;
     }
     if( strncmp(cmd , "DRIVER LINKSPEED" , 16) == 0 ) {
	LOGW( "wifi: %s(): function     command=%s comannd ignored! return 0;",
	      __FUNCTION__ , cmd );
	reply="";
	*reply_len=0;
	return 0;
     }
     else if( strncmp(cmd , "DRIVER" , 6) == 0 ) {
	LOGW( "wifi: %s(): function     command=%s comannd ignored! return 0;",
	      __FUNCTION__ , cmd );
	*reply_len=0;
	return 0;
      }
     break;

   case 'G':
     if( strncmp(cmd , "GET_" , 4 ) == 0 ) {
	LOGW( "wifi: %s(): function     command=%s comannd ignored! return 0;",
	      __FUNCTION__ , cmd );
	*reply_len=0;
	return 0;
     }
     break;
   } */

    ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), reply, reply_len, NULL);
    snprintf( text , 254 , "%s" , reply );
    text[((*reply_len<256)?*reply_len:255)]='\0';

    if (ret == -2) {
      LOGD("wifi: %s(): '%s' command timed out.", __FUNCTION__ , cmd);
        return -2;
    }

    else if (ret < 0 || strncmp(reply, "FAIL", 4 ) == 0 ) {
      LOGE( "wifi: %s(): function     command=%s (reply=FAIL || ret<0) reply=%s length=%d ret=%d return -1;",
	    __FUNCTION__ , cmd, text, *reply_len , ret );
      return -1;
    }

    LOGD( "wifi: %s(): function     command=%s reply=%s ret=%d", __FUNCTION__ , cmd , text , ret );

    if (strncmp(cmd, "PING", 4) == 0) {
        reply[*reply_len] = '\0';
    }

    return 0;
}

int wifi_wait_for_event(char *buf, size_t buflen)
{
    size_t nread = buflen - 1;
    int fd;
    fd_set rfds;
    int result;
    struct timeval tval;
    struct timeval *tptr;
    LOGD( "wifi: %s(): function in", __FUNCTION__ );

    if (monitor_conn == NULL) {
      LOGD("wifi: %s(): Connection closed\n" , __FUNCTION__ );
        strncpy(buf, WPA_EVENT_TERMINATING " - connection closed", buflen-1);
        buf[buflen-1] = '\0';
        return strlen(buf);
    }

    result = wpa_ctrl_recv(monitor_conn, buf, &nread);
    if (result < 0) {
      LOGD("wifi: %s(): wpa_ctrl_recv failed: %s\n", __FUNCTION__ , strerror(errno));
        strncpy(buf, WPA_EVENT_TERMINATING " - recv error", buflen-1);
        buf[buflen-1] = '\0';
        return strlen(buf);
    }
    buf[nread] = '\0';
    /* LOGD("wait_for_event: result=%d nread=%d string=\"%s\"\n", result, nread, buf); */
    /* Check for EOF on the socket */
    if (result == 0 && nread == 0) {
        /* Fabricate an event to pass up */
      LOGD("wifi: %s(): Received EOF on supplicant socket" , __FUNCTION__ );
        strncpy(buf, WPA_EVENT_TERMINATING " - signal 0 received", buflen-1);
        buf[buflen-1] = '\0';
        return strlen(buf);
    }
    /*
     * Events strings are in the format
     *
     *     <N>CTRL-EVENT-XXX 
     *
     * where N is the message level in numerical form (0=VERBOSE, 1=DEBUG,
     * etc.) and XXX is the event name. The level information is not useful
     * to us, so strip it off.
     */
    if (buf[0] == '<') {
        char *match = strchr(buf, '>');
        if (match != NULL) {
            nread -= (match+1-buf);
            memmove(buf, match+1, nread+1);
        }
    }
    return nread;
}

void wifi_close_supplicant_connection()
{
  LOGD( "wifi: %s(): function in", __FUNCTION__ );

    if (ctrl_conn != NULL) {
        wpa_ctrl_close(ctrl_conn);
        ctrl_conn = NULL;
    }
    if (monitor_conn != NULL) {
        wpa_ctrl_close(monitor_conn);
        monitor_conn = NULL;
    }
}

int wifi_command(const char *command, char *reply, size_t *reply_len)
{
    return wifi_send_command(ctrl_conn, command, reply, reply_len);
}

RSSI(電界強度)をGUIに反映させるには?

fi01さんより、RSSI値をAndroid GUIに反映させる修正をコメントに頂きました。
driver_wext.c はシャープのWebサイトより、IS01向けGPLソースを取得して driver_wext.c のみ利用した。
$ diff -u driver_wext.c.gpl_is01 driver_wext.c
--- driver_wext.c.gpl_is01	2011-01-13 22:05:39.827724368 +0900
+++ driver_wext.c	2011-01-13 22:06:34.807605306 +0900
@@ -2715,7 +2715,7 @@
     }
     else if( os_strncasecmp(cmd, "scan-channels", 13) == 0 ) {
     }
-    else if( os_strcasecmp(cmd, "rssi") == 0 ) {
+    else if( os_strcasecmp(cmd, "rssi") == 0 || os_strcasecmp(cmd, "rssi-approx") == 0 ) {
 		struct iwreq wrq;
 		struct iw_statistics stats;
 		signed int rssi;
以上。

コメント
  • テスト -- (is01rebuild ) 2011-01-05 15:14:10
  • IS01向けGPLソースでのRSSIの取得は下記でよいかもです。
    - else if( os_strcasecmp(cmd, "rssi") == 0 ) {
    + else if( os_strcasecmp(cmd, "rssi") == 0 || os_strcasecmp(cmd, "rssi-approx") == 0 ) -- (fi01) 2011-01-13 16:54:22
  • fi01さん、ありがとうございます。
    追って、組み込みます。
    wpa_supplicant/driver_wext.c
    はまだ、全く見ていなかったので助かります。
    私がすると、/sysから直接読み込むところでした^^; -- (is01rebuild ) 2011-01-13 21:19:04
  • # echo 0 > wifi
    # echo 0 > polling
    # echo 1 > wifi
    # echo 1 > polling
    # stop synergy_service
    # start synergy_service
    でwlan0が復活することが確認できました。
    wifi.cを上手く書き換えると確実性が上がるかもしれません。 -- (RO215IS01) 2011-01-14 04:29:06
  • wpa_ctrl_openで"/dev/socket/wpa_wlan0"を指定すれば
    "/data/misc/wifi/wpa_supplicant.conf"の修正
    ctrl_interface=DIR=/data/misc/wifi/sockets
    は不要です。 -- (fi01) 2011-01-14 08:56:30
  • 自ビルドcyanogenmodの場合は設定ファイルの修正が必要でした。
    dhcpでIPアドレス取得後すぐに切断されてしまう場合は下記を適用してみてください。
    system/etc/dhcpcd/dhcpcd-run-hooks
    - if ls "${hook}" >/dev/null 2>&1; then
    + if [ -f "${hook}" ]; then
    -- (fi01) 2011-01-14 14:46:51
  • RO215IS01さん、fi01さんありがとうございます。
    wpa_ctrl_openで"/dev/socket/wpa_wlan0"は後ほど試してみます。
    wiki内にマージします。
    デフォルトのservice起動では
    socket wpa_wlan0 dgram 660 wifi wifi
    が指定されてますので、それを利用という形でしょうか。
    wpa_supplicant も Android もかなりの素人なので助かります。

    現段階でAndroidのバージョンが、2.2_r1.3、2.2.1_r1、2.3.1r1、
    CyanogenMod6(でしょうか?)の情報が入ってきていますので、
    本wikiでもバージョン毎の差異をまとめないといけないですね。
    ベースが大きく変わらなければほぼ同一の内容でいけるとは思いますが。 -- (is01rebuild ) 2011-01-14 18:52:20
  • No spitting on the street.I know what you wantHe resolved to give up smoking.The teams are coming onto the field.What's the weather like to day? Does the computer ever make a mistake.It rather surprised me.Is this the fight bus for the Capital Library? Cancer is a deadly disease.Will you connect this wire to the television ? -- (http://oakleyfrogskins2.cabanova.com/) 2013-03-17 06:38:29
名前:
コメント:

すべてのコメントを見る















最終更新:2011年01月19日 00:58
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。