之前讲了 loc eng 是如何把 SV status(SV是Satellite Value,可以看作是卫星信息的简称)信息传递给 Android framework层,都是1系列 callback 而已。
本文要讲的是 SV status 如何从 Modem层(由于 QMI层 是高通的 Ap 跟 Modem 的通讯机制,不需要我们来处理,所以我这里把 QMI+Modem 统称为 Modem层,可能不准确,但是大家理解了就行)传递到 loc eng层。
loc eng层 的 SV status 是通过 sv_status_cb函数 来扔给 Android framework层,我们需要看下loc eng层的sv_status_cb是在哪里被调用的,具体以下:
hardware/qcom/gps/loc_api/libloc_api_50001/loc_eng.cpp
// 我们需要记住的是:loc eng层 是通过1个 proc()方法 把数据传递到上层的
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层 是属于消息触发的,也就是说正常的流程是:Modem层 传上来1个消息,经过1系列处理传递到 loc eng层,loc eng层 传递给 Android framework层,然后交给 App 来处理。所以本文的讲授flow跟上1篇可能有1些不1样,需要从底层(loc_api层)往上层讲(loc eng层)。在讲授flow之前,有1个架构性的东西需要讲授1下。高通平台的GPS核心部份都在 Modem里面,这里面实现了GPS相干的协议,类似 Wi-Fi的 supplicant + driver 部份。我们把这个部份(Modem 中的 GPS)看作是GPS Service;另外1部份在 Ap 里面,我们把这部份看作是GPS Client。Client 主要是通过 QMI 的通讯方式接收 Service 发过来的信息,固然 Client也能够通过 QMI 发送信息给 Service,这个就是GPS的最大的框架。
QMI 暂时不是本文需要关注的,所以这里从 QMI 之上开始讲起,QMI 之上有1个叫 loc_api 的层,具体作用是通过 QMI 读取 Service 发送过来的信息,固然也能够通过 QMI 发送信息给 Service,有1个专门处理 Service 发送过来信息的 callback 需要重点关注,在看 callback 之前有1些数据结构需要先给出来,不然后续代码理解起来可能会比较麻烦。
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