搜星流程(1)-[Qualcomm][BSP-GPS]
之前講了 loc eng 是如何把 SV status(SV是Satellite Value,可以看做是衛(wèi)星信息的簡稱)信息傳遞給?Android?framework層,都是一系列 callback 而已。
本文要講的是 SV status 如何從 Modem層(由于 QMI層 是高通的 Ap 跟 Modem 的通信機(jī)制,不需要我們來處理,所以我這里把 QMI+Modem 統(tǒng)稱為 Modem層,可能不準(zhǔn)確,但是大家理解了就行)傳遞到 loc eng層。
loc eng層 的 SV status 是通過?sv_status_cb函數(shù)?來扔給 Android framework層,我們需要看下loc eng層的sv_status_cb是在哪里被調(diào)用的,具體如下:
hardware/qcom/gps/loc_api/libloc_api_50001/loc_eng.cpp
// 我們需要記住的是:loc eng層 是通過一個(gè)?proc()方法?把數(shù)據(jù)傳遞到上層的
?840 void LocEngReportSv::proc()?const {
?841 ? ? LocEngAdapter* adapter = (LocEngAdapter*)mAdapter;
?842 ? ? loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)adapter->getOwner() ? ? ;
?843?
?844 ? ? if (locEng->mute_session_state != LOC_MUTE_SESS_IN_SESSION)
?845 ? ? {
?846 ? ? ? ? if (locEng->sv_status_cb != NULL) {
?847 ? ? ? ? ? ? locEng->sv_status_cb((GpsSvStatus*)&(mSvStatus),
?848 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(void*)mSvExt);
?849 ? ? ? ? }
?850?
?851 ? ? ? ? if (locEng->generateNmea)
?852 ? ? ? ? {
?853 ? ? ? ? ? ? loc_eng_nmea_generate_sv(locEng, mSvStatus, mLocationExtended);
?854 ? ? ? ? }
?855 ? ? }
?856 }
在講解flow之前,有一個(gè)架構(gòu)性的東西需要講解一下。高通平臺(tái)的GPS核心部分都在 Modem里面,這里面實(shí)現(xiàn)了GPS相關(guān)的協(xié)議,類似 Wi-Fi的 supplicant + driver 部分。我們把這個(gè)部分(Modem 中的 GPS)看做是GPS Service;另外一部分在 Ap 里面,我們把這部分看做是GPS Client。Client 主要是通過 QMI 的通信方式接收 Service 發(fā)過來的信息,當(dāng)然 Client也可以通過 QMI 發(fā)送信息給 Service,這個(gè)就是GPS的最大的框架。
QMI 暫時(shí)不是本文需要關(guān)注的,所以這里從?QMI?之上開始講起,QMI?之上有一個(gè)叫?loc_api?的層,具體作用是通過?QMI?讀取 Service 發(fā)送過來的信息,當(dāng)然也可以通過?QMI?發(fā)送信息給 Service,有一個(gè)專門處理 Service 發(fā)送過來信息的 callback 需要重點(diǎn)關(guān)注,在看 callback 之前有一些數(shù)據(jù)結(jié)構(gòu)需要先給出來,不然后續(xù)代碼理解起來可能會(huì)比較麻煩。
locClientCallbackDataType的各種callback定義:?
vendor/qcom/opensource/location/loc_api/loc_api_v02/loc_api_v02_client.c
?629 typedef struct locClientCbDataStructT locClientCallbackDataType;
?630?
?631 struct locClientCbDataStructT
?632 {
?633 ?// client cookie
?634 ? void *pClientCookie;
?635 ? //QCCI handle for this control point
?636 ? qmi_client_type userHandle;
?637?
?638 ? // callbacks registered by the clients
?639 ? locClientEventIndCbType eventCallback;
?640 ? locClientRespIndCbType respCallback;
?641 ? locClientErrorCbType ? errorCallback;
?642?
?643 ? // the event mask the client has registered for
?644 ? locClientEventMaskType eventRegMask;
?645?
?646 ? //pointer to itself for checking consistency data
?647 ? ?locClientCallbackDataType *pMe;
?648 };
vendor/qcom/opensource/location/loc_api/loc_api_v02/loc_api_v02_client.c
?865 /** locClientIndCb
?866 ?* ?@brief handles the indications sent from the service, if a
?867 ?* ? ? ? ? response indication was received then the it is sent
?868 ?* ? ? ? ? to the response callback. If a event indication was
?869 ?* ? ? ? ? received then it is sent to the event callback
?870 ?* ?@param [in] user handle
?871 ?* ?@param [in] msg_id
?872 ?* ?@param [in] ind_buf
?873 ?* ?@param [in] ind_buf_len
?874 ?* ?@param [in] ind_cb_data */
?875?
?876 static void locClientIndCb
?877 (
?878 ?qmi_client_type ? ? ? ? ? ? ? ?user_handle,
?879 ?unsigned int ? ? ? ? ? ? ? ? ? msg_id,
?880 ?void ? ? ? ? ? ? ? ? ? ? ? ? ? *ind_buf,
?881 ?unsigned int ? ? ? ? ? ? ? ? ? ind_buf_len,
?882 ?void ? ? ? ? ? ? ? ? ? ? ? ? ? *ind_cb_data
?883 )
?884 {
?885 ? locClientIndEnumT indType;
?886 ? size_t indSize = 0;
?887 ? qmi_client_error_type rc ;
?888 ? locClientCallbackDataType* pCallbackData =
?889 ? ? ? (locClientCallbackDataType *)ind_cb_data;
?890?
?891 ? LOC_LOGV("%s:%d]: Indication: msg_id=%d buf_len=%d pCallbackData = %p\n",
?892 ? ? ? ? ? ? ? ? __func__, __LINE__, (uint32_t)msg_id, ind_buf_len,
?893 ? ? ? ? ? ? ? ? pCallbackData);
?894?
?895 ? // check callback data
?896 ? if(NULL == pCallbackData ||(pCallbackData != pCallbackData->pMe))
?897 ? {
?898 ? ? LOC_LOGE("%s:%d]: invalid callback data", __func__, __LINE__);
?899 ? ? return;
?900 ? }
?901? ?902 ? // check user handle
?903 ? if(memcmp(&pCallbackData->userHandle, &user_handle, sizeof(user_handle)))
?904 ? {
?905 ? ? LOC_LOGE("%s:%d]: invalid user_handle got %p expected %p\n",
?906 ? ? ? ? __func__, __LINE__,
?907 ? ? ? ? user_handle, pCallbackData->userHandle);
?908 ? ? return;
?909 ? }
?910 ? // Get the indication size and type ( eventInd or respInd)
?911 ? if( true == locClientGetSizeAndTypeByIndId(msg_id, &indSize, &indType))
?912 ? {
?913 ? ? void *indBuffer = NULL;
?914?
?915 ? ? // decode the indication
?916 ? ? indBuffer = malloc(indSize);
?917?
?918 ? ? if(NULL == indBuffer)
?919 ? ? {
?920 ? ? ? LOC_LOGE("%s:%d]: memory allocation failed\n", __func__, __LINE__);
?921 ? ? ? return;
?922 ? ? }
?923?
?924 ? ? rc = QMI_NO_ERR;
?925?
?926 ? ? if (ind_buf_len > 0)
?927 ? ? {
?928 ? ? ? ? // decode the indication
?929 ? ? ? ? rc = qmi_client_message_decode(
?930 ? ? ? ? ? ? user_handle,
?931 ? ? ? ? ? ? QMI_IDL_INDICATION,
?932 ? ? ? ? ? ? msg_id,
?933 ? ? ? ? ? ? ind_buf,
?934 ? ? ? ? ? ? ind_buf_len,
?935 ? ? ? ? ? ? indBuffer,
?936 ? ? ? ? ? ? indSize);
?937 ? ? }
?938?
?939 ? ? if( rc == QMI_NO_ERR )
?940 ? ? {
?941 ? ? ? if(eventIndType == indType)
?942 ? ? ? {
?943 ? ? ? ? locClientEventIndUnionType eventIndUnion;
?944?
?945 ? ? ? ? /* copy the eventCallback function pointer from the callback
?946 ? ? ? ? ?* data to local variable. This is to protect against the race
?947 ? ? ? ? ?* condition between open/close and indication callback.
?948 ? ? ? ? ?*/
?949 ? ? ? ? locClientEventIndCbType localEventCallback =
?950 ? ? ? ? ? ? pCallbackData->eventCallback;
?951?
?952 ? ? ? ? // dummy event
?953 ? ? ? ? eventIndUnion.pPositionReportEvent =
?954 ? ? ? ? ? ? (qmiLocEventPositionReportIndMsgT_v02 *)indBuffer;
?955?
?956 ? ? ? ? /* call the event callback
?957 ? ? ? ? ?* To avoid calling the eventCallback after locClientClose
?958 ? ? ? ? ?* is called, check pCallbackData->eventCallback again here
?959 ? ? ? ? ?*/
?960 ? ? ? ? if((NULL != localEventCallback) &&
?961 ? ? ? ? ? ?(NULL != pCallbackData->eventCallback))
?962 ? ? ? ? {
?963 ? ? ? ? ? localEventCallback(
?964 ? ? ? ? ? ? ? (locClientHandleType)pCallbackData,
?965 ? ? ? ? ? ? ? msg_id,
?966 ? ? ? ? ? ? ? eventIndUnion,
?967 ? ? ? ? ? ? ? pCallbackData->pClientCookie);
?968 ? ? ? ? }
?969 ? ? ? }
?970 ? ? ? else if(respIndType == indType)
?971 ? ? ? {
?972 ? ? ? ? locClientRespIndUnionType respIndUnion;
?973?
?974 ? ? ? ? /* copy the respCallback function pointer from the callback
?975 ? ? ? ? ?* data to local variable. This is to protect against the race
?976 ? ? ? ? ?* condition between open/close and indication callback.
?977 ? ? ? ? ?*/
?978 ? ? ? ? locClientRespIndCbType localRespCallback =
?979 ? ? ? ? ? ? pCallbackData->respCallback;
?980?
?981 ? ? ? ? // dummy to suppress compiler warnings
?982 ? ? ? ? respIndUnion.pDeleteAssistDataInd =
?983 ? ? ? ? ? ? (qmiLocDeleteAssistDataIndMsgT_v02 *)indBuffer;
?984?
?985 ? ? ? ? /* call the response callback
?986 ? ? ? ? ?* To avoid calling the respCallback after locClientClose
?987 ? ? ? ? ?* is called, check pCallbackData->respCallback again here
?988 ? ? ? ? ?*/
?989 ? ? ? ? if((NULL != localRespCallback) &&
?990 ? ? ? ? ? ?(NULL != pCallbackData->respCallback))
?991 ? ? ? ? {
?992 ? ? ? ? ? localRespCallback(
?993 ? ? ? ? ? ? ? (locClientHandleType)pCallbackData,
?994 ? ? ? ? ? ? ? msg_id,
?995 ? ? ? ? ? ? ? respIndUnion,
?996 ? ? ? ? ? ? ? pCallbackData->pClientCookie);
?997 ? ? ? ? }
?998 ? ? ? }
?999 ? ? }
1000 ? ? else
1001 ? ? {
1002 ? ? ? LOC_LOGE("%s:%d]: Error decoding indication %d\n",
1003 ? ? ? ? ? ? ? ? ? ? __func__, __LINE__, rc);
1004 ? ? }
1005 ? ? if(indBuffer)
1006 ? ? {
1007 ? ? ? free (indBuffer);
1008 ? ? }
1009 ? }
1010 ? else // Id not found
1011 ? {
1012 ? ? LOC_LOGE("%s:%d]: Error indication not found %d\n",
1013 ? ? ? ? ? ? ? ? ? __func__, __LINE__,(uint32_t)msg_id);
1014 ? }
1015 ? return;
1016 }
1017?
總結(jié)
以上是生活随笔為你收集整理的搜星流程(1)-[Qualcomm][BSP-GPS]的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android接口和框架学习
- 下一篇: 修改 Android 5.1 默认设置