android QMI机制---Modem消息接收
来源:互联网 发布:循序渐进学java 编辑:程序博客网 时间:2024/06/06 00:29
6 Modem消息接收
3.1 消息初始化
初始化:qmi_modem_taskàqmii_init()àqmux_init()。qmux_init方法完成对控制通道的初始化后,
通过函数qmuxi_process_rx_sig方法开始从共享内存接收数据。调用流程如如下,
(void)qmi_set_sig_handler(QMI_QMUX_RX_SIGNAL, qmuxi_process_rx_sig, NULL);
在qmuxi_process_rx_sig方法中,首先通过dsm_dequeue()读取在队列中等待的QMUX消息,
赋值给指针qmux_pdu表示QMUX消息的首地址。
qmux_pdu = dsm_dequeue( &qmux_s->io.rx_wm );
然后调用qmuxi_process_msg方法开始对AP侧发过来的QMUX消息解包。
qmuxi_process_msg( qmux_s, qmux_pdu );
qmuxi_process_msg方法首先拆分IF Type,通过函数dsm_pull8()进行解包。然后判断IF Type类型,
然后把QMUX Message通过qmuxi_input()继续处理。
在qmuxi_input()中,会拆分QMUX的消息头,将消息头大卸八块,包括length,control_flags,client_id,service_id,
然后调用qmi_framework_svc_recv方法将剩下的QMUX SDU从拆分出来的QMUX消息头中,
找到BP侧相对应的service处理。
if((svci == NULL) || (!(svci->registered))) { status = qmi_framework_svc_recv( qmi_instance_by_qmux_state(qmux_s), (qmux_service_e_type) qmux_hdr.svc_type, qmux_hdr.clid, *qmux_pdu ); *qmux_pdu = NULL; return status; }
在qmi_framework_svc_recv方法中,并不会马上根据service_id等对QMUX消息进行处理,这里也是一个接口,
将消息打包成BP侧的QMI_framework的一个command,发送出去。
qmi_framework_msg_hdr_type msg_hdr;qmi_framework_svc_info_type * svc_info;•••svc_info = qmi_framework_svc_state[service];
定义一个qmi_framework_svc_info_type的指针变量,对svc_info的操作就等于对qmi_framework_svc_state的操作。
打包到msg_hdr
msg_hdr.common_hdr.service = service; msg_hdr.common_hdr.client_id = client_id; msg_hdr.common_hdr.qmi_instance = (int32)qmi_instance; msg_hdr.common_hdr.transaction_id = msg_x_id; msg_hdr.msg_ctl_flag = msg_ctl; msg_hdr.msg_len = remaining_bytes;
最后
svc_info->cfg.cbs.cmd_hdlr(&msg_hdr,&sdu_in);
这个机制是怎么样呢?以phone相关的qmi_voice.c为例。
3.2 消息分类处理
qmi_voice.c在qmi_voice_init方法进行初始化时,
qmi_mmode_set_cmd_handler(QMI_MMODE_CMD_VOICE_FW_CB, qmi_voice_handle_fw_cmd);•••qmi_voicei_cfg.cmn_svc_cfg.fw_cfg.cbs.alloc_clid = qmi_voice_fw_alloc_clid_cback;qmi_voicei_cfg.cmn_svc_cfg.fw_cfg.cbs.dealloc_clid = qmi_voice_fw_dealloc_clid_cback;qmi_voicei_cfg.cmn_svc_cfg.fw_cfg.cbs.init_cback = qmi_voice_fw_init_cback;qmi_voicei_cfg.cmn_svc_cfg.fw_cfg.cbs.cmd_hdlr = qmi_voice_fw_req_cback; qmi_voicei_cfg.cmn_svc_cfg.cmd_hdlr_array = qmi_voicei_cmd_callbacks;qmi_voicei_cfg.cmn_svc_cfg.cmd_num_entries = VOICEI_CMD_MAX;qmi_voicei_cfg.cmn_svc_cfg.service_id = QMUX_SERVICE_VOICE; /*----------------------------------------------------------------------- step 2: calling QMI Framework API to register the service. ----------------------------------------------------------------------*/ errval= qmi_framework_reg_service(QMUX_SERVICE_VOICE, &qmi_voicei_cfg.cmn_svc_cfg.fw_cfg);
初始化的时候,用结构体指针&qmi_voicei _cfg,到qmi_framework里面注册服务,获取AP测发送过来的qmux,
可以关注给cmd_hdlr赋值的函数qmi_voice_fw_req_cback,这是从qmi_framework返回的回调函数。
因此,对于phone消息, qmi_framework_svc_recv都是回调qmi_voice_fw_req_cback进行处理,
qmi_voice_fw_req_cback方法读取QMUX消息的头指针,和QMUX SDU的首地址。发送到voice服务里面专门
的command_handle。
qmi_mmode_send_cmd(QMI_MMODE_CMD_VOICE_FW_CB, cmd_ptr);
在voice初始化可找到QMI_MMODE_CMD_VOICE_FW_CB对应的方法为qmi_voice_handle_fw_cmd。
qmi_mmode_send_cmd方法会调用qmi_voice_handle_fw_cmd方法,该方法根据不同的消息类型调用不同的
方法进行处理,
switch(qmi_info->id) { case QMI_MMODE_FW_INIT_CB: qmi_voicei_fw_init_cback_hdlr(qmi_info->data.qmi_fw_info.init_cb.num_instances); break; case QMI_MMODE_FW_ALLOC_CLID_CB: qmi_voicei_fw_alloc_clid_hdlr(&qmi_info->data.qmi_fw_info.alloc_clid.msg_hdr); break; case QMI_MMODE_FW_DEALLOC_CLID_CB: qmi_voicei_fw_dealloc_clid_hdlr(&qmi_info->data.qmi_fw_info.dealloc_clid.msg_hdr); break; case QMI_MMODE_FW_REQ_CB: qmi_voicei_fw_req_hdlr(&qmi_info->data.qmi_fw_info.req_cb.msg_hdr, qmi_info->data.qmi_fw_info.req_cb.sdu_in); break; default: QM_MSG_ERROR("Unsupported qmi-voice fw cmd"); break; }
qmi_voicei_fw_req_hdlr并不会马上对获取的消息进行处理,而是判断头消息中的client_id是否符合,
符合则通过函数qmi_mmode_svc_req_hdlr发送到request_handler中,
if( msg_hdr->common_hdr.client_id > 0 ) { cl_sp = (qmi_voicei_client_state_type *) qmi_voice_state.client[msg_hdr->common_hdr.client_id - 1]; ASSERT(cl_sp); /*------------------------------------------------------------------------- Invoke the common svc request handler -------------------------------------------------------------------------*/ qmi_mmode_svc_req_hdlr(&qmi_voicei_cfg.cmn_svc_cfg, msg_hdr, &cl_sp->common, sdu_in);
到此,几乎所有的消息类型最后都会调用qmi_mmode_svc_req_hdlr方法发送到request_handler中。
3.3 消息分发
在qmi_mmode_svc_req_hdlr函数中,真正对QMUX消息进行处理。首先拆分头消息中的service_id,control_flag等。
svc_id = svc_cfg->service_id;
然后通过一个while循环开始对QMUX SDU进行解包。
while (sdu_in) { /*----------------------------------------------------------------------- Extract service message header -----------------------------------------------------------------------*/ temp = dsm_pull16( &sdu_in );
解包函数dsm_pull16()作用,按照一定的大小,从&sdu_in这个地址中获取数据。获取完后,跳出while循环,
调用qmi_mmode_svci_dispatch_transaction方法进行处理。
qmi_mmode_svci_dispatch_transaction(&msg_hdr->common_hdr,svc_cfg,x_p);
其中参数x_p是解包后的qmux_sdu存放的buffer。
qmi_mmode_svci_input方法会通过request_handler对消息进行处理分发。
response_ptr = cmd_hdlr->request_hdlr( svc_cfg->svc_sp, cmd_buf_p, cl_sp, sdu_in );
request_hdlr方法是被封装了的,没法继续跟进,BP侧的接收处理到此结束。
- android QMI机制---Modem消息接收
- android QMI机制---modem消息发送
- android QMI机制---QCRIL消息发送
- android QMI机制---底层消息发送
- android QMI机制---概论
- android QMI机制---QMUX
- android QMI机制---Qcril初始化流程
- 高通Modem qmi log
- qualcomm qmi(modem-linux通信)
- RIL 机制---消息从reference-ril到Modem
- Android 学习之QCRIL QMI
- Android中消息机制初探(创建一个可以接收消息的子线程)
- Android广播接收机制(BroadcastReceiver)
- Android广播接收机制(BroadcastReceiver)
- Android广播接收机制(BroadcastReceiver)
- Android消息机制(Handler机制)
- android Handler机制 消息机制
- Android 消息处理机制
- Java操作word模板插入多种编号的列表
- TC实现不重复取数功能
- java加锁
- 堆和栈
- CSS 点击事件on 和onclick有什么区别? // CSS关于文本的那几个实用的属性
- android QMI机制---Modem消息接收
- 学习:C++ Primer 第1章 开始
- 一些学习记录
- 【Docker加速】- 解决docker pull镜像速度慢的问题
- Mysql语句练习
- CentOS安装流程
- C/C++面试题(一)
- 数据结构 C语言 队列 迷宫问题
- 文件I/O(不带缓存)++标准I/O(带缓存)