1 /*
2  * Copyright (c) 2017, The Linux Foundation. All rights reserved.
3  * Not a Contribution
4  */
5 /*
6  * Copyright (C) 2016 The Android Open Source Project
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #define LOG_TAG "LocSvc__AGnssRilInterface"
22 
23 #include <log_util.h>
24 #include <dlfcn.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <sys/un.h>
28 #include <sstream>
29 #include <string>
30 #include "Gnss.h"
31 #include "AGnssRil.h"
32 typedef void* (getLocationInterface)();
33 
34 namespace android {
35 namespace hardware {
36 namespace gnss {
37 namespace V1_0 {
38 namespace implementation {
39 
40 static bool sendConnectionEvent(const bool connected, const int8_t type);
41 
AGnssRil(Gnss * gnss)42 AGnssRil::AGnssRil(Gnss* gnss) : mGnss(gnss) {
43     ENTRY_LOG_CALLFLOW();
44 }
45 
~AGnssRil()46 AGnssRil::~AGnssRil() {
47     ENTRY_LOG_CALLFLOW();
48 }
49 
updateNetworkState(bool connected,NetworkType type,bool roaming)50 Return<bool> AGnssRil::updateNetworkState(bool connected, NetworkType type, bool roaming) {
51     ENTRY_LOG_CALLFLOW();
52 
53     // for XTRA
54     sendConnectionEvent(connected, (int8_t)type);
55 
56     return true;
57 }
58 
59 // for XTRA
createSocket()60 static inline int createSocket() {
61     int socketFd = -1;
62 
63     if ((socketFd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
64         LOC_LOGe("create socket error. reason:%s", strerror(errno));
65 
66      } else {
67         const char* socketPath = "/data/vendor/location/xtra/socket_hal_xtra";
68         struct sockaddr_un addr = { .sun_family = AF_UNIX };
69         snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", socketPath);
70 
71         if (::connect(socketFd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
72             LOC_LOGe("cannot connect to XTRA. reason:%s", strerror(errno));
73             if (::close(socketFd)) {
74                 LOC_LOGe("close socket error. reason:%s", strerror(errno));
75             }
76             socketFd = -1;
77         }
78     }
79 
80     return socketFd;
81 }
82 
closeSocket(const int socketFd)83 static inline void closeSocket(const int socketFd) {
84     if (socketFd >= 0) {
85         if(::close(socketFd)) {
86             LOC_LOGe("close socket error. reason:%s", strerror(errno));
87         }
88     }
89 }
90 
sendConnectionEvent(const bool connected,const int8_t type)91 static inline bool sendConnectionEvent(const bool connected, const int8_t type) {
92     int socketFd = createSocket();
93     if (socketFd < 0) {
94         LOC_LOGe("XTRA unreachable. sending failed.");
95         return false;
96     }
97 
98     std::stringstream ss;
99     ss <<  "connection";
100     ss << " " << (connected ? "1" : "0");
101     ss << " " << (int)type;
102     ss << "\n"; // append seperator
103 
104     const std::string& data = ss.str();
105     int remain = data.length();
106     ssize_t sent = 0;
107 
108     while (remain > 0 &&
109           (sent = ::send(socketFd, data.c_str() + (data.length() - remain),
110                        remain, MSG_NOSIGNAL)) > 0) {
111         remain -= sent;
112     }
113 
114     if (sent < 0) {
115         LOC_LOGe("sending error. reason:%s", strerror(errno));
116     }
117 
118     closeSocket(socketFd);
119 
120     return (remain == 0);
121 }
122 
123 }  // namespace implementation
124 }  // namespace V1_0
125 }  // namespace gnss
126 }  // namespace hardware
127 }  // namespace android
128