核心原则
框架层隐形,业务层极简。BP侧服务开发者只需实现回调,TLV编解码、事务管理、连接状态都由框架自动处理。
一、服务生命周期(3个函数)
| 阶段 | 函数 | 作用 |
|---|---|---|
| 注册 | qmi_csi_register() |
服务上线,传入回调表 |
| 运行 | process_req_cb() |
处理请求,发送响应/指示 |
| 注销 | qmi_csi_unregister() |
服务下线 |
二、请求处理标准范式
AP请求到达
│
▼
┌─────────────────────────────────┐
│ QMI框架(自动完成) │
│ • QMUX解复用 │
│ • TLV decode → req_c_struct │
│ • txn_id 提取到 req_handle │
└─────────────────────────────────┘
│
▼
process_req_cb(req_handle, msg_id, req_c_struct, req_len, service_cookie)
│
├── switch(msg_id)
│ │
│ ├── case REQ_XXX:
│ │ 读取 req_c_struct
│ │ 业务逻辑处理
│ │ 填充 resp_c_struct
│ │
│ │ qmi_csi_send_resp(req_handle, msg_id,
│ │ resp_c_struct, resp_len)
│ │ break
│ │
│ └── case REQ_YYY:
│ ...
│
└── 异常/默认:返回错误码
三、发送接口(2个函数)
| 函数 | 场景 | 关键参数 |
|---|---|---|
qmi_csi_send_resp() |
响应AP请求 | req_handle(复用事务上下文) |
qmi_csi_send_ind() |
主动上报事件 | client_handle(指定目标客户端) |
四、回调表(注册时传入)
c
// 连接/断开回调(可选,用于资源管理)
service_connect_cb(client_handle, service_cookie);
service_disconnect_cb(client_handle, service_cookie);
// 核心处理回调(必须)
process_req_cb(req_handle, msg_id, req_c_struct, req_len, service_cookie);
五、框架隐藏的细节(业务层不可见)
| 机制 | AP侧显式处理 | BP侧框架自动 |
|---|---|---|
| TLV编解码 | qmi_idl_message_encode/decode |
回调直接收/发C结构体 |
| 事务ID(txn_id) | 手动匹配请求-响应 | 封装在req_handle中自动复用 |
| 服务发现 | qmi_client_get_service_list() |
框架自动响应CTL查询 |
| 客户端标识 | qmi_client_init()生成 |
client_handle区分多AP连接 |
六、与AP侧的对称关系
AP侧(客户端) BP侧(服务端)
─────────────────────────────────────────────────────────
qmi_client_init() ─────────────→ service_connect_cb
qmi_client_send_msg_sync() ─────→ process_req_cb
等待响应回调 ◄──────────────────── qmi_csi_send_resp()
qmi_client_release() ───────────→ service_disconnect_cb
七、关键修正
| 我之前瞎编的 | 实际正确的 |
|---|---|
qmi_framework_init() |
不存在或RTOS静态完成,业务层不可见 |
qmi_service_register() |
qmi_csi_register() |
qmi_csi_process_request() |
框架内部函数,业务层看到的是process_req_cb回调 |
qmi_idl_message_decode()在回调中调用 |
框架已decode完,req_c_struct直接可用 |
这就是BP侧QMI框架的完整图景:极简回调驱动,框架包办底层 。你的switch(msg_id)流程是标准范式。