2018年11月25日 星期日

SIP Header fields

SIP 信頭欄位 [RFC3261 §20]

有些信頭欄位只在特定請求或回應有意義,不該出現的或不認識的都忽略。一些常見的信頭欄位名稱也定義了 compact (abbreviated ) 形式,當整個訊息過長造成問題時使用,例如使用 UDP 時超過 MTU。compact form 可以在任何時候使用,也可以混合使用。

完整信頭欄位見 https://www.iana.org/assignments/sip-parameters/sip-parameters.xhtml#sip-parameters-2

信頭欄位相關於 method 和 proxy 處理的資訊如下表。
Header fieldwhereproxyACKBYECANINVOPTREGPRACK
Accept請求
-o-om*oo
2xx
---om*o-
415
-c-cc cc
Accept-Encoding請求
-o-oo oo
2xx
---om*o-
415
-c-cc cc
Accept-Language請求
-o-oo oo
2xx
---om*o-
415
-c-cc cc
Alert-Info請求ar---o- --
180ar---o- --
Allow請求
-o-oo oo
2xx
-o-mm*oo
回應
-o-oo oo
405
-m-mm mm
Authentication-Info2xx
-o-oo oo
Authorization請求
ooooo oo
Call-IDcopyrmmmmm mm
Call-Info任何ar---oo o-
Contact請求
o--mo o-
1xx
---m- --
2xx
---mo o-
3xxd-o-oo oo
485
-o-oo oo
Content-Disposition任何
oo-oo oo
Content-Encoding任何
oo-oo oo
Content-Language任何
oo-oo oo
Content-Length任何arttttt tt
Content-Type任何
**-** **
CSeq複製rmmmmm mm
Date任何aooooo oo
Error-Info300-699a-oooo oo
Expires任何
---o- o-
From複製rmmmmm mm
In-Reply-To請求
---o- --
Max-Forwards請求ammmmmm mm
Min-Expires423
----- m-
MIME-Version任何
oo-oo oo
Organization任何ar---oo o-
Priority請求ar ---o - --
Proxy-Authenticate407ar -m-m m mm
401ar -ooo o oo
Proxy-Authorization請求dr oo-o o oo
Proxy-Require請求ar -o-o o oo
Record-Route請求ar oooo o -o
2xx,18xmr -ooo o -o
Reply-To任何
---o - --
Require任何ar -c-c c cc
Retry-After404,413,480,486
500,503
600,603

-ooo o oo
Route請求adrcccc c cc
Server回應
-ooo o oo
Subject請求
---o - --
Supported請求
-oom*o oo
2xx
-oom*m*oo
Timestamp任何
oooo o oo
To複製(1)r mmmm m mm
Unsupported420
-m-m m mm
User-Agent任何
oooo o oo
Via請求amrmmmm m mm
回應,複製dr mmmm m mm
Warning回應
-ooo o oo
WWW-Authenticate401ar -m-m m mm
407ar -o-o o oo
  • where 欄表示用在請求、回應、特定回應、或是任何請求和回應。複製是指由請求複製到回應,(1) 含可能的 tag 一起複製。
  • proxy 欄表示在 proxy 可進行的動作:
    • a (add):如沒有可新增或 concatenate
    • m (modify):可修改。
    • d (delete):可移除。
    • r (read):必須可讀,所以不能加密。
  • 各個 method 欄說明是否要有:
    • c (conditional):視訊息內容需要。
    • m (mandatory):必要,且接收端必須了解。
    • m*:應該要有,但接收端沒收到時要能處理。
    • o (optional):選擇性的。可有可無,接收端可忽略,例外是 RFC 3261 §20.32 的 Require。
    • t:應該要有,但接收端沒收到時要能處理。如果 transport 用 stream-based 協定 (例如 TCP),則是必要的。
    • *:有訊息 body 時必要。見 RFC 3261 §20.14、§20.15 和 §7.4。
    • -:不能有,接收端遇到的話忽略。
UA 忽略不認識的 extension header parameters。

如果 Contact、From、和 To 包含的 URI 有「,」、「?」、或「;」,必須 用 < and > 包起來。沒包在內的「;」是分割出 header 參數,不是 URI 參數。

Accept

指定回應內容可接受的媒體類型,預設是「application/sdp」,空的 Accept 欄位值表示不接受任何格式,其它語法和語意依循 HTTP Accept

譬喻:
Accept: application/sdp;level=1, application/x-private, text/html

Accept-Encoding

類似 Accept,但限制回應內容可接受的編碼,一般是指壓縮方式。語意跟 HTTP Accept-Encoding 相同。

空的 Accept-Encoding 相當於「Accept-Encoding: identity」,也就是沒有編碼。
沒有 Accept-Encoding 欄位預設 identity。

註:在 HTTP,沒有 Accept-Encoding 欄位表示任何編碼都可以,但偏好 identity。

譬喻:
Accept-Encoding: gzip

Accept-Language

用在請求表示回應訊息內容的 reason phrases、session descriptions、或 status responses 的偏好語言,如果沒有則假設接受任何語言。

依循 HTTP Accept-Language 語法,包括 "q" 參數 (quality) 的偏好順序。

譬喻:
Accept-Language: da, en-gb;q=0.8, en;q=0.7

Alert-Info

在 INVITE 請求,提供不同的鈴聲給 UAS。在 180 (Ringing),提供不同的回鈴音給 UAC。典型用途是 proxy 用來提供不同聲音識別用。

Call-Info 一樣存在安全風險,被放入惡意音訊。應該提供使用者可關閉此功能。

譬喻:
Alert-Info: <http://www.example.com/sounds/moo.wav>

Allow

告知對方所有支援的 Method 列表。沒有 Allow 代表沒講支援哪些 Method,不是不支援任何 Method。

在 method OPTIONS 以外的回應提供 Allow 欄位,減少需要的訊息數目 (???)。

例如:
Allow: INVITE, ACK, OPTIONS, CANCEL, BYE

Authentication-Info

提供跟 HTTP Digest 的相互認證,UAS 可以在成功認證請求的 2xx 回應放這個 header,使用基於 Authorization 的 digest。

語法和語意遵循 RFC 2617

譬喻:
Authentication-Info: nextnonce="47364c23432d2e131a5fb210812c"

Authorization

UA 的認證憑證。RFC 3261 Section 22.2 概述 Authorization 的使用,Section 22.4 說明和 HTTP 認證一起使用時的語法和語意。

Authorization (和 Proxy-Authorization) 多個信頭欄位值不能合併成逗號分隔的列表,要分成多個信頭欄位行。

下面列子,Digest 參數沒用引號刮起來。

Authorization: Digest username="Alice", realm="atlanta.com",
  nonce="84a4cc6f3082121f32b42a2187831a9e",
  response="7587245234b3434cc3412213e5f113a5"

Call-ID (i)

Call 的唯一識別碼,所有 SIP 訊息都需要,關聯的 SIP 訊息都會有相同的值。
  • 一個 UA 註冊應該都使用相同的 Call-ID。
  • dialog 內所有 SIP 訊息的 Call-ID 都相同。Call-ID 加上 From tag 及 To tag 形成一個 peer-to-peer 的 SIP 關係,稱為一個 dialog。一個 Call 可能有多個 dialog。
  • 其它可能的特殊 Method 行為。
Call-ID 用字串比對是否符合,需減少無意的碰撞可能性。 
建議產生方式:由隨機字串加上 UAC 的主機名或 IP 位址組合而成。
使用加密的亂數識別碼 (RFC 1750)
https://tools.ietf.org/html/rfc1750
https://tools.ietf.org/html/rfc4086
實作可使用 "localid@host" 的 form. 
使用加密亂數提供一些保護 against session hijacking (為什麼???)。

一個多媒體會議可能需要多個不同 Call-ID 的呼叫。

譬喻:
Call-ID: f81d4fae-7dec-11d0-a765-00a0c91e6bf6@biloxi.com
i:f81d4fae-7dec-11d0-a765-00a0c91e6bf6@192.0.2.4

Call-Info

提供發話者 (請求) 或受話者 (回應) 額外資訊的 URI,在其 "purpose" 參數說明目的:
  • "icon" 表示適合顯示為 icon 的影像。
  • "info" 是用戶一般描述,例如經由網頁。
  • "card" 提供 vCardLDIF 等格式的名片。
使用 Call-Info 存在安全風險,而被放入惡意訊息,可能是 peer UA,也可能是中間的 proxy。建議只有在放 Call-ID 的設備可以驗證真偽,並且是可信任的,才顯示資訊。

譬喻:
Call-Info: <http://wwww.example.com/alice/photo.jpg> ;purpose=icon,
   <http://www.example.com/alice/> ;purpose=info

Contact (m)

後續請求的接洽窗口 URI,其意義依據所在的請求或回應。可以包含顯示名稱、URI 參數、header 參數。如果有顯示名稱、或 URI 參數、或者 URI 含有「,」「;」「?」時,URI 和 URI 參數要用「<」和「>」包起來。沒包起來的參數都視為 header 參數。顯示名稱可以是 token,要較大的字元集的話用一個 quoted string。這些規則也應用在 To 和 From。

URI 通常有 username,位於某個 FQDN 或者沒註冊的 domain names 則用 IP 位址。

Contact 和 HTTP 的 Location 有類似的角色,然而 HTTP 只允許一個 unquoted 位址。

Contact 參數 "q" 和 "expires" 只用在 REGISTER 請求和回應,或者 3xx 回應。

格式

STAR / (contact-param *(COMMA contact-param))
contact-param  = (name-addr / addr-spec) *(SEMI contact-params)
contact-params = "q" EQUAL qvalue / "expires" EQUAL 1*DIGIT / generic-param
qvalue         =  ( "0" [ "." 0*3DIGIT ] ) / ( "1" [ "." 0*3("0") ] )
譬喻:
Contact: "Mr. Watson" <sip:watson@worcester.bell-telephone.com>
   ;q=0.7; expires=3600,
   "Mr. Watson" <mailto:watson@bell-telephone.com> ;q=0.1
m: <sips:bob@192.0.2.4>;expires=60
  • UAC 建立 dialog 的請求 (在 RFC 3261 只有 INVITE),必須提供只有一個 URI 的 Contact,無論後續請求在不在 dialog 內都可以作為接受請求使用。
  • 如果 Request-URI 或 top Route 含有一個 SIPS URI,Contact 也必須是 SIPS URI。
  • REGISTER
  • Contact alias
  • 只有 * 允許 comma-separated list
註:m 意思 moved。
比較:Via

Content-Disposition

訊息體或其中 multipart 的部署,擴展 RFC 2183 的 MIME Content-Type

Content-Disposition 在 RFC 3261 新增,並在 IANA 註冊了 4 種新 disposition-types:
  • alert:alert 使用者的客製化鈴聲。
  • icon:顯示給使用者的 icon 影像。
  • render:顯示給使用者。
  • session :作為通話媒體的 session 描述,如 SDP
為了向前相容,如果沒 Content-Disposition, Content-Type 是 application/sdp 時假設為 "session",其它為 "render"。

如果收到不了解的 Content-Type 或 Content-Disposition,參數 handling 說明 UAS 應
該如何反應。 有定義的值有 "optional" 和 "required",預設是 "required"。handling 參數說明在 RFC 3204。

譬喻:
Content-Disposition: session

Content-Encoding (e)

訊息體的編碼,需要解壓縮或解碼才能得到 Content-Type 所參照的 media-type 時才需要,可依序列出多個施加的編碼。

Content-Encoding 欄位值不分大小寫,登記在 IANA。
https://tools.ietf.org/html/rfc2616#section-3.5 定義的語法。

Client 可對請求的訊息體編碼。
Server 可用列在請求 Accept-Encoding 的編碼,對回應的訊息體編碼。

譬喻:
Content-Encoding: gzip
e: tar

Content-Language

訊息體的語言,見 https://tools.ietf.org/html/rfc2616#section-14.12

譬喻:
Content-Language: fr

Content-Length (l)

訊息體的長度。十進位數字表示位元組數目,不含分隔 body 的 CRLF,0 以上的 值都是 valid。如果使用 stream-based transport 協定 (例如 TCP) 是必要的。沒 body 時,Content-Length 是 0。

能夠省略 Content-Length 簡化建立動態產生回應的像 cgi scripts。

譬喻:
Content-Length: 349
l: 173

Content-Type (c)

訊息體媒體類型,有 message-body 時是必要的。

譬喻:
Content-Type: application/sdp
c: text/html; charset=ISO-8859-4

CSeq

Command Sequence,每個 SIP 訊息都要有,包含一個序號及一個 Method 名稱,譬喻:
CSeq: 314159 INVITE
序號是某個 UAC 在同一個 Call-ID 下 Command 的順序,大致來講就是 Transaction 的順序,一開始是比 231 小的亂數,後續每次發出仝款 Call-ID 的新請求時,序號就加 1,讓 UAS 辨別是新的 Transaction 還是重傳。
  • 例外是 ACK 和 CANCEL,他們算是 INVITE 的延伸,沿用 INVITE 的序號。PRACK 序號會加 1。
  • 一個 UA 的 REGISTER 原則上開機後都使用仝款 Call-ID,CSeq 序號是註冊請求的順序。

Date

請求或回應首次送時的 GMT 日期和時間。不同於 HTTP/1.1,SIP 只支援最新的 RFC 1123 格式的日期,但如同 HTTP/1.1,SIP 限制時區為 "GMT"。RFC 1123 Date 有分大小寫。

Date 可讓沒 battery-backed clock 的簡易終端系統獲得目前時間。

譬喻:
      Date: Sat, 13 Nov 2010 23:29:00 GMT

Expires

訊息或內容從接收到請求開始的過期時間,值是 0 到 (2**32)-1 之間的秒數,精確的意思
視 Method 而定。

INVITE 的過期不影響邀請成功後實際 session 可使用的時間。session 可使用的時間限制
可表達在 Session 描述協定裡。

Error-Info

提供關於錯誤狀態回應的額外資訊。

UAC 用戶界面可能從有彈出式視窗和聲音的 PC softclients,到透過 gateway 連接、只有聲音的「黑」話機或端點。與其強迫 server 選擇在 Reason-Phrase 傳送細節還是播放錄音,Error-Info 允許兩者都送,由 UAC 選擇用哪種呈現給發話者。

UAC 可視 Error-Info 的 SIP 或 SIPS URI 如同 redirect 的 Contact 產生新 INVITE 得到錄音,非 SIP URI 可呈現給用戶。
譬喻:
  SIP/2.0 404 The number you have dialed is not in service
  Error-Info: <sip:not-in-service-recording@atlanta.com>

From (f)

請求的發出端。可能跟請求建立 dialog 的發出端不同。和 Contact 有相同規則的顯示名稱、URI、URI 參數、和信頭參數。 

選擇性的顯示名稱用來顯示在人機界面,要隱藏的話用「Anonymous」。

格式是 name-addr 或 addr-spec 加上 tag 參數,和其它參數

( name-addr / addr-spec ) SEMI "tag" EQUAL token *( SEMI generic-param )

addr-spec 是 name-addr 的簡化,不能有 display-name、「,」、「?」、「;」。

兩個 From 相等:URI 且參數 match。擴充參數一個沒有則忽略。display name 和有無 angle bracket 不影響是否相等。

譬喻:
From: "A. G. Bell" <sip:agb@bell-telephone.com> ;tag=a48s
From: sip:+12125551212@server.phone2net.com;tag=887s
f: Anonymous <sip:c8oqz84zk7z@privacy.org>;tag=hyh8

Organization

送出請求或回應的 SIP 元件所屬組織名稱。Client 可用來過濾呼叫。

譬喻:
Organization: Boxes by Bob

Record-Route

格式
rec-route *(COMMA rec-route)
rec-route = name-addr *( SEMI generic-param )

Reply-To

格式
( name-addr / addr-spec ) *( SEMI generic-param )

Route

格式
route-param *(COMMA route-param)
route-param = name-addr *( SEMI generic-param )

To (t)

格式
( name-addr / addr-spec ) *( SEMI to-param )
to-param  =  "tag" EQUAL token / generic-param

Via (v)

一開始的 UAC 和後續途經的每個 proxy 都會加一個 Via 放 transport 及位址,依序作為回應的路徑。

格式 sent-protocol host[:port];branch=branch[;參數...]

  • sent-protocol 格式是「SIP/2.0/transport」,transport 可以是 UDPTCPTLSSCTP 等。
  • host 可以是主機名稱或網路位址,可以加上 port number。(沒用途?)
  • 參數 branch:
    • 意思是分支。在 RFC3261 以「z9hG4bK」開頭,是必要的。值對某個 UAC 而言是時空上唯一,用來快速識別 Transaction,但在 CANCEL 和 INVITE 失敗的 ACK 是沿用原始請求的 branch。
    • 在 RFC2543,forking proxy 插入 branch 用來區分不同分支,同一個 call 在不同 proxy 可能用相同的 branch 值,沒有唯一的特性,不適合作為 Transaction ID。某種程度上不會產生「z9hG4bK」開頭的值。
    • Proxy 也用來偵測 loop。
  • 參數 sent-by:Client Transport 紀錄送出的位址「host:port」,host 建議 FQDN。port 可省略,預設值依據傳輸協定,UDP/TCP/SCTP 是 5060、TLS 是 5061。在 用來送回應。
    • 收到請求的 Via 中有 sent-by 且 branch 符合自己送的,
  • 參數 received: Server Transport 收到請求檢查頂頭 Via 的 sent-by,
    如果是網域主機名稱,或不同於封包的來源 IP 位址時,紀錄封包的來源位址,助於之後 server transport 送回應。
  • 參數 maddr:Client Transport 紀錄
  • 參數 ttl:Client Transport 紀錄
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds
比較:Contact

2018年11月10日 星期六

lightning

Lightning to USB-C

Lightning 訊號 (接頭單面有 8 接腳點對稱到另一面,插座只有單面)

1A8B8GNDGround
2A7B2L0+Lane 0 positive
3A6B3L0-Lane 0 negative
4A5B1ID0Identification/Control 0
5A4B4VBUSPower
6A3B6D-Lane 1 negative
7A2B7D+Lane 1 positive
8A1B5GNDIdentification/Control 1

USB 線含有 4 IC

  • NXP SP3D2
  • STMicroelectronics USB2A
  • Texas Instruments BQ2025
  • markings identified as 4S (functionality is known)
週邊
  • 母 USB-A + 母 Lightning (Lightning 對 USB 3 相機轉接器 $1190):轉成母 USB 3 + Lightning,讀取相片、影片,連接各種 USB 周邊設備,如集線器、乙太網路、音訊/MIDI 介面、讀卡機 (可轉HDMI?)
  • 母 micro USB (Lightning 對 Micro USB 轉接器 $590):可連接 micro USB 連接線進行同步與充電。
  • Ethernet + 母 Lightning (Belkin 乙太網路 + 電源轉接器 $3290):支援 PoE,Belkin Connect app 韌體更新
  • 轉成 HDMI 或 VGA + Lightning $1490 https://www.techbang.com/posts/12467
  • 轉成兩個 Lightning:可同時聽音樂和充電 (Belkin Lightning Audio + Charge Rockstar)
  • 轉成 3.5mm Audio + Lightning:可同時聽音樂和充電 (Belkin 3.5 mm Audio + Charge Rockstar)
  • 母 3.5mm Audio 或 EarPods:內有 DAC「338S00140/A0QK1623/TW」,有可能來自 Cirrus Logic。
  • SD 相片讀卡機 (只能讀相片?)
  • USB 相片轉接器 (只能讀相片?)

Apple iPad Camera Connection Kit 裡面的 Camera Connector (轉 USB 母頭那個)

lightning:USB slave、USB master (SD reader)、HDMI/VGA output

參考

  1. https://www.techinsights.com/blog/systems-analysis-apple-lightning-usb-cable
  • https://www.techinsights.com/blog/apple-lightning-cable-teardown
  • https://zh.ifixit.com/News/8448/apple-audio-adapter-teardown

2018年11月4日 星期日

bash: SHELL GRAMMAR

bash 基本指令以 control operator 結束,組成成份用 blank 分隔,格式依序如下:
[變數指定...] 指令 [引數...][輸出入導向]
用到的 metacharacter 除了輸出入轉向,就只有 blank。

回傳值是 exit status。如果被 signal n 結束,回傳 128+n 。

基本指令可以組合成 Pipeline 和 Lists。另外還有 Compound Commands、Coprocesses、Function。

Pipelines

pipeline 是一系列用控制運算子「|」或「|&」分隔的一個以上基本指令 (一個也算!?)。
[time [-p]] [ ! ] command [ [|⎪|&] command2 ... ]
前一個指令的標準輸出透過 pipe 導到下個指令的標準輸入。如果使用「|&」包含標準錯誤一併導向,相當於「2>&1 |」。


所有指令結束後才回傳最後指令的離開狀態。但如果啟用 pipefail 選項時,回傳最後回傳非 0 指令的狀態。如果 pipeline 前面有 !,邏輯反向離開狀態。

如果前面有保留字 time,結束時回報執行歷經的時間、耗用的使用者及系統時間。加選項 -p 採用 POSIX 輸出格式。如果在 posix 模式,下個 token 以「-」開始,time 不作為保留字。可設定變數 TIMEFORMAT 指定時間訊息的顯示格式。

如果在 posix 模式,time 之後可能跟著換行,此時顯示 shell 和其 children 耗用的全部使用者和系統時間。

pipeline 的每個指令都在獨立的行程 (i.e., subshell) 執行。
一個 pipeline 稱為一個 job。

Lists

list 是一系列用控制運算子 「;」、「&」、「&&」或「||」分隔的一個以上 pipeline,最後可以「;」或「&」結束。<newline> 可取代「;」。

這些 list 運算子前後有特定的執行關係:
  • 「&&」:執行成功 (回傳 0) 才執行後面的指令。
  • 「||」:執行失敗 (回傳非 0) 才執行後面的指令。
  • 「;」或換行:等候執行完成後再執行後面的指令。
  • 「&」:在 subshell 背景執行,不等候完成直接回傳 0,後面指令開始執行。
其中「&&」和「||」有相同 precedence,再來是「;」和「&」有相同 precedence。
List 最後回傳最後指令執行的結果。

Compound Commands

複合指令

(list)

在 subshell 環境執行 list (見 bash COMMAND EXECUTION ENVIRONMENT),結束不影響原本環境變數。

{ list; }

在目前 shell 環境執行 list。需要以 <newline> 或「;」結束,是由於「{」、「 }」只是保留字,不是 metacharacter 能區隔出字,需要有 metacharacter 區隔出字來,且 list 必須有「;」或換行表示最後的指令結束。

((expression))

進行算術運算,結果 0 回傳 1;否則回傳 0。

[[ expression ]]

依據 conditional expression 是 true 回傳 0,否則回傳 1。不進行 Word splitting 和 pathname expansion。進行 tilde expansion、parameter and variable expansion、arithmetic expansion、command  substitution、process  substitution、和 quote removal。Conditional operators such as -f must be unquoted to be recognized as primaries.

當 == (或 =) 或 != 用在 [[ 指令,右邊是 pattern 進行 Pattern Matching,如同啟用選項 extglob。如果啟用選項 nocasematch,比對不分大小寫。pattern 任何部份可以 quoted 來強迫直接字串比對。

另外還有額外 binary operator「=~」使用 extended  regular  expression (regex()),如果  regular  expression syntactically 錯誤回傳 2。Substrings  matched  by parenthesized subexpressions within the regular expression 存在 BASH_REMATCH 陣列,其中 index 0 是整個符合的部份,index n 是第 n 個parenthesized subexpression 符合的部份。

用下列優先權,表示式可以結合:
( expression ):優先進行。
! expression:True if expression is false.
expression1 && expression2:expression1 false 回傳 false,否則看 expression2 是否 true。
expression1 || expression2:expression1 true 回傳 true,否則看 expression2 是否 true。

for name [ [ in [ word ... ] ] ; ] do list ; done

擴展 in 之後的 word 列表產生許多項目,變數 name 依序設成每個項目來執行 list。如果省略 in word,則拿有設的位置參數當作項目。

for (( expr1 ; expr2 ; expr3 )) ; do list ; done

expr1、expr2、和 expr3 都是 arithmetic expression,如有省略則 evaluate 為 1。首先計算 expr1,然後重複計算 expr2 直到為 0。每次 expr2 算出不為 0,執行 list 後計算 expr3。

select name [ in word ] ; do list ; done

擴展 in 之後的 word 列表產生許多項目,在標準錯誤前置順序數字印出。如果省略 in word,則拿有設的位置參數當作項目。然後顯示 PS3 prompt,讀取標準輸入選擇項目設為 name 執行 list。直到讀到 EOF 後結束。讀到其它不合理的值 name 會設為 null。讀到的會存在變數 REPLY。

case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac

首先擴展 word,然後依序比對每個 pattern,採用 pathname 擴展的比對方式。word 用到的擴展有 tilde expansion、parameter  and  variable  expansion、arithmetic  expansion、command substitution、process substitution、和 quote removal。每個檢查的 pattern 用到的擴展有 tilde expansion、parameter and variable expansion、arithmetic expansion、command substitution、和 process substitution。如果啟用選項 nocasematch,比對不管大小寫。當找到一個符合,執行對應的 list。如果使用 ;; operator,不進行後續比對。如果使用 ;&,持續執行下個 pattern 的 list。使用 ;;& 持續比對剩下的 patten,如果符合執行其 list。比對沒符合回傳 0。

if list; then list; [ elif list; then list; ] ... [ else list; ] fi

執行 if list,回傳 0 則執行 then list,否則依序執行每個 elif  list 如果回傳 0 執行對應的 then list 後結束。都沒有回傳 0,執行 else list。

while list-1; do list-2; done
until list-1; do list-2; done

while:只要 list-1 回傳 0,不斷執行 list-2 。
until:只要 list-1 回傳 0,不斷執行 list-2 。 

Coprocesses

coprocess 是前置保留字 coproc 的 shell 指令,在子 shell 背景執行,並建立雙向 pipe。
coproc [NAME] command [redirections]
建立名為 NAME 的 coprocess,預設名稱是 COPROC。如果 command 是基本指令,不能提供 NAME,否則會被解釋成基本指令的第一個字。當 coprocess 執行時,會建立名為 NAME 的陣列。指令的標準輸出透過 pipe 連結到指定給 NAME[0] 的 file descriptor,指令的標準輸入透過 pipe 連結到指定給 NAME[1] 的 file descriptor。pipe 在任何 redirection 前建立。那些 file descriptor 可用標準 word expansion 作為其它指令的引數或導向。執行 coprocess 的 process ID 可見變數 NAME_PID。內建指令 wait 可用來等候 coprocess 結束。

Shell Function

shell 函數像基本指令一樣呼叫,暫時使用新的一組位置參數來自引數和參數 # 執行 compound command,結束後回復。如下宣告名為 name 的 shell 函數:

[function] name () compound-command [redirection]
function name { compound-command; } [redirection]
有 () 可以不需要保留字 function,沒有 () 需要 { list; }。

在 posix 模式,name 不可以跟 POSIX special builtins 一樣。shell 函數定義的離開狀態是 0,除非有 syntax 錯誤或 name 跟 readonly 函數相同。執行的離開狀態是裡面最後執行指令的離開狀態。

shell function stores  a  series  of commands for later execution.
Functions are executed
       in the context of the current shell;  no  new  process  is  created  to
       interpret  them  (contrast  this with the execution of a shell script).

特殊參數 0 不變,變數 FUNCTNAME 的 first  element 設為函數名稱。

其它執行環境不變,除了
  • DEBUG 和 RETURN traps (見 bash 內建指令 trap),除非函數有給 trace 屬性 (見內建指令 declare) 或透過內建指令 set 啟用 shell 選項 -o functrace
  • ERR trap,除非啟用 shell 選項 -o errtrace。
變數跟 caller 共享,函數 local 變數可以用內建指令 local 宣告。

函數可以 recursive 執行。變數 FUNCNEST 如果設為大於 0 的值,限制函數最大 nesting level,執行超過的話造成整個 command abort。

函數內執行內建指令 return,結束函數,RETURN  trap 的指令會執行。

函數名稱和定義可用有 -f 選項的內建指令 declare 或  typeset 列出。-F 選項只列出函數名稱。函數可用內建指令 export -f 匯出給子 shell 使用。內建指令 unset -f 可刪除函數。註:相同名稱的函數和變數會造成傳遞的環境變數 multiple identically-named  entries 而可能造成問題。

參考來源

bash mag-page 的 SHELL GRAMMAR 和 FUNCTIONS 節

2018年11月1日 星期四

[C] VLA

VLA (Variable-Length Array) 起自 C99,讓陣列大小可以在執行時才決定,雖然有方便性,但有缺點:
  • 執行時需要決定陣列大小,會慢一點,程式也會大一點。(或許最終使用的記憶體較少)
  • LLVM Clang 不支援在 struct 裡放 VLA (GCC 支援),只支援 C99 形式的 VLA。
  • 最重要的是 VLA 的使用在 kernel 堆疊有安全疑慮 (security implication)。 
Linux v4.20 移除了 VLA,並加了「-Wvla」來發出編譯告警,避免不經意再加入 VLA 的程式碼。

參考:
  1. The Linux Kernel Is Now VLA-Free: A Win For Security, Less Overhead & Better For Clang
延伸閱讀:
  • 大小 0 的陣列

2018年10月27日 星期六

bash PARAMETERS

bash 或其它 shell 的參數 (parameter),是一個儲存值的地方,可以是
  • 變數 (variable),名稱 (name) 非數字開頭由英文字母、數字及「_」組成的字,有一個值,並有屬性 (attribute) 可由內建指令 declare 指定。陣列。Shell 有內動的變數。
  • 一個數字
  • 一個特殊字元
參數經過指定或空字串 (沒) 產生。
參數=[]
透過內建指令 unset 移除。

所有值會經歷 tilde 擴展、參數和變數擴展、指令取代、算術擴展、及 quote 移除 (見 EXPANSION)。如果變數的屬性為整數 (integer),即使沒 $((...)) 也會以[算術表示式](見 bash Arithmetic Expansion) evaluated。除了「$@」外,不進行 Word splitting。不進行 Pathname expansion。變數指定亦可放在內建指令 alias、declare、typeset、export、readonly、及 local (declaration 指令) 的引數。
當用在 posix 模式,這些內建指令 may appear in a command after one or more instances of the command builtin and retain these assignment statement properties。

使用 += 運算指定一個值給 shell 變數或 array index 可進行 append 或加法運算,包括前面接受變數指定作為引數的內建指令。:
  • 整數變數:加法運算加上目前的值。
  • 使用 compound assignment 應用在陣列:indexed 陣列最後會多加一個值,associative 陣列新增 key-value 對。
  • 字串變數:值擴展後附加到字串後面。

Positional Parameters 位置參數

位置參數是從 1 開始的數字,由執行時的引數依序指定,不能由指定 statement 指定,可由內建指令 set 重新指定。執行 shell 函數時,位置參數暫時由函數引數取代。

當位置參數是多位數字時,需要用 braces 括起來。

註:$0 不算是位置參數。

Special Parameters 特殊參數

只能讀,不能指定。
*從 1 開始的所有位置參數,每個位置參數擴展為個別的字。依據進行的 context,可能會進行進一步 word splitting 和 pathname expansion。如果在雙引號裡面 ("$*"),擴展為一個字。位置參數間由特殊變數 IFS 第一個字元連接起來的。如果 IFS 沒設,則用 space 連接。如果 IFS 是 null,則不插入字元直接連接。
@從 1 開始的所有位置參數。如果在雙引號裡面 ("$@"),每個位置參數擴展為個別的字,相當於 "$1" "$2" ...  If the double-quoted expansion occurs  within  a word,  the  expansion of the first parameter is joined with the beginning part of the original word, and the expansion  of  the last  parameter  is  joined  with the last part of the original word.
#位置參數的數目。
?最後前景執行 pipeline 的 exit statu。
-目前 option flags。
$shell 的 process ID。在 ()  subshell,是 current shell 的 process ID,不是 subshell 的。
!最後背景執行的 process ID。
0shell 或 shell script 的名稱。
_shell 一開始時,設為 the absolute pathname used  to  invoke the shell or shell script being executed as passed in the environment or argument list.  Subsequently, expands  to  the  last argument to the previous command, after expansion.  Also set to the full pathname used to  invoke  each  command  executed  and placed  in  the  environment  exported  to  that command.  When checking mail, this parameter holds the name of the  mail  file currently being checked.

Shell Variables

下列變數由 shell 設定:
BASH:執行的完整檔名。
BASHOPTS
BASHPID
BASH_ARGC
BASH_ARGV
BASH_CMDS
BASH_COMMAND
BASH_EXECUTION_STRING
BASH_LINENO



BASH_REMATCH
由指令 [[ 的 =~ 運算指定的唯讀陣列,其中 index 0 是整個比對符合的字串,index n 是 第 n 個 parenthesized subexpression 比對的結果。
BASH_SOURCE
BASH_SUBSHELL
BASH_VERSINFO
BASH_VERSION
COMP_CWORD
COMP_KEY
COMP_LINE
COMP_POINT
COMP_TYPE
COMP_WORDBREAKS
COMP_WORDS
COPROC
DIRSTACK
EUID
FUNCNAME
GROUPS
HISTCMD
HOSTNAME
HOSTTYPE
LINENO
MACHTYPE
MAPFILE
OLDPWD
OPTARG
OPTIND
OSTYPE
PIPESTATUS
PPID
PWD
RANDOM
READLINE_LINE
READLINE_POINT
REPLY
SECONDS
SHELLOPTS
SHLVL
UID

下列變數 shell 會使用到,有時 bash 會指定預設值:

BASH_COMPAT
BASH_ENV
BASH_XTRACEFD
CDPATH
CHILD_MAX
COLUMNS
COMPREPLY
EMACS
ENV
FCEDIT
FIGNORE
FUNCNEST
GLOBIGNORE
HISTCONTROL
HISTFILE
HISTFILESIZE
HISTIGNORE
HISTSIZE
HISTTIMEFORMAT


HOME
目前使用者的家目錄。作為內建指令 cd 的預設引數及進行 tilde 擴展用。

每個使用者帳戶在 /etc/passwd 會有一行,包含用「:」分隔的 7 個欄位,其中最後第二欄是使用者的家目錄,login 程式用來設 $HOME。
HOSTFILE
IFS
IGNOREEOF
INPUTRC
LANG
LC_ALL
LC_COLLATE
LC_CTYPE
LC_MESSAGES
LC_NUMERIC

LINES
MAIL
MAILCHECK
MAILPATH
OPTERR
PATH
POSIXLY_CORRECT
PROMPT_COMMAND
PROMPT_DIRTRIM
PS1
PS2
PS3
PS4
SHELL
TIMEFORMAT
TMOUT
TMPDIR
auto_resume
histchars

Arrays

nameref 參考變數

變數可使用內建指令 declare 或 local 的 -n 選項設定 nameref 屬性,參照另一個變數,讓變數間接修改,此時除了改變 nameref 屬性外,指定、移除和其它屬性修改都進行在參照的變數。
declare -n ref=$R #建立 nameref 變數 ref
unset ref #移除變數 $R
unset -n ref #移除 nameref ref

nameref 常用在 shell 函數裡參照函數引數。例如在 shell 函數裡:
declare -n ref=$1
建立 nameref 變數 ref 參照第 1 個引數。

如果 for 迴圈的 control variable 有 nameref 屬性, the list of words can be a list of shell variables, and a name reference will be established for each word in the list, in turn,  when the loop is executed.

陣列變數不能指定 nameref 屬性,但 nameref 變數可以參照陣列變數和 subscripted  array variables。

參考

man bash 的 PARAMETERS

2018年10月6日 星期六

bash EXPANSION

bash 指令行切成字後會進行7 種擴展,依下列順序:
  1. brace ({}):
  2. tilde (~):目錄擴展
  3. $ parameter and variable 擴展、arithmetic 擴展、command substitution ($)
  4. word splitting:上面 ($) 類擴展如不在雙引號內,會依據 IFS 進行字切割。
  5. pathname
有些系統還支援額外的 process substitution,在上述順序 2 和 3 同時進行。

最後移除一開始就有的、未 quoted 的 quote 字元。

只有 brace expansion, word splitting, 及 pathname expansion 會改變字的數目,其它擴展擴展一個字為一個字,唯一的例外是 "$@" 及 "${name[@]}" 的擴展 (見 PARAMETERS).

Brace Expansion {}

{} 間一系列以「,」區隔的字串個別擴展為 word,或是兩個數字或兩個單一字元以「..」區隔的序列擴展 {x..y[..incr]}。序列擴展如果是數字的,前面可以加 0 來嘗試強迫產生相同位
數的數字。數字或字元間的序列擴展預設的增減值是 1 或 -1,可以再加「..數字」設定增減值。{} 裡可以有 {} 進行巢狀擴展。

「${」不做 brace 擴展,以免跟 parameter 擴展衝突。

例如
  • 「a{d,c,b}e」會擴展成「ade ace abe」
  • mkdir /usr/local/src/bash/{old,new,dist,bugs}
  • chown root /usr/{ucb/{ex,edit},lib/{ex?.?*,how_ex}}
傳統的 sh 沒有 Brace 擴展,要停用 Brace 擴展可以使用 +B 選項。

Tilde Expansion ~

tilde-prefix

Parameter Expansion

$ 字元引入參數擴展、指令取代、或算術擴展。

$參數 或 ${參數} 取代為變數值,參數名稱可用 {} 包起來避免跟緊接著的字元有錯誤連結。名稱是兩位以上數子,必須用 {} 包起來。

間接變數

下面 word 的部份會進行 tilde expansion、參數擴展、指令取代、和算術擴展。


${parameter:-word}
當 parameter unset 或 null 時,使用預設值 word。
${parameter:=word}
當 parameter unset 或 null 時,使用預設值 word 並指定給 parameter。位置參數和特殊參數不能用這種方式指定。
${parameter:?word}
${parameter:+word}
${parameter:offset}
${parameter:offset:length}
${!prefix*}
${!prefix@}
${!name[*]}
${!name[@]}
${#parameter}
參數長度
${parameter#word}
移除字串開頭最短符合 word 的部份。
${parameter##word}
移除字串開頭最長符合 word 的部份。
${parameter%word}
移除字串結尾最短符合 word 的部份。
${parameter%%word}
移除字串結尾最長符合 word 的部份。
${parameter/pattern/string}
${parameter//pattern/string}
${parameter/#pattern/string}
???
${parameter^pattern}
${parameter^^pattern}
轉換成大寫。
${parameter,pattern}
${parameter,,pattern}
轉換成小寫。

Command Substitution 指令取代

$(指令) 或 `指令`,取代為指令執行的輸出 (移除最後換行)。

$(cat file) 可以用更快的 $(< file) 取代。

Arithmetic Expansion

$((expression))

Process Substitution

Word Splitting 切割字

Pathname Expansion 路徑擴展

Pattern Matching

Quote Removal

移除所有非上述擴展產生的,unquoted 用的「\」、「'」、及「"」。

參考

  1. man bash 的 EXPANSION 節
  2. http://godleon.blogspot.tw/2007/06/shell-script-linux-pipe.html

2018年9月15日 星期六

compile wireshark

ninja-build
libgcrypt20-dev
qtbase5-dev
qttools5-dev-tools
qtmultimedia5-dev
libqt5svg5-dev
https://www.wireshark.org/docs/wsdg_html_chunked/ChSrcBuildFirstTime.html#_building_on_unix


$ cd run
$ WIRESHARK_RUN_FROM_BUILD_DIRECTORY=1 ./wireshark

參考
wireshark

SIP header Via

所有 SIP 訊息 都要有 Via,縮寫 v。一開始的 UAC 和後續途經的每個 proxy 都會疊加一個 Via 放傳送的位址,依序作為回應的路徑。 格式 sent-protocol sent-by [ ;branch= branch ][ ; 參數 ...] s...