GPS HAL: support config multi-band of GNSS constellation

Configure multi-band of GNSS constellation and retrieve the
constellation configure

Change-Id: I8d37c1478c74d5742b4d59ec8ce773b5d073b576
CRs-fixed: 2723496
diff --git a/core/LocApiBase.cpp b/core/LocApiBase.cpp
index 47f89dd..3f15d69 100644
--- a/core/LocApiBase.cpp
+++ b/core/LocApiBase.cpp
@@ -717,7 +717,8 @@
 LocationError LocApiBase::setBlacklistSvSync(const GnssSvIdConfig& /*config*/)
 DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
 
-void LocApiBase::setBlacklistSv(const GnssSvIdConfig& /*config*/)
+void LocApiBase::setBlacklistSv(const GnssSvIdConfig& /*config*/,
+                                LocApiResponse* /*adapterResponse*/)
 DEFAULT_IMPL()
 
 void LocApiBase::getBlacklistSv()
@@ -780,4 +781,12 @@
     getParameter(uint32_t sessionId, GnssConfigFlagsMask flags, LocApiResponse* /*adapterResponse*/)
 DEFAULT_IMPL()
 
+void LocApiBase::
+    configConstellationMultiBand(const GnssSvTypeConfig& secondaryBandConfig,
+                                 LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::
+    getConstellationMultiBandConfig(uint32_t sessionId, LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
 } // namespace loc_core
diff --git a/core/LocApiBase.h b/core/LocApiBase.h
index 0d8f3a4..fbfd0bd 100644
--- a/core/LocApiBase.h
+++ b/core/LocApiBase.h
@@ -288,7 +288,8 @@
 
     /* Requests for SV/Constellation Control */
     virtual LocationError setBlacklistSvSync(const GnssSvIdConfig& config);
-    virtual void setBlacklistSv(const GnssSvIdConfig& config);
+    virtual void setBlacklistSv(const GnssSvIdConfig& config,
+                                LocApiResponse *adapterResponse=nullptr);
     virtual void getBlacklistSv();
     virtual void setConstellationControl(const GnssSvTypeConfig& config,
                                          LocApiResponse *adapterResponse=nullptr);
@@ -313,6 +314,11 @@
     virtual LocationError setParameterSync(const GnssConfig & gnssConfig);
     virtual void getParameter(uint32_t sessionId, GnssConfigFlagsMask flags,
                               LocApiResponse* adapterResponse=nullptr);
+
+    virtual void configConstellationMultiBand(const GnssSvTypeConfig& secondaryBandConfig,
+                                              LocApiResponse* adapterResponse=nullptr);
+    virtual void getConstellationMultiBandConfig(uint32_t sessionId,
+                                        LocApiResponse* adapterResponse=nullptr);
 };
 
 typedef LocApiBase* (getLocApi_t)(LOC_API_ADAPTER_EVENT_MASK_T exMask,
diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp
index dc5288c..58f7bc5 100644
--- a/gnss/GnssAdapter.cpp
+++ b/gnss/GnssAdapter.cpp
@@ -86,6 +86,7 @@
     mPowerVoteId(0),
     mNmeaMask(0),
     mGnssSvIdConfig(),
+    mGnssSeconaryBandConfig(),
     mGnssSvTypeConfig(),
     mGnssSvTypeConfigCb(nullptr),
     mLocConfigInfo{},
@@ -1433,6 +1434,19 @@
     return mLocApi->setBlacklistSvSync(mGnssSvIdConfig);
 }
 
+void
+GnssAdapter::gnssSecondaryBandConfigUpdate(LocApiResponse* locApiResponse)
+{
+    LOC_LOGd("secondary band config, size %d, enabled constellation 0x%" PRIx64 ","
+             "disabled constellation 0x%" PRIx64 "", mGnssSeconaryBandConfig.size,
+             mGnssSeconaryBandConfig.enabledSvTypesMask,
+             mGnssSeconaryBandConfig.blacklistedSvTypesMask);
+    if (mGnssSeconaryBandConfig.size == sizeof(mGnssSeconaryBandConfig)) {
+        // Now set required secondary band config
+        mLocApi->configConstellationMultiBand(mGnssSeconaryBandConfig, locApiResponse);
+    }
+}
+
 uint32_t*
 GnssAdapter::gnssGetConfigCommand(GnssConfigFlagsMask configMask) {
 
@@ -1663,18 +1677,17 @@
                 // SBAS does not support enable/disable whole constellation
                 // so do not set up svTypeMask for SBAS
                 svMaskPtr = &config.sbasBlacklistSvMask;
-                // SBAS currently has two ranges
-                // range of SV id: 120 to 158 and 183 to 191
+                // SBAS currently has two ranges, [120, 158] and [183, 191]
                 if (0 == source.svId) {
                     LOC_LOGd("blacklist all SBAS SV");
                 } else if (source.svId >= GNSS_SV_CONFIG_SBAS_INITIAL2_SV_ID) {
-                    // handle SV id in range of 183 to 191
+                    // handle SV id in range [183, 191]
                     initialSvId = GNSS_SV_CONFIG_SBAS_INITIAL2_SV_ID;
                     svIndexOffset = GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH;
                 } else if ((source.svId >= GNSS_SV_CONFIG_SBAS_INITIAL_SV_ID) &&
                            (source.svId < (GNSS_SV_CONFIG_SBAS_INITIAL_SV_ID +
                                            GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH))){
-                        // handle SV id in range of 120 to 158
+                        // handle SV id in range of [120, 158]
                         initialSvId = GNSS_SV_CONFIG_SBAS_INITIAL_SV_ID;
                     } else {
                         LOC_LOGe("invalid SBAS sv id %d", source.svId);
@@ -1718,8 +1731,8 @@
 
     LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64
             ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64 ", sbas 0x%" PRIx64 ", navic 0x%" PRIx64,
-            config.bdsBlacklistSvMask, config.gloBlacklistSvMask,
-            config.qzssBlacklistSvMask, config.galBlacklistSvMask,
+             config.bdsBlacklistSvMask, config.gloBlacklistSvMask,
+             config.qzssBlacklistSvMask, config.galBlacklistSvMask,
             config.sbasBlacklistSvMask, config.navicBlacklistSvMask);
 
     return retVal;
@@ -1750,16 +1763,27 @@
                 GNSS_SV_CONFIG_QZSS_INITIAL_SV_ID, GNSS_SV_TYPE_QZSS);
     }
     if (svConfig.sbasBlacklistSvMask) {
+        // SBAS - SV 120 to 158, maps to 0 to 38
+        //        SV 183 to 191, maps to 39 to 47
+        uint64_t sbasBlacklistSvMask = svConfig.sbasBlacklistSvMask;
+        // operate on 120 and 158 first
+        sbasBlacklistSvMask <<= (64 - GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH);
+        sbasBlacklistSvMask >>= (64 - GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH);
         convertGnssSvIdMaskToList(
-                svConfig.sbasBlacklistSvMask, blacklistedSvIds,
+                sbasBlacklistSvMask, blacklistedSvIds,
                 GNSS_SV_CONFIG_SBAS_INITIAL_SV_ID, GNSS_SV_TYPE_SBAS);
+        // operate on the second range
+        sbasBlacklistSvMask = svConfig.sbasBlacklistSvMask;
+        sbasBlacklistSvMask >>= GNSS_SV_CONFIG_SBAS_INITIAL_SV_LENGTH;
+        convertGnssSvIdMaskToList(
+                sbasBlacklistSvMask, blacklistedSvIds,
+                GNSS_SV_CONFIG_SBAS_INITIAL2_SV_ID, GNSS_SV_TYPE_SBAS);
     }
     if (svConfig.navicBlacklistSvMask) {
         convertGnssSvIdMaskToList(
                 svConfig.navicBlacklistSvMask, blacklistedSvIds,
                 GNSS_SV_CONFIG_NAVIC_INITIAL_SV_ID, GNSS_SV_TYPE_NAVIC);
     }
-
 }
 
 void GnssAdapter::convertGnssSvIdMaskToList(
@@ -2419,6 +2443,7 @@
             mAdapter.broadcastCapabilities(mAdapter.getCapabilities());
             mAdapter.gnssSvIdConfigUpdate();
             mAdapter.gnssSvTypeConfigUpdate();
+            mAdapter.gnssSecondaryBandConfigUpdate();
             mAdapter.updatePowerState(mAdapter.getPowerState());
 
             // restart sessions
@@ -5297,42 +5322,54 @@
     return sessionId;
 }
 
-void
-GnssAdapter::updateSvConfig(uint32_t         sessionId,
-                            const GnssSvTypeConfig& svTypeConfig,
-                            const GnssSvIdConfig&   svIdConfig) {
+void GnssAdapter::gnssUpdateSvConfig(
+        uint32_t sessionId, const GnssSvTypeConfig& constellationEnablementConfig,
+        const GnssSvIdConfig&   blacklistSvConfig) {
 
-    // check whether if any constellation is removed from the new config
-    GnssSvTypesMask enabledRemoved = mGnssSvTypeConfig.enabledSvTypesMask &
-            (mGnssSvTypeConfig.enabledSvTypesMask ^ svTypeConfig.enabledSvTypesMask);
-    // Send reset if any constellation is removed from the enabled list
-    if (enabledRemoved != 0) {
+    // suspend all tracking sessions to apply the constellation config
+    suspendSessions();
+    if (constellationEnablementConfig.size == sizeof(constellationEnablementConfig)) {
+        // check whether if any constellation is removed from the new config
+        GnssSvTypesMask currentEnabledMask = mGnssSvTypeConfig.enabledSvTypesMask;
+        GnssSvTypesMask newEnabledMask = constellationEnablementConfig.enabledSvTypesMask;
+        GnssSvTypesMask enabledRemoved = currentEnabledMask & (currentEnabledMask ^ newEnabledMask);
+        // Send reset if any constellation is removed from the enabled list
+        if (enabledRemoved != 0) {
+            mLocApi->resetConstellationControl();
+        }
+
+        // if the constellation config is valid, issue request to modem
+        // to enable/disable constellation
+        mLocApi->setConstellationControl(mGnssSvTypeConfig);
+    } else if (constellationEnablementConfig.size == 0) {
+        // when the size is not set, meaning reset to modem default
         mLocApi->resetConstellationControl();
     }
+    // save the constellation settings to be used for modem SSR
+    mGnssSvTypeConfig = constellationEnablementConfig;
 
-    mGnssSvTypeConfig = svTypeConfig;
-    mGnssSvIdConfig   = svIdConfig;
+    // handle blacklisted SV settings
+    mGnssSvIdConfig   = blacklistSvConfig;
+    // process blacklist svs info
     mBlacklistedSvIds.clear();
-    convertFromGnssSvIdConfig(svIdConfig, mBlacklistedSvIds);
-
-    // Send blacklist info
-    mLocApi->setBlacklistSv(mGnssSvIdConfig);
-
-    // Send only enabled constellation config
-    GnssSvTypeConfig svTypeConfigCopy = {sizeof(GnssSvTypeConfig), 0, 0};
-    svTypeConfigCopy.enabledSvTypesMask = mGnssSvTypeConfig.enabledSvTypesMask;
+    // need to save the balcklisted sv info into mBlacklistedSvIds as well
+    convertFromGnssSvIdConfig(blacklistSvConfig, mBlacklistedSvIds);
     LocApiResponse* locApiResponse = new LocApiResponse(*getContext(),
             [this, sessionId] (LocationError err) {
             reportResponse(err, sessionId);});
     if (!locApiResponse) {
         LOC_LOGe("memory alloc failed");
     }
-    mLocApi->setConstellationControl(svTypeConfigCopy, locApiResponse);
+    mLocApi->setBlacklistSv(mGnssSvIdConfig, locApiResponse);
+
+    // resume all tracking sessions after the constellation config has been applied
+    restartSessions(false);
 }
 
-uint32_t GnssAdapter::gnssUpdateSvConfigCommand(
-        const GnssSvTypeConfig& svTypeConfig,
-        const GnssSvIdConfig& svIdConfig) {
+uint32_t
+GnssAdapter::gnssUpdateSvConfigCommand(
+        const GnssSvTypeConfig& constellationEnablementConfig,
+        const GnssSvIdConfig& blacklistSvConfig) {
 
     // generated session id will be none-zero
     uint32_t sessionId = generateSessionId();
@@ -5341,78 +5378,115 @@
     struct MsgUpdateSvConfig : public LocMsg {
         GnssAdapter&     mAdapter;
         uint32_t         mSessionId;
-        GnssSvTypeConfig mSvTypeConfig;
-        GnssSvIdConfig   mSvIdConfig;
+        GnssSvTypeConfig mConstellationEnablementConfig;
+        GnssSvIdConfig   mBlacklistSvIdConfig;
 
         inline MsgUpdateSvConfig(GnssAdapter& adapter,
                                  uint32_t sessionId,
-                                 const GnssSvTypeConfig& svTypeConfig,
-                                 const GnssSvIdConfig& svIdConfig) :
+                                 const GnssSvTypeConfig& constellationEnablementConfig,
+                                 const GnssSvIdConfig& blacklistSvConfig) :
             LocMsg(),
             mAdapter(adapter),
             mSessionId(sessionId),
-            mSvTypeConfig(svTypeConfig),
-            mSvIdConfig(svIdConfig) {}
+            mConstellationEnablementConfig(constellationEnablementConfig),
+            mBlacklistSvIdConfig(blacklistSvConfig) {}
         inline virtual void proc() const {
-            mAdapter.updateSvConfig(mSessionId, mSvTypeConfig, mSvIdConfig);
+            mAdapter.gnssUpdateSvConfig(mSessionId, mConstellationEnablementConfig,
+                                        mBlacklistSvIdConfig);
         }
     };
 
     if (sessionId != 0) {
-        sendMsg(new MsgUpdateSvConfig(*this, sessionId,
-                                       svTypeConfig, svIdConfig));
+        sendMsg(new MsgUpdateSvConfig(*this, sessionId, constellationEnablementConfig,
+                                      blacklistSvConfig));
     }
     return sessionId;
 }
 
-void
-GnssAdapter::resetSvConfig(uint32_t sessionId) {
+void GnssAdapter::gnssUpdateSecondaryBandConfig(
+        uint32_t sessionId, const GnssSvTypeConfig& secondaryBandConfig) {
 
-    // Clear blacklisting
-    memset(&mGnssSvIdConfig, 0, sizeof(GnssSvIdConfig));
-    mGnssSvIdConfig.size = sizeof(mGnssSvIdConfig);
-    mBlacklistedSvIds.clear();
-    gnssSvIdConfigUpdate();
-
-    // Reset constellation config, including mGnssSvTypeConfig
-    // when size is set to 0, upon subsequent modem restart, sv type
-    // config will not be sent down to modem
-    gnssSetSvTypeConfig({sizeof(GnssSvTypeConfig), 0, 0});
-
-    LocApiResponse* locApiResponse = nullptr;
-    if (sessionId != 0) {
-        locApiResponse =
-                new LocApiResponse(*getContext(),
-                                   [this, sessionId] (LocationError err) {
-                                   reportResponse(err, sessionId);});
-        if (!locApiResponse) {
-            LOC_LOGe("memory alloc failed");
-        }
+    LocApiResponse* locApiResponse = new LocApiResponse(*getContext(),
+            [this, sessionId] (LocationError err) {
+            reportResponse(err, sessionId);});
+    if (!locApiResponse) {
+        LOC_LOGe("memory alloc failed");
     }
-    mLocApi->resetConstellationControl(locApiResponse);
+
+    // handle secondary band info
+    mGnssSeconaryBandConfig = secondaryBandConfig;
+    gnssSecondaryBandConfigUpdate(locApiResponse);
 }
 
-uint32_t GnssAdapter::gnssResetSvConfigCommand() {
+uint32_t
+GnssAdapter::gnssUpdateSecondaryBandConfigCommand(
+        const GnssSvTypeConfig& secondaryBandConfig) {
 
     // generated session id will be none-zero
     uint32_t sessionId = generateSessionId();
     LOC_LOGd("session id %u", sessionId);
 
-    struct MsgResetSvConfig : public LocMsg {
+    struct MsgUpdateSecondaryBandConfig : public LocMsg {
         GnssAdapter&     mAdapter;
         uint32_t         mSessionId;
+        GnssSvTypeConfig mSecondaryBandConfig;
 
-        inline MsgResetSvConfig(GnssAdapter& adapter,
-                                uint32_t sessionId) :
+        inline MsgUpdateSecondaryBandConfig(GnssAdapter& adapter,
+                                 uint32_t sessionId,
+                                 const GnssSvTypeConfig& secondaryBandConfig) :
+            LocMsg(),
+            mAdapter(adapter),
+            mSessionId(sessionId),
+            mSecondaryBandConfig(secondaryBandConfig) {}
+        inline virtual void proc() const {
+            mAdapter.gnssUpdateSecondaryBandConfig(mSessionId,  mSecondaryBandConfig);
+        }
+    };
+
+    if (sessionId != 0) {
+        sendMsg(new MsgUpdateSecondaryBandConfig(*this, sessionId, secondaryBandConfig));
+    }
+    return sessionId;
+}
+
+// This function currently retrieves secondary band configuration
+// for constellation enablement/disablement.
+void
+GnssAdapter::gnssGetSecondaryBandConfig(uint32_t sessionId) {
+
+    LocApiResponse* locApiResponse = new LocApiResponse(*getContext(),
+            [this, sessionId] (LocationError err) {
+            reportResponse(err, sessionId);});
+    if (!locApiResponse) {
+        LOC_LOGe("memory alloc failed");
+    }
+
+    mLocApi->getConstellationMultiBandConfig(sessionId, locApiResponse);
+}
+
+uint32_t
+GnssAdapter::gnssGetSecondaryBandConfigCommand() {
+
+    // generated session id will be none-zero
+    uint32_t sessionId = generateSessionId();
+    LOC_LOGd("session id %u", sessionId);
+
+    struct MsgGetSecondaryBandConfig : public LocMsg {
+        GnssAdapter& mAdapter;
+        uint32_t     mSessionId;
+        inline MsgGetSecondaryBandConfig(GnssAdapter& adapter,
+                              uint32_t sessionId) :
             LocMsg(),
             mAdapter(adapter),
             mSessionId(sessionId) {}
         inline virtual void proc() const {
-            mAdapter.resetSvConfig(mSessionId);
+            mAdapter.gnssGetSecondaryBandConfig(mSessionId);
         }
     };
 
-    sendMsg(new MsgResetSvConfig(*this, sessionId));
+    if (sessionId != 0) {
+        sendMsg(new MsgGetSecondaryBandConfig(*this, sessionId));
+    }
     return sessionId;
 }
 
diff --git a/gnss/GnssAdapter.h b/gnss/GnssAdapter.h
index 7a18433..ba20eb1 100644
--- a/gnss/GnssAdapter.h
+++ b/gnss/GnssAdapter.h
@@ -193,6 +193,7 @@
     uint32_t mNmeaMask;
     uint64_t mPrevNmeaRptTimeNsec;
     GnssSvIdConfig mGnssSvIdConfig;
+    GnssSvTypeConfig mGnssSeconaryBandConfig;
     GnssSvTypeConfig mGnssSvTypeConfig;
     GnssSvTypeConfigCallback mGnssSvTypeConfigCb;
     LocIntegrationConfigInfo mLocConfigInfo;
@@ -318,8 +319,13 @@
     void setConstrainedTunc(bool enable, float tuncConstraint,
                             uint32_t energyBudget, uint32_t sessionId);
     void setPositionAssistedClockEstimator(bool enable, uint32_t sessionId);
-    void updateSvConfig(uint32_t sessionId, const GnssSvTypeConfig& svTypeConfig,
-                        const GnssSvIdConfig& svIdConfig);
+    void gnssUpdateSvConfig(uint32_t sessionId,
+                        const GnssSvTypeConfig& constellationEnablementConfig,
+                        const GnssSvIdConfig& blacklistSvConfig);
+
+    void gnssUpdateSecondaryBandConfig(
+        uint32_t sessionId, const GnssSvTypeConfig& secondaryBandConfig);
+    void gnssGetSecondaryBandConfig(uint32_t sessionId);
     void resetSvConfig(uint32_t sessionId);
     void configLeverArm(uint32_t sessionId, const LeverArmConfigInfo& configInfo);
     void configRobustLocation(uint32_t sessionId, bool enable, bool enableForE911);
@@ -372,6 +378,7 @@
     { mGnssSvTypeConfigCb = callback; }
     inline GnssSvTypeConfigCallback gnssGetSvTypeConfigCallback()
     { return mGnssSvTypeConfigCb; }
+    void gnssSecondaryBandConfigUpdate(LocApiResponse* locApiResponse= nullptr);
 
     /* ========= AGPS ====================================================================== */
     /* ======== COMMANDS ====(Called from Client Thread)==================================== */
@@ -385,9 +392,11 @@
     uint32_t setConstrainedTuncCommand (bool enable, float tuncConstraint,
                                         uint32_t energyBudget);
     uint32_t setPositionAssistedClockEstimatorCommand (bool enable);
-    uint32_t gnssUpdateSvConfigCommand(const GnssSvTypeConfig& svTypeConfig,
-                                       const GnssSvIdConfig& svIdConfig);
-    uint32_t gnssResetSvConfigCommand();
+    uint32_t gnssUpdateSvConfigCommand(const GnssSvTypeConfig& constellationEnablementConfig,
+                                       const GnssSvIdConfig& blacklistSvConfig);
+    uint32_t gnssUpdateSecondaryBandConfigCommand(
+                                       const GnssSvTypeConfig& secondaryBandConfig);
+    uint32_t gnssGetSecondaryBandConfigCommand();
     uint32_t configLeverArmCommand(const LeverArmConfigInfo& configInfo);
     uint32_t configRobustLocationCommand(bool enable, bool enableForE911);
     uint32_t configMinGpsWeekCommand(uint16_t minGpsWeek);
diff --git a/gnss/location_gnss.cpp b/gnss/location_gnss.cpp
index f914b24..d29840a 100644
--- a/gnss/location_gnss.cpp
+++ b/gnss/location_gnss.cpp
@@ -79,13 +79,14 @@
                      int blockDurationMsec, double latLonDiffThreshold);
 static void updateBatteryStatus(bool charging);
 static void updatePowerState(PowerStateType powerState);
-static uint32_t gnssUpdateSvConfig(const GnssSvTypeConfig& svTypeConfig,
-                                   const GnssSvIdConfig& svIdConfig);
-static uint32_t gnssResetSvConfig();
+static uint32_t gnssUpdateSvConfig(const GnssSvTypeConfig& constellationEnablementConfig,
+                                   const GnssSvIdConfig& blacklistSvConfig);
 static uint32_t configLeverArm(const LeverArmConfigInfo& configInfo);
 static uint32_t configRobustLocation(bool enable, bool enableForE911);
 static uint32_t configMinGpsWeek(uint16_t minGpsWeek);
 static uint32_t configDeadReckoningEngineParams(const DeadReckoningEngineConfig& dreConfig);
+static uint32_t gnssUpdateSecondaryBandConfig(const GnssSvTypeConfig& secondaryBandConfig);
+static uint32_t gnssGetSecondaryBandConfig();
 
 static const GnssInterface gGnssInterface = {
     sizeof(GnssInterface),
@@ -126,11 +127,12 @@
     setConstrainedTunc,
     setPositionAssistedClockEstimator,
     gnssUpdateSvConfig,
-    gnssResetSvConfig,
     configLeverArm,
     configRobustLocation,
     configMinGpsWeek,
     configDeadReckoningEngineParams,
+    gnssUpdateSecondaryBandConfig,
+    gnssGetSecondaryBandConfig,
 };
 
 #ifndef DEBUG_X86
@@ -407,19 +409,11 @@
 }
 
 static uint32_t gnssUpdateSvConfig(
-        const GnssSvTypeConfig& svTypeConfig,
-        const GnssSvIdConfig& svIdConfig) {
+        const GnssSvTypeConfig& constellationEnablementConfig,
+        const GnssSvIdConfig&   blacklistSvConfig) {
     if (NULL != gGnssAdapter) {
         return gGnssAdapter->gnssUpdateSvConfigCommand(
-                svTypeConfig, svIdConfig);
-    } else {
-        return 0;
-    }
-}
-
-static uint32_t gnssResetSvConfig() {
-    if (NULL != gGnssAdapter) {
-        return gGnssAdapter->gnssResetSvConfigCommand();
+                constellationEnablementConfig, blacklistSvConfig);
     } else {
         return 0;
     }
@@ -456,3 +450,20 @@
         return 0;
     }
 }
+
+static uint32_t gnssUpdateSecondaryBandConfig(
+        const GnssSvTypeConfig& secondaryBandConfig) {
+    if (NULL != gGnssAdapter) {
+        return gGnssAdapter->gnssUpdateSecondaryBandConfigCommand(secondaryBandConfig);
+    } else {
+        return 0;
+    }
+}
+
+static uint32_t gnssGetSecondaryBandConfig(){
+    if (NULL != gGnssAdapter) {
+        return gGnssAdapter->gnssGetSecondaryBandConfigCommand();
+    } else {
+        return 0;
+    }
+}
diff --git a/location/ILocationAPI.h b/location/ILocationAPI.h
index d00cb3f..96076e9 100644
--- a/location/ILocationAPI.h
+++ b/location/ILocationAPI.h
@@ -191,27 +191,17 @@
     virtual uint32_t gnssDeleteAidingData(GnssAidingData& data) = 0;
 
     /** @brief
-        Reset the constellation settings to modem default.
-
-        @param
-        None
-
-        @return
-        A session id that will be returned in responseCallback to
-        match command with response. This effect is global for all
-        clients of LocationAPI responseCallback returns:
-                LOCATION_ERROR_SUCCESS if successful
-                LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
-    */
-    virtual uint32_t resetConstellationConfig() = 0;
-
-    /** @brief
-        Configure the constellation to be used by the GNSS engine on
+        Configure the constellation and SVs to be used by the GNSS engine on
         modem.
 
         @param
-        constellationConfig: specify the constellation configuration
-        used by GNSS engine.
+        constellationEnablementConfig: configuration to enable/disable SV
+        constellation to be used by SPE engine. When size in
+        constellationEnablementConfig is set to 0, this indicates to reset SV
+        constellation configuration to modem NV default.
+
+        blacklistSvConfig: configuration to blacklist or unblacklist SVs
+        used by SPE engine
 
         @return
         A session id that will be returned in responseCallback to
@@ -221,8 +211,26 @@
                 LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
     */
     virtual uint32_t configConstellations(
-            const GnssSvTypeConfig& svTypeConfig,
-            const GnssSvIdConfig&   svIdConfig) = 0;
+            const GnssSvTypeConfig& constellationEnablementConfig,
+            const GnssSvIdConfig&   blacklistSvConfig) = 0;
+
+    /** @brief
+        Configure the secondary band of constellations to be used by
+        the GNSS engine on modem.
+
+        @param
+        secondaryBandConfig: configuration the secondary band usage
+        for SPE engine
+
+        @return
+        A session id that will be returned in responseCallback to
+        match command with response. This effect is global for all
+        clients of LocationAPI responseCallback returns:
+                LOCATION_ERROR_SUCCESS if successful
+                LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
+    */
+    virtual uint32_t configConstellationSecondaryBand(
+            const GnssSvTypeConfig& secondaryBandConfig) = 0;
 
     /** @brief
         Enable or disable the constrained time uncertainty feature.
diff --git a/location/LocationAPI.cpp b/location/LocationAPI.cpp
index 5189728..284a625 100644
--- a/location/LocationAPI.cpp
+++ b/location/LocationAPI.cpp
@@ -753,12 +753,15 @@
     return id;
 }
 
-uint32_t LocationControlAPI::resetConstellationConfig() {
+uint32_t LocationControlAPI::configConstellations(
+        const GnssSvTypeConfig& constellationEnablementConfig,
+        const GnssSvIdConfig&   blacklistSvConfig) {
     uint32_t id = 0;
     pthread_mutex_lock(&gDataMutex);
 
     if (gData.gnssInterface != NULL) {
-        id = gData.gnssInterface->gnssResetSvConfig();
+        id = gData.gnssInterface->gnssUpdateSvConfig(
+                constellationEnablementConfig, blacklistSvConfig);
     } else {
         LOC_LOGe("No gnss interface available for Location Control API");
     }
@@ -767,15 +770,13 @@
     return id;
 }
 
-uint32_t LocationControlAPI::configConstellations(
-        const GnssSvTypeConfig& svTypeConfig,
-        const GnssSvIdConfig&   svIdConfig) {
+uint32_t LocationControlAPI::configConstellationSecondaryBand(
+        const GnssSvTypeConfig& secondaryBandConfig) {
     uint32_t id = 0;
     pthread_mutex_lock(&gDataMutex);
 
     if (gData.gnssInterface != NULL) {
-        id = gData.gnssInterface->gnssUpdateSvConfig(
-                svTypeConfig, svIdConfig);
+        id = gData.gnssInterface->gnssUpdateSecondaryBandConfig(secondaryBandConfig);
     } else {
         LOC_LOGe("No gnss interface available for Location Control API");
     }
diff --git a/location/LocationAPI.h b/location/LocationAPI.h
index 01c6ec9..5646ec8 100644
--- a/location/LocationAPI.h
+++ b/location/LocationAPI.h
@@ -263,27 +263,17 @@
     virtual uint32_t gnssDeleteAidingData(GnssAidingData& data) override;
 
     /** @brief
-        Reset the constellation settings to modem default.
-
-        @param
-        None
-
-        @return
-        A session id that will be returned in responseCallback to
-        match command with response. This effect is global for all
-        clients of LocationAPI responseCallback returns:
-                LOCATION_ERROR_SUCCESS if successful
-                LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
-    */
-    virtual uint32_t resetConstellationConfig() override;
-
-    /** @brief
-        Configure the constellation to be used by the GNSS engine on
+        Configure the constellation and SVs to be used by the GNSS engine on
         modem.
 
         @param
-        constellationConfig: specify the constellation configuration
-        used by GNSS engine.
+        constellationEnablementConfig: configuration to enable/disable SV
+        constellation to be used by SPE engine. When size in
+        constellationEnablementConfig is set to 0, this indicates to reset SV
+        constellation configuration to modem NV default.
+
+        blacklistSvConfig: configuration to blacklist or unblacklist SVs
+        used by SPE engine
 
         @return
         A session id that will be returned in responseCallback to
@@ -293,8 +283,26 @@
                 LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
     */
     virtual uint32_t configConstellations(
-            const GnssSvTypeConfig& svTypeConfig,
-            const GnssSvIdConfig&   svIdConfig) override;
+            const GnssSvTypeConfig& constellationEnablementConfig,
+            const GnssSvIdConfig&   blacklistSvConfig) override;
+
+    /** @brief
+        Configure the secondary band of constellations to be used by
+        the GNSS engine on modem.
+
+        @param
+        secondaryBandConfig: configuration the secondary band usage
+        for SPE engine
+
+        @return
+        A session id that will be returned in responseCallback to
+        match command with response. This effect is global for all
+        clients of LocationAPI responseCallback returns:
+                LOCATION_ERROR_SUCCESS if successful
+                LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
+    */
+    virtual uint32_t configConstellationSecondaryBand(
+            const GnssSvTypeConfig& secondaryBandConfig) override;
 
     /** @brief
         Enable or disable the constrained time uncertainty feature.
diff --git a/location/LocationDataTypes.h b/location/LocationDataTypes.h
index efba0f5..7fe2abe 100644
--- a/location/LocationDataTypes.h
+++ b/location/LocationDataTypes.h
@@ -341,6 +341,7 @@
     GNSS_CONFIG_FLAGS_ROBUST_LOCATION_BIT                  = (1<<11),
     GNSS_CONFIG_FLAGS_MIN_GPS_WEEK_BIT                     = (1<<12),
     GNSS_CONFIG_FLAGS_MIN_SV_ELEVATION_BIT                 = (1<<13),
+    GNSS_CONFIG_FLAGS_CONSTELLATION_SECONDARY_BAND_BIT     = (1<<14),
 } GnssConfigFlagsBits;
 
 typedef enum {
@@ -928,7 +929,6 @@
     float yawUnc;         // Uncertainty of Yaw, 68% confidence level (radian)
 } GnssLocationPositionDynamicsExt;
 
-
 typedef struct {
     /** Validity mask for below fields */
     GnssSystemTimeStructTypeFlags validityMask;
@@ -1242,7 +1242,7 @@
 }
 
 #define GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK ((uint64_t)0xFFFFFFFFFFFFFFFF)
-typedef struct {
+struct GnssSvIdConfig {
     uint32_t size; // set to sizeof(GnssSvIdConfig)
 
     // GLONASS - SV 65 maps to bit 0
@@ -1271,7 +1271,21 @@
     //Navic - SV 401 maps to bit 0
 #define GNSS_SV_CONFIG_NAVIC_INITIAL_SV_ID 401
     uint64_t navicBlacklistSvMask;
-} GnssSvIdConfig;
+
+    inline bool equals(const GnssSvIdConfig& inConfig) {
+        if ((inConfig.size == size) &&
+                (inConfig.gloBlacklistSvMask == gloBlacklistSvMask) &&
+                (inConfig.bdsBlacklistSvMask == bdsBlacklistSvMask) &&
+                (inConfig.qzssBlacklistSvMask == qzssBlacklistSvMask) &&
+                (inConfig.galBlacklistSvMask == galBlacklistSvMask) &&
+                (inConfig.sbasBlacklistSvMask == sbasBlacklistSvMask) &&
+                (inConfig.navicBlacklistSvMask == navicBlacklistSvMask)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+};
 
 // Specify the valid mask for robust location configure
 // defined in GnssConfigRobustLocation.
@@ -1312,6 +1326,37 @@
     }
 };
 
+/* Mask indicating enabled or disabled constellations and
+   secondary frequency.*/
+typedef uint64_t GnssSvTypesMask;
+typedef enum {
+    GNSS_SV_TYPES_MASK_GLO_BIT   = (1<<0),
+    GNSS_SV_TYPES_MASK_BDS_BIT   = (1<<1),
+    GNSS_SV_TYPES_MASK_QZSS_BIT  = (1<<2),
+    GNSS_SV_TYPES_MASK_GAL_BIT   = (1<<3),
+    GNSS_SV_TYPES_MASK_NAVIC_BIT = (1<<4),
+    GNSS_SV_TYPES_MASK_GPS_BIT   = (1<<5),
+} GnssSvTypesMaskBits;
+#define GNSS_SV_TYPES_MASK_ALL \
+    (GNSS_SV_TYPES_MASK_GPS_BIT|GNSS_SV_TYPES_MASK_GLO_BIT|GNSS_SV_TYPES_MASK_BDS_BIT|\
+     GNSS_SV_TYPES_MASK_QZSS_BIT|GNSS_SV_TYPES_MASK_GAL_BIT|GNSS_SV_TYPES_MASK_NAVIC_BIT)
+
+/* This SV Type config is injected directly to GNSS Adapter
+ * bypassing Location API */
+struct GnssSvTypeConfig{
+    uint32_t size; // set to sizeof(GnssSvTypeConfig)
+    // Enabled Constellations
+    GnssSvTypesMask enabledSvTypesMask;
+    // Disabled Constellations
+    GnssSvTypesMask blacklistedSvTypesMask;
+
+    inline bool equals (const GnssSvTypeConfig& inConfig) const {
+        return ((inConfig.size == size) &&
+                (inConfig.enabledSvTypesMask == enabledSvTypesMask) &&
+                (inConfig.blacklistedSvTypesMask == blacklistedSvTypesMask));
+    }
+};
+
 struct GnssConfig{
     uint32_t size;  // set to sizeof(GnssConfig)
     GnssConfigFlagsMask flags; // bitwise OR of GnssConfigFlagsBits to mark which params are valid
@@ -1329,6 +1374,7 @@
     GnssConfigRobustLocation robustLocationConfig;
     uint16_t minGpsWeek;
     uint8_t minSvElevation;
+    GnssSvTypeConfig secondaryBandConfig;
 
     inline bool equals(const GnssConfig& config) {
         if (flags == config.flags &&
@@ -1345,7 +1391,8 @@
                 blacklistedSvIds == config.blacklistedSvIds &&
                 robustLocationConfig.equals(config.robustLocationConfig) &&
                 minGpsWeek == config.minGpsWeek &&
-                minSvElevation == config.minSvElevation) {
+                minSvElevation == config.minSvElevation &&
+                secondaryBandConfig.equals(config.secondaryBandConfig)) {
             return true;
         }
         return false;
@@ -1445,26 +1492,6 @@
     LeapSecondSystemInfo   leapSecondSysInfo;
 };
 
-/* Mask indicating enabled or disabled constellations */
-typedef uint64_t GnssSvTypesMask;
-typedef enum {
-    GNSS_SV_TYPES_MASK_GLO_BIT  = (1<<0),
-    GNSS_SV_TYPES_MASK_BDS_BIT  = (1<<1),
-    GNSS_SV_TYPES_MASK_QZSS_BIT = (1<<2),
-    GNSS_SV_TYPES_MASK_GAL_BIT  = (1<<3),
-    GNSS_SV_TYPES_MASK_NAVIC_BIT = (1<<4),
-} GnssSvTypesMaskBits;
-
-/* This SV Type config is injected directly to GNSS Adapter
- * bypassing Location API */
-typedef struct {
-    uint32_t size; // set to sizeof(GnssSvTypeConfig)
-    // Enabled Constellations
-    GnssSvTypesMask enabledSvTypesMask;
-    // Disabled Constellations
-    GnssSvTypesMask blacklistedSvTypesMask;
-} GnssSvTypeConfig;
-
 // Specify parameters related to lever arm
 struct LeverArmParams {
     // Offset along the vehicle forward axis
diff --git a/location/location_interface.h b/location/location_interface.h
index b8c185e..cbbdf4d 100644
--- a/location/location_interface.h
+++ b/location/location_interface.h
@@ -87,13 +87,14 @@
     void (*updatePowerState)(PowerStateType powerState);
     uint32_t (*setConstrainedTunc) (bool enable, float tuncConstraint, uint32_t energyBudget);
     uint32_t (*setPositionAssistedClockEstimator) (bool enable);
-    uint32_t (*gnssUpdateSvConfig)(const GnssSvTypeConfig& svTypeConfig,
-                                   const GnssSvIdConfig& svIdConfig);
-    uint32_t (*gnssResetSvConfig)();
+    uint32_t (*gnssUpdateSvConfig)(const GnssSvTypeConfig& constellationEnablementConfig,
+                                   const GnssSvIdConfig&   blacklistSvConfig);
     uint32_t (*configLeverArm)(const LeverArmConfigInfo& configInfo);
     uint32_t (*configRobustLocation)(bool enable, bool enableForE911);
     uint32_t (*configMinGpsWeek)(uint16_t minGpsWeek);
     uint32_t (*configDeadReckoningEngineParams)(const DeadReckoningEngineConfig& dreConfig);
+    uint32_t (*gnssUpdateSecondaryBandConfig)(const GnssSvTypeConfig& secondaryBandConfig);
+    uint32_t (*gnssGetSecondaryBandConfig)();
 };
 
 struct FlpInterface {