uicc详解-2(uicc在UE端的软件架构及命令流程)

    UE侧使用android操作系统,高通平台,uicc软件架构如下:

    

uicc软件架构图

    QCRIL传输的是GENERIC COMMANDS即上章中的命令(文件操作,pin,鉴权等),而QCRIL STK传输的是CAT COMMANDS(toolkit及文件操作)。

    从MODEM侧的uimtask来看,一个卡槽会起一个task来跑,每个uim_task都有属于自己的uim_ptr,uim_ptr基本包括了uim卡的所有信息,结构体如下所示:


    由于uim的每个task使用的是同一套代码,所以使用instance id来区分当前是哪个task。

    从modem收到qmi命令mmgsdi收到命令后发生给uim的过程:

    1.qmi_sim_internal.c中的qmi_sim_internal_init为sim qmi server端的初始化函数,其中关键函数为


    注册了回调函数qmi_sim_internal_handle_req_cb,该函数每当qmi收到client发送过来的消息后就会调用该函数,该函数中的关键代码如下


    2.从qmi_sim_internal_req_handle_table中找到对应命令的回调,然后执行,


    在此我们分析下qmi_sim_internal_mmgsdi_session_get_all_pin_status_handler的代码流程,在该函数中直接调用了如下函数


其中qmi_sim_internal_mmgsdi_response_callback会在下篇文章中调用。

    3.在mmgsdi_session_get_all_pin_status函数中填充了结构体task_cmd_ptr,并通过mmgsdi_cmd发送,如下

mmgsdi_cmd通过调用mmgsdi_cmd_ext接口发送命令如下

    mmgsdi_cmd_ext函数则通过队列与信号的方式发送命令,这个是modem侧常用的任务间命令发送方式,代码如下:


    4.在gsdimain主task中,初始化完成后会使用mmgsdi_wati一直在等待信号,这是modem的task基本流程。收到MMGSDI_TASK_CMD_Q_SIG信号

    后会调用mmgsdi_handle_queue_sig来处理,过程如下:


    mmgsdi_handle_queue_sig函数会从队列中取出mmgsdi_task_ptr然后通过mmgsdi_process_command发送出去,如下:


    mmgsdi_process_command->mmgsdi_process_get_all_pin_status_cmd->mmgsdi_uicc_pin_status->mmgsdi_util_build_pin_req->mmgsdi_uim_common_verify_pin->

    mmgsdi_send_cmd_to_uim_server->uim_cmd

    在这里需要注意下,mmgsdi_process_command函数中,给mmgsdi_process_get_all_pin_status_cmd传递的参数task_cmd_ptr->cmd.cmd是一个共用体,这也是modem线程交互信息常用手法,采用共用体一般把命令头放在成员变量的头位置,这样使得在接收方能够解析不同命令发送过来的命令头。还有一种用法是,可以定义一个大的buff,大buff有一定长度的队列组成,每次传递信息时从这个大buff中取一个队列,使用完把队列放回去,以避免内存泄露哦问题。


    上述函数中,mmgsdi_send_cmd_to_uim_server函数中会对把mmgsdi_uim_report函数指针赋给cmd_ptr->hdr.rpt_function,该回调函数会在uim task收到uim返回的数据后调用,最后的uim_cmd采用来本文所说到的信号队列机制发送命令给uim task。

    注意中上诉函数中的cmd赋值

    该值会在后续中使用。

    5.在uim_task中跟gsdi_task类似,一样是一个无限循环,在循环中判断信号,然后调用对应处理函数,


    在uim_handle_cmd_q_sig函数中取出队列函数,并赋值到uim_ptr的command结构体中,


    然后在该函数中调用uim_process_command->uim_process_generic_command,在uim_process_generic_command函数中会对gsdi传过来的命令进行处理,


    然后调用uim_gentric_command函数,

    在该函数中会进行apdu填充,然后通过uim_send_command进行发送,在uim_send_command中会把uim_req_buf_static_ptr填充到uim_ptr->card_cmd中(该函数有个关键点,就是uim_req_buf_static_ptr->rsp_ptr指针指向uim_ptr->command.rsp_buf,在uim_send_command函数中,又会把该指针赋值给uim_ptr->card_cmd.resp_buf_ptr,该指针会用来存放sim回复的数据,下节分析),然后通过uim_send_apdu->uim_send_apdu_command_hdr->uim_tx写入URAT串口,发送到实体卡上。

    至此分析了从qmi接口到实体卡的过程。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值