1/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 *     * Redistributions of source code must retain the above copyright
7 *       notice, this list of conditions and the following disclaimer.
8 *     * Redistributions in binary form must reproduce the above
9 *       copyright notice, this list of conditions and the following
10 *       disclaimer in the documentation and/or other materials provided
11 *       with the distribution.
12 *     * Neither the name of The Linux Foundation, nor the names of its
13 *       contributors may be used to endorse or promote products derived
14 *       from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30#define LOG_NDDEBUG 0
31#define LOG_TAG "LocSvc_FlpAPIClient"
32
33#include <log_util.h>
34#include <loc_cfg.h>
35
36#include "LocationUtil.h"
37#include "FlpAPIClient.h"
38
39namespace android {
40namespace hardware {
41namespace gnss {
42namespace V1_0 {
43namespace implementation {
44
45static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
46        LocationCapabilitiesMask mask);
47
48FlpAPIClient::FlpAPIClient(const sp<IGnssBatchingCallback>& callback) :
49    LocationAPIClientBase(),
50    mGnssBatchingCbIface(callback),
51    mDefaultId(42),
52    mLocationCapabilitiesMask(0)
53{
54    LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
55
56    LocationCallbacks locationCallbacks;
57    locationCallbacks.size = sizeof(LocationCallbacks);
58
59    locationCallbacks.trackingCb = nullptr;
60    locationCallbacks.batchingCb = nullptr;
61    if (mGnssBatchingCbIface != nullptr) {
62        locationCallbacks.batchingCb = [this](size_t count, Location* location) {
63            onBatchingCb(count, location);
64        };
65    }
66    locationCallbacks.geofenceBreachCb = nullptr;
67    locationCallbacks.geofenceStatusCb = nullptr;
68    locationCallbacks.gnssLocationInfoCb = nullptr;
69    locationCallbacks.gnssNiCb = nullptr;
70    locationCallbacks.gnssSvCb = nullptr;
71    locationCallbacks.gnssNmeaCb = nullptr;
72    locationCallbacks.gnssMeasurementsCb = nullptr;
73
74    locAPISetCallbacks(locationCallbacks);
75}
76
77FlpAPIClient::~FlpAPIClient()
78{
79    LOC_LOGD("%s]: ()", __FUNCTION__);
80}
81
82int FlpAPIClient::flpGetBatchSize()
83{
84    LOC_LOGD("%s]: ()", __FUNCTION__);
85    return locAPIGetBatchSize();
86}
87
88int FlpAPIClient::flpStartSession(const IGnssBatching::Options& opts)
89{
90    LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
91            static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
92    int retVal = -1;
93    LocationOptions options;
94    convertBatchOption(opts, options, mLocationCapabilitiesMask);
95    uint32_t mode = 0;
96    if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
97        mode = SESSION_MODE_ON_FULL;
98    }
99    if (locAPIStartSession(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
100        retVal = 1;
101    }
102    return retVal;
103}
104
105int FlpAPIClient::flpUpdateSessionOptions(const IGnssBatching::Options& opts)
106{
107    LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
108            static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
109    int retVal = -1;
110    LocationOptions options;
111    convertBatchOption(opts, options, mLocationCapabilitiesMask);
112
113    uint32_t mode = 0;
114    if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
115        mode = SESSION_MODE_ON_FULL;
116    }
117    if (locAPIUpdateSessionOptions(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
118        retVal = 1;
119    }
120    return retVal;
121}
122
123int FlpAPIClient::flpStopSession()
124{
125    LOC_LOGD("%s]: ", __FUNCTION__);
126    int retVal = -1;
127    if (locAPIStopSession(mDefaultId) == LOCATION_ERROR_SUCCESS) {
128        retVal = 1;
129    }
130    return retVal;
131}
132
133void FlpAPIClient::flpGetBatchedLocation(int last_n_locations)
134{
135    LOC_LOGD("%s]: (%d)", __FUNCTION__, last_n_locations);
136    locAPIGetBatchedLocations(last_n_locations);
137}
138
139void FlpAPIClient::flpFlushBatchedLocations()
140{
141    LOC_LOGD("%s]: ()", __FUNCTION__);
142    locAPIGetBatchedLocations(SIZE_MAX);
143}
144
145void FlpAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
146{
147    LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
148    mLocationCapabilitiesMask = capabilitiesMask;
149}
150
151void FlpAPIClient::onBatchingCb(size_t count, Location* location)
152{
153    LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, count);
154    if (mGnssBatchingCbIface != nullptr && count > 0) {
155        hidl_vec<GnssLocation> locationVec;
156        locationVec.resize(count);
157        for (size_t i = 0; i < count; i++) {
158            convertGnssLocation(location[i], locationVec[i]);
159        }
160        auto r = mGnssBatchingCbIface->gnssLocationBatchCb(locationVec);
161        if (!r.isOk()) {
162            LOC_LOGE("%s] Error from gnssLocationBatchCb description=%s",
163                __func__, r.description().c_str());
164        }
165    }
166}
167
168static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
169        LocationCapabilitiesMask mask)
170{
171    memset(&out, 0, sizeof(LocationOptions));
172    out.size = sizeof(LocationOptions);
173    out.minInterval = (uint32_t)(in.periodNanos / 1000000L);
174    out.minDistance = 0;
175    out.mode = GNSS_SUPL_MODE_STANDALONE;
176    if (mask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
177        out.mode = GNSS_SUPL_MODE_MSA;
178    if (mask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
179        out.mode = GNSS_SUPL_MODE_MSB;
180}
181
182}  // namespace implementation
183}  // namespace V1_0
184}  // namespace gnss
185}  // namespace hardware
186}  // namespace android
187