/*=========================================================================== FUNCTION: msg_q_unblock ===========================================================================*/ msq_q_err_type msg_q_unblock(void* msg_q_data) { if ( msg_q_data == NULL ) { LOC_LOGE("%s: Invalid msg_q_data parameter!\n", __FUNCTION__); return eMSG_Q_INVALID_HANDLE; } msg_q* p_msg_q = (msg_q*)msg_q_data; pthread_mutex_lock(&p_msg_q->list_mutex); if( p_msg_q->unblocked ) { LOC_LOGE("%s: Message queue has been unblocked.\n", __FUNCTION__); pthread_mutex_unlock(&p_msg_q->list_mutex); return eMSG_Q_UNAVAILABLE_RESOURCE; } LOC_LOGD("%s: Unblocking Message Queue\n", __FUNCTION__); /* Unblocking message queue */ p_msg_q->unblocked = 1; /* Allow all the waiters to wake up */ pthread_cond_broadcast(&p_msg_q->list_cond); pthread_mutex_unlock(&p_msg_q->list_mutex); LOC_LOGD("%s: Message Queue unblocked\n", __FUNCTION__); return eMSG_Q_SUCCESS; }
/** @brief Register sensor client with SLIM CORE Function sends message to slim daemon to initiate client registration with SLIM CORE @param z_Txn: Parameters for sensor client registration */ int SocketClientWrapper::ClientRegister(slim_OpenTxnStructType &z_Txn) { LOC_LOGD("%s:%d] Received client register", __func__, __LINE__); SocketClientOpenReq openRequest; memset(&openRequest, 0, sizeof(openRequest)); openRequest.msgHeader.msgId = eSLIM_SOCKET_CLIENT_MSG_ID_OPEN_REQ; openRequest.msgHeader.msgSize = sizeof(SocketClientOpenReq); openRequest.msgPayload = z_Txn; LOC_LOGD("%s:%d] sizeof(SocketClientOpenReq) is %d, sizeof(openRequest.msgHeader) is %d", __func__, __LINE__, sizeof(SocketClientOpenReq), sizeof(openRequest.msgHeader)); SocketClientWrapper::mCallbackFunction = openRequest.msgPayload.fn_Callback; LOC_LOGD("%s:%d] Received client register, p_Handle is %08X", __func__, __LINE__, z_Txn.p_Handle); LOC_LOGD("%s:%d] Received fn_Callback is %08X", __func__, __LINE__, openRequest.msgPayload.fn_Callback); // If socket_not_present or socket_not_connected, then error/warning if ( (SocketClientWrapper::mSocketFd < 0) ) { LOC_LOGE("%s[%d]: socket not present/connected\n", __func__, __LINE__); return -1; } if (write(SocketClientWrapper::mSocketFd, &openRequest, sizeof(openRequest)) < 0) { LOC_LOGE("%s[%d]: error writing on socket\n", __func__, __LINE__); return -1; } return 0; }
/** @brief Deregister sensor client with SLIM CORE Function sends message to slim daemon to initiate client de-registration with SLIM CORE @param z_Txn: Parameters for sensor client de-registration */ int SocketClientWrapper::ClientDeRegister(slim_GenericTxnStructType &z_Txn) { LOC_LOGD("%s:%d] Received client deregister", __func__, __LINE__); SocketClientCloseReq closeRequest; memset(&closeRequest, 0, sizeof(closeRequest)); closeRequest.msgHeader.msgId = eSLIM_SOCKET_CLIENT_MSG_ID_CLOSE_REQ; closeRequest.msgHeader.msgSize = sizeof(SocketClientCloseReq); closeRequest.msgPayload = z_Txn; // If socket_not_present or socket_not_connected, then error/warning if ( (SocketClientWrapper::mSocketFd < 0) ) { LOC_LOGE("%s[%d]: socket not present/connected\n", __func__, __LINE__); return -1; } if (write(SocketClientWrapper::mSocketFd, &closeRequest, sizeof(closeRequest)) < 0) { LOC_LOGE("%s[%d]: error writing on socket\n", __func__, __LINE__); return -1; } return 0; }
LocApiAdapter* LocApiAdapter::getLocApiAdapter(LocEng &locEng) { void* handle; LocApiAdapter* adapter = NULL; handle = dlopen ("libloc_api_v02.so", RTLD_NOW); if (!handle) { LOC_LOGE("%s: dlopen(libloc_api_v02.so) failed, trying to load libloc_api-rpc-qc.so", __FUNCTION__); LOC_LOGE("%s: %s", __FUNCTION__, dlerror()); handle = dlopen ("libloc_api-rpc-qc.so", RTLD_NOW); } else LOC_LOGI("%s: dlopen(libloc_api_v02.so) succeeded.", __FUNCTION__); if (!handle) { LOC_LOGE("%s: dlopen(libloc_api-rpc-qc.so) failed, constructing LocApiAdapter", __FUNCTION__); adapter = new LocApiAdapter(locEng); } else { getLocApiAdapter_t* getHandle = (getLocApiAdapter_t*)dlsym(handle, "_Z16getLocApiAdapterR6LocEng"); if (!getHandle) { LOC_LOGE("%s: dlsym(getLocApiAdapter) failed", __FUNCTION__); LOC_LOGE("%s: %s", __FUNCTION__, dlerror()); return NULL; } adapter = (*getHandle)(locEng); } return adapter; }
/** @brief Enabling or disabling of sensor data streaming for sensor client Function sends enabling or disabling of sensor data streaming for sensor client to slim daemon @param z_Txn: Request parameters for sensor streaming */ int SocketClientWrapper::requestSensorData(slim_EnableSensorDataTxnStructType &z_Txn) { LOC_LOGD("%s:%d] Received sensor data request", __func__, __LINE__); SocketClientSensorDataReq sensorDataRequest; memset(&sensorDataRequest, 0, sizeof(sensorDataRequest)); sensorDataRequest.msgHeader.msgId = eSLIM_SOCKET_CLIENT_MSG_ID_SENSOR_DATA_REQ; sensorDataRequest.msgHeader.msgSize = sizeof(SocketClientSensorDataReq); sensorDataRequest.msgPayload = z_Txn; LOC_LOGD("%s:%d] Received sensor request, p_Handle is %08X", __func__, __LINE__, z_Txn.z_TxnData.p_Handle); // If socket_not_present or socket_not_connected, then error/warning if ( (SocketClientWrapper::mSocketFd < 0) ) { LOC_LOGE("%s[%d]: socket not present/connected\n", __func__, __LINE__); return -1; } if (write(SocketClientWrapper::mSocketFd, &sensorDataRequest, sizeof(sensorDataRequest)) < 0) { LOC_LOGE("%s[%d]: error writing on socket\n", __func__, __LINE__); return -1; } return 0; }
/** * @brief Stops a data call associated with the handle * * @param[in] client_handle Client handle * * @return Operation result * @retval E_DS_CLIENT_SUCCESS On success. * @retval E_DS_CLIENT_FAILURE... On error. */ static ds_client_status_enum_type ds_client_stop_call(dsClientHandleType client_handle) { ds_client_status_enum_type ret = E_DS_CLIENT_SUCCESS; ds_client_session_data *p_ds_global_data = (ds_client_session_data *)client_handle; LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__); if(client_handle == NULL) { LOC_LOGE("%s:%d]: Null argument received. Failing\n", __func__, __LINE__); ret = E_DS_CLIENT_FAILURE_GENERAL; goto err; } if(dsi_stop_data_call(p_ds_global_data->dsi_net_handle) == DSI_SUCCESS) { LOC_LOGD("%s:%d]: Sent request to stop data call\n", __func__, __LINE__); } else { LOC_LOGE("%s:%d]: Could not send request to stop data call\n", __func__, __LINE__); ret = E_DS_CLIENT_FAILURE_GENERAL; goto err; } err: LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__); return ret; }
/*=========================================================================== FUNCTION loc_eng_dmn_conn_glue_pipeget DESCRIPTION create a named pipe. pipe_name - pipe name path mode - mode DEPENDENCIES None RETURN VALUE 0: success or negative value for failure SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_dmn_conn_glue_pipeget(const char * pipe_name, int mode) { int fd; int result; LOC_LOGD("%s, mode = %d\n", pipe_name, mode); result = mkfifo(pipe_name, 0660); if ((result == -1) && (errno != EEXIST)) { LOC_LOGE("failed: %s\n", strerror(errno)); return result; } // The mode in mkfifo is not honoured and does not provide the // group permissions. Doing chmod to add group permissions. result = chmod (pipe_name, 0660); if (result != 0){ LOC_LOGE ("%s failed to change mode for %s, error = %s\n", __func__, pipe_name, strerror(errno)); } fd = open(pipe_name, mode); if (fd <= 0) { LOC_LOGE("failed: %s\n", strerror(errno)); } LOC_LOGD("fd = %d, %s\n", fd, pipe_name); return fd; }
const GpsGeofencingInterface* get_geofence_interface(void) { ENTRY_LOG(); void *handle; const char *error; typedef const GpsGeofencingInterface* (*get_gps_geofence_interface_function) (void); get_gps_geofence_interface_function get_gps_geofence_interface; static const GpsGeofencingInterface* geofence_interface = NULL; dlerror(); /* Clear any existing error */ handle = dlopen ("libgeofence.so", RTLD_NOW); if (!handle) { if ((error = dlerror()) != NULL) { LOC_LOGE ("%s, dlopen for libgeofence.so failed, error = %s\n", __func__, error); } goto exit; } dlerror(); /* Clear any existing error */ get_gps_geofence_interface = (get_gps_geofence_interface_function)dlsym(handle, "gps_geofence_get_interface"); if ((error = dlerror()) != NULL) { LOC_LOGE ("%s, dlsym for ulpInterface failed, error = %s\n", __func__, error); goto exit; } geofence_interface = get_gps_geofence_interface(); exit: EXIT_LOG(%d, geofence_interface == NULL); return geofence_interface; }
/*This function obtains the list of supported profiles*/ static ds_client_status_enum_type ds_client_get_profile_list( qmi_client_type *ds_client_handle, ds_client_resp_union_type *profile_list_resp_msg, wds_profile_type_enum_v01 profile_type) { ds_client_status_enum_type ret = E_DS_CLIENT_SUCCESS; ds_client_req_union_type req_union; LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__); req_union.p_get_profile_list_req = NULL; req_union.p_get_profile_list_req = (wds_get_profile_list_req_msg_v01 *) calloc(1, sizeof(wds_get_profile_list_req_msg_v01)); if(req_union.p_get_profile_list_req == NULL) { LOC_LOGE("%s:%d]: Could not allocate memory for" "wds_get_profile_list_req_msg_v01\n", __func__, __LINE__); goto err; } //Populate required members of the request structure req_union.p_get_profile_list_req->profile_type_valid = 1; req_union.p_get_profile_list_req->profile_type = profile_type; ret = ds_client_send_qmi_sync_req(ds_client_handle, QMI_WDS_GET_PROFILE_LIST_REQ_V01, profile_list_resp_msg, &req_union); if(ret != E_DS_CLIENT_SUCCESS) { LOC_LOGE("%s:%d]: ds_client_send_qmi_req failed. ret: %d\n", __func__, __LINE__, ret); goto err; } err: LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__); if(req_union.p_get_profile_list_req) free(req_union.p_get_profile_list_req); return ret; }
/*=========================================================================== FUNCTION loc_set_config_entry DESCRIPTION Potentially sets a given configuration table entry based on the passed in configuration value. This is done by using a string comparison of the parameter names and those found in the configuration file. PARAMETERS: config_entry: configuration entry in the table to possibly set config_value: value to store in the entry if the parameter names match DEPENDENCIES N/A RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ void loc_set_config_entry(loc_param_s_type* config_entry, loc_param_v_type* config_value) { if(NULL == config_entry || NULL == config_value) { LOC_LOGE("%s: INVALID config entry or parameter", __FUNCTION__); return; } if (strcmp(config_entry->param_name, config_value->param_name) == 0 && config_entry->param_ptr) { switch (config_entry->param_type) { case 's': if (strcmp(config_value->param_str_value, "NULL") == 0) { *((char*)config_entry->param_ptr) = '\0'; } else { strlcpy((char*) config_entry->param_ptr, config_value->param_str_value, LOC_MAX_PARAM_STRING + 1); } /* Log INI values */ LOC_LOGD("%s: PARAM %s = %s", __FUNCTION__, config_entry->param_name, (char*)config_entry->param_ptr); if(NULL != config_entry->param_set) { *(config_entry->param_set) = 1; } break; case 'n': *((int *)config_entry->param_ptr) = config_value->param_int_value; /* Log INI values */ LOC_LOGD("%s: PARAM %s = %d", __FUNCTION__, config_entry->param_name, config_value->param_int_value); if(NULL != config_entry->param_set) { *(config_entry->param_set) = 1; } break; case 'f': *((double *)config_entry->param_ptr) = config_value->param_double_value; /* Log INI values */ LOC_LOGD("%s: PARAM %s = %f", __FUNCTION__, config_entry->param_name, config_value->param_double_value); if(NULL != config_entry->param_set) { *(config_entry->param_set) = 1; } break; default: LOC_LOGE("%s: PARAM %s parameter type must be n, f, or s", __FUNCTION__, config_entry->param_name); } } }
static int loc_api_server_proc_init(void *context) { loc_api_server_msgqid = loc_eng_dmn_conn_glue_msgget(global_loc_api_q_path, O_RDWR); //change mode/group for the global_loc_api_q_path pipe int result = chmod (global_loc_api_q_path, 0660); if (result != 0) { LOC_LOGE("failed to change mode for %s, error = %s\n", global_loc_api_q_path, strerror(errno)); } struct group * gps_group = getgrnam("gps"); if (gps_group != NULL) { result = chown (global_loc_api_q_path, -1, gps_group->gr_gid); if (result != 0) { LOC_LOGE("chown for pipe failed, pipe %s, gid = %d, result = %d, error = %s\n", global_loc_api_q_path, gps_group->gr_gid, result, strerror(errno)); } } else { LOC_LOGE("getgrnam for gps failed, error code = %d\n", errno); } loc_api_resp_msgqid = loc_eng_dmn_conn_glue_msgget(global_loc_api_resp_q_path, O_RDWR); //change mode/group for the global_loc_api_resp_q_path pipe result = chmod (global_loc_api_resp_q_path, 0660); if (result != 0) { LOC_LOGE("failed to change mode for %s, error = %s\n", global_loc_api_resp_q_path, strerror(errno)); } if (gps_group != NULL) { result = chown (global_loc_api_resp_q_path, -1, gps_group->gr_gid); if (result != 0) { LOC_LOGE("chown for pipe failed, pipe %s, gid = %d, result = %d, error = %s\n", global_loc_api_resp_q_path, gps_group->gr_gid, result, strerror(errno)); } } quipc_msgqid = loc_eng_dmn_conn_glue_msgget(global_quipc_ctrl_q_path, O_RDWR); msapm_msgqid = loc_eng_dmn_conn_glue_msgget(global_msapm_ctrl_q_path , O_RDWR); msapu_msgqid = loc_eng_dmn_conn_glue_msgget(global_msapu_ctrl_q_path , O_RDWR); LOC_LOGD("%s:%d] loc_api_server_msgqid = %d\n", __func__, __LINE__, loc_api_server_msgqid); return 0; }
static int loc_api_server_proc(void *context) { int length, sz; int result = 0; static int cnt = 0; struct ctrl_msgbuf * p_cmsgbuf; struct ctrl_msgbuf cmsg_resp; sz = sizeof(struct ctrl_msgbuf) + 256; p_cmsgbuf = (struct ctrl_msgbuf *) malloc(sz); if (!p_cmsgbuf) { LOC_LOGE("%s:%d] Out of memory\n", __func__, __LINE__); return -1; } cnt ++; LOC_LOGD("%s:%d] %d listening on %s...\n", __func__, __LINE__, cnt, (char *) context); length = loc_eng_dmn_conn_glue_msgrcv(loc_api_server_msgqid, p_cmsgbuf, sz); if (length <= 0) { free(p_cmsgbuf); LOC_LOGE("%s:%d] fail receiving msg from gpsone_daemon, retry later\n", __func__, __LINE__); usleep(1000); return 0; } LOC_LOGD("%s:%d] received ctrl_type = %d\n", __func__, __LINE__, p_cmsgbuf->ctrl_type); switch(p_cmsgbuf->ctrl_type) { case GPSONE_LOC_API_IF_REQUEST: result = loc_eng_dmn_conn_loc_api_server_if_request_handler(p_cmsgbuf, length); break; case GPSONE_LOC_API_IF_RELEASE: result = loc_eng_dmn_conn_loc_api_server_if_release_handler(p_cmsgbuf, length); break; case GPSONE_UNBLOCK: LOC_LOGD("%s:%d] GPSONE_UNBLOCK\n", __func__, __LINE__); break; default: LOC_LOGE("%s:%d] unsupported ctrl_type = %d\n", __func__, __LINE__, p_cmsgbuf->ctrl_type); break; } free(p_cmsgbuf); return 0; }
/** * @brief Starts a data call using the profile number provided * * The function uses parameters provided from @a ds_client_open_call_type * call result. * * @param[in] client_handle Client handle * @param[in] profile_index Profile index * @param[in] pdp_type PDP type * * @return Operation result * @retval E_DS_CLIENT_SUCCESS On success. * @retval E_DS_CLIENT_FAILURE... On error. */ static ds_client_status_enum_type ds_client_start_call ( dsClientHandleType client_handle, int profile_index, int pdp_type ) { ds_client_status_enum_type ret = E_DS_CLIENT_FAILURE_GENERAL; dsi_call_param_value_t param_info; dsi_hndl_t dsi_handle; ds_client_session_data *ds_global_data = (ds_client_session_data *)client_handle; LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__); if(ds_global_data == NULL) { LOC_LOGE("%s:%d]: Null callback parameter\n", __func__, __LINE__); goto err; } dsi_handle = ds_global_data->dsi_net_handle; //Set profile index as call parameter param_info.buf_val = NULL; param_info.num_val = profile_index; dsi_set_data_call_param(dsi_handle, DSI_CALL_INFO_UMTS_PROFILE_IDX, ¶m_info); //Set IP Version as call parameter param_info.buf_val = NULL; param_info.num_val = pdp_type; dsi_set_data_call_param(dsi_handle, DSI_CALL_INFO_IP_VERSION, ¶m_info); LOC_LOGD("%s:%d]: Starting emergency call with profile index %d; pdp_type:%d\n", __func__, __LINE__, profile_index, pdp_type); if(dsi_start_data_call(dsi_handle) == DSI_SUCCESS) { LOC_LOGD("%s:%d]: Sent request to start data call\n", __func__, __LINE__); ret = E_DS_CLIENT_SUCCESS; } else { LOC_LOGE("%s:%d]: Could not send req to start data call \n", __func__, __LINE__); ret = E_DS_CLIENT_FAILURE_GENERAL; goto err; } err: LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__); return ret; }
/*This function obtains settings for the profile specified by the profile_identifier*/ static ds_client_status_enum_type ds_client_get_profile_settings( qmi_client_type *ds_client_handle, ds_client_resp_union_type *profile_settings_resp_msg, wds_profile_identifier_type_v01 *profile_identifier) { ds_client_status_enum_type ret = E_DS_CLIENT_SUCCESS; ds_client_req_union_type req_union; LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__); //Since it's a union containing a pointer to a structure, //following entities have the same address //- req_union //- req_union.p_get_profile_settings_req //- req_union.p_get_profile_settings_req->profile //so we can very well assign req_union = profile_identifier req_union.p_get_profile_settings_req = (wds_get_profile_settings_req_msg_v01 *)profile_identifier; ret = ds_client_send_qmi_sync_req(ds_client_handle, QMI_WDS_GET_PROFILE_SETTINGS_REQ_V01, profile_settings_resp_msg, &req_union); if(ret != E_DS_CLIENT_SUCCESS) { LOC_LOGE("%s:%d]: ds_client_send_qmi_req failed. ret: %d\n", __func__, __LINE__, ret); goto err; } err: LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__); return ret; }
/*=========================================================================== FUNCTION loc_eng_inject_xtra_data_in_buffer DESCRIPTION Injects buffered XTRA file into the engine and clears the buffer. DEPENDENCIES N/A RETURN VALUE 0: success >0: failure SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_inject_xtra_data_in_buffer() { int rc = 0; char *data; int length; pthread_mutex_lock(&loc_eng_data.xtra_module_data.lock); data = loc_eng_data.xtra_module_data.xtra_data_for_injection; length = loc_eng_data.xtra_module_data.xtra_data_len; loc_eng_data.xtra_module_data.xtra_data_for_injection = NULL; loc_eng_data.xtra_module_data.xtra_data_len = 0; pthread_mutex_unlock(&loc_eng_data.xtra_module_data.lock); if (data) { if (qct_loc_eng_inject_xtra_data(data, length)) { // FIXME gracefully handle injection error LOC_LOGE("XTRA injection failed."); rc = -1; } free(data); } return rc; }
/*=========================================================================== FUNCTION: linked_list_flush ===========================================================================*/ linked_list_err_type linked_list_flush(void* list_data) { if( list_data == NULL ) { LOC_LOGE("%s: Invalid list parameter!\n", __FUNCTION__); return eLINKED_LIST_INVALID_HANDLE; } list_state* p_list = (list_state*)list_data; /* Remove all dynamically allocated elements */ while( p_list->p_head != NULL ) { list_element* tmp = p_list->p_head->next; /* Free data pointer if told to do so. */ if( p_list->p_head->dealloc_func != NULL ) { p_list->p_head->dealloc_func(p_list->p_head->data_ptr); } /* Free list element */ free(p_list->p_head); p_list->p_head = tmp; } p_list->p_tail = NULL; return eLINKED_LIST_SUCCESS; }
/*=========================================================================== FUNCTION loc_eng_ni_callback DESCRIPTION Loc API callback handler RETURN VALUE error code (0 for success) ===========================================================================*/ int loc_eng_ni_callback ( rpc_loc_event_mask_type loc_event, /* event mask */ const rpc_loc_event_payload_u_type* loc_event_payload /* payload */ ) { int rc = 0; const rpc_loc_ni_event_s_type *ni_req = &loc_event_payload->rpc_loc_event_payload_u_type_u.ni_request; if (loc_event == RPC_LOC_EVENT_NI_NOTIFY_VERIFY_REQUEST) { switch (ni_req->event) { case RPC_LOC_NI_EVENT_VX_NOTIFY_VERIFY_REQ: LOC_LOGI("VX Notification"); loc_ni_request_handler("VX Notify", ni_req); break; case RPC_LOC_NI_EVENT_UMTS_CP_NOTIFY_VERIFY_REQ: LOC_LOGI("UMTS CP Notification\n"); loc_ni_request_handler("UMTS CP Notify", ni_req); break; case RPC_LOC_NI_EVENT_SUPL_NOTIFY_VERIFY_REQ: LOC_LOGI("SUPL Notification\n"); loc_ni_request_handler("SUPL Notify", ni_req); break; default: LOC_LOGE("Unknown NI event: %x\n", (int) ni_req->event); break; } } return rc; }
/*=========================================================================== FUNCTION ulp_msg_forward_quipc_coarse_position_request DESCRIPTION This function is called when libulp module need to forward coarse position request from ULP named pipe to message queue. This is done so that all ULP state transition is done in one thread. DEPENDENCIES None RETURN VALUE 0: success -1: failure SIDE EFFECTS N/A ===========================================================================*/ int ulp_msg_forward_quipc_coarse_position_request () { int ret_val = -1; ENTRY_LOG_CALLFLOW(); do { // Forward the coarse position request in ULP named pipe to ULP message queue // so that all state transition is done in one thread ulp_msg *msg(new ulp_msg(&ulp_data, ULP_MSG_REQUEST_COARSE_POSITION)); if (msg == NULL) { LOC_LOGE ("%s, failed to create message: ULP_MSG_REQUEST_COARSE_POSITION \n", __func__); break; } msg_q_snd(ulp_data.loc_proxy->mQ, msg, ulp_msg_free); ret_val = 0; } while (0); EXIT_LOG(%d, ret_val); return ret_val; }
/*=========================================================================== FUNCTION ulp_msg_send_monitor_request DESCRIPTION This function is called when ulp monitor thread need to send a message to ULP main thread to request ULP to re-evaluate its subsystems. DEPENDENCIES None RETURN VALUE 0: success -1: failure SIDE EFFECTS N/A ===========================================================================*/ int ulp_msg_send_monitor_request () { int ret_val = -1; ENTRY_LOG_CALLFLOW(); do { //Pass the start messgage to ULP if present & activated ulp_msg *ulpMonitorMsg(new ulp_msg(&ulp_data, ULP_MSG_MONITOR)); if (ulpMonitorMsg == NULL) { LOC_LOGE ("%s, failed to create message: ULP_MSG_MONITOR \n", __func__); break; } msg_q_snd(ulp_data.loc_proxy->mQ, ulpMonitorMsg, ulp_msg_free); ret_val = 0; } while (0); EXIT_LOG(%d, ret_val); return ret_val; }
void GnssAPIClient::onStopTrackingCb(LocationError error) { LOC_LOGD("%s]: (%d)", __FUNCTION__, error); if (error == LOCATION_ERROR_SUCCESS && mGnssCbIface != nullptr) { auto r = mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssStatusCb SESSION_END description=%s", __func__, r.description().c_str()); } r = mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssStatusCb ENGINE_OFF description=%s", __func__, r.description().c_str()); } } }
/*=========================================================================== FUNCTION loc_get_extension DESCRIPTION Get the gps extension to support XTRA. DEPENDENCIES N/A RETURN VALUE The GPS extension interface. SIDE EFFECTS N/A ===========================================================================*/ static const void* loc_get_extension(const char* name) { ENTRY_LOG(); const void* ret_val = NULL; if (strcmp(name, GPS_XTRA_INTERFACE) == 0) { ret_val = &sLocEngXTRAInterface; } else if (strcmp(name, AGPS_INTERFACE) == 0) { ret_val = &sLocEngAGpsInterface; } else if (strcmp(name, GPS_NI_INTERFACE) == 0) { ret_val = &sLocEngNiInterface; } else if (strcmp(name, AGPS_RIL_INTERFACE) == 0) { char baseband[PROPERTY_VALUE_MAX]; property_get("ro.baseband", baseband, "msm"); if (strcmp(baseband, "csfb") == 0) { ret_val = &sLocEngAGpsRilInterface; } } else if (strcmp(name, ULP_RAW_CMD_INTERFACE) == 0) { ret_val = &sLocEngInjectRawCmdInterface; } else if(strcmp(name, ULP_PHONE_CONTEXT_INTERFACE) == 0) { ret_val = &sLocEngUlpPhoneContextInterface; } else if(strcmp(name, ULP_NETWORK_INTERFACE) == 0) { //Return a valid value for ULP Network Interface only if ULP //turned on in gps.conf if(gps_conf.CAPABILITIES & ULP_CAPABILITY) ret_val = &sUlpNetworkInterface; } else if (strcmp(name, GPS_GEOFENCING_INTERFACE) == 0) { if ((gps_conf.CAPABILITIES | GPS_CAPABILITY_GEOFENCING) == gps_conf.CAPABILITIES) { ret_val = get_geofence_interface(); } } else { LOC_LOGE ("get_extension: Invalid interface passed in\n"); } EXIT_LOG(%p, ret_val); return ret_val; }
/*=========================================================================== FUNCTION ulp_msg_forward_quipc_position_report DESCRIPTION This function is called when libulp module need to forward a position report from ULP named pipe to message queue. This is done so that all ULP state transition is done in one thread. DEPENDENCIES None RETURN VALUE 0: success -1: failure SIDE EFFECTS N/A ===========================================================================*/ int ulp_msg_forward_quipc_position_report (int error_code, const UlpLocation* quipc_location_ptr, int debug_info_length, char* debug_info_ptr) { int ret_val = -1; UlpLocation quipc_location; char* debug_info = NULL; ENTRY_LOG_CALLFLOW(); do { if (quipc_location_ptr == NULL) { break; } quipc_location = *quipc_location_ptr; LOC_LOGI ("%s, Debug Info = %s, Length = %d\n", __func__, debug_info_ptr, debug_info_length); // Make a copy of the debug info received. Needs to be freed by ulp_brain. if (debug_info_length != 0) { debug_info = new char[debug_info_length]; if (debug_info != NULL) { strlcpy((char*)debug_info, debug_info_ptr, debug_info_length); quipc_location.rawData = (void*) debug_info; quipc_location.rawDataSize = debug_info_length; } } ulp_msg_report_quipc_position *ulpPositionMsg( new ulp_msg_report_quipc_position(&ulp_data, quipc_location, error_code)); if (ulpPositionMsg == NULL) { LOC_LOGE ("%s, failed to create message: ulp_msg_report_quipc_position \n", __func__); // Free the allocated memory delete [] debug_info; debug_info = NULL; quipc_location.rawData = NULL; quipc_location.rawDataSize = 0; break; } msg_q_snd(ulp_data.loc_proxy->mQ, ulpPositionMsg, ulp_msg_free); ret_val = 0; } while (0); EXIT_LOG(%d, ret_val); return ret_val; }
/*=========================================================================== FUNCTION ulp_zpp_start_engine DESCRIPTION This function is called to start ZPP provider. DEPENDENCIES None RETURN VALUE 0: success -1: failure SIDE EFFECTS N/A ===========================================================================*/ int ulp_zpp_start_engine () { int ret_val = -1; LocAdapterBase* adapter = ulp_data.loc_proxy->getAdapter(); ENTRY_LOG_CALLFLOW(); LOC_LOGD ("%s, zpp state = %d, ulp_zpp_engine_running () = %d\n", __func__, ulp_data.zpp_provider_info.state, ulp_zpp_engine_running()); do { // Wait for first fix to complete if (ulp_data.zpp_provider_info.first_fix_pending == true) { break; } if (ulp_zpp_engine_running () == false) { if ((ULP_LOC_SCREEN_ON == ulp_data.system_event)|| (ULP_LOC_TIMEZONE_CHANGE == ulp_data.system_event)|| (ULP_LOC_PHONE_CONTEXT_UPDATE == ulp_data.system_event)) { //these events require single shot ZPP updates ulp_data.zpp_provider_info.recurrence_type = ULP_LOC_RECURRENCE_SINGLE; } else if ( ULP_LOC_POWER_CONNECTED == ulp_data.system_event) { ulp_data.zpp_provider_info.recurrence_type = ULP_LOC_RECURRENCE_PERIODIC; pthread_mutex_lock(&zpp_provider_info_p->tLock); ulp_data.zpp_provider_info.periodic_session_active = true; pthread_mutex_unlock(&zpp_provider_info_p->tLock); if (NULL == ulp_data.zpp_provider_info.thread) { //Launch a thread to do a periodic ZPP update int rc = 0; rc = pthread_create(&ulp_data.zpp_provider_info.thread, NULL, ulp_zpp_thread_proc, &ulp_data); if (rc) LOC_LOGE("ZPP thread could not created. rc = %d\n", rc); } } // Send ZPP location request to engine adapter->getZppInt(); ulp_data.zpp_provider_info.state = ZPP_STATE_ACTIVE; ulp_data.zpp_provider_info.first_fix_pending = true; ret_val = 0; } } while (0); EXIT_LOG(%d, ret_val); return ret_val; }
void GnssMeasurement::GnssMeasurementDeathRecipient::serviceDied( uint64_t cookie, const wp<IBase>& who) { LOC_LOGE("%s] service died. cookie: %llu, who: %p", __FUNCTION__, static_cast<unsigned long long>(cookie), &who); if (mGnssMeasurement != nullptr) { mGnssMeasurement->close(); } }
/*=========================================================================== FUNCTION: linked_list_add ===========================================================================*/ linked_list_err_type linked_list_add(void* list_data, void *data_obj, void (*dealloc)(void*)) { //LOC_LOGV("%s: Adding to list data_obj = 0x%08X\n", __FUNCTION__, data_obj); if( list_data == NULL ) { LOC_LOGE("%s: Invalid list parameter!\n", __FUNCTION__); return eLINKED_LIST_INVALID_HANDLE; } if( data_obj == NULL ) { LOC_LOGE("%s: Invalid input parameter!\n", __FUNCTION__); return eLINKED_LIST_INVALID_PARAMETER; } list_state* p_list = (list_state*)list_data; list_element* elem = (list_element*)malloc(sizeof(list_element)); if( elem == NULL ) { LOC_LOGE("%s: Memory allocation failed\n", __FUNCTION__); return eLINKED_LIST_FAILURE_GENERAL; } /* Copy data to newly created element */ elem->data_ptr = data_obj; elem->next = NULL; elem->prev = NULL; elem->dealloc_func = dealloc; /* Replace head element */ list_element* tmp = p_list->p_head; p_list->p_head = elem; /* Point next to the previous head element */ p_list->p_head->next = tmp; if( tmp != NULL ) { tmp->prev = p_list->p_head; } else { p_list->p_tail = p_list->p_head; } return eLINKED_LIST_SUCCESS; }
/*=========================================================================== FUNCTION: msg_q_init ===========================================================================*/ msq_q_err_type msg_q_init(void** msg_q_data) { if( msg_q_data == NULL ) { LOC_LOGE("%s: Invalid msg_q_data parameter!\n", __FUNCTION__); return eMSG_Q_INVALID_PARAMETER; } msg_q* tmp_msg_q; tmp_msg_q = (msg_q*)calloc(1, sizeof(msg_q)); if( tmp_msg_q == NULL ) { LOC_LOGE("%s: Unable to allocate space for message queue!\n", __FUNCTION__); return eMSG_Q_FAILURE_GENERAL; } if( linked_list_init(&tmp_msg_q->msg_list) != 0 ) { LOC_LOGE("%s: Unable to initialize storage list!\n", __FUNCTION__); free(tmp_msg_q); return eMSG_Q_FAILURE_GENERAL; } if( pthread_mutex_init(&tmp_msg_q->list_mutex, NULL) != 0 ) { LOC_LOGE("%s: Unable to initialize list mutex!\n", __FUNCTION__); linked_list_destroy(&tmp_msg_q->msg_list); free(tmp_msg_q); return eMSG_Q_FAILURE_GENERAL; } if( pthread_cond_init(&tmp_msg_q->list_cond, NULL) != 0 ) { LOC_LOGE("%s: Unable to initialize msg q cond var!\n", __FUNCTION__); linked_list_destroy(&tmp_msg_q->msg_list); pthread_mutex_destroy(&tmp_msg_q->list_mutex); free(tmp_msg_q); return eMSG_Q_FAILURE_GENERAL; } tmp_msg_q->unblocked = 0; *msg_q_data = tmp_msg_q; return eMSG_Q_SUCCESS; }
/*=========================================================================== FUNCTION thelper_main DESCRIPTION This function is the main thread. It will be launched as a child thread data - pointer to the instance DEPENDENCIES None RETURN VALUE NULL SIDE EFFECTS N/A ===========================================================================*/ static void * thelper_main(void *data) { int result = 0; struct loc_eng_dmn_conn_thelper * thelper = (struct loc_eng_dmn_conn_thelper *) data; if (thelper->thread_proc_init) { result = thelper->thread_proc_init(thelper->thread_context); if (result < 0) { thelper->thread_exit = 1; thelper_signal_ready(thelper); LOC_LOGE("%s:%d] error: 0x%lx\n", __func__, __LINE__, (long) thelper); return NULL; } } thelper_signal_ready(thelper); if (thelper->thread_proc_pre) { result = thelper->thread_proc_pre(thelper->thread_context); if (result < 0) { thelper->thread_exit = 1; LOC_LOGE("%s:%d] error: 0x%lx\n", __func__, __LINE__, (long) thelper); return NULL; } } do { if (thelper->thread_proc) { result = thelper->thread_proc(thelper->thread_context); if (result < 0) { thelper->thread_exit = 1; LOC_LOGE("%s:%d] error: 0x%lx\n", __func__, __LINE__, (long) thelper); } } } while (thelper->thread_exit == 0); if (thelper->thread_proc_post) { result = thelper->thread_proc_post(thelper->thread_context); } if (result != 0) { LOC_LOGE("%s:%d] error: 0x%lx\n", __func__, __LINE__, (long) thelper); } return NULL; }
/*=========================================================================== FUNCTION loc_init DESCRIPTION Initialize the location engine, this include setting up global datas and registers location engien with loc api service. DEPENDENCIES None RETURN VALUE 0: success SIDE EFFECTS N/Ax ===========================================================================*/ static int loc_init(GpsCallbacks* callbacks) { int retVal = -1; ENTRY_LOG(); if(callbacks == NULL) { LOC_LOGE("loc_init failed. cb = NULL\n"); EXIT_LOG(%d, retVal); return retVal; }
/*=========================================================================== FUNCTION loc_api_glue_init DESCRIPTION Initiates the RPC client RETURN VALUE 1 for success 0 for failure ===========================================================================*/ int loc_api_glue_init(void) { if (loc_api_clnt == NULL) { /* Initialize data */ int i; int pid = getpid(); for (i = 0; i < LOC_API_CB_MAX_CLIENTS; i++) { loc_glue_callback_table[i].cb_id = i | (pid << 16); loc_glue_callback_table[i].cb_func = NULL; loc_glue_callback_table[i].handle = -1; loc_glue_callback_table[i].rpc_cb = NULL; loc_glue_callback_table[i].user = NULL; } /* Print msg */ LOC_LOGV("Trying to create RPC client...\n"); loc_api_clnt = clnt_create(NULL, LOC_APIPROG, LOC_APIVERS, NULL); LOC_LOGV("Created loc_api_clnt ---- %x\n", (unsigned int)loc_api_clnt); if (loc_api_clnt == NULL) { LOC_LOGE("Error: cannot create RPC client.\n"); return 0; } /* Init RPC callbacks */ loc_api_sync_call_init(); int rc = loc_apicb_app_init(); if (rc >= 0) { LOC_LOGD("Loc API RPC client initialized.\n"); clnt_register_reset_notification_cb(loc_api_clnt, loc_api_glue_rpc_cb); } else { LOC_LOGE("Loc API callback initialization failed.\n"); return 0; } } return 1; }
/*=========================================================================== FUNCTION loc_sync_send_req DESCRIPTION Synchronous req call (thread safe) DEPENDENCIES N/A RETURN VALUE Loc API 2.0 status SIDE EFFECTS N/A ===========================================================================*/ locClientStatusEnumType loc_sync_send_req ( locClientHandleType client_handle, uint32_t req_id, /* req id */ locClientReqUnionType req_payload, uint32_t timeout_msec, uint32_t ind_id, //ind ID to block for, usually the same as req_id */ void *ind_payload_ptr /* can be NULL*/ ) { locClientStatusEnumType status = eLOC_CLIENT_SUCCESS ; int select_id; int rc = 0; // Select the callback we are waiting for select_id = loc_sync_select_ind(client_handle, ind_id, req_id, ind_payload_ptr); if (select_id >= 0) { status = locClientSendReq (client_handle, req_id, req_payload); LOC_LOGV("%s:%d]: select_id = %d,locClientSendReq returned %d\n", __func__, __LINE__, select_id, status); if (status != eLOC_CLIENT_SUCCESS ) { loc_free_slot(select_id); } else { // Wait for the indication callback if (( rc = loc_sync_wait_for_ind( select_id, timeout_msec / 1000, ind_id) ) < 0) { if ( rc == -ETIMEDOUT) status = eLOC_CLIENT_FAILURE_TIMEOUT; else status = eLOC_CLIENT_FAILURE_INTERNAL; // Callback waiting failed LOC_LOGE("%s:%d]: loc_api_wait_for_ind failed, err %d, " "select id %d, status %s", __func__, __LINE__, rc , select_id, loc_get_v02_client_status_name(status)); } else { status = eLOC_CLIENT_SUCCESS; LOC_LOGV("%s:%d]: success (select id %d)\n", __func__, __LINE__, select_id); } } } /* select id */ return status; }