分類彙整: 樹莓派

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

若是仔細觀察『地壘』之 Signal/Noise/History 圖

horst-history_1

 

當可知道即使在『固定』位置,所測得的『 RSSI 』也像是『隨機』的勒!?一張典型 RF 發射系統圖,也許足以說明這個『不確定性』的由來︰

 

RF_TX

 

或許另一張實測圖︰

Histogram-of-signal-strength

引自《 Indoor Localization using Multiple Wireless Technologies 》論文

 

更能清楚了解那些數值的『機率分佈』。如此我們當知 RSSI 的數據必須經過『處理』,方能代表某種『 金文尺 』尺度,而且還得『校正 』才能表達『□□』的吧!那個『數據』的『時間序列』本身

X_{t_1}, \ X_{t_2}, \ X_{t_3}, \ \cdots , \ X_{t_n}, \ \cdots

宛如起伏之波瀾,正待適當『模型』的詮釋哩!!

如是看來這麼個『簡單定向器』也『不簡單』的耶?那麼我們將要如何用這根 RSSI 『尺』的呢?又怎樣能夠得到下面的圖的呢??

 

figure9

 

俗話說︰有煙 必有火,無風不起浪。是否『煙』可以作『火』的『指標』?『浪』一定是『風』引起的呢??相繼的現象,伴隨的關係常為『徵候』的由來,卻未必有『物理因 果』性。雖說大多數物質『熱脹冷縮』,水結冰、冰化水,卻是『冷漲熱縮』!更別講此一現象對水中生物之生存重要性的哩!!所以當我們談到度量的『 金文尺 』尺,就必須注意『現象』的『重複性』、『再現性』……『可靠性』的概念區分。此處引用維基百科相關詞條︰

Repeatability

Repeatability or test–retest reliability[1] is the variation in measurements taken by a single person or instrument on the same item, under the same conditions, and in a short period of time. A less-than-perfect test–retest reliability causes test–retest variability. Such variability can be caused by, for example, intra-individual variability and intra-observer variability. A measurement may be said to be repeatable when this variation is smaller than a pre-determined acceptance criteria.

Test–retest variability is practically used, for example, in medical monitoring of conditions. In these situations, there is often a predetermined “critical difference”, and for differences in monitored values that are smaller than this critical difference, the possibility of pre-test variability as a sole cause of the difference may be considered in addition to, for examples, changes in diseases or treatments.[2]

───

Reproducibility

Reproducibility is the ability of an entire experiment or study to be duplicated, either by the same researcher or by someone else working independently. Reproducing an experiment is called replicating it. Reproducibility is one of the main principles of the scientific method.

The values obtained from distinct experimental trials are said to be commensurate if they are obtained according to the same reproducible experimental description and procedure. The basic idea can be seen in Aristotle‘s dictum that there is no scientific knowledge of the individual, where the word used for individual in Greek had the connotation of the idiosyncratic, or wholly isolated occurrence. Thus all knowledge, all science, necessarily involves the formation of general concepts and the invocation of their corresponding symbols in language (cf. Turner). Aristotle′s conception about the knowledge of the individual being considered unscientific is due to lack of the field of statistics in his time, so he could not appeal to statistical averaging by the individual.

A particular experimentally obtained value is said to be reproducible if there is a high degree of agreement between measurements or observations conducted on replicate specimens in different locations by different people—that is, if the experimental value is found to have a high precision.[1]

───

Reliability

In the psychometrics, reliability is the overall consistency of a measure. A measure is said to have a high reliability if it produces similar results under consistent conditions. For example, measurements of people’s height and weight are often extremely reliable.[1][2]

Types

There are several general classes of reliability estimates:

  • Inter-rater reliability assesses the degree of agreement between two or more raters in their appraisals.
  • Test-retest reliability assesses the degree to which test scores are consistent from one test administration to the next. Measurements are gathered from a single rater who uses the same methods or instruments and the same testing conditions.[2] This includes intra-rater reliability.
  • Inter-method reliability assesses the degree to which test scores are consistent when there is a variation in the methods or instruments used. This allows inter-rater reliability to be ruled out. When dealing with forms, it may be termed parallel-forms reliability.[3]
  • Internal consistency reliability, assesses the consistency of results across items within a test.[3]

───

方便讀者對比意義的差別,或將發現建立 RSSI 『尺度』之法的耶 !?

 

 

 

 

 

 

 

 

 

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

不論用什麼樣的『 金文尺 』尺來度量,都得了解那根尺的構成,以及量到數值的意義,要如何校正資料,方能有實際的用途。為此特別介紹一個稱之為『地壘』 horst 的軟體︰

spiralsun_smallbr1 blog

high-tech or low-life?

horst

“horst” is a small, lightweight IEEE802.11 wireless LAN analyzer with a text interface. Its basic function is similar to tcpdump, Wireshark or Kismet, but it’s much smaller and shows different, aggregated information which is not easily available from other tools. It is mainly targeted at debugging wireless LANs with a focus on ad-hoc (IBSS) mode in larger mesh networks. It can be useful to get a quick overview of what’s going on on all wireless LAN channels and to identify problems.

  • Shows signal (RSSI) values per station
  • Calculates channel utilization (“usage”) by adding up the amount of time the packets actually occupy the medium
  • “Spectrum Analyzer” shows signal levels and usage per channel
  • Graphical packet history, with signal, packet type and physical rate
  • Shows all stations per ESSID and the live TSF per node as it is counting
  • Detects IBSS “splits” (same ESSID but different BSSID – this is a common driver problem)
  • Statistics of packets/bytes per physical rate and per packet type
  • Has some support for mesh protocols (OLSR and batman)
  • Can filter specific packet types, source addresses or BSSIDs
  • Client/server support for monitoring on remote nodes

“horst” is a Linux program and can be used on any wireless LAN monitor interface. The latest version is 4.2 from Oct 1 2014.

……

【主畫面】

horst-main_0

 

【訊號‧雜訊‧歷史】

horst-history_1

 

【頻譜分析】

horst-spec1

 

以期加深讀者對無線網路的認識。由於這個程式使用 IEEE802.11 的『monitor』操作模式,讀者可用『 iw list 』來確認 USB 無線 dongle 是否具有這個模式︰

 

# iw 工具安裝
pi@raspberrypi ~ sudo apt-get install iw  # 如果 iw list 顯示空行,那個 USB WiFi dongle 不具 IEEE802.11 相容模式。  pi@raspberrypi ~ iw list
Wiphy phy0
# ………
# USB WiFi dongle 提供哪些模式
	Supported interface modes:
		 * IBSS
		 * managed
		 * AP
		 * AP/VLAN
		 * WDS
# 有 monitor 模式
		 * monitor
		 * mesh point
	software interface modes (can always be added):
		 * AP/VLAN
		 * monitor
	valid interface combinations:
		 * #{ AP, mesh point } <= 8,
		   total <= 8, #channels <= 1

 

地壘 horst 之安裝及執行︰

# 將 IEEE802.11 的 USB WiFi dongle 設定為 monitor only 模式
pi@raspberrypi ~ iwconfig  wlan0     IEEE 802.11bgn  ESSID:off/any             Mode:Managed  Access Point: Not-Associated   Tx-Power=20 dBm              Retry short limit:7   RTS thr:off   Fragment thr:off           Power Management:off            lo        no wireless extensions.  eth0      no wireless extensions.  # 刪除 wlan0 managed 模式 pi@raspberrypi ~ sudo iw dev wlan0 del
pi@raspberrypi ~ iwconfig  lo        no wireless extensions.  eth0      no wireless extensions.  # 增加命名為 mono0 的 monitor 模式 pi@raspberrypi ~ sudo iw phy phy0 interface add mon0 type monitor
pi@raspberrypi ~ iwconfig  lo        no wireless extensions.  mon0      IEEE 802.11bgn  Mode:Monitor  Frequency:2.412 GHz  Tx-Power=20 dBm              Retry short limit:7   RTS thr:off   Fragment thr:off           Power Management:off            eth0      no wireless extensions.  # 取得 horst,編譯地壘,以及執行 pi@raspberrypi ~ wget http://br1.einfach.org/horst_dl/horst-4.2.tar.gz
pi@raspberrypi ~ tar -zxvf horst-4.2.tar.gz pi@raspberrypi ~ cd horst-4.2/
pi@raspberrypi ~/horst-4.2 make pi@raspberrypi ~/horst-4.2 sudo ./horst -i mon0

 

 

 

 

 

 

 

 

 

勇闖新世界︰ 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%)

 

 

 

 

 

 

 

 

 

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

就讓我們從

python-wifi 0.6.0

Python WiFi is a Python module that provides read and write access to a wireless network card’s capabilities using the Linux Wireless Extensions.

Python WiFi is a Python module that provides read and write access to a wireless network card’s capabilities using the Linux Wireless Extensions. It was initially developed by Roman Joost with advice from Guido Goldstein of Infrae. It is currently maintained by Sean Robinson.……

 

的安裝開始,

wget http://git.tuxfamily.org/pythonwifi/pythonwifi.git/snapshot/pythonwifi-0.6.0.tar.gz
tar zxvf pythonwifi-0.6.0.tar.gz
cd pythonwifi-0.6.0/
sudo python setup.py install

※ 註記︰因為萬國碼的相容性問題,目前 pythonwifi 只能用於派生二,不能用於派生三。

進入

Python WiFi

A new api is being organized for Python WiFi beyond v0.6.0. Your feedback will make Python WiFi better, so please participate. Join the mailing list and join the discussion.

Python WiFi is intended for developers that wish to use their WiFi card from within a Python program. If you are looking for a GNU/Linux program to scan for, and connect with, WiFi networks, you may want to try WiFi Radar, Wicd, or NetworkManager.

Python WiFi is a Python module that provides read and write access to a wireless network card’s capabilities using the Linux Wireless Extensions. This module was initially created by Róman Joost and is currently maintained by Sean Robinson <robinson@tuxfamily.org>. The latest version is 0.6.0.

Documentation

Matrices of features to try to match: Wireless Extensions, iwconfig.py, and iwlist.py.

Source Code

Browse the Source

Download

A Python source package is available at the Python Package Index.

“Python” and the Python logos are trademarks or registered trademarks of the Python Software Foundation, used with permission.

Last Update: March 23, 2015

 

派生 WiFi 程式之域。然而這個程式庫的說明文件僅有兩個範例,將要如何學習的呢?固然閱讀原始碼是一種方法,通常耗時得慢活,一般乃必要才為之之事。幸好大部份『派生程式庫』的作者喜歡『吉多』 Guido 大教主倡導的『 Code Style 』編碼風格,於是我們可以嘗試『help □○』,

pi@raspberrypi ~ 
*** QuickLaTeX cannot compile formula:
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 = Wireless('eth1')
>>> help(wifi)
</pre>
<span style="color: #808000;">結果得到</span>

<span style="color: #808080;">Help on Wireless in module <span style="color: #ff9900;">pythonwifi.iwlibs</span> object:</span>

<span style="color: #808080;">class <span style="color: #ff9900;">Wireless</span>(__builtin__.object)</span>
<span style="color: #808080;"> | Provides high-level access to wireless interfaces.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | This class uses <span style="color: #ff9900;">WirelessInfo</span> for most access.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | Methods defined here:</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | __init__(self, ifname)</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | commit(self)</span>
<span style="color: #808080;"> | Commit pending changes.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">getAPaddr</span>(self)</span>
<span style="color: #808080;"> | Returns the access point MAC address.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless, getNICnames</span>
<span style="color: #808080;"> | >>> ifnames = getNICnames()</span>
<span style="color: #808080;"> | >>> ifnames</span>
<span style="color: #808080;"> | ['eth1', 'wifi0']</span>
<span style="color: #808080;"> | >>> wifi = Wireless(ifnames[0])</span>
<span style="color: #808080;"> | >>> wifi.getAPaddr()</span>
<span style="color: #808080;"> | '00:0D:88:8E:4E:93'</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | Test with non-wifi card:</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth0')</span>
<span style="color: #808080;"> | >>> wifi.getAPaddr()</span>
<span style="color: #808080;"> | (95, 'Operation not supported')</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | Test with non-existant card:</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth2')</span>
<span style="color: #808080;"> | >>> wifi.getAPaddr()</span>
<span style="color: #808080;"> | (19, 'No such device')</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">getBitrate</span>(self)</span>
<span style="color: #808080;"> | Returns the device's currently set bit rate in Mbit.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | >>> wifi.getBitrate()</span>
<span style="color: #808080;"> | '11 Mb/s'</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> |<span style="color: #ff9900;"> getBitrates</span>(self)</span>
<span style="color: #808080;"> | Returns the number of bitrates available for the device.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | >>> num, rates = wifi.getBitrates()</span>
<span style="color: #808080;"> | >>> num == len(rates)</span>
<span style="color: #808080;"> | True</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">getChannelInfo</span>(self)</span>
<span style="color: #808080;"> | Returns the number of channels and available frequencies for</span>
<span style="color: #808080;"> | the device.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | >>> num, rates = wifi.getChannelInfo()</span>
<span style="color: #808080;"> | >>> num == len(rates)</span>
<span style="color: #808080;"> | True</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">getEncryption</span>(self)</span>
<span style="color: #808080;"> | Get the association mode, which is probably a string of '*',</span>
<span style="color: #808080;"> | 'open', 'private', 'off'.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | As a normal user, you will get an 'Operation not permitted'</span>
<span style="color: #808080;"> | error:</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | >>> wifi.getEncryption()</span>
<span style="color: #808080;"> | (1, 'Operation not permitted')</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> |<span style="color: #ff9900;"> getEssid</span>(self)</span>
<span style="color: #808080;"> | Returns the current ESSID information.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | >>> wifi.getEssid()</span>
<span style="color: #808080;"> | 'romanofski'</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">getFragmentation</span>(self)</span>
<span style="color: #808080;"> | Returns the fragmentation threshold.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | It depends on what the driver says. If you have fragmentation</span>
<span style="color: #808080;"> | threshold turned on, you'll get an int. If it's turned off</span>
<span style="color: #808080;"> | you'll get a string: 'off'.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | >>> wifi.getFragmentation()</span>
<span style="color: #808080;"> | 'off'</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">getFrequency</span>(self)</span>
<span style="color: #808080;"> | Returns currently set frequency of the card.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | >>> wifi.getFrequency()</span>
<span style="color: #808080;"> | '2.417 GHz'</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">getKey</span>(self, key=0, formatted=True)</span>
<span style="color: #808080;"> | Get an encryption key.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | key 0 is current key, otherwise, retrieve specific key (1-4)</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | As a normal user, you will get an 'Operation not permitted'</span>
<span style="color: #808080;"> | error:</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | >>> wifi.getKey()</span>
<span style="color: #808080;"> | ABCD-9512-34</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">getKeys</span>(self)</span>
<span style="color: #808080;"> | Get all encryption keys.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | Returns a list of tuples.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | As a normal user, you will get a 'Operation not permitted'</span>
<span style="color: #808080;"> | error:</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | >>> wifi.getKeys()</span>
<span style="color: #808080;"> | [(1, '1234-5678-91'), (2, None), (3, 'ABCD-EFAB-CD'), (4, None)]</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">getMode</span>(self)</span>
<span style="color: #808080;"> | Returns currently set operation mode.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | >>> wifi.getMode()</span>
<span style="color: #808080;"> | 'Managed'</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">getPowermanagement</span>(self)</span>
<span style="color: #808080;"> | Returns the power management settings.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | #>>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | #>>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | #>>> wifi.getPowermanagement()</span>
<span style="color: #808080;"> | #'off'</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">getQualityAvg</span>(self)</span>
<span style="color: #808080;"> | Returns an Iwquality object with average quality information.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | >>> aq = wifi.getQualityAvg()</span>
<span style="color: #808080;"> | >>> print "quality:", aq.quality, "signal:", aq.siglevel, "noise:", aq.nlevel</span>
<span style="color: #808080;"> | quality: 38 signal: 13 noise: 0</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">getQualityMax</span>(self)</span>
<span style="color: #808080;"> | Returns an Iwquality object with maximum quality information.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | >>> mq = wifi.getQualityMax()</span>
<span style="color: #808080;"> | >>> print "quality:", mq.quality, "signal:", mq.siglevel, "noise:", mq.nlevel</span>
<span style="color: #808080;"> | quality: 38 signal: 13 noise: 0</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">getRTS</span>(self)</span>
<span style="color: #808080;"> | Returns the RTS threshold, likely to be int, 'auto',</span>
<span style="color: #808080;"> | 'fixed', 'off'</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | man iwconfig:</span>
<span style="color: #808080;"> | "RTS/CTS adds a handshake before each packet transmission to</span>
<span style="color: #808080;"> | make sure that the channel is clear. This adds overhead, but</span>
<span style="color: #808080;"> | increases performance in case of hidden nodes or a large</span>
<span style="color: #808080;"> | number of active nodes. This parameter sets the size of the</span>
<span style="color: #808080;"> | smallest packet for which the node sends RTS; a value equal</span>
<span style="color: #808080;"> | to the maximum packet size disable the mechanism."</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | >>> wifi.getRTS()</span>
<span style="color: #808080;"> | 'off'</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">getRetrylimit</span>(self)</span>
<span style="color: #808080;"> | Returns the retry/lifetime limit.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | man iwconfig:</span>
<span style="color: #808080;"> | "Most cards have MAC retransmissions, and some allow to set</span>
<span style="color: #808080;"> | the behaviour of the retry mechanism."</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | >>> wifi.getRetrylimit()</span>
<span style="color: #808080;"> | 16</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">getSensitivity</span>(self)</span>
<span style="color: #808080;"> | Returns sensitivity information.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | man iwconfig:</span>
<span style="color: #808080;"> | "This is the lowest signal level for which the hardware</span>
<span style="color: #808080;"> | attempt packet reception, signals weaker than this are</span>
<span style="color: #808080;"> | ignored. This is used to avoid receiving background noise,</span>
<span style="color: #808080;"> | so you should set it according to the average noise</span>
<span style="color: #808080;"> | level. Positive values are assumed to be the raw value used</span>
<span style="color: #808080;"> | by the hardware or a percentage, negative values are</span>
<span style="color: #808080;"> | assumed to be dBm."</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | >>> wifi.getSensitivity()</span>
<span style="color: #808080;"> | 'off'</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">getStatistics</span>(self)</span>
<span style="color: #808080;"> | Returns statistics information which can also be found in</span>
<span style="color: #808080;"> | /proc/net/wireless.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">getTXPower</span>(self)</span>
<span style="color: #808080;"> | Returns the transmit power in dBm.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | >>> wifi.getTXPower()</span>
<span style="color: #808080;"> | '17 dBm'</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">getWirelessName</span>(self)</span>
<span style="color: #808080;"> | Returns the wireless name.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | >>> wifi.getWirelessName()</span>
<span style="color: #808080;"> | 'IEEE 802.11-DS'</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">scan</span>(self)</span>
<span style="color: #808080;"> | Returns Iwscanresult objects, after a successful scan.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">setAPaddr</span>(self, addr)</span>
<span style="color: #808080;"> | Sets the access point MAC address.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | translated from iwconfig.c</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | FIXME: This needs to check address type before acting.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">setEncryption</span>(self, mode)</span>
<span style="color: #808080;"> | Set the association mode.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | As a normal user, you will get an 'Operation not permitted'</span>
<span style="color: #808080;"> | error:</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | >>> wifi.setEncryption()</span>
<span style="color: #808080;"> | (1, 'Operation not permitted')</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">setEssid</span>(self, essid)</span>
<span style="color: #808080;"> | Sets the ESSID.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | >>> wifi.getEssid()</span>
<span style="color: #808080;"> | 'romanofski'</span>
<span style="color: #808080;"> | >>> wifi.setEssid('Joost')</span>
<span style="color: #808080;"> | >>> wifi.getEssid()</span>
<span style="color: #808080;"> | 'Joost'</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">setFrequency</span>(self, freq)</span>
<span style="color: #808080;"> | Sets the frequency on the card.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | translated from iwconfig.c</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">setKey</span>(self, key, index=1)</span>
<span style="color: #808080;"> | Set an encryption key.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | As a normal user, you will get an 'Operation not permitted'</span>
<span style="color: #808080;"> | error:</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | >>> from iwlibs import Wireless</span>
<span style="color: #808080;"> | >>> wifi = Wireless('eth1')</span>
<span style="color: #808080;"> | >>> wifi.setKey()</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | <span style="color: #ff9900;">setMode</span>(self, mode)</span>
<span style="color: #808080;"> | Sets the operation mode.</span>
<span style="color: #808080;"> |</span>
<span style="color: #808080;"> | ----------------------------------------------------------------------</span>

 

<span style="color: #808000;">再輔之以派生『內省』之『 <span style="color: #ff9900;"><a style="color: #ff9900;" href="https://docs.python.org/3/library/inspect.html">inspect</a></span> 』視察之法,如是就能試行,</span>
<pre class="lang:sh decode:true">pi@raspberrypi ~

*** Error message:
You can't use `macro parameter character #' in math mode.
leading text: <span style="color: #
Unicode character 結 (U+7D50)
leading text: <span style="color: #808000;">結
Unicode character 果 (U+679C)
leading text: <span style="color: #808000;">結果
Unicode character 得 (U+5F97)
leading text: <span style="color: #808000;">結果得
Unicode character 到 (U+5230)
leading text: <span style="color: #808000;">結果得到
Missing $ inserted.
You can't use `macro parameter character #' in horizontal mode.
leading text: <span style="color: #
You can't use `macro parameter character #' in horizontal mode.
leading text: ...n Wireless in module <span style="color: #
You can't use `macro parameter character #' in horizontal mode.
leading text: <span style="color: #

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 = Wireless('wlan0')
>>> dir(wifi)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_formatBitrate', '_formatFrequency', 'commit', 'getAPaddr', 'getBitrate', 'getBitrates', 'getChannelInfo', 'getEncryption', 'getEssid', 'getFragmentation', 'getFrequency', 'getKey', 'getKeys', 'getMode', 'getPowermanagement', 'getQualityAvg', 'getQualityMax', 'getRTS', 'getRetrylimit', 'getSensitivity', 'getStatistics', 'getTXPower', 'getWirelessName', 'ifname', 'iwstruct', 'scan', 'setAPaddr', 'setEncryption', 'setEssid', 'setFrequency', 'setKey', 'setMode', 'sockfd', 'wireless_info']
>>> wifi.getQualityAvg()
<pythonwifi.iwlibs.Iwquality object at 0x767fd110>
>>> dir(wifi.getQualityAvg())
['__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']
>>> wifi.getQualityAvg().getSignallevel()
178
>>> wifi.getQualityAvg().getNoiselevel()
0

 

這就是 Python 之『非同的禪!!』,『派生大道』 Pythonic Way 的中心主旨也。

 

 

 

 

 

 

 

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

雖然不知 M♪o 所用的『無線阡陌網』科技如何?就讓我們用常見的『熱點』與 USB WiFi 『小玩意』來研究那『定向器』可以怎樣實現的呢??在一篇名為

Testing of location systems using WiFi in indoor environments

的文章裡,有人探討了這個技術。更有一本叫做

Principles of Wireless Access and Localization

的書,較詳細說明了無限 WiFi 之 WPS 定位技術。

其中一個關鍵之處就在『接收訊號強度指示』 RSSI 這個『術語』。據維基百科解釋︰

Received signal strength indication

RSSI in 802.11 implementations

In an IEEE 802.11 system, RSSI is the relative received signal strength in a wireless environment, in arbitrary units. RSSI is an indication of the power level being received by the antenna. Therefore, the higher the RSSI number, the stronger the signal.

RSSI can be used internally in a wireless networking card to determine when the amount of radio energy in the channel is below a certain threshold at which point the network card is clear to send (CTS). Once the card is clear to send, a packet of information can be sent. The end-user will likely observe a RSSI value when measuring the signal strength of a wireless network through the use of a wireless network monitoring tool like Wireshark, Kismet or Inssider. As an example, Cisco Systems cards have a RSSI_Max value of 100 and will report 101 different power levels, where the RSSI value is 0 to 100. Another popular Wi-Fi chipset is made by Atheros. An Atheros based card will return an RSSI value of 0 to 127 (0x7f) with 128 (0x80) indicating an invalid value.

There is no standardized relationship of any particular physical parameter to the RSSI reading. The 802.11 standard does not define any relationship between RSSI value and power level in mW or dBm. Vendors and chipset makers provide their own accuracy, granularity, and range for the actual power (measured as mW or dBm) and their range of RSSI values (from 0 to RSSI_Max).[2] One subtlety of the 802.11 RSSI metric comes from how it is sampled—RSSI is acquired during only the preamble stage of receiving an 802.11 frame, not over the full frame. As early as 2000, researchers were able to use RSSI for coarse-grained location estimates.[3] More recent work was able to reproduce these results using more advanced techniques.[4] Nevertheless, RSSI doesn’t always provide measurements that are sufficiently accurate to properly determine the location.[5]

 

可知它不是像『尺』一般的『量距離』設備,比較像海邊『燈塔』一樣的『遠近』指示。所以實務上 WPS 常和 GPS 組在一塊,用以收集、定位、校正那些『WiFi AP』的數據。在此引用前面網文裡的兩張圖,或可意會 RSSI 與距離的複雜關係。

 

figure-8

 

figure9

 

假使在樹莓派已有 USB WiFi 『小玩意』,而且連接到 WiFi AP 上,一個『 iwconfig 』指令,可以告知『連接品質』 Link Quality 以及『訊號準位』 Signal level 。

pi@raspberrypi ~ iwconfig wlan0 wlan0     IEEE 802.11bg  ESSID:"caseyhome"  Nickname:"<WIFI@REALTEK>"           Mode:Managed  Frequency:2.412 GHz  Access Point: 10:6F:3F:62:2C:15              Bit Rate:54 Mb/s   Sensitivity:0/0             Retry:off   RTS thr:off   Fragment thr:off           Power Management:off           Link Quality=100/100  Signal level=100/100  Noise level=0/100           Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0           Tx excessive retries:0  Invalid misc:0   Missed beacon:0  pi@raspberrypi ~ 

 

另一個『 iwlist wlan0 scanning 』之指令,則能提供周遭可連線之 WiFi AP 的『連接品質』與『訊號準位』數據。這兩個指令來自於 Jean Tourrilhes 先生啟始的

Wireless Tools for Linux

Presentation

The Linux Wireless Extension and the Wireless Tools are an Open Source project sponsored by Hewlett Packard (through my contribution) since 1996, and build with the contribution of many Linux users all over the world.

The Wireless Extension (WE) is a generic API allowing a driver to expose to the user space configuration and statistics specific to common Wireless LANs. The beauty of it is that a single set of tool can support all the variations of Wireless LANs, regardless of their type (as long as the driver support Wireless Extension). Another advantage is these parameters may be changed on the fly without restarting the driver (or Linux).

The Wireless Tools (WT) is a set of tools allowing to manipulate the Wireless Extensions. They use a textual interface and are rather crude, but aim to support the full Wireless Extension. There are many other tools you can use with Wireless Extensions, however Wireless Tools is the reference implementation.

  • iwconfig manipulate the basic wireless parameters
  • iwlist allow to initiate scanning and list frequencies, bit-rates, encryption keys…
  • iwspy allow to get per node link quality
  • iwpriv allow to manipulate the Wireless Extensions specific to a driver (private)
  • ifrename allow to name interfaces based on various static criteria

Most Linux distributions also have integrated Wireless Extensions support in their networking initialisation scripts, for easier boot-time configuration of wireless interfaces. They also include Wireless Tools as part of their standard packages.

Wireless configuration can also be done using the Hotplug or uDev scripts and distribution specific support, this enable the proper support of any removable wireless interface (Pcmcia, CardBus, USB…).

Any versions of the Pcmcia package offer the possibility to do wireless configuration of Pcmcia and Cardbus card through thefile wireless.opts. This allow to fully integrate wireless settings in the Pcmcia scheme mechansism. However, this method is now deprecated in favor of distribution specific methods.

Please note that the Wireless Tools (starting with version 19) supports fully IEEE 802.11 parameters and devices, support older style of devices and most proprietary protocols, and are prepared to handle HiperLan as well. More recent versions of course adds more 802.11 support.
But, unfortunately not all drivers support all these features…

………

雖然根據

User Tools

About iw

iw is a new nl80211 based CLI configuration utility for wireless devices. It supports all new drivers that have been added to the kernel recently. The old tool iwconfing, which uses Wireless Extensions interface, is deprecated and it’s strongly recommended to switch to iw and nl80211.

Like rest of Linux kernel, iw is still under development. Features are added ‘as we go’. The only documentation for iw is this page and output from ‘iw help’. Please help expand this page.

There is a page listing use cases with iwconfig and iw: replacing iwconfig.

Getting iw

Release tarballs of iw are available from http://kernel.org/pub/software/network/iw/.

Alternatively, you can download iw from git: http://git.kernel.org/?p=linux/kernel/git/jberg/iw.git.

Build requirements

  • libnl >= libnl1
  • libnl-dev >= libnl-dev-1
  • pkg-config Using iw requires you to have libnl, the first working version is 1.0 pre8 as this release introduced genl, Generic Netlink, which nl80211 relies on. If your distribution’s libnl is a wrong version then you’ll have to download and compile libnl yourself for now (http://www.infradead.org/~tgr/libnl/).

 

所言『 Wireless Extension 』終逐步步入歷史,這個替換過程或許還很長。何不就通熟兩者的呢!接續的文本,將以『派生』方便性與『實務』容易性為考量,應用兩套工具,或有『取巧之嫌』,豈可不辯之以學習『簡易是尚』的耶!!