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