勇闖新世界︰ W!o《卡夫卡村》變形祭︰圓局定向‧三

從實用性來講,要是非得連上『無線阡陌網』,否則不能使用那個『定向器』,除非為了安全顧慮,大概並不方便。那麼將如何用 Python WiFi 來取得 AP 『熱點資訊』 的呢?由於作者不知道哪裡有文件可讀?所以只是依著玩遊戲『過關』之精神,到處看看,隨便試試,這或許就是『互動式』程式的好處吧!略將結果整理如下︰

 

pi@raspberrypi ~ 
*** QuickLaTeX cannot compile formula:
sudo python
Python 2.7.3 (default, Mar 18 2014, 05:13:23) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from pythonwifi.iwlibs import Wireless

# 選取 WiFi 裝置
>>> wifi = Wireless('wlan0')

# AP 熱點掃描
>>> iwScan = wifi.scan()

# 探詢掃描物件屬性
>>> dir(iwScan)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__len__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_parse', 'aplist', 'getScan', 'ifname', 'index', 'next', 'range', 'stream']

# AP 表列物件
>>> apList = iwScan.aplist

# AP 表列物件屬性
>>> dir(apList[1])
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'addEvent', 'bssid', 'custom', 'display', 'encode', 'essid', 'frequency', 'mode', 'protocol', 'quality', 'range', 'rate']

# 探詢某一 AP 物件
>>> apList[1].essid
'iHOME'
>>> apList[1].bssid
'78:54:2E:FB:77:B0'
>>> apList[1].encode
<pythonwifi.iwlibs.Iwpoint object at 0x767d3630>
>>> apList[1].frequency
<pythonwifi.iwlibs.Iwfreq object at 0x767d3610>
>>> apList[1].mode
'Master'

# 探詢何謂 AP 品質?
>>> apList[1].quality
<pythonwifi.iwlibs.Iwquality object at 0x767d3570>

# 探詢 AP 品質物件屬性
>>> dir(apList[1].quality)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'fmt', 'getNoiselevel', 'getSignallevel', 'nlevel', 'noiselevel', 'parse', 'quality', 'setNoiselevel', 'setSignallevel', 'setValues', 'siglevel', 'signallevel', 'updated']

# 訊號強度?!
>>> apList[1].quality.getSignallevel()
49
>>> 
</pre>
 

<span style="color: #808000;">也許有人會先讀『 iwlist.py 』範例原始碼,畢竟『 iwlist 』指令能夠作 AP 掃描的啊!!</span>

 
<pre class="lang:python decode:true "># iwlist.py 原始碼 scanning 部份

def print_scanning_results(wifi, args=None):
    """ Print the access points detected nearby.

    """
    # "Check if the interface could support scanning"
    try:
        iwrange = Iwrange(wifi.ifname)
    except IOError, (error_number, error_string):
        sys.stderr.write("%-8.16s  Interface doesn't support scanning.\n\n" % (
                            wifi.ifname))
    else:
        # "Check for Active Scan (scan with specific essid)"
        # "Check for last scan result (do not trigger scan)"
        # "Initiate Scanning"
        try:
            results = wifi.scan()
        except IOError, (error_number, error_string):
            if error_number != errno.EPERM:
                sys.stderr.write(
                    "%-8.16s  Interface doesn't support scanning : %s\n\n" %
                    (wifi.ifname, error_string))
        else:
            if (len(results) == 0):
                print "%-8.16s  No scan results" % (wifi.ifname, )
            else:
                (num_channels, frequencies) = wifi.getChannelInfo()
                print "%-8.16s  Scan completed :" % (wifi.ifname, )
                index = 1
                for ap in results:
                    print "          Cell %02d - Address: %s" % (index, ap.bssid)
                    print "                    ESSID:\"%s\"" % (ap.essid, )
                    print "                    Mode:%s" % (ap.mode, )
                    print "                    Frequency:%s (Channel %d)" % \
                        (wifi._formatFrequency(ap.frequency.getFrequency()),
                        frequencies.index(wifi._formatFrequency(
                            ap.frequency.getFrequency())) + 1)
                    if (ap.quality.updated & \
                                pythonwifi.flags.IW_QUAL_QUAL_UPDATED):
                        quality_updated = "="
                    else:
                        quality_updated = ":"
                    if (ap.quality.updated & \
                                pythonwifi.flags.IW_QUAL_LEVEL_UPDATED):
                        signal_updated = "="
                    else:
                        signal_updated = ":"
                    if (ap.quality.updated & \
                                pythonwifi.flags.IW_QUAL_NOISE_UPDATED):
                        noise_updated = "="
                    else:
                        noise_updated = ":"
                    print "                    " + \
                        "Quality%c%s/%s  Signal level%c%s/%s  Noise level%c%s/%s" % \
                        (quality_updated,
                        ap.quality.quality,
                        wifi.getQualityMax().quality,
                        signal_updated,
                        ap.quality.getSignallevel(),
                        "100",
                        noise_updated,
                        ap.quality.getNoiselevel(),
                        "100")
                    # This code on encryption keys is very fragile
                    if (ap.encode.flags & pythonwifi.flags.IW_ENCODE_DISABLED):
                        key_status = "off"
                    else:
                        if (ap.encode.flags & pythonwifi.flags.IW_ENCODE_NOKEY):
                            if (ap.encode.length <= 0):
                                key_status = "on"
                    print "                    Encryption key:%s" % (key_status, )
                    if len(ap.rate) > 0:
                        for rate_list in ap.rate:
                            # calc how many full lines of bitrates
                            rate_lines = len(rate_list) / 5
                            # calc how many bitrates on last line
                            rate_remainder = len(rate_list) % 5
                            line = 0
                            # first line should start with a label
                            rate_line = "                    Bit Rates:"
                            while line < rate_lines:
                                # print full lines
                                if line > 0:
                                    # non-first lines should start *very* indented
                                    rate_line = "                              "
                                rate_line = rate_line + "%s; %s; %s; %s; %s" % \
                                    tuple(wifi._formatBitrate(x) for x in
                                        rate_list[line * 5:(line * 5) + 5])
                                line = line + 1
                                print rate_line
                            if line > 0:
                                # non-first lines should start *very* indented
                                rate_line = "                              "
                            # print non-full line
                            print rate_line + "%s; "*(rate_remainder - 1) % \
                                tuple(wifi._formatBitrate(x) for x in
                                    rate_list[line * 5:line * 5 + rate_remainder - 1]) + \
                                "%s" % (wifi._formatBitrate(
                                        rate_list[line * 5 + rate_remainder - 1]))
                    index = index + 1
            print
</pre>
 

<span style="color: #808000;">若說條條大路通羅馬。事物總有交會處,事理經常能互補。何不就盡興的『玩』科技呢??方法之事或許多多益善!終會有應用之時的耶!!</span>

 

<span style="color: #ff9900;">※ 補記︰請特別注意上面那個『 sudo 』。想多了解『 iwlib 』資料結構者,或將需要『 iwlib.h 』檔案,請用</span>

<span style="color: #808080;">sudo apt-get install libiw-dev</span>

<span style="color: #ff9900;">取得。</span>

<span style="color: #808080;"><strong>【參考資料】</strong></span>
<pre class="lang:sh decode:true ">pi@raspberrypi ~

*** Error message:
Missing $ inserted.
You can't use `macro parameter character #' in vertical mode.
leading text: #
Unicode character 選 (U+9078)
leading text: # 選
Unicode character 取 (U+53D6)
leading text: # 選取
Unicode character 裝 (U+88DD)
leading text: # 選取 WiFi 裝
Unicode character 置 (U+7F6E)
leading text: # 選取 WiFi 裝置
You can't use `macro parameter character #' in vertical mode.
leading text: #
Unicode character 熱 (U+71B1)
leading text: # AP 熱
Unicode character 點 (U+9EDE)
leading text: # AP 熱點
Unicode character 掃 (U+6383)
leading text: # AP 熱點掃
Unicode character 描 (U+63CF)
leading text: # AP 熱點掃描
You can't use `macro parameter character #' in vertical mode.
leading text: #
Unicode character 探 (U+63A2)

more /usr/include/iwlib.h
/*
* Wireless Tools
*
* Jean II - HPLB 97->99 - HPL 99->09
*
* Common header for the Wireless Extension library...
*
* This file is released under the GPL license.
* Copyright (c) 1997-2009 Jean Tourrilhes <jt@hpl.hp.com>
*/

#ifndef IWLIB_H
#define IWLIB_H

/***************************** INCLUDES *****************************/

/* Standard headers */
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <math.h>
#include <errno.h>
#include <fcntl.h>
--More--(3%)