1、前言
1.1目的
本文档解释说明了QMI Client APIs的用法。这些APIs可以结合QMI IDL编辑器自动生成的文件来写一个发送消息到modem端的一个服务的一个客户端程序。
1.2适用范围
本文档适用于熟悉高通调制解调器接口(QMI)和意在开发一个跑在应用处理器上的客户端来控制modem端的客户。
本文档所提及的APIs的改动需要与高通讨论,但是不希望有大的改动。
1.3约定
函数说明,函数名,类型声明和代码样例有不同的格式。
1.4参考文献
序号 | 文档名称 | 作者或资料来源 |
1 | Application Note: Software Glossary for Customers | QRD |
1.5缩略词
缩写、术语 | 解释、含义 |
QMI | Qualcomm Messaging Interface |
API | Application Programming Interface(应用程序编程接口) |
Modem | 调制解调(基带) |
IDL | Interface Description Language |
QCCI | Qualcomm Common Client Interface |
2、QMI APIs
QMI APIs可以被分为五大类:
n 回调函数原型
n 连接 APIs
n 消息发送 APIs
n 释放连接 APIs
n 编解码 APIs
2.1回调函数原型
2.1.1qmi_client_recv_raw_msg_async_cb
当用qmi_client_send_raw_msg_async()函数发送请求后收到回应此函数由QCCI基础调用
Parameters
void *
qmi_client_recv_raw_msg_async_cb
(
qmi_client_type user_handle,
unsigned int msg_id,
void *resp_buf,
unsigned int resp_buf_len,
void *resp_cb_data,
qmi_client_error_type transp_err
);
→ | user_handle | Handle used by the infrastructure to identify different clients |
→ | msg_id | Message ID |
→ | resp_buf | Pointer to the response |
→ | resp_buf_len | Length of the response |
→ | resp_cb_data | User data |
→ | transp_err | Error code |
2.1.2qmi_client_recv_msg_async_cb
当用qmi_client_send_msg_async()函数发送请求后收到回应此函数由QCCI基础调用
Parameters
void *
qmi_client_recv_msg_async_cb
(
qmi_client_type user_handle,
unsigned int msg_id,
void *resp_c_struct,
unsigned int resp_c_struct_len,
void *resp_cb_data,
qmi_client_error_type transp_err
);
→ | user_handle | Handle used by the infrastructure to identify different clients |
→ | msg_id | Message ID |
→ | resp_c_struct | Pointer to the response |
→ | resp_c_struct_len | Length of the response |
→ | resp_cb_data | User data |
→ | transp_err | Error code |
2.1.3 qmi_client_ind_cb
当收到指示(indication)此函数由QCCI基础调用,此回调函数初始化时注册。
Parameters
void *
qmi_client_ind_cb
(
qmi_client_type user_handle,
unsigned int msg_id,
void *ind_buf,
unsigned int ind_buf_len,
void *resp_cb_data
);
→ | user_handle | Handle used by the infrastructure to identify different clients |
→ | msg_id | Message ID |
→ | resp_c_struct | Pointer to the indication |
→ | resp_c_struct_len | Length of the indication |
→ | resp_cb_data | User data |
图2-3
2.1.4 qmi_client_error_cb
当服务终止或注销时函数由QCCI基础调用,它是注册在qmi_client_register_error_cb函数里
Parameters
void *
qmi_client_error_cb
(
qmi_client_type user_handle,
qmi_client_error_type error,
void *err_cb_data
);
→ | user_handle | Handle used by the infrastructure to identify different clients |
→ | error | Error value |
→ | err_cb_data | User data |
2.2连接 APIs
2.2.1 qmi_client_notifier_init
这个函数用来初始化一个服务管理对象,当一个新的服务注册支持service_obj,信号或事件中指定的对象将被设置入os_params。
Parameters
extern qmi_client_error_type
qmi_client_notifier_init
(
qmi_idl_service_object_type service_obj,
qmi_client_os_params *os_params,
qmi_client_type *user_handle
);
→ | qmi_client_notifier_init | Sets the user handle |
→ | service_obj | Service object |
→ | os_params | OS-specific parameters; can be a pointer to an event object, or signal mask and TCB |
← | user_handle | Handle used by the infrastructure to identify different clients |
Return value
This function returns:
n QMI_NO_ERROR –If successful
n ERROR code –Otherwise
2.2.2 qmi_client_init
这个函数用作初始化一个连向服务的连接
Parameters
extern qmi_client_error_type
qmi_client_init
(
qmi_service_info *service_info,
qmi_idl_service_object_type service_obj,
qmi_client_ind_cb ind_cb,
void *ind_cb_data,
qmi_client_os_params *os_params,
qmi_client_type *user_handle
);
→ | qmi_client_init | Sets the user handle |
→ | service_info | Pointer to an entry in the service_info array returned by qmi_client_get_service_list() |
→ | service_obj | Service object |
→ | ind_cb | Indication callback function |
→ | ind_cb_data | Indication callback user data |
→ | os_params | OS-specific parameters; can be a pointer to an event object, or signal mask and TCB |
← | user_handle | Handle used by the infrastructure to identify different clients |
Return value
This function returns:
n QMI_NO_ERROR –If successful
n ERROR code –Otherwise
2.2.3 qmi_client_get_service_list
这个函数用作获取服务列表
Parameters
qmi_client_error_type
qmi_client_get_service_list
(
qmi_idl_service_object_type service_obj,
qmi_service_info *service_info_array,
uint32_t *num_entries,
uint32_t *num_services
);
→ | qmi_client_get_service_list | Retrieves a list of services |
→ | service_obj | Service object |
← | service_info_array | Array to fill |
↔ | num_entries | Number of entries in the array as input; number of entries filled as output |
← | num_services | Number of known services; if num_services > num_entries, a larger array is needed |
Return value
This function returns:
n QMI_NO_ERROR –If successful
n ERROR code – Otherwise
2.2.4 qmi_client_get_instance_id
这个函数用来获取一个特定服务的实例id
Parameters
qmi_client_error_type
qmi_client_get_instance_id
(
qmi_service_info *service_info,
qmi_service_instance *instance_id
);
→ | qmi_client_get_instance_id | Retrieves a list of services |
→ | service_info | Pointer to an entry in the service_info array |
← | instance_id | Instance ID of the service_info entry |
Return value
This function returns:
n QMI_NO_ERROR –If successful
n ERROR code –Otherwise
2.2.5 qmi_client_register_error_cb
这个函数用来注册一个回调函数,当服务终止或注销时会被调用。
Parameters
qmi_client_error_type
qmi_client_register_error_cb
(
qmi_client_type user_handle,
qmi_client_error_cb err_cb,
void *err_cb_data
);
→ | qmi_client_get_instance_id | Retrieves a list of services |
→ | user_handle | Opaque handle |
→ | err_cb | Pointer to callback function |
→ | err_cb_data | User data |
Return value
This function returns:
n QMI_NO_ERROR –If successful
n ERROR code –Otherwise
2.3消息发送 APIs
2.3.1异步消息
2.3.1.1 qmi_client_send_raw_msg_async
这个函数功能是发送一个异步消息给服务,调用者必须在调用之前对消息进行编码。注意在这个函数里,req_buf必须足够长来容纳消息和Qmux协议头。
Parameters
extern qmi_client_error_type
qmi_client_send_raw_msg_async
(
qmi_client_type user_handle,
unsigned int msg_id,
void *req_buf,
unsigned int req_buf_len,
void *resp_buf,
unsigned int resp_buf_len
qmi_client_async_rsp_cb *resp_cb,
void *resp_cb_data
qmi_txn_handle *txn_handle
);
→ | qmi_client_send_raw_msg_async | Sends asynchronous messages to the service |
→ | user_handle | Handle used by the infrastructure to identify the different clients |
→ | msg_id | Message ID |
→ | req_buf | Pointer to the request |
→ | req_buf_len | Length of the request |
→ | resp_buf | Pointer to where the response will be stored |
→ | resp_buf_len | Length of the response buffer |
→ | resp_cb | Callback function to handle the response |
→ | resp_cb_data | Callback user data |
← | txn_handle | Handle used to identify the transaction |
Return value
This function returns:
n QMI_NO_ERR – Sets transaction handle on success
n Error code – Otherwise
2.3.1.2 qmi_client_send_msg_async
这个函数功能是发送一个异步消息给服务,这个函数自己会处理消息的编解码。
Parameters
extern qmi_client_error_type
qmi_client_send_msg_async
(
qmi_client_type user_handle,
unsigned int msg_id,
void *req_c_struct,
unsigned int req_c_struct_len,
void *resp_c_struct,
unsigned int resp_c_struct_len
qmi_client_recv_msg_async_cb resp_cb,
void *resp_cb_data
qmi_txn_handle *txn_handle
);
→ | qmi_client_send_msg_async | Sends asynchronous messages to the service |
→ | user_handle | Indicates user handle |
→ | msg_id | Message ID |
→ | req_c_struct | Pointer to the request |
→ | req_c_struct_len | Length of the request |
→ | resp_c_struct | Pointer to where the response will be stored |
→ | resp_c_struct_len | Length of the response buffer |
→ | resp_cb | Callback function to handle the response |
→ | resp_cb_data | Callback user data |
← | txn_handle | Handle used to identify the transaction |
Return value
This function returns:
n QMI_NO_ERR –Sets transaction handle on success
n Error code – Otherwise
2.3.1.3 qmi_client_delete_async_txn
这个函数用来取消一个异步传输。
Parameters
extern qmi_client_error_type
qmi_client_delete_async_txn
(
qmi_client_type user_handle,
qmi_txn_handle async_txn_handle
);
→ | qmi_client_delete_async_txn | Cancels an async transaction |
→ | user_handle | Indicates a client handle user handle |
→ | async_txn_handle | Sends handle async |
Return value
This function returns:
n qmi_client_send_msg_async –async_txn_handle is returned bythefunction
n QMI_NO_ERR –If successful
n Negative(负数) –Otherwise
当异步回应回调函数未返回之前,使用者应该意识到潜在的竞争条件
Users should be aware of the potential race condition where an asynchronous response may be in
the process of being handled by the users_rsp_cb callback up until this routine returns.
2.3.2 同步消息
2.3.2.1 qmi_client_send_raw_msg_sync
这个函数功能是发送一个同步消息给服务,调用者必须在调用之前对消息进行编码。注意在这个函数里,req_buf必须足够长来容纳消息和Qmux协议头。
Parameters
extern qmi_client_error_type
qmi_client_send_raw_msg_sync
(
qmi_client_type user_handle,
unsigned int msg_id,
void *req_buf,
unsigned int req_buf_len,
void *resp_buf,
unsigned int resp_buf_len,
unsigned int resp_buf_recv_len,
unsigned int timeout_msecs
);
→ | qmi_client_send_raw_msg_sync | Sends synchronous messages to the service |
→ | user_handle | Handle used by the infrastructure to identify different clients |
→ | msg_id | Message ID |
→ | req_buf | Pointer to the request |
→ | req_buf_len | Length of the request |
→ | resp_buf | Pointer to where the response will be stored |
→ | resp_buf_len | Length of the response buffer |
→ | resp_buf_recv_len | Length of the response received |
→ | timeout_msecs | Indicates timeout in milliseconds |
Return value
This function returns:
n QMI_NO_ERROR –If successful
n Error code – Otherwise
这个timeout_msecs参数毫秒单位指定超时时间. reply_buf 是回应缓冲区, reply_buf_len 是回应缓冲最大容量, reply_buf_received_len 是从服务接收的buffer大小。
2.3.2.2 qmi_client_send_msg_sync
这个函数功能是发送同步消息到服务,它提供消息编解码功能,使用者获取到解码的回应数据结构体。
Parameters
extern qmi_client_error_type
qmi_client_send_msg_sync
(
qmi_client_type user_handle,
unsigned int msg_id,
void *req_c_struct,
unsigned int req_c_struct_len,
void *resp_c_struct,
unsigned int resp_c_struct_len,
unsigned int resp_c_struct_recv_len,
unsigned int timeout_msecs
);
→ | qmi_client_send_msg_sync | Sends synchronous messages to the service |
→ | user_handle | Handle used by the infrastructure to identify different clients |
→ | msg_id | Message ID |
→ | req_c_struct | Pointer to the request |
→ | req_c_struct_len | Length of the request |
→ | resp_c_struct | Pointer to where the response will be stored |
→ | resp_c_struct_len | Length of the response buffer |
→ | resp_c_struct_recv_len | Length of the response received |
→ | timeout_msecs | Indicates timeout in milliseconds |
Return value
This function returns:
n QMI_NO_ERROR –If successful
n Error code – Otherwise
这个timeout_msecs参数毫秒单位指定超时时间. reply_buf 是回应缓冲区, reply_buf_len 是回应缓冲最大容量, reply_buf_received_len 是从服务接收的buffer大小。
2.4 释放连接
这个函数用来释放连接
Parameters
extern qmi_client_error_type
qmi_client_release
(
qmi_client_type user_handle,
);
→ | user_handle | Handle used by the infrastructure to identify different clients |
Return value
This function returns:
n QMI_NO_ERROR –If successful
n Error code – Otherwise
2.5 编解码APIs
2.5.1 qmi_client_message_encode
这个函数功能是对QMI 消息体进行编码(c数据格式->传输数据格式)
Parameters
extern qmi_client_error_type
qmi_client_message_encode
(
qmi_client_type user_handle,
qmi_idl_type_of_message_type req_resp_ind,
unsigned int message_id,
const void *p_src,
unsigned int src_len,
void *p_dst,
unsigned int dst_len,
unsigned int *dst_encoded_len
);
→ | qmi_client_message_encode | Encodes C structures to QMI wire format |
→ | user_handle | Handle used by the infrastructure to identify different clients |
→ | req_resp_ind | Type of message: request, response, or indication |
→ | message_id | Message ID |
→ | p_src | Pointer to C structure containing message data |
→ | src_len | Length of p_src C structure in bytes |
← | p_dst | Pointer to the beginning of the first TLV in message |
→ | dst_len | Length of p_dst buffer in bytes |
← | dst_encoded_len | Pointer to the return value, the length of the encoded message |
Return value
This function returns:
n QMI_NO_ERROR –If successful
n Error code – Otherwise
2.5.2 qmi_client_message_decode
这个函数功能是对QMI 消息体进行解码(传输数据格式->c数据格式)
Parameters
extern qmi_client_error_type
qmi_client_message_decode
(
qmi_client_type user_handle,
qmi_idl_type_of_message_type req_resp_ind,
unsigned int message_id,
const void *p_src,
unsigned int src_len,
void *p_dst,
unsigned int dst_len
);
→ | qmi_client_message_decode | Decodes QMI message into C structure |
→ | user_handle | Handle used by the infrastructure to identify different clients |
→ | req_resp_ind | Type of message – Request, response, or indication |
→ | message_id | Message ID |
→ | p_src | Pointer to the beginning of the first TLV in message |
→ | src_len | Length of p_src buffer in bytes |
← | p_dst | Pointer to C structure for decoded data |
→ | dst_len | Length of p_dst C structure in bytes |
Return value
This function returns:
n QMI_NO_ERROR –If successful
n Error code – Otherwise
3、操作描述
3.1调用流程
下面展示了对不同的客户端事件的基本调用过程。
3.1.1初始化一个客户端
3.1.2发送一个同步消息
3.1.3发送一个异步消息
两个文件提供给语音服务接口,它们是voice_service_v02.c 和voice_service_v02.h,它们由高通接口维护工具Interface Definition Language (.idl)自动生成,.idl 没有释放给顾客。相反高通从中取出自动生成APIs给顾客。
为了发送QMI_VOICE_DIAL_CALL_REQ请求,客户端需要以下本地参数:
voice_dial_call_req_msg_V02 voice_dial_call_req_msg;
/* DIAL message to send */
voice_dial_call_resp_msg_V02 voice_dial_call_resp_msg;
/* QMI response to DIAL message*/
qmi_client_handle voice_service_handle;
/* Assigned when service clientis initialized */
qmi_service_info service_info;
/* Set to a value that allows the client to connect to a particular service. */
3.3初始化QMI语音服务
这个部分提供一个注册QMI语音服务的示例;
err = qmi_get_service_list(voice_get_service_object_v02(),&service_info,
&num_entries,&num_services);
err = qmi_client_init (&service_info, voice_get_service_object_v02(),
voice_indication_callback, &voice_indication_info, &os_params,
&voice_service_handle );
n voice_indication_callback – 这个回调函数原型定义在2.1.3
n voice_indication_info –Optional pointer to whatever the client wants; it is returned in each
call to the voice_indication_callback() asthe parameter user_ind_cb_data.
n os_params – OS-specific parameters;it can be a pointer to an event object, or signal mask
and TCB.
n voice_service_handle – An opaque handle to the newly initialized service returned by
qmi_client_init(); this handle is used by the client in all future interactions with the service.
3.4填入voice_service_v02.h中定义的c数据结构
typedef struct{
/* Mandatory*/
/*Calling number */
char calling_number[NUMBER_MAX + 1];
/*Numberto be dialed in ASCII string */
/* Optional*/
/*Call type */
boolean call_type_valid;
/* Must be set to true if call_typeis being passed */
uint8_t call_type;
/*Call type
0x00 - VOICE (automatic selection)
0x08 - NON_STD_OTASP
0x09 - EMERGENCY
*/
}voice_dial_call_req_msg_V01; /* Message*/
客户端填入 voice_dial_call_req_msg 结构体成员的值然后发送。
3.5发送消息
err = qmi_client_send_msg_sync (
voice_service_handle,
QMI_VOICE_DIAL_CALL_REQ_V02,
&voice_dial_call_req_msg, sizeof(voice_dial_call_req_msg_V02),
&voice_dial_call_resp_msg, sizeof(voice_dial_call_resp_msg_V02),
&response_size_in_bytes,
MSG_TIMEOUT, /* in milliseconds, to block waitingfor response */
);