android通话流程浅析RIL层.doc_第1页
android通话流程浅析RIL层.doc_第2页
android通话流程浅析RIL层.doc_第3页
android通话流程浅析RIL层.doc_第4页
android通话流程浅析RIL层.doc_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

欢迎大家相互学习:电眼娃娃 QQ:760340539拨出电话流程:1 在系统源码这个路径下/packages/apps/Phone/src/com/android/phone/DialtactsActivity.javacontacts的androidmanifest.xml android:process=cess.acore说明此应用程序运行在acore进程中。DialtactsActivity的intent-filter的action属性设置为main,catelog属性设置为launcher,所以此activity能出现, 首先启动的就是这个activity在主菜单中,并且是点击此应用程序的第一个界面。dialtactsactivity包含四个tab,分别由TwelveKeyDialer、RecentCallsListActivity,两个activity-alias DialtactsContactsEntryActivity和DialtactsFavoritesEntryActivity分别表示联系人和收藏tab,但是正真的联系人列表和收藏是由ContactsListActivity负责。2 进入TwelveKeyDialer OnClick方法,按住的按钮id为: R.id.digits,执行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实际字符串为ent.action.CALL_PRIVILEGED,通过查找知道了packegs/phone下面的androidmanifest.xml中PrivilegedOutgoingCallBroadcaster activity-alias设置了intent-filter,所以需要找到其targetactivity为OutgoingCallBroadcaster。所以进入OutgoingCallBroadcaster的onCreate()/如果为紧急号码马上启动intent.setClass(this, InCallScreen.class); startActivity(intent); 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(); if (LOGV) Log.v(TAG, Broadcasting intent + broadcastIntent + .); sendOrderedBroadcast(broadcastIntent, PERMISSION, null, null, Activity.RESULT_OK, number, null);4、Intent.ACTION_NEW_OUTGOING_CALL实际字符串为ent.action.NEW_OUTGOING_CALL,通过查找知道了packegs/phone 下面的androidmanifest.xml中OutgoingCallReceiver Receiver接收此intent消息。找到OutgoingCallReceiver,执行 onReceive()函数 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部分流程 onCreate(第一次)/onNewIntent(非第一次) internalResolveIntent placeCall(intent); PhoneUtils.placeCall(mPhone, number, intent.getData(); phone.dial(number); mCT.dial(newDialString); dial(dialString, CommandsInterface.CLIR_DEFAULT); cm.dial(pendingMO.address, clirMode, obtainCompleteMessage();/obtainCompleteMessage(EVENT_OPERATION_COMPLETE); send(rr); msg = mSender.obtainMessage(EVENT_SEND, rr); acquireWakeLock(); msg.sendToTarget(); RILSender.handleMessage() case EVENT_SEND: . s.getOutputStream().write(dataLength); s.getOutputStream().write(data);/从这里流程跑到下面ril.cpp中监听部份 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 dont 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_commandsrequest); 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); 第二部分: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_unsolResponsesunsolResponseIndex.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); . 第三部分、第四部分:猫相关的各种状态的监听和通知机制通话相关的图标变换的工作原理。网络状态,edge,gprs图标的处理a、注册监听部分=SystemServer.java init2() Thread thr = new ServerThread(); thr.setName(android.server.ServerThread); thr.start(); ServerThread.run() com.android.server.status.StatusBarPolicy.installIcons(context, statusBar); sInstance = new StatusBarPolicy(context, service); / phone_signal mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); mPhoneData = IconData.makeIcon(phone_signal, null, ernal.R.drawable.stat_sys_signal_null, 0, 0); mPhoneIcon = service.addIcon(mPhoneData, null); / register for phone state notifications. (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE) .listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE | PhoneStateListener.LISTEN_SIGNAL_STRENGTH | PhoneStateListener.LISTEN_CALL_STATE | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE | PhoneStateListener.LISTEN_DATA_ACTIVITY); /实际是调用的是TelephonyRegistry.listen,此listen函数会将Iphonestatelistener添加到对应的的handler数组中,到时来了事件会轮询回调。 / data_connection mDataData = IconData.makeIcon(data_connection, null, ernal.R.drawable.stat_sys_data_connected_g, 0, 0); mDataIcon = service.addIcon(mDataData, null); service.setIconVisibility(mDataIcon, false);b、事件通知部分=PhoneFactory.javamakeDefaultPhones() sPhoneNotifier = new DefaultPhoneNotifier(); useNewRIL(context); phone = new GSMPhone(context, new RIL(context), sPhoneNotifier);for example=DataConnectionTracker.javanotifyDefaultData(String reason) phone.notifyDataConnection(reason); mNotifier.notifyDataConnection(this, reason); =DefaultPhoneNotifier.java mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( telephony.registry); mRegistry.notifyDataConnection(convertDataState(sender.getDataConnectionState(), sender.isDataConnectivityPossible(), reason, sender.getActiveApn(), sender.getInterfaceName(null); 第五部分:gprs拨号上网的通路原理。上层java程序调用gprs流程:=PhoneApp.java onCreate() PhoneFactory.makeDefaultPhones(this); phone = new GSMPhone(context, new SimulatedCommands(), sPhoneNotifier); mDataConnection = new DataConnectionTracker (this); createAllPdpList();/建立缺省pdpconnection pdp = new PdpConnection(phone); dataLink = new PppLink(phone.mDataConnection); dataLink.setOnLinkChange(this, EVENT_LINK_STATE_CHANGED, null); /某个条件触发执行 trySetupData(String reason) setupData(reason); pdp = findFreePdp(); Message msg = obtainMessage(); msg.what = EVENT_DATA_SETUP_COMPLETE; msg.obj = reason; pdp.connect(apn, msg); phone.mCM.setupDefaultPDP(apn.apn, apn.user, apn.password, obtainMessage(EVENT_SETUP_PDP_DONE); /收到EVENT_SETUP_PDP_DONE消息 =pdpconnection.java handleMessage() case EVENT_SETUP_PDP_DONE: dataLink.connect();/dataLink是pppLink.java SystemService.start(SERVICE_PPPD_GPRS);/启动pppd_grps服务 poll.what = EVENT_POLL_DATA_CONNECTION; sendMessageDelayed(poll, POLL_SYSFS_MILLIS);/启动轮询,看是否成功连接gprs checkPPP()/每隔5秒轮询,看是否连接成功,或断开 /如果已经连接 mLinkChangeRegistrant.notifyResult(LinkState.LINK_UP); /执行到pdpconnection.handleMessage() case EVENT_LINK_STATE_CHANGED onLinkStateChanged(ls); case LINK_UP: notifySuccess(onConnectCompleted); onCompleted.sendToTarget(); /执行dataConnectionTracker.java的handleMessage() case EVENT_DATA_SETUP_COMPLETE notifyDefaultData(reason); setupDnsProperties(); setState(State.CONNECTED); phone.notifyDataConnection(reason); startNetStatPoll(); resetPollStats(); 1、读取发送出去的包数和接受到的包数 2、如果发送的数据包且没有收到应答包数n大于等于看门狗追踪的限定包数。 2.1、开始轮询pdp context list,尝试恢复网络连接 2.2、如果轮询24次后还没有联通网络则停止网络状态轮询,进行一次ping实验。 2.2.1、如果ping成功则,重新进行网络状态轮询,否则发送EVENT_START_RECOVERY事件。 / reset reconnect timer nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;着重c+部分代码的角度分析DataConnectionTracker.javatrySetupData(String reason) setupData(reason); PdpConnection.java pdp.connect(apn, msg); =RIL.JAVA phone.mCM.setupDefaultPDP(apn.apn, apn.user, apn.password, obtainMessage(EVENT_SETUP_PDP_DONE); send(rr); /send socket to RIL /enter c+ layer =ril.cpp processCommandsCallback (int fd, short flags, void *param) processCommandBuffer(p_record, recordlen); status = p.readInt32(&request); pRI-pCI = &(s_commandsrequest); pRI-pCI-dispatchFunction(p, pRI); dispatchStrings(); s_callbacks.onRequest(pRI-pCI-requestNumber, pStrings, datalen, pRI); =reference-ril.c onRequest(); requestSetupDefaultPDP(data, datalen, t); err = write_at_to_data_channel(ATD*99*1#,1); /after a while.get connect fr

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论