多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > gps搜星流程

gps搜星流程

來源:程序員人生   發布時間:2017-04-06 09:38:59 閱讀次數:5737次

前面有講過gps的搜星流程,本文要講授的是跟搜星類似的流程–gps定位流程,由于全部進程比較類似,所以決定用1篇文章來說解,modem層到loc eng層的數據傳遞和loc eng層到android framework層的數據傳遞


loc eng層的gps location是通過location_cb函數來扔給android framework層的,我們需要看下loc eng層的location_cb是在哪里被調用的,具體以下: 
hardware/qcom/gps/loc_api/libloc_api_50001/loc_eng.cpp

void LocEngReportPosition::proc() const { //跟搜星流程是否是很類似,一樣是通過loc eng層的1個proc()方法把location的數據傳遞給上層的 LocEngAdapter* adapter = (LocEngAdapter*)mAdapter; loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)adapter->getOwner(); if (locEng->mute_session_state != LOC_MUTE_SESS_IN_SESSION) { bool reported = falseif (locEng->location_cb != NULL) { if (LOC_SESS_FAILURE == mStatus) { //如果狀態不對,那末給到上層的location信息是NULL // in case we want to handle the failure case locEng->location_cb(NULL, NULL); reported = true; } // what's in the else if is... (line by line) // 1. this is a final fix; and // 1.1 it is a Satellite fix; or // 1.2 it is a sensor fix // 2. (must be intermediate fix... implicit) // 2.1 we accepte intermediate; and // 2.2 it is NOT the case that // 2.2.1 there is inaccuracy; and // 2.2.2 we care about inaccuracy; and // 2.2.3 the inaccuracy exceeds our tolerance else if ((LOC_SESS_SUCCESS == mStatus && ((LOC_POS_TECH_MASK_SATELLITE | LOC_POS_TECH_MASK_SENSORS | LOC_POS_TECH_MASK_HYBRID) & mTechMask)) || (LOC_SESS_INTERMEDIATE == locEng->intermediateFix && !((mLocation.gpsLocation.flags & GPS_LOCATION_HAS_ACCURACY) && (gps_conf.ACCURACY_THRES != 0) && (mLocation.gpsLocation.accuracy > gps_conf.ACCURACY_THRES)))) { //否則把location的信息通過location_cb傳遞給android framework層, //注意:這里傳遞的數據類型是UlpLocation*類型的,不是HAL層所能辨認的格式GpsLocation* //搜星流程在這里傳遞的是HAL層能辨認的GpsSvStatus*類型的,所以一定有1個地方在做UlpLocation到GpsLocation的轉換 locEng->location_cb((UlpLocation*)&(mLocation), (void*)mLocationExt); reported = true; } } // if we have reported this fix if (reported && // and if this is a singleshot GPS_POSITION_RECURRENCE_SINGLE == locEng->adapter->getPositionMode().recurrence) { if (LOC_SESS_INTERMEDIATE == mStatus) { // modem could be still working for a final fix, // although we no longer need it. So stopFix(). locEng->adapter->stopFix(); } // turn off the session flag. locEng->adapter->setInSession(false); } if (locEng->generateNmea && mLocation.position_source == ULP_LOCATION_IS_FROM_GNSS && mTechMask & (LOC_POS_TECH_MASK_SATELLITE | LOC_POS_TECH_MASK_SENSORS | LOC_POS_TECH_MASK_HYBRID)) { unsigned char generate_nmea = reported && (mStatus != LOC_SESS_FAILURE); loc_eng_nmea_generate_pos(locEng, mLocation, mLocationExtended, generate_nmea); } // Free the allocated memory for rawData UlpLocation* gp = (UlpLocation*)&(mLocation); if (gp != NULL && gp->rawData != NULL) { delete (char*)gp->rawData; gp->rawData = http://blog.csdn.net/lele_cheny/article/details/NULL; gp->rawDataSize = 0; } } }


gps定位流程跟搜星流程1樣,都是消息觸發機制,location的信息是從底層(modem層)發送上來的,所以我們從底層往上來跟進全部流程


gps定位流程底層會有比很多callback綁定,如果是跟搜星流程1樣的callback的話,我們就1筆帶過,如果有不1樣的才拿出來分析。

一樣從loc_api層的locClientIndCb開始走起: 
vendor/qcom/opensource/location/loc_api/loc_api_v02/loc_api_v02_client.c

static void locClientIndCb ( qmi_client_type user_handle, unsigned int msg_id, void *ind_buf, unsigned int ind_buf_len, void *ind_cb_data ) { //定義和初始化,關鍵參數ind_cb_data會賦值給locClientCallbackDataType類型的pCallbackData locClientIndEnumT indType; size_t indSize = 0; qmi_client_error_type rc ; locClientCallbackDataType* pCallbackData = http://blog.csdn.net/lele_cheny/article/details/(locClientCallbackDataType *)ind_cb_data; LOC_LOGV("%s:%d]: Indication: msg_id=%d buf_len=%d pCallbackData = http://blog.csdn.net/lele_cheny/article/details/%p/n", __func__, __LINE__, (uint32_t)msg_id, ind_buf_len, pCallbackData); // check callback data if(NULL == pCallbackData ||(pCallbackData != pCallbackData->pMe)) { //如果傳進來的參數是NULL,那末1切免談了 LOC_LOGE("%s:%d]: invalid callback data", __func__, __LINE__); return; } // check user handle if(memcmp(&pCallbackData->userHandle, &user_handle, sizeof(user_handle))) { LOC_LOGE("%s:%d]: invalid user_handle got %p expected %p\n", __func__, __LINE__, user_handle, pCallbackData->userHandle); //填充callback的userHandle,如果異常則返回 return; } // Get the indication size and type ( eventInd or respInd) //顧名思義從msg_id里面獲得size和type,type分為event和response iftrue == locClientGetSizeAndTypeByIndId(msg_id, &indSize, &indType)) { void *indBuffer = NULL; // if the client did not register for this event then just drop it if( (eventIndType == indType) && ( (NULL == pCallbackData->eventCallback) || (false == isClientRegisteredForEvent(pCallbackData->eventRegMask, msg_id)) ) ) { //如果是eventIndType,但是eventCallback是NULL,或msg_id的eventRegMask是沒有注冊的 LOC_LOGW("%s:%d]: client is not registered for event %d\n", __func__, __LINE__, (uint32_t)msg_id); return; } // decode the indication indBuffer = malloc(indSize); if(NULL == indBuffer) { //分配內存失敗 LOC_LOGE("%s:%d]: memory allocation failed\n", __func__, __LINE__); return; } //初始化rc為QMI_NO_ERR rc = QMI_NO_ERR; if (ind_buf_len > 0) { // decode the indication //解析qmi message,ind_buf是傳入數據,indBuffer是解析以后的數據 rc = qmi_client_message_decode( user_handle, QMI_IDL_INDICATION, msg_id, ind_buf, ind_buf_len, indBuffer, indSize); } if( rc == QMI_NO_ERR ) { //validate indication //解析終了以后就要開始switch case了,其中case是msg_id if (true == locClientHandleIndication(msg_id, indBuffer, indSize)) { //1般只要indBuffer沒有問題,就會走這個flow if(eventIndType == indType) { locClientEventIndUnionType eventIndUnion; /* copy the eventCallback function pointer from the callback * data to local variable. This is to protect against the race * condition between open/close and indication callback. */ //這里可以看到eventCallback賦值給了localEventCallback,就是等于后面的globalEventCb(具體后面有講),這里是重點!!! locClientEventIndCbType localEventCallback = pCallbackData->eventCallback; // dummy event eventIndUnion.pPositionReportEvent = (qmiLocEventPositionReportIndMsgT_v02 *)indBuffer; /* call the event callback * To avoid calling the eventCallback after locClientClose * is called, check pCallbackData->eventCallback again here */ if((NULL != localEventCallback) && (NULL != pCallbackData->eventCallback)) { //如果LocalEventCallback不為NULL,則調用callback所綁定的函數,也就是globalEventCb localEventCallback( (locClientHandleType)pCallbackData, msg_id, eventIndUnion, pCallbackData->pClientcookie); } } else if(respIndType == indType) { //resp類型的msg先不講 locClientRespIndUnionType respIndUnion; /* copy the respCallback function pointer from the callback * data to local variable. This is to protect against the race * condition between open/close and indication callback. */ locClientRespIndCbType localRespCallback = pCallbackData->respCallback; // dummy to suppress compiler warnings respIndUnion.pDeleteAssistDataInd = (qmiLocDeleteAssistDataIndMsgT_v02 *)indBuffer; /* call the response callback * To avoid calling the respCallback after locClientClose * is called, check pCallbackData->respCallback again here */ if((NULL != localRespCallback) && (NULL != pCallbackData->respCallback)) { localRespCallback( (locClientHandleType)pCallbackData, msg_id, respIndUnion, pCallbackData->pClientCookie); } } } else // error handling indication { LOC_LOGE("%s:%d]: Error handling the indication %d\n", __func__, __LINE__, (uint32_t)msg_id); } } else { LOC_LOGE("%s:%d]: Error decoding indication %d\n", __func__, __LINE__, rc); } if(indBuffer) { free (indBuffer); } } else // Id not found { LOC_LOGE("%s:%d]: Error indication not found %d\n", __func__, __LINE__,(uint32_t)msg_id); } return; }

一樣到locClientHandleIndication里面進去看下: 
vendor/qcom/opensource/location/loc_api/loc_api_v02/loc_api_v02_client.c

static bool locClientHandleIndication( uint32_t indId, void* indBuffer, size_t indSize ) { bool status = falseswitch(indId) { ... //從這里開始就跟sv_status_cb走不1樣的flow了,這里需要care的id是QMI_LOC_EVENT_POSITION_REPORT_IND_V02 // handle position report case QMI_LOC_EVENT_POSITION_REPORT_IND_V02: { status = locClientHandlePosReportInd(indId, indBuffer, indSize); break; } ... return status; }

在往下看之前,有必要看1個數據結構,主要是為了存儲decorder出來的信息,具體以下(1個龐大的結構體,主要包括了會話狀態,經度,緯度,海拔,速度等信息): 
vendor/qcom/opensource/location/loc_api/loc_api_v02/location_service_v02.h

/** Indication Message; Sends the position report to the control point. */ typedef struct { /* Mandatory */ /* Session Status */ qmiLocSessionStatusEnumT_v02 sessionStatus; //session的狀態,具體值下面有列出 /**< Session status. Valid values: \n - eQMI_LOC_SESS_STATUS_SUCCESS (0) -- Session was successful - eQMI_LOC_SESS_STATUS_IN_PROGRESS (1) -- Session is still in progress; further position reports will be generated until either the fix criteria specified by the client are met or the client response timeout occurs - eQMI_LOC_SESS_STATUS_GENERAL_FAILURE (2) -- Session failed - eQMI_LOC_SESS_STATUS_TIMEOUT (3) -- Fix request failed because the session timed out - eQMI_LOC_SESS_STATUS_USER_END (4) -- Fix request failed because the session was ended by the user - eQMI_LOC_SESS_STATUS_BAD_PARAMETER (5) -- Fix request failed due to bad parameters in the request - eQMI_LOC_SESS_STATUS_PHONE_OFFLINE (6) -- Fix request failed because the phone is offline - eQMI_LOC_SESS_STATUS_ENGINE_LOCKED (7) -- Fix request failed because the engine is locked */ /* Mandatory */ /* Session ID */ uint8_t sessionId; /**< ID of the session that was specified in the Start request QMI_LOC_START_REQ. \n - Range: 0 to 255 */ /* Optional */ /* Latitude */ uint8_t latitude_valid; /**< Must be set to true if latitude is being passed */ double latitude; /**< Latitude (specified in WGS84 datum). \begin{itemize1} \item Type: Floating point \item Units: Degrees \item Range: ⑼0.0 to 90.0 \begin{itemize1} \item Positive values indicate northern latitude //北緯度是正數 \item Negative values indicate southern latitude //南緯度是負數 \vspace{-0.18in} \end{itemize1} \end{itemize1} */ /* Optional */ /* Longitude */ uint8_t longitude_valid; /**< Must be set to true if longitude is being passed */ double longitude; /**< Longitude (specified in WGS84 datum). \begin{itemize1} \item Type: Floating point \item Units: Degrees \item Range: ⑴80.0 to 180.0 \begin{itemize1} \item Positive values indicate eastern longitude //東經度是正數 \item Negative values indicate western longitude //西經度是負數 \vspace{-0.18in} \end{itemize1} \end{itemize1} */ /* Optional */ /* Circular Horizontal Position Uncertainty */ uint8_t horUncCircular_valid; /**< Must be set to true if horUncCircular is being passed */ float horUncCircular; /**< Horizontal position uncertainty (circular).\n - Units: Meters */ /* Optional */ /* Horizontal Elliptical Uncertainty (Semi-Minor Axis) */ uint8_t horUncEllipseSemiMinor_valid; /**< Must be set to true if horUncEllipseSemiMinor is being passed */ float horUncEllipseSemiMinor; /**< Semi-minor axis of horizontal elliptical uncertainty.\n - Units: Meters */ /* Optional */ /* Horizontal Elliptical Uncertainty (Semi-Major Axis) */ uint8_t horUncEllipseSemiMajor_valid; /**< Must be set to true if horUncEllipseSemiMajor is being passed */ float horUncEllipseSemiMajor; /**< Semi-major axis of horizontal elliptical uncertainty.\n - Units: Meters */ /* Optional */ /* Elliptical Horizontal Uncertainty Azimuth */ uint8_t horUncEllipseOrientAzimuth_valid; /**< Must be set to true if horUncEllipseOrientAzimuth is being passed */ float horUncEllipseOrientAzimuth; /**< Elliptical horizontal uncertainty azimuth of orientation.\n - Units: Decimal degrees \n - Range: 0 to 180 */ /* Optional */ /* Horizontal Confidence */ uint8_t horConfidence_valid; /**< Must be set to true if horConfidence is being passed */ uint8_t horConfidence; /**< Horizontal uncertainty confidence. If both elliptical and horizontal uncertainties are specified in this message, the confidence corresponds to the elliptical uncertainty. \n - Units: Percent \n - Range: 0 to 99 */ /* Optional */ /* Horizontal Reliability */ uint8_t horReliability_valid; /**< Must be set to true if horReliability is being passed */ qmiLocReliabilityEnumT_v02 horReliability; /**< Specifies the reliability of the horizontal position. Valid values: \n - eQMI_LOC_RELIABILITY_NOT_SET (0) -- Location reliability is not set - eQMI_LOC_RELIABILITY_VERY_LOW (1) -- Location reliability is very low; use it at your own risk - eQMI_LOC_RELIABILITY_LOW (2) -- Location reliability is low; little or no cross-checking is possible - eQMI_LOC_RELIABILITY_MEDIUM (3) -- Location reliability is medium; limited cross-check passed - eQMI_LOC_RELIABILITY_HIGH (4) -- Location reliability is high; strong cross-check passed */ /* Optional */ /* Horizontal Speed */ uint8_t speedHorizontal_valid; /**< Must be set to true if speedHorizontal is being passed */ float speedHorizontal; //水平速度,單位是m/s /**< Horizontal speed.\n - Units: Meters/second */ /* Optional */ /* Speed Uncertainty */ uint8_t speedUnc_valid; /**< Must be set to true if speedUnc is being passed */ float speedUnc; //3維速度,單位是m/s /**< 3-D Speed uncertainty.\n - Units: Meters/second */ /* Optional */ /* Altitude With Respect to Ellipsoid */ uint8_t altitudeWrtEllipsoid_valid; /**< Must be set to true if altitudeWrtEllipsoid is being passed */ float altitudeWrtEllipsoid; /**< Altitude with respect to the WGS84 ellipsoid.\n - Units: Meters \n - Range: ⑸00 to 15883 */ /* Optional */ /* Altitude With Respect to Sea Level */ uint8_t altitudeWrtMeanSeaLevel_valid; /**< Must be set to true if altitudeWrtMeanSeaLevel is being passed */ float altitudeWrtMeanSeaLevel; /**< Altitude with respect to mean sea level.\n - Units: Meters */ /* Optional */ /* Vertical Uncertainty */ uint8_t vertUnc_valid; /**< Must be set to true if vertUnc is being passed */ float vertUnc; /**< Vertical uncertainty.\n - Units: Meters */ /* Optional */ /* Vertical Confidence */ uint8_t vertConfidence_valid; /**< Must be set to true if vertConfidence is being passed */ uint8_t vertConfidence; /**< Vertical uncertainty confidence.\n - Units: Percent \n - Range: 0 to 99 */ /* Optional */ /* Vertical Reliability */ uint8_t vertReliability_valid; /**< Must be set to true if vertReliability is being passed */ qmiLocReliabilityEnumT_v02 vertReliability; /**< Specifies the reliability of the vertical position. Valid values: \n - eQMI_LOC_RELIABILITY_NOT_SET (0) -- Location reliability is not set - eQMI_LOC_RELIABILITY_VERY_LOW (1) -- Location reliability is very low; use it at your own risk - eQMI_LOC_RELIABILITY_LOW (2) -- Location reliability is low; little or no cross-checking is possible - eQMI_LOC_RELIABILITY_MEDIUM (3) -- Location reliability is medium; limited cross-check passed - eQMI_LOC_RELIABILITY_HIGH (4) -- Location reliability is high; strong cross-check passed */ /* Optional */ /* Vertical Speed */ uint8_t speedVertical_valid; /**< Must be set to true if speedVertical is being passed */ float speedVertical; //垂直速度,單位是m/s /**< Vertical speed.\n - Units: Meters/second */ /* Optional */ /* Heading */ uint8_t heading_valid; /**< Must be set to true if heading is being passed */ float heading; /**< Heading.\n - Units: Degrees \n - Range: 0 to 359.999 */ /* Optional */ /* Heading Uncertainty */ uint8_t headingUnc_valid; /**< Must be set to true if headingUnc is being passed */ float headingUnc; /**< Heading uncertainty.\n - Units: Degrees \n - Range: 0 to 359.999 */ /* Optional */ /* Magnetic Deviation */ uint8_t magneticDeviation_valid; /**< Must be set to true if magneticDeviation is being passed */ float magneticDeviation; /**< Difference between the bearing to true north and the bearing shown on a magnetic compass. The deviation is positive when the magnetic north is east of true north. */ /* Optional */ /* Technology Used */ uint8_t technologyMask_valid; /**< Must be set to true if technologyMask is being passed */ qmiLocPosTechMaskT_v02 technologyMask; //定位的方法,方式有衛星,基站,Wi-Fi,傳感器等等 /**< Technology used in computing this fix. Valid bitmasks: \n - QMI_LOC_POS_TECH_MASK_SATELLITE (0x00000001) -- Satellites were used to generate the fix - QMI_LOC_POS_TECH_MASK_CELLID (0x00000002) -- Cell towers were used to generate the fix - QMI_LOC_POS_TECH_MASK_WIFI (0x00000004) -- Wi-Fi access points were used to generate the fix - QMI_LOC_POS_TECH_MASK_SENSORS (0x00000008) -- Sensors were used to generate the fix - QMI_LOC_POS_TECH_MASK_REFERENCE_LOCATION (0x00000010) -- Reference Location was used to generate the fix - QMI_LOC_POS_TECH_MASK_INJECTED_COARSE_POSITION (0x00000020) -- Coarse position injected into the location engine was used to generate the fix - QMI_LOC_POS_TECH_MASK_AFLT (0x00000040) -- AFLT was used to generate the fix - QMI_LOC_POS_TECH_MASK_HYBRID (0x00000080) -- GNSS and Network-provided measurements were used to generate the fix */ /* Optional */ /* Dilution of Precision */ uint8_t DOP_valid; /**< Must be set to true if DOP is being passed */ qmiLocDOPStructT_v02 DOP; /**< \vspace{0.06in} \n Dilution of precision associated with this position. */ /* Optional */ /* UTC Timestamp */ uint8_t timestampUtc_valid; /**< Must be set to true if timestampUtc is being passed */ uint64_t timestampUtc; /**< UTC timestamp. \n - Units: Milliseconds since Jan. 1, 1970 */ /* Optional */ /* Leap Seconds */ uint8_t leapSeconds_valid; /**< Must be set to true if leapSeconds is being passed */ uint8_t leapSeconds; /**< Leap second information. If leapSeconds is not available, timestampUtc is calculated based on a hard-coded value for leap seconds. \n - Units: Seconds */ /* Optional */ /* GPS Time */ uint8_t gpsTime_valid; /**< Must be set to true if gpsTime is being passed */ qmiLocGPSTimeStructT_v02 gpsTime; /**< \vspace{0.06in} \n The number of weeks since Jan. 5, 1980, and milliseconds into the current week. */ /* Optional */ /* Time Uncertainty */ uint8_t timeUnc_valid; /**< Must be set to true if timeUnc is being passed */ float timeUnc; /**< Time uncertainty. \n - Units: Milliseconds */ /* Optional */ /* Time Source */ uint8_t timeSrc_valid; /**< Must be set to true if timeSrc is being passed */ qmiLocTimeSourceEnumT_v02 timeSrc; /**< Time source. Valid values: \n - eQMI_LOC_TIME_SRC_INVALID (0) -- Invalid time. - eQMI_LOC_TIME_SRC_NETWORK_TIME_TRANSFER (1) -- Time is set by the 1X system - eQMI_LOC_TIME_SRC_NETWORK_TIME_TAGGING (2) -- Time is set by WCDMA/GSM time tagging (i.e., associating network time with GPS time) - eQMI_LOC_TIME_SRC_EXTERNAL_INPUT (3) -- Time is set by an external injection - eQMI_LOC_TIME_SRC_TOW_DECODE (4) -- Time is set after decoding over-the-air GPS navigation data from one GPS satellite - eQMI_LOC_TIME_SRC_TOW_CONFIRMED (5) -- Time is set after decoding over-the-air GPS navigation data from multiple satellites - eQMI_LOC_TIME_SRC_TOW_AND_WEEK_CONFIRMED (6) -- Both time of the week and the GPS week number are known - eQMI_LOC_TIME_SRC_NAV_SOLUTION (7) -- Time is set by the position engine after the fix is obtained - eQMI_LOC_TIME_SRC_SOLVE_FOR_TIME (8) -- Time is set by the position engine after performing SFT; this is done when the clock time uncertainty is large - eQMI_LOC_TIME_SRC_GLO_TOW_DECODE (9) -- Time is set after decoding GLO satellites - eQMI_LOC_TIME_SRC_TIME_TRANSFORM (10) -- Time is set after transforming the GPS to GLO time - eQMI_LOC_TIME_SRC_WCDMA_SLEEP_TIME_TAGGING (11) -- Time is set by the sleep time tag provided by the WCDMA network - eQMI_LOC_TIME_SRC_GSM_SLEEP_TIME_TAGGING (12) -- Time is set by the sleep time tag provided by the GSM network - eQMI_LOC_TIME_SRC_UNKNOWN (13) -- Source of the time is unknown - eQMI_LOC_TIME_SRC_SYSTEM_TIMETICK (14) -- Time is derived from the system clock (better known as the slow clock); GNSS time is maintained irrespective of the GNSS receiver state - eQMI_LOC_TIME_SRC_QZSS_TOW_DECODE (15) -- Time is set after decoding QZSS satellites - eQMI_LOC_TIME_SRC_BDS_TOW_DECODE (16) -- Time is set after decoding BDS satellites */ /* Optional */ /* Sensor Data Usage */ uint8_t sensorDataUsage_valid; /**< Must be set to true if sensorDataUsage is being passed */ qmiLocSensorUsageIndicatorStructT_v02 sensorDataUsage; /**< \vspace{0.06in} \n Indicates whether sensor data was used in computing the position in this position report. */ /* Optional */ /* Fix Count for This Session */ uint8_t fixId_valid; /**< Must be set to true if fixId is being passed */ uint32_t fixId; /**< Fix count for the session. Starts with 0 and increments by one for each successive position report for a particular session. */ /* Optional */ /* SVs Used to Calculate the Fix */ uint8_t gnssSvUsedList_valid; /**< Must be set to true if gnssSvUsedList is being passed */ uint32_t gnssSvUsedList_len; /**< Must be set to # of elements in gnssSvUsedList */ uint16_t gnssSvUsedList[QMI_LOC_MAX_SV_USED_LIST_LENGTH_V02]; /**< Each entry in the list contains the SV ID of a satellite used for calculating this position report. The following information is associated with each SV ID: \n Range: \n - For GPS: 1 to 32 \n - For SBAS: 33 to 64 \n - For GLONASS: 65 to 96 \n - For QZSS: 193 to 197 \n - For BDS: 201 to 237 */ /* Optional */ /* Altitude Assumed */ uint8_t altitudeAssumed_valid; /**< Must be set to true if altitudeAssumed is being passed */ uint8_t altitudeAssumed; //FALSE說明海拔是計算出來的,TRUE說明海拔是推測的 /**< Indicates whether altitude is assumed or calculated: \begin{itemize1} \item 0x00 (FALSE) -- Altitude is calculated \item 0x01 (TRUE) -- Altitude is assumed; there may not be enough satellites to determine the precise altitude \vspace{-0.18in} \end{itemize1}*/ }qmiLocEventPositionReportIndMsgT_v02; /* Message */

跟locClientHandleSatReportInd的作用類似,locClientHandlePosReportInd的主要作用是打印position相應的信息,具體實現以下: 
vendor/qcom/opensource/location/loc_api/loc_api_v02/loc_api_v02_client.c

static bool locClientHandlePosReportInd ( uint32_t msg_id, const void* ind_buf, uint32_t ind_buf_len ) { // validate position report //把decorder出來的數據強轉成qmiLocEventPositionReportIndMsgT_v02*類型的 qmiLocEventPositionReportIndMsgT_v02 *posReport = (qmiLocEventPositionReportIndMsgT_v02 *)ind_buf; //打印相應的position信息 LOC_LOGV ("%s:%d]: len = %d lat = %f, lon = %f, alt = %f\n", __func__, __LINE__, ind_buf_len, posReport->latitude, posReport->longitude, posReport->altitudeWrtEllipsoid); return true; }

localEventCallback終究綁定的是globalEventCb,具體在《gps搜星流程(下)》有講過,這里就不再講了,我們直接來看globalEventCb: 
vendor/qcom/opensource/location/loc_api/loc_api_v02/LocApiV02.cpp

static void globalEventCb(locClientHandleType clientHandle, uint32_t eventId, const locClientEventIndUnionType eventPayload, void* pClientCookie) { MODEM_LOG_CALLFLOW(%s, loc_get_v02_event_name(eventId)); LocApiV02 *locApiV02Instance = (LocApiV02 *)pClientCookie; LOC_LOGV ("%s:%d] client = %p, event id = %d, client cookie ptr = %p\n", __func__, __LINE__, clientHandle, eventId, pClientCookie); // return if null is passed if( NULL == locApiV02Instance) { LOC_LOGE ("%s:%d] NULL object passed : client = %p, event id = %d\n", __func__, __LINE__, clientHandle, eventId); return; } locApiV02Instance->eventCb(clientHandle, eventId, eventPayload); }

看下eventCb的具體實現: 
vendor/qcom/opensource/location/loc_api/loc_api_v02/LocApiV02.cpp

/* event callback registered with the loc_api v02 interface */ void LocApiV02 :: eventCb(locClientHandleType clientHandle, uint32_t eventId, locClientEventIndUnionType eventPayload) { LOC_LOGD("%s:%d]: event id = %d\n", __func__, __LINE__, eventId); switch(eventId) { ... //跟搜星流程不1樣了哦,這里是position report,不是satellite report了哈 //Position Report case QMI_LOC_EVENT_POSITION_REPORT_IND_V02: reportPosition(eventPayload.pPositionReportEvent); break; ... } }

在看reportPosition之前,有兩個結構體需要介紹1下: 
1:loc eng層能辨認的position格式UlpLocation: 
hardware/qcom/gps/core/gps_extended_c.h

typedef struct { /** set to sizeof(UlpLocation) */ size_t size; GpsLocation gpsLocation; //看到了沒,HAL層能辨認的GpsLocation類型!!! /* Provider indicator for HYBRID or GPS */ uint16_t position_source; /*allows HAL to pass additional information related to the location */ int rawDataSize; /* in # of bytes */ void * rawData; bool is_indoor; float floor_number; char map_url[GPS_LOCATION_MAP_URL_SIZE]; unsigned char map_index[GPS_LOCATION_MAP_INDEX_SIZE]; } UlpLocation;

2:HAL層能夠辨認的position格式GpsLocation: 
hardware/libhardware/include/hardware/gps.h

/** Represents a location. */ typedef struct { /** set to sizeof(GpsLocation) */ size_t size; /** Contains GpsLocationFlags bits. */ uint16_t flags; /** Represents latitude in degrees. */ double latitude; /** Represents longitude in degrees. */ double longitude; /** Represents altitude in meters above the WGS 84 reference * ellipsoid. */ double altitude; /** Represents speed in meters per second. */ float speed; /** Represents heading in degrees. */ float bearing; /** Represents expected accuracy in meters. */ float accuracy; /** Timestamp for the location fix. */ GpsUtcTime timestamp; } GpsLocation;

繼續跟進看下reportPosition的具體實現: 
vendor/qcom/opensource/location/loc_api/loc_api_v02/LocApiV02.cpp

/* convert position report to loc eng format and send the converted position to loc eng */ void LocApiV02 :: reportPosition ( const qmiLocEventPositionReportIndMsgT_v02 *location_report_ptr) { //從傳入的參數可以看到,loc_api層用的position類型是qmiLocEventPositionReportIndMsgT_v02*類型的 //UlpLocation類型,這個是給loc eng層用的哈,所以可以猜想這個函數的作用是: //把qmiLocEventPositionReportIndMsgT_v02逐漸填充到UlpLocation中,然后傳遞給loc eng層 UlpLocation location; LocPosTechMask tech_Mask = LOC_POS_TECH_MASK_DEFAULT; LOC_LOGD("Reporting postion from V2 Adapter\n"); memset(&location, 0sizeof (UlpLocation)); location.size = sizeof(location); GpsLocationExtended locationExtended; memset(&locationExtended, 0sizeof (GpsLocationExtended)); locationExtended.size = sizeof(locationExtended); // Process the position from final and intermediate reports if( (location_report_ptr->sessionStatus == eQMI_LOC_SESS_STATUS_SUCCESS_V02) || (location_report_ptr->sessionStatus == eQMI_LOC_SESS_STATUS_IN_PROGRESS_V02) ) { // Latitude & Longitude if( (location_report_ptr->latitude_valid == 1 ) && (location_report_ptr->longitude_valid == 1) && (location_report_ptr->latitude != 0 || location_report_ptr->longitude!= 0)) { //看見沒?開始填充了UlpLocation類型了,這里填充的是flags,latitude,longtitude3個 //這里gpsLocation是GpsLocation類型的,所以1步到位直接填充的是HAL層能辨認的GpsLocation類型 location.gpsLocation.flags |= GPS_LOCATION_HAS_LAT_LONG; location.gpsLocation.latitude = location_report_ptr->latitude; location.gpsLocation.longitude = location_report_ptr->longitude; // Time stamp (UTC) if(location_report_ptr->timestampUtc_valid == 1) { //如果timestampUtc是可用的,則填充到GpsLocation的timestamp location.gpsLocation.timestamp = location_report_ptr->timestampUtc; } // Altitude if(location_report_ptr->altitudeWrtEllipsoid_valid == 1 ) { //填充GpsLocation的altitude location.gpsLocation.flags |= GPS_LOCATION_HAS_ALTITUDE; location.gpsLocation.altitude = location_report_ptr->altitudeWrtEllipsoid; } // Speed if((location_report_ptr->speedHorizontal_valid == 1) && (location_report_ptr->speedVertical_valid ==1 ) ) { //原來GpsLocation的速度是用勾股定理算出來的,水平速度和海拔速度的平方和開根號 location.gpsLocation.flags |= GPS_LOCATION_HAS_SPEED; location.gpsLocation.speed = sqrt( (location_report_ptr->speedHorizontal * location_report_ptr->speedHorizontal) + (location_report_ptr->speedVertical * location_report_ptr->speedVertical) ); } // Heading if(location_report_ptr->heading_valid == 1) { location.gpsLocation.flags |= GPS_LOCATION_HAS_BEARING; location.gpsLocation.bearing = location_report_ptr->heading; } // Uncertainty (circular) if( (location_report_ptr->horUncCircular_valid ) ) { //GpsLocation的精度,單位是m location.gpsLocation.flags |= GPS_LOCATION_HAS_ACCURACY; location.gpsLocation.accuracy = location_report_ptr->horUncCircular; } // Technology Mask tech_Mask |= location_report_ptr->technologyMask; //Mark the location source as from GNSS location.gpsLocation.flags |= LOCATION_HAS_SOURCE_INFO; //填充UlpLocation的position_source location.position_source = ULP_LOCATION_IS_FROM_GNSS; if (location_report_ptr->magneticDeviation_valid) { locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_MAG_DEV; locationExtended.magneticDeviation = location_report_ptr->magneticDeviation; } if (location_report_ptr->DOP_valid) { locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_DOP; locationExtended.pdop = location_report_ptr->DOP.PDOP; locationExtended.hdop = location_report_ptr->DOP.HDOP; locationExtended.vdop = location_report_ptr->DOP.VDOP; } if (location_report_ptr->altitudeWrtMeanSeaLevel_valid) { locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL; locationExtended.altitudeMeanSeaLevel = location_report_ptr->altitudeWrtMeanSeaLevel; } if (location_report_ptr->vertUnc_valid) { locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_VERT_UNC; locationExtended.vert_unc = location_report_ptr->vertUnc; } if (location_report_ptr->speedUnc_valid ) { locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_SPEED_UNC; locationExtended.speed_unc = location_report_ptr->speedUnc; } //經過上面的1堆填充,總算拿到了完全的UlpLocation數據,固然也就包括了完全的GpsLocation數據, //然后調用LocApiBase::reportPosition,帶著UlpLocation的數據進入到了loc eng層哈 LocApiBase::reportPosition( location, locationExtended, (void*)location_report_ptr, (location_report_ptr->sessionStatus == eQMI_LOC_SESS_STATUS_IN_PROGRESS_V02 ? LOC_SESS_INTERMEDIATE : LOC_SESS_SUCCESS), tech_Mask); } } else { LocApiBase::reportPosition(location, locationExtended, NULL, LOC_SESS_FAILURE); LOC_LOGD("%s:%d]: Ignoring position report with sess status = %d, " "fix id = %u\n", __func__, __LINE__, location_report_ptr->sessionStatus, location_report_ptr->fixId ); } }

繼續跟進LocApiBase::reportPosition的實現: 
hardware/qcom/gps/core/LocApiBase.cpp

void LocApiBase::reportPosition(UlpLocation &location, GpsLocationExtended &locationExtended, void* locationExt, enum loc_sess_status status, LocPosTechMask loc_technology_mask) { // loop through adapters, and deliver to all adapters. TO_ALL_LOCADAPTERS( mLocAdapters[i]->reportPosition(location, locationExtended, locationExt, status, loc_technology_mask) ); }

TO_ALL_LOCADAPTERS的define前面有講過,這里就不再贅述了,直接看下LocAdapterBase的reportPosition具體定義: 
hardware/qcom/gps/core/LocAdapterBase.h

class LocAdapterBase { ... public//帶著UlpLocation類型的參數,postion的數據就這么傳到了loc eng層 virtual void reportPosition(UlpLocation &location, GpsLocationExtended &locationExtended, void* locationExt, enum loc_sess_status sta

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 国产高清1024永久免费 | 日本高清69| 国内精品久久久久激情影院 | 欧美福利视频在线 | 第一福利视频网 | www.日本xxxx | 成年人视频在线观看免费 | 欧美精品99毛片免费高清观看 | 8av国产精品爽爽ⅴa在线观看 | 亚洲国产欧美日韩一区二区 | h网站免费在线观看 | 叼嘿在线观看 | 国产成人毛片亚洲精品不卡 | 国产亚洲精品九九久在线观看 | 欧美国产成人在线 | 国产高清视频免费人人爱 | 国内精品18videosex性欧美 | 亚洲午夜免费视频 | 欧美性网站 | 影音先锋成人影院 | 亚洲天堂777| 欧美亚洲网站 | 国产精品新婚门 | 久久本网站受美利坚法律保护 | 一级空姐毛片 | 一区小说二区另类小说三区图 | 国产精品亚洲第一区二区三区 | 多人做人爱视频大全在线观看 | 在线亚洲国产精品区 | 国产在线视频一区 | 中文字幕久久久久一区 | 亚洲免费精品视频 | 国产成人精品免费视频网页大全 | 久久91精品国产91久 | 看一级毛片一区二区三区免费 | 东京干男人都知道的网站 | jzz欧美| 色干综合 | 成人欧美精品久久久久影院 | 校园春色自拍偷拍 | 亚洲好视频 |