勇闖新世界︰ 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 』終逐步步入歷史,這個替換過程或許還很長。何不就通熟兩者的呢!接續的文本,將以『派生』方便性與『實務』容易性為考量,應用兩套工具,或有『取巧之嫌』,豈可不辯之以學習『簡易是尚』的耶!!

 

 

 

 

 

 

 

 

 

 

勇闖新世界︰ W!o《卡夫卡村》變形祭︰ ○ 局 □ 陣【☲】

既不知如何入夢?又不曉如何清醒!只覺得腦海中有個聲音在說︰入口到了。方見好大一片林子,宛如沒有盡頭一般。正疑惑著, 祇聽到 W!o^{+} 講︰這片林子和另一片林子是一雙的,在地原鄉人傳言,都是不知幾千年之前就有的古林。眼前這個圓的,古音讀若『圓局』,內有他處皆無的『蘿荔』之樹。這『蘿荔』說也奇怪,不但性喜『三五成群』,圍若圓狀,而且不時或合小圓組大圓,或散大圈為小圈,原鄉人稱之為『嫁娶』,說是『風媒』之故。由於此地四季季風不斷,而且『蘿荔』之樹之生滅快速,遂成了天造的『迷宮』一般。林徑廣十里,綠葉閉雲日,實難行也。剛想問︰… , W!o^{+} 又講︰我知你想說︰拿個『指北針』不就好了?又能有何難行之處。殊不知這『蘿荔』之樹,或因此處的水土特殊,都帶有生物磁性,那『指北針』更本不管用。根據『未公開研究』,正是這個『磁性』決定了『嫁娶』方向的呢!?也許造林子的古人刻意如此,所以建有『九石台』,誰知卻種下了,後人『九石台』之辯。這『九石台』乃依洛書方位,八座小居圓周之上,一座大在林中央。台邊土據方位五行之色,周遭『蘿荔』不生。考察發現那台石能夠導電且深入地層,今人以為是『地熱電池』。後來 M♪o 在台上建置了『無線阡陌網』之『定向器』,方便谷內之人的進出。由於事涉保安,不便多言,況且可逛之處太多,祭典不遠,就趕路的吧!!……

此『無線阡陌網』之『定向器』將要如何比之擬之的哩?苦思冥想之後,或可比擬為『WPS』的耶??維基百科說︰

Wi-Fi positioning system

Wi-Fi-based positioning system (WPS) or WiPS/WFPS is used where GPS is inadequate due to various causes including multipath and signal blockage indoors. Such systems include indoor positioning systems. Wi-Fi positioning takes advantage of the rapid growth in the early 21st century of wireless access points in urban areas.

The localization technique used for positioning with wireless access points is based on measuring the intensity of the received signal (received signal strength or RSS) and the method of “fingerprinting”.[1][2] Typical parameters useful to geolocate the Wi-Fi hotspot or wireless access point include the SSID and the MAC address of the access point. The accuracy depends on the number of positions that have been entered into the database. The Wi-Fi hotspot database gets filled by correlating mobile device GPS location data with Wi-Fi hotspot MAC addresses.[3] The possible signal fluctuations that may occur can increase errors and inaccuracies in the path of the user. To minimize fluctuations in the received signal, there are certain techniques that can be applied to filter the noise.

In the case of low precision, some techniques have been proposed to merge the Wi-Fi traces with other data sources such as geographical information and time constraints (i.e., time geography).[4]

 

因為網路科技博大精深,難以筆墨形容,況且更兼實務描述困難,不得不採系統『疊套想象』之法,補之以剝洋蔥『層層分解』之術 ,以期方便讀者閱讀。特舉範例文本如下︰

咬一口 TCPIP!!上》───

internet1

清代  歸莊觀田家收獲
稻香秫熟暮秋天,
阡陌縱橫萬畝連。
五載輸糧女真國,
天全我誌獨無田。

中醫觀象上說︰入於處之小腸趨於居之,…;講的是四季頤養之道依時進補之法。或許網路道荼蓼一文,可與之相通;所謂荼蓼目之 ☲,坤地之 ☷, 自然能得離日耀目出地中天的 ☲ ☷ 卦之進取之境,所以才倒吃甘蔗

俗話說『民以食為天』,今日不吃『英特乃』大概不能活了!!頭上既有青天白雲,腳底常陪綠地嫩草,奈何伊只顧低頭一指觸知天下事?一個奇想帶來的蝴蝶效應,豈只驚天動地,簡直併吞地球,不過英特乃是否真源自『地球村』之『桃花源』尚待『考證』。之前講了『其人其事』,現在就談談『其物』──  乙太網 ──吧。人們一般以為乙太網發明於 1973 年,其因在於 Robert Melancton “BobMetcalfe 工作於全錄 PARC 時,受到 ALOHA 網路架構的啟發 ,寫了一張給他老闆有關乙太網潛力備忘錄。但是梅特卡夫自己卻認為乙太網是其後幾年才出現的,至少應該說是在 1976 年和他的助手David Boggs 發表了一篇名為《乙太網:區域網路的分封交換技術 》的文章之後。不論早三年還是晚三年,大體與 ARPA 網之父時期相當;作者試著簡化長篇歷史,假借卦象比之擬之的對比祈能易懂易讀。

澤風大過 ☱ ☴根莖葉網際網路
上六,過涉滅頂,
凶,旡咎。
一套網際網路規範
Internet Protocol Suite
九五,枯楊生華,
老婦得其士夫,旡咎旡譽。
應用層
Application Layer
九四,棟隆,
吉,有它吝。
傳送層
Transport Layer
九三,棟橈,
凶。
網際網路層
Internet Layer
九二,枯楊生稊,
老夫得其女妻,旡不利。
網路存取層
Network Access Layer
初六,藉用白茅,
旡咎。
實體層
Physical

───

 

吃一節 TCPIP!!中》───

240px-Möbius_strip

220px-Trefoil_knot_arb

MobiusStrip-01

拓撲學 Topology 一詞源自希臘文『地點之研究』,始於歐拉柯尼斯堡的七橋問題。這門數學探討連通性 connectedness 、連續性 continuity 、以及邊界 boundary。它不用東西的『形狀』來作分類,而是分析那個東西裡所有連通的點,各個連續的區域,和有哪些分別內外的邊界。想畫德國數學家莫比烏斯發現的帶子  Möbius strips ,它只有一個『』和一條『邊界』?!

Möbius strips

220px-BusNetwork.svg

220px-Network_card

500px-Coaxial_cable_cutaway.svg

lans.bus

220px-StarNetwork.svg

剛開始乙太網是用一條『同軸電纜』當作信號訊息傳送的骨幹,它的網路拓撲就像一個『』字,稱之為匯流排 BUS,是個運『信號波』的公車站。由於每一個連接到 BUS 的節點 = 接點 NODE,都可用作『收發』點,那就必須考慮對應的通訊機制。當然一個節點發送每個接點都同時接收沒有什麼問題;然而多個節點同時發送,就會產生信號『碰撞』以致訊息錯誤。這些特性的總稱叫做 CSMA/CD ── CS = 載波偵聽、MA=多路存取和CD=碰撞察覺 ──,可以說 BUS 上廣告著 ALOHA 在這裡!

由於任一節點的收發都是連通的自己發送自己也可以接收,這稱為 loopback 回送;在 Raspbian 裡,就是你用 ifconfig 命令看到的 lo ,它的 IP 地址通常是 127.0.0.1 ,這是 IPv4 所保留的 256 個地址區塊 127.0.0.0/8 ── 127.0.0.0 到127.0.0.255 ──之一。其次任一個節點都可以接收所有其它接點的信號,不管是不是發送給它的;通常乙太網卡驅動程式過濾掉這些不是自己應該接收的訊息,但是你也可以進入所謂混雜模式 Promiscuous mode 去監聽所有的收發。再者,乙太網使用自己全球唯一的 48 位元 MAC 媒介存取控制位址,約為二百八十兆個地址來區別連上它的整個世界不同的節點。不知是夠是不夠??

碰撞察覺的載波偵聽多路存取 CSMA/CD 技術要如何實現通訊機制呢?藉著節點收發守則

一、開始發送前── 偵聽到線路空閒才啟動傳輸,否則移至第四步

二、發送──即使察覺碰撞,繼續發送一段最小的時距,用以確保 所有其它節點都能察覺碰撞,再移至第四步

三、發送成功──回報上層的網路協定傳送成功,結束發送模式。

四、忙線中──等待,直至偵聽到線路空閒

五、擲骰子──線路雖已進入空閒狀態 ,必須等待隨機的一段時間,才可移至第一步,假如超過約定的最大嘗試次數,就走下一步吧

六、失敗── 回報上層的網路協定傳送失敗,結束發送模式

咦!說的不是收發守則嗎?怎們沒講到『接收』呢?節點總是接收的,就像耳朵聽的到自己說話一樣;更何況以對談的目的而言,一大半都是聽別人講話,所以講的人需要懂得『禮貌』,如果大家『搶著說』那就一團混亂了。哦!愛因斯坦不是說『上帝不擲骰子』嗎?為什麼要擲骰子呢?由於『等待多久』是很難決定的,所以才把它交給能確定『隨機』的上帝!!

───

 

啃一塊唄 K TCPIP!!下》───

金文回

金文串

220px-Screenshot_Recursion_via_vlc

TCPIP規範之堆疊 Stack 看起來什麼呢?俯察個『』字,側寫個『』文。不論它看起來像個什麼或有沒有形狀,它是網路主宰,也是通往英特乃大道老子第二十五章裡說︰
有物混成,天地兮,獨立不改周行不殆可以为天地。吾不知其名字之为之曰:。大曰,逝曰,遠曰

回文都能讀通的句子,有人說它源自『道德经』,故稱之為『道原』︰
第二十章 ── 俗人昭昭,我獨昏昏,俗人察察,我獨悶悶。
六十三章 ── 為无為,事无事,味无味。
八十一章 ── 信言不美,美言不信。

苏伯玉妻盘中诗

苏伯玉妻

可以清心也

那視之成串回文字之道原可有一個『讀法』?有人不止能讀還能寫,話說蘇伯玉赴蜀日久未歸,其妻獨居長安,七巧心思制作相思盤,探盼其夫心中是否有個她?

漢代 蘇伯玉盤中詩
山樹高,鳥鳴悲。泉水深,鯉魚肥。
空倉雀,常苦飢。吏人婦,會夫稀。
出門望,見白衣。謂當是,而更非。
還入門,中心悲。北上堂,西入階。
急機絞,杼聲催。長嘆息,當語誰。
君有行,妾念之。出有日,還無期。
結中帶,長相思。君忘妾,天知之。
妾忘君,罪當治。妾有行,宜知之。
黃者金,白者玉。高者山,下者谷。
姓者蘇,字伯玉,作人才多智謀足。
家居長安身在蜀,何惜馬蹄歸不數。
羊肉千斤酒百斛,令君馬肥麥與粟。
今時人智不足與其書不能讀
當從中央周四角

作者不知蘇伯玉歸是不歸?一杯『可以清心也』之己能『千回百轉』,解者自能消酷暑之永晝!!

說道這個規範堆疊分解的說也許可以圖示如下︰

TCP-IP-STACK

上圖各色分明左說右講程式所中道其事

精讀細思后,設想作這樣『一個包裹著另一個』的事有什麼好處呢?其實這就是就層層對應中之某層而言『上中下』相關的譯解結構在上目的語言為在『其中』者分割譯解在下手段控制。這使得越往上技術細節將被越多層所包裹不必知其詳,所以網際網路應用軟體的人,通常知道 TCP/IP 界面的 API 用法就夠了,很少直接用到乙太網的實體層界面。當然愈向下的技術細節也就愈多,也許有時發生的『狀況』超出程式的預期時會很有用。在此將它綜合成一個表解吧︰

彼接點信號之發送↑↓←→
層對層
上語下
列言列
↓↑→←
列知列
下道上
層應層
此節點訊息之接收
彼上上‧目的此上上‧目的
彼上‧目的語言此上‧目的語言
轉譯彼上之目的
話成彼下之手段
←→
堆言疊語
彼文此解
←→
疊語堆言
此字彼譯
轉翻此上之目的
說解此下之手段
彼下‧手段文字此下‧手段文字
彼下下‧手段此下下‧手段

───

 

 

 

 

 

 

 

 

勇闖新世界︰ W!o《卡夫卡村》變形祭︰夢游神行

‧     月

明

‧                    星

希

月明星稀

夢李白

其一
死別已吞聲,生別常惻惻。
江南瘴癘地,逐客無消息。
故人入我夢,明我長相憶。
君今在羅網,何以有羽翼?
恐非平生魂,路遠不可測。
魂來楓葉青,魂返關塞黑。
落月滿屋梁,猶疑照顏色。
水深波浪闊,無使蛟龍得。

其二
浮雲終日行,游子久不至。
三夜頻夢君,情親見君意。
告歸常局促,苦道來不易。
江湖多風波,舟楫恐失墜。
出門搔白首,若負平生志。
冠蓋滿京華,斯人獨憔悴。
孰雲網恢恢?將老身反累。
千秋萬歲名,寂寞身後事。

 

杜甫

 

祇覺大喊一聲︰小心!驚醒過來。猶恐夢中腦海之印象忘其蹤跡,故而振筆疾書,或塗或寫雜亂成篇。現今再讀,果然鬼畫符般不成文字的耶!!

原來 W!o{+} 不只有傳腦之術,還會託夢之法?如今之計,也僅能就勉記強憶所及隨筆鋪陳,若有錯搭誤改怕終難免,想也莫可奈何的了!或許有緣再見也說不定的吧??聽聞此事發生於

Tux@rpi ︰ 《環中基地》

──

以為方將夢醒,誰知仍在夢中?只聞見

△

世上只有兩種力量:利劍和思想。從長而論,利劍總是敗在思想手下 ── 拿破崙

△︰ ☆ 隨著候鳥前往遙遠的『 科赫王國』已逾百年,還不知能不能借得來『雪花製造機』 呢?而今海水升溫,兩極崩解,危在旦夕, Tux 們!我們不能再哀嘆 ㄊ 了!依靠自己保鄉衛土 ㄊ 吧!!德不孤,必有鄰啊!

洛水小海龜已來助陣的嘍,傳了一幅『女偊』得道圖 ㄊ 呦!!『大 T 』化解為『 ㄏㄓ』之法,可得『極地震盪』先機,天助 Tux ,天助 Tux ㄊㄊㄊㄜˋ♬

……

話說︰三更有夢書當枕。怎曉書滑人清醒??僅就所記之言,鋪陳一番《企鵝的復國》,以為寓言罷了!! ───

之『ㄏㄓ 計畫』失敗之後。那時兩極大半已崩解,海平面上升吞噬著大地,四處常有狂風暴雨,一日可睹四季異象。這《卡夫卡村》就是那『企鵝小學堂』的現址, M♪o 的執教處也。據 W!o 說︰這個『變形祭』是 M♪o 達觀面對後所始,當『長陽之祀』因怨『日』廢止之後,早就沒有『飛龍祭』的了。社會上瀰漫著『踏天無望』之情,眼只見『亢龍有悔』之境。於是高唱教育無用論,何不及時行樂,以免悔不當初!因此 M♪o 以科學生活化為經,技術日常化為緯,帶領熱情的學生們重新打造自己家園。經過幾年的辛勤努力,感動了當地眾人紛紛投入創造運動。因為經常於『秋雪』來臨前,慶收一年的耕耘成果,久而久之,就正式命名為『變形祭』的了,以為傳承『科技護生』之旨。然而許多人都不了解 M♪o 為什麼會采『變形記』初版之封面圖,作為『變形祭』的標誌之故?這是因為『初』『化』二字使然。所謂『變形』Transformation 之義,重在『變化』之『化』,其要在『化』之『初』。若是用 M♪o 的說法︰『化』化,教行也。因形近『 It 』,故假借來象徵 Intelligent technology 。千萬別跟『 甲骨文它 』『它』混淆,《 文 》文說︰

它,虫也。从虫而長,象冤曲垂尾形。上古艸居患它,故相問無它乎。凡它之屬皆从它。蛇,它或从虫。

要是弄錯了豈不可笑也!!然而『 It 』智慧科技的傳播力大,而且各種『 It 裝置』『形變』『井通』『貫串』成了『 It 網』阡陌縱橫利益彼此, M♪o 也只能置之一笑,無可如何的了。

行文至此,一時惘然,雖說眼見表面容易,探究事實底蘊困難,更何況還是他鄉之『物』 It ,又缺乏適當範本,看來只好求其神韻,也用借假修真之法,比之擬之僅止形似,徒遺笑於大方之家吧!?

 

 

 

 

 

 

 

 

 

勇闖新世界︰ W!o《卡夫卡村》變形祭︰夢想原點

從《恐懼與戰慄》索倫‧奧貝‧齊克果 1843

經《變形記》法蘭茲‧卡夫卡 1915

到《異鄉人》阿爾貝‧卡繆 1942

一條『存在即感知』的道路,而今早為荒煙漫草掩覆。

W!o^{+} 既來自未來,為何總是言詞不清?恐將變未定之天耶!今日已是『中元節』,也作『盂蘭盆』法會,何故會有『變形祭』乎? ?

一句,

The Transformation Festival on August 28 at Kafka village

 

一張初版《變形記》封面圖,

220px-Metamorphosis

 

一段節自 1995 年板《The Linux Programmer’s Guide》書中文字

6.3.1 Basic Concepts

A named pipe works much like a regular pipe, but does have some noticeable differences.

  • Named pipes exist as a device special file in the file system.
  • Processes of different ancestry can share data through a named pipe.
  • When all I/O is done by sharing processes, the named pipe remains in the file system for later use.

 

到底『甲骨文行 甲骨文不 甲骨文行』行不行解讀的呢?或終將落在『月明星稀』 變形祭☆★ 之時??此『祭』不用古字『甲骨文祭』,譯作 Festival ,是想說『古為今用』的耶!與其疑神疑鬼的『費疑猜』,莫若靜觀其變矣!!

 

 

 

 

 

 

 

 

勇闖新世界︰ 《 Kernel 4.X 》之整裝蓄勢‧設備管理及應用‧五

什麼是『熱插拔』 Hot plugging 呢?根據維基百科詞條所說︰

熱插拔英文Hot swappingHot plugging)即「帶電插拔」,指可以在電腦運作時插上或拔除硬體。配合適當的軟體,便可以在不用關閉電源的情況下插入或拔除支援熱插拔的周邊裝置,不會導致主機或周邊裝置燒毀並且能夠即時偵測及使用新的裝置。相比隨插即用(Plug-and-Play),熱插拔對軟硬體的要求還包含了電源、信號與接地線的接觸順序。

這麼一個『動作』將會引發許多『事件』,就應用上講如何知道有新裝置連上系統?以及作必要的後續處理,常是重要的實務工作。比方說,如果插入一個 USB 大拇哥,樹莓派 raspbian 桌面環境將會開啟一個視窗,問你要不要掛載上面的檔案系統。如此就不必手動 mount ,果然便利得很。不過那個 PCMANFM 檔案管理程式並沒有卸載鍵,需要自己小心處理。此事在樹莓派論壇《Umounting》裡有些人討論。也許最通用的辦法是︰

# 查詢掛載點
pi@raspberrypi ~ mount sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime) proc on /proc type proc (rw,nosuid,nodev,noexec,relatime) udev on /dev type devtmpfs (rw,relatime,size=10240k,nr_inodes=108331,mode=755) devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000) tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=88264k,mode=755) /dev/mmcblk0p2 on / type ext4 (rw,noatime,data=ordered) tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k) tmpfs on /run/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=176520k) /dev/mmcblk0p1 on /boot type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro) none on /sys/fs/cgroup type tmpfs (rw,relatime) none on /sys/fs/cgroup/memory type cgroup (rw,relatime,memory)  # USB 大拇哥第一個掛載點 /dev/sda1 on /media/boot type vfat (rw,nosuid,nodev,relatime,uid=1000,gid=1000,fmask=0022,dmask=0077,codepage=437,iocharset=ascii,shortname=mixed,showexec,utf8,flush,errors=remount-ro,uhelper=udisks)  # USB 大拇哥第二個掛載點 /dev/sda2 on /media/1263ae8d-aaf3-41b6-9ac0-03e7fecb5d6a type ext4 (rw,nosuid,nodev,relatime,data=ordered,uhelper=udisks)  # 卸載 pi@raspberrypi ~ umount /media/boot 
pi@raspberrypi ~ umount /media/1263ae8d-aaf3-41b6-9ac0-03e7fecb5d6a  pi@raspberrypi ~ 

 

要是我們使用 dmesg 指令,則可以觀察插入與移除時,核心輸出的訊息。

# 插入 USB 大拇哥
# dmesg

[261197.348663] usb 1-1.3.3: new high-speed USB device number 11 using dwc_otg
[261197.451619] usb 1-1.3.3: New USB device found, idVendor=0951, idProduct=1624
[261197.451648] usb 1-1.3.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[261197.451666] usb 1-1.3.3: Product: DataTraveler G2
[261197.451683] usb 1-1.3.3: Manufacturer: Kingston
[261197.451700] usb 1-1.3.3: SerialNumber: 0013729982D5A9B0B632008C
[261197.452983] usb-storage 1-1.3.3:1.0: USB Mass Storage device detected
[261197.453599] scsi host2: usb-storage 1-1.3.3:1.0
[261198.449606] scsi 2:0:0:0: Direct-Access Kingston DataTraveler G2 1.00 PQ: 0 ANSI: 2
[261198.451354] sd 2:0:0:0: Attached scsi generic sg0 type 0
[261198.452573] sd 2:0:0:0: [sda] 15663104 512-byte logical blocks: (8.01 GB/7.46 GiB)
[261198.453311] sd 2:0:0:0: [sda] Write Protect is off
[261198.453338] sd 2:0:0:0: [sda] Mode Sense: 23 00 00 00
[261198.453861] sd 2:0:0:0: [sda] No Caching mode page found
[261198.453885] sd 2:0:0:0: [sda] Assuming drive cache: write through
[261198.558981] sda: sda1 sda2
[261198.562407] sd 2:0:0:0: [sda] Attached SCSI removable disk
[261199.064691] FAT-fs (sda1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck.
[261199.168132] EXT4-fs (sda2): mounted filesystem with ordered data mode. Opts: (null)

#移除

[261439.836720] usb 1-1.3.3: USB disconnect, device number 11

 

這就是很多人用 python udev 想做的事。假使你仔細閱讀 pyudev 的文件而且如實操作,你將早已發現

Monitoring devices

Synchronous monitoring

The Linux kernel emits events whenever devices are added, removed (e.g. a USB stick was plugged or unplugged) or have their attributes changed (e.g. the charge level of the battery changed). With pyudev.Monitor you can react on such events, for example to react on added or removed mountable filesystems:

>>> monitor = pyudev.Monitor.from_netlink(context)
>>> monitor.filter_by('block')
>>> for device in iter(monitor.poll, None):
...     if 'ID_FS_TYPE' in device:
...         print('{0} partition {1}'.format(action, device.get('ID_FS_LABEL')))
...
add partition MULTIBOOT
remove partition MULTIBOOT

After construction of a monitor, you can install an event filter on the monitor using filter_by(). In the above example only events from the block subsystem are handled.

Note

Always prefer filter_by() and filter_by_tag() over manually filtering devices (e.g. by device.subsystem == 'block' or tag in device.tags). These methods install the filter on the kernel side. A process waiting for events is thus only woken up for events that match these filters. This is much nicer in terms of power consumption and system load than executing filters in the process itself.

Eventually, you can receive events from the monitor. As you can see, a Monitor is iterable and synchronously yields occurred events. If you iterate over a Monitor, you will synchronously receive events in an endless loop, until you raise an exception, or break the loop.

This is the quick and dirty way of monitoring, suitable for small scripts or quick experiments. In most cases however, simply iterating over the monitor is not sufficient, because it blocks the main thread, and can only be stopped if an event occurs (otherwise the loop is not entered and you have no chance to break it).

所舉的例子 don’t work 。在此給出修正過的例子︰

pi@raspberrypi ~ python3 Python 3.2.3 (default, Mar  1 2013, 11:53:50)  [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import pyudev >>> context = pyudev.Context() >>> monitor = pyudev.Monitor.from_netlink(context) >>> monitor.filter_by('block')  # 需要啟動 >>> monitor.start()  # 修改 action 為 device.action >>> for device in iter(monitor.poll, None): ...     if 'ID_FS_TYPE' in device: ...         print('{0} partition {1}'.format(device.action, device.get('ID_FS_LABEL'))) ...  add partition boot add partition None remove partition None remove partition boot  </pre>    <span style="color: #666699;">同時也給個</span> <h3><a class="toc-backref" href="https://pyudev.readthedocs.org/en/latest/guide.html#id10">Asynchronous monitoring</a></h3> For such use cases, pyudev provides asynchronous monitoring with <a class="reference internal" title="pyudev.MonitorObserver" href="https://pyudev.readthedocs.org/en/latest/api/pyudev.html#pyudev.MonitorObserver"><tt class="xref py py-class docutils literal"><span class="pre">MonitorObserver</span></tt></a>. You can use it to log added and removed mountable filesystems to a file, for example:  <span style="color: #666699;">對當的例子︰</span> <pre class="lang:sh decode:true">pi@raspberrypi ~ python3
Python 3.2.3 (default, Mar  1 2013, 11:53:50) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyudev
>>> context = pyudev.Context()
>>> monitor = pyudev.Monitor.from_netlink(context)
>>> monitor.filter_by('block')
>>> def log_event(action, device):
...     if 'ID_FS_TYPE' in device:
...         print('{0} partition {1}'.format(device.action, device.get('ID_FS_LABEL')))
... 
>>> observer = pyudev.MonitorObserver(monitor, log_event)
>>> observer.start()
>>> add partition boot
add partition None

>>> remove partition None
remove partition boot

>>> 

 

為方便讀寫程式有興趣的讀者,特別列出

gvalkov/python-evdev

裡的兩個程式

【evtest 派生板】

#!/usr/bin/env python
# encoding: utf-8

'''
evdev example - input device event monitor
'''


from sys import argv, exit
from select import select
from evdev import ecodes, InputDevice, list_devices, AbsInfo


usage = 'usage: evtest <device> [<type> <value>]'
evfmt = 'time {:<16} type {} ({}), code {:<4} ({}), value {}'
device_dir = '/dev/input/'
query_type = None
query_value = None


def select_device():
    '''Select a device from the list of accessible input devices.'''

    devices = [InputDevice(i) for i in reversed(list_devices(device_dir))]
    if not devices:
        print('error: no input devices found (do you have rw permission on /dev/input/*?)')
        exit(1)

    dev_fmt = '{0:<3} {1.fn:<20} {1.name:<35} {1.phys}'
    dev_lns = [dev_fmt.format(n, d) for n, d in enumerate(devices)]

    print('ID  {:<20} {:<35} {}'.format('Device', 'Name', 'Phys'))
    print('-' * len(max(dev_lns, key=len)))
    print('\n'.join(dev_lns))
    print('')

    choice = input('Select device [0-{}]:'.format(len(dev_lns)-1))
    return devices[int(choice)]


def print_event(e):
    if e.type == ecodes.EV_SYN:
        if e.code == ecodes.SYN_MT_REPORT:
            print('time {:<16} +++++++++ {} ++++++++'.format(e.timestamp(), ecodes.SYN[e.code]))
        else:
            print('time {:<16} --------- {} --------'.format(e.timestamp(), ecodes.SYN[e.code]))
    else:
        if e.type in ecodes.bytype:
            codename = ecodes.bytype[e.type][e.code]
        else:
            codename = '?'

        print(evfmt.format(e.timestamp(), e.type, ecodes.EV[e.type], e.code, codename, e.value))


if len(argv) == 1:
    device = select_device()

elif len(argv) == 2:
    device = InputDevice(argv[1])

elif len(argv) == 4:
    device = InputDevice(argv[1])
    query_type = argv[2]
    query_value = argv[3]
else:
    print(usage)
    exit(1)

capabs = device.capabilities(verbose=True)

print('Device name: {.name}'.format(device))
print('Device info: {.info}'.format(device))
print('Repeat settings: {}\n'.format(device.repeat))

if ('EV_LED', ecodes.EV_LED) in capabs:
    leds = ','.join(i[0] for i in device.leds(True))
    print('Active LEDs: %s' % leds)

active_keys = ','.join(k[0] for k in device.active_keys(True))
print('Active keys: %s\n' % active_keys)

print('Device capabilities:')
for type, codes in capabs.items():
    print('  Type {} {}:'.format(*type))
    for i in codes:
        # i <- ('BTN_RIGHT', 273) or (['BTN_LEFT', 'BTN_MOUSE'], 272)
        if isinstance(i[1], AbsInfo):
            print('    Code {:<4} {}:'.format(*i[0]))
            print('      {}'.format(i[1]))
        else:
            # multiple names may resolve to one value
            s = ', '.join(i[0]) if isinstance(i[0], list) else i[0]
            print('    Code {:<4} {}'.format(s, i[1]))
    print('')


print('Listening for events ...\n')
while True:
    r, w, e = select([device], [], [])

    for ev in device.read():
        print_event(ev)

 

【pyudev 範例】

#!/usr/bin/env python3

'''
This is an example of using pyudev[1] alongside evdev.
[1]: https://pyudev.readthedocs.org/
'''

import functools
import pyudev

from select import select
from evdev import InputDevice

context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by(subsystem='input')
monitor.start()

fds = {monitor.fileno(): monitor}
finalizers = []

while True:
    r, w, x = select(fds, [], [])

    if monitor.fileno() in r:
        r.remove(monitor.fileno())

        for udev in iter(functools.partial(monitor.poll, 0), None):
            # we're only interested in devices that have a device node
            # (e.g. /dev/input/eventX)
            if not udev.device_node:
                break

            # find the device we're interested in and add it to fds
            for name in (i['NAME'] for i in udev.ancestors if 'NAME' in i):
                # I used a virtual input device for this test - you
                # should adapt this to your needs
                if u'py-evdev-uinput' in name:
                    if udev.action == u'add':
                        print('Device added: %s' % udev)
                        fds[dev.fd] = InputDevice(udev.device_node)
                        break
                    if udev.action == u'remove':
                        print('Device removed: %s' % udev)

                        def helper():
                            global fds
                            fds = {monitor.fileno(): monitor}

                        finalizers.append(helper)
                        break

    for fd in r:
        dev = fds[fd]
        for event in dev.read():
            print(event)

    for i in range(len(finalizers)):
        finalizers.pop()()

 

若是讀者試著用『派生三』 Python3 的萬國碼『標識符』將那兩個程式『中文化』,或果能夠複習許多所學的耶!!