diff options
| author | Simon Shields <keepcalm444@gmail.com> | 2016-10-22 02:10:14 +1100 |
|---|---|---|
| committer | Simon Shields <keepcalm444@gmail.com> | 2016-10-22 12:20:07 +1100 |
| commit | 1d3b193298e5bb11505913ed94869799f62c6ef1 (patch) | |
| tree | 7e16a1cc960dbaeb6739a3aba8d7c3e863b23524 | |
| parent | 477b4348313825f092ab5d86ccd759137096fcbb (diff) | |
i9300: add GPS shim
* AGpsRefLocation changed size between M and N, causing AGPS to
explode. Fix this by passing our own, M version of the struct and
translating between the two ABIs.
Change-Id: Ic755dbcf842fa9e6f928d384a0c504d10656ee9b
| -rw-r--r-- | i9300.mk | 3 | ||||
| -rw-r--r-- | proprietary-files.txt | 2 | ||||
| -rw-r--r-- | shims/Android.mk | 17 | ||||
| -rw-r--r-- | shims/libgps-shim/Android.mk | 28 | ||||
| -rw-r--r-- | shims/libgps-shim/gps.c | 122 | ||||
| -rw-r--r-- | shims/libgps-shim/gps.h | 49 |
6 files changed, 220 insertions, 1 deletions
@@ -45,6 +45,9 @@ PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/configs/gps.xml:system/etc/gps.xml \ $(LOCAL_PATH)/gps_daemon.sh:system/bin/gps_daemon.sh +PRODUCT_PACKAGES += \ + gps.smdk4x12 + # Keylayout PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/keylayout/sec_touchkey.kl:system/usr/keylayout/sec_touchkey.kl diff --git a/proprietary-files.txt b/proprietary-files.txt index 027777e..bc71c03 100644 --- a/proprietary-files.txt +++ b/proprietary-files.txt @@ -1,4 +1,4 @@ system/bin/glgps -system/lib/hw/gps.exynos4.so:system/lib/hw/gps.tegra3.so +system/lib/hw/gps.exynos4.vendor.so:system/lib/hw/gps.tegra3.so system/lib/libakm.so system/lib/libsec-ril.so diff --git a/shims/Android.mk b/shims/Android.mk new file mode 100644 index 0000000..07abb16 --- /dev/null +++ b/shims/Android.mk @@ -0,0 +1,17 @@ +# Copyright (C) 2016 The CyanogenMod Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH := $(call my-dir) + +include $(call all-makefiles-under, $(LOCAL_PATH)) diff --git a/shims/libgps-shim/Android.mk b/shims/libgps-shim/Android.mk new file mode 100644 index 0000000..cfcedb2 --- /dev/null +++ b/shims/libgps-shim/Android.mk @@ -0,0 +1,28 @@ +# Copyright (C) 2016 The CyanogenMod Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := gps.c + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + liblog + +LOCAL_MODULE := gps.$(TARGET_BOOTLOADER_BOARD_NAME) +LOCAL_MODULE_RELATIVE_PATH := hw + +include $(BUILD_SHARED_LIBRARY) diff --git a/shims/libgps-shim/gps.c b/shims/libgps-shim/gps.c new file mode 100644 index 0000000..1b1a19d --- /dev/null +++ b/shims/libgps-shim/gps.c @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2016 The CyanogenMod Project <http://www.cyanogenmod.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "libgps-shim" + +#include <utils/Log.h> +#include <hardware/gps.h> + +#include <dlfcn.h> +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "gps.h" +#define REAL_GPS_PATH "/system/lib/hw/gps.exynos4.vendor.so" + +const GpsInterface* (*vendor_get_gps_interface)(struct gps_device_t* dev); +const void* (*vendor_get_extension)(const char* name); +void (*vendor_set_ref_location)(const AGpsRefLocationNoLTE *agps_reflocation, size_t sz_struct); + +void shim_set_ref_location(const AGpsRefLocation *agps_reflocation, size_t sz_struct) { + // this is mildly ugly + AGpsRefLocationNoLTE vendor_ref; + if (sizeof(AGpsRefLocationNoLTE) < sz_struct) { + ALOGE("%s: AGpsRefLocation is too small, bailing out!", __func__); + return; + } + ALOGE("%s: shimming AGpsRefLocation", __func__); + // the two structs are identical, so this is ok + memcpy(&vendor_ref, agps_reflocation, sizeof(AGpsRefLocationNoLTE)); + vendor_set_ref_location(&vendor_ref, sizeof(AGpsRefLocationNoLTE)); + // copy it back + memcpy(agps_reflocation, &vendor_ref, sizeof(AGpsRefLocationNoLTE)); +} + +const void* shim_get_extension(const char* name) { + ALOGE("%s(%s)", __func__, name); + if (strcmp(name, AGPS_RIL_INTERFACE) == 0) { + // RIL interface + AGpsRilInterface *ril = (AGpsRilInterface*)vendor_get_extension(name); + // now we shim the ref_location callback + ALOGE("%s: shimming RIL ref_location callback", __func__); + vendor_set_ref_location = ril->set_ref_location; + ril->set_ref_location = shim_set_ref_location; + return ril; + } else { + return vendor_get_extension(name); + } +} + +const GpsInterface* shim_get_gps_interface(struct gps_device_t* dev) { + ALOGE("%s: shimming vendor get_extension", __func__); + GpsInterface *halInterface = vendor_get_gps_interface(dev); + + vendor_get_extension = halInterface->get_extension; + halInterface->get_extension = &shim_get_extension; + + return halInterface; +} + +static int open_gps(const struct hw_module_t* module, char const* name, + struct hw_device_t** device) { + void *realGpsLib; + int gpsHalResult; + struct hw_module_t *realHalSym; + + struct gps_device_t **gps = (struct gps_device_t **)device; + + realGpsLib = dlopen(REAL_GPS_PATH, RTLD_LOCAL); + if (!realGpsLib) { + ALOGE("Failed to load real GPS HAL '" REAL_GPS_PATH "': %s", dlerror()); + return -EINVAL; + } + + realHalSym = (struct hw_module_t*)dlsym(realGpsLib, HAL_MODULE_INFO_SYM_AS_STR); + if (!realHalSym) { + ALOGE("Failed to locate the GPS HAL module sym: '" HAL_MODULE_INFO_SYM_AS_STR "': %s", dlerror()); + goto dl_err; + } + + int result = realHalSym->methods->open(realHalSym, name, device); + if (result < 0) { + ALOGE("Real GPS open method failed: %d", result); + goto dl_err; + } + ALOGE("Successfully loaded real GPS hal, shimming get_gps_interface..."); + // now, we shim hw_device_t + vendor_get_gps_interface = (*gps)->get_gps_interface; + (*gps)->get_gps_interface = &shim_get_gps_interface; + + return 0; +dl_err: + dlclose(realGpsLib); + return -EINVAL; +} + +static struct hw_module_methods_t gps_module_methods = { + .open = open_gps +}; + +struct hw_module_t HAL_MODULE_INFO_SYM = { + .tag = HARDWARE_MODULE_TAG, + .module_api_version = 1, + .hal_api_version = 0, + .id = GPS_HARDWARE_MODULE_ID, + .name = "BCM451x GPS shim", + .author = "The CyanogenMod Project", + .methods = &gps_module_methods +}; diff --git a/shims/libgps-shim/gps.h b/shims/libgps-shim/gps.h new file mode 100644 index 0000000..591f464 --- /dev/null +++ b/shims/libgps-shim/gps.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2016 The CyanogenMod Project <http://www.cyanogenmod.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <hardware/gps.h> + +/* CellID for 2G, 3G and LTE, used in AGPS. */ +typedef struct { + AGpsRefLocationType type; + /** Mobile Country Code. */ + uint16_t mcc; + /** Mobile Network Code .*/ + uint16_t mnc; + /** Location Area Code in 2G, 3G and LTE. In 3G lac is discarded. In LTE, + * lac is populated with tac, to ensure that we don't break old clients that + * might rely in the old (wrong) behavior. + */ + uint16_t lac; + /** Cell id in 2G. Utran Cell id in 3G. Cell Global Id EUTRA in LTE. */ + uint32_t cid; +#if 0 // introduced in N. + /** Tracking Area Code in LTE. */ + uint16_t tac; + /** Physical Cell id in LTE (not used in 2G and 3G) */ + uint16_t pcid; +#endif +} AGpsRefLocationCellIDNoLTE; + +/** Represents ref locations */ +typedef struct { + AGpsRefLocationType type; + union { + AGpsRefLocationCellIDNoLTE cellID; + AGpsRefLocationMac mac; + } u; +} AGpsRefLocationNoLTE; + + |
