android系统如何为第三方应用添加drx api(二)
由于项目比较忙,drx-api后续耽搁至今,向有需要的各位大佬致歉。
前面我们说到java层通过指令调用到 c,c++的函数,这里我们需要在两个模块去定义我们需要的函数,即 qcril 和 qcril-hal层,其实两个地方需要定义的方法一样,只是有可能都会用到,一开始我只是加了其中一个地方,drx方法并没有生效,然后两个都加上,才能成功调用,这里大家可以试试只加其中一个地方,验证是否能够实现你需要的功能。
一、我们先来看看 qcril 的代码:
同样需要定义指令代码,在“vendor/qcom/proprietary/qcril/qcril_qmi/qcrili.h ”qcril_evt_e_type枚举中添加如下代码:
QCRIL_EVT_HOOK_SET_DRX = QCRIL_EVT_HOOK_BASE + 203,
QCRIL_EVT_HOOK_GET_DRX = QCRIL_EVT_HOOK_BASE + 204,
注册RIL_REQUESTS,“vendor/qcom/proprietary/qcril/qcril_qmi/qcril.c”中添加如下代码:
QCRIL_EVT_HOOK_SET_DRX就是我们上面定义的指令,qcril_qmi_nas2_set_drx是我们接下来需要定义的函数,这里相当于就是一个函数地址映射。
“vendor/qcom/proprietary/qcril/qcril_qmi/qcril_qmi_nas2.h“”声明我们需要的drx的set和get方法:
params_ptr指针接收java传过来的参数,ret_ptr存放返回的结果,具体类型可自己在源码中查看。
void qcril_qmi_nas2_get_drx(
const qcril_request_params_type *const params_ptr,
qcril_request_return_type *const ret_ptr );
void qcril_qmi_nas2_set_drx(
const qcril_request_params_type *const params_ptr,
qcril_request_return_type *const ret_ptr );
接下来我们具体看看“vendor/qcom/proprietary/qcril/qcril_qmi/qcril_qmi_nas2.c”中定义的具体方法,敲黑板了。
大致思路是:取出java层传过来的参数(ptw = (int *)params_ptr->data)并做判断,获取nas服务client,然后通过client发送消息给bp,将我们要做的操作封装到请求体,把返回结果存放到返回体,然后将返回体send到java层;整个过程是个异步操作,所以我们会定义超时时间。
获取nas-client drx_client = qcril_qmi_client_get_user_handle (QCRIL_QMI_CLIENT_NAS);
定义请求体和返回体并封装
nas_set_drx_req_msg_v01 req_msg;//请求体 req_msg.drx = NAS_DRX_CN6_T32_V01;
nas_set_drx_resp_msg_v01 rsp_msg;//返回体
可以设置的drx值是固定的,在源码中有一个枚举定义,“vendor/qcom/proprietary/qcril-qmi-services-headers/network_access_service_v01.h”,所以我们自己做好对应便可。
发送消息 ret_val = qmi_client_send_msg_sync(drx_client,
QMI_NAS_SET_DRX_REQ_MSG_V01,
&req_msg,
sizeof(req_msg),
&rsp_msg,
sizeof(rsp_msg),
QCRIL_QMI_SYNC_REQ_UNRESTRICTED_TIMEOUT);
QMI_NAS_SET_DRX_REQ_MSG_V01消息指令在“vendor/qcom/proprietary/qcril-qmi-services-headers/network_access_service_v01.h”中有定义,如下:
我们只需要SET_DRX和GET_DRX这两个指令就可以完成我们需要的功能。
然后便是从返回结果中取出返回体,做处理后发送给java,如下:
qcril_default_request_resp_params( QCRIL_DEFAULT_INSTANCE_ID, params_ptr->t, params_ptr->event_id, ril_req_res, &resp );
qcril_send_request_response( &resp );
便于自行理解,我将整个方法贴出来,由于get方法和set类似,就不重复贴出。
void qcril_qmi_nas2_set_drx(const qcril_request_params_type *const params_ptr,
qcril_request_return_type *const ret_ptr)
{
QCRIL_LOG_DEBUG ("qcril_qmi_nas2_set_drx() ---- ret = ");
qmi_client_error_type ret_val = QMI_NO_ERR;
qcril_request_resp_params_type resp;
int* ptw;
QCRIL_NOTUSED( ret_ptr );
qmi_client_type drx_client = qcril_qmi_client_get_user_handle (QCRIL_QMI_CLIENT_NAS);
nas_set_drx_req_msg_v01 req_msg;
nas_set_drx_resp_msg_v01 rsp_msg;
RIL_Errno ril_req_res = RIL_E_GENERIC_FAILURE;//设置返回状态
if(NULL == params_ptr->data){
QCRIL_LOG_DEBUG ("qcril_qmi_nas2_set_drx() ---- params_ptr->data == null");
}
if( params_ptr->datalen > QMI_RIL_ZERO){
QCRIL_LOG_DEBUG ("qcril_qmi_nas2_set_drx() ---- params_ptr->datalen >QMI_RIL_ZERO");
}
if(NULL == drx_client){
QCRIL_LOG_DEBUG ("qcril_qmi_nas2_set_drx() ----drx_client == null");
}
if ( NULL != params_ptr->data && params_ptr->datalen > QMI_RIL_ZERO && NULL != drx_client )
{
QCRIL_LOG_DEBUG ("qcril_qmi_nas2_set_drx() ---- big if");
ptw = (int *)params_ptr->data;
memset(&req_msg, 0, sizeof(req_msg));
memset(&rsp_msg, 0, sizeof(rsp_msg));
switch(*ptw)
{
case 0x06:
req_msg.drx = NAS_DRX_CN6_T32_V01;
break;
case 0x07:
req_msg.drx = NAS_DRX_CN7_T64_V01;
break;
case 0x08:
req_msg.drx = NAS_DRX_CN8_T128_V01;
break;
case 0x09:
req_msg.drx = NAS_DRX_CN9_T256_V01;
break;
default:
req_msg.drx = NAS_DRX_UNKNOWN_V01;
break;
}
ret_val = qmi_client_send_msg_sync(drx_client,
QMI_NAS_SET_DRX_REQ_MSG_V01,
&req_msg,
sizeof(req_msg),
&rsp_msg,
sizeof(rsp_msg),
QCRIL_QMI_SYNC_REQ_UNRESTRICTED_TIMEOUT);
QCRIL_LOG_DEBUG("qcril_qmi_nas2_set_drx() --drx=%d, ret = %d",req_msg.drx, ret_val);
if(ret_val == QMI_NO_ERR)
{
//drx_value set success
ril_req_res = RIL_E_SUCCESS;
QCRIL_LOG_DEBUG("qcril_qmi_nas2_set_drx() success! ");
} else{
ril_req_res = RIL_E_GENERIC_FAILURE;
QCRIL_LOG_DEBUG("qcril_qmi_nas2_set_drx() error ! result=%d", rsp_msg.resp.result);
QCRIL_LOG_DEBUG("qcril_qmi_nas2_set_drx() error ! error=%d", rsp_msg.resp.error);
}
}else{
QCRIL_LOG_DEBUG ("qcril_qmi_nas2_set_drx() ---- can`t enter big if");
}
// ** respond always
qcril_default_request_resp_params( QCRIL_DEFAULT_INSTANCE_ID, params_ptr->t, params_ptr->event_id, ril_req_res, &resp );
qcril_send_request_response( &resp );
}// qcril_qmi_nas2_set_drx
方便调试可以加日志打印查看,不过要打印qmi事件需要做配置,在“vendor/qcom/proprietary/qcril/qcril_qmi/qcril_log.c”-qcril_log_lookup_event_name方法中添加:
case QCRIL_EVT_HOOK_SET_DRX:
return "QCRIL_EVT_HOOK_SET_DRX";
case QCRIL_EVT_HOOK_GET_DRX:
return "QCRIL_EVT_HOOK_GET_DRX";
二、接下来便是qcril-hal:
vendor/qcom/proprietary/qcril-hal/qcril_qmi/oem_socket/qcril_qmi_oem_reqlist.h
vendor/qcom/proprietary/qcril-hal/qcril_qmi/oem_socket/qcril_qmi_oem_events.cc
vendor/qcom/proprietary/qcril-hal/qcril_qmi/oem_socket/qcril_qmi_oem_eventlist.h
vendor/qcom/proprietary/qcril-hal/modules/nas/src/qcril_qmi_nas2.cpp
#include "network_access_service_v01.h" |
get和set方法和上面保持一致
vendor/qcom/proprietary/qcril-hal/include/modules/nas/qcril_qmi_nas2.h
三、编译:
1、cd LINUX/android
2、source build/envsetup.sh
3、lunch
因为我们修改了framework,所以需要
make update-api,然后再进行全编一次,生成的framework jar在out\target\product下,这种方式需要集成jar包到app项目中才能使用,下一篇我们讲解如何生成系统jar通过反射的方式调用api
上一篇: 内核notifier机制应用