ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上

2012年1月30日 星期一

*** Forcing "make installclean"... *** rm -rf out/target/product/CV/data/* out/target/product/CVdata-qemu/* out/target/product/CV/userdata-qemu.img out/host/linux-x86/obj/NOTICE_FILES out/host/linux-x86/sdk out/target/product/CV/*.img out/target/product/CV/*.txt out/target/product/CV/*.xlb out/target/product/CV/*.zip out/target/product/CV/data out/target/product/CV/obj/APPS out/target/product/CV/obj/NOTICE_FILES out/target/product/CV/obj/PACKAGING out/target/product/CV/recovery out/target/product/CV/root out/target/product/CV/system out/target/product/CV/dex_bootjars out/target/product/CV/obj/JAVA_LIBRARIES *** Done with the cleaning, now starting the real build.

root fs copy-to, file attribute

要在 root fs 中加東西,結果 copy 過去後,file attr 變了。
這部份有點糟。
除了要把 file 寫在 /system/core/rootfs/Android.mk 裡,
還要修改 /system/core/include/private/android_filesystem_config.h
像: static struct fs_path_config android_files[] = { { 00440, AID_ROOT, AID_SHELL, "system/etc/init.goldfish.rc" }, { 00550, AID_ROOT, AID_SHELL, "system/etc/init.goldfish.sh" }, ..

INSTALL_FAILED_SHARED_USER_INCOMPATIBLE

使用 vendor 的 apk, install 後,無法再 uninstall,在系統中也找不到 apk,所以無法刪除。
install 會出現: INSTALL_FAILED_SHARED_USER_INCOMPATIBLE 後來在 logcat 中找到 unpack native ... 的 message,原來apk 解開後,安裝到 /data/app 下,並且是以 package name 而不是 filename存在。
rm 後 install 還是 fail,但是這次error是 Attempt to re-install xxx.xxx.xxx without first uninstalling. 所以 uninstall xxx.xxx.xxx 後,再 install 一次就 OK 了。

dell N4010 : enable bluetooth

Dell N4010 的 bluetooth 是 Bus 001 Device 008: ID 413c:8160 Dell Computer Corp. Wireless 365 Bluetooth 但是不知道為什麼,在 ubuntu 下 lsusb 沒有出現,只有出現 他的 usb hub : Bus 001 Device 003: ID 0a5c:4500 Broadcom Corp. BCM2046B1 USB 2.0 Hub (part of BCM2046 Bluetooth) 猜是沒有 enable,但是 bluetooth enable 。
而且 debian 的 dell hotkey 沒有 support wireless (wifi, bt) 的 switch。

所以,只好..

開到 windows 7 下, enable bluetooth,重新開到 debian ...

bluetooth 出現了...

2012年1月13日 星期五

diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java index f0f2ecb..940bd24 100755 --- a/core/java/android/provider/Telephony.java +++ b/core/java/android/provider/Telephony.java @@ -1712,21 +1712,6 @@ public final class Telephony { public static final String TYPE = "type"; - /** - * The protocol to be used to connect to this APN. - * - * One of the PDP_type values in TS 27.007 section 10.1.1. - * For example, "IP", "IPV6", "IPV4V6", or "PPP". - */ - public static final String PROTOCOL = "protocol"; - - /** - * The protocol to be used to connect to this APN when roaming. - * - * The syntax is the same as protocol. - */ - public static final String ROAMING_PROTOCOL = "roaming_protocol"; - public static final String CURRENT = "current"; }

2012年1月11日 星期三

android code trace : at command engine

response 都是 char *
有可能是很多個 reponse ,所以用一個 ATLine 來包裝,
ATLine 是一個 char * 的 linking list: typedef struct ATLine { struct ATLine *p_next; char *line; } ATLine; reponse 是用addIntermediate(const char *line) 來填入資料: ATLine *p_new; p_new = (ATLine *) malloc(sizeof(ATLine)); p_new->line = strdup(line); /* note: this adds to the head of the list, so the list will be in reverse order of lines received. the order is flipped again before passing on to the command issuer */ p_new->p_next = sp_response->p_intermediates; sp_response->p_intermediates = p_new; 對於 singleline response 的處理: case SINGLELINE: if (sp_response->p_intermediates == NULL && strStartsWith (line, s_responsePrefix) ) { addIntermediate(line); } else { /* we already have an intermediate response */ handleUnsolicited(line); } break; 所以拿到的 reponse,其中的 ATLine->line 才是 char* 的內容。



reference-ril/at_tok.c 是 response 的字串處理 function。

at_tok_start(char*) : 找到 ':' 後面的位置,通常是回應的內容的開始。

所以要處理 available network 的 ( ),要增加 function..

android code trace -- rild. reference-ril

從前一篇,可以知道,rild daemon ,處理 command 的部份是libril/ril.cpp 的 processCommandCallback
其中的 processCommandBuffer( )

Command 的內容格式 (protocol) 好像是 Parcel 這個 structure。
分為 request, token。
request 就是 command 的 id。

然後簡單由查表找出 request command id 對應的 function 是 ?
然後去執行他。

這個 table 就是 static CommandInfo s_commands[] = { #include "ril_commands.h" };

trace 一下,以 QUERY_AVAILABLE_NETWORKS.

在 ril_commands.h 裡,有 {RIL_REQUEST_QUERY_AVAILABLE_NETWORKS , dispatchVoid, responseStrings},T 所以,是 call dispatchVoid(),然後 response 送到 reponseStrings( )。

dispatchVoid( ) 實際 call s_callbacks.onRequest( )。
s_callbacks 是: static const RIL_RadioFunctions s_callbacks = { RIL_VERSION, onRequest, currentState, onSupports, onCancel, getVersion }; 所以 call 的是 onRequest (reference-ril.c)

rild support 的 command 就寫在 onRequest。
.. 裡面沒有 implement AVAILABLE_NETWORK..

... 難怪每一家 modem vendor 都不願意給 source,都給so.

AVAILABLE_NETWORK 的 AT COMMAND 是 at+cops=? response 是 一行:
ref: http://r40eubuntu.blogspot.com/2012/01/modem-at-command-cops-operator.html

所以送的 at_command 應該用 SINGLELINE。 at_send_command_singleline reponse 也是以 COPS: 開始,所以送command 應該是: err = at_send_command_singleline("AT+COPS=?","+COPS:",&p_response);
response 的部份可以參考 CM 的 android_hardware_ril 為了 htc 的 reference-ril.so 的修改: https://github.com/CyanogenMod/android_hardware_ril/commit/90102813ee766b658c9d11f47bfffa785a98b6cd

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

標籤

網誌存檔