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_AGnssRilInterface"
18 
19 #include "AGnssRil.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>> AGnssRil::sThreadFuncArgsList;
28 sp<IAGnssRilCallback> AGnssRil::sAGnssRilCbIface = nullptr;
29 bool AGnssRil::sInterfaceExists = false;
30 
31 AGpsRilCallbacks AGnssRil::sAGnssRilCb = {
32     .request_setid = AGnssRil::requestSetId,
33     .request_refloc = AGnssRil::requestRefLoc,
34     .create_thread_cb = AGnssRil::createThreadCb
35 };
36 
AGnssRil(const AGpsRilInterface * aGpsRilIface)37 AGnssRil::AGnssRil(const AGpsRilInterface* aGpsRilIface) : mAGnssRilIface(aGpsRilIface) {
38     /* Error out if an instance of the interface already exists. */
39     LOG_ALWAYS_FATAL_IF(sInterfaceExists);
40     sInterfaceExists = true;
41 }
42 
~AGnssRil()43 AGnssRil::~AGnssRil() {
44     sThreadFuncArgsList.clear();
45     sInterfaceExists = false;
46 }
47 
requestSetId(uint32_t flags)48 void AGnssRil::requestSetId(uint32_t flags) {
49     if (sAGnssRilCbIface == nullptr) {
50         ALOGE("%s: AGNSSRil Callback Interface configured incorrectly", __func__);
51         return;
52     }
53 
54     auto ret = sAGnssRilCbIface->requestSetIdCb(flags);
55     if (!ret.isOk()) {
56         ALOGE("%s: Unable to invoke callback", __func__);
57     }
58 }
59 
requestRefLoc(uint32_t)60 void AGnssRil::requestRefLoc(uint32_t /*flags*/) {
61     if (sAGnssRilCbIface == nullptr) {
62         ALOGE("%s: AGNSSRil Callback Interface configured incorrectly", __func__);
63         return;
64     }
65 
66     auto ret = sAGnssRilCbIface->requestRefLocCb();
67     if (!ret.isOk()) {
68         ALOGE("%s: Unable to invoke callback", __func__);
69     }
70 }
71 
createThreadCb(const char * name,void (* start)(void *),void * arg)72 pthread_t AGnssRil::createThreadCb(const char* name, void (*start)(void*), void* arg) {
73     return createPthread(name, start, arg, &sThreadFuncArgsList);
74 }
75 
76 // Methods from ::android::hardware::gnss::V1_0::IAGnssRil follow.
setCallback(const sp<IAGnssRilCallback> & callback)77 Return<void> AGnssRil::setCallback(const sp<IAGnssRilCallback>& callback)  {
78     if (mAGnssRilIface == nullptr) {
79         ALOGE("%s: AGnssRil interface is unavailable", __func__);
80         return Void();
81     }
82 
83     sAGnssRilCbIface = callback;
84 
85     mAGnssRilIface->init(&sAGnssRilCb);
86     return Void();
87 }
88 
setRefLocation(const IAGnssRil::AGnssRefLocation & aGnssRefLocation)89 Return<void> AGnssRil::setRefLocation(const IAGnssRil::AGnssRefLocation& aGnssRefLocation)  {
90     if (mAGnssRilIface == nullptr) {
91         ALOGE("%s: AGnssRil interface is unavailable", __func__);
92         return Void();
93     }
94 
95     AGpsRefLocation aGnssRefloc;
96     aGnssRefloc.type = static_cast<uint16_t>(aGnssRefLocation.type);
97 
98     auto& cellID = aGnssRefLocation.cellID;
99     aGnssRefloc.u.cellID = {
100         .type = static_cast<uint16_t>(cellID.type),
101         .mcc = cellID.mcc,
102         .mnc = cellID.mnc,
103         .lac = cellID.lac,
104         .cid = cellID.cid,
105         .tac = cellID.tac,
106         .pcid = cellID.pcid
107     };
108 
109     mAGnssRilIface->set_ref_location(&aGnssRefloc, sizeof(aGnssRefloc));
110     return Void();
111 }
112 
setSetId(IAGnssRil::SetIDType type,const hidl_string & setid)113 Return<bool> AGnssRil::setSetId(IAGnssRil::SetIDType type, const hidl_string& setid)  {
114     if (mAGnssRilIface == nullptr) {
115         ALOGE("%s: AGnssRil interface is unavailable", __func__);
116         return false;
117     }
118 
119     mAGnssRilIface->set_set_id(static_cast<uint16_t>(type), setid.c_str());
120     return true;
121 }
122 
updateNetworkState(bool connected,IAGnssRil::NetworkType type,bool roaming)123 Return<bool> AGnssRil::updateNetworkState(bool connected,
124                                           IAGnssRil::NetworkType type,
125                                           bool roaming) {
126     if (mAGnssRilIface == nullptr) {
127         ALOGE("%s: AGnssRil interface is unavailable", __func__);
128         return false;
129     }
130 
131     mAGnssRilIface->update_network_state(connected,
132                                          static_cast<int>(type),
133                                          roaming,
134                                          nullptr /* extra_info */);
135     return true;
136 }
137 
updateNetworkAvailability(bool available,const hidl_string & apn)138 Return<bool> AGnssRil::updateNetworkAvailability(bool available, const hidl_string& apn)  {
139     if (mAGnssRilIface == nullptr) {
140         ALOGE("%s: AGnssRil interface is unavailable", __func__);
141         return false;
142     }
143 
144     mAGnssRilIface->update_network_availability(available, apn.c_str());
145     return true;
146 }
147 
148 }  // namespace implementation
149 }  // namespace V1_0
150 }  // namespace gnss
151 }  // namespace hardware
152 }  // namespace android
153