Sensor系列之SensorDaemon与DSPS端通信过程
本文导读:
SensorDaemon服务端流程解析
Qualcomm messaging Interface(QMI)消息定义概述
Sensor架构系列之dsps架构分析
之前的文章我们知道了SensorDaemon服务端的启动以及dsps的架构及主要组成模块,今天我们继续深入挖掘下SensorDaemon与dsps具体的通信构建过程。
首先回顾下,SensorDaemon的启动过程。
1.init.qcom.sh中配置调用start_sensors启动,配置settings文件;
2.call start sensors则我们的daemon进程main方法开始执行
3.初始化sensors,sns_init_once;
4.创建服务端socket,注册sns_main_notify_cb回调
5.启动线程监听服务端数据,一旦数据达到,遍历客户端 handle,将数据发到client端
那么SensorDaemon又是怎样与DSPS端通信的呢?我们跟进sns_init_once来一探究竟。
static void sns_init_once( void )
{
int i;
struct sigaction action;
sigset_t set;
static const struct init_ptrs
{
sns_init_fcn fcn;
const char * fcn_name;
} init_ptrs[] = SNS_INIT_FUNCTIONS;
static const struct opt_init_ptrs
{
sns_init_fcn fcn;
const char * fcn_name;
} opt_init_ptrs[] = SNS_INIT_OPT_FUNCTIONS;
/* Mask of SIGALRM for use by EM */
sigemptyset( &set );
sigaddset( &set, SIGALRM );
sigprocmask( SIG_SETMASK, &set, NULL );
/* Set up the fault handler */
action.sa_handler = sns_init_fault_hndlr;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
for( i = 1; i < NSIG ; i++ )
{
sigaction( i, &action, &old_action[i] );
}
(void)sem_init( &sns_init_sem, 0, 0 );
/* Call each module's init function */
for( i = 0; NULL != init_ptrs[i].fcn; i++ ) {
SNS_PRINTF_STRING_HIGH_1(SNS_DBG_MOD_APPS_INIT,
"initializing %s",
(intptr_t)init_ptrs[i].fcn_name);
sns_init_sns_err = init_ptrs[i].fcn();
if( SNS_SUCCESS != sns_init_sns_err ) {
SNS_PRINTF_STRING_ERROR_2(SNS_DBG_MOD_APPS_INIT,
"Error %d initializing %s",
sns_init_sns_err,
(intptr_t)init_ptrs[i].fcn_name);
return;
}
SNS_PRINTF_STRING_HIGH_1(SNS_DBG_MOD_APPS_INIT,
"Waiting for %s...",
(intptr_t)init_ptrs[i].fcn_name);
sem_wait( &sns_init_sem );
SNS_PRINTF_STRING_HIGH_1(SNS_DBG_MOD_APPS_INIT,
"Done waiting for %s",
(intptr_t)init_ptrs[i].fcn_name);
}
/* Call each module's optional init function */
for( i = 0; NULL != opt_init_ptrs[i].fcn; i++ ) {
SNS_PRINTF_STRING_HIGH_1(SNS_DBG_MOD_APPS_INIT,
"initializing %s",
(intptr_t)opt_init_ptrs[i].fcn_name);
sns_init_sns_err = opt_init_ptrs[i].fcn();
if( SNS_SUCCESS != sns_init_sns_err ) {
SNS_PRINTF_STRING_ERROR_2(SNS_DBG_MOD_APPS_INIT,
"Error %d initializing %s",
sns_init_sns_err,
(intptr_t)opt_init_ptrs[i].fcn_name);
sns_init_sns_err = SNS_SUCCESS;
continue;
}
SNS_PRINTF_STRING_HIGH_1(SNS_DBG_MOD_APPS_INIT,
"Waiting for %s...",
(intptr_t)opt_init_ptrs[i].fcn_name);
sem_wait( &sns_init_sem );
SNS_PRINTF_STRING_HIGH_1(SNS_DBG_MOD_APPS_INIT,
"Done waiting for %s",
(intptr_t)opt_init_ptrs[i].fcn_name);
}
(void)sem_destroy( &sns_init_sem );
SNS_PRINTF_STRING_HIGH_0(SNS_DBG_MOD_APPS_INIT,
"All modules initializied" );
}
之前也提到过,这个方法的主体部分就是通过定义的init_ptrs以及opt_init_ptrs指向的多个init func依次调用。
我们从log来看看这些fuction的初始化顺序。
[ 01-03 04:39:11.125 713: 713 I/] main, sensordaemon started.
[ 01-03 04:39:11.125 713: 713 I/] sensor1_init, huilin, sns_acm.c
01-03 04:39:11.125 E/Sensors: sns_debug_set_dbg_str_mask: Setting log level to 0
01-03 04:39:11.132 I/Sensors: sns_init_la.c(216):Waiting for sns_debug_test_init1...
01-03 04:39:11.132 I/Sensors: sns_init_la.c(220):Done waiting for sns_debug_test_init1
01-03 04:39:11.132 I/Sensors: sns_init_la.c(203):initializing sns_pwr_init
01-03 04:39:11.134 I/Sensors: sns_pwr.c(332):releasing wakelock
01-03 04:39:11.134 I/Sensors: sns_pwr.c(338):sns_pwr_wake_unlock: wakeunlock write error: -1, 22
01-03 04:39:11.134 I/Sensors: sns_pwr.c(332):releasing wakelock
01-03 04:39:11.134 I/Sensors: sns_pwr.c(338):sns_pwr_wake_unlock: wakeunlock write error: -1, 22
01-03 04:39:11.134 I/Sensors: sns_init_la.c(216):Waiting for sns_pwr_init...
01-03 04:39:11.134 I/Sensors: sns_init_la.c(220):Done waiting for sns_pwr_init
01-03 04:39:11.134 I/Sensors: sns_init_la.c(203):initializing sns_em_init
01-03 04:39:11.134 I/Sensors: sns_init_la.c(216):Waiting for sns_em_init...
01-03 04:39:11.135 I/Sensors: sns_init_la.c(220):Done waiting for sns_em_init
01-03 04:39:11.135 I/Sensors: sns_init_la.c(203):initializing sns_reg_init
01-03 04:39:11.137 I/Sensors: sns_init_la.c(216):Waiting for sns_reg_init...
01-03 04:39:11.654 I/Sensors: sns_init_la.c(220):Done waiting for sns_reg_init
01-03 04:39:11.654 I/Sensors: sns_init_la.c(203):initializing sns_time_init
01-03 04:39:11.657 I/Sensors: sns_init_la.c(216):Waiting for sns_time_init...
01-03 04:39:11.660 I/Sensors: sns_init_la.c(220):Done waiting for sns_time_init
01-03 04:39:11.660 I/Sensors: sns_init_la.c(203):initializing sns_sam_init
01-03 04:39:11.660 I/Sensors: sns_init_la.c(216):Waiting for sns_sam_init...
01-03 04:39:11.819 D/Sensors: sns_sam.c(4745):SAM Started.....
01-03 04:39:11.820 I/Sensors: sns_init_la.c(220):Done waiting for sns_sam_init
01-03 04:39:11.820 I/Sensors: sns_init_la.c(203):initializing sns_file_init
01-03 04:39:11.821 D/Sensors: sns_file.c(373):sns_file_init
01-03 04:39:11.832 W/XTCC-5.1.0.8: [CCC-Main] wifi: 1, ap cell: 0, modem cell: 1, waa: 0, sstp: 0
01-03 04:39:11.865 E/XTCC-5.1.0.8: [StorageMgr] init tile_folder = /data/misc/location/xtwifi
01-03 04:39:11.866 I/Sensors: sns_init_la.c(216):Waiting for sns_file_init...
01-03 04:39:11.875 I/Sensors: sns_init_la.c(220):Done waiting for sns_file_init
01-03 04:39:11.875 I/Sensors: sns_init_la.c(203):initializing sns_acm_init
01-03 04:39:13.969 I/Sensors: sns_init_la.c(216):Waiting for sns_acm_init...
01-03 04:39:13.969 I/Sensors: sns_pwr.c(650):sns_pwr_off: vote mask 0x1, g_vote_mask 0x0, fd: -1
01-03 04:39:13.969 D/Sensors: sns_acm.c(1355):Initialization complete
01-03 04:39:13.969 I/Sensors: sns_init_la.c(220):Done waiting for sns_acm_init
01-03 04:39:13.969 I/Sensors: sns_init_la.c(227):initializing sns_debug_test_init2
01-03 04:39:13.970 D/Sensors: sns_debug_main.c(861):Init: In DIAG_Debug_Test_Init function!
01-03 04:39:13.971 D/Sensors: sns_debug_main.c(917):Sensors Diag Init:Can create EM timer object
01-03 04:39:13.971 D/Sensors: sns_debug_main.c(349):SNS DEBUG thread started
01-03 04:39:13.971 D/Sensors: sns_debug_main.c(929):Sensors DIAG Init: Initialization complete
01-03 04:39:13.971 I/Sensors: sns_init_la.c(240):Waiting for sns_debug_test_init2...
01-03 04:39:13.971 E/Sensors: sns_debug_main.c(544):Debug Config File missing in EFS!
01-03 04:39:13.971 D/Sensors: sns_debug_mr.c(401):DEBUG VERSION RESP: Ver: 1 Max ID:3
01-03 04:39:13.972 I/Sensors: sns_init_la.c(244):Done waiting for sns_debug_test_init2
01-03 04:39:13.972 I/Sensors: sns_init_la.c(249):All modules initializied
01-03 04:39:13.975 I/Sensors: sns_main.c(227):enabled=true
01-03 04:39:13.975 D/Sensors: sns_main.c(1689):Start thread to monitor ADSP restart
01-03 04:39:13.975 D/Sensors: sns_main.c(1602):Register for SMRG service
01-03 04:39:13.975 D/Sensors: sns_main.c(1620):Waiting for SMGR service up
01-03 04:39:13.975 D/Sensors: sns_main.c(1631):Get SMGR servive info
01-03 04:39:13.975 D/Sensors: sns_main.c(1642):Initialize client for SMRG
01-03 04:39:13.976 D/Sensors: sns_main.c(1653):Register for SMGR error notification
01-03 04:39:14.906 I/libsensor1: sensor1_init_once: Setting log level to 0
01-03 04:39:14.906 E/mm-camera-isp2: isp_module_start_session:361 num_session_opened 1
01-03 04:39:14.906 D/libsensor1: sensor1_init_once
很显然,就是我们在sns_init.h中函数指针声明的顺序呀。
/* LA-based Builds */
# define SNS_INIT_FUNCTIONS \
{ { sns_memmgr_init, "sns_memmgr_init" }, \ // 用于内存管理
{ sns_debug_test_init1, "sns_debug_test_init1" }, \ // 调试模块,得益于此,我么你才能看到上面的龙输出
{ sns_pwr_init, "sns_pwr_init" }, \ // power管理模块
{ sns_em_init, "sns_em_init" }, \ // event manager
{ sns_reg_init, "sns_reg_init" }, \ // Sensors Registry,会创建一个线程处理寄存器数据sns.reg
{ sns_time_init, "sns_time_init" }, \ // 时间管理器
{ sns_sam_init, "sns_sam_init" }, \ // SAM (sensor algorithm manager)
{ sns_file_init, "sns_file_init" }, \ // 文件管理器,处理open,write,close等操作并管理打开的文件列表
{ sns_acm_init, "sns_acm_init" }, \ // application client manager, 应用客户端管理器,直接与sensor client交互.
{ NULL, ""} }
# define SNS_INIT_OPT_FUNCTIONS \
{ { sns_debug_test_init2, "sns_debug_test_init2" }, \ // 第二个debug模块入口
{ NULL, ""} }
我们还是重点关注下重要模块ACM,先看其init方法:
sns_err_code_e
sns_acm_init( void )
{
sns_err_code_e error_code;
int32_t i;
uint8_t err;
int32_t max_clients = sns_acm_max_clients();
if( true == sns_acm_initialized ) {
return SNS_SUCCESS;
}
error_code = sns_em_create_timer_obj( sns_acm_timer_cb,
(void*)(intptr_t)SNS_ACM_TMR_WRITABLE,
SNS_EM_TIMER_TYPE_ONESHOT,
&sns_acm_writable_tmr_ptr);
if( SNS_SUCCESS != error_code ) {
SNS_PRINTF_STRING_FATAL_0( SNS_DBG_MOD_ACM,
"init: can't create EM timer object" );
return SNS_ERR_NOMEM;
}
sns_acm_flag_grp = sns_os_sigs_create( 0, &err );
if( sns_acm_flag_grp == NULL ) {
sns_em_delete_timer_obj( sns_acm_writable_tmr_ptr );
SNS_PRINTF_STRING_FATAL_0( SNS_DBG_MOD_ACM,
"init: can't create OS signal" );
return SNS_ERR_NOMEM;
}
for( i = 0; i < max_clients; i++ ) {
sns_acm_init_client_handle( sns_acm_client_handle( i ) );
}
sns_acm_db_mutex = sns_os_mutex_create( SNS_MODULE_PRI_ACM_MUTEX,
&err );
if( 0 != err ) {
SNS_PRINTF_STRING_FATAL_0( SNS_DBG_MOD_ACM,
"init: can't create db mutex" );
sns_em_delete_timer_obj( sns_acm_writable_tmr_ptr );
return SNS_ERR_FAILED;
}
sns_acm_log_mutex = sns_os_mutex_create( SNS_MODULE_PRI_ACM_MUTEX,
&err );
if( 0 != err ) {
SNS_PRINTF_STRING_FATAL_0( SNS_DBG_MOD_ACM,
"init: can't create log mutex" );
sns_em_delete_timer_obj( sns_acm_writable_tmr_ptr );
sns_os_mutex_del( sns_acm_db_mutex, 0, &err );
return SNS_ERR_FAILED;
}
error_code = sns_acm_mr_init( sns_acm_flag_grp, SNS_ACM_SMR_RX_FLAG );
if( SNS_SUCCESS != error_code ) {
sns_em_delete_timer_obj( sns_acm_writable_tmr_ptr );
sns_os_mutex_del( sns_acm_db_mutex, 0, &err );
sns_os_mutex_del( sns_acm_log_mutex, 0, &err );
SNS_PRINTF_STRING_FATAL_0( SNS_DBG_MOD_ACM,
"init: can't register with SMR" );
return SNS_ERR_FAILED;
}
error_code = sns_os_task_create( sns_acm_rx_thread,
NULL,
NULL,
SNS_MODULE_PRI_ACM );
if( 0 != error_code ) {
SNS_PRINTF_STRING_FATAL_0( SNS_DBG_MOD_ACM,
"init: can't create thread" );
sns_em_delete_timer_obj( sns_acm_writable_tmr_ptr );
sns_os_mutex_del( sns_acm_db_mutex, 0, &err );
sns_os_mutex_del( sns_acm_log_mutex, 0, &err );
// TODO: it is not possible to deregister from SMR
return SNS_ERR_FAILED;
}
sns_acm_initialized = true;
return SNS_SUCCESS;
}
这里的一个重要方调用时sns_acm_mr_init,这个方法用于给sensor1的服务端请求QMI的信息,mr指的是message router的东西。
sns_err_code_e
sns_acm_mr_init( OS_FLAG_GRP *sig_grp_ptr, OS_FLAGS sig_flag )
{
UNREFERENCED_PARAMETER( sig_grp_ptr );
UNREFERENCED_PARAMETER( sig_flag );
uint32_t i;
uint8_t os_err = 0;
pthread_t thread_id[SNS_ACM_MAX_SVC_ID];
pthread_attr_t thread_attr;
sns_acm_mr_msg_queue_first = NULL;
sns_acm_mr_msg_queue_last = NULL;
sns_acm_mr_queue_mutex = sns_os_mutex_create( SNS_MODULE_PRI_APPS_ACM_MUTEX, &os_err );
if( 0 != os_err )
{
SNS_PRINTF_STRING_FATAL_1( SNS_DBG_MOD_ACM, "Cannot create mutex %i", os_err );
return SNS_ERR_FAILED;
}
if( -1 == sem_init( &sns_acm_mr_queue_sem, 0, SNS_ACM_MAX_MSG_QUEUE ) )
{
SNS_PRINTF_STRING_FATAL_1( SNS_DBG_MOD_ACM, "Cannot create semaphore %i", errno );
return SNS_ERR_FAILED;
}
pthread_attr_init( &thread_attr );
pthread_attr_setdetachstate( &thread_attr, PTHREAD_CREATE_JOINABLE );
for( i = 0; i < SNS_ACM_MAX_SVC_ID; i++ )
{
uint32_t *svc_id = SNS_OS_MALLOC( SNS_MODULE_ACM, sizeof(uint32_t) );
if( NULL == svc_id )
{
SNS_PRINTF_STRING_ERROR_0( SNS_DBG_MOD_ACM, "Malloc Error" );
return SNS_ERR_FAILED;
}
else
{
*svc_id = i;
pthread_create( &thread_id[ i ], &thread_attr, sns_acm_mr_client_init, svc_id );
}
}
pthread_attr_destroy( &thread_attr );
for( i = 0; i < SNS_ACM_MAX_SVC_ID; i++ )
{
pthread_join( thread_id[ i ], NULL );
}
return SNS_SUCCESS;
}
for循环中执行60次,构建60个mr client:pthread_create( &thread_id[ i ], &thread_attr, sns_acm_mr_client_init, svc_id );
我们跟进看一下client的初始化流程。
void* sns_acm_mr_client_init( void *svc_id )
{
sns_err_code_e sns_err;
uint32_t j,
svc_num = *((uint32_t *)svc_id);
int timeout_ms = (svc_num == 0) ? 10000 : 2000;
qmi_idl_service_object_type service;
service = sns_smr_get_svc_obj( svc_num );
if( service == NULL )
{
SNS_PRINTF_STRING_HIGH_1( SNS_DBG_MOD_ACM, "Service %i is NULL", svc_num ); // 如果得到的service为null,则并不会去请求该server的info
}
else
{
SNS_PRINTF_STRING_LOW_1( SNS_DBG_MOD_ACM, "Initializing connection for svc %i", svc_num );
sns_err = sns_smr_get_qmi_service_info( &service, timeout_ms, &service_info[ svc_num ] ); // 获取server端对应的info
if( SNS_SUCCESS == sns_err )
{
SNS_PRINTF_STRING_LOW_1( SNS_DBG_MOD_ACM, "Retrieved info for service %i", svc_num );
service_enabled[ svc_num ] = true;
}
else
{
SNS_PRINTF_STRING_ERROR_1( SNS_DBG_MOD_ACM, "Error getting info for service %i", svc_num );
service_enabled[ svc_num ] = false;
}
for( j = 0; j < SNS_ACM_MAX_CLIENTS; j++ )
{
external_clients[ j ].cb_data[ svc_num ] = NULL;
}
}
SNS_OS_FREE( svc_id );
return NULL;
}
sns_err_code_e sns_smr_get_qmi_service_info (
qmi_idl_service_object_type const *svc_obj,
uint32_t timeout_ms, qmi_service_info *svc_info)
{
qmi_client_type notifier_handle;
qmi_client_error_type qmi_err;
qmi_cci_os_signal_type os_params_tmp;
qmi_service_info svc_info_array[ SMR_MAX_QMI_SVC_CNT ];
qmi_service_instance instance_id;
sns_err_code_e rv = SNS_SUCCESS;
uint32_t svc_num = -1,
num_entries = SMR_MAX_QMI_SVC_CNT,
num_services,
i,
max_iid,
max_idx;
qmi_idl_get_service_id( *svc_obj, &svc_num );
#if defined(SNS_DSPS_BUILD) || defined(SNS_PCSIM) || defined(QDSP6)
os_params_tmp.ext_signal = NULL;
os_params_tmp.sig = SNS_SMR_QMI_CLI_SIG;
os_params_tmp.timer_sig = SNS_SMR_QMI_TIMER_SIG;
#endif
qmi_err = qmi_client_notifier_init( *svc_obj, &os_params_tmp, ¬ifier_handle ); //
if( QMI_NO_ERR != qmi_err )
{
SNS_PRINTF_STRING_ERROR_1( SMR_DBG_MODULE_ID,
"qmi_client_notifier_init error %i", qmi_err );
rv = SNS_ERR_FAILED;
}
else
{
QMI_CCI_OS_SIGNAL_WAIT( &os_params_tmp, timeout_ms );
QMI_CCI_OS_SIGNAL_CLEAR( &os_params_tmp );
if( os_params_tmp.timed_out )
{
SNS_PRINTF_STRING_ERROR_2( SMR_DBG_MODULE_ID,
"Unable to initialize service %d with QCCI, timed out (%d ms)",
svc_num, timeout_ms );
rv = SNS_ERR_FAILED;
}
else if( QMI_NO_ERR != ( qmi_err =
qmi_client_get_service_list( *svc_obj, svc_info_array,
&num_entries, &num_services ) ) )
{
SNS_PRINTF_STRING_ERROR_1( SMR_DBG_MODULE_ID,
"Unable to initialize service %d with QCCI",
svc_num );
rv = SNS_ERR_FAILED;
}
else if( num_entries > 0 )
{
if( num_services != num_entries )
{
SNS_PRINTF_STRING_LOW_2( SMR_DBG_MODULE_ID,
"Too many service instances found (%i / %i)", num_services, num_entries );
}
for( i = 0, max_idx = 0, max_iid = 0; i < num_entries; i++ )
{
if( QMI_NO_ERR == ( qmi_err =
qmi_client_get_instance_id( &svc_info_array[ i ], &instance_id) ))
{
// Choose the service with the largest instance ID
if( max_iid < instance_id )
{
max_idx = i;
max_iid = instance_id;
}
}
else
{
SNS_PRINTF_STRING_MEDIUM_2( SMR_DBG_MODULE_ID,
"Instance ID not found for service %i (%i)",
svc_num, qmi_err );
}
}
*svc_info = svc_info_array[ max_idx ];
}
else
{
SNS_PRINTF_STRING_ERROR_2( SMR_DBG_MODULE_ID,
"No services found for num %i (%i)",
svc_num, qmi_err );
rv = SNS_ERR_FAILED;
}
qmi_client_release( notifier_handle );
}
return rv;
}
上面的流程主要是微Application Client Manager创建QCCI的客户端,这里就可以看到QCCI的标准API了,其实这些API在之前的博文中我已经提提过,这里在详细说一下。
QCCI API讲解
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
)
该方法通过向指定的service obj注册一个notifier,一旦对应的服务器成功注册且用于支持对应的service obj,会发送一个sig信号或者以event的方式放置在os_params中。
qmi_client_get_service_list
(
qmi_idl_service_object_type service_obj,
qmi_service_info *service_info_array,
unsigned int *num_entries,
unsigned int *num_services
)
用于获取服务端的地址信息以访问该服务,如果对应的服务器列表中有匹配service type的类型,那么将会把该服务的信息填充到service_info_array结构体中,该service信息将会传给qmi_client_init方法,这样客户端就可以操作该service以获取相应的功能了。
extern qmi_client_error_type
qmi_client_init
(
const char *dev_id,
qmi_idl_service_object_type service_obj,/* Defined in the Library header file */
qmi_client_ind_cb ind_cb,
void *ind_cb_data,
qmi_client_type *user_handle
)
该方法用于客户端连接服务器端的初始化工作。
下图展示了client端使用QCCI API初始化的流程
另一方面, sns_acm_init方法后有call sns_monitor_adsp_restart方法,该方法中启动了一个线程来进行连接SMGR服务的初始化工作。
static int
sns_monitor_adsp_restart()
{
pthread_t thread_id;
pthread_attr_t attr;
SNS_PRINTF_STRING_MEDIUM_0( SNS_DBG_MOD_APPS_MAIN,
"Start thread to monitor ADSP restart");
pthread_attr_init( &attr );
pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
pthread_create( &thread_id, &attr,
sns_handle_adsp_restart, NULL );
pthread_attr_destroy( &attr );
return 0;
}
static void*
sns_handle_adsp_restart( void *unused )
{
qmi_client_error_type qmi_err;
qmi_service_info service_info;
qmi_client_type smgr_client;
qmi_idl_service_object_type service;
qmi_client_type notifier_handle;
qmi_cci_os_signal_type os_params;
UNREFERENCED_PARAMETER(unused);
SNS_PRINTF_STRING_MEDIUM_0( SNS_DBG_MOD_APPS_MAIN,
"Register for SMRG service");
service = sns_smr_get_svc_obj( SNS_SMGR_SVC_ID_V01 );
if( service == NULL )
{
SNS_PRINTF_STRING_ERROR_0( SNS_DBG_MOD_APPS_MAIN,
"Error: SMGR service is NULL" );
return (void*)0;
}
qmi_err = qmi_client_notifier_init( service, &os_params, ¬ifier_handle );
if( QMI_NO_ERR != qmi_err )
{
SNS_PRINTF_STRING_ERROR_1( SNS_DBG_MOD_APPS_MAIN,
"qmi_client_notifier_init for SMGR failed, err=%d",
qmi_err );
return (void*)0;
}
SNS_PRINTF_STRING_MEDIUM_0( SNS_DBG_MOD_APPS_MAIN,
"Waiting for SMGR service up" );
QMI_CCI_OS_SIGNAL_WAIT( &os_params, SNS_SMGR_SVC_TIMEOUT_MS );
if( QMI_CCI_OS_SIGNAL_TIMED_OUT(&os_params) )
{
SNS_PRINTF_STRING_ERROR_0( SNS_DBG_MOD_APPS_MAIN,
"Timeout waiting for SMGR service. Exit sensors daemon!" );
sns_main_exit();
}
else
{
SNS_PRINTF_STRING_MEDIUM_0( SNS_DBG_MOD_APPS_MAIN,
"Get SMGR servive info" );
qmi_err = qmi_client_get_any_service( service, &service_info );
if( qmi_err != QMI_NO_ERR )
{
SNS_PRINTF_STRING_ERROR_1( SNS_DBG_MOD_APPS_MAIN,
"qmi_client_get_any_service for SMGR failed, err=%d",
qmi_err );
}
else
{
SNS_PRINTF_STRING_MEDIUM_0( SNS_DBG_MOD_APPS_MAIN,
"Initialize client for SMRG" );
qmi_err = qmi_client_init( &service_info, service, NULL, NULL, NULL, &smgr_client );
if( QMI_NO_ERR != qmi_err )
{
SNS_PRINTF_STRING_ERROR_1( SNS_DBG_MOD_APPS_MAIN,
"qmi_client_init for SMGR failed, err=%d",
qmi_err);
}
else
{
SNS_PRINTF_STRING_MEDIUM_0( SNS_DBG_MOD_APPS_MAIN,
"Register for SMGR error notification" );
qmi_err = qmi_client_register_error_cb( smgr_client, sns_smgr_svc_error_cb, NULL );
if( QMI_NO_ERR != qmi_err )
{
SNS_PRINTF_STRING_ERROR_1( SNS_DBG_MOD_APPS_MAIN,
"qmi_client_register_error_cb for SMGR failed, err=%d",
qmi_err );
qmi_client_release( smgr_client );
}
}
}
}
qmi_client_release( notifier_handle );
return (void*)0;
}
这里通过sns_smr_get_svc_obj获取的是我们的sensor manager服务。
Sensor manager. */
#define SNS_SMGR_SVC_ID_V01 0
所以这部分流程则是初始化的SMGR的客户端部分。
#define SNS_MODULE_APPS_PP (SNS_MODULE_APPS + 00) /* Power Proxy */
#define SNS_MODULE_APPS_SAM (SNS_MODULE_APPS + 01) /* Legacy Sensor Algorithm Manager */
#define SNS_MODULE_APPS_SMR (SNS_MODULE_APPS + 02) /* Sensors Message Router */
#define SNS_MODULE_APPS_DIAG (SNS_MODULE_APPS + 03) /* Sensors diag agent module */
#define SNS_MODULE_APPS_ACM (SNS_MODULE_APPS + 04) /* Sensors application client module */
#define SNS_MODULE_APPS_REG (SNS_MODULE_APPS + 05) /* Sensors Registry Module */
#define SNS_MODULE_APPS_EM (SNS_MODULE_APPS + 06) /* Sensors Event Manager Module */
#define SNS_MODULE_APPS_INIT (SNS_MODULE_APPS + 07) /* Initialization module */
#define SNS_MODULE_APPS_PWR (SNS_MODULE_APPS + 8) /* Power module */
#define SNS_MODULE_APPS_TIME (SNS_MODULE_APPS + 9) /* Sensors Time Module */
#define SNS_MODULE_APPS_SCM (SNS_MODULE_APPS + 10) /* Sensors Calibration Module on Apps */
#define SNS_MODULE_APPS_FILE (SNS_MODULE_APPS + 11) /* Sensors File internal module */
#define SNS_MODULE_APPS_SAM2 (SNS_MODULE_APPS + 12) /* Updated SAM Framework */
如上定义的module,都会有对应的client端创建。
一旦这些client成功创建,便可以通过QMI的标准API向服务端发送消息了。
qmi_client_send_msg_sync
qmi_client_send_msg_async
qmi_client_send_raw_msg_sync
qmi_client_send_raw_msg_async
client端发送同步消息的流程如下:
发送异步消息:
这些所谓的服务都在modem端有相应的处理函数,关于server端(adsp)部分,我们会在后续文章中继续分析,欢迎关注。
后面的文章我们将深入driver层,看看sensor driver的具体实现了,现在我们串一下SensorContext到SensorDaemon的数据流程图,QCCI部分在上面的流程图里已经给出,请各位参考:
凝视美女,有益健康,大家休息一下。