[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;
+}
+