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