之前讲了 loc eng 是如何把 SV status(SV是Satellite Value,可以看做是卫星信息的简称)信息传递给 Android framework层,都是一系列 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层 是通过一个 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层 传上来一个消息,经过一系列处理传递到 loc eng层,loc eng层 传递给 Android framework层,然后交给 App 来处理。所以本文的讲解flow跟上一篇可能有一些不一样,需要从底层(loc_api层)往上层讲(loc eng层)。在讲解flow之前,有一个架构性的东西需要讲解一下。高通平台的GPS核心部分都在 Modem里面,这里面实现了GPS相关的协议,类似 Wi-Fi的 supplicant + driver 部分。我们把这个部分(Modem 中的 GPS)看做是GPS Service;另外一部分在 Ap 里面,我们把这部分看做是GPS Client。Client 主要是通过 QMI 的通信方式接收 Service 发过来的信息,当然 Client也可以通过 QMI 发送信息给 Service,这个就是GPS的最大的框架。
QMI 暂时不是本文需要关注的,所以这里从 QMI 之上开始讲起,QMI 之上有一个叫 loc_api 的层,具体作用是通过 QMI 读取 Service 发送过来的信息,当然也可以通过 QMI 发送信息给 Service,有一个专门处理 Service 发送过来信息的 callback 需要重点关注,在看 callback 之前有一些数据结构需要先给出来,不然后续代码理解起来可能会比较麻烦。
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
