2020年3月24日 星期二

system arp cache

指令

arp -aip neigh show顯示 arp cache
arp -d hostname?移除 entry
arp -s hostname hw_addr?新增永久 entry
arp -s hostname hw_addr temp?新增暫時 entry

-A 或 -p [inet|...]: protocol

-H 或 -t [ether|...]:HW type

nDv

/proc/net/arp

arp flags

0x02COM, completed entry (ha valid)
0x04PERM, permanent entry
0x08PUBL, publish entry
0x10USETRAILERS, has requested trailers
0x20NETMASK, want to use a netmask (only for proxy entries)
0x40DONTPUB, don't answer this addresses
0x?MAGIC, AUTO

arp 項目狀態

none新建立。
incomplete新建立後首次 ARP 請求。
reachable
已確認可達性後尚未過期。更新?
permanent手動設定,不偵測可達性,從不過期。
noarp
不偵測可達性。
stale已過期仍嘗試直送,使用時進入 delay 確認。經過 gc_stale_time 時間進入 ?failed 狀態。
delay排程 ARP 請求確認
probe送 ARP 請求
failed
沒收到回應。?gc_interval 週期檢查如果沒任何參照則移除。

/proc/sys/net/ipv4/neigh/*/*

  • anycast_delay
  • app_solicit
  • base_reachable_time, base_reachable_time_ms:過期時間,預設 30 秒,實際會設為 ± 一半時間的亂數。過期後稱為 stale。
  • delay_first_probe_time:過期後 first probe 的延遲,預設 5 秒。
  • gc_stale_time:garbage collection stale time,多久檢查 stale entry 一次,預設 60 秒。it is resolved again before sending data to it.
  • locktime
  • mcast_solicit
  • proxy_delay
  • proxy_qlen
  • retrans_time, retrans_time_ms
  • ucast_solicit
  • unres_qlen

註:IPv6 用 ND 取代 ARP

在 ARP table 至少有 gc_thresh1 筆時,才以 gc_interval 週期執行 neigh_periodic_work() 進行 ARP garbage collection,避免消耗太多 CPU cycles 卻沒有省到什麼記憶體。gc_thresh3 是 ARP table 筆數上限。

?只有 ARP 的 mac 會存到 ARP cache

?何時會 unicast ARP 確認?

參考

  1. man arp
  2. http://linux-ip.net/html/ether-arp.html

2020年3月23日 星期一

reverse voltage protection

diode:浪費的電 = VF x IF,以 1N5401T 為例,2A 時 VF = 0.85,浪費 1.7W。

schottky diode:有較小的 VF,但注意許多有達數 mA 的 reverse leakage current (IR),保護效果較差。STPS2L60 2A 時 VF = 0.55 = 1.1W,IR < 100uA。

pMOSFET FQP47P06 VGS < -4V 時 ON。MOSFET 有 parasitic body diode ,接 12V 電源有 1V 壓降,相當於 VGS = 1V - 12V = -11V,RDS(ON) 最大 = 0.026 ohm,浪費 I2R = 22 x 0.026 = 0.104W。選擇 pMOSFET,VDS 耐壓要夠,VGS break down 電壓要夠,RDS 越小越好。

有些 MOSFET VGS break down 電壓只有 +-15V,Gate 加電阻到地,Gate 和 Source 間放 10V zener diode,讓 VGS 最大 10V

https://www.youtube.com/watch?v=IrB-FPcv1Dc

https://lirobo.blogspot.com/2020/03/bjt.html

2020年3月21日 星期六

bash exit status

bash 結束狀態 (exit status)
指令執行的結束狀態是 waitpid 系統呼叫或等效函數的回傳值,範圍 0 ~ 255,0 表示成功 (true),否則表示失敗 (false)。shell 特別定義 126 以上的值。
  • 2:所有內建指令回傳 2 表示使用不正確,一般是 invalid options 或 missing arguments。
  • 126:檔案有找到,但不含可執行屬性。
  • 127:檔案沒找到。
  • 128+N:因 fatal signal N 而結束
指令因 expansion 或 redirection 錯誤也是回傳失敗。bash 本身回傳最後執行指令的結束狀態。見內建指令 exit。

參考:man bash 的 EXIT STATUS

BJT

  • 天生是防逆流。
  • 教科書講飽和時的 Vce  0.2V 起跳。 但實際上,大多 BJT 在小電流 10mA~50mA 時都觀察到壓降更小,甚至接近 0V。 在很多電子開關應用上已經夠了,甚至比一些 nMOS 還低。

BJT 是電流放大,在架構上帶限流,不用擔心瞬間電流過大弄垮系統,可避免一些雜訊減少 EMI。BJT 只要電流控制好不易燒毀~尤其是靜電。 BJT 非常強壯,不像 MOS,適合用在連外的電源開關上。 https://www.facebook.com/twembedded/posts/2915547031826847

BJT 大功率會比較燙。

應用:電流開關,天生防逆流

應用:電壓偵測器

應用:簡易耐十幾 V 小電流 LDO。例如用 12 Vin 供電給 RTC。https://www.facebook.com/twembedded/photos/a.336725383042371/3117519414962940

應用:OCP https://www.facebook.com/twembedded/posts/3072405346141014

應用:小電流系統

  • https://www.facebook.com/twembedded/posts/2976382489076634  
  • https://www.facebook.com/twembedded/posts/2635953676452852
參考
  1. https://www.facebook.com/twembedded/posts/2915611271820423

https://www.facebook.com/twembedded/posts/2915743455140538

https://www.facebook.com/twembedded/posts/2638640626184157

https://www.facebook.com/twembedded/posts/3018693128178903 

https://www.facebook.com/twembedded/posts/2822064987841719

2020年3月15日 星期日

SIP Transactions

SIP 是靠 Transaction (譯作「交易」?) 完成的協定,用 Method 表示款功能,動作是發出請求 (request),然後等候回應 (response)。回應會使先有一寡暫時回應 (provisional responses),最尾攏有一個最後回應 (final responses)。INVITE Transaction 較複雜,除了上述回應外,最尾還要送 ACK 請求來確定最後回應。

以 SIP 分層功能來看,Transaction 服務 Transaction User (TU),透過 SIP Transport 層藉由 UDP/TCP/? 傳收封包。Transaction 層又可分成在 Client 端的 Client Transaction,對應到 Server 端的 Server Transaction。Transaction 層找出訊息的相關 Transaction,處理逾時及重傳。任何 UAC 的工作都透過一系列 transaction 完成。流程如下:
  1. [Client] TU 發出請求,Transaction 層建立一個新 Client Transaction,透過傳輸層確保可靠地送出。
  2. [Server] 收到請求時上傳給 TU 處理,依需要建立 Server Transaction。
  3. [Server] TU 的任何回應,都經過 Server Transaction 給傳輸層確保可靠地傳送。如果收到重傳的請求,不再送給 TU,只重傳回應。
  4. [Client] 收到回應找到對應的 Client Transaction,過濾掉重傳的最後回應或不允許的回應 (例如 ACK 的回應),然後地交給 TU。
此外,如果是 INVITE 請求,Client Transaction 還負責產生失敗回應的 ACK。Server Transaction 吸收失敗回應的 ACK。

INVITE 2xx 回應和其 ACK 特別處理。INVITE 2xx 回應只由 UAS 重傳,ACK 只由 UAC 重傳,確保主叫端得知所有接受呼叫的用戶。因此,INVITE 2xx 回應重傳和 ACK 產生由 UA core 處理,不是 Transaction 層。沿路上的每個 Proxy 只是轉送每個 INVITE 的 2xx 回應和 ACK。

UA 和 stateful proxy 都有 transaction 層功能,stateless proxy 則不需要 transaction 層功能。

找出訊息的相關 Transaction 比對
Via branch
[待續]

以下說明分成一般 Transaction 和 INVITE Transaction (含 ACK)。

一般 Transaction

請求要在 64*T1 (T1 預設 0.5 秒,所以總共是 64*0.5 = 32 秒) 前要收到最後回應,不然就逾時而結束。

如果使用 UDP,由 Transaction 層提供重傳機制,Client Transaction 重送請求直到收到最後回應,間隔是 T1, 2*T1, 4*T1, ..., T2, T2, T2, ...。一開始是 T1,然後每次加倍直到 T2 或收到暫時回應後,改為 T2。
Server Transaction 收到重傳的請求,不往 TU 送,有回應過會重送回應。傳送最後回應後,有可能對方沒收到而收到重傳的請求,需使用 Timer J 等候 64*T1 才把 Transaction 結束。
T2 表示 server transaction 不馬上回應時應該的回應時間。

一般請求重送間隔照 T1 指數型退讓最大 T2,總共最長 64*T1。預設 T1 0.5 秒、T2 4 秒,間隔會是 0.5 秒、1 秒、2 秒、4 秒、4 秒、4 秒、4 秒、4 秒、4 秒、4 秒 (共 7 次 4 秒)。

Client Transaction 收到最後回應後,可能還會有重傳的回應在半路,等候 T4 才把 Transaction 結束,預設是 5 秒。

一般 Client Transaction 狀態流程 (修改自 RFC3261)

                    |Request from TU:
                    |send request
Timer E:            V
send request  +-----------+
    +---------|           |-------------------+
    |         |  Trying   | Timer F           |
    +-------->|           | or Transport Err.:|
              +-----------+ inform TU         |
 200-699:        |  |1xx:                     |
 resp. to TU     |  |resp. to TU              |
 +---------------+  |                         |
 |                  |                         |
 |   Timer E:       V       Timer F           |
 |   send req +-----------+ or Transport Err.:|
 |  +---------|           | inform TU         |
 |  |         |Proceeding |------------------>|
 |  +-------->|           |-----+             |
 |            +-----------+     |1xx:         |
 |   200-699:    |     ^        |resp to TU   |
 |   resp. to TU |     +--------+             |
 |               V                            |
 |            +-----------+                   |
 +----------->| Completed |                   |
              +-----------+                   |
                    | Timer K:                |
                    V                         |
              +-----------+                   |
              | Terminated|<------------------+
              +-----------+

註:Timer F 計數 64*T1 逾時,Timer E 在 UDP 時計數重傳間隔,Timer K 在 UDP 時計數 T4 等候可能還在半路的重傳回應。

一般 Server Transaction 狀態流程 (修改自 RFC3261)

                    | 收到請求:
                    | 轉給 TU
TU 最後回應:         V
送回應         +-----------+
+-------------| Trying    |
|             +-----------+
|                   | TU 暫時回應:
|                   | 送回應
| TU 新暫時回應或     V       Trnsprt Err:
| 再次收到請求:+-----------+ Inform TU
| 送回應  +----| Proceeding|-------------->+
|        |    +-----------+               |
|        |      ^   |                     | 
|        +------+   |TU 最後回應:          |
+------------------>|送回應                |
                    V       Trnsprt Err:  |
  再次收到請求:+-----------+ Inform TU     |
  送回應  +----| Completed |-------------->+
         |    +-----------+               |
         |      ^   |Timer J 到期          |
         +------+   V                     |
              +-----------+               |
              | Terminated|<--------------+
              +-----------+

註:

  • TU 回應都轉給傳輸層傳輸,不主動重傳,只有再次收到請求才重傳。
  • 請求含重傳最久持續 64*T1,Timer J 等候可能的重傳。

INVITE Transaction

INVITE Transaction 比一般 Transaction 多了要對最後回應回送 ACK 作確認,形成三路交握 -- INVITE、回應、ACK。

如果使用 UDP,由 SIP Transaction 層提供重傳機制

  • Client Transaction 重傳 INVITE 直到收到回應 (通常會有暫時回應)。Server Transaction 收到重傳的 INVITE,重送回應。
  • Server Transaction 重傳失敗的最後回應直到收到 ACK。Client Transaction 收到重傳的最後回應,重送 ACK。
註:一般請求預期很快會完成 (應該不會超過 T2,預設 4 秒)。而 INVITE 預期會有長時間延遲,包括路由到被叫端、振鈴等到接聽後才有最後回應。過程中通常會有多個暫時回應,例如 100 Trying 和 180 Ringing。Proxy/UAS 收到 INVITE,預期 0.2 秒內不會有回應必須先回送 100 Trying,停止 INVITE 重送來避免網路擁塞。到達被叫端振鈴時回送 180 Ringing。
註:一般請求是重傳直到收到最後回應,可確認有收到最後回應。而 INVITE 最後回應較久,所以收到任何回應就停止重傳,並需要另外 ACK 確認最後回應。
註:除了 100 Trying 以外的暫時回應,如 180 Ringing,這些如果需要重傳機制,需要另
外支援 PRACK

INVITE 重送間隔是 T1、2*T1、4*T1、8*T1、16*T1、32*T1 (exponential backoff)。一開始是 T1,然後每次加倍,逾時是 64*T1,所以總共最多傳 7 次。。

失敗回應重送間隔和一般請求相同,一樣是 T1, 2*T1, 4*T1, ..., T2, T2, T2, ...。
成功回應的重送間隔也是一樣,只是改由 UAC Core 重送。

失敗回應的 ACK 和 UAC core 產生給 2xx 的 ACK 不同 (Section 13)。
  • 原始 INVITE 請求的 Call-ID、From、Request-URI、To、單一 Via。
  • 回應的 To tag 和 Route
  • CSeq 序號和原始請求一樣,method 為 ACK。
雖然任何請求都可以放信體,但避免讓 ACK 因信體不認得而 reject,並不建議放信體。如果要放,type 限制出現在 INVITE 的 type。如果是 415 的 ACK,ACK 信體可以是任何列在 415 Accept 信頭欄位的 type。

INVITE Client Transaction 狀態流程 (修改自 RFC3261)
                               |INVITE from TU:
             Timer A fires:    |INVITE sent
             Reset A,          V                      Timer B fires
             INVITE sent +-----------+                or Transport Err.:
               +---------|           |---------------+inform TU
               |         |  Calling  |               |
               +-------->|           |-------------->|
                         +-----------+ 2xx:          |
                            |  |       2xx to TU     |
300-699:    +---------------+  |1xx:                 |
ACK sent    |                  |1xx to TU            |
resp. to TU |  1xx:            V                     |
            |  1xx to TU  -----------+ 2xx:          |
            |  +---------|           | 2xx to TU     |
            |  |         |Proceeding |-------------->|
            |  +-------->|           |               |
            |            +-----------+               |
            |                  |300-699:             |
            +----------------->|ACK sent,            |
                               |resp. to TU          |
               300-699:        V                     |
               ACK sent  +-----------+Transport Err.:|
               +---------|           |Inform TU      |
               |         | Completed |-------------->|
               +-------->|           |               |
                         +-----------+               |
                               | Timer D fires:      |
                               v                     |
                         +-----------+               |
                         | Terminated|<--------------+
                         +-----------+
註:Timer B 計數 64*T1 逾時,Timer A 在 UDP 時計數重傳間隔。
註:收到暫時回應進入 "Proceeding" 狀態。
註:最後回應是成功時 (2xx) 通知 TU 後結束,ACK 由 TU 負責。不同 TU 對 2xx 有不同處理,Proxy Core 會往上游轉送,UAC Core 會產生 ACK,並直送 UAS。重傳的 2xx 會沒有 Client Transaction 符合並上傳 TU 處理。
註:收到最後回應是失敗時進入 "Completed" 狀態,負責 ACK 事宜。在 UDP 時,再次收到重送,Timer D 計數 32 秒以上等候有可能還在半路上的最後回應。Timer D 相當於 INVITE Server Transaction 的 Timer H,預設是 64*T1。但由於 INVITE Client Transaction 並不知道對方 T1 值,所以使用 absolute minimum of 32s instead of basing Timer D on T1。

INVITE Server Transaction 狀態流程 (修改自 RFC3261)

      收到請求:|
      轉給 TU  |  如果無法在 200ms 內回應:
               +-------+ 送 100 Trying 
               |       |
TU 回應失敗:    V       |     TU 回應成功:
送回應     +---------+  |     送回應
+---------| Trying  |--|----------------->+
|         +---------+  |                  |
|     TU 暫時回應:|     |                 |
|         送回應  |     |                  |
| TU 暫時回應或    V     v     TU 回應成功: |
| 再次收到請求:+-----------+   送回應       |
| 送回應  +----| Proceeding|-------------->+
|        |    |           |               |
|        +--->|           |               |
|             +-----------+ Trnsprt Err:  | 
|       TU 回應失敗:|    |   Inform TU     |
|           送回應   |   +---------------->|
+------------------>|       Timer H 到期或 |
 再次收到請求或       V       Trnsprt Err:  |
 Timer G 到期:+-----------+ Inform TU     |
 送回應   +----| Completed |-------------->+
         |    +-----------+               |
         |      ^   | ACK                 |
         +------+   V                     |
              +-----------+               |
              | Confirmed |               |
              +-----------+               |
                    |Timer I 到期          |
                    V                     |
              +-----------+               |
              | Terminated|<--------------+
              +-----------+

和一般 Transaction 差別:

  • 如果預期無法在 200ms 內回應,就送 100 Trying 直接進 Proceeding。100 Trying 依據 Section 8.2.6 建立,除了 To tag 不應該 (SHOULD NOT) 放 (當請求沒有時)。
  • 成功就回 2xx 結束 Transaction,收到 ACK 是不同 Transaction 不建 Transaction 直接上傳 TU。TU 重傳 2xx 直到收到 ACK,然後做可能的後續處理,包括 SDP、可能進行 re-INVITE 等。
  • 再次收到請求重傳失敗回應機制還是在,但因為對方收到暫時回應後就不會再次請求,所以多了 Timer G 主動重傳失敗回應,最多歷時 Timer H (64*T1),直到收到 ACK。再次請求也最多歷時 64*T1,加上回應失敗的延遲,可以有效覆蓋 Timer J 的角色。收到 ACK 後,路上可能還有,多了狀態 Confirmed 等候 Timer I (5 秒) 消化額外的 ACK。

Client Transaction

事件狀態主動重送逾時
送INV請求CallingTimer ATimer B
收到暫時回應Proceeding
收到失敗回應送 ACK
CompletedTimer D
逾時 或 無法送 或 收到 2xx
TerminatedNA
事件狀態主動重送逾時
送一般請求TryingTimer ETimer F
收到暫時回應ProceedingTimer ETimer F
收到最後回應CompletedTimer K
逾時 或 無法送
TerminatedNA

Server Transaction

事件狀態再次收到請求主動重送逾時
收到請求Trying忽略
送暫時回應Proceeding重送回應無 (PRACK)
一般送最後回應CompletedTimer J
INV送失敗回應Timer G64*T1
INV送成功回應
收到 ACK (相同 Via branch)Confirmed忽略Timer I
收到 ACK (在 TU 有 Dialog)
逾時 或
無法送 (通知 TU)
TerminatedNA
送成功回應在 TU 有 DialogTU 處理TU 處理
收到 ACK (不同 Via branch)TU 處理

INV 成功回應的重傳本來是在 TU 處理的,可整合到 Completed 狀態,採用 INV 失敗回應相同的 Timer G 重送和 Timer H 結束,變成 INV 最後回應都採用相同的處理方式。此時收到 ACK 也要進到 Confirmed 狀態。

註:transaction 源自 HTTP

參考

  1. RFC3261 §17

2020年3月13日 星期五

IP Multicast

有些應用需要進行一對多或多對多的封包傳送,例如網路廣播電台、網路電視廣播。如果封包使用 unicast 單點傳送的方式,傳送端需要先知道所有傳送的對象,一個一個傳送,對傳送端負擔較大,也需要很多倍的網路頻寬。封包的 broadcast 廣播通常會侷限在本地區域網路內,如果開放到網際網路容易造成網路雍塞而癱瘓。最適當的方式是用 multicast 多點傳送,傳送端負擔變少只需要傳送一次,由網路設備 (router 或 switch) 負責複製給每個需要的接收者,大大減少傳送端所需要的網路頻寬。

由於是由網路設備複製,網路設備需要知道那些網路埠有接收者,傳送者並不需要知道每個接收者是誰,只要知道有接收者並負責把風包丟出來即可。

IPv4 multicast 位址
  • 224.0.0.0/4,開頭為二進位的 1110,範圍為 224.0.0.0 ~ 239.255.255.255。
  • 對應的 Ethernet MAC 位址為 01:00:5e:xx:xx:xx,後 23-bit 來自 IP 位址後面 23 bits。可能 IP 位址不同,但 MAC 位址相同,此時 Switch 需要 multicast 它們的聯集。
  • 224.0.0/24:local link 區塊,由 IANA 個別指定。對應的 MAC 位址是 01:00:5e:00:00:xx,通常 L2 switch 會 broadcast 處理,不出 router。
    • 224.0.0.1:all hosts
    • 224.0.0.2:all routers
    • 224.0.0.18:VRRP
    • 224.0.0.22:IGMPv3 report
    • 224.0.0.251:mDNS
    • 224.0.0.252:LLMNR
  • 224.0.1/24:internetwork 區塊,由 IANA 個別指定
    • 224.0.1.1:NTP
    • 224.0.1.129 ~ 132:PTP 
    • 224.0.1.75:SIP
  • 224.0.2/24,224.4/15,233.252/14:Ad Hoc
  • 224.2/16:SDP/SAP
  • 232.0.0.0/8:Source Specific Multicast
  • 233.0.0.0/8:GLOP,16-bit ASN
  • 234.0.0.0/8:Unicast-Prefix-Based IPv4 Multicast addresses
  • 239.0.0.0/8:Administratively Scoped IP Multicast,由網管使用,封包不跨網管,位址在不同網管可重複使用。通常會再切割成較小區塊來限制特定 multicast 應用的範圍,避免小區塊間不必要的資料量。
    • 239.192/14:Organization local scope
    • 239.255/16:Local scope,不能再分割,可以往下擴充
    • Scope Relative addresses:相對於每個小區塊最後一個位址。每個小區塊預留最後 256 個位址
      • -0 (239.255.255.255):
      • -5 (239.255.255.250):SSDP
其他說明
  • 主要概念是一個 multicast IP 位址及由接收者驅動而建立的 multicast distribution tree
    • 接收者透過協定加入 multicast 群組,在 LAN 使用 IGMP (IPv4) 或 MLD (IPv6),在 routing domain 內用 PIM, MOSPF,domain 外用 MBGP
  • Protocol Independent Multicast
  • 封包傳送要遠離 source IP,跟 unicast 要接近 destination IP 不同。
  • IPv6 multicast 位址使用 Ethernet MAC 位址 33:33:xx:xx:xx:xx,後 32-bit 來自 IPv6 位址後面 4 bytes。
  • switch 監聽 IGMP 來維護其 multicast 表格稱為 IGMP snooping,如果有 L3 功能則可作為 IGMP querier。如果網路沒有 multicast router,有 IGMP snooping 能力的 switch 可用來產生需要的 IGMP 訊息給用戶加入 multicast 群組。如果 switch 沒這些功能,就只能 broadcast 處理這些 multicast 封包。
  • 無線網路原本就是 boardcast 環境,行為跟 Ethernet 有些不同。如果用戶都不在省電模式,multicast 封包會馬上送。如果有用戶在省電模式,AP 只在每個 DTIM interval 後送,且只在一個支援的速率送。無線網路有 ACK 來避免高遺失率,但 multicast 封包並不用 ACK 而可能有高遺失率。現在有一些方法處理這個問題,例如改用 unicast 一個一個傳 (只需改 AP)、或要求每個用戶 ACK (需要 AP 跟用戶都改)。
  • RTP、RSVP、mDNS
  • multicast 本質比較不適合 connection-oriented 這種有重傳的協定,但也有 TCP 例子 -- Pragmatic General Multicast
應用
  • Multicast Paging
參考來源
  1. CISCO:GUIDELINES FOR ENTERPRISE IP MULTICAST ADDRESS ALLOCATION (2004)
  2. https://en.wikipedia.org/wiki/IP_multicast
  3. https://en.wikipedia.org/wiki/Multicast_address 

2020年3月7日 星期六

Singly Linked List

Linked List 是程式常見的資料結構,通常是指 Double Linked List (如 linux/list.h),但這裡說 Singly Linked List。

Singly linked list 第一個 node 透過 head 指標存取,每個 node 有一個 next 指標串下個 node,最後 node (稱為 tail) 的next 為 nil。

移除 node

typedef struct list {
    item *head;
} list;

static inline item **ll_find(list *list, item *node)
{
    item **pp = &list->head;
    while(*pp != node)
        pp = &(*pp)->next;
    return pp;
}

void ll_remove(list *list, item *node)
{
    item **pp = ll_find(list, node);
    *pp = node->next;
}
  • https://github.com/mkirchner/linked-list-good-taste:傳統用 prev 和 cur 指標,這裡用 ndirect pointer 是指到 node pointer 的 pointer,可用來移除一個 node (remove 只是將 node 脫離 list,而 delete 還包括抹除) 和在 node 之前插入一個 node。

如果作為 FIFO 常常需要將 node 放到 tail,額外紀錄 tail 指標:

typedef struct list {
    item *head;
    item *tail;
} list;

// 先準備好 node, node->next = null;
void ll_insert_tail(list *list, item *node)
{
    if (list->tail)
        list->tail->next = node; // 避免 node 加入時,tail 剛好刪除
    else
        list->head = node;
    list->tail = node;
}

item *ll_remove_head(list *list)
{
    item *node = list->head;
    list->head = node->next;
    if (list->tail == node)
        list->tail = NULL;
    return node;
}

lock-free linked list 用在 concurrent 環境:兩個或以上 thread 執行操作不干擾彼此間的工作。

基本操作有兩個

  1. 插入 node p 之後
  2. 移除 node p 之後那個 node
// compare and swap
void *cas(void **addr, void *old, void *new)
{
    void *value = ∗addr
    if (value == old)
        ∗add = new
    return value;
}

void ll_insert_after(item *p, item *n)
{
    do {
        item *next = p->next;
        n->next = next;
    } while (cas(address-of(p->next), next, n));
}

itme *ll_remove_after(item *p)
{
}

問題:如何確認某個 node 是否有其它 thread 仍在使用?例如 thread A 停在 node n (可能搜尋一半,或其它),此時 thread B 移除 node n 並釋出記憶體,會造成 thread A 問題

問題
cache unfriendly

https://en.wikipedia.org/wiki/Non-blocking_linked_list
https://ithelp.ithome.com.tw/articles/10214944
https://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html

Circular doubly linked list

kamailio tm module

tm (transaction module) 為有些應用需要,提供 t_relay() 建立 SIP transaction 狀態,依據 destination set 全部一起轉送。會吸收上游的重傳,產生下游的重傳,會需要較多記憶體及處理器處理,延遲也較長。

destination set 項目可以來自:
  • configuration file
  • user location database
  • seturi
  • sethost
  • append_branch
  • exec_dset()
destination set 內有多個時,會全部一起轉送 (forward in parallel)。也可以依 Q 的優先權循序轉送 (forward in serial),先用 t_load_contacts() 將全部 destination set 載到變數,並依照 Q 排序。t_next_contacts() 將最高優先權取出作為 destination set,t_on_failure() 設定收到失敗或 timeout 要執行的函數,然後執行 t_relay() 轉送。如果收到失敗回應或 timeout,會執行 t_on_failure() 設定的函數,這個函式內容應該是 t_next_contacts() 看有沒有下一個優先權,有的話的一樣 t_on_failure() 設定函數和 t_relay() 轉送。

參數

函數
  • t_relay([ host, port ]), t_relay_to_xxx:stateful 版本的 forward() (自動建立 transaction state?)
  • t_on_failure(failure_route):
  • t_on_branch_failure(branch_failure_route):
  • t_on_reply(onreply_route)
  • t_on_branch(branch_route)
  • t_newtran():用在 UAS
  • t_reply(code, reason_phrase):
  • t_lookup_request()
  • t_retransmit_reply()
  • t_release():timeout 後結束 state
  • t_forward_nonack([ip, port]), t_forward_nonack_xxx
  • t_set_fr(fr_inv_timeout [, fr_timeout]), t_reset_fr()
  • t_set_max_lifetime(inv_lifetime, noninv_lifetime), t_reset_max_lifetime()
  • t_set_retr(retr_t1_interval, retr_t2_interval), t_reset_retr()
  • t_set_auto_inv_100(0|1)
  • t_branch_timeout()
  • t_branch_replied()
  • t_any_timeout()
  • t_any_replied()
  • t_grep_status("code")
  • t_is_canceled()
  • t_is_expired()
  • t_relay_cancel()
  • t_lookup_cancel([1])
  • t_drop_replies([mode])
  • t_save_lumps()
  • t_load_contacts()
  • t_next_contacts()
  • t_next_contact_flow()
  • t_check_status(re)
  • t_check_trans()
  • t_set_disable_6xx(0|1)
  • t_set_disable_failover(0|1)
  • t_set_disable_internal_reply(0|1)
  • t_replicate([params])
  • t_relay_to(proxy, flags)
  • t_set_no_e2e_cancel_reason(0|1)
  • t_is_set(target)
  • t_use_uac_headers()

to_replicate
to_relay_to

佈署 UAS
t_newtran()
t_reply()

t_check_trans()
參考來源:
  1. http://kamailio.org/docs/modules/stable/modules/tm.html

2020年3月6日 星期五

類比話機

無免持KX-TS500KX-TSC60KX-T7703KX-TSC11KX-TS560
有免持
KX-TSC62KX-T7705
?KX-TS580
電源電池
來電顯示30 組50 組
脈衝撥號?
鈴聲大/小/關大/小/關大/小/關大/小/關大/小/關
聽筒音量4 段4 段可調整4 段4 段
暫切100/300/600ms
靜音?有 (KX-TS580)
音樂保留?
重撥5 組5 組20組20組
自動重撥15次??
日期時間
其它
秘密撥號
50組電話簿
長途限撥
按鍵鎖
暫停鍵
LCD 亮度調整
50組電話簿
限制撥號
長途限撥(限0,或2位數)
按鍵鎖
暫停鍵

20151011 購買 KX-TSC62 NT$1090, KX-TS500 NT$488


中諾話機 F013 響鈴太大聲,喇叭串 200Ω (後來發現可設定鈴聲)

有免電池變壓器,但支援耳麥的話機嗎?

藍牙

  • Panasonic國際牌KX-TGH260TWB 無線DECT電話(黑)(藍芽
  • 松下藍牙電話機 KX-TG7621B KX-TG7731S
  • Vtech 2合1藍牙整合室內無線電話雙子機組 ES1610 TW
  • 藍牙室內電話轉接器BTA340 BTA320黑,同ARTECH XBA802
  • Xlink BT2 藍牙電話轉接器
  • BT-3000 藍芽 電話 + 藍芽 耳機 (可辦公室及家用-BPVOICE第一遠距及通話品質效果最佳的 藍芽 電話)

WiFi+DECT雙系統 Panasonic KX-PRW120 智慧型無線電話

Homesitter HS-700/E 保護神 四合一 警報器: 淹水 + 高溫/低溫 + 斷電(竊盜) + 主機低電量

SIP header Via

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