程序员人生 网站导航

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

栏目:综合技术时间:2017-02-22 08:32:14

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

最新技术推荐