搜星流程(1)-[Qualcomm][BSP-GPS]

    xiaoxiao2026-04-01  7

    之前讲了 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 

    转载请注明原文地址: https://ju.6miu.com/read-1308402.html
    最新回复(0)