[Feature]add MT2731_MP2_MR2_SVN388 baseline version
Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/connectivity/gps/lbs_hidl_service/Android.backup b/src/connectivity/gps/lbs_hidl_service/Android.backup
new file mode 100644
index 0000000..562ca85
--- /dev/null
+++ b/src/connectivity/gps/lbs_hidl_service/Android.backup
@@ -0,0 +1,57 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := lbs_hidl_service-impl
+LOCAL_PROPRIETARY_MODULE := true
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/mtk_socket_utils/inc \
+
+LOCAL_SRC_FILES := \
+ lbs_hidl_service.cpp \
+ mtk_socket_utils/src/mtk_socket_data_coder.c \
+ mtk_socket_utils/src/mtk_socket_utils.c \
+
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libcutils \
+ libdl \
+ libbase \
+ libhardware \
+ libbinder \
+ libhidlbase \
+ libhidltransport \
+ libutils \
+ vendor.mediatek.hardware.lbs@1.0_vendor \
+
+include $(BUILD_SHARED_LIBRARY)
+
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := lbs_hidl_service
+LOCAL_PROPRIETARY_MODULE := true
+LOCAL_INCLUDE_MTK_GLOBAL_CONFIGS := no
+LOCAL_INIT_RC := lbs_hidl_service.rc
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/mtk_socket_utils/inc \
+
+LOCAL_SRC_FILES := \
+ service.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libcutils \
+ libdl \
+ libbase \
+ libhardware \
+ libbinder \
+ libhidlbase \
+ libhidltransport \
+ libutils \
+ vendor.mediatek.hardware.lbs@1.0_vendor \
+ lbs_hidl_service-impl \
+
+include $(BUILD_EXECUTABLE)
diff --git a/src/connectivity/gps/lbs_hidl_service/lbs_hidl_service.cpp b/src/connectivity/gps/lbs_hidl_service/lbs_hidl_service.cpp
new file mode 100644
index 0000000..1ed5ee2
--- /dev/null
+++ b/src/connectivity/gps/lbs_hidl_service/lbs_hidl_service.cpp
@@ -0,0 +1,573 @@
+#include <android/log.h>
+#include <unistd.h> // usleep
+#include <sys/epoll.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <time.h>
+#include <cutils/properties.h>
+
+#include <hidl/LegacySupport.h>
+
+#include "lbs_hidl_service.h"
+
+namespace vendor {
+namespace mediatek {
+namespace hardware {
+namespace lbs {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::wp;
+using ::android::status_t;
+using ::android::hardware::hidl_death_recipient;
+using ::android::hidl::base::V1_0::IBase;
+
+char g_ver[] = "1.05";
+// 1.01 add agps_apn <-> lbs hidl service
+// 1.02 add mnld -> lbs hidl service
+// 1.03 add synchronization for HIDL callback from server to client
+// 1.04 add HAL callback return value check
+// 1.05 add handler timer to restart
+
+#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "lbs_hidl_service", __VA_ARGS__);
+#define LOGE LOGD
+
+#define LBS_HANDLER_TIMEOUT (30 * 1000)
+#define MAX_EPOLL_EVENT 50
+typedef void (* timer_callback)(sigval_t sig);
+int g_epfd = epoll_create(MAX_EPOLL_EVENT);
+int handleCase = 0;
+
+// LPPe Service
+sp<LbsHidlService> hidlLPPeAgps;
+sp<LbsHidlService> hidlLPPeWlan;
+sp<LbsHidlService> hidlLPPeBT;
+sp<LbsHidlService> hidlLPPeSensor;
+sp<LbsHidlService> hidlLPPeNetwork;
+sp<LbsHidlService> hidlLPPeIpAddr;
+sp<LbsHidlService> hidlLPPeLbs;
+sp<LbsHidlService> hidlApn2Agps;
+sp<LbsHidlService> hidlMnld2NlpUtils;
+sp<LbsHidlService> hidlMnld2DebugService;
+sp<LbsHidlService> hidlDebugService2Mnld;
+sp<LbsHidlService> hidlMeta2Mnld;
+
+
+// LocationEM, CMCC AGPS Settings, OP01
+sp<LbsHidlService> hidlAgpsInterface;
+sp<AgpsDebugInterfaceHidlService> hidlAgpsDebugInterface;
+sp<Agps2ApnHidlService> hidlAgps2Apn;
+
+
+void covertVector2Array(std::vector<uint8_t> in, char* out) {
+ int size = in.size();
+ for(int i = 0; i < size; i++) {
+ out[i] = in.at(i);
+ }
+}
+
+void covertArray2Vector(const char* in, int len, std::vector<uint8_t>& out) {
+ out.clear();
+ for(int i = 0; i < len; i++) {
+ out.push_back(in[i]);
+ }
+}
+
+void dump_vector(std::vector<uint8_t>& vec) {
+ LOGD("dump_vector() size=%d\n", (int)vec.size());
+ for(int i = 0; i < (int)vec.size(); i++) {
+ LOGD(" i=%d %02x\n", i, vec.at(i) & 0xff);
+ }
+}
+
+void dump_buff(const char* buff, int len) {
+ int i = 0;
+ LOGD("dump_buff() len=%d\n", len);
+ for(i = 0; i < len; i++) {
+ LOGD(" i=%d %02x\n", i, buff[i] & 0xff);
+ }
+}
+
+static void msleep(int interval) {
+ usleep(interval * 1000);
+}
+
+//-1 failed
+int epoll_add_fd(int epfd, int fd) {
+ struct epoll_event ev;
+ memset(&ev, 0, sizeof(ev));
+ ev.data.fd = fd;
+ ev.events = EPOLLIN;
+ //don't set the fd to edge trigger
+ //the some event like accept may be lost if two or more clients are connecting to server at the same time
+ //level trigger is preferred to avoid event lost
+ //do not set EPOLLOUT due to it will always trigger when write is available
+ if(epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) == -1) {
+ LOGE("epoll_add_fd() epoll_ctl() failure reason=[%s] epfd=%d fd=%d\n", strerror(errno), epfd, fd);
+ return -1;
+ }
+ return 0;
+}
+
+//LbsHidlService
+LbsHidlService::LbsHidlService(const char* name) :
+ mLbsHidlDeathRecipient(new LbsHidlDeathRecipient(this)) {
+
+ safe_strncpy(mName, name, sizeof(mName));
+ status_t status;
+ status = this->registerAsService(mName);
+ if(status != 0) {
+ LOGE("[%s] LbsHidlService() registerAsService() for name=[%s] failed status=[%d]",
+ g_ver, mName, status);
+ }
+ mLbsCallback = nullptr;
+ sem_init(&mSem, 0, 1);
+}
+
+LbsHidlService::~LbsHidlService() {
+ LOGD("[%s] ~LbsHidlService()", g_ver);
+ sem_destroy(&mSem);
+}
+
+Return<void> LbsHidlService::setCallback(const sp<ILbsCallback>& callback) {
+ LOGD("[%s][%s] setCallback()", g_ver, mName);
+ mLbsCallback = callback;
+ mLbsCallback->linkToDeath(mLbsHidlDeathRecipient, 0);
+ return Void();
+}
+
+Return<bool> LbsHidlService::sendToServer(const hidl_vec<uint8_t>& data) {
+ std::vector<uint8_t> tmp = data;
+ bool ret = false;
+ LOGE("[%s][%s] sendToServer() size=[%d] TBD!!!!", g_ver, mName, (int)tmp.size());
+ dump_vector(tmp);
+ return ret;
+}
+
+Return<bool> LbsHidlService::sendToServerWithCallback(const sp<ILbsCallback>& callback, const hidl_vec<uint8_t>& data) {
+ UNUSED(callback);
+ std::vector<uint8_t> tmp = data;
+ bool ret = false;
+ LOGE("[%s][%s] sendToServerWithCallback() size=[%d] TBD!!!", g_ver, mName, (int)tmp.size());
+ dump_vector(tmp);
+ return ret;
+}
+
+void LbsHidlService::handleHidlDeath() {
+ sem_wait(&mSem);
+ LOGD("[%s][%s] handleHidlDeath()", g_ver, mName);
+ mLbsCallback = nullptr;
+ sem_post(&mSem);
+}
+
+bool LbsHidlService::handleSocketEvent(int fd) {
+ int _ret;
+ int _offset = 0;
+ char _buff[16 * 1024] = {0};
+
+ _ret = read(fd, _buff, sizeof(_buff));
+ LOGD("[%s][%s] handleSocketEvent() ret=[%d]", g_ver, mName, _ret);
+ if(_ret == -1) {
+ LOGE("[%s][%s] handleSocketEvent() read() failed, fd=%d err=[%s]%d",
+ g_ver, mName, fd, strerror(errno), errno);
+ return false;
+ }
+ sem_wait(&mSem);
+ if(mLbsCallback != nullptr) {
+ std::vector<uint8_t> tmp;
+ covertArray2Vector(_buff, _ret, tmp);
+ auto ret = mLbsCallback->callbackToClient(tmp);
+ if (!ret.isOk()) {
+ LOGE("[%s][%s] handleSocketEvent() callbackToClient() failed", g_ver, mName);
+ }
+ }
+ sem_post(&mSem);
+ return true;
+}
+
+//UdpHidlService
+UdpHidlService::UdpHidlService(const char* name) : LbsHidlService(name) {
+ mtk_socket_client_init_local(&mSocketLPPe, mName, SOCK_NS_ABSTRACT);
+}
+
+Return<bool> UdpHidlService::sendToServer(const hidl_vec<uint8_t>& data) {
+ std::vector<uint8_t> tmp = data;
+ LOGD("[%s][%s] sendToServer() size=[%d]", g_ver, mName, (int)tmp.size());
+
+
+ if(!mtk_socket_client_connect(&mSocketLPPe)) {
+ LOGE("[%s][%s] sendToServer() mtk_socket_client_connect() failed", g_ver, mName);
+ return false;
+ }
+ //dump_vector(tmp);
+ char _buff[16 * 1024] = {0};
+ int _offset = (int)tmp.size();
+ covertVector2Array(data, _buff);
+ //dump_buff(_buff, _offset);
+ int _ret = mtk_socket_write(mSocketLPPe.fd, _buff, _offset);
+ if(_ret == -1) {
+ LOGE("[%s][%s] sendToServer() mtk_socket_write() failed", g_ver, mName);
+ return false;
+ }
+ mtk_socket_client_close(&mSocketLPPe);
+ return true;
+}
+
+//AgpsInterfaceHidlService
+AgpsInterfaceHidlService::AgpsInterfaceHidlService(const char* name) : LbsHidlService(name) {
+}
+
+Return<bool> AgpsInterfaceHidlService::sendToServerWithCallback(const sp<ILbsCallback>& callback, const hidl_vec<uint8_t>& data) {
+ std::vector<uint8_t> tmp = data;
+ char buff[16 * 1024] = {0};
+ bool ret = true;
+ int read_len = 0;
+ LOGD("[%s][%s] sendToServerWithCallback() size=%d", g_ver, mName, (int)tmp.size());
+ int fd = mtk_socket_tcp_connect_local("/dev/socket/agpsd2", SOCK_NS_FILESYSTEM);
+ if(fd < 0) {
+ LOGE("[%s][%s] mtk_socket_tcp_connect_local() failed", g_ver, mName);
+ return false;
+ }
+ covertVector2Array(data, buff);
+ read_len = mtk_socket_write(fd, buff, (int)tmp.size());
+ if(read_len == -1) {
+ ret = false;
+ }
+ memset(buff, 0, sizeof(buff));
+ read_len = 0;
+ if(ret) {
+ read_len = read(fd, buff, sizeof(buff));
+ }
+ close(fd);
+ covertArray2Vector(buff, read_len, tmp);
+ auto _ret = callback->callbackToClient(tmp);
+ if (!_ret.isOk()) {
+ LOGE("[%s][%s] sendToServerWithCallback() callbackToClient() failed", g_ver, mName);
+ }
+ return ret;
+}
+
+//AgpsDebugInterfaceHidlService
+AgpsDebugInterfaceHidlService::AgpsDebugInterfaceHidlService(const char* name) : LbsHidlService(name) {
+ mSocketFd = -1;
+ mIsExit = true;
+}
+
+Return<void> AgpsDebugInterfaceHidlService::setCallback(const sp<ILbsCallback>& callback) {
+ LOGD("[%s][%s] setCallback()", g_ver, mName);
+ mLbsCallback = callback;
+ mLbsCallback->linkToDeath(mLbsHidlDeathRecipient, 0);
+ mSocketFd = mtk_socket_tcp_connect_local("/dev/socket/agpsd3", SOCK_NS_FILESYSTEM);
+ if(mSocketFd < 0) {
+ LOGE("[%s][%s] setCallback() mtk_socket_tcp_connect_local() failed", g_ver, mName);
+ return Void();
+ }
+ epoll_add_fd(g_epfd, mSocketFd);
+ mIsExit = false;
+ return Void();
+}
+
+Return<bool> AgpsDebugInterfaceHidlService::sendToServer(const hidl_vec<uint8_t>& data) {
+ std::vector<uint8_t> tmp = data;
+ LOGD("[%s][%s] sendToServer() size=[%d]", g_ver, mName, (int)tmp.size());
+ char buff[16 * 1024] = {0};
+ int read_len = 0;
+ covertVector2Array(data, buff);
+ read_len = mtk_socket_write(mSocketFd, buff, (int)tmp.size());
+ // we don't care the error happens in this scenario
+ UNUSED(read_len);
+ mIsExit = true;
+ return true;
+}
+
+bool AgpsDebugInterfaceHidlService::handleSocketEvent(int fd) {
+ int _ret;
+ char _buff[16 * 1024] = {0};
+
+ _ret = read(fd, _buff, sizeof(_buff));
+ LOGD("[%s][%s] handleSocketEvent() ret=[%d] isExit=[%d]", g_ver, mName, _ret, mIsExit);
+ if(mIsExit) {
+ close(mSocketFd);
+ } else if (_ret <= 0) {
+ LOGE("[%s][%s] handleSocketEvent() read() failed, fd=%d err=[%s]%d",
+ g_ver, mName, fd, strerror(errno), errno);
+ close(mSocketFd);
+ mSocketFd = -1;
+ while(mSocketFd < 0) {
+ msleep(500);
+ mSocketFd = mtk_socket_tcp_connect_local("/dev/socket/agpsd3", SOCK_NS_FILESYSTEM);
+ LOGD("[%s][%s] handleSocketEvent() mtk_socket_tcp_connect_local() mSocketFd=[%d]",
+ g_ver, mName, mSocketFd);
+ if(mSocketFd > 0) {
+ epoll_add_fd(g_epfd, mSocketFd);
+ break;
+ }
+ }
+ LOGD("[%s][%s] handleSocketEvent() re-connect done", g_ver, mName);
+ } else {
+ sem_wait(&mSem);
+ if(mLbsCallback != nullptr) {
+ std::vector<uint8_t> tmp;
+ covertArray2Vector(_buff, _ret, tmp);
+ auto ret = mLbsCallback->callbackToClient(tmp);
+ if (!ret.isOk()) {
+ LOGE("[%s][%s] handleSocketEvent() callbackToClient() failed", g_ver, mName);
+ }
+ }
+ sem_post(&mSem);
+ }
+ return true;
+}
+
+int AgpsDebugInterfaceHidlService::getSocketFd() {
+ return mSocketFd;
+}
+
+
+//Agps2ApnHidlService, lbs hidl service -> agps_apn
+Agps2ApnHidlService::Agps2ApnHidlService(const char* name) : UdpHidlService(name) {
+ mSocketFd = -1;
+}
+
+Return<void> Agps2ApnHidlService::setCallback(const sp<ILbsCallback>& callback) {
+ LbsHidlService::setCallback(callback);
+
+ mSocketFd = mtk_socket_server_bind_local("mtk_agps2framework", SOCK_NS_ABSTRACT);
+ if(mSocketFd < 0) {
+ LOGE("[%s][%s] setCallback() mtk_socket_server_bind_local(mtk_agps2framework) failed", g_ver, mName);
+ return Void();
+ }
+ epoll_add_fd(g_epfd, mSocketFd);
+ return Void();
+}
+
+void Agps2ApnHidlService::handleHidlDeath() {
+ LbsHidlService::handleHidlDeath();
+
+ if (mSocketFd < 0) {
+ LOGE("[%s][%s] handleHidlDeath() error mSocketFd: %d", g_ver, mName, mSocketFd);
+ return;
+ }
+ close(mSocketFd);
+ mSocketFd = -1;
+}
+
+int Agps2ApnHidlService::getSocketFd() {
+ return mSocketFd;
+}
+
+/*************************************************
+* Timer
+**************************************************/
+// -1 means failure
+
+timer_t init_timer_id(timer_callback cb, int id) {
+ struct sigevent sevp;
+ timer_t timerid;
+
+ memset(&sevp, 0, sizeof(sevp));
+ sevp.sigev_value.sival_int = id;
+ sevp.sigev_notify = SIGEV_THREAD;
+ sevp.sigev_notify_function = cb;
+
+ if (timer_create(CLOCK_MONOTONIC, &sevp, &timerid) == -1) {
+ LOGE("timer_create failed reason=[%s]", strerror(errno));
+ return (timer_t)-1;
+ }
+ LOGE("successfully timer created id= %d", timerid);
+ return timerid;
+}
+
+// -1 means failure
+timer_t init_timer(timer_callback cb) {
+ return init_timer_id(cb, 0);
+}
+
+// -1 means failure
+int start_timer(timer_t timerid, int milliseconds) {
+ struct itimerspec expire;
+ expire.it_interval.tv_sec = 0;
+ expire.it_interval.tv_nsec = 0;
+ expire.it_value.tv_sec = milliseconds/1000;
+ expire.it_value.tv_nsec = (milliseconds%1000)*1000000;
+ return timer_settime(timerid, 0, &expire, NULL);
+}
+
+// -1 means failure
+int stop_timer(timer_t timerid) {
+ return start_timer(timerid, 0);
+}
+
+// -1 means failure
+int deinit_timer(timer_t timerid) {
+ if (timer_delete(timerid) == -1) {
+ // errno
+ return -1;
+ }
+ return 0;
+}
+
+
+bool lbs_timeout_restart_enabled(void) {
+ char result[PROPERTY_VALUE_MAX] = {0};
+
+ if((property_get("ro.mtk_hidl_consolidation", result, NULL) != 0) && (result[0] == '1')) {
+ LOGD("LBS_timeout disabled because hidl service consolidation enabled!!!");
+ return false;
+ } else {
+ LOGD("LBS_timeout enabled because hidl service consolidation disabled!!!");
+ return true;
+ }
+}
+
+bool lbs_timeout_ne_enabled(void) {
+ char result[PROPERTY_VALUE_MAX] = {0};
+
+ if((property_get("debug.gps.mnld.ne", result, NULL) != 0) && (result[0] == '1')) {
+ LOGD("NE enabled!!!");
+ return true;
+ } else {
+ LOGD("NE disabled!!!");
+ return false;
+ }
+}
+
+static void crash_to_debug() {
+ int* crash = 0;
+ *crash = 100;
+}
+
+static void lbs_control_thread_timeout(sigval_t sig) {
+ UNUSED(sig);
+
+ LOGE("lbs_control timeout handleCase = %d", handleCase);
+ if (lbs_timeout_restart_enabled()) {
+ if (lbs_timeout_ne_enabled() == false) {
+ LOGE("lbs_control_thread_timeout() exit.");
+ exit(0);
+ } else {
+ LOGE("lbs_control_thread_timeout() crash here for debugging");
+ crash_to_debug();
+ }
+ }
+}
+
+static void* lbs_hidl_thread(void *arg) {
+ UNUSED(arg);
+ struct epoll_event events[MAX_EPOLL_EVENT];
+ int fd_lppe_wlan = mtk_socket_server_bind_local("mtk_lppe_socket_wlan", SOCK_NS_ABSTRACT);
+ int fd_lppe_bt = mtk_socket_server_bind_local("mtk_lppe_socket_bt", SOCK_NS_ABSTRACT);
+ int fd_lppe_sensor = mtk_socket_server_bind_local("mtk_lppe_socket_sensor", SOCK_NS_ABSTRACT);
+ int fd_lppe_network = mtk_socket_server_bind_local("mtk_lppe_socket_network", SOCK_NS_ABSTRACT);
+ int fd_lppe_ipaddr = mtk_socket_server_bind_local("mtk_lppe_socket_ipaddr", SOCK_NS_ABSTRACT);
+ int fd_lppe_lbs = mtk_socket_server_bind_local("mtk_lppe_socket_lbs", SOCK_NS_ABSTRACT);
+ int fd_mnld2nlputils = mtk_socket_server_bind_local("mtk_mnld2nlputils", SOCK_NS_ABSTRACT);
+ int fd_mnld2debugService = mtk_socket_server_bind_local("mtk_mnld2debugService", SOCK_NS_ABSTRACT);
+ timer_t hdlr_timer = init_timer(lbs_control_thread_timeout);
+
+ epoll_add_fd(g_epfd, fd_lppe_wlan);
+ epoll_add_fd(g_epfd, fd_lppe_bt);
+ epoll_add_fd(g_epfd, fd_lppe_sensor);
+ epoll_add_fd(g_epfd, fd_lppe_network);
+ epoll_add_fd(g_epfd, fd_lppe_ipaddr);
+ epoll_add_fd(g_epfd, fd_lppe_lbs);
+ epoll_add_fd(g_epfd, fd_mnld2nlputils);
+ epoll_add_fd(g_epfd, fd_mnld2debugService);
+
+ while(1) {
+ int i;
+ int n;
+
+ n = epoll_wait(g_epfd, events, MAX_EPOLL_EVENT , -1);
+ if(n == -1) {
+ if(errno == EINTR) {
+ continue;
+ } else {
+ LOGE("[%s] lbs_hidl_thread() epoll_wait() failure reason=[%s]\n", g_ver, strerror(errno));
+ return NULL;
+ }
+ }
+
+ start_timer(hdlr_timer, LBS_HANDLER_TIMEOUT);
+ for(i = 0; i < n; i++) {
+ if(events[i].data.fd == fd_lppe_wlan && events[i].events & EPOLLIN) {
+ handleCase = 1;
+ hidlLPPeWlan->handleSocketEvent(fd_lppe_wlan);
+ } else if(events[i].data.fd == fd_lppe_bt && events[i].events & EPOLLIN) {
+ handleCase = 2;
+ hidlLPPeBT->handleSocketEvent(fd_lppe_bt);
+ } else if(events[i].data.fd == fd_lppe_sensor && events[i].events & EPOLLIN) {
+ handleCase = 3;
+ hidlLPPeSensor->handleSocketEvent(fd_lppe_sensor);
+ } else if(events[i].data.fd == fd_lppe_network && events[i].events & EPOLLIN) {
+ handleCase = 4;
+ hidlLPPeNetwork->handleSocketEvent(fd_lppe_network);
+ } else if(events[i].data.fd == fd_lppe_ipaddr && events[i].events & EPOLLIN) {
+ handleCase = 5;
+ hidlLPPeIpAddr->handleSocketEvent(fd_lppe_ipaddr);
+ } else if(events[i].data.fd == fd_lppe_lbs && events[i].events & EPOLLIN) {
+ handleCase = 6;
+ hidlLPPeLbs->handleSocketEvent(fd_lppe_lbs);
+ } else if(events[i].data.fd == hidlAgpsDebugInterface->getSocketFd() && events[i].events & EPOLLIN) {
+ handleCase = 7;
+ hidlAgpsDebugInterface->handleSocketEvent(hidlAgpsDebugInterface->getSocketFd());
+ } else if(events[i].data.fd == hidlAgps2Apn->getSocketFd() && events[i].events & EPOLLIN) {
+ handleCase = 8;
+ hidlAgps2Apn->handleSocketEvent(hidlAgps2Apn->getSocketFd());
+ } else if(events[i].data.fd == fd_mnld2nlputils && events[i].events & EPOLLIN) {
+ handleCase = 9;
+ hidlMnld2NlpUtils->handleSocketEvent(fd_mnld2nlputils);
+ } else if(events[i].data.fd == fd_mnld2debugService && events[i].events & EPOLLIN) {
+ handleCase = 10;
+ hidlMnld2DebugService->handleSocketEvent(fd_mnld2debugService);
+ }
+ }
+ stop_timer(hdlr_timer);
+ }
+ return NULL;
+}
+
+int cpp_main() {
+ LOGD("[%s] lbs hidl service is running", g_ver);
+
+ ::android::hardware::configureRpcThreadpool(20, true);
+
+ hidlLPPeAgps = new UdpHidlService("mtk_lppe_socket_agps");
+ hidlLPPeWlan = new UdpHidlService("mtk_lppe_socket_wlan");
+ hidlLPPeBT = new UdpHidlService("mtk_lppe_socket_bt");
+ hidlLPPeSensor = new UdpHidlService("mtk_lppe_socket_sensor");
+ hidlLPPeNetwork = new UdpHidlService("mtk_lppe_socket_network");
+ hidlLPPeIpAddr = new UdpHidlService("mtk_lppe_socket_ipaddr");
+ hidlLPPeLbs = new UdpHidlService("mtk_lppe_socket_lbs");
+
+ // agps_apn -> lbs hidl service
+ hidlApn2Agps = new UdpHidlService("mtk_framework2agps");
+ // lbs hidl service -> agps_apn
+ hidlAgps2Apn = new Agps2ApnHidlService("mtk_agps2framework");
+ // mnld -> lbs hidl service
+ hidlMnld2NlpUtils = new UdpHidlService("mtk_mnld2nlputils");
+ // mnld -> debug service
+ hidlMnld2DebugService = new UdpHidlService("mtk_mnld2debugService");
+ // debug service -> mnld
+ hidlDebugService2Mnld = new UdpHidlService("mtk_debugService2mnld");
+ // meta -> mnld
+ hidlMeta2Mnld = new UdpHidlService("mtk_meta2mnld");
+
+ hidlAgpsInterface = new AgpsInterfaceHidlService("AgpsInterface");
+ hidlAgpsDebugInterface = new AgpsDebugInterfaceHidlService("AgpsDebugInterface");
+
+ // ... add more LBS HIDL Service here
+
+ pthread_t pthread1;
+ pthread_create(&pthread1, NULL, lbs_hidl_thread, NULL);
+
+ return 0;
+}
+
+} // implementation
+} // namespace V1_0
+} // namespace lbs
+} // namespace hardware
+} // namespace mediatek
+} // namespace vendor
+
diff --git a/src/connectivity/gps/lbs_hidl_service/lbs_hidl_service.h b/src/connectivity/gps/lbs_hidl_service/lbs_hidl_service.h
new file mode 100644
index 0000000..d7f7a7d
--- /dev/null
+++ b/src/connectivity/gps/lbs_hidl_service/lbs_hidl_service.h
@@ -0,0 +1,109 @@
+
+#ifndef __LBS_HIDL_SERVICE_H__
+#define __LBS_HIDL_SERVICE_H__
+
+#include <vendor/mediatek/hardware/lbs/1.0/ILbs.h>
+#include <semaphore.h>
+#include "mtk_socket_utils.h"
+
+namespace vendor {
+namespace mediatek {
+namespace hardware {
+namespace lbs {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::wp;
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_death_recipient;
+using ::android::hidl::base::V1_0::IBase;
+
+#ifdef UNUSED
+#undef UNUSED
+#endif
+#define UNUSED(expr) do { (void)(expr); } while (0)
+
+class LbsHidlService : public ILbs {
+public:
+ LbsHidlService(const char* name);
+ ~LbsHidlService();
+
+ virtual Return<void> setCallback(const sp<ILbsCallback>& callback) override;
+ virtual Return<bool> sendToServer(const hidl_vec<uint8_t>& data) override;
+ virtual Return<bool> sendToServerWithCallback(const sp<ILbsCallback>& callback, const hidl_vec<uint8_t>& data) override;
+
+ class LbsHidlDeathRecipient : public hidl_death_recipient {
+ public:
+ LbsHidlDeathRecipient(const sp<LbsHidlService> lbs) : mLbs(lbs) {
+ }
+ virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
+ UNUSED(cookie);
+ UNUSED(who);
+ mLbs->handleHidlDeath();
+ }
+ private:
+ sp<LbsHidlService> mLbs;
+ };
+ virtual void handleHidlDeath();
+
+ virtual bool handleSocketEvent(int fd);
+
+protected:
+ char mName[64];
+ sp<ILbsCallback> mLbsCallback;
+ sp<LbsHidlDeathRecipient> mLbsHidlDeathRecipient;
+ sem_t mSem;
+};
+
+class UdpHidlService : public LbsHidlService {
+public:
+ UdpHidlService(const char* name);
+ Return<bool> sendToServer(const hidl_vec<uint8_t>& data) override;
+protected:
+ mtk_socket_fd mSocketLPPe;
+};
+
+class AgpsInterfaceHidlService : public LbsHidlService {
+public:
+ AgpsInterfaceHidlService(const char* name);
+ Return<bool> sendToServerWithCallback(const sp<ILbsCallback>& callback, const hidl_vec<uint8_t>& data) override;
+};
+
+class AgpsDebugInterfaceHidlService : public LbsHidlService {
+public:
+ AgpsDebugInterfaceHidlService (const char* name);
+ Return<void> setCallback(const sp<ILbsCallback>& callback) override;
+ Return<bool> sendToServer(const hidl_vec<uint8_t>& data) override;
+ bool handleSocketEvent(int fd) override;
+ int getSocketFd();
+protected:
+ int mSocketFd;
+ bool mIsExit;
+};
+
+class Agps2ApnHidlService : public UdpHidlService {
+public:
+ Agps2ApnHidlService (const char* name);
+ Return<void> setCallback(const sp<ILbsCallback>& callback) override;
+ void handleHidlDeath() override;
+ int getSocketFd();
+protected:
+ int mSocketFd;
+};
+
+extern int cpp_main();
+
+} // implementation
+} // namespace V1_0
+} // namespace lbs
+} // namespace hardware
+} // namespace mediatek
+} // namespace vendor
+
+#endif // __LBS_HIDL_SERVICE_H__
+
diff --git a/src/connectivity/gps/lbs_hidl_service/lbs_hidl_service.rc b/src/connectivity/gps/lbs_hidl_service/lbs_hidl_service.rc
new file mode 100644
index 0000000..b75296c
--- /dev/null
+++ b/src/connectivity/gps/lbs_hidl_service/lbs_hidl_service.rc
@@ -0,0 +1,4 @@
+service lbs_hidl_service /vendor/bin/lbs_hidl_service
+ class main
+ user system
+ group system gps radio inet sdcard_r sdcard_rw
diff --git a/src/connectivity/gps/lbs_hidl_service/mtk_socket_utils/inc/mtk_socket_data_coder.h b/src/connectivity/gps/lbs_hidl_service/mtk_socket_utils/inc/mtk_socket_data_coder.h
new file mode 100644
index 0000000..da994d9
--- /dev/null
+++ b/src/connectivity/gps/lbs_hidl_service/mtk_socket_utils/inc/mtk_socket_data_coder.h
@@ -0,0 +1,50 @@
+// This source code is generated by UdpGeneratorTool, not recommend to modify it directly
+#ifndef __DATA_CODER_H__
+#define __DATA_CODER_H__
+
+#include "mtk_socket_utils.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool mtk_socket_get_bool(char* buff, int* offset);
+int8_t mtk_socket_get_char(char* buff, int* offset);
+int16_t mtk_socket_get_short(char* buff, int* offset);
+int32_t mtk_socket_get_int(char* buff, int* offset);
+int64_t mtk_socket_get_int64_t(char* buff, int* offset);
+float mtk_socket_get_float(char* buff, int* offset);
+double mtk_socket_get_double(char* buff, int* offset);
+int mtk_socket_get_string(char* buff, int* offset, char* output, int max_size);
+int mtk_socket_get_bool_array(char* buff, int* offset, bool output[], int max_size);
+int mtk_socket_get_char_array(char* buff, int* offset, int8_t output[], int max_size);
+int mtk_socket_get_short_array(char* buff, int* offset, int16_t output[], int max_size);
+int mtk_socket_get_int_array(char* buff, int* offset, int32_t output[], int max_size);
+int mtk_socket_get_int64_t_array(char* buff, int* offset, int64_t output[], int max_size);
+int mtk_socket_get_float_array(char* buff, int* offset, float output[], int max_size);
+int mtk_socket_get_double_array(char* buff, int* offset, double output[], int max_size);
+int mtk_socket_get_string_array(char* buff, int* offset, strings output, int max_size1, int max_size2);
+
+void mtk_socket_put_bool(char* buff, int* offset, bool input);
+void mtk_socket_put_char(char* buff, int* offset, int8_t input);
+void mtk_socket_put_short(char* buff, int* offset, int16_t input);
+void mtk_socket_put_int(char* buff, int* offset, int32_t input);
+void mtk_socket_put_int64_t(char* buff, int* offset, int64_t input);
+void mtk_socket_put_float(char* buff, int* offset, float input);
+void mtk_socket_put_double(char* buff, int* offset, double input);
+void mtk_socket_put_string(char* buff, int* offset, const char* input);
+void mtk_socket_put_bool_array(char* buff, int* offset, bool input[], int size);
+void mtk_socket_put_char_array(char* buff, int* offset, int8_t input[], int size);
+void mtk_socket_put_short_array(char* buff, int* offset, int16_t input[], int size);
+void mtk_socket_put_int_array(char* buff, int* offset, int32_t input[], int size);
+void mtk_socket_put_int64_t_array(char* buff, int* offset, int64_t input[], int size);
+void mtk_socket_put_float_array(char* buff, int* offset, float input[], int size);
+void mtk_socket_put_double_array(char* buff, int* offset, double input[], int size);
+void mtk_socket_put_string_array(char* buff, int* offset, strings input, int size1, int size2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/connectivity/gps/lbs_hidl_service/mtk_socket_utils/inc/mtk_socket_utils.h b/src/connectivity/gps/lbs_hidl_service/mtk_socket_utils/inc/mtk_socket_utils.h
new file mode 100644
index 0000000..436a2dd
--- /dev/null
+++ b/src/connectivity/gps/lbs_hidl_service/mtk_socket_utils/inc/mtk_socket_utils.h
@@ -0,0 +1,246 @@
+// This source code is generated by UdpGeneratorTool, not recommend to modify it directly
+#ifndef __MTK_SOCKET_UTILS_H__
+#define __MTK_SOCKET_UTILS_H__
+
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <pthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define strings void*
+
+#ifndef UNUSED
+#define UNUSED(x) (x)=(x)
+#endif
+
+typedef enum {
+ SOCK_NS_ABSTRACT = 0,
+ SOCK_NS_FILESYSTEM = 1,
+} mtk_socket_namespace;
+
+typedef struct {
+ int fd;
+ bool is_local;
+ pthread_mutex_t mutex;
+
+ // Network
+ char* host;
+ int port;
+
+ // Local
+ char* path;
+ mtk_socket_namespace namesapce;
+} mtk_socket_fd;
+
+void _mtk_socket_log(int type, const char *fmt, ...);
+
+#define SOCK_LOGD(...) _mtk_socket_log(0, __VA_ARGS__);
+#define SOCK_LOGE(...) _mtk_socket_log(1, __VA_ARGS__);
+
+//-1 means failure
+int mtk_socket_server_bind_network(int port);
+//-1 means failure
+int mtk_socket_server_bind_network_ipv6(int port);
+//-1 means failure
+int mtk_socket_server_bind_local(const char* path, mtk_socket_namespace sock_namespace);
+
+void mtk_socket_client_init_network(mtk_socket_fd* sock_fd, const char* host, int port);
+void mtk_socket_client_init_local(mtk_socket_fd* sock_fd, const char* path, mtk_socket_namespace sock_namespace);
+
+void mtk_socket_client_cleanup(mtk_socket_fd* sock_fd);
+
+bool mtk_socket_client_connect(mtk_socket_fd* sock_fd);
+void mtk_socket_client_close(mtk_socket_fd* sock_fd);
+
+// return -1 means fail
+int mtk_socket_tcp_connect_local(const char* path, mtk_socket_namespace sock_namespace);
+
+//-1 means failure
+int mtk_socket_read(int fd, char* buff, int len);
+
+//-1 means failure
+int mtk_socket_write(int fd, void* buff, int len);
+
+// <= 0 means no data received
+int mtk_socket_poll(int fd, int timeout);
+
+
+void mtk_socket_buff_dump(const char* buff, int len);
+
+bool mtk_socket_string_is_equal(char* data1, char* data2);
+bool mtk_socket_string_array_is_equal(strings data1, int data1_size, strings data2, int data2_size, int string_size);
+void mtk_socket_string_array_dump(strings input, int size1, int size2);
+
+bool mtk_socket_bool_array_is_equal(bool data1[], int data1_size, bool data2[], int data2_size);
+void mtk_socket_bool_array_dump(bool input[], int size);
+
+bool mtk_socket_char_array_is_equal(char data1[], int data1_size, char data2[], int data2_size);
+void mtk_socket_char_array_dump(char input[], int size);
+
+bool mtk_socket_short_array_is_equal(short data1[], int data1_size, short data2[], int data2_size);
+void mtk_socket_short_array_dump(short input[], int size);
+
+bool mtk_socket_int_array_is_equal(int data1[], int data1_size, int data2[], int data2_size);
+void mtk_socket_int_array_dump(int input[], int size);
+
+bool mtk_socket_int64_t_array_is_equal(int64_t data1[], int data1_size, int64_t data2[], int data2_size);
+void mtk_socket_int64_t_array_dump(int64_t input[], int size);
+
+bool mtk_socket_float_array_is_equal(float data1[], int data1_size, float data2[], int data2_size);
+void mtk_socket_float_array_dump(float input[], int size);
+
+bool mtk_socket_double_array_is_equal(double data1[], int data1_size, double data2[], int data2_size);
+void mtk_socket_double_array_dump(double input[], int size);
+
+bool mtk_socket_expected_bool(char* buff, int* offset, bool expected_value, const char* func, int line);
+bool mtk_socket_expected_char(char* buff, int* offset, char expected_value, const char* func, int line);
+bool mtk_socket_expected_short(char* buff, int* offset, short expected_value, const char* func, int line);
+bool mtk_socket_expected_int(char* buff, int* offset, int expected_value, const char* func, int line);
+bool mtk_socket_expected_int64_t(char* buff, int* offset, int64_t expected_value, const char* func, int line);
+bool mtk_socket_expected_float(char* buff, int* offset, float expected_value, const char* func, int line);
+bool mtk_socket_expected_double(char* buff, int* offset, double expected_value, const char* func, int line);
+bool mtk_socket_expected_string(char* buff, int* offset, const char* expected_value, int max_size, const char* func, int line);
+
+char *safe_strncpy(char *dest, const char *src, size_t n);
+
+#define ASSERT_EQUAL_INT(d1, d2) \
+{\
+ int _d1 = d1;\
+ int _d2 = d2;\
+ if(_d1 != _d2) {\
+ SOCK_LOGE("%s():%d ASSERT_EQUAL_INT() failed, d1=[%d], d2=[%d]",\
+ __func__, __LINE__, _d1, _d2);\
+ return false;\
+ }\
+}
+
+#define EXPECTED_BOOL(buff, offset, expected_value) \
+{\
+ if(!mtk_socket_expected_bool(buff, offset, expected_value, __func__, __LINE__)) {\
+ return false;\
+ }\
+}
+
+#define EXPECTED_CHAR(buff, offset, expected_value) \
+{\
+ if(!mtk_socket_expected_char(buff, offset, expected_value, __func__, __LINE__)) {\
+ return false;\
+ }\
+}
+
+#define EXPECTED_SHORT(buff, offset, expected_value) \
+{\
+ if(!mtk_socket_expected_short(buff, offset, expected_value, __func__, __LINE__)) {\
+ return false;\
+ }\
+}
+
+#define EXPECTED_INT(buff, offset, expected_value) \
+{\
+ if(!mtk_socket_expected_int(buff, offset, expected_value, __func__, __LINE__)) {\
+ return false;\
+ }\
+}
+
+#define EXPECTED_INT64_T(buff, offset, expected_value) \
+{\
+ if(!mtk_socket_expected_int64_t(buff, offset, expected_value, __func__, __LINE__)) {\
+ return false;\
+ }\
+}
+
+#define EXPECTED_FLOAT(buff, offset, expected_value) \
+{\
+ if(!mtk_socket_expected_float(buff, offset, expected_value, __func__, __LINE__)) {\
+ return false;\
+ }\
+}
+
+#define EXPECTED_DOUBLE(buff, offset, expected_value) \
+{\
+ if(!mtk_socket_expected_double(buff, offset, expected_value, __func__, __LINE__)) {\
+ return false;\
+ }\
+}
+
+#define EXPECTED_STRING(buff, offset, expected_value, max_size) \
+{\
+ if(!mtk_socket_expected_string(buff, offset, expected_value, max_size, __func__, __LINE__)) {\
+ return false;\
+ }\
+}
+
+#define EXPECTED_STRUCT(buff, offset, expected_value, struct_name) \
+{\
+ struct_name _tmp;\
+ struct_name##_decode(buff, offset, &_tmp);\
+ if(!struct_name##_is_equal(&_tmp, expected_value)) {\
+ SOCK_LOGE("%s():%d EXPECTED_STRUCT() %s_is_equal() fail", __func__, __LINE__, #struct_name);\
+ SOCK_LOGE(" ============= read ===============");\
+ struct_name##_dump(&_tmp);\
+ SOCK_LOGE(" ============= expected ===============");\
+ struct_name##_dump(expected_value);\
+ return false;\
+ }\
+}
+
+#define EXPECTED_ARRAY(buff, offset, expected_num, expected_value, type, max_size) \
+{\
+ type _tmp[max_size] = {0};\
+ int _tmp_num = mtk_socket_get_##type##_array(buff, offset, _tmp, max_size);\
+ if(!mtk_socket_##type##_array_is_equal(expected_value, expected_num, _tmp, _tmp_num)) {\
+ SOCK_LOGE("%s():%d expected_%s_array() fail", __func__, __LINE__, #type);\
+ SOCK_LOGE(" ============= read ===============");\
+ mtk_socket_##type##_array_dump(_tmp, _tmp_num);\
+ SOCK_LOGE(" ============= expected ===============");\
+ mtk_socket_##type##_array_dump(expected_value, expected_num);\
+ return false;\
+ }\
+}
+
+#define EXPECTED_STRING_ARRAY(buff, offset, expected_num, expected_value, max_size1, max_size2) \
+{\
+ char _tmp[max_size1][max_size2];\
+ int _tmp_num = mtk_socket_get_string_array(buff, offset, _tmp, max_size1, max_size2);\
+ if(!mtk_socket_string_array_is_equal(expected_value, expected_num, _tmp, _tmp_num, max_size2)) {\
+ SOCK_LOGE("%s():%d expected_string_array() fail", __func__, __LINE__);\
+ SOCK_LOGE(" ============= read ===============");\
+ mtk_socket_string_array_dump(_tmp, _tmp_num, max_size2);\
+ SOCK_LOGE(" ============= expected ===============");\
+ mtk_socket_string_array_dump(expected_value, expected_num, max_size2);\
+ return false;\
+ }\
+}
+
+#define EXPECTED_STRUCT_ARRAY(buff, offset, expected_num, expected_value, type, max_size) \
+{\
+ type _tmp[max_size];\
+ int _tmp_num = type##_array_decode(buff, offset, _tmp, max_size);\
+ if(!type##_array_is_equal(expected_value, expected_num, _tmp, _tmp_num)) {\
+ SOCK_LOGE("%s():%d expected_%s_array() fail", __func__, __LINE__, #type);\
+ SOCK_LOGE(" ============= read ===============");\
+ type##_array_dump(_tmp, _tmp_num);\
+ SOCK_LOGE(" ============= expected ===============");\
+ type##_array_dump(expected_value, expected_num);\
+ return false;\
+ }\
+}
+
+#define ASSERT_LESS_EQUAL_THAN(d1, d2) \
+{\
+ if(d1 > d2) {\
+ SOCK_LOGE("%s():%d ASSERT_LESS_EQUAL_THAN() fail, %s=[%d] > [%d]", __func__, __LINE__, #d1, d1, d2);\
+ return false;\
+ }\
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/connectivity/gps/lbs_hidl_service/mtk_socket_utils/src/mtk_socket_data_coder.c b/src/connectivity/gps/lbs_hidl_service/mtk_socket_utils/src/mtk_socket_data_coder.c
new file mode 100644
index 0000000..8d37e3d
--- /dev/null
+++ b/src/connectivity/gps/lbs_hidl_service/mtk_socket_utils/src/mtk_socket_data_coder.c
@@ -0,0 +1,256 @@
+// This source code is generated by UdpGeneratorTool, not recommend to modify it directly
+#include "mtk_socket_data_coder.h"
+
+bool mtk_socket_get_bool(char* buff, int* offset) {
+ bool ret = (mtk_socket_get_char(buff, offset) == 0)? false : true;
+ return ret;
+}
+
+int8_t mtk_socket_get_char(char* buff, int* offset) {
+ int8_t ret = buff[*offset];
+ *offset += 1;
+ return ret;
+}
+
+int16_t mtk_socket_get_short(char* buff, int* offset) {
+ int16_t ret = 0;
+ ret |= mtk_socket_get_char(buff, offset) & 0xff;
+ ret |= (mtk_socket_get_char(buff, offset) << 8);
+ return ret;
+}
+
+int32_t mtk_socket_get_int(char* buff, int* offset) {
+ int32_t ret = 0;
+ ret |= mtk_socket_get_short(buff, offset) & 0xffff;
+ ret |= (mtk_socket_get_short(buff, offset) << 16);
+ return ret;
+}
+
+int64_t mtk_socket_get_int64_t(char* buff, int* offset) {
+ int64_t ret = 0;
+ ret |= mtk_socket_get_int(buff, offset) & 0xffffffffL;
+ ret |= ((int64_t)mtk_socket_get_int(buff, offset) << 32);
+ return ret;
+}
+
+float mtk_socket_get_float(char* buff, int* offset) {
+ float ret;
+ int32_t tmp = mtk_socket_get_int(buff, offset);
+ ret = *((float*)&tmp);
+ return ret;
+}
+
+double mtk_socket_get_double(char* buff, int* offset) {
+ double ret;
+ int64_t tmp = mtk_socket_get_int64_t(buff, offset);
+ ret = *((double*)&tmp);
+ return ret;
+}
+
+int mtk_socket_get_string(char* buff, int* offset, char* output, int max_size) {
+ int size = mtk_socket_get_int(buff, offset);
+ memset(output, 0, max_size);
+ memcpy(output, &buff[*offset], (size > max_size)? max_size : size);
+ output[max_size - 1] = 0;
+ *offset += size;
+ return (size > max_size)? max_size : size;
+}
+
+int mtk_socket_get_bool_array(char* buff, int* offset, bool output[], int max_size) {
+ int i = 0;
+ int size = mtk_socket_get_int(buff, offset);
+ for(i = 0; i < size; i++) {
+ bool data = mtk_socket_get_bool(buff, offset);
+ if(i < max_size) {
+ output[i] = data;
+ }
+ }
+ return (size > max_size)? max_size : size;
+}
+
+int mtk_socket_get_char_array(char* buff, int* offset, int8_t output[], int max_size) {
+ int size = mtk_socket_get_int(buff, offset);
+ memcpy(output, &buff[*offset], (size > max_size)? max_size : size);
+ *offset += size;
+ return (size > max_size)? max_size : size;
+}
+
+int mtk_socket_get_short_array(char* buff, int* offset, int16_t output[], int max_size) {
+ int i = 0;
+ int size = mtk_socket_get_int(buff, offset);
+ for(i = 0; i < size; i++) {
+ int16_t data = mtk_socket_get_short(buff, offset);
+ if(i < max_size) {
+ output[i] = data;
+ }
+ }
+ return (size > max_size)? max_size : size;
+}
+
+int mtk_socket_get_int_array(char* buff, int* offset, int32_t output[], int max_size) {
+ int i = 0;
+ int size = mtk_socket_get_int(buff, offset);
+ for(i = 0; i < size; i++) {
+ int32_t data = mtk_socket_get_int(buff, offset);
+ if(i < max_size) {
+ output[i] = data;
+ }
+ }
+ return (size > max_size)? max_size : size;
+}
+
+int mtk_socket_get_int64_t_array(char* buff, int* offset, int64_t output[], int max_size) {
+ int i = 0;
+ int size = mtk_socket_get_int(buff, offset);
+ for(i = 0; i < size; i++) {
+ int64_t data = mtk_socket_get_int64_t(buff, offset);
+ if(i < max_size) {
+ output[i] = data;
+ }
+ }
+ return (size > max_size)? max_size : size;
+}
+
+int mtk_socket_get_float_array(char* buff, int* offset, float output[], int max_size) {
+ int i = 0;
+ int size = mtk_socket_get_int(buff, offset);
+ for(i = 0; i < size; i++) {
+ float data = mtk_socket_get_float(buff, offset);
+ if(i < max_size) {
+ output[i] = data;
+ }
+ }
+ return (size > max_size)? max_size : size;
+}
+
+int mtk_socket_get_double_array(char* buff, int* offset, double output[], int max_size) {
+ int i = 0;
+ int size = mtk_socket_get_int(buff, offset);
+ for(i = 0; i < size; i++) {
+ double data = mtk_socket_get_double(buff, offset);
+ if(i < max_size) {
+ output[i] = data;
+ }
+ }
+ return (size > max_size)? max_size : size;
+}
+
+int mtk_socket_get_string_array(char* buff, int* offset, strings output, int max_size1, int max_size2) {
+ int i = 0;
+ int size1 = mtk_socket_get_int(buff, offset);
+ for(i = 0; i < size1; i++) {
+ if(i < max_size1) {
+ mtk_socket_get_string(buff, offset, output, max_size2);
+ output = (char*)output + max_size2;
+ } else {
+ char tmp[max_size2];
+ mtk_socket_get_string(buff, offset, tmp, max_size2);
+ }
+ }
+ return (size1 > max_size1)? max_size1 : size1;
+}
+
+void mtk_socket_put_bool(char* buff, int* offset, bool input) {
+ mtk_socket_put_char(buff, offset, input);
+}
+
+void mtk_socket_put_char(char* buff, int* offset, int8_t input) {
+ *((int8_t*)&buff[*offset]) = input;
+ *offset += 1;
+}
+
+void mtk_socket_put_short(char* buff, int* offset, int16_t input) {
+ mtk_socket_put_char(buff, offset, input & 0xff);
+ mtk_socket_put_char(buff, offset, (input >> 8) & 0xff);
+}
+
+void mtk_socket_put_int(char* buff, int* offset, int32_t input) {
+ mtk_socket_put_short(buff, offset, input & 0xffff);
+ mtk_socket_put_short(buff, offset, (input >> 16) & 0xffff);
+}
+
+void mtk_socket_put_int64_t(char* buff, int* offset, int64_t input) {
+ mtk_socket_put_int(buff, offset, input & 0xffffffffL);
+ mtk_socket_put_int(buff, offset, ((input >> 32L) & 0xffffffffL));
+}
+
+void mtk_socket_put_float(char* buff, int* offset, float input) {
+ int32_t* data = (int32_t*)&input;
+ mtk_socket_put_int(buff, offset, *data);
+}
+
+void mtk_socket_put_double(char* buff, int* offset, double input) {
+ int64_t* data = (int64_t*)&input;
+ mtk_socket_put_int64_t(buff, offset, *data);
+}
+
+void mtk_socket_put_string(char* buff, int* offset, const char* input) {
+ int len = strlen(input);
+ mtk_socket_put_int(buff, offset, len);
+ memcpy(&buff[*offset], input, len);
+ *offset += len;
+}
+
+void mtk_socket_put_bool_array(char* buff, int* offset, bool input[], int size) {
+ int i = 0;
+ mtk_socket_put_int(buff, offset, size);
+ for(i = 0; i < size; i++) {
+ mtk_socket_put_bool(buff, offset, input[i]);
+ }
+}
+
+void mtk_socket_put_char_array(char* buff, int* offset, int8_t input[], int size) {
+ mtk_socket_put_int(buff, offset, size);
+ memcpy(&buff[*offset], input, size);
+ *offset += size;
+}
+
+void mtk_socket_put_short_array(char* buff, int* offset, int16_t input[], int size) {
+ int i = 0;
+ mtk_socket_put_int(buff, offset, size);
+ for(i = 0; i < size; i++) {
+ mtk_socket_put_short(buff, offset, input[i]);
+ }
+}
+
+void mtk_socket_put_int_array(char* buff, int* offset, int32_t input[], int size) {
+ int i = 0;
+ mtk_socket_put_int(buff, offset, size);
+ for(i = 0; i < size; i++) {
+ mtk_socket_put_int(buff, offset, input[i]);
+ }
+}
+
+void mtk_socket_put_int64_t_array(char* buff, int* offset, int64_t input[], int size) {
+ int i = 0;
+ mtk_socket_put_int(buff, offset, size);
+ for(i = 0; i < size; i++) {
+ mtk_socket_put_int64_t(buff, offset, input[i]);
+ }
+}
+
+void mtk_socket_put_float_array(char* buff, int* offset, float input[], int size) {
+ int i = 0;
+ mtk_socket_put_int(buff, offset, size);
+ for(i = 0; i < size; i++) {
+ mtk_socket_put_float(buff, offset, input[i]);
+ }
+}
+
+void mtk_socket_put_double_array(char* buff, int* offset, double input[], int size) {
+ int i = 0;
+ mtk_socket_put_int(buff, offset, size);
+ for(i = 0; i < size; i++) {
+ mtk_socket_put_double(buff, offset, input[i]);
+ }
+}
+
+void mtk_socket_put_string_array(char* buff, int* offset, strings input, int size1, int size2) {
+ int i = 0;
+ mtk_socket_put_int(buff, offset, size1);
+ for(i = 0; i < size1; i++) {
+ mtk_socket_put_string(buff, offset, (char*)input);
+ input = (char*)input + size2;
+ }
+}
+
diff --git a/src/connectivity/gps/lbs_hidl_service/mtk_socket_utils/src/mtk_socket_utils.c b/src/connectivity/gps/lbs_hidl_service/mtk_socket_utils/src/mtk_socket_utils.c
new file mode 100644
index 0000000..b58328b
--- /dev/null
+++ b/src/connectivity/gps/lbs_hidl_service/mtk_socket_utils/src/mtk_socket_utils.c
@@ -0,0 +1,704 @@
+// This source code is generated by UdpGeneratorTool, not recommend to modify it directly
+#include "mtk_socket_utils.h"
+#include "mtk_socket_data_coder.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <time.h>
+#include <stddef.h> // offsetof
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <unistd.h> //usleep
+#include <sys/socket.h>
+#include <string.h>
+#include <fcntl.h>
+#include <arpa/inet.h> //inet_addr
+#include <sys/un.h> //struct sockaddr_un
+#include <sys/epoll.h>
+#include <poll.h>
+#include <sys/types.h>
+#include <netdb.h>
+
+#if defined(__ANDROID_OS__)
+#include <cutils/log.h> // Android log
+
+#define ANDROID_LOG_TAG "mtk_socket"
+#endif
+
+
+#if !defined(__ANDROID_OS__)
+//-1 means failure
+static int get_time_str(char* buff, int len) {
+ struct timeval tv;
+ struct timezone tz;
+ struct tm *tm;
+
+ gettimeofday(&tv, &tz);
+ tm = localtime(&tv.tv_sec);
+
+ memset(buff, 0, len);
+ sprintf(buff, "%04d/%02d/%02d %02d:%02d:%02d.%03d",
+ tm->tm_year + 1900, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min,
+ tm->tm_sec, (int)(tv.tv_usec / 1000));
+
+ return 0;
+}
+#endif
+
+void _mtk_socket_log(int type, const char *fmt, ...) {
+ char buff[1024] = {0};
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsnprintf(buff, sizeof(buff), fmt, ap);
+ va_end(ap);
+
+#if defined(__ANDROID_OS__)
+ if(type == 0) {
+ __android_log_print(ANDROID_LOG_DEBUG, ANDROID_LOG_TAG, "%s", buff);
+ } else {
+ __android_log_print(ANDROID_LOG_ERROR, ANDROID_LOG_TAG, "ERR: %s", buff);
+ }
+#else
+ char time_buff[64] = {0};
+ get_time_str(time_buff, sizeof(time_buff));
+ if(type == 0) {
+ printf("%s %s\n", time_buff, buff);
+ } else {
+ printf("%s ERR: %s\n", time_buff, buff);
+ }
+ fflush(stdout);
+#endif
+}
+
+//-1 means failure
+int mtk_socket_server_bind_network(int port) {
+ struct sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (fd < 0) {
+ SOCK_LOGE("mtk_socket_server_bind_network() socket() failed reason=[%s]%d",
+ strerror(errno), errno);
+ return -1;
+ }
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
+ SOCK_LOGE("mtk_socket_server_bind_network() bind() failed reason=[%s]%d for port=[%d]",
+ strerror(errno), errno, port);
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+//-1 means failure
+int mtk_socket_server_bind_network_ipv6(int port) {
+ struct sockaddr_in6 addr;
+ memset(&addr, 0, sizeof(addr));
+ int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ if (fd < 0) {
+ SOCK_LOGE("mtk_socket_server_bind_network_ipv6() socket() failed reason=[%s]%d",
+ strerror(errno), errno);
+ return -1;
+ }
+ addr.sin6_family = AF_INET6;
+ addr.sin6_port = htons(port);
+ addr.sin6_addr = in6addr_any;
+ if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
+ SOCK_LOGE("mtk_socket_server_bind_network_ipv6() bind() failed reason=[%s]%d for port=[%d]",
+ strerror(errno), errno, port);
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+//-1 means failure
+int mtk_socket_server_bind_local(const char* path, mtk_socket_namespace sock_namespace) {
+ int size;
+ struct sockaddr_un addr;
+ int fd = socket(AF_UNIX, SOCK_DGRAM, 0);
+ if (fd < 0) {
+ SOCK_LOGE("mtk_socket_server_bind_local() socket() failed reason=[%s]%d",
+ strerror(errno), errno);
+ return -1;
+ }
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ size = strlen(path) + offsetof(struct sockaddr_un, sun_path) + 1;
+ if(sock_namespace == SOCK_NS_ABSTRACT) {
+ addr.sun_path[0] = 0;
+ memcpy(addr.sun_path + 1, path, strlen(path));
+ } else if(sock_namespace == SOCK_NS_FILESYSTEM) {
+ safe_strncpy(addr.sun_path, path, sizeof(addr.sun_path));
+ unlink(addr.sun_path);
+ } else {
+ SOCK_LOGE("mtk_socket_server_bind_local() unknown namespace=[%d]", sock_namespace);
+ close(fd);
+ return -1;
+ }
+ if (bind(fd, (struct sockaddr *)&addr, size) == -1) {
+ SOCK_LOGE("mtk_socket_server_bind_local() bind() failed reason=[%s]%d for path=[%s]",
+ strerror(errno), errno, path);
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+
+void mtk_socket_client_init_network(mtk_socket_fd* sock_fd, const char* host, int port) {
+ int len = strlen(host);
+ memset(sock_fd, 0, sizeof(*sock_fd));
+ sock_fd->fd = -1;
+ sock_fd->is_local = false;
+ pthread_mutex_init(&sock_fd->mutex, NULL);
+ sock_fd->host = malloc(len + 1);
+ safe_strncpy(sock_fd->host, host, len + 1);
+ sock_fd->port = port;
+}
+
+void mtk_socket_client_init_local(mtk_socket_fd* sock_fd, const char* path, mtk_socket_namespace sock_namespace) {
+ int len = strlen(path);
+ memset(sock_fd, 0, sizeof(*sock_fd));
+ sock_fd->fd = -1;
+ sock_fd->is_local = true;
+ pthread_mutex_init(&sock_fd->mutex, NULL);
+ sock_fd->path = malloc(len + 1);
+ safe_strncpy(sock_fd->path, path, len + 1);
+ sock_fd->namesapce = sock_namespace;
+}
+
+void mtk_socket_client_cleanup(mtk_socket_fd* sock_fd) {
+ mtk_socket_client_close(sock_fd);
+ if(sock_fd->host) {
+ free(sock_fd->host);
+ sock_fd->host = NULL;
+ }
+ if(sock_fd->path) {
+ free(sock_fd->path);
+ sock_fd->path = NULL;
+ }
+}
+
+// return -1 means fail
+int mtk_socket_tcp_connect_local(const char* path, mtk_socket_namespace sock_namespace) {
+ int size;
+ struct sockaddr_un addr;
+ int fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fd < 0) {
+ SOCK_LOGE("mtk_socket_tcp_connect_local() socket() failed reason=[%s]%d",
+ strerror(errno), errno);
+ return false;
+ }
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_LOCAL;
+ size = strlen(path) + offsetof(struct sockaddr_un, sun_path) + 1;
+ if(sock_namespace == SOCK_NS_ABSTRACT) {
+ addr.sun_path[0] = 0;
+ memcpy(addr.sun_path + 1, path, strlen(path));
+ } else if(sock_namespace == SOCK_NS_FILESYSTEM) {
+ safe_strncpy(addr.sun_path, path, sizeof(addr.sun_path));
+ } else {
+ SOCK_LOGE("mtk_socket_connect_local() unknown namespace=[%d]", sock_namespace);
+ close(fd);
+ return -1;
+ }
+ if (connect(fd, (struct sockaddr *)&addr, size) < 0) {
+ SOCK_LOGE("mtk_socket_connect_local() connect() failed reason=[%s]%d for path=[%s]",
+ strerror(errno), errno, path);
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+static bool mtk_socket_connect_local(mtk_socket_fd* sock_fd) {
+ int size;
+ struct sockaddr_un addr;
+ int fd = socket(AF_UNIX, SOCK_DGRAM, 0);
+ if (fd < 0) {
+ SOCK_LOGE("mtk_socket_connect_local() socket() failed reason=[%s]%d",
+ strerror(errno), errno);
+ return false;
+ }
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_LOCAL;
+ size = strlen(sock_fd->path) + offsetof(struct sockaddr_un, sun_path) + 1;
+ if(sock_fd->namesapce == SOCK_NS_ABSTRACT) {
+ addr.sun_path[0] = 0;
+ memcpy(addr.sun_path + 1, sock_fd->path, strlen(sock_fd->path));
+ } else if(sock_fd->namesapce == SOCK_NS_FILESYSTEM) {
+ safe_strncpy(addr.sun_path, sock_fd->path, sizeof(addr.sun_path));
+ } else {
+ SOCK_LOGE("mtk_socket_connect_local() unknown namespace=[%d]", sock_fd->namesapce);
+ close(fd);
+ return false;
+ }
+ if (connect(fd, (struct sockaddr *)&addr, size) < 0) {
+ SOCK_LOGE("mtk_socket_connect_local() connect() failed reason=[%s]%d for path=[%s]",
+ strerror(errno), errno, sock_fd->path);
+ close(fd);
+ return false;
+ }
+ sock_fd->fd = fd;
+ return true;
+}
+
+static int mtk_socket_connect_network_ipv4(struct sockaddr_in* addr) {
+ int port = ntohs(addr->sin_port);
+ char ip_str[64] = {0};
+ inet_ntop(AF_INET, &(addr->sin_addr), ip_str, sizeof(ip_str));
+ int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (fd < 0) {
+ SOCK_LOGE("mtk_socket_connect_network_ipv4() socket() failed reason=[%s]%d",
+ strerror(errno), errno);
+ return -1;
+ }
+ //SOCK_LOGD("mtk_socket_connect_network_ipv4() IPv4=[%s] port=[%d]", ip_str, port);
+ if (connect(fd, (struct sockaddr *)addr, sizeof(*addr)) < 0) {
+ SOCK_LOGE("mtk_socket_connect_network_ipv4() connect() failed reason=[%s]%d for host=[%s] port=[%d]",
+ strerror(errno), errno, ip_str, port);
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+//-1 means failure
+static int mtk_socket_connect_network_ipv6(struct sockaddr_in6* addr) {
+ int port = ntohs(addr->sin6_port);
+ int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ if (fd < 0) {
+ SOCK_LOGE("mtk_socket_connect_network_ipv6() socket() failed reason=[%s]%d",
+ strerror(errno), errno);
+ return -1;
+ }
+ //unsigned char* ipv6_addr = addr->sin6_addr.s6_addr;
+ //SOCK_LOGD("mtk_socket_connect_network_ipv6() IPv6=[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x] port=[%d]",
+ // ipv6_addr[0], ipv6_addr[1], ipv6_addr[2], ipv6_addr[3], ipv6_addr[4], ipv6_addr[5], ipv6_addr[6], ipv6_addr[7],
+ // ipv6_addr[8], ipv6_addr[9], ipv6_addr[10], ipv6_addr[11], ipv6_addr[12], ipv6_addr[13], ipv6_addr[14], ipv6_addr[15],
+ // port);
+ if (connect(fd, (struct sockaddr *)addr, sizeof(*addr)) < 0) {
+ SOCK_LOGE("mtk_socket_connect_network_ipv6() connect() failed reason=[%s]%d for port=[%d]",
+ strerror(errno), errno, port);
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+static bool mtk_socket_connect_network(mtk_socket_fd* sock_fd) {
+ struct addrinfo hints;
+ struct addrinfo *result;
+ struct addrinfo *rp;
+ int ret;
+ char port_str[11] = {0};
+ sprintf(port_str, "%u", sock_fd->port);
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC; // Allow IPv4 or IPv6, AF_UNSPEC, AF_INET, AF_INET6
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = AI_ADDRCONFIG; // check local system
+ hints.ai_protocol = IPPROTO_UDP;
+ ret = getaddrinfo(sock_fd->host, port_str, &hints, &result);
+ if(ret != 0) {
+ SOCK_LOGE("mtk_socket_connect_network() getaddrinfo() failure reason=[%s] %d\n",
+ gai_strerror(ret), ret);
+ return false;
+ }
+ for (rp = result; rp != NULL; rp = rp->ai_next) {
+ if(rp->ai_family == AF_INET) {
+ ret = mtk_socket_connect_network_ipv4((struct sockaddr_in*)rp->ai_addr);
+ if(ret >= 0) {
+ sock_fd->fd = ret;
+ break;
+ }
+ }
+ if(rp->ai_family == AF_INET6) {
+ ret = mtk_socket_connect_network_ipv6((struct sockaddr_in6*)rp->ai_addr);
+ if(ret >= 0) {
+ sock_fd->fd = ret;
+ break;
+ }
+ }
+ }
+ freeaddrinfo(result);
+ if(ret >= 0) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool mtk_socket_client_connect(mtk_socket_fd* sock_fd) {
+ if(sock_fd->is_local) {
+ return mtk_socket_connect_local(sock_fd);
+ } else {
+ return mtk_socket_connect_network(sock_fd);
+ }
+}
+
+void mtk_socket_client_close(mtk_socket_fd* sock_fd) {
+ if(sock_fd->fd >= 0) {
+ close(sock_fd->fd);
+ sock_fd->fd = -1;
+ }
+}
+
+//-1 means failure
+int mtk_socket_read(int fd, char* buff, int len) {
+ int n, retry = 10;
+ if(fd < 0 || buff == NULL || len < 0) {
+ SOCK_LOGE("mtk_socket_read() invalid params fd=[%d] buff=[%p] len=[%d]", fd, buff, len);
+ return -1;
+ }
+ if(len == 0) {
+ return 0;
+ }
+ while((n = read(fd, buff, len)) < 0) {
+ if(errno == EINTR) continue;
+ if(errno == EAGAIN) {
+ if(retry-- > 0) {
+ usleep(100 * 1000);
+ continue;
+ }
+ goto exit;
+ }
+ goto exit;
+ }
+ return n;
+exit:
+ SOCK_LOGE("mtk_socket_read() read() failed, fd=[%d] len=[%d] errno=[%s]%d",
+ fd, len, strerror(errno), errno);
+ return -1;
+}
+
+//-1 means failure
+int mtk_socket_write(int fd, void* buff, int len) {
+ int n, retry = 10;
+ if(fd < 0 || buff == NULL || len < 0) {
+ SOCK_LOGE("mtk_socket_write() invalid params fd=[%d] buff=[%p] len=[%d]", fd, buff, len);
+ return -1;
+ }
+ while((n = write(fd, buff, len)) != len) {
+ if(errno == EINTR) continue;
+ if(errno == EAGAIN) {
+ if(retry-- > 0) {
+ usleep(100 * 1000);
+ continue;
+ }
+ goto exit;
+ }
+ goto exit;
+ }
+ return n;
+exit:
+ SOCK_LOGE("mtk_socket_write() write() failed, fd=[%d] len=[%d] errno=[%s]%d\n",
+ fd, len, strerror(errno), errno);
+ return -1;
+}
+
+// <= 0 means no data received
+int mtk_socket_poll(int fd, int timeout) {
+ struct pollfd poll_fd[1];
+ int ret = 0;
+ memset(poll_fd, 0, sizeof(poll_fd));
+ poll_fd[0].fd = fd;
+ poll_fd[0].events = POLLIN;
+ poll_fd[0].revents = 0;
+
+ ret = poll(poll_fd, 1, timeout);
+ if(ret > 0) {
+ if(poll_fd[0].revents & POLLIN ||
+ poll_fd[0].revents & POLLERR) {
+ ret = 1 << 0;
+ }
+ }
+ return ret;
+}
+
+void mtk_socket_buff_dump(const char* buff, int len) {
+ int i = 0;
+ char tmp[512] = {0};
+ SOCK_LOGD("mtk_socket_buff_dump len=%d", len);
+ for(i = 0; i < len; i++) {
+ if((i % 16 == 0) && (i != 0)) {
+ SOCK_LOGD(" %s", tmp);
+ memset(tmp, 0, sizeof(tmp));
+ }
+ sprintf(tmp + ((i % 16) * 3), "%02x ", buff[i] & 0xff);
+ }
+ if(i > 0) {
+ SOCK_LOGD(" %s", tmp);
+ }
+}
+
+bool mtk_socket_string_is_equal(char* data1, char* data2) {
+ return (strcmp(data1, data2) == 0)? true : false;
+}
+
+bool mtk_socket_bool_array_is_equal(bool data1[], int data1_size, bool data2[], int data2_size) {
+ int i = 0;
+ if(data1_size != data2_size) {
+ return false;
+ }
+ for(i = 0; i < data1_size; i++) {
+ if(data1[i] != data2[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool mtk_socket_char_array_is_equal(char data1[], int data1_size, char data2[], int data2_size) {
+ int i = 0;
+ if(data1_size != data2_size) {
+ return false;
+ }
+ for(i = 0; i < data1_size; i++) {
+ if(data1[i] != data2[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool mtk_socket_short_array_is_equal(short data1[], int data1_size, short data2[], int data2_size) {
+ int i = 0;
+ if(data1_size != data2_size) {
+ return false;
+ }
+ for(i = 0; i < data1_size; i++) {
+ if(data1[i] != data2[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool mtk_socket_int_array_is_equal(int data1[], int data1_size, int data2[], int data2_size) {
+ int i = 0;
+ if(data1_size != data2_size) {
+ return false;
+ }
+ for(i = 0; i < data1_size; i++) {
+ if(data1[i] != data2[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool mtk_socket_int64_t_array_is_equal(int64_t data1[], int data1_size, int64_t data2[], int data2_size) {
+ int i = 0;
+ if(data1_size != data2_size) {
+ return false;
+ }
+ for(i = 0; i < data1_size; i++) {
+ if(data1[i] != data2[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool mtk_socket_float_array_is_equal(float data1[], int data1_size, float data2[], int data2_size) {
+ int i = 0;
+ if(data1_size != data2_size) {
+ return false;
+ }
+ for(i = 0; i < data1_size; i++) {
+ if(data1[i] != data2[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool mtk_socket_double_array_is_equal(double data1[], int data1_size, double data2[], int data2_size) {
+ int i = 0;
+ if(data1_size != data2_size) {
+ return false;
+ }
+ for(i = 0; i < data1_size; i++) {
+ if(data1[i] != data2[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool mtk_socket_string_array_is_equal(strings data1, int data1_size, strings data2, int data2_size, int string_size) {
+ int i = 0;
+ if(data1_size != data2_size) {
+ return false;
+ }
+ for(i = 0; i < data1_size; i++) {
+ if(!mtk_socket_string_is_equal(data1, data2)) {
+ return false;
+ }
+ data1 = (char*)data1 + string_size;
+ data2 = (char*)data2 + string_size;
+ }
+ return true;
+}
+
+void mtk_socket_bool_array_dump(bool input[], int size) {
+ int i = 0;
+ SOCK_LOGD("mtk_socket_bool_array_dump size=%d", size);
+ for(i = 0; i < size; i++) {
+ SOCK_LOGD(" i=[%d] data=[%d]", i, input[i]);
+ }
+}
+
+void mtk_socket_char_array_dump(char input[], int size) {
+ int i = 0;
+ SOCK_LOGD("mtk_socket_char_array_dump size=%d", size);
+ for(i = 0; i < size; i++) {
+ SOCK_LOGD(" i=[%d] data=[%d]", i, input[i] & 0xff);
+ }
+}
+
+void mtk_socket_short_array_dump(short input[], int size) {
+ int i = 0;
+ SOCK_LOGD("mtk_socket_short_array_dump size=%d", size);
+ for(i = 0; i < size; i++) {
+ SOCK_LOGD(" i=[%d] data=[%d]", i, input[i] & 0xffff);
+ }
+}
+
+void mtk_socket_int_array_dump(int input[], int size) {
+ int i = 0;
+ SOCK_LOGD("mtk_socket_int_array_dump size=%d", size);
+ for(i = 0; i < size; i++) {
+ SOCK_LOGD(" i=[%d] data=[%d]", i, input[i]);
+ }
+}
+
+void mtk_socket_int64_t_array_dump(int64_t input[], int size) {
+ int i = 0;
+ SOCK_LOGD("mtk_socket_int64_t_array_dump size=%d", size);
+ for(i = 0; i < size; i++) {
+ SOCK_LOGD(" i=[%d] data=[%lld]", i, (long long)input[i]);
+ }
+}
+
+void mtk_socket_float_array_dump(float input[], int size) {
+ int i = 0;
+ SOCK_LOGD("mtk_socket_float_array_dump size=%d", size);
+ for(i = 0; i < size; i++) {
+ SOCK_LOGD(" i=[%d] data=[%f]", i, input[i]);
+ }
+}
+
+void mtk_socket_double_array_dump(double input[], int size) {
+ int i = 0;
+ SOCK_LOGD("mtk_socket_double_array_dump size=%d", size);
+ for(i = 0; i < size; i++) {
+ SOCK_LOGD(" i=[%d] data=[%f]", i, input[i]);
+ }
+}
+
+void mtk_socket_string_array_dump(strings input, int size1, int size2) {
+ int i = 0;
+ SOCK_LOGD("mtk_socket_string_array_dump size1=%d size2=%d", size1, size2);
+ for(i = 0; i < size1; i++) {
+ SOCK_LOGD(" i=[%d] data=[%s]", i, (char*)input);
+ input = (char*)input + size2;
+ }
+}
+
+bool mtk_socket_expected_bool(char* buff, int* offset, bool expected_value, const char* func, int line) {
+ bool value = mtk_socket_get_bool(buff, offset);
+ if(value != expected_value) {
+ SOCK_LOGE("%s():%d mtk_socket_expected_bool() failed, read=[%d], expected=[%d]",
+ func, line, value, expected_value);
+ return false;
+ }
+ return true;
+}
+
+bool mtk_socket_expected_char(char* buff, int* offset, char expected_value, const char* func, int line) {
+ char value = mtk_socket_get_char(buff, offset);
+ if(value != expected_value) {
+ SOCK_LOGE("%s():%d mtk_socket_expected_char() failed, read=[%d], expected=[%d]",
+ func, line, value, expected_value);
+ return false;
+ }
+ return true;
+}
+
+bool mtk_socket_expected_short(char* buff, int* offset, short expected_value, const char* func, int line) {
+ short value = mtk_socket_get_short(buff, offset);
+ if(value != expected_value) {
+ SOCK_LOGE("%s():%d mtk_socket_expected_short() failed, read=[%d], expected=[%d]",
+ func, line, value, expected_value);
+ return false;
+ }
+ return true;
+}
+
+bool mtk_socket_expected_int(char* buff, int* offset, int expected_value, const char* func, int line) {
+ int value = mtk_socket_get_int(buff, offset);
+ if(value != expected_value) {
+ SOCK_LOGE("%s():%d mtk_socket_expected_int() failed, read=[%d], expected=[%d]",
+ func, line, value, expected_value);
+ return false;
+ }
+ return true;
+}
+
+bool mtk_socket_expected_int64_t(char* buff, int* offset, int64_t expected_value, const char* func, int line) {
+ int64_t value = mtk_socket_get_int64_t(buff, offset);
+ if(value != expected_value) {
+ SOCK_LOGE("%s():%d mtk_socket_expected_int64_t() failed, read=[%lld], expected=[%lld]",
+ func, line, value, expected_value);
+ return false;
+ }
+ return true;
+}
+
+bool mtk_socket_expected_float(char* buff, int* offset, float expected_value, const char* func, int line) {
+ float value = mtk_socket_get_float(buff, offset);
+ if(value != expected_value) {
+ SOCK_LOGE("%s():%d mtk_socket_expected_float() failed, read=[%f], expected=[%f]",
+ func, line, value, expected_value);
+ return false;
+ }
+ return true;
+}
+
+bool mtk_socket_expected_double(char* buff, int* offset, double expected_value, const char* func, int line) {
+ double value = mtk_socket_get_double(buff, offset);
+ if(value != expected_value) {
+ SOCK_LOGE("%s():%d mtk_socket_expected_double() failed, read=[%f], expected=[%f]",
+ func, line, value, expected_value);
+ return false;
+ }
+ return true;
+}
+
+bool mtk_socket_expected_string(char* buff, int* offset, const char* expected_value, int max_size, const char* func, int line) {
+ char value[max_size];
+ mtk_socket_get_string(buff, offset, value, sizeof(value));
+ if(strcmp(value, expected_value) != 0) {
+ SOCK_LOGE("%s():%d mtk_socket_expected_string() failed, read=[%s], expected=[%s]",
+ func, line, value, expected_value);
+ return false;
+ }
+ return true;
+}
+
+char *safe_strncpy(char *dest, const char *src, size_t n) {
+ if (dest && n > 0) {
+ // Use strncat for performance because strncpy will always fill n bytes in dest
+ dest[0] = '\0'; // Let dest be an empty string
+ strncat(dest, src, --n); // n-1 because strncat may fill n+1 bytes
+ }
+ return dest;
+}
+
diff --git a/src/connectivity/gps/lbs_hidl_service/service.cpp b/src/connectivity/gps/lbs_hidl_service/service.cpp
new file mode 100644
index 0000000..0b2daea
--- /dev/null
+++ b/src/connectivity/gps/lbs_hidl_service/service.cpp
@@ -0,0 +1,12 @@
+#define LOG_TAG "lbs_hidl_service"
+
+#include <lbs_hidl_service.h>
+#include <hidl/LegacySupport.h>
+
+int main() {
+ ::vendor::mediatek::hardware::lbs::V1_0::implementation::cpp_main();
+ ::android::hardware::joinRpcThreadpool();
+
+ return 0;
+}
+