1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define LOG_TAG "GnssHAL_AGnssInterface" 18 19 #include "AGnss.h" 20 21 namespace android { 22 namespace hardware { 23 namespace gnss { 24 namespace V1_0 { 25 namespace implementation { 26 27 std::vector<std::unique_ptr<ThreadFuncArgs>> AGnss::sThreadFuncArgsList; 28 sp<IAGnssCallback> AGnss::sAGnssCbIface = nullptr; 29 bool AGnss::sInterfaceExists = false; 30 31 AGpsCallbacks AGnss::sAGnssCb = { 32 .status_cb = statusCb, 33 .create_thread_cb = createThreadCb 34 }; 35 36 AGnss::AGnss(const AGpsInterface* aGpsIface) : mAGnssIface(aGpsIface) { 37 /* Error out if an instance of the interface already exists. */ 38 LOG_ALWAYS_FATAL_IF(sInterfaceExists); 39 sInterfaceExists = true; 40 } 41 42 AGnss::~AGnss() { 43 sThreadFuncArgsList.clear(); 44 sInterfaceExists = false; 45 } 46 47 void AGnss::statusCb(AGpsStatus* status) { 48 if (sAGnssCbIface == nullptr) { 49 ALOGE("%s: AGNSS Callback Interface configured incorrectly", __func__); 50 return; 51 } 52 53 if (status == nullptr) { 54 ALOGE("AGNSS status is invalid"); 55 return; 56 } 57 58 /* 59 * Logic based on AGnssStatus processing by GnssLocationProvider. Size of 60 * AGpsStatus is checked for backward compatibility since some devices may 61 * be sending out an older version of AGpsStatus that only supports IPv4. 62 */ 63 size_t statusSize = status->size; 64 if (status->size == sizeof(AGpsStatus)) { 65 switch (status->addr.ss_family) 66 { 67 case AF_INET: 68 { 69 /* 70 * ss_family indicates IPv4. 71 */ 72 struct sockaddr_in* in = reinterpret_cast<struct sockaddr_in*>(&(status->addr)); 73 IAGnssCallback::AGnssStatusIpV4 aGnssStatusIpV4 = { 74 .type = static_cast<IAGnssCallback::AGnssType>(status->type), 75 .status = static_cast<IAGnssCallback::AGnssStatusValue>(status->status), 76 .ipV4Addr = in->sin_addr.s_addr, 77 }; 78 79 /* 80 * Callback to client with agnssStatusIpV4Cb. 81 */ 82 auto ret = sAGnssCbIface->agnssStatusIpV4Cb(aGnssStatusIpV4); 83 if (!ret.isOk()) { 84 ALOGE("%s: Unable to invoke callback", __func__); 85 } 86 break; 87 } 88 case AF_INET6: 89 { 90 /* 91 * ss_family indicates IPv6. Callback to client with agnssStatusIpV6Cb. 92 */ 93 IAGnssCallback::AGnssStatusIpV6 aGnssStatusIpV6; 94 95 aGnssStatusIpV6.type = static_cast<IAGnssCallback::AGnssType>(status->type); 96 aGnssStatusIpV6.status = static_cast<IAGnssCallback::AGnssStatusValue>( 97 status->status); 98 99 struct sockaddr_in6* in6 = reinterpret_cast<struct sockaddr_in6 *>( 100 &(status->addr)); 101 memcpy(&(aGnssStatusIpV6.ipV6Addr[0]), in6->sin6_addr.s6_addr, 102 aGnssStatusIpV6.ipV6Addr.size()); 103 auto ret = sAGnssCbIface->agnssStatusIpV6Cb(aGnssStatusIpV6); 104 if (!ret.isOk()) { 105 ALOGE("%s: Unable to invoke callback", __func__); 106 } 107 break; 108 } 109 default: 110 ALOGE("Invalid ss_family found: %d", status->addr.ss_family); 111 } 112 } else if (statusSize >= sizeof(AGpsStatus_v2)) { 113 AGpsStatus_v2* statusV2 = reinterpret_cast<AGpsStatus_v2*>(status); 114 uint32_t ipV4Addr = statusV2->ipaddr; 115 IAGnssCallback::AGnssStatusIpV4 aGnssStatusIpV4 = { 116 .type = static_cast<IAGnssCallback::AGnssType>(AF_INET), 117 .status = static_cast<IAGnssCallback::AGnssStatusValue>(status->status), 118 /* 119 * For older versions of AGpsStatus, change IP addr to net order. This 120 * was earlier being done in GnssLocationProvider. 121 */ 122 .ipV4Addr = htonl(ipV4Addr) 123 }; 124 /* 125 * Callback to client with agnssStatusIpV4Cb. 126 */ 127 auto ret = sAGnssCbIface->agnssStatusIpV4Cb(aGnssStatusIpV4); 128 if (!ret.isOk()) { 129 ALOGE("%s: Unable to invoke callback", __func__); 130 } 131 } else { 132 ALOGE("%s: Invalid size for AGPS Status", __func__); 133 } 134 } 135 136 pthread_t AGnss::createThreadCb(const char* name, void (*start)(void*), void* arg) { 137 return createPthread(name, start, arg, &sThreadFuncArgsList); 138 } 139 140 /* 141 * Implementation of methods from ::android::hardware::gnss::V1_0::IAGnss follow. 142 */ 143 Return<void> AGnss::setCallback(const sp<IAGnssCallback>& callback) { 144 if (mAGnssIface == nullptr) { 145 ALOGE("%s: AGnss interface is unavailable", __func__); 146 return Void(); 147 } 148 149 sAGnssCbIface = callback; 150 151 mAGnssIface->init(&sAGnssCb); 152 return Void(); 153 } 154 155 Return<bool> AGnss::dataConnClosed() { 156 if (mAGnssIface == nullptr) { 157 ALOGE("%s: AGnss interface is unavailable", __func__); 158 return false; 159 } 160 161 return (mAGnssIface->data_conn_closed() == 0); 162 } 163 164 Return<bool> AGnss::dataConnFailed() { 165 if (mAGnssIface == nullptr) { 166 ALOGE("%s: AGnss interface is unavailable", __func__); 167 return false; 168 } 169 170 return (mAGnssIface->data_conn_failed() == 0); 171 } 172 173 Return<bool> AGnss::setServer(IAGnssCallback::AGnssType type, 174 const hidl_string& hostname, 175 int32_t port) { 176 if (mAGnssIface == nullptr) { 177 ALOGE("%s: AGnss interface is unavailable", __func__); 178 return false; 179 } 180 181 return (mAGnssIface->set_server(static_cast<AGpsType>(type), hostname.c_str(), port) == 0); 182 } 183 184 Return<bool> AGnss::dataConnOpen(const hidl_string& apn, IAGnss::ApnIpType apnIpType) { 185 if (mAGnssIface == nullptr) { 186 ALOGE("%s: AGnss interface is unavailable", __func__); 187 return false; 188 } 189 190 return (mAGnssIface->data_conn_open_with_apn_ip_type(apn.c_str(), 191 static_cast<uint16_t>(apnIpType)) == 0); 192 } 193 194 } // namespace implementation 195 } // namespace V1_0 196 } // namespace gnss 197 } // namespace hardware 198 } // namespace android 199