1 /* Copyright (c) 2017, 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
51 using namespace loc_core;
52
53 #define XTRA_HAL_SOCKET_NAME "/data/vendor/location/xtra/socket_hal_xtra"
54
updateLockStatus(uint32_t lock)55 bool XtraSystemStatusObserver::updateLockStatus(uint32_t lock) {
56 stringstream ss;
57 ss << "gpslock";
58 ss << " " << lock;
59 ss << "\n"; // append seperator
60 return ( sendEvent(ss) );
61 }
62
updateConnectionStatus(bool connected,uint32_t type)63 bool XtraSystemStatusObserver::updateConnectionStatus(bool connected, uint32_t type) {
64 stringstream ss;
65 ss << "connection";
66 ss << " " << (connected ? "1" : "0");
67 ss << " " << (int)type;
68 ss << "\n"; // append seperator
69 return ( sendEvent(ss) );
70 }
updateTac(const string & tac)71 bool XtraSystemStatusObserver::updateTac(const string& tac) {
72 stringstream ss;
73 ss << "tac";
74 ss << " " << tac.c_str();
75 ss << "\n"; // append seperator
76 return ( sendEvent(ss) );
77 }
78
updateMccMnc(const string & mccmnc)79 bool XtraSystemStatusObserver::updateMccMnc(const string& mccmnc) {
80 stringstream ss;
81 ss << "mncmcc";
82 ss << " " << mccmnc.c_str();
83 ss << "\n"; // append seperator
84 return ( sendEvent(ss) );
85 }
86
sendEvent(const stringstream & event)87 bool XtraSystemStatusObserver::sendEvent(const stringstream& event) {
88 int socketFd = createSocket();
89 if (socketFd < 0) {
90 LOC_LOGe("XTRA unreachable. sending failed.");
91 return false;
92 }
93
94 const string& data = event.str();
95 int remain = data.length();
96 ssize_t sent = 0;
97 while (remain > 0 &&
98 (sent = ::send(socketFd, data.c_str() + (data.length() - remain),
99 remain, MSG_NOSIGNAL)) > 0) {
100 remain -= sent;
101 }
102
103 if (sent < 0) {
104 LOC_LOGe("sending error. reason:%s", strerror(errno));
105 }
106
107 closeSocket(socketFd);
108
109 return (remain == 0);
110 }
111
112
createSocket()113 int XtraSystemStatusObserver::createSocket() {
114 int socketFd = -1;
115
116 if ((socketFd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
117 LOC_LOGe("create socket error. reason:%s", strerror(errno));
118
119 } else {
120 const char* socketPath = XTRA_HAL_SOCKET_NAME ;
121 struct sockaddr_un addr = { .sun_family = AF_UNIX };
122 snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", socketPath);
123
124 if (::connect(socketFd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
125 LOC_LOGe("cannot connect to XTRA. reason:%s", strerror(errno));
126 if (::close(socketFd)) {
127 LOC_LOGe("close socket error. reason:%s", strerror(errno));
128 }
129 socketFd = -1;
130 }
131 }
132
133 return socketFd;
134 }
135
closeSocket(const int socketFd)136 void XtraSystemStatusObserver::closeSocket(const int socketFd) {
137 if (socketFd >= 0) {
138 if(::close(socketFd)) {
139 LOC_LOGe("close socket error. reason:%s", strerror(errno));
140 }
141 }
142 }
143
subscribe(bool yes)144 void XtraSystemStatusObserver::subscribe(bool yes)
145 {
146 // Subscription data list
147 list<DataItemId> subItemIdList;
148 subItemIdList.push_back(NETWORKINFO_DATA_ITEM_ID);
149 subItemIdList.push_back(MCCMNC_DATA_ITEM_ID);
150
151 if (yes) {
152 mSystemStatusObsrvr->subscribe(subItemIdList, this);
153
154 list<DataItemId> reqItemIdList;
155 reqItemIdList.push_back(TAC_DATA_ITEM_ID);
156
157 mSystemStatusObsrvr->requestData(reqItemIdList, this);
158
159 } else {
160 mSystemStatusObsrvr->unsubscribe(subItemIdList, this);
161 }
162 }
163
164 // IDataItemObserver overrides
getName(string & name)165 void XtraSystemStatusObserver::getName(string& name)
166 {
167 name = "XtraSystemStatusObserver";
168 }
169
notify(const list<IDataItemCore * > & dlist)170 void XtraSystemStatusObserver::notify(const list<IDataItemCore*>& dlist)
171 {
172 struct handleOsObserverUpdateMsg : public LocMsg {
173 XtraSystemStatusObserver* mXtraSysStatObj;
174 list <IDataItemCore*> mDataItemList;
175
176 inline handleOsObserverUpdateMsg(XtraSystemStatusObserver* xtraSysStatObs,
177 const list<IDataItemCore*>& dataItemList) :
178 mXtraSysStatObj(xtraSysStatObs) {
179 for (auto eachItem : dataItemList) {
180 IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem(
181 eachItem->getId());
182 if (NULL == dataitem) {
183 break;
184 }
185 // Copy the contents of the data item
186 dataitem->copy(eachItem);
187
188 mDataItemList.push_back(dataitem);
189 }
190 }
191
192 inline ~handleOsObserverUpdateMsg() {
193 for (auto each : mDataItemList) {
194 delete each;
195 }
196 }
197
198 inline void proc() const {
199 for (auto each : mDataItemList) {
200 switch (each->getId())
201 {
202 case NETWORKINFO_DATA_ITEM_ID:
203 {
204 SystemStatusNetworkInfo* networkInfo =
205 reinterpret_cast<SystemStatusNetworkInfo*>(each);
206 mXtraSysStatObj->updateConnectionStatus(networkInfo->mConnected,
207 networkInfo->mType);
208 }
209 break;
210
211 case TAC_DATA_ITEM_ID:
212 {
213 SystemStatusTac* tac = reinterpret_cast<SystemStatusTac*>(each);
214 mXtraSysStatObj->updateTac(tac->mValue);
215 }
216 break;
217
218 case MCCMNC_DATA_ITEM_ID:
219 {
220 SystemStatusMccMnc* mccmnc = reinterpret_cast<SystemStatusMccMnc*>(each);
221 mXtraSysStatObj->updateMccMnc(mccmnc->mValue);
222 }
223 break;
224
225 default:
226 break;
227 }
228 }
229 }
230 };
231 mMsgTask->sendMsg(new (nothrow) handleOsObserverUpdateMsg(this, dlist));
232 }
233
234
235