/* * Copyright (c) 2017, The Linux Foundation. All rights reserved. * Not a Contribution */ /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "LocSvc__AGnssRilInterface" #include #include #include #include #include #include #include #include "Gnss.h" #include "AGnssRil.h" typedef void* (getLocationInterface)(); namespace android { namespace hardware { namespace gnss { namespace V1_0 { namespace implementation { static bool sendConnectionEvent(const bool connected, const int8_t type); AGnssRil::AGnssRil(Gnss* gnss) : mGnss(gnss) { ENTRY_LOG_CALLFLOW(); } AGnssRil::~AGnssRil() { ENTRY_LOG_CALLFLOW(); } Return AGnssRil::updateNetworkState(bool connected, NetworkType type, bool roaming) { ENTRY_LOG_CALLFLOW(); // for XTRA sendConnectionEvent(connected, (int8_t)type); return true; } // for XTRA static inline int createSocket() { int socketFd = -1; if ((socketFd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { LOC_LOGe("create socket error. reason:%s", strerror(errno)); } else { const char* socketPath = "/data/vendor/location/xtra/socket_hal_xtra"; struct sockaddr_un addr = { .sun_family = AF_UNIX }; snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", socketPath); if (::connect(socketFd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { LOC_LOGe("cannot connect to XTRA. reason:%s", strerror(errno)); if (::close(socketFd)) { LOC_LOGe("close socket error. reason:%s", strerror(errno)); } socketFd = -1; } } return socketFd; } static inline void closeSocket(const int socketFd) { if (socketFd >= 0) { if(::close(socketFd)) { LOC_LOGe("close socket error. reason:%s", strerror(errno)); } } } static inline bool sendConnectionEvent(const bool connected, const int8_t type) { int socketFd = createSocket(); if (socketFd < 0) { LOC_LOGe("XTRA unreachable. sending failed."); return false; } std::stringstream ss; ss << "connection"; ss << " " << (connected ? "1" : "0"); ss << " " << (int)type; ss << "\n"; // append seperator const std::string& data = ss.str(); int remain = data.length(); ssize_t sent = 0; while (remain > 0 && (sent = ::send(socketFd, data.c_str() + (data.length() - remain), remain, MSG_NOSIGNAL)) > 0) { remain -= sent; } if (sent < 0) { LOC_LOGe("sending error. reason:%s", strerror(errno)); } closeSocket(socketFd); return (remain == 0); } } // namespace implementation } // namespace V1_0 } // namespace gnss } // namespace hardware } // namespace android