分享
分销 收藏 举报 申诉 / 25
播放页_导航下方通栏广告

类型Android-APN开发流程分析.doc

  • 上传人:仙人****88
  • 文档编号:11877033
  • 上传时间:2025-08-18
  • 格式:DOC
  • 页数:25
  • 大小:155.50KB
  • 下载积分:10 金币
  • 播放页_非在线预览资源立即下载上方广告
    配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    Android APN 开发 流程 分析
    资源描述:
    Android APN开发流程分析 2 Data Connect流程分析 Android的数据连接是基于PPP方式的,主要步骤为:首先通过AT命令激活PDP连接,然后利用pppd通过数据端口完成拨号连接; 数据连接的核心控制类是DataConnectionTracker,存在于GSMPhone里,数据连接不需要用户的干预,在APN设置好之后,在适当的情况下就会自动激活,激活的入口点是:DataConnectionTracker.trySetupData→setupData→ PdpConnection.connetc→CommandsInterface.setupDefaultPDP,通过PdpConnection访问GSMPhone中的RIL层的setupDefaultPDP实现,setupDefaultPDP的结果由EVENT_SETUP_PDP_DONE返回,如果成功,则开始调用pppd完成实际连接,这是通过DataLink.connect实现的; DataLink只是抽象基类,此处它的实现类是PppLink,实现DataLinkInterface接口,所以DataLink.connect实际上调用PppLink.connect,它通过SystemService.start(SERVICE_PPPD_GPRS)开始pppd服务,并通过checkPPP函数访问Linux的sys文件系统来查询pppd的连接状态,如果成功,便可以将LINKUP的消息通知出去以完成连接流程。 2 Data Connect流程分析 Android的数据连接是基于PPP方式的,主要步骤为:首先通过AT命令激活PDP连接,然后利用pppd通过数据端口完成拨号连接; 数据连接的核心控制类是DataConnectionTracker,存在于GSMPhone里,数据连接不需要用户的干预,在APN设置好之后,在适当的情况下就会自动激活,激活的入口点是:DataConnectionTracker.trySetupData→setupData→ PdpConnection.connetc→CommandsInterface.setupDefaultPDP,通过PdpConnection访问GSMPhone中的RIL层的setupDefaultPDP实现,setupDefaultPDP的结果由EVENT_SETUP_PDP_DONE返回,如果成功,则开始调用pppd完成实际连接,这是通过DataLink.connect实现的; DataLink只是抽象基类,此处它的实现类是PppLink,实现DataLinkInterface接口,所以DataLink.connect实际上调用PppLink.connect,它通过SystemService.start(SERVICE_PPPD_GPRS)开始pppd服务,并通过checkPPP函数访问Linux的sys文件系统来查询pppd的连接状态,如果成功,便可以将LINKUP的消息通知出去以完成连接流程。 3.3 RILD源码分析 RIL对对消息的处理是将消息通过LocalSocket发送到以rild为名称的有名端口。这个有名Socket的创建在ril.cpp代码中。s_fdListen = android_get_control_socket(SOCKET_NAME_RIL) RILD是守护进程,执行的过程为:获取参数→打开功能库→建立事件循环→执行RIL_Init→RIL_register;事件循环式核心,通过Select多路复用机制,读取来自上层的Socket接口的具体操作命令,同时一些命令Timeout唤醒机制,也通过Select实现; 1.   Request流程 命令下发流程:首先从JAVA层通过Socket将命令发送到RIL层的RILD守护进程,RILD中负责监听的ril_event_loop消息循环中的Select发现RILD Socket有了请求连接信号,建立一个record_stream,打通与上层的数据通道并开始接收请求数据,数据通道的回调函数processCommandsCallback()会保证收到一个完整的Request后,将其送达processCommandBuffer()函数; 解析过程:processCommandBuffer()从Socket中序列化的数据流里还原信息,将其组织到RequestInfo中;RequestInfo数据结构如下(存在于ril.cpp中): typedef struct RequestInfo { int32_t token; //this is not RIL_Token CommandInfo *pCI; struct RequestInfo *p_next; char cancelled; char local; // responses to local commands do not go back to command process } RequestInfo; RIL层以Request号为基础采用表驱动方式分发请求,CommandInfo结构表示命令的信息,关联了Request号和实际的请求函数,以及响应函数之间的关系; 分发流程:s_callback.onRequest()完成分发操作,s_callback获取自libreference-ril的RIL_RadioFunction结构指针,Request请求在这里转入底层的libreference-ril处理,handler是reference-ril.cpp中的Request。 onRequest根据Request号进行简单的switch分发,然后将命令和参数转换成对应的AT命令,由writeline()完成驱动层的发送,writeline通过驱动程序节点的文件描述符进行写操作实现控制。 2.   Response流程 Response有两类:unsolicited表示主动上报的消息,如来电,来短信等,而solicited是AT命令的响应,判断是否是solicited的依据有两点:一是当前用AT命令正在等待响应;二是读取的响应符合该AT命令的响应格式。 对于Response流程来讲,流程是从Modem设备发回响应数据开始的。 RIL通过readerLoop函数,利用readline逐行读取响应数据,随后通过processLine进行分析,主动上报的一般以+XXXX的形式出现,而AT命令的响应格式则有一行或多行之分,但最终一定以OK或者ERROR结尾,于是PrcessLine有以下几种情况: 1)、没有AT命令等待响应或不符合AT响应格式,一般是主动上报行,由handleUnsolicited处理,handleUnsolicited→onUnsolicetd→RIL_onUnsolicitedResponse; 2)、isFinalResponseSucess/isFinalResponseError是最终响应行,转到handleFinalResponse处理,handleFInalResponse会发送线程同步信号,激活等到的发送线程; 3)、符合当前AT命令响应格式的行,解析并获取数据,这是响应处理的中间过程,然后继续收到最终响应行,然后进入2)流程 最后的发送动作由sendResponse→sendResponseRaw→blockingWrite通过Socket回传给上层来完成,响应解析由上层完成。 Android MMS 源码流程(一) 2010-06-25 08:21 概述 MMS的收发操作借助于手机的短信机制,实际收发过程需要网络的APN支持,使用特定的APN接入点实现MMS数据的真实发送和接收; 源码流程 1) Telephpony.java getOrCreateThreadId()函数: 目录:\frameworks\base\core\java\android\provider\ 说明:这个函数根据接收者列表和未保存的消息返回一个线程ID,如果这个消息开始一个新的线程,那么函数分配一个线程ID,否则返回一个适当的已经存在的线程ID; 2) MmsMessageSender.java sendMessage()函数: 目录:\packages\apps\mms\src\com\android\mms\transaction\ 说明:对Mms进行封包 3) 再一次调用第一步函数 4) ConnectivityService.java startUsingNetworkFeature()函数: 目录:\framework\base\services\java\com\android\server\ 说明:该函数为实现Mms 网络连接的关键函数,下面我们详细分析: A、enforceChangePermission():判断调用的进程是否具有操作权限,如果不具有,抛出一个SecurityException异常,并强制准许权限 B、 ConnectivityManager.isNetworkTypeValid(networkType)来判断networkType是否合法,如果不合法返回一个APN_REQUEST_FAILED, 在这里用到了最重要的ConnectivityManager类: public class ConnectivityManager定义在\frameworks\base\core\java\android\net的ConnectivityManager.java里,其主要作用为: 1、监视网络连接,如WIFI、GPRS、UMTS等 2、当网路连接出现变化的时候,发送广播intents 3、当一个网络连接丢失之后,尝试连接另一个网络 4、为App提供粗粒度、细粒度的有效网络状态查询 C、 FeatureUser f = new FeatureUser(networkType, feature, binder); 新建一个FeatureUser类变量,该类实现:当调用进程died时发送一个Notice,这样就可以自我老化 D、int usedNetworkType = networkType; if(networkType == ConnectivityManager.TYPE_MOBILE) { if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) { usedNetworkType = ConnectivityManager.TYPE_MOBILE_MMS; } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) { usedNetworkType = ConnectivityManager.TYPE_MOBILE_SUPL; } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN)) { usedNetworkType = ConnectivityManager.TYPE_MOBILE_DUN; } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_HIPRI)) { usedNetworkType = ConnectivityManager.TYPE_MOBILE_HIPRI; } } 这段代码获取使用的网络类型; E、NetworkStateTracker network = mNetTrackers[usedNetworkType]; NetworkStateTracker类在NetworkStateTracker.java里:每个子类保持跟踪一个网络接口的连接状态,一个网络的状态信息由一个Tracker类保持,基类管理network-type-independent 网络状态 F、mFeatureUsers.add(f); 列表操作,将f添加到列表的end G、if (!mNetRequestersPids[usedNetworkType].contains(currentPid)) { // this gets used for per-pid dns when connected mNetRequestersPids[usedNetworkType].add(currentPid); } 判断网络操作需要的Pid是否包含当前Pid,如果不包含就添加进去 H、mHandler.sendMessageDelayed(mHandler.obtainMessage( NetworkStateTracker.EVENT_RESTORE_DEFAULT_NETWORK, f), getRestoreDefaultNetworkDelay()); 消息发送,问题:消息的Handle函数也在该文件本地,? I、 if ((ni.isConnectedOrConnecting() == true) && !network.isTeardownRequested()) { if (ni.isConnected() == true) { // add the pid-specific dns Log.d(TAG, "fanyl test ++++ before handleDnsConfigurationChange"); handleDnsConfigurationChange(); if (DBG) Log.d(TAG, "special network already active"); return Phone.APN_ALREADY_ACTIVE; } if (DBG) Log.d(TAG, "special network already connecting"); return Phone.APN_REQUEST_STARTED; } 这里判断网络是正在连接还是已经连接完成,如果是已经连接完成,就去设置Dns,并返回already状态 J、network.reconnect() 如果网络不是已经连接完成的状态的话,这里触发一个重新连接,直到网络状态变成isConnected; Android MMS 源码流程(二) 2010-06-25 08:21 5) 接下来的操作存在于DataConnectionTracker.java里: public synchronized int enableApnType(String type): 该函数确保用指定的类型连接APN,成功返回APN_ALREADY_ACTIVE或者APN_REQUEST_STARTED private void setEnabled(int id, boolean enable): 发送EVENT_ENABLE_NEW_APN事件 protected synchronized void onEnableApn(int apnId, int enabled) 该实例主要功能是判断目前是enable还是disable APN,如果是enable的话,调用onEnableNewApn();实现enable APN,如果是disable的话,根据enabledCount,onCleanUpConnection关闭APN或者改为默认连接 6) public void handleMessage(Message msg),ConnectivityService.java里 进入到对事件EVENT_STATE_CHANGED的处理,state= CONNECTED, old= CONNECTING, reason= apnChanged, apnTypeList= mms,应该是最后调用了handleConnect(info);发送一个广播事件 7) MobileDataStateTracker.java:MobileDataStateReceiver类的public void onReceive(Context context, Intent intent)函数里处理case CONNECTED处理;调用setDetailedState(NetworkStateTracker类实例)发送了EVENT_STATE_CHANGED事件 8) 然后又跳回ConnectivityService.java里的handleMessage函数EVENT_STATE_CHANGED事件的CONNECTED状态处理 9) handleConnect里最后调用updateNetworkSettings(实现在NetworkStateTracker类里),并发送sendConnectedBroadcast(info);广播事件 10)              ConnectivityService.java handleDnsConfigurationChange配置DNS信息,并在handleConnect 函数调用addPrivateDnsRoutes添加路由信息 11)              接下来调用了GpsLocationProvider.java里的updateNetworkState和runLocked,原因不明? 12)              接下来返回去调用startUsingNetworkFeature(ConnectivityService.java),又一次add dns ?,然后返回APN_ALREADY_ACTIVE状态 13)              ensureRouteToHost()(/packages/apps/Mms/src/com/android/mms/transaction/Transaction.java)调用了ConnectivityManager类里的requestRouteToHost 至此关于Mms的Apn网络连接就建立起来了, 下面的步骤是在RILJ层以及RILD层实现数据和AT命令与modem的数据通信,省去 下面分析disable APN的流程,基本上就是Start的反过程: 1) 数据通信完毕,SendTransaction.java里的run函数给出数据通信完成之后的状态 2) stopUsingNetworkFeature()(ConnectivityService实例);这个就是startUsingNetworkFeature的反过程 3) disableApnType(mms),DataConnectionTracker类 4) setEnabled,DataConnectionTracker类 Android平台中Wifi的初始化 收藏 1. WIFI JAVA layer: 1.1 . 当android系统启动WIFI 模块时, 它将调用 Wifiserver 类的setWifiEnabledBlocking函数。 1.2 . 在该函数中,如果是使能WIFI, 它将做四件事: a. load wifi driver. b. 启动wpa_supplicant. c. 启动 event loop. d. 更新wifi的状态. 2. WIFI Native layer: 2.1 . 当java层调用 loadDriver时, 它实际上是通过JNI来调用Native函数, JNI->android_net_wifi_loadDriver -> wifi_load_driver。 在wifi_load_driver函数中,它将首先通过system property -- wlan.driver.status 的状态来判断驱动是否已经加载。如果没有加载,将会加载该驱动。 2.2 . 当java层调用startSupplicant时,它实际上是通过JNI调用到wifi_start_supplicant函数, 在wifi_start_supplicant函数里,首先确定wpa supplicant的配置文件存在,如果不存在,将默认配置文件拷贝到相应目录下,下面是配置文件的默认路径和工作路径: static const char SUPP_CONFIG_TEMPLATE[]= "/system/etc/wifi/wpa_supplicant.conf"; static const char SUPP_CONFIG_FILE[] = "/data/misc/wifi/wpa_supplicant.conf"; 然后,调用control_supplicant函数, 如果这时wpa_supplicant还没有启动, 将会启动wpa_supplicant. 2.3 . java层通过connectToSupplicant调用wifi_connect_to_supplicant函数,在该函数中,将通过 wpa_ctrl_open函数分别创建两个AF_UNIX地址族和数据报方式的socket,一个是ctrl_conn, 用于向wpa_supplicant发送命令并接收response, 另一个是monitor_conn, 它一直阻塞等待从wpa_supplicant过来的event。最后,通过monitor_conn向wpa_supplicant发送命令 ATTACH,用于将自己的socket信息注册到wpa_supplicant, 由于socket是数据报方式的,这一步是必须的,对于存在于wpa_supplicant的服务器端,它是所有客户端共享的,由于它需要主动向 monitor_conn客户端发送事件,所以它必须先记录下该客户端的详细信息,wpa_supplicant就可以将EVENT发向该socket。 在完成上面这些操作后,java层会通过jni方式调用函数android_net_wifi_waitForEvent(应该是起一个线程,在线程里调用),该函数会调用wifi_wait_for_event,在wifi_wait_for_event函数里,会阻塞接收从 wpa_supplicant模块传来的事件,一旦wpa_supplicant模块有事件发,wifi_wait_for_event接收到后,会将包含事件的buf通过函数参数的方式回传到java层,java收到事件后,再继续调用wifi_wait_for_event函数进行阻塞等待接收,从而完成一个循环。 2.4 . 以上的流程完成以后,WIFI java layer 调用的WIFI native api 就和wpa_supplicant进程就建立了联系,WIFI java layer就可以向wpa_supplicant发送命令和接收response, 并且wpa_supplicant也可以主动向WIFI java layer发送事件了。 本文来自CSDN博客,转载请标明出处: android 新建一个Apn后的数据连接的调试过程 android, Apn, 数据, 调试 当我新建了一个APN 保存信息后,系统发现APN发生了改变就会去进行数据连接. 我查看调试信息发现第一次发送 setup_data_call 请求后,底层做出了响应,数据连接成功了状态为 CONNECTED, 却出现了PREFERED APN is null, 然后又监听到了 Apn 发生了改变,所以就将状态改变为 DISCONNECTING ,接着就发送一个DEACTIVATE_DATA_CALL  的请求要求断开数据连接,然后又发送一个 setup_data_call 去进行数据连接,第二次就连接成功了并在屏幕上显示出来了 G 标志. 其中让我非常纳闷的是: 为什么检测到两次APN 发生了改变? 当第一次连接状态已经为 CONNECTED 了却又监听到了 APN 发生了改变. 添加APN网络接入点,设置指定网络为默认网络 收藏 网上看了很多资料,再加上自己的理解和探索,终于实现了添加接入点设置和将当前网络设置为自己指定的网络接入点。废话不多说,上源码,大家分享下:(在moto-xt800,CDMA下进行了测试) 1.准备工作: AndroidManifest。xml文件里添加以下三个权限设置: <uses-permission android:name="android.permission.WRITE_APN_SETTINGS"></uses-permission> <uses-permission android:name="android.permission.INTERNET"></uses-permission> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 开始上代码了,很期待吧? 2.新建一个类ApnNode,算是属性设置吧 public class ApnNode { private String name ; private String apn ; private String proxy ; private String port; private String user; private String server; private String password; private String mmsc; private String mmsproxy; private String mmsport; private String mcc; private String mnc; private String numeric; private String type; /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } /** * @return the apn */ public String getApn() { return apn; } /** * @param apn the apn to set */ public void setApn(String apn) { this.apn = apn; } /** * @return the proxy */ public String getProxy() { return proxy; } /** * @param proxy the proxy to set */ public void setProxy(String proxy) { this.proxy = proxy; } /** * @return the port */ public String getPort() { return port; } /** * @param port the port to set */ public void setPort(String port) { this.port = port; } /** * @return the user */ public String getUser() { return user; } /** * @param user the user to set */ public void setUser(String user) { this.user = user; } /** * @return the server */ public String getServer() { return server; } /** * @param server the server to set */ public void setServer(String server) { this.server = server; } /** * @return the password */ public String getPassword() { return password; } /** * @param password the password to set */ public void setPassword(String password) { this.password = password; } /** * @return the mmsc */ public String getMmsc() { return mmsc; } /** * @param mmsc the mmsc to set */ public void setMmsc(String mmsc) { this.mmsc = mmsc; } /** * @return the mmsproxy */ public String getMmsproxy() { return mmsproxy; } /** * @param mmsproxy the mmsproxy to set */ public void setMmsproxy(String mmsproxy) { this.mmsproxy = mmsproxy; } /** * @return the mmsport */ public String getMmsport() { return mmsport; } /** * @param mmsport the mmsport to set */ public void setMmsport(String mmsport) { this.mmsport = mmsport; } /** * @return the mcc */ public String getMcc() { return mcc; } /** * @param mcc the mcc to set */ public void setMcc(String mcc) { this.mcc = mcc; } /** * @return the mnc */ public String getMnc() { return mnc; } /** * @param mnc the mnc to set */ public void setMnc(String mnc) { this.mnc = mnc; } /** * @return the numeric */ public String getNumeric() { return numeric; } /** * @param numeric the numeric to set */ public void setN
    展开阅读全文
    提示  咨信网温馨提示:
    1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
    2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
    3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
    4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
    5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
    6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

    开通VIP折扣优惠下载文档

    自信AI创作助手
    关于本文
    本文标题:Android-APN开发流程分析.doc
    链接地址:https://www.zixin.com.cn/doc/11877033.html
    页脚通栏广告

    Copyright ©2010-2025   All Rights Reserved  宁波自信网络信息技术有限公司 版权所有   |  客服电话:0574-28810668    微信客服:咨信网客服    投诉电话:18658249818   

    违法和不良信息举报邮箱:help@zixin.com.cn    文档合作和网站合作邮箱:fuwu@zixin.com.cn    意见反馈和侵权处理邮箱:1219186828@qq.com   | 证照中心

    12321jubao.png12321网络举报中心 电话:010-12321  jubao.png中国互联网举报中心 电话:12377   gongan.png浙公网安备33021202000488号  icp.png浙ICP备2021020529号-1 浙B2-20240490   


    关注我们 :微信公众号  抖音  微博  LOFTER               

    自信网络  |  ZixinNetwork