chuliang014 2016-11-24 06:02 采纳率: 0%
浏览 1515
已结题

有人熟悉android上层AT+VMOBID这个AT指令的用法吗?

图片说明

有人可以给个例子吗?..表示看不太懂

  • 写回答

1条回答 默认 最新

  • -修- 2016-11-24 08:29
    关注

    android中如何添加一个AT命令 简介: android平台,自带的参考RIL层是使用AT命令来和modem进行通信的,因为它假定AP和CP可能来自不同的厂家,所以AP和CP之间采用的是松耦合的机制。而高通平台,AP和CP都由高通提供,所以两颗CPU之间的通信采用紧耦合机制,采用ONCRPC或QMI来进行通信。 AT命令和QMI各有优缺点,AT命令有国际统一的标准,实现简单,但是实现的功能少,效率较低。而QMI机制是高通制定的,其实现复杂,但是效率高。 下面介绍使用AT命令机制实现的RIL,如何添加一个AT命令。我们假定要加一个读取CDMA modem的IMSI值的AT命令。 一、在上层添加所要发的AT命令的方法 1. 在接口phone中添加所要发的AT命令的方法。接口phone所在的位置是:frameworks/base/telephony/java/com/android/internal/telephony/Phone.java 在phone的接口中添加方法:getcdmaIMSI(); Phone是个接口,因此,添加完方法后,得在实现Phone接口的java类里面实现这个方法,GSM实现Phone的类是GSMPhone.java,CDMA实现phone的类是CDMAPhone.java GSMPhone.java位于 frameworks/base/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java CDMAPhone.java位于 frameworks/base/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java public String getcdmaIMSI() { return mSST.getImsi(); } 2. Phone接口的实现方法调用CommandsInterface接口里面的方法,所以我们还需要在CommandsInterface里面把我们要增加的方法添加进去。 CommandsInterface接口位于: rameworks/base/telephony/java/com/android/internal/telephony/commandsinterface.java 在commandsinterface接口中添加方法:void getIMSI(String aid, Message result); 同样的,CommandInterface也是个接口,我们需要在实现接口的类里实现这个方法。而实现这个接口的类有2个: 1. frameworks/base/telephony/java/com/android/internal/telephony /RIL.java 2. frameworks/base/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java 其中第2个是在模拟器里面测试用的, 我们只需要在里面把方法添加进去,然后调用个resultSuccess或者umimplement都可以。 而第1个才是真正实现功能的类。 所以,我们得在RIL.java中,实现具体的方法。
    tob_id_2536
    在RIL.java的方法里面,只需要定义好你所需要发送AT命令的一个标识MARK(下面还会提到), 再把RilRequest类里面的Parcel成员mp赋值, 然后发送出去即可。 赋给mp的值,即为我们需要发送到下层去处理的值, 例如传个数组下去, 一般都先把长度写进去, 其次再把成员依次写入。 public void getIMSI(String aid, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMSI, result); rr.mp.writeInt(1); rr.mp.writeString(aid); if (RILJ_LOGD) riljLog(rr.serialString() + "> getIMSI: " + requestToString(rr.mRequest) + " aid: " + aid); send(rr); } 二、在下层添加实现的函数 1. 在hardware/ril/include/telephony/ril.h h文件中添加AT命令标识,即上文提到的MARK。注意不要和别的宏发生冲突。 int RIL_REQUEST_GET_IMSI = 11; 注意: 这里的MARK必须定义在最后面, 不然会带来不必要的麻烦, 理由如下: 在ril.h中定义了每个关键字对应的值,同时在ril_command.h有张映射表,而且是按ril.h中的顺序映射的,大家可以看作是数组的下标。这里要一一对应,如果从中间插入,将会导致后面的字段映射不对。 除非把ril.h中关键字对应的值修改,但这样会浪费比较多的时间。 2. 在hardware/ril/libril/ril.cpp中添加消息映射字符串。 在该文件的const char *requestToString(int request)函数里面。 case RIL_REQUEST_GET_IMSI: return "GET_IMSI"; 3. 在hardware/ril/libril/ril_commands.h文件的最后添加函数映射表。 形如{MARK, dispatch, response} 解释如下: 首先第1个参数即为我们之前所定义的标识,即MARK。 第2个参数是下层的从数据流中解出数据的函数,这里要和上层所传下来的类型对应,例如上层传下来的是int数组,这里也得是dispathInts, 否则数据会出错 第3个参数是该函数所要返回的值, 这里的和第2个参数的一样。 {RIL_REQUEST_GET_IMSI, dispatchStrings, responseString}, 4. 在hardware/ril/reference-ril/reference-ril.c中添加处理AT命令函数

    此文件中,函数static void onRequest (int request, void *data, size_t datalen, RIL_Token t)是RIL发送请求的入口函数。在此函数里面添加我们所要处理的AT命令函数。 一般对于只返回成功与否的AT命令,我们用at_send_command()。 而对于有返回值的命令,我们用at_send_command_singleline()。 case RIL_REQUEST_GET_IMSI: at_send_command_numeric("AT+CIMI", &p_response); 三、添加返回值 命令发送成功后,modem会返回命令的响应消息。因此我们还需要对响应消息进行处理。 响应消息的处理是在RIL.java文件中的processUnsolicited()或者processSolicited()函数中。 processSolicited()处理的是 通过发送命令然后才会返回结果的消息。 而processUnsolicited()处理的是 主动上报类型的结果消息,即不需要你发送命令,modem侧会主动发的消息。比如:modem主动上报来电消息。 注意我们选用的返回函数,得和我们在ril_command.h里面所添加的函数映射表里的返回函数对应。 case RIL_REQUEST_GET_IMSI: ret = responseString(p); break; 到了这里,AT命令的过程就添加结束, 命令的返回值就在调用Phone里面的函数所传入的Message中。 返回的是一个AsyncResult, 就是Message的obj成员 。 这里我们可以处理异常,一般可通过如下代码处理(假设传入的Message为msg): AsyncResult ar = (AsyncResult)msg.obj if (ar.exception != null) 处理异常 处理结果,就对ar.result进行处理。

    1、hardware\ril\reference-ril\Reference-ril.c 中 onRequest() 处理RIL_REQUEST_DIAL 时会 调用requestDial();
    2、requestDial()中转换RIL_REQUEST_DIAL 请求为AT指令;
    3、通过at_send_command()下发;
    4、经过at_send_command_full,at_send_command_full_nolock ,writeline()写到设备中。

    要满足这三个条件:
    1,单开线程自动写at
    2,单开线程读at
    3,打开文件读配置,将读出来后的配置文件放到log文件里去。
    这边记录下如何在ui下开一个线程的过程:用一个handler变量调用handler.post函数,然后在runnable里面重写run接口就可以,实际上,这样调用出来的线程跟ui主线程是一个线程,不会创建新的。所以这边如果要用线程创建的话,必须
    wthread = new HandlerThread("thread");

    wthread.start();

    wHandler = new Handler(wthread.getLooper());

    wHandler.post(runnable);
    这时重写runnable的run函数才可以实现重新开启一个线程。
    在这个线程里面可以读写串口,但是界面的刷新不能在这个子线程里面做。必须主线程在做一个handler,然后子线程调用Message 变量传进主线程的handler.sendMessage(msg);然后主线程用handlerMessage接收子线程传过来的消息,在主线程里面刷新界面。

    你看下,不知道有没有帮助,不喜勿喷

    评论

报告相同问题?

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题