ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上

2012年1月11日 星期三

android code trace : rild, service socket

  1. s_listen_event : processCommandsCallback, listenCallback,
  2. s_commands_event : listenCallback
  3. s_wakeupfd_event : eventLoop
  4. s_debug_event : RIL_register
其中 各 event 對應的 socket, callback function:
  1. s_listen_event : s_fdListen, listenCallback
  2. s_commands_event : s_fdCommand, processCommandsCallback
  3. s_wakeupfd_event : s_fdWakeupRead, processWakeupCallback
  4. s_debug_event : s_fdDebug, debugCallback
s_wakeupfd_event 是用 pipe implement,只是為讓 event loop 跳出 select( ) 的 blocking 狀態。
所以內容很無聊。
正如變數名稱所說:只是為了 wakeup event loop。

s_debug_event 提供 socket : SOCKET_NAME_RIL_DEBUG 供額外控制 ril 的介面。

s_listen_event 是 Rild 的主要 service socket : SOCKET_NAME_RIL。

這兩個 socket: #define SOCKET_NAME_RIL "rild" #define SOCKET_NAME_RIL_DEBUG "rild-debug" 都是在 init.rc 中 create 好:
socket rild stream 660 root radio socket rild-debug stream 660 radio system 所以在 rild 中只要經過 android_get_control_socket() 從環境變數中取出 socket id 就可以,不用自己 create (bind)。


rild 是一對多的 server,所有的 client 經過 SOCKET_RIL 向 rild 取得命令通道,之後就可以和 rild 溝通。

rild 從 s_fdListen 得到 client 的連線 (accept),就keep 這個 connection : s_command_event。
同時,繼續 s_fdListen 的 listen( ),等待另一個 client 的連線。
==> 一般 network server 的作法。

這個 socket base , event callback 的架構中心,就是 libril/ril_event.cpp 的 ril_event_loop().

ril_event_loop 是一個一般化的 event callback loop,就是select block,return if data available
然後call 對應的 callback。

2012年1月10日 星期二

android code trace : gsm service

base/telephony/java/android/telephony/ServiceState.java 是 3G Modem 的狀態。
用來表示 3G Service State。

因為 3G State 不是單純的 OK, fail。
所以些class 來存放 Service state。

ServiceState 裡面包含的資料有: private int mState = STATE_OUT_OF_SERVICE; private boolean mRoaming; private String mOperatorAlphaLong; private String mOperatorAlphaShort; private String mOperatorNumeric; private boolean mIsManualNetworkSelection; private boolean mIsEmergencyOnly; //***** CDMA private int mRadioTechnology; private boolean mCssIndicator; private int mNetworkId; private int mSystemId; private int mCdmaRoamingIndicator; private int mCdmaDefaultRoamingIndicator; private int mCdmaEriIconIndex; private int mCdmaEriIconMode; System Setting 和 Status 的大部分資料都是從 SeviceState 這個 object 來的。

在 TelephonyRegistry.java : 有一堆 BroadcastXXXChange(xxx)。
這些 function 都會 呼嘯 fillInNotifierBundle( ),把 Bundle 放到 intent 的 extra,然後再 broadcast 。

以 ServiceStateChanged( ) 來看。
notifyServiceState broadcastServiceStateChanged

Modem AT Command : COPS -- 與 operator 相關

AT+COPS 這個 command 跟 operator 相關。
可以用來:
  1. 顯示目前註冊的operator
  2. 選擇 operator 的方法:自動,手動
  3. 列出所有搜尋到的 operator
例如: at+cops=? +COPS: (2,"Chunghwa Telecom","Chunghwa","46692",2), (1,"Chunghwa Telecom","Chunghwa","46692",0), (3,"VIBO","VIBO","46689",2), (3,"Far EasTone","FET","46601",0), (3,"TW Mobile","TWM","46697",0), (3,"TW Mobile","TWM","46697",2), (3,"Far EasTone","FET","46601",2), ,(0,1,2,3,4),(0,1,2) -- 實際上是連在一起,為好看,我加上分行。

每個 ( ) 代表一個 operator, 各攔的意思是:
( state, operator name - long, operator name -short, operator id, rate )
  1. state : operator 的狀態。
    0 : unknown,
    1 : 可用
    2 : 目前註冊的 operator
    3 : 禁止使用
  2. operator name , long, short, id : 分別是 operator 的三種表示法
  3. rate : 網路型態:
    0 : GSM/GPRS
    2: WCDMA

2012年1月5日 星期四

3gdongle on linux & android, some notes

中華電信的某種 帳戶 服務 ,在 android 上有點奇怪。

APN 只能使用 "internet" 的 simcard。

一旦設定使用 "emome" 這個 apn name,data channel 無法連上 (這是當然的),
但是把 apn 改回 internet,也是一樣無法連上,
重開機也一樣。

結果是用 3g dongle,接上 linux,手動撥接..
第一次:撥接 OK,但是ppp 連線,取得 dns 位址時,一直得到 fake 的 10.11.12.13 和 14,
pppd keep retry,還是一樣。
... 猜 android 手機大概是維持在這個狀態。

之後m,再差拔一次 3g dongle,
再 撥接一次才OK。

之後,放在 android 手機上也 OK 了。


  1. 手機是 nexus S
  2. 在改apn name 為 emome ,無法連線,之後有作一次 "恢復 default setting" 的 apn setting
  3. 還有作過 "搜尋可用網路",也無效

2012年1月3日 星期二

android code trace : rild

mainLoop(){ for(;;){ open /dev/ttyXXX at_open( ); // 設定好 at command 的 read back thread. RIL_requestTimedCallback(initializeCallback, NULL, &TIMEVAL_DELAYINIT); // delay 一段時間, call initializeCallback waitForClose(); // 會停在這,一直到 device 被關掉,發出 signal } } 這個 mainLoop( ) 就是 rild 的主體。

initializeCallback() 負責送出 modem 的初始化 at command (有一堆)。

所以 at_open( ) 會先執行,然後才是 modem initialize commands。

at_open 實際呼叫時: at_open(fd,onUnsolicited)

這裡的 onUnsolicited 是 function : 負責處理 還沒送出 initialize command 前, modem 自己送回來得 command。
-- 所以一定是 unsolicited



Service 的 socket interface 部份。

在RIL_register( ) 開始。
這是在 mainLoop() 前就執行的。



ril 好像有兩種啟動方法:
  1. 直接由 reference-ril 的 main 啟動
  2. 由 rild 呼叫 RIL_Init( ) 啟動
在 init.rc 中好像是用 rild 呼叫 RIL_Init 。

這樣的話..
RIL_Init ( ) 只做:
  1. start uevent monitor -- probe usb device..
  2. 取得 device, data port,開啟 mainLoop( ) thread.
  3. 執行 RIL_register

2012年1月2日 星期一

rild AT_DUMP 的陷阱

android 的 ril。
AT_DUMP( ) 原先應該是要 dump 到 file (ref comment)。
但是好像是沒有implement,所以用 LOGD,但是又不一樣。所以把 AT_DEBUG set 1,不會動作。

不能用 LOGD("%s",buff) 直接輸出的原因是 buff 有可能是部份的 AT string,還沒到 ending,所以沒有 ending null。

所以 AT_DUMP( )的 argument 有 len。

但是要注意,如果想改用 memcpy( ) copy 到 tmp 後加上 ending null 再印出去,run 起來會 exception。
因為在reference-ril.c 有這樣呼叫的: static void * mainLoop(void *param) { .... AT_DUMP("== ", "entering mainLoop()", -1 ); .... .. len 是 -1.

所以真的要改 AT_DUMP( ) 的話,要針對 len -1 作處理。
signal() 會直接送出 signal。
alarm(n) 就是 delay n sec 後送出 alarm signal。

兩個 function 都是 none-block (呼叫後會繼續執行)。

因為都是 signal,所以使用上要設定 signal handler,當signal 發生後 (馬上或是 n 秒後)。
signal handler 會被呼叫。x

標籤

網誌存檔