Michael Bestas | 3a0209e | 2023-05-04 01:15:47 +0300 | [diff] [blame^] | 1 | /* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. |
| 2 | * |
| 3 | * Redistribution and use in source and binary forms, with or without |
| 4 | * modification, are permitted provided that the following conditions are |
| 5 | * met: |
| 6 | * * Redistributions of source code must retain the above copyright |
| 7 | * notice, this list of conditions and the following disclaimer. |
| 8 | * * Redistributions in binary form must reproduce the above |
| 9 | * copyright notice, this list of conditions and the following |
| 10 | * disclaimer in the documentation and/or other materials provided |
| 11 | * with the distribution. |
| 12 | * * Neither the name of The Linux Foundation, nor the names of its |
| 13 | * contributors may be used to endorse or promote products derived |
| 14 | * from this software without specific prior written permission. |
| 15 | * |
| 16 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED |
| 17 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| 18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT |
| 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS |
| 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
| 23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
| 25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
| 26 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | * |
| 28 | */ |
| 29 | #define LOG_TAG "LocSvc_XtraSystemStatusObs" |
| 30 | |
| 31 | #include <sys/stat.h> |
| 32 | #include <sys/un.h> |
| 33 | #include <errno.h> |
| 34 | #include <ctype.h> |
| 35 | #include <cutils/properties.h> |
| 36 | #include <math.h> |
| 37 | #include <arpa/inet.h> |
| 38 | #include <netinet/in.h> |
| 39 | #include <netdb.h> |
| 40 | #include <string> |
| 41 | #include <loc_log.h> |
| 42 | #include <loc_nmea.h> |
| 43 | #include <SystemStatus.h> |
| 44 | #include <vector> |
| 45 | #include <sstream> |
| 46 | #include <XtraSystemStatusObserver.h> |
| 47 | #include <LocAdapterBase.h> |
| 48 | #include <DataItemId.h> |
| 49 | #include <DataItemsFactoryProxy.h> |
| 50 | #include <DataItemConcreteTypesBase.h> |
| 51 | |
| 52 | using namespace loc_util; |
| 53 | using namespace loc_core; |
| 54 | |
| 55 | #ifdef LOG_TAG |
| 56 | #undef LOG_TAG |
| 57 | #endif |
| 58 | #define LOG_TAG "LocSvc_XSSO" |
| 59 | |
| 60 | class XtraIpcListener : public ILocIpcListener { |
| 61 | IOsObserver* mSystemStatusObsrvr; |
| 62 | const MsgTask* mMsgTask; |
| 63 | XtraSystemStatusObserver& mXSSO; |
| 64 | public: |
| 65 | inline XtraIpcListener(IOsObserver* observer, const MsgTask* msgTask, |
| 66 | XtraSystemStatusObserver& xsso) : |
| 67 | mSystemStatusObsrvr(observer), mMsgTask(msgTask), mXSSO(xsso) {} |
| 68 | virtual void onReceive(const char* data, uint32_t length, |
| 69 | const LocIpcRecver* recver) override { |
| 70 | #define STRNCMP(str, constStr) strncmp(str, constStr, sizeof(constStr)-1) |
| 71 | if (!STRNCMP(data, "ping")) { |
| 72 | LOC_LOGd("ping received"); |
| 73 | #ifdef USE_GLIB |
| 74 | } else if (!STRNCMP(data, "connectBackhaul")) { |
| 75 | char clientName[30] = {0}; |
| 76 | sscanf(data, "%*s %29s", clientName); |
| 77 | mSystemStatusObsrvr->connectBackhaul(string(clientName)); |
| 78 | } else if (!STRNCMP(data, "disconnectBackhaul")) { |
| 79 | char clientName[30] = {0}; |
| 80 | sscanf(data, "%*s %29s", clientName); |
| 81 | mSystemStatusObsrvr->disconnectBackhaul(string(clientName)); |
| 82 | #endif |
| 83 | } else if (!STRNCMP(data, "requestStatus")) { |
| 84 | int32_t xtraStatusUpdated = 0; |
| 85 | sscanf(data, "%*s %d", &xtraStatusUpdated); |
| 86 | |
| 87 | struct HandleStatusRequestMsg : public LocMsg { |
| 88 | XtraSystemStatusObserver& mXSSO; |
| 89 | int32_t mXtraStatusUpdated; |
| 90 | inline HandleStatusRequestMsg(XtraSystemStatusObserver& xsso, |
| 91 | int32_t xtraStatusUpdated) : |
| 92 | mXSSO(xsso), mXtraStatusUpdated(xtraStatusUpdated) {} |
| 93 | inline void proc() const override { |
| 94 | mXSSO.onStatusRequested(mXtraStatusUpdated); |
| 95 | /* SSR for DGnss Ntrip Source*/ |
| 96 | mXSSO.restartDgnssSource(); |
| 97 | } |
| 98 | }; |
| 99 | mMsgTask->sendMsg(new HandleStatusRequestMsg(mXSSO, xtraStatusUpdated)); |
| 100 | } else { |
| 101 | LOC_LOGw("unknown event: %s", data); |
| 102 | } |
| 103 | } |
| 104 | }; |
| 105 | |
| 106 | XtraSystemStatusObserver::XtraSystemStatusObserver(IOsObserver* sysStatObs, |
| 107 | const MsgTask* msgTask) : |
| 108 | mSystemStatusObsrvr(sysStatObs), mMsgTask(msgTask), |
| 109 | mGpsLock(-1), mConnections(~0), mXtraThrottle(true), |
| 110 | mReqStatusReceived(false), |
| 111 | mIsConnectivityStatusKnown(false), |
| 112 | mSender(LocIpc::getLocIpcLocalSender(LOC_IPC_XTRA)), |
| 113 | mDelayLocTimer(*mSender) { |
| 114 | subscribe(true); |
| 115 | auto recver = LocIpc::getLocIpcLocalRecver( |
| 116 | make_shared<XtraIpcListener>(sysStatObs, msgTask, *this), |
| 117 | LOC_IPC_HAL); |
| 118 | mIpc.startNonBlockingListening(recver); |
| 119 | mDelayLocTimer.start(100 /*.1 sec*/, false); |
| 120 | } |
| 121 | |
| 122 | bool XtraSystemStatusObserver::updateLockStatus(GnssConfigGpsLock lock) { |
| 123 | // mask NI(NFW bit) since from XTRA's standpoint GPS is enabled if |
| 124 | // MO(AFW bit) is enabled and disabled when MO is disabled |
| 125 | mGpsLock = lock & ~GNSS_CONFIG_GPS_LOCK_NI; |
| 126 | |
| 127 | if (!mReqStatusReceived) { |
| 128 | return true; |
| 129 | } |
| 130 | |
| 131 | stringstream ss; |
| 132 | ss << "gpslock"; |
| 133 | ss << " " << mGpsLock; |
| 134 | string s = ss.str(); |
| 135 | return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) ); |
| 136 | } |
| 137 | |
| 138 | bool XtraSystemStatusObserver::updateConnections(uint64_t allConnections, |
| 139 | NetworkInfoType* networkHandleInfo) { |
| 140 | mIsConnectivityStatusKnown = true; |
| 141 | mConnections = allConnections; |
| 142 | |
| 143 | LOC_LOGd("updateConnections mConnections:%" PRIx64, mConnections); |
| 144 | for (uint8_t i = 0; i < MAX_NETWORK_HANDLES; ++i) { |
| 145 | mNetworkHandle[i] = networkHandleInfo[i]; |
| 146 | LOC_LOGd("updateConnections [%d] networkHandle:%" PRIx64 " networkType:%u", |
| 147 | i, mNetworkHandle[i].networkHandle, mNetworkHandle[i].networkType); |
| 148 | } |
| 149 | |
| 150 | if (!mReqStatusReceived) { |
| 151 | return true; |
| 152 | } |
| 153 | |
| 154 | stringstream ss; |
| 155 | ss << "connection" << endl << mConnections << endl |
| 156 | << mNetworkHandle[0].toString() << endl |
| 157 | << mNetworkHandle[1].toString() << endl |
| 158 | << mNetworkHandle[2].toString() << endl |
| 159 | << mNetworkHandle[3].toString() << endl |
| 160 | << mNetworkHandle[4].toString() << endl |
| 161 | << mNetworkHandle[5].toString() << endl |
| 162 | << mNetworkHandle[6].toString() << endl |
| 163 | << mNetworkHandle[7].toString() << endl |
| 164 | << mNetworkHandle[8].toString() << endl |
| 165 | << mNetworkHandle[MAX_NETWORK_HANDLES-1].toString(); |
| 166 | string s = ss.str(); |
| 167 | return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) ); |
| 168 | } |
| 169 | |
| 170 | bool XtraSystemStatusObserver::updateTac(const string& tac) { |
| 171 | mTac = tac; |
| 172 | |
| 173 | if (!mReqStatusReceived) { |
| 174 | return true; |
| 175 | } |
| 176 | |
| 177 | stringstream ss; |
| 178 | ss << "tac"; |
| 179 | ss << " " << tac.c_str(); |
| 180 | string s = ss.str(); |
| 181 | return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) ); |
| 182 | } |
| 183 | |
| 184 | bool XtraSystemStatusObserver::updateMccMnc(const string& mccmnc) { |
| 185 | mMccmnc = mccmnc; |
| 186 | |
| 187 | if (!mReqStatusReceived) { |
| 188 | return true; |
| 189 | } |
| 190 | |
| 191 | stringstream ss; |
| 192 | ss << "mncmcc"; |
| 193 | ss << " " << mccmnc.c_str(); |
| 194 | string s = ss.str(); |
| 195 | return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) ); |
| 196 | } |
| 197 | |
| 198 | bool XtraSystemStatusObserver::updateXtraThrottle(const bool enabled) { |
| 199 | mXtraThrottle = enabled; |
| 200 | |
| 201 | if (!mReqStatusReceived) { |
| 202 | return true; |
| 203 | } |
| 204 | |
| 205 | stringstream ss; |
| 206 | ss << "xtrathrottle"; |
| 207 | ss << " " << (enabled ? 1 : 0); |
| 208 | string s = ss.str(); |
| 209 | return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) ); |
| 210 | } |
| 211 | |
| 212 | inline bool XtraSystemStatusObserver::onStatusRequested(int32_t xtraStatusUpdated) { |
| 213 | mReqStatusReceived = true; |
| 214 | |
| 215 | if (xtraStatusUpdated) { |
| 216 | return true; |
| 217 | } |
| 218 | |
| 219 | stringstream ss; |
| 220 | |
| 221 | ss << "respondStatus" << endl; |
| 222 | (mGpsLock == -1 ? ss : ss << mGpsLock) << endl; |
| 223 | (mConnections == (uint64_t)~0 ? ss : ss << mConnections) << endl |
| 224 | << mNetworkHandle[0].toString() << endl |
| 225 | << mNetworkHandle[1].toString() << endl |
| 226 | << mNetworkHandle[2].toString() << endl |
| 227 | << mNetworkHandle[3].toString() << endl |
| 228 | << mNetworkHandle[4].toString() << endl |
| 229 | << mNetworkHandle[5].toString() << endl |
| 230 | << mNetworkHandle[6].toString() << endl |
| 231 | << mNetworkHandle[7].toString() << endl |
| 232 | << mNetworkHandle[8].toString() << endl |
| 233 | << mNetworkHandle[MAX_NETWORK_HANDLES-1].toString() << endl |
| 234 | << mTac << endl << mMccmnc << endl << mIsConnectivityStatusKnown; |
| 235 | |
| 236 | string s = ss.str(); |
| 237 | return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) ); |
| 238 | } |
| 239 | |
| 240 | void XtraSystemStatusObserver::startDgnssSource(const StartDgnssNtripParams& params) { |
| 241 | stringstream ss; |
| 242 | const GnssNtripConnectionParams* ntripParams = &(params.ntripParams); |
| 243 | |
| 244 | ss << "startDgnssSource" << endl; |
| 245 | ss << ntripParams->useSSL << endl; |
| 246 | ss << ntripParams->hostNameOrIp.data() << endl; |
| 247 | ss << ntripParams->port << endl; |
| 248 | ss << ntripParams->mountPoint.data() << endl; |
| 249 | ss << ntripParams->username.data() << endl; |
| 250 | ss << ntripParams->password.data() << endl; |
| 251 | if (ntripParams->requiresNmeaLocation && !params.nmea.empty()) { |
| 252 | ss << params.nmea.data() << endl; |
| 253 | } |
| 254 | string s = ss.str(); |
| 255 | |
| 256 | LOC_LOGd("%s", s.data()); |
| 257 | LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()); |
| 258 | // make a local copy of the string for SSR |
| 259 | mNtripParamsString.assign(std::move(s)); |
| 260 | } |
| 261 | |
| 262 | void XtraSystemStatusObserver::restartDgnssSource() { |
| 263 | if (!mNtripParamsString.empty()) { |
| 264 | LocIpc::send(*mSender, |
| 265 | (const uint8_t*)mNtripParamsString.data(), mNtripParamsString.size()); |
| 266 | LOC_LOGv("Xtra SSR %s", mNtripParamsString.data()); |
| 267 | } |
| 268 | } |
| 269 | |
| 270 | void XtraSystemStatusObserver::stopDgnssSource() { |
| 271 | LOC_LOGv(); |
| 272 | mNtripParamsString.clear(); |
| 273 | |
| 274 | const char s[] = "stopDgnssSource"; |
| 275 | LocIpc::send(*mSender, (const uint8_t*)s, strlen(s)); |
| 276 | } |
| 277 | |
| 278 | void XtraSystemStatusObserver::updateNmeaToDgnssServer(const string& nmea) |
| 279 | { |
| 280 | stringstream ss; |
| 281 | ss << "updateDgnssServerNmea" << endl; |
| 282 | ss << nmea.data() << endl; |
| 283 | |
| 284 | string s = ss.str(); |
| 285 | LOC_LOGd("%s", s.data()); |
| 286 | LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()); |
| 287 | } |
| 288 | |
| 289 | void XtraSystemStatusObserver::subscribe(bool yes) |
| 290 | { |
| 291 | // Subscription data list |
| 292 | list<DataItemId> subItemIdList; |
| 293 | subItemIdList.push_back(NETWORKINFO_DATA_ITEM_ID); |
| 294 | subItemIdList.push_back(MCCMNC_DATA_ITEM_ID); |
| 295 | |
| 296 | if (yes) { |
| 297 | mSystemStatusObsrvr->subscribe(subItemIdList, this); |
| 298 | |
| 299 | list<DataItemId> reqItemIdList; |
| 300 | reqItemIdList.push_back(TAC_DATA_ITEM_ID); |
| 301 | |
| 302 | mSystemStatusObsrvr->requestData(reqItemIdList, this); |
| 303 | |
| 304 | } else { |
| 305 | mSystemStatusObsrvr->unsubscribe(subItemIdList, this); |
| 306 | } |
| 307 | } |
| 308 | |
| 309 | // IDataItemObserver overrides |
| 310 | void XtraSystemStatusObserver::getName(string& name) |
| 311 | { |
| 312 | name = "XtraSystemStatusObserver"; |
| 313 | } |
| 314 | |
| 315 | void XtraSystemStatusObserver::notify(const list<IDataItemCore*>& dlist) |
| 316 | { |
| 317 | struct HandleOsObserverUpdateMsg : public LocMsg { |
| 318 | XtraSystemStatusObserver* mXtraSysStatObj; |
| 319 | list <IDataItemCore*> mDataItemList; |
| 320 | |
| 321 | inline HandleOsObserverUpdateMsg(XtraSystemStatusObserver* xtraSysStatObs, |
| 322 | const list<IDataItemCore*>& dataItemList) : |
| 323 | mXtraSysStatObj(xtraSysStatObs) { |
| 324 | for (auto eachItem : dataItemList) { |
| 325 | IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem( |
| 326 | eachItem->getId()); |
| 327 | if (NULL == dataitem) { |
| 328 | break; |
| 329 | } |
| 330 | // Copy the contents of the data item |
| 331 | dataitem->copy(eachItem); |
| 332 | |
| 333 | mDataItemList.push_back(dataitem); |
| 334 | } |
| 335 | } |
| 336 | |
| 337 | inline ~HandleOsObserverUpdateMsg() { |
| 338 | for (auto itor = mDataItemList.begin(); itor != mDataItemList.end(); ++itor) { |
| 339 | if (*itor != nullptr) { |
| 340 | delete *itor; |
| 341 | *itor = nullptr; |
| 342 | } |
| 343 | } |
| 344 | } |
| 345 | |
| 346 | inline void proc() const { |
| 347 | for (auto each : mDataItemList) { |
| 348 | switch (each->getId()) |
| 349 | { |
| 350 | case NETWORKINFO_DATA_ITEM_ID: |
| 351 | { |
| 352 | NetworkInfoDataItemBase* networkInfo = |
| 353 | static_cast<NetworkInfoDataItemBase*>(each); |
| 354 | NetworkInfoType* networkHandleInfo = |
| 355 | static_cast<NetworkInfoType*>(networkInfo->getNetworkHandle()); |
| 356 | mXtraSysStatObj->updateConnections(networkInfo->getAllTypes(), |
| 357 | networkHandleInfo); |
| 358 | } |
| 359 | break; |
| 360 | |
| 361 | case TAC_DATA_ITEM_ID: |
| 362 | { |
| 363 | TacDataItemBase* tac = |
| 364 | static_cast<TacDataItemBase*>(each); |
| 365 | mXtraSysStatObj->updateTac(tac->mValue); |
| 366 | } |
| 367 | break; |
| 368 | |
| 369 | case MCCMNC_DATA_ITEM_ID: |
| 370 | { |
| 371 | MccmncDataItemBase* mccmnc = |
| 372 | static_cast<MccmncDataItemBase*>(each); |
| 373 | mXtraSysStatObj->updateMccMnc(mccmnc->mValue); |
| 374 | } |
| 375 | break; |
| 376 | |
| 377 | default: |
| 378 | break; |
| 379 | } |
| 380 | } |
| 381 | } |
| 382 | }; |
| 383 | mMsgTask->sendMsg(new (nothrow) HandleOsObserverUpdateMsg(this, dlist)); |
| 384 | } |