sm8250-common: import location from LA.UM.9.12.r1-13500.01-SMxx50.QSSI12.0

Change-Id: If93ba9b50dc3bb07a4ba81694187e99f58dd172c
This commit is contained in:
SGCMarkus 2022-03-23 21:42:45 +01:00
parent 72410cf795
commit 64ab05b033
103 changed files with 92521 additions and 0 deletions

View file

@ -0,0 +1,42 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libloc_socket
# activate the following line for debug purposes only, comment out for production
#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
LOCAL_MODULE_TAGS := optional
LOCAL_SHARED_LIBRARIES := \
libutils \
libcutils \
liblog \
libgps.utils
LOCAL_SRC_FILES := \
LocSocket.cpp
LOCAL_CFLAGS := \
-fno-short-enums \
-D_ANDROID_
## Includes
LOCAL_C_INCLUDES := \
$(TARGET_OUT_HEADERS)/qmi-framework/inc \
$(TARGET_OUT_HEADERS)/qmi/inc
LOCAL_HEADER_LIBRARIES := \
libloc_core_headers \
libgps.utils_headers \
libloc_pla_headers \
liblocation_api_headers
LOCAL_CFLAGS += $(GNSS_CFLAGS)
ifeq ($(TARGET_KERNEL_VERSION),$(filter $(TARGET_KERNEL_VERSION),3.18 4.4 4.9))
LOCAL_CFLAGS += -DUSE_QSOCKET
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qsocket/inc
LOCAL_SHARED_LIBRARIES += libqsocket
endif
include $(BUILD_SHARED_LIBRARY)

View file

@ -0,0 +1,377 @@
/* Copyright (c) 2019 - 2020 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation, nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <unistd.h>
#include <memory>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#ifdef USE_QSOCKET
#include <sys/ioctl.h>
#include <poll.h>
#include <qsocket.h>
#include <qsocket_ipcr.h>
#else
#include <endian.h>
#include <linux/qrtr.h>
#endif
#include <log_util.h>
#include <LocIpc.h>
namespace loc_util {
#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "LocSvc_Qrtr"
class ServiceInfo {
const int32_t mServiceId;
const int32_t mInstanceId;
const string mName;
public:
inline ServiceInfo(int32_t service, int32_t instance) :
mServiceId(service), mInstanceId(instance),
mName(to_string(service) + ":" + to_string(instance)) {}
inline const char* getName() const { return mName.data(); }
inline int32_t getServiceId() const { return mServiceId; }
inline int32_t getInstanceId() const { return mInstanceId; }
};
#ifdef USE_QSOCKET
class LocIpcQsockSender : public LocIpcSender {
protected:
shared_ptr<Sock> mSock;
const ServiceInfo mServiceInfo;
qsockaddr_ipcr mAddr;
mutable bool mLookupPending;
inline virtual bool isOperable() const override {
return mSock != nullptr && mSock->mSid != -1;
}
inline void serviceLookup() const {
if (mLookupPending && mSock->isValid()) {
ipcr_name_t ipcrName = {
.service = (uint32_t)mServiceInfo.getServiceId(),
.instance = (uint32_t)mServiceInfo.getInstanceId()
};
uint32_t numEntries = 1;
int rc = ipcr_find_name(mSock->mSid, &ipcrName,
(struct qsockaddr_ipcr*)&mAddr, NULL, &numEntries, 0);
LOC_LOGd("serviceLookup, rc = %d, numEntries = %d\n", rc, numEntries);
if (rc < 0 || 1 != numEntries) {
mSock->close();
}
mLookupPending = false;
}
}
inline virtual ssize_t send(const uint8_t data[], uint32_t length,
int32_t /* msgId */) const override {
serviceLookup();
return mSock->send(data, length, 0, (struct sockaddr*)&mAddr,
sizeof(mAddr));
}
public:
inline LocIpcQsockSender(const qsockaddr_ipcr& destAddr) :
LocIpcSender(),
mSock(make_shared<Sock>(::socket(AF_IPC_ROUTER, SOCK_DGRAM, 0))),
mServiceInfo(0, 0), mAddr(destAddr), mLookupPending(false) {
}
inline LocIpcQsockSender(int service, int instance) :
LocIpcSender(),
mSock(make_shared<Sock>(::socket(AF_IPC_ROUTER, SOCK_DGRAM, 0))),
mServiceInfo(service, instance), mAddr({}), mLookupPending(true) {
}
unique_ptr<LocIpcRecver> getRecver(const shared_ptr<ILocIpcListener>& listener) override {
return make_unique<SockRecver>(listener, *this, mSock);
}
};
class LocIpcQsockRecver : public LocIpcQsockSender, public LocIpcRecver {
protected:
inline virtual ssize_t recv() const override {
socklen_t size = sizeof(mAddr);
return mSock->recv(*this, mDataCb, 0, (struct sockaddr*)&mAddr, &size);
}
public:
inline LocIpcQsockRecver(const shared_ptr<ILocIpcListener>& listener,
int service, int instance) :
LocIpcQsockSender(service, instance),
LocIpcRecver(listener, *this) {
qsockaddr_ipcr addr = {
AF_IPC_ROUTER,
{
IPCR_ADDR_NAME,
{
(uint32_t)service,
(uint32_t)instance
}
},
0
};
if (mSock->isValid() &&
::bind(mSock->mSid, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
LOC_LOGe("bind socket error. sock fd: %d,reason: %s",
mSock->mSid, strerror(errno));
mSock->close();
}
}
inline virtual unique_ptr<LocIpcSender> getLastSender() const override {
return make_unique<LocIpcQsockSender>(mAddr);
}
inline virtual const char* getName() const override {
return mServiceInfo.getName();
}
inline virtual void abort() const override {
if (isSendable()) {
serviceLookup();
mSock->sendAbort(0, (struct sockaddr*)&mAddr, sizeof(mAddr));
}
}
};
shared_ptr<LocIpcSender> createLocIpcQrtrSender(int service, int instance) {
return make_shared<LocIpcQsockSender>(service, instance);
}
unique_ptr<LocIpcRecver> createLocIpcQrtrRecver(const shared_ptr<ILocIpcListener>& listener,
int service, int instance,
const shared_ptr<LocIpcQrtrWatcher>& qrtrWatcher) {
return make_unique<LocIpcQsockRecver>(listener, service, instance);
}
#else
#define SOCKET_TIMEOUT_SEC 2
static inline __le32 cpu_to_le32(uint32_t x) { return htole32(x); }
static inline uint32_t le32_to_cpu(__le32 x) { return le32toh(x); }
class LocIpcQrtrSender : public LocIpcSender {
protected:
const ServiceInfo mServiceInfo;
shared_ptr<Sock> mSock;
mutable sockaddr_qrtr mAddr;
mutable struct qrtr_ctrl_pkt mCtrlPkt;
mutable bool mLookupPending;
bool ctrlCmdAndResponse(enum qrtr_pkt_type cmd) const {
if (mSock->isValid()) {
int rc = 0;
sockaddr_qrtr addr = mAddr;
addr.sq_port = QRTR_PORT_CTRL;
mCtrlPkt.cmd = cpu_to_le32(cmd);
if ((rc = ::sendto(mSock->mSid, &mCtrlPkt, sizeof(mCtrlPkt), 0,
(const struct sockaddr *)&addr, sizeof(addr))) < 0) {
LOC_LOGe("failed: sendto rc=%d reason=(%s)", rc, strerror(errno));
} else if (QRTR_TYPE_NEW_LOOKUP == cmd) {
int len;
struct qrtr_ctrl_pkt pkt;
while ((len = ::recv(mSock->mSid, &pkt, sizeof(pkt), 0)) > 0) {
if (len >= (decltype(len))sizeof(pkt) && 0 != pkt.server.service &&
cpu_to_le32(QRTR_TYPE_NEW_SERVER) == pkt.cmd) {
mAddr.sq_node = le32_to_cpu(pkt.server.node);
mAddr.sq_port = le32_to_cpu(pkt.server.port);
LOC_LOGv("server found pkt.cmd %d, service %d, node, %d, port %d",
le32_to_cpu(pkt.cmd), le32_to_cpu(pkt.server.service),
mAddr.sq_node, mAddr.sq_port);
break;
}
}
}
}
return mSock->isValid();
}
inline virtual bool isOperable() const override {
return mSock != nullptr && mSock->isValid() &&
(mAddr.sq_node != 0 || mAddr.sq_port != 0);
}
inline virtual ssize_t send(const uint8_t data[], uint32_t length,
int32_t /* msgId */) const override {
if (mLookupPending) {
mLookupPending = false;
ctrlCmdAndResponse(QRTR_TYPE_NEW_LOOKUP);
}
return mSock->send(data, length, 0, (struct sockaddr*)&mAddr, sizeof(mAddr));
}
public:
inline LocIpcQrtrSender(const sockaddr_qrtr& destAddr) :
LocIpcSender(), mServiceInfo(0, 0),
mSock(make_shared<Sock>(::socket(AF_QIPCRTR, SOCK_DGRAM, 0))),
mAddr(destAddr), mCtrlPkt({}), mLookupPending(false) {
}
inline LocIpcQrtrSender(int service, int instance) : LocIpcSender(),
mServiceInfo(service, instance),
mSock(make_shared<Sock>(::socket(AF_QIPCRTR, SOCK_DGRAM, 0))),
mAddr({AF_QIPCRTR, 0, 0}),
mCtrlPkt({}),
mLookupPending(true) {
// set timeout so if failed to send, call will return after 2 seconds timeout
// otherwise, call may never return
timeval timeout;
timeout.tv_sec = SOCKET_TIMEOUT_SEC;
timeout.tv_usec = 0;
setsockopt(mSock->mSid, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
socklen_t sl = sizeof(mAddr);
int rc = 0;
if ((rc = getsockname(mSock->mSid, (struct sockaddr*)&mAddr, &sl)) ||
mAddr.sq_family != AF_QIPCRTR || sl != sizeof(mAddr)) {
LOC_LOGe("failed: getsockname rc=%d reason=(%s), mAddr.sq_family=%d",
rc, strerror(errno), mAddr.sq_family);
mSock->close();
} else {
mCtrlPkt.server.service = cpu_to_le32(service);
mCtrlPkt.server.instance = cpu_to_le32(instance);
mCtrlPkt.server.node = cpu_to_le32(mAddr.sq_node);
mCtrlPkt.server.port = cpu_to_le32(mAddr.sq_port);
}
}
unique_ptr<LocIpcRecver> getRecver(const shared_ptr<ILocIpcListener>& listener) override {
return make_unique<SockRecver>(listener, *this, mSock);
}
inline virtual void copyDestAddrFrom(const LocIpcSender& otherSender) override {
mLookupPending = false;
mAddr = (reinterpret_cast<const LocIpcQrtrSender&>(otherSender)).mAddr;
}
};
class LocIpcQrtrListener : public ILocIpcListener {
const shared_ptr<ILocIpcListener> mRealListener;
const shared_ptr<LocIpcQrtrWatcher> mQrtrWatcher;
inline bool handleQrtrCtrlMsg(const char* data, uint32_t len) {
const struct qrtr_ctrl_pkt* pkt = reinterpret_cast<const struct qrtr_ctrl_pkt*>(data);
bool handledAsQrtrCtrlMsg = false;
if (sizeof(*pkt) == len) {
const uint32_t cmd = le32_to_cpu(pkt->cmd);
if (cmd >= QRTR_TYPE_DATA && cmd <= QRTR_TYPE_DEL_LOOKUP) {
handledAsQrtrCtrlMsg = true;
int serviceId = le32_to_cpu(pkt->server.service);
int instanceId = le32_to_cpu(pkt->server.instance);
uint32_t serverNodeId = le32_to_cpu(pkt->server.node);
uint32_t serverPort = le32_to_cpu(pkt->server.port);
int clientNodeId = le32_to_cpu(pkt->client.node);
int clientPort = le32_to_cpu(pkt->client.port);
LOC_LOGv("qrtr control msg: cmd %d, server.service:instance-node:port %d:%d-%d:%d,"
" client node:port %d:%d", cmd, serviceId, instanceId, serverNodeId,
serverPort, clientNodeId, clientPort);
if (nullptr != mQrtrWatcher) {
if ((QRTR_TYPE_NEW_SERVER == cmd || QRTR_TYPE_DEL_SERVER == cmd) &&
mQrtrWatcher->isServiceInWatch(serviceId)) {
LocIpcQrtrWatcher::ServiceStatus status = (QRTR_TYPE_NEW_SERVER == cmd) ?
LocIpcQrtrWatcher::ServiceStatus::UP :
LocIpcQrtrWatcher::ServiceStatus::DOWN;
sockaddr_qrtr addr = {AF_QIPCRTR, serverNodeId, serverPort};
const LocIpcQrtrSender sender(addr);
mQrtrWatcher->onServiceStatusChange(serviceId, instanceId, status, sender);
} else if ((QRTR_TYPE_DEL_CLIENT == cmd || QRTR_TYPE_BYE == cmd) &&
mQrtrWatcher->isClientInWatch(clientNodeId)) {
mQrtrWatcher->onClientGone(clientNodeId, clientPort);
}
}
}
}
return handledAsQrtrCtrlMsg;
}
public:
inline LocIpcQrtrListener(const shared_ptr<ILocIpcListener>& listener,
const shared_ptr<LocIpcQrtrWatcher>& qrtrWatcher) :
mRealListener(listener), mQrtrWatcher(qrtrWatcher) {}
inline virtual void onListenerReady() override {
if (nullptr != mRealListener) mRealListener->onListenerReady();
}
inline virtual void onReceive(const char* data, uint32_t len,
const LocIpcRecver* recver) override {
if ((!handleQrtrCtrlMsg(data, len)) && (nullptr != mRealListener)) {
mRealListener->onReceive(data, len, recver);
}
}
};
class LocIpcQrtrRecver : public LocIpcQrtrSender, public LocIpcRecver {
protected:
inline virtual ssize_t recv() const override {
socklen_t size = sizeof(mAddr);
return mSock->recv(*this, mDataCb, 0, (struct sockaddr*)&mAddr, &size);
}
public:
inline LocIpcQrtrRecver(const shared_ptr<ILocIpcListener>& listener,
int service, int instance,
const shared_ptr<LocIpcQrtrWatcher>& qrtrWatcher) :
LocIpcQrtrSender(service, instance),
LocIpcRecver(make_shared<LocIpcQrtrListener>(listener, qrtrWatcher), *this) {
ctrlCmdAndResponse(QRTR_TYPE_NEW_SERVER);
if (nullptr != qrtrWatcher) {
sockaddr_qrtr addr = mAddr;
addr.sq_port = QRTR_PORT_CTRL;
struct qrtr_ctrl_pkt pkt = {};
pkt.cmd = cpu_to_le32(QRTR_TYPE_NEW_LOOKUP);
int rc = 0;
for (int serviceId : qrtrWatcher->getServicesToWatch()) {
pkt.server.service = cpu_to_le32(serviceId);
if ((rc = ::sendto(mSock->mSid, &pkt, sizeof(pkt), 0,
(const struct sockaddr *)&addr, sizeof(addr))) < 0) {
LOC_LOGe("failed: sendto rc=%d reason=(%s)\n", rc, strerror(errno));
}
}
}
}
inline ~LocIpcQrtrRecver() { ctrlCmdAndResponse(QRTR_TYPE_DEL_SERVER); }
inline virtual unique_ptr<LocIpcSender> getLastSender() const override {
return make_unique<LocIpcQrtrSender>(mAddr);
}
inline virtual const char* getName() const override {
return mServiceInfo.getName();
}
inline virtual void abort() const override {
if (isSendable()) {
mSock->sendAbort(0, (struct sockaddr*)&mAddr, sizeof(mAddr));
}
}
};
shared_ptr<LocIpcSender> createLocIpcQrtrSender(int service, int instance) {
return make_shared<LocIpcQrtrSender>(service, instance);
}
unique_ptr<LocIpcRecver> createLocIpcQrtrRecver(const shared_ptr<ILocIpcListener>& listener,
int service, int instance,
const shared_ptr<LocIpcQrtrWatcher>& qrtrWatcher) {
return make_unique<LocIpcQrtrRecver>(listener, service, instance, qrtrWatcher);
}
#endif
}

View file

@ -0,0 +1,50 @@
AM_CFLAGS = \
-DDEBUG \
-I src/ \
-I inc/ \
$(QMIFW_CFLAGS) \
$(GPSUTILS_CFLAGS) \
-fpermissive
if USE_QSOCKET
AM_CFLAGS += -DUSE_QSOCKET
endif
ACLOCAL_AMFLAGS = -I m4
AM_CPPFLAGS = -std=c++14
requiredlibs = \
$(QMIFW_LIBS) \
$(GPSUTILS_LIBS)
c_sources = \
LocSocket.cpp
libloc_socket_la_SOURCES = \
$(c_sources)
######################
# Build loc_socket
######################
if USE_GLIB
libloc_socket_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
libloc_socket_la_LDFLAGS = -lstdc++ -g -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
libloc_socket_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
else
libloc_socket_la_CFLAGS = $(AM_CFLAGS)
libloc_socket_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread -shared -version-info 1:0:0
libloc_socket_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
endif
libloc_socket_la_LIBADD = $(requiredlibs) -lstdc++
#Create and Install libraries
library_include_HEADERS =
lib_LTLIBRARIES = libloc_socket.la
library_includedir = $(pkgincludedir)
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = loc-socket.pc
EXTRA_DIST = $(pkgconfig_DATA)

View file

@ -0,0 +1,97 @@
# configure.ac -- Autoconf script for gps location-utils
#
# Process this file with autoconf to produce a configure script
# Requires autoconf tool later than 2.61
AC_PREREQ(2.61)
# Initialize the loc_socket package version 1.0.0
AC_INIT([loc-socket],1.0.0)
# Does not strictly follow GNU Coding standards
AM_INIT_AUTOMAKE([foreign subdir-objects])
# Disables auto rebuilding of configure, Makefile.ins
AM_MAINTAINER_MODE
# Verifies the --srcdir is correct by checking for the path
AC_CONFIG_SRCDIR([Makefile.am])
# defines some macros variable to be included by source
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
# Checks for programs.
AC_PROG_LIBTOOL
AC_PROG_CXX
AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_AWK
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
PKG_PROG_PKG_CONFIG
# Checks for libraries.
PKG_CHECK_MODULES([GPSUTILS], [gps-utils])
AC_SUBST([GPSUTILS_CFLAGS])
AC_SUBST([GPSUTILS_LIBS])
AC_ARG_WITH([external_ap],
AC_HELP_STRING([--with-external_ap=@<:@dir@:>@],
[Using External Application Processor]),
[],
with_external_ap=no)
if test "x$with_external_ap" != "xno"; then
CPPFLAGS="${CPPFLAGS} -DFEATURE_EXTERNAL_AP"
fi
AM_CONDITIONAL(USE_EXTERNAL_AP, test "x${with_external_ap}" = "xyes")
AC_ARG_WITH([qsocket],
AC_HELP_STRING([--with-qsocket], [kernel supports qsocket]))
AM_CONDITIONAL(USE_QSOCKET, test "x${with_qsocket}" = "xyes")
AM_COND_IF(USE_QSOCKET, [
PKG_CHECK_MODULES([QMIFW], [qmi-framework])
AC_SUBST([QMIFW_CFLAGS])
AC_SUBST([QMIFW_LIBS])
])
AC_ARG_WITH([external_ap],
AC_HELP_STRING([--with-external_ap=@<:@dir@:>@],
[Using External Application Processor]),
[],
with_external_ap=no)
if test "x$with_external_ap" != "xno"; then
CPPFLAGS="${CPPFLAGS} -DFEATURE_EXTERNAL_AP"
else
# Checks for libraries.
PKG_CHECK_MODULES([CUTILS], [libcutils])
AC_SUBST([CUTILS_CFLAGS])
AC_SUBST([CUTILS_LIBS])
fi
AC_ARG_WITH([glib],
AC_HELP_STRING([--with-glib],
[enable glib, building HLOS systems which use glib]))
if (test "x${with_glib}" = "xyes"); then
AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib])
PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes,
AC_MSG_ERROR(GThread >= 2.16 is required))
PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
AC_MSG_ERROR(GLib >= 2.16 is required))
GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS"
GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS"
AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS)
fi
AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes")
AC_CONFIG_FILES([ \
Makefile \
loc-socket.pc
])
AC_OUTPUT

View file

@ -0,0 +1,10 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: loc-socket
Description: location socket library
Version: @VERSION@
Libs: -L${libdir} -lloc_socket
Cflags: -I${includedir} -I${includedir}/loc-socket