搜星流程(1)-[Qualcomm][BSP-GPS]
來源:程序員人生 發(fā)布時(shí)間:2017-02-22 08:32:14 閱讀次數(shù):5949次
之前講了 loc eng 是如何把 SV status(SV是Satellite Value,可以看作是衛(wèi)星信息的簡稱)信息傳遞給 Android framework層,都是1系列 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層 是通過1個(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 }
由于 loc eng層 到 Modem層 是屬于消息觸發(fā)的,也就是說正常的流程是:Modem層 傳上來1個(gè)消息,經(jīng)過1系列處理傳遞到 loc eng層,loc eng層 傳遞給 Android framework層,然后交給 App 來處理。所以本文的講授flow跟上1篇可能有1些不1樣,需要從底層(loc_api層)往上層講(loc eng層)。在講授flow之前,有1個(gè)架構(gòu)性的東西需要講授1下。高通平臺(tái)的GPS核心部份都在 Modem里面,這里面實(shí)現(xiàn)了GPS相干的協(xié)議,類似 Wi-Fi的 supplicant + driver 部份。我們把這個(gè)部份(Modem 中的 GPS)看作是GPS Service;另外1部份在 Ap 里面,我們把這部份看作是GPS Client。Client 主要是通過 QMI 的通訊方式接收 Service 發(fā)過來的信息,固然 Client也能夠通過 QMI 發(fā)送信息給 Service,這個(gè)就是GPS的最大的框架。
QMI 暫時(shí)不是本文需要關(guān)注的,所以這里從 QMI 之上開始講起,QMI 之上有1個(gè)叫 loc_api 的層,具體作用是通過 QMI 讀取 Service 發(fā)送過來的信息,固然也能夠通過 QMI 發(fā)送信息給 Service,有1個(gè)專門處理 Service 發(fā)送過來信息的 callback 需要重點(diǎn)關(guān)注,在看 callback 之前有1些數(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
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)