首页 Android_Telephony_Architecture

Android_Telephony_Architecture

举报
开通vip

Android_Telephony_ArchitecturenullnullAndroid Telephony ArchitectureJun_YangMar 23 2012nullAgenda 1. Structure 2. Telephony Framework 3. Setup Data Connection 4. Net Status Notification 5. Q&A nullStructure Phone.apk, Mms, Settings...android.telephony.*com.android.internal.telephony.*RI...

Android_Telephony_Architecture
nullnullAndroid Telephony ArchitectureJun_YangMar 23 2012nullAgenda 1. Structure 2. Telephony Framework 3. Setup Data Connection 4. Net Status Notification 5. Q&A nullStructure Phone.apk, Mms, Settings...android.telephony.*com.android.internal.telephony.*RIL.javasocket “rild”Java ApplicationJava Frameworkrild daemonlibhuawei-ril.solibril.soModem driverRILdlopen RIL_initRIL_startEventLoop() RIL_register() RIL_onRequestComplete() ...KernelAT commandsnullTelephony framework contains a set of telephony API for applications. There are two categaries of JAVA pacakges in telephony framework: 1.The internal telephony packages - com.android.internal.telephony.*, source code: frameworks/base/telephony/java/com/android/internal/telephony 2.The open telephony packages - android.telephony.*. source code: frameworks/base/telephony/java/android/telephony The internal packages are used for Android default telephony application - Phone.apk, and the open packages are for any 3rd party telephony applications.Telephony FrameworknullThis figure show the relationship of these Classes Telephony FrameworkPhoneBase (abstract class)GSMPhoneCDMAPhonePhoneProxyPhone (interface)extendsimplementscallCommandsInterface (interface)RILJBaseCommands (abstarct class)PhoneFactorynullInternal Telephony Packages: frameworks/base/telephony/java/com/android/internal/telephony The public interface Phone is used to control the phone. The abstract class PhoneBase implements this interface. And the class GSMPhone extends this abstract class. Phone.java Telephony Framework 44 public interface Phone { 326 String getPhoneName(); 332 int getPhoneType(); void setPreferredNetworkType(int networkType, Message response); void getPreferredNetworkType(Message response); ... nullThe default telephony application could use makeDefaultPhones() and getDefaultPhone() in the class PhoneFactory to obtain the unique instance of Phone. The code below shows how this be done. packages/apps/Phone/src/com/android/phone/PhoneApp.java PhoneFactory.java Telephony Framework 410 public void onCreate() { ... 425 if (phone == null) { 426 // Initialize the telephony framework 427 PhoneFactory.makeDefaultPhones(this); 428 429 // Get the default phone 430 phone = PhoneFactory.getDefaultPhone(); 56 public static void makeDefaultPhone(Context context) { ... 130 sCommandsInterface = new RIL(context, networkMode, cdmaSubscription); 132 int phoneType = getPhoneType(networkMode); if (phoneType == Phone.PHONE_TYPE_GSM) { 135 sProxyPhone = new PhoneProxy(new GSMPhone(context, sCommandsInterface, sPhoneNotifier)); 137 } else if (phoneType == Phone.PHONE_TYPE_CDMA) {nullLet’s suppose the current network mode is in GSM/GPRS, so the default telephony application could obtain a PhoneProxy to a GSMPhone, and use its API to achieve telephony functionalities. ProxyPhone is also extended from Phone. It is used to abstract the specific instance of a specific network mode. PhoneProxy.java Telephony Framework 57 public PhoneProxy(Phone phone) { 58 mActivePhone = phone; ... 66 mCommandsInterface = ((PhoneBase)mActivePhone).mCM; 67 mCommandsInterface.registerForRadioTechnologyChanged( 68 this, EVENT_RADIO_TECHNOLOGY_CHANGED, null); 69 } ... 549 public void getPreferredNetworkType(Message response) { 550 mActivePhone.getPreferredNetworkType(response); 551 } nullThe class PhoneBase has a member mCM of the type CommandsInterface. And this is assigned in the constructor of GSMPhone. GSMPhone.java PhoneBase.java Telephony Framework114 public CommandsInterface mCM; ... 203 protected PhoneBase(PhoneNotifier notifier, Context context, CommandsInterface ci, 204 boolean unitTestMode) { 207 mLooper = Looper.myLooper(); mCM = ci; ... 757 public void getPreferredNetworkType(Message response) { 758 mCM.getPreferredNetworkType(response); 759 }130 GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier, boolean unitTestMode) { 131 super(notifier, context, ci, unitTestMode); ...nullAll the telephony functionalities which need sending AT command to RIL daemon should be achieved by the the interface CommandsInterface. And the class RIL implements this interface. Moreover, RIL also extends the abstract class BaseCommands to provide unsolicited result code to default telephony application. CommandsInterface.java BaseCommands.java RIL.java Telephony Framework27 public interface CommandsInterface { 1332 void getPreferredNetworkType(Message response);36 public abstract class BaseCommands implements CommandsInterface { 199 public final class RIL extends BaseCommands implements CommandsInterface { 1861 public void getPreferredNetworkType(Message response) { 1862 RILRequest rr = RILRequest.obtain( 1863 RILConstants.RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, response); 1867 send(rr); //call sender and send to targetnullThis figure show how RILJ communicates with RILC RIL_REQUEST_XXX and RIL_UNSOLE_XXX are defined the same in RILC and FrameworkTelephony FrameworkRILSenderRILReciverril-daemonModuleRIL_REQUEST_XXXAT_COMMAND_XXXRESPONSEUNSOLED RESPONSERIL_UNSOLE_XXXREQUEST_COMPLETEUnsolicited ResponseSolicited ResponsenullState Machine (frameworks/base/core/java/com/android/internal/util/StateMachine.java) 104 mP0 105 / \ 106 mP1 mS0 107 / \ 108 mS2 mS1 109 / \ \ 110 mS3 mS4 mS5 ---> initial state 111 * 112 * After starting mS5 the list of active states is mP0, mP1, mS1 and mS5. 113 * So the order of calling processMessage when a message is received is mS5, 114 * mS1, mP1, mP0 assuming each processMessage indicates it can't handle this 115 * message by returning false or NOT_HANDLED. 116 * 117 * Now assume mS5.processMessage receives a message it can handle, and during 118 * the handling determines the machine should change states. It could call 119 * transitionTo(mS4) and return true or HANDLED. Immediately after returning from 120 * processMessage the state machine runtime will find the common parent, 121 * which is mP1. It will then call mS5.exit, mS1.exit, mS2.enter and then 122 * mS4.enter. The new list of active states is mP0, mP1, mS2 and mS4. So 123 * when the next message is received mS4.processMessage will be invoked. Setup Data ConnectionMost used function: enter() – Called when enter this state exit() – Called when exit current state transitionTo() –Switch to other state deferMessage() –Push msg to the front of queue when transitioned to next state processMessage() –Like handleMessage()nullDcDefaultState (The parent state for all other states)DcDisconnectionError CreatingConnectionDcActivingStateDcActiveStateDcDisconnectingStateDcInactiveState (initial state)EVENT_CONNECT(EVENT_SETUP_DATA_CONNECTION_DONE &&(ERR_BadCommand||ERR_RilError)) || EVENT_GET_LAST_FAIL_DONEEVENT_DEACTIVATE_DONEEVENT_SETUP_DATA_CONNECTION_DONE && SetupResult ==SUCCESSEVENT_SETUP_DATA_CONNECTION_DONE && SetupResult == ERR_UnacceptableParameterEVENT_DEACTIVATE_DONEEVENT_DISCONNECTSetup Data ConnectionDataconnection.java maintained a dataconnection state machinenullGsmDataConnectionTrackerDataConnection/GsmDCRILJEVENT_CONNECTDcInactiveStateDISCONNECTDcActivingStateDcActiveStateOnDataSetupComplete-> NotifyDefaultData-> Phone.notifyDataConnection-> mNotifier.notifyDataConnection(this, reason);EVENT_SETUP_DATA_ CONNECTION_DONE(GsmDC)onConnect(cp) phone.mCM.setupDataCallSetup Data ConnectiontrySetupData->setupData dc.bringUp()RIL_REQUEST_SET UP_DATA_CALLnullSetup Data ConnectionRILJ RILSenderRILReceiverAT+CGDCONT=1,"IP",“3gnet“ AT+CGDATA="PPP",1 onRequest()onRequestComplete()Parcel p {user, apn ,password…} Modem RIL_REQUEST_SETUP_DATA_CALLrequest_setup_default_pdp_ppp setup_ppp_connection() at_send_command()Switch(request){ case AT < OK …pppd enable_ppp_interface (create two threads)start_ipcheck_threadstart_ppp_threadParcel p { ppp0, ip, dns…}RILDAT commandssocketCreate LCP IPCP protocol DNS saved in propertyHow to establish a connection in rilRIL_REQUEST_SETUP_DATA_CALLnullHow huawei lib-ril process RIL_REQUEST_SETUP_DATA_CALL: Vendor version: huawei ril 2.3 ril-ps.c 55 void hwril_request_ps (int request, void *data, size_t datalen, RIL_Token token) 56 { 57 switch (request) { 58 case RIL_REQUEST_SETUP_DATA_CALL: 59 { 60 #ifdef HUAWEI_RMNET 61 request_setup_default_pdp_rmnet( request, data, datalen,token); 62 #else 63 request_setup_default_pdp_ppp( request, data, datalen,token); ... //in function request_setup_default_pdp_ppp 204 apn = ((const char **)data)[2]; 205 user = ((const char **)data)[3]; ... 247 ret = setup_ppp_connection(t, pdp_apn, ppp_user, ppp_passwd); ... //in function setup_ppp_connection 363 /* Step1: Define the CID */ 366 asprintf(&cmd, "AT+CGDCONT=%s,\"IP\",\"%s\"", DEFAULT_CID, apn ); 367 err = at_send_command(cmd, &p_response); 378 /* Step2: Active the PDP Context */ 380 asprintf(&cmd, "AT+CGDATA=\"PPP\",%s", DEFAULT_CID); 389 /* Step3: Enable the network interface */ 394 int ret = enable_ppp_interface(token,cid, user, passwd);Setup Data ConnectionnullHow huawei lib-ril process RIL_REQUEST_SETUP_DATA_CALL: Vendor version: huawei ril 2.3 ril-ps-api.c //in function enable_ppp_interface, start two threads 611 sprintf(shell, "/system/bin/pppd %s 115200 mru 1280 nodetach debug dump defaultroute usepeerdns novj noauth novjccomp noipdefault ipcp-accept-local ipcp-accept-remote connect-delay 5000 ", ppp_device_path); 618 if((ret = start_ppp_pthread()) < 0) //call system(shell), and dns will saved in property “net.ppp0.dns1” 624 sleep(1); 625 if((ret = start_ip_check_pthread(token))<0) //in function start_ip_check_pthread 495 RIL_Data_Call_Response_v6 *response = (RIL_Data_Call_Response_v6 *)malloc(sizeof(RIL_Data_Call_Response_v6)); ... 509 ifc_get_info("ppp0", &myaddr, NULL, NULL); //get ip address 516 property_get("net.ppp0.dns1", dns, ""); //get dns ... 537 response->ifname = "ppp0"; 538 response->addresses = ipaddress; 539 540 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(RIL_Data_Call_Response_v6));Setup Data ConnectionnullTelephony framework needs to track the network return value and events happened in RIL daemon. At the same time, default telephony application should also be able to be notified by telephony framework. In the constructor of GSMPhone, a GsmServiceStateTracker would be created to track the network status. And in the contructor of GsmServiceStateTracker, it would register to RIL for network status message. gsm/GSMPhone.java gsm/GsmServiceStateTracker.java 101 GsmServiceStateTracker mSST; 130 public GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier, boolean unitTestMode) { ... 139 mSST = new GsmServiceStateTracker (this);186 public GsmServiceStateTracker(GSMPhone phone) { 189 this.phone = phone; 190 cm = phone.mCM; 204 cm.registerForVoiceNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null);Net Status NotificationnullIt registers into a registrant list of BaseCommands. BaseCommands.java When network state changes, the endless loop waiting for the message in telephony framework will be notified by RIL daemon. And the message is deliverred to registrant. RIL.java 58 protected RegistrantList mVoiceNetworkStateRegistrants = new RegistrantList(); ... 324 public void registerForVoiceNetworkStateChanged(Handler h, int what, Object obj) { 325 Registrant r = new Registrant (h, what, obj); 327 mVoiceNetworkStateRegistrants.add(r); 328 }2395 private void 2396 processUnsolicited (Parcel p) { ... 2467 case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: 2468 if (RILJ_LOGD) unsljLog(response); 2469 2470 mVoiceNetworkStateRegistrants 2471 .notifyRegistrants(new AsyncResult(null, null, null));Net Status NotificationnullGsmServiceStateTracker is a subclass of Handler. When RILJ call notifyRegistrants(), the registed handler obj will call sendMessage(msg), then handleMessage() will be call. gsm/GsmServiceStateTracker.java 260 public void handleMessage (Message msg) { 261 AsyncResult ar; 262 int[] ints; 263 String[] strings; 264 Message message; 265 266 switch (msg.what) { ... 304 case EVENT_NETWORK_STATE_CHANGED: 305 pollState(); 306 break;Net Status NotificationnullOpen telephony packages: frameworks/base/telephony/java/android/telephony TelephonyManager provides a way for 3rd application interacting with internal telephony packages. Class Overview (from android sdk document) Provides access to information about the telephony services on the device. Applications can use the methods in this class to determine telephony services and states, as well as to access some types of subscriber information. Applications can also register a listener to receive notification of telephony state changes. You do not instantiate this class directly; instead, you retrieve a reference to an instance through Context.getSystemService(Context.TELEPHONY_SERVICE). Note that access to some telephony information is permission-protected. Your application cannot access the protected information unless it has the appropriate permissions declared in its manifest file. Where permissions apply, they are noted in the the methods through which you access the protected information. Net Status NotificationnullThe figure show the relationship among Internal and Open telephony package and 3 applications. PhoneService (phone service) PhoneApp TelephonyManager3rd ApplicationTelephonyRegistryPhoneStateListenerBoardCastGSM/CDMAPhoneRILJPhoneProxyITelephonyITelephonyRegistryDefaultPhoneNotifierNet Status NotificationPhoneFactoryPhoneInterfaceManagermCMril-daemonsocketnullIf we want to track telephony state in 3rd application: We should retrive an instance of TelephonyManager and get Phone service. Implement a PhoneStateListener what you want to listen. You can also register a BroadCastReceiver to receive broadcast if you want. Don’t forget add permission in manifest file. Take Settings as example to show how to achieve these. packages/apps/Settings/src/com/android/settings/deviceinfo/ Status.java 111 private TelephonyManager mTelephonyManager; 169 private PhoneStateListener mPhoneStateListener = new PhoneStateListener() { 170 @Override 171 public void onDataConnectionStateChanged(int state) { UpdateDataState(); //you can override with your own code here 178 protected void onCreate(Bundle icicle) { 184 mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE); 268 protected void onResume() { 278 mTelephonyManager.listen(mPhoneStateListener, 279 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE); 337 private void updateDataState() { 338 int state = mTelephonyManager.getDataState(); 341 switch (state) {Net Status NotificationConstant value is “phone” nullframeworks/base/telephony/java/android/telephony/PhoneStateListener.java frameworks/base/services/java/com/android/server/TelephonyRegistry.java 228 public void onDataConnectionStateChanged(int state) { 229 // default implementation empty 230 } 282 IPhoneStateListener callback = new IPhoneStateListener.Stub() { 310 public void onDataConnectionStateChanged(int state, int networkType) { 311 Message.obtain(mHandler, LISTEN_DATA_CONNECTION_STATE, state, networkType). 312 sendToTarget(); 313 } 328 Handler mHandler = new Handler() { 329 public void handleMessage(Message msg) { 350 case LISTEN_DATA_CONNECTION_STATE: 351 PhoneStateListener.this.onDataConnectionStateChanged(msg.arg1, msg.arg2); 54 class TelephonyRegistry extends ITelephonyRegistry.Stub { 137 public void listen(String pkgForDebug, IPhoneStateListener callback, int events, 138 boolean notifyNow) { 159 r.callback = callback; //a IPhoneStateListener 432 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) { 433 try { 434 r.callback.onDataConnectionStateChanged(mDataConnectionState, 435 mDataConnectionNetworkType); Net Status Notificationnullframeworks/base/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java Net Status Notification33 public class DefaultPhoneNotifier implements PhoneNotifier { 37 private ITelephonyRegistry mRegistry; 40 DefaultPhoneNotifier() { 41 mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( 42 "telephony.registry")); 43 } 103 public void notifyDataConnection(Phone sender, String reason, String apnType, 126 mRegistry.notifyDataConnection( 127 convertDataState(state), ...33 public class DefaultPhoneNotifier implements PhoneNotifier { 37 private ITelephonyRegistry mRegistry; 40 DefaultPhoneNotifier() { 41 mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( 42 "telephony.registry")); 43 } 103 public void notifyDataConnection(Phone sender, String reason, String apnType, 126 mRegistry.notifyDataConnection( 127 convertDataState(state), ...33 public class DefaultPhoneNotifier implements PhoneNotifier { 37 private ITelephonyRegistry mRegistry; 40 DefaultPhoneNotifier() { 41 mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( 42 "telephony.registry")); 43 } 103 public void notifyDataConnection(Phone sender, String reason, String apnType, 126 mRegistry.notifyDataConnection( 127 convertDataState(state), ...OnDataSetupComplete-> NotifyDefaultData-> Phone.notifyDataConnection-> mNotifier.notifyDataConnection(this, reason); case ... … case EVENT_SETUP_DATA_CONNECTION_DONEGsmDataConnectionTrackernullQ & A Any questions?nullThanks!
本文档为【Android_Telephony_Architecture】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_226296
暂无简介~
格式:ppt
大小:857KB
软件:PowerPoint
页数:0
分类:互联网
上传时间:2013-03-17
浏览量:19