星期日, 7月 24, 2016

scanf()

輸入格式轉換,存到記憶體

#include <stdio.h>

int scanf(const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);
int sscanf(const char *str, const char *format, ...);

#include <stdarg.h>

int vscanf(const char *format, va_list ap);
int vsscanf(const char *str, const char *format, va_list ap);
int vfscanf(FILE *stream, const char *format, va_list ap);

format 是一個字串,描述如何處理輸入字元。如果沒有輸入、或比對失敗,就停止,回傳轉換成功的次數。format 內容可以是:
  • 空白字元集,包括 space、tab、newline 等,比對 0 個以上的空白字元集。
  • % 開頭的轉換規範。
  • 其它一般字元
每個轉換規範以 '%' 或 %n$ 開始,後者指定用第幾個變數存。接著:
  • (optional) '*':依照轉換定義讀取,但不儲存,不計成功轉換次數。
  • (optional) 'm':用在字串轉換 (%s, %c, %[),自動配置足夠的記憶體放字串,之後需要 free()。
  • (optional) 十位數字說明最大 field width,不含字串結尾 0。
  • (optional) 改變存成的資料型態
    • h:存成 short int 或 unsigned short int
    • hh:存成 signed char 或 unsigned char
    • j:存成 intmax_t 或 uintmax_t
    • l:整數存成 long 或 unsigned long,浮點存成 double
    • ll:跟 L 一樣,用在 %c 或 %s 表示寬字元。
    • L:整數存成 long long,浮點存成 long double
    • t:存成 ptrdiff_t
    • z:存成 size_t
  • 轉換定義
    • %:比對 %
    • d:比對十進位整數,可以是有號,結果存到 int
    • i:比對對整數,可以是有號,可以是 0x 或 0X 開始的十六進位數字、0 開頭的八進位數字、不然則是十進位。結果存到 int。
    • o:比對無號八進位整數,結果存到 unsigned int。
    • u:比對無號十進位整數,結果存到 unsigned int。
    • x, X:比對無號十六進位整數,結果存到 unsigned int。
    • f, e, g, E, a:有號浮點數字,結果存到 float。
    • s:不含 white-space 的字串,存到字串。
    • c:數個字元,存到 char 陣列。
    • [字元集]:比對字元集存到字串。字元集不能是空的,不省略開頭的 white space。排除這些字元集的話,字元集以 ^ 開始。如果字元集要包含 ],可放在第一個字元。兩字元間可夾 - 表示範圍。例如 [^]0-9-] 表示任何字元不含 ]、0 到 9、-。
    • p:比對指標值存到 void 指標。
    • n:計數字元數目存到 int。可能不計成功的轉換次數。

問題:可以忽略開頭字元嗎?

參考:printf

SIP REGISTER

SIP 註冊 [RFC3261 §10]

SIP 用戶在其網域 (domain) 中有個帳號,稱為 address-of-record,簡單來說就是「user@domain」,但其對應的實際位址 (binding) 是可以變動的,可透過 SIP REGISTER 登記目前的位址。registrar 專指接受並回覆 SIP REGISTER 請求的 UAS,在其管理的網域維護對應表,讓其它用戶要建立通話時可透過 proxy server 或 redirect server 查詢。
                                              bob
                                            +----+
                                            | UA |
                                            |    |
                                            +----+
                                               |
                                               |3)INVITE
                                               |   carol@chicago.com
      chicago.com        +--------+            V
      +---------+ 2)Store|Location|4)Query +-----+
      |Registrar|=======>| Service|<=======|Proxy|sip.chicago.com
      +---------+        +--------+=======>+-----+
            A                      5)Resp      |
            |                                  |
            |                                  |
  1)REGISTER|                                  |
            |                                  |
         +----+                                |
         | UA |<-------------------------------+
cube2214a|    |                            6)INVITE
         +----+                    carol@cube2214a.chicago.com
          carol

SIP REGISTER 可進行的動作包括建立 (create)、新增 (add)、更新效期 (refresh)、詢問 (query)、移除 (delete)、及修改 (modify)。每個用戶可有多個位址,可能是多個 UAC 註冊的不同位址,或者是不同情況使用的位址。每個位址都有效期限,到期前需要更新效期才能持續使用。效期設為 0 將位址移除,之後可再新增來達到修改的目的。

header 欄位
  • Request-URI (必要):domain,例如 "sip:chicago.com",不能有 "userinfo" 及 "@"。
  • To (必要):要建立、詢問、或修改的 address-of-record,包含有 user name。
  • From (必要):負責註冊者的 address-of-record,通常跟 To: 一致,或者由第三方註冊。
  • Call-ID 及 CSeq (必要):對特定 registrar,UAC 每次開機後應該使用相同的 Call-ID,搭配 CSeq 每次請求加一,依此 registrar 可以偵測出沒按照順序到達的 REGISTER 請求。(反之,如果 Call-ID 不同便無法偵測順序是否正確)
  • Contact (may): 要登記連結的位址 (address bindings),可有多個,可以是 sip:、tel:、mailto: 等。可加 q 參數作為偏好使用。沒此項欄位時用來詢問。
  • Contact 各自的 expires 參數、或 Expires (may):到期秒數,註冊時可建議,但最終由 registar 決定。大於 232-1 (4294967295 秒或 136 年) 可視為 232-1,Malformed 值應該視為 3600。0 表示移除,此時 Contact 可用 * 移除所有位址連結。
  • Route (may)
  • Record-Route (有可能會有,但忽略):因為不會建立 dialog,所以沒效用。
  • Contact 的 action 參數:來自 RFC 2543,deprecated,不該使用。
registrar response:
  • 2xx 的 Contact 會列出所有的 binding。註冊成功的 UA 找出自己那一項,根據其 expires 參數或 Expires 欄位值計算並更新有效期限。
  • Date: 用來設定時間。
  • 423 (Interval Too Brief) 的 Min-Expires:可使用等於或大於 Min-Expires 的 expires 值重新嘗試註冊。
  • 501 Not Implemented:不支援單純詢問。
  • 不能產生 6xx,不能有 Record-Route。
動作ContactExpire
建立特定位址建議值
新增特定位址建議值
更新效期特定位址建議值
詢問不需要
移除特定位址,或 * 表全部。0
修改特定位址建議值
registrar 位址除了使用設定外,也可以用 domain 位址 DNS 取得,或 well-known "all SIP servers" 的 multicast 位址 "sip.mcast.net" (IPv4 是 224.0.1.75,IPv6 ?)。但使用 multicast 只是讓 registrar 知道位置,不會有回應 (為什麼?)。

參考

  • From TS 24.229:Unless either the user or the application within the UE has determined that a continued registration is not required the UE shall reregister an already registered public user identity either 600 seconds before the expiration time if the previous registration was for greater than 1200 seconds, or when half of the time has expired if the previous registration was for 1200 seconds or less, or when the UE intends to update its capabilities according to RFC 3840 [62] or when the UE needs to modify the ICSI values that the UE intends to use in a g.3gpp.icsi-ref media feature tag or IARI values that the UE intends to use in the g.3gpp.iari-ref media feature tag.
  • M. Schooler, "A multicast user directory service for synchronous rendezvous," Master's Thesis CS-TR-96-18, Department of Computer Science, California Institute of Technology, Pasadena, California, Aug. 1996.