《AT指令介绍》PPT课件.ppt_第1页
《AT指令介绍》PPT课件.ppt_第2页
《AT指令介绍》PPT课件.ppt_第3页
《AT指令介绍》PPT课件.ppt_第4页
《AT指令介绍》PPT课件.ppt_第5页
已阅读5页,还剩32页未读 继续免费阅读

下载本文档

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

文档简介

AT指令介绍,谢万财 2011-08-10,AT命令(AT Commands)概述 RIL概述 Android的系统架构 Android RIL与AT概述 实例 操作 拓展 练习,缩略词,AT: ATtention; this two-character abbreviation is always used to start a command line to be sent from TE to TA ME: Mobile Equipment MT: Mobile Termination TA: Terminal Adaptor, e.g. a GSM data card (equal to DCE; Data Circuit terminating Equipment) TE: Terminal Equipment, e.g. a computer (equal to DTE; Data Terminal Equipment) DTE: Data Terminal Equipment DCE: Data Circuit Terminal Equipment MS : Mobile Station,AT命令(AT Commands)概述,由Hayes公司发明,现在已成为事实上的标准并被所有调制解调器制造商采用的一个调制解调器命令语言。每条命令以字母“AT“开头,因而得名。 AT 即Attention,AT指令集是从终端设备(TE)或数据终端设备(DTE)向终端适配器(TA)或数据电路终端设备(DCE)发送的。通过TA,TE发送AT指令来控制移动台(MS)的功能,与GSM 网络业务进行交互。用户可以通过AT指令进行呼叫、短信、电话本、数据业务、传真等方面的控制。,AT命令(AT Commands)概述,因为 AT 命令是作为一个接口标准,所以它的命令和返回的值和格式都是固定的,总体上说 AT 命令有四种形式: 1. 无参数命令。它是一种单纯的命令,格式是 AT|&,如开机、显示当前设置列表等:AT+ON、AT&V 2. 查询命令。它用来查询该命令当前设置的值,格式是 AT|&?,如:AT+CSCA? 3. 帮助(测试)命令。它是用来列出该命令的可能参数,格式是 AT|&=?,如: AT+CMGL=? 4. 带 参 数 命 令 。 它 是 应 用 最 广 的一种格式, 它为命令提供了强大的灵活性, 格式是AT |&=,AT命令(AT Commands)概述,目前的智能机在硬件上多采用双cpu的架构,一个是基带处理器,主要处理数字信号、语音信号的编码解码以及GSM通信协议,另一个是应用处理器,运行操作系统和各种应用程序。基带处理器、射频和其它外围芯片作为一个模块,成为GSM/GPRS modem,提供AT命令接口。 网络的应用已经是一个需求的热点,而目前的GSM模块大多都能支持GPRS功能。应用处理器通过AT命令集与带GPRS功能的无线通讯模块通信,为实现网络的应用提供了一个最底层的支持。,AT命令(AT Commands)概述,TE、TA间接口的操作可以通过使用物理存在的串口线、红外连接,或其他具有相似功能的连接方式。,RIL概述,RIL,Radio Interface Layer。 本层为一个协议转换层,手机框架需要适应多类型的 Modem接入到系统中,而对于不同的 Modem 有不同的特性,AT 指令的格式或者回应有所不同,但是这种特性在设计应用时不可能完全考虑和兼容。所以设计者在设计电话系统时,建立了一个虚拟电话系统,为该虚拟电话系统规定了标准的功能,上层的电话管理都是建立在这些标准的功能基础之上。而 RIL 则是将虚拟电话系统的标准功能转换成实际的所使用的 Modem的 AT 指令。,Android的系统架构,BroadCom修改的系统架构,相对而言,BroadCom平台增加了HAL层,并有URIL和KRIL的说法,但不影响我们对RIL层整体架构的理解。,Android RIL与AT概述,Android 设计者将电话系统设计成了三部分,Android 给出了一个 ril实现框架。由于 Android 开发者使用的 Modem 是不一样的,各种指令格式,初始化序列都可能不一样,GSM 和 CDMA 就差别更大了,所以为了消除这些差别,Android 设计者将 ril 做了一个抽象,使用一个虚拟电话的概念。这个虚拟电话对象就是GSMPhone(CDMAPhone),Phone对象所提供的功能协议,以及要求下层的支撑环境都有一个统一的描述,这个底层描述的实现就是靠 RIL 来完成适配,Android RIL与AT概述,ril 是具体的 AT 指令合成者和应答解析者。从最基本的功能来讲,ril 建立了一个侦听Socket,等待客户端的连接,然后从该连接上读取 RIL-Java 成传递来的命令并转化成 AT指令发送到 Modem。并等待 Modem 的回应,然后将结果通过套接口传回到 Ril-Java 层。,Android RIL与AT概述,为什么要定义这些接口呢?这函数接口不是凭空捏造出来的, 这些都是电话的基本功能的描述,是对 Modem AT 指令的提炼抽象。大多数 Modem 都是根据通讯协议提供接口,在 ril.java 源代码中,我们可以看到 RIL-JAVA 对象提供了如述的 Command Interface,Android RIL与AT概述,Rild是 Init进程启动的一个本地服务,这个本地服务并没有使用 Binder之类的通讯手段,而是采用了 socket 通讯这种方式。,Android RIL与AT概述,android 电话系统整体框架图,从这个图看来,应该是Phone对象中有个RIL类型的成员变量,通过RIL中的Reciver/Sender向下层发送数据,Android RIL与AT概述,下面的数据流传递描述图表描述了 RIL-JAVA 层发出一个电话指令的 5 步曲,RIL_JAVA 传递的命令格式:Parcel ,由命令号,令牌,内容组成。RIL_JAVA 到达 RIL_C时转为构建本地 RequestInfo,并将被翻译成具体的 AT 指令。由于每条 AT 命令的参数是不同的,所以对不同的 AT指令,有不同的转换函数.,但是我感觉Java和C中都有Parcel和RequestInfo,只不过一个是进行封装,一个是进行解析,这个图画的略微有点模糊 主要是讲了两个应用的具体流程: 请求和主动上报 黄线是函数调用,绿线是解释。 (不过这图画的真烂),实例,TwelveKeyDialer.java,public class TwelveKeyDialer extends Activity implements View.OnClickListener,View.OnLongClickListener, View.OnKeyListener, AdapterView.OnItemClickListener, TextWatcher public void afterTextChanged(Editable input) if (SpecialCharSequenceMgr.handleChars(this, input.toString(), mDigits) / A special sequence was entered, clear the digits mDigits.getText().clear(); ,拨号键显示、监听、处理,这个例子是查询IMEI号,所以稍微有些特殊,实例,SpecialCharSequenceMgr.java,static boolean handleChars(Context context, String input, EditText textField) return handleChars(context, input, false, textField); ,static boolean handleChars(Context context, String input, boolean useSystemWindow,EditText textField) /get rid of the separators so that the string gets parsed correctly String dialString = PhoneNumberUtils.stripSeparators(input); if (handleIMEIDisplay(context, dialString, useSystemWindow) | handlePinEntry(context, dialString) | handleAdnEntry(context, dialString, textField) | handleSecretCode(context, dialString) /2010-12-15And by ying.pang for quick lanuch application | handleApplicationQuickLaunch(context,dialString) return true; return false; ,static boolean handleIMEIDisplay(Context context, String input, boolean useSystemWindow) if (input.equals(MMI_IMEI_DISPLAY) int phoneType = (TelephonyManager)context.getSystemService( Context.TELEPHONY_SERVICE).getPhoneType(); if (phoneType = TelephonyManager.PHONE_TYPE_GSM) showIMEIPanel(context, useSystemWindow); return true; else if (phoneType =TelephonyManager.PHONE_TYPE_CDMA) return false; ,static void showIMEIPanel(Context context, boolean useSystemWindow) String imeiStr = (TelephonyManager)context.getSystemService( Context.TELEPHONY_SERVICE).getDeviceId(); ,判断你是否在查询IMEI号,发现还真是的,实例,TelephonyManager.java,public String getDeviceId() try return getSubscriberInfo().getDeviceId(); catch (RemoteException ex) return null; catch (NullPointerException ex) return null; ,private IPhoneSubInfo getSubscriberInfo() / get it each time because that process crashes a lot return IPhoneSubInfo.Stub.asInterface( ServiceManager.getService(“iphonesubinfo“); ,public String getDeviceId( () mContext.enforceCallingOrSelfPermission( READ_PHONE_STATE, “Requires READ_PHONE_STATE“); return mPhone. getDeviceId(); ,PhoneSubInfo.java,采用AIDL来实现IPC(进程间通信)的跨进程调度,终于到了Phone对象中,实例,GSMPhone.java,public GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier, boolean unitTestMode) mSIMRecords = new SIMRecords(this); mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null); mSIMRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null); mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null); mCM.registerForOn(this, EVENT_RADIO_ON, null); mCM.setOnUSSD(this, EVENT_USSD, null); mCM.setOnSuppServiceNotification(this, EVENT_SSN, null); mSST.registerForNetworkAttach(this, EVENT_REGISTERED_TO_NETWORK, null); ,public String getSubscriberId() return mSIMRecords.imsi; ,注册各种服务,从这里开始有点茫然了 反正就是后面又到了Ril.java,实例,GSMPhone.java,Override public void handleMessage (Message msg) AsyncResult ar; Message onComplete; switch (msg.what) case EVENT_RADIO_AVAILABLE: mCM.getIMEI(obtainMessage(EVENT_GET_IMEI_DONE); case EVENT_GET_IMEI_DONE: ar = (AsyncResult)msg.obj; if (ar.exception != null) break; mImei = (String)ar.result; break; ,处理所注册服务消息,做初始化工作,实例,public final class RIL extends BaseCommands implements CommandsInterface class RILSender extends Handler implements Runnable public void handleMessage(Message msg) switch (msg.what) case EVENT_SEND: try LocalSocket s; s = mSocket; s.getOutputStream().write(dataLength); s.getOutputStream().write(data); ,Ril.java,public void getIMEI(Message result) RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMEI, result); if (RILJ_LOGD) riljLog(rr.serialString() + “ “ + requestToString(rr.mRequest); send(rr); ,获取RILRequest实例,封装“令牌”,发送消息到消息队列,待mSender对象处理,对rr打包数据解包,以字节流方式,写入socket,在”AndroidPhoneApplication”中讲到 Send以后,是发给了另一个线程的HandleMessage,在handleMessage中通过socket发送给Ril.cpp,提到过Parcel对象,它是封装在rr中的,实例,onRequest (int request, void *data, size_t datalen, RIL_Token t) ATResponse *p_response; int err; switch (request) case RIL_REQUEST_GET_IMEI: p_response = NULL; err = at_send_command_numeric(“AT+CGSN“, ,Reference-ril.c,发送AT命令,response传回socket,跳过Ril.cpp,到了Reference_ril的onRequest,At_send_command就是向硬件发送AT指令,err表示请求的状态,如果请求查询成功了,就调用RIL_onRequestComplete回传 P_reponse是查询的结果,public final class RIL extends BaseCommands implements CommandsInterface class RILReceiver implements Runnable processResponse(p); private void processResponse (Parcel p) int type; type = p.readInt(); if (type = RESPONSE_UNSOLICITED) processUnsolicited (p); else if (type = RESPONSE_SOLICITED) processSolicited (p); releaseWakeLockIfDone(); ,Ril.java,private void processSolicited (Parcel p) RILRequest rr; rr = findAndRemoveRequestFromList(serial); try switch (rr.mRequest) case RIL_REQUEST_GET_IMEI: ret = responseString(p); break; if (rr.mResult != null) AsyncResult.forMessage(rr.mResult, ret, null); rr.mResult.sendToTarget(); rr.release(); private Object responseString(Parcel p) String response; response = p.readString(); return response; ,接收Socket上报字节流进行处理,处理主动上报,处理请求(命令异步)响应,上报请求,根据“令牌”找RILRequest,又跳过了Ril.cpp直接到了java中,这个地方又有些蹊跷 查询IMEI是需要返回一个string的,实例,SpecialCharSequenceMgr.java,static private void showIMEIPanel(Context context) if (DBG) log(“showIMEIPanel“); /要发送请求了 String imeiStr = PhoneFactory.getDefaultPhone().getDeviceId(); /响应已经传回来了 AlertDialog alert = new AlertDialog.Builder(context) .setTitle(R.string.imei) .setMessage(imeiStr) .setPositiveButton(R.string.ok, null) .setCancelable(false) .show(); alert.getWindow().setType( WindowManager.LayoutParams.TYPE_PRIORITY_PHONE); ,显示请求消息,操作,2 adb shell:启动控制台,3 bcmtest l:启用AT命令程序,1 cmd:进入命令模式,注:broadcom AT命令程序并不是支持所有AT命令,具体内容见froyo_r1brcmatatchandlersat_cmd.tbl 本例中broadcom使用”at*mimeitst?”实现,拓展:使用AT命令收发短消息,目前,发送短消息常用Text和PDU(Protocol Data Unit,协议数据单元)模式,拓展:使用AT命令收发短消息,拓展:使用AT命令收发短消息,一般的PDU编码由A B C D E F G H I J K L M十三项组成: A:短信息中心地址长度,2位十六进制数(1字节)。 B:短信息中心号码类型,2位十六进制数。 C:短信息中心号码,B+C的长度将由A中的数据决定。 D:文件头字节,2位十六进制数。 E:信息类型,2位十六进制数。 F:被叫号码长度,2位十六进制数。 G:被叫号码类型,2位十六进制数,取值同B。 H:被叫号码,长度由F中的数据决定。 I :协议标识,2位十六进制数。 J:数据编码方案,2位十六进制数。 K:有效期,2位十六进制数。 L:用户数据长度,2位十六进制数。 M:用户数据,其长度由L中的数据决定。J中设定采用UCS2编码,这里是中英文的Unicode字符。,发送:SMSC(+8613800250500),对方, 消息内容(“Hello!”) 从手机发出的PDU串可以是 0891683108200505F011000D91683196032930F0000000 06C8329BFD0E01 08 SMSC地址信息的长度 共8个八位字节(包括91) 91 SMSC地址格式(TON/NPI) 用国际格式号码(在前面加+) 68 31 08 20 05 05 F0 SMSC地址 8613800250500,补F凑 成偶数个 11 基本参数(TP-MTI/VFP) 发送,TP-VP用相对格式 00 消息基准值(TP-MR) 0 0D 目标地址数字个数 共13个十进制数(不包括91和F) 91 目标地址格式(TON/NPI) 用国际格式号码(在前面加+) 68 31 96 03 29 30 F0 目标地址(TP-DA) 8613693092030, 补F凑成偶数个 00 协议标识(TP-PID) 是普通GSM类型,点到点方式 00 用户信息编码方式(TP-DCS) 7-bit编码 00 有效期(TP-VP) 5分钟 06 用户信息长度(TP-UDL) 实际长度6个字节 C8 32 9B FD 0E 01 用户信息(TP-UD) “Hello!”,拓展:使用AT命令收发短消息,一般的PDU编码由A B C D E F G H I J K L M十三项组成: A:短信息中心地址长度,2位十六进制数(1字节)。 B:短信息中心号码类型,2位十六进制数。 C:短信息中心号码,B+C的长度将由A中的数据决定。 D:文件头字节,2位十六进制数。 E:信息类型,2位十六进制数。 F:被叫号码长度,2位十六进制数。 G:被叫号码类型,2位十六进制数,取值同B。 H:被叫号码,长度由F中的数据决定。 I :协议标识,2位十六进制数。 J:数据编码方案,2位十六进制数。 K:有效期,2位十六进制数。 L:用户数据长度,2位十六进制数。 M:用户数据,其长度由L中的数据决定。J中设定采用UCS2编码,这里是中英文的Unicode字符。,接收:SMSC(+8613800250500),对方, 消息内容(“你好!”) 手机接收到的PDU串可以是 0891683108200505F0840D91683196032930F0000830 302180635480064F60597D0021 08 地址信息的长度 个八位字节(包括91) 91 SMSC地址格式(TON/NPI) 用国际格式号码(在前面加+) 68 31 08 20 05 05 F0 SMSC地址 8613800250500,补F凑成偶数个 84 基本参数(TP-MTI/MMS/RP) 接收,无更多消息,有回复 地址 0D 回复地址数字个数 共13个十进制数(不包括91和F) 91 回复地址格式(TON/NPI) 用国际格式号码(在前面加+) 68 31 96 03 29 30 F0 回复地址(TP-RA) 8613693092030, 00 协议标识(TP-PID) 是普通GSM类型,点到点方式 08 用户信息编码方式(TP-DCS) UCS2编码 30 30 21 80 63 54 80 时间戳(TP-SCTS) 2003-3-12

温馨提示

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

评论

0/150

提交评论