Andriod Phone模組相關

來源:互聯網
上載者:User

原文地址::http://lisaguo.iteye.com/blog/920065

 

 

Andriod Phone模組相關(總覽)
2010-01-30 13:50
1、從java端發送at命令的處理流程。
2、unsolicited 訊息從modem上報到java的流程。
3、貓相關的各種狀態的監聽和通知機制。
4、通話相關的表徵圖變換的工作原理。
5、gprs撥接的通路原理。
6、通話相關的語音通路切換原理、震動介面。
7、通話相關的notification服務。
8、通話相關的各種server。

Andriod Phone模組相關(一)
2010-01-30 14:52
第一部分:從java端發送at命令的處理流程。
已撥電話流程:
1、Contacts的AndroidManifest.xml 中android:process="android.process.acore"說明此應用程式運行在acore進程中。
DialtactsActivity 的intent-filter的action屬性設定為main,catelog屬性設定為launcher,所以此activity能出現在主菜單中,並且是點擊此應用程式的第一個介面。dialtactsactivity包含四個tab,分別由TwelveKeyDialer、 RecentCallsListActivity,兩個activity-alias DialtactsContactsEntryActivity和DialtactsFavoritesEntryActivity分別表示連絡人和收藏
tab,但是正真的連絡人清單和收藏是由ContactsListActivity負責。
2、進入TwelveKeyDialer 中OnClick方法,按住的按鈕id為:R.id.dialButton,執行placecall()方法:
Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,Uri.fromParts("tel", number, null));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
3、 intert.ACTION_CALL_PRIVILEGED實際字串為 android.intent.action.CALL_PRIVILEGED,通過尋找知道了packegs/phone下面的 AndroidManifest.xml中PrivilegedOutgoingCallBroadcaster activity-alias設定了intent-filter,所以需要找到其targetactivity為 OutgoingCallBroadcaster。所以進入OutgoingCallBroadcaster的onCreate()中:
String action = intent.getAction();
String number = PhoneNumberUtils.getNumberFromIntent(intent, this);
if (number != null) {
number = PhoneNumberUtils.convertKeypadLettersToDigits(number);
number = PhoneNumberUtils.stripSeparators(number);
}
final boolean emergencyNumber =
(number != null) && PhoneNumberUtils.isEmergencyNumber(number);
擷取過來的Action以及Number,並對Action以及Number類型進行判斷。
//如果為callNow = true;則啟動InCall介面:
intent.setClass(this, InCallScreen.class);
startActivity(intent);
並發送廣播給OutgoingCallReceiver:
Intent broadcastIntent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL);
if (number != null) broadcastIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, number);
broadcastIntent.putExtra(EXTRA_ALREADY_CALLED, callNow);
broadcastIntent.putExtra(EXTRA_ORIGINAL_URI, intent.getData().toString());
sendOrderedBroadcast(broadcastIntent, PERMISSION,
new OutgoingCallReceiver(), null, Activity.RESULT_OK, number, null);
4、 Intent.ACTION_NEW_OUTGOING_CALL實際字串 android.intent.action.NEW_OUTGOING_CALL,通過尋找知道了packegs/phone下面的 androidmanifest.xml中OutgoingCallReceiver Receiver接收此intent訊息。找到OutgoingCallBroadcaster類中的內部類OutgoingCallReceiver,執行onReceive()函數:
執行doReceive(context, intent);方法:
擷取傳給來的號碼,根據PhoneApp的執行個體擷取PhoneType等。最後啟動InCall介面:
Intent newIntent = new Intent(Intent.ACTION_CALL, uri);
newIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, number);
newIntent.setClass(context, InCallScreen.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
5、請求撥號的java部分流程

6、請求撥號的c/c++部分流程
6.1、初始化事件迴圈,啟動串口監聽,註冊socket監聽。
rild.c->main()
(1)、RIL_startEventLoop
//建立事件迴圈線程
ret = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
//註冊進程喚醒事件回調
ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,
processWakeupCallback, NULL);
rilEventAddWakeup (&s_wakeupfd_event);
//建立事件迴圈
ril_event_loop
for (;;) {
...
n = select(nfds, &rfds, NULL, NULL, ptv);
// Check for timeouts
processTimeouts();
// Check for read-ready
processReadReadies(&rfds, n);
// Fire away
firePending();
}
(2)、funcs = rilInit(&s_rilEnv, argc, rilArgv);//實際是通過動態載入動態庫的方式執行reference-ril.c中的RIL_Init
//單獨啟動一個線程讀取串口資料
ret = pthread_create(&s_tid_mainloop, &attr, mainLoop, NULL);
fd = open (s_device_path, O_RDWR);
ret = at_open(fd, onUnsolicited);
ret = pthread_create(&s_tid_reader, &attr, readerLoop, &attr);
RIL_requestTimedCallback(initializeCallback, NULL, &TIMEVAL_0);

在initializeCallback中執行的程式:
setRadioState (RADIO_STATE_OFF);
at_handshake();
/* note: we don't check errors here. Everything important will
be handled in onATTimeout and onATReaderClosed */
/* atchannel is tolerant of echo but it must */
/* have verbose result codes */
at_send_command("ATE0Q0V1", NULL);
/* No auto-answer */
at_send_command("ATS0=0", NULL);
...
//註冊rild socket連接埠事件監聽到事件迴圈中
(3)、RIL_register(funcs);
s_fdListen = android_get_control_socket(SOCKET_NAME_RIL);
ret = listen(s_fdListen, 4);
ril_event_set (&s_listen_event, s_fdListen, false,
listenCallback, NULL);//將此連接埠加入事件select隊列
rilEventAddWakeup (&s_listen_event);

如果rild socket連接埠有資料來了將執行listencallback函數
listencallback
//為此用戶端串連建立新的監聽控制代碼,s_fdListen繼續監聽其他用戶端的串連。
s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen);
ril_event_set (&s_commands_event, s_fdCommand, 1,
processCommandsCallback, p_rs);//將此連接埠加入事件select隊列
rilEventAddWakeup (&s_commands_event);
6.2、socket監聽,收到dial的socket請求
processCommandsCallback
//讀資料到p_record中
ret = record_stream_get_next(p_rs, &p_record, &recordlen);
processCommandBuffer(p_record, recordlen);
p.setData((uint8_t *) buffer, buflen);
// status checked at end
status = p.readInt32(&request);
status = p.readInt32 (&token);//請求隊列中的序號
pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
pRI->token = token;

/*
包含#include "ril_commands.h"語句,結構體如下:
typedef struct {
int requestNumber;
void (*dispatchFunction) (Parcel &p, struct RequestInfo *pRI);
int(*responseFunction) (Parcel &p, void *response, size_t responselen);
} CommandInfo;
*/
pRI->pCI = &(s_commands[request]);
pRI->p_next = s_pendingRequests;
s_pendingRequests = pRI;
pRI->pCI->dispatchFunction(p, pRI);

//假設是接收了dial指令,pRI->PCI->dispatchFunction(p,pRI),調用dispatchDial (p,pRI)
dispatchDial (p,pRI)
s_callbacks.onRequest(pRI->pCI->requestNumber, &dial, sizeof(dial), pRI);
in reference-ril.c onRequest()
...
switch (request) {
case RIL_REQUEST_DIAL:
requestDial(data, datalen, t);
asprintf(&cmd, "ATD%s%s;", p_dial->address, clir);
ret = at_send_command(cmd, NULL);
err = at_send_command_full (command, NO_RESULT, NULL, NULL, 0, pp_outResponse);
err = at_send_command_full_nolock(command, type, responsePrefix, smspdu,timeoutMsec, sponse);
err = writeline (command);
//此處等待,直到收到成功應答或失敗的應答,如:ok,connect,error cme等
err = pthread_cond_wait(&s_commandcond, &s_commandmutex);
waiting....
waiting....

/* success or failure is ignored by the upper layer here.
it will call GET_CURRENT_CALLS and determine success that way */
RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
p.writeInt32 (RESPONSE_SOLICITED);
p.writeInt32 (pRI->token);
errorOffset = p.dataPosition();
p.writeInt32 (e);
if (e == RIL_E_SUCCESS) {
/* process response on success */
ret = pRI->pCI->responseFunction(p, response, responselen);
if (ret != 0) {
p.setDataPosition(errorOffset);
p.writeInt32 (ret);
}
}
sendResponse(p);
sendResponseRaw(p.data(), p.dataSize());
blockingWrite(fd, (void *)&header, sizeof(header));
blockingWrite(fd, data, dataSize);
6.4、串口監聽收到atd命令的應答"OK"或"no carrier"等
readerLoop()
line = readline();
processLine(line);
handleFinalResponse(line);
pthread_cond_signal(&s_commandcond);//至此,前面的等待結束,接著執行RIL_onRequestComplete函數
6.5、java層收到應答後的處理,以dial為例子.
ril.java->RILReceiver.run()
for(;;)
{
...
length = readRilMessage(is, buffer);
p = Parcel.obtain();
p.unmarshall(buffer, 0, length);
p.setDataPosition(0);
processResponse(p);
type = p.readInt();
if (type == RESPONSE_SOLICITED) {
processSolicited (p);
serial = p.readInt();
rr = findAndRemoveRequestFromList(serial);
rr.mResult.sendToTarget();
......
}
CallTracker.java->handleMessage (Message msg)
switch (msg.what) {
case EVENT_OPERATION_COMPLETE:
ar = (AsyncResult)msg.obj;
operationComplete();
cm.getCurrentCalls(lastRelevantPoll);

Andriod Phone模組相關(二)
2010-01-30 15:09
第二部分:unsolicited 訊息從modem上報到java的流程。
C++部分:
readerLoop()
line = readline();
processLine(line);
handleUnsolicited(line);
if (s_unsolHandler != NULL) {
s_unsolHandler (line1, line2);//實際執行的是void onUnsolicited (const char *s, const char *sms_pdu)
if (strStartsWith(s,"+CRING:")|| strStartsWith(s,"RING")
|| strStartsWith(s,"NO CARRIER") || strStartsWith(s,"+CCWA") )
RIL_onUnsolicitedResponse (RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0);
p.writeInt32 (RESPONSE_UNSOLICITED);
p.writeInt32 (unsolResponse);
ret = s_unsolResponses[unsolResponseIndex].responseFunction(p, data, datalen);
ret = sendResponse(p);
sendResponseRaw(p.data(), p.dataSize());
ret = blockingWrite(fd, (void *)&header, sizeof(header));
blockingWrite(fd, data, dataSize);
Java部分:
ril.java->RILReceiver.run()
for(;;)
{
...
length = readRilMessage(is, buffer);
p = Parcel.obtain();
p.unmarshall(buffer, 0, length);
p.setDataPosition(0);
processResponse(p);
processUnsolicited (p);
response = p.readInt();
switch(response) {
...
case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: ret = responseVoid(p); break;
...
}
switch(response) {
case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
if (RILJ_LOGD) unsljLog(response);
mCallStateRegistrants
.notifyRegistrants(new AsyncResult(null, null, null));
...
}

 

Andriod Phone模組相關(三、四)
2010-02-01 10:51
第三部分:貓相關的各種狀態的監聽和通知機制
第四部分:通話相關的表徵圖變換的工作原理。
A. 註冊監聽部分

B.事件通知部分

註:所有的狀態改變通知都在TelephonyRegistry中處理,詳見該類源碼。

手機SIM卡功能解析
2010-02-01 17:25
SIM卡是GSM手機特有的使用者身份的象徵。
那麼,SIM卡到底具有哪些功能,其原理如何呢?下面作一簡要描述。
SIM卡作為使用者身份的象徵,主要含有以下兩種資訊:IMSI號和鑒權、密碼編譯演算法。

IMSI號全稱為國際移動台使用者識別號,與IMEI國際行動裝置識別號是完全不同的兩個概念。IMSI號是固化在SIM卡內部儲存晶片上的號碼。當客戶申請入網時,電信營業人員隨意拿來一張嶄新的SIM卡,將卡上標註的15位IMSI號,對應記錄在使用者挑選的號碼資料中,輸入電腦建立檔案。這就是 GSM系統方便快捷的入網方式。
IMEI號則是一部手機機身內部固有的一個號碼,反應這部手機的出廠地、所屬廠商等一系列資訊。
這兩個號碼的不同體現了GSM系統機、號分開的原則。
GSM系統具有良好的保密性還體現在SIM卡上。在使用者上網通話時,需要在空中傳送IMSI號碼以便鑒權。IMSI號碼在空中傳送是經過SIM卡中的鑒權、加密運算後發送的。經過這些複雜的運算,破譯基本上是不可能的。這也是GSM系統優於ETACS系統的一大體現。
從外觀上看,SIM卡有大、小卡之分,這是為滿足不同手機的不同尺寸需求而設計的。但隨著手機市場日益小巧、輕便的發展趨勢,越來越多的廠商淘汰了大卡機型,小卡越來越受到青睞。
觀察SIM卡可以看到每張卡上,都有8個金屬觸腳,它們分別有如下功能,見圖1。

圖1 SIM卡引腳
SIM卡的供電有兩種:5V和3V。早期的SIM卡一般是5V供電。隨著人們對電池使用時間的要求日趨加長,廠家採取了各種手法來降低手機的用電量,包括將CPU由原來的5V左右供電降至3V左右,隨之手機整體機身的供電也基本上降到3V左右,這樣SIM卡供電電壓的下降也就勢在必行了。目前,許多SIM卡可以相容兩種電壓供電,這是為了適應過渡時期的需要。
另外,SIM卡的容量也不相同,這取決於SIM卡內部儲存晶片的記憶體容量大小。卡的容量體現在使用者使用電話簿功能時能往SIM卡上存多少條記錄。
在日常使用時,有時會出現"SIM卡不被接受"、"請插入SIM卡"等不正常的現象。這時,我們可以將SIM卡從機內取出,用橡皮輕輕地擦卡面。切不可用尖銳的東西刮卡面,以免造成卡觸腳不平而接觸不良,甚至徹底損壞SIM卡。如果擦拭後仍無法正常使用,則應將手機連卡送到專業維修點,讓維修人員檢查。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.