1 /*
2  * Copyright (c) 2017-2019, 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_AGnssInterface"
22 
23 #include <log_util.h>
24 #include "Gnss.h"
25 #include "AGnss.h"
26 
27 namespace android {
28 namespace hardware {
29 namespace gnss {
30 namespace V2_0 {
31 namespace implementation {
32 
33 static AGnss* spAGnss = nullptr;
34 
AGnss(Gnss * gnss)35 AGnss::AGnss(Gnss* gnss) : mGnss(gnss) {
36     spAGnss = this;
37 }
38 
~AGnss()39 AGnss::~AGnss() {
40     spAGnss = nullptr;
41 }
42 
agnssStatusIpV4Cb(AGnssExtStatusIpV4 status)43 void AGnss::agnssStatusIpV4Cb(AGnssExtStatusIpV4 status) {
44     if (nullptr != spAGnss) {
45         spAGnss->statusCb(status.type, status.status);
46     }
47 }
48 
statusCb(AGpsExtType type,LocAGpsStatusValue status)49 void AGnss::statusCb(AGpsExtType type, LocAGpsStatusValue status) {
50 
51     V2_0::IAGnssCallback::AGnssType  aType;
52     IAGnssCallback::AGnssStatusValue aStatus;
53 
54     switch (type) {
55     case LOC_AGPS_TYPE_SUPL:
56         aType = IAGnssCallback::AGnssType::SUPL;
57         break;
58     case LOC_AGPS_TYPE_SUPL_ES:
59         aType = IAGnssCallback::AGnssType::SUPL_EIMS;
60         break;
61     default:
62         LOC_LOGE("invalid type: %d", type);
63         return;
64     }
65 
66     switch (status) {
67     case LOC_GPS_REQUEST_AGPS_DATA_CONN:
68         aStatus = IAGnssCallback::AGnssStatusValue::REQUEST_AGNSS_DATA_CONN;
69         break;
70     case LOC_GPS_RELEASE_AGPS_DATA_CONN:
71         aStatus = IAGnssCallback::AGnssStatusValue::RELEASE_AGNSS_DATA_CONN;
72         break;
73     case LOC_GPS_AGPS_DATA_CONNECTED:
74         aStatus = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONNECTED;
75         break;
76     case LOC_GPS_AGPS_DATA_CONN_DONE:
77         aStatus = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONN_DONE;
78         break;
79     case LOC_GPS_AGPS_DATA_CONN_FAILED:
80         aStatus = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONN_FAILED;
81         break;
82     default:
83         LOC_LOGE("invalid status: %d", status);
84         return;
85     }
86 
87     if (mAGnssCbIface != nullptr) {
88         auto r = mAGnssCbIface->agnssStatusCb(aType, aStatus);
89         if (!r.isOk()) {
90             LOC_LOGw("Error invoking AGNSS status cb %s", r.description().c_str());
91         }
92     }
93     else {
94         LOC_LOGw("setCallback has not been called yet");
95     }
96 }
97 
setCallback(const sp<V2_0::IAGnssCallback> & callback)98 Return<void> AGnss::setCallback(const sp<V2_0::IAGnssCallback>& callback) {
99 
100     if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
101         LOC_LOGE("Null GNSS interface");
102         return Void();
103     }
104 
105     // Save the interface
106     mAGnssCbIface = callback;
107 
108     AgpsCbInfo cbInfo = {};
109     cbInfo.statusV4Cb = (void*)agnssStatusIpV4Cb;
110     cbInfo.atlType = AGPS_ATL_TYPE_SUPL | AGPS_ATL_TYPE_SUPL_ES;
111 
112     mGnss->getGnssInterface()->agpsInit(cbInfo);
113     return Void();
114 }
115 
dataConnClosed()116 Return<bool> AGnss::dataConnClosed() {
117 
118     if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
119         LOC_LOGE("Null GNSS interface");
120         return false;
121     }
122 
123     mGnss->getGnssInterface()->agpsDataConnClosed(LOC_AGPS_TYPE_SUPL);
124     return true;
125 }
126 
dataConnFailed()127 Return<bool> AGnss::dataConnFailed() {
128 
129     if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
130         LOC_LOGE("Null GNSS interface");
131         return false;
132     }
133 
134     mGnss->getGnssInterface()->agpsDataConnFailed(LOC_AGPS_TYPE_SUPL);
135     return true;
136 }
137 
dataConnOpen(uint64_t,const hidl_string & apn,V2_0::IAGnss::ApnIpType apnIpType)138 Return<bool> AGnss::dataConnOpen(uint64_t /*networkHandle*/, const hidl_string& apn,
139         V2_0::IAGnss::ApnIpType apnIpType) {
140 
141     if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
142         LOC_LOGE("Null GNSS interface");
143         return false;
144     }
145 
146     /* Validate */
147     if(apn.empty()){
148         LOC_LOGE("Invalid APN");
149         return false;
150     }
151 
152     LOC_LOGD("dataConnOpen APN name = [%s]", apn.c_str());
153 
154     AGpsBearerType bearerType;
155     switch (apnIpType) {
156     case IAGnss::ApnIpType::IPV4:
157         bearerType = AGPS_APN_BEARER_IPV4;
158         break;
159     case IAGnss::ApnIpType::IPV6:
160         bearerType = AGPS_APN_BEARER_IPV6;
161         break;
162     case IAGnss::ApnIpType::IPV4V6:
163         bearerType = AGPS_APN_BEARER_IPV4V6;
164         break;
165     default:
166         bearerType = AGPS_APN_BEARER_IPV4;
167         break;
168     }
169 
170     mGnss->getGnssInterface()->agpsDataConnOpen(
171         LOC_AGPS_TYPE_SUPL, apn.c_str(), apn.size(), (int)bearerType);
172     return true;
173 }
174 
setServer(V2_0::IAGnssCallback::AGnssType type,const hidl_string & hostname,int32_t port)175 Return<bool> AGnss::setServer(V2_0::IAGnssCallback::AGnssType type,
176                               const hidl_string& hostname,
177                               int32_t port) {
178     if (mGnss == nullptr) {
179         LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
180         return false;
181     }
182 
183     GnssConfig config;
184     memset(&config, 0, sizeof(GnssConfig));
185     config.size = sizeof(GnssConfig);
186     config.flags = GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT;
187     config.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer);
188     if (type == IAGnssCallback::AGnssType::SUPL) {
189         config.assistanceServer.type = GNSS_ASSISTANCE_TYPE_SUPL;
190     } else if (type == IAGnssCallback::AGnssType::C2K) {
191         config.assistanceServer.type = GNSS_ASSISTANCE_TYPE_C2K;
192     } else if (type == IAGnssCallback::AGnssType::SUPL_EIMS) {
193         config.assistanceServer.type = GNSS_ASSISTANCE_TYPE_SUPL_EIMS;
194     } else if (type == IAGnssCallback::AGnssType::SUPL_IMS) {
195         config.assistanceServer.type = GNSS_ASSISTANCE_TYPE_SUPL_IMS;
196     } else {
197         LOC_LOGE("%s]: invalid AGnssType: %d", __FUNCTION__, static_cast<uint8_t>(type));
198         return false;
199     }
200     config.assistanceServer.hostName = strdup(hostname.c_str());
201     config.assistanceServer.port = port;
202     return mGnss->updateConfiguration(config);
203 }
204 
205 }  // namespace implementation
206 }  // namespace V2_0
207 }  // namespace gnss
208 }  // namespace hardware
209 }  // namespace android
210