diff --git a/android/AGnssRil.cpp b/android/AGnssRil.cpp new file mode 100644 index 00000000..0cf79a32 --- /dev/null +++ b/android/AGnssRil.cpp @@ -0,0 +1,127 @@ +/* + * 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 uint8_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, (uint8_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/misc/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 uint8_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 diff --git a/android/AGnssRil.h b/android/AGnssRil.h new file mode 100644 index 00000000..61216d8f --- /dev/null +++ b/android/AGnssRil.h @@ -0,0 +1,83 @@ +/* + * 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. + */ + +#ifndef ANDROID_HARDWARE_GNSS_V1_0_AGNSSRIL_H_ +#define ANDROID_HARDWARE_GNSS_V1_0_AGNSSRIL_H_ + +#include +#include +#include + +namespace android { +namespace hardware { +namespace gnss { +namespace V1_0 { +namespace implementation { + +using ::android::hardware::gnss::V1_0::IAGnssRil; +using ::android::hardware::gnss::V1_0::IAGnssRilCallback; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::hidl_vec; +using ::android::hardware::hidl_string; +using ::android::sp; + +struct Gnss; +/* + * Extended interface for AGNSS RIL support. An Assisted GNSS Radio Interface Layer interface + * allows the GNSS chipset to request radio interface layer information from Android platform. + * Examples of such information are reference location, unique subscriber ID, phone number string + * and network availability changes. Also contains wrapper methods to allow methods from + * IAGnssiRilCallback interface to be passed into the conventional implementation of the GNSS HAL. + */ +struct AGnssRil : public IAGnssRil { + AGnssRil(Gnss* gnss); + ~AGnssRil(); + + /* + * Methods from ::android::hardware::gnss::V1_0::IAGnssRil follow. + * These declarations were generated from IAGnssRil.hal. + */ + Return setCallback(const sp& /*callback*/) override { + return Void(); + } + Return setRefLocation(const IAGnssRil::AGnssRefLocation& /*agnssReflocation*/) override { + return Void(); + } + Return setSetId(IAGnssRil::SetIDType /*type*/, const hidl_string& /*setid*/) override { + return false; + } + Return updateNetworkAvailability(bool /*available*/, + const hidl_string& /*apn*/) override { + return false; + } + Return updateNetworkState(bool connected, NetworkType type, bool roaming) override; + + private: + Gnss* mGnss = nullptr; +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GNSS_V1_0_AGNSSRIL_H_ diff --git a/android/Android.mk b/android/Android.mk index a9b0d4bc..e3c3d500 100644 --- a/android/Android.mk +++ b/android/Android.mk @@ -14,6 +14,7 @@ LOCAL_SRC_FILES := \ GnssNi.cpp \ GnssConfiguration.cpp \ GnssDebug.cpp \ + AGnssRil.cpp LOCAL_SRC_FILES += \ location_api/LocationUtil.cpp \ diff --git a/android/Gnss.cpp b/android/Gnss.cpp index d17077cc..9a362f0a 100644 --- a/android/Gnss.cpp +++ b/android/Gnss.cpp @@ -316,6 +316,11 @@ Return> Gnss::getExtensionGnssDebug() { return mGnssDebug; } +Return> Gnss::getExtensionAGnssRil() { + mGnssRil = new AGnssRil(this); + return mGnssRil; +} + IGnss* HIDL_FETCH_IGnss(const char* hal) { ENTRY_LOG_CALLFLOW(); IGnss* iface = nullptr; diff --git a/android/Gnss.h b/android/Gnss.h index 99c5e40b..e4589d60 100644 --- a/android/Gnss.h +++ b/android/Gnss.h @@ -22,6 +22,7 @@ #define ANDROID_HARDWARE_GNSS_V1_1_GNSS_H #include +#include #include #include #include @@ -91,9 +92,7 @@ struct Gnss : public IGnss { Return> getExtensionGnssGeofencing() override; Return> getExtensionGnssBatching() override; - inline Return> getExtensionAGnssRil() override { - return nullptr; - } + Return> getExtensionAGnssRil() override; inline Return> getExtensionGnssNavigationMessage() override { return nullptr; @@ -130,6 +129,7 @@ struct Gnss : public IGnss { sp mGnssGeofencingIface = nullptr; sp mGnssBatching = nullptr; sp mGnssDebug = nullptr; + sp mGnssRil = nullptr; GnssAPIClient* mApi = nullptr; sp mGnssCbIface = nullptr;