blob: 6f0a348633e3d9135c421524bd43ec1e7179fa12 [file] [log] [blame]
Michael Bestas3a0209e2023-05-04 01:15:47 +03001/* 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>
Michael Bestas222c86c2024-07-18 12:36:55 -040050#include <DataItemConcreteTypes.h>
Michael Bestas3a0209e2023-05-04 01:15:47 +030051
52using namespace loc_util;
53using namespace loc_core;
54
55#ifdef LOG_TAG
56#undef LOG_TAG
57#endif
58#define LOG_TAG "LocSvc_XSSO"
59
60class XtraIpcListener : public ILocIpcListener {
61 IOsObserver* mSystemStatusObsrvr;
62 const MsgTask* mMsgTask;
63 XtraSystemStatusObserver& mXSSO;
64public:
65 inline XtraIpcListener(IOsObserver* observer, const MsgTask* msgTask,
66 XtraSystemStatusObserver& xsso) :
67 mSystemStatusObsrvr(observer), mMsgTask(msgTask), mXSSO(xsso) {}
Michael Bestasdb7342c2021-01-06 19:23:51 +020068 virtual void onReceive(const char* data, uint32_t length __unused,
69 const LocIpcRecver* recver __unused) override {
Michael Bestas3a0209e2023-05-04 01:15:47 +030070#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
106XtraSystemStatusObserver::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
122bool 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
138bool 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
170bool 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
184bool 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
198bool 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
212inline 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
240void 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
262void 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
270void 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
278void 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
289void 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
310void XtraSystemStatusObserver::getName(string& name)
311{
312 name = "XtraSystemStatusObserver";
313}
314
315void 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) {
Michael Bestas222c86c2024-07-18 12:36:55 -0400325 IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem(eachItem);
Michael Bestas3a0209e2023-05-04 01:15:47 +0300326 if (NULL == dataitem) {
327 break;
328 }
Michael Bestas3a0209e2023-05-04 01:15:47 +0300329
330 mDataItemList.push_back(dataitem);
331 }
332 }
333
334 inline ~HandleOsObserverUpdateMsg() {
335 for (auto itor = mDataItemList.begin(); itor != mDataItemList.end(); ++itor) {
336 if (*itor != nullptr) {
337 delete *itor;
338 *itor = nullptr;
339 }
340 }
341 }
342
343 inline void proc() const {
344 for (auto each : mDataItemList) {
345 switch (each->getId())
346 {
347 case NETWORKINFO_DATA_ITEM_ID:
348 {
Michael Bestas222c86c2024-07-18 12:36:55 -0400349 NetworkInfoDataItem* networkInfo = static_cast<NetworkInfoDataItem*>(each);
Michael Bestas3a0209e2023-05-04 01:15:47 +0300350 NetworkInfoType* networkHandleInfo =
351 static_cast<NetworkInfoType*>(networkInfo->getNetworkHandle());
352 mXtraSysStatObj->updateConnections(networkInfo->getAllTypes(),
353 networkHandleInfo);
354 }
355 break;
356
357 case TAC_DATA_ITEM_ID:
358 {
Michael Bestas222c86c2024-07-18 12:36:55 -0400359 TacDataItem* tac = static_cast<TacDataItem*>(each);
Michael Bestas3a0209e2023-05-04 01:15:47 +0300360 mXtraSysStatObj->updateTac(tac->mValue);
361 }
362 break;
363
364 case MCCMNC_DATA_ITEM_ID:
365 {
Michael Bestas222c86c2024-07-18 12:36:55 -0400366 MccmncDataItem* mccmnc = static_cast<MccmncDataItem*>(each);
Michael Bestas3a0209e2023-05-04 01:15:47 +0300367 mXtraSysStatObj->updateMccMnc(mccmnc->mValue);
368 }
369 break;
370
371 default:
372 break;
373 }
374 }
375 }
376 };
377 mMsgTask->sendMsg(new (nothrow) HandleOsObserverUpdateMsg(this, dlist));
378}