Fix gnss 8122 and IPC socket.
Change-Id: Id413efb4dd8df3e5a52333cc0c1400db7f84ad9f
diff --git a/mbtk/mbtk_gnssd/Makefile b/mbtk/mbtk_gnssd/Makefile
index 70ac7ef..0cefa40 100755
--- a/mbtk/mbtk_gnssd/Makefile
+++ b/mbtk/mbtk_gnssd/Makefile
@@ -24,7 +24,7 @@
#MY_FILES_PATH += $(LOCAL_PATH)/platform/linux
#endif
#LOCAL_SRC_FILES = $(wildcard *.c) $(wildcard *.cpp)
-LOCAL_SRC_FILES = gnss_main.c gnss_nmea.c gnss_6228.c gnss_ubus.c gnss_utils.c gnss_hd8122.c
+LOCAL_SRC_FILES = gnss_main.c gnss_nmea.c gnss_6228.c gnss_ipc.c gnss_utils.c gnss_hd8122.c
OBJS = $(patsubst %.c, %.o, $(patsubst %.cpp, %.o, $(LOCAL_SRC_FILES)))
$(info OBJS = $(OBJS))
diff --git a/mbtk/mbtk_gnssd/gnss_hd8122.c b/mbtk/mbtk_gnssd/gnss_hd8122.c
index dc36267..57b2e30 100755
--- a/mbtk/mbtk_gnssd/gnss_hd8122.c
+++ b/mbtk/mbtk_gnssd/gnss_hd8122.c
@@ -27,10 +27,91 @@
#define UART_BITRATE_NMEA_DEF_FW 115200 // Default bitrate.
#define GNSS_POWER_GPIO 43
+#define GNSS_SET_TIMEOUT 3000 // 3s
+#define GNSS_PACK_BUFF_SIZE 1024
+
static pthread_cond_t read_cond;
static pthread_mutex_t read_mutex;
+static bool setting_busy = FALSE;
+static void *gnss_set_rsp_ptr = NULL;
+static gnss_err_enum gnss_set_result = GNSS_ERR_OK;
+int gnss_write(int fd, const void *data, int data_len);
+
+static uint16 fletcher16(const uint8_t* data, int data_len) {
+ uint16_t sum1 = 0;
+ uint16_t sum2 = 0;
+ int index;
+
+ for (index = 0; index < data_len; ++index ) {
+ sum1 = (sum1 + data[index]) % 0xff;
+ sum2 = (sum2 + sum1) % 0xff;
+ }
+
+ // ???
+ sum2--;
+
+ return (sum2 << 8) | sum1;
+}
+
+static void gnss_set_timer_cb(int signo)
+{
+ if(setting_busy) {
+ pthread_mutex_lock(&read_mutex);
+ pthread_cond_signal(&read_cond);
+ pthread_mutex_unlock(&read_mutex);
+ gnss_set_result = GNSS_ERR_TIMEOUT;
+ }
+ return;
+}
+
+
+static int pack_create(hd8122_id_type_enum id_type, uint8 id, uint16 data_len, const uint8 *data, uint8 *pack, int pack_len)
+{
+ if(pack == NULL || pack_len < HD8122_PACK_LEN_MIN) {
+ return -1;
+ }
+ memset(pack, 0, pack_len);
+ uint8 *data_ptr = pack;
+ data_ptr += uint16_2_byte(HD8122_PACK_HEAD, data_ptr, false);
+ *data_ptr++ = (uint8)id_type;
+ *data_ptr++ = id;
+ data_ptr += uint16_2_byte(data_len, data_ptr, false);
+ if(data_len > 0) {
+ memcpy(data_ptr, data, data_len);
+ data_ptr += data_len;
+ }
+ data_ptr += uint16_2_byte(fletcher16(pack + 2, 4 + data_len), data_ptr, false);
+ return (data_ptr - pack);
+}
+
+static void gnss_cmd_rsp_process(const void *data, int data_len) {
+ const char *ptr = (const char*)data;
+ log_hex("RSP", data, data_len);
+ if(0)
+ {
+ mbtk_timer_clear();
+
+ pthread_mutex_lock(&read_mutex);
+ pthread_cond_signal(&read_cond);
+ pthread_mutex_unlock(&read_mutex);
+ }
+}
+
+static gnss_err_enum gnss_8122_reset(int fd, int reset)
+{
+ uint8 buff[GNSS_PACK_BUFF_SIZE];
+ LOGD("RESET");
+ int len = pack_create(HD8122_ID_TYPE_CFG, HD8122_ID_CFG_SIMPLERST, 1, (uint8*)(&reset), buff, sizeof(buff));
+ if(len <= 0) {
+ LOGE("pack_create() fail.");
+ return GNSS_ERR_ARG;
+ }
+ log_hex("PACK", buff, len);
+ gnss_write(fd, buff, len);
+ return GNSS_ERR_OK;
+}
int gnss_8122_dev_open()
{
@@ -61,9 +142,55 @@
return 0;
}
+void gnss_8122_set_cb(const void *data, int data_len)
+{
+ const char *buff = (const char*)data;
+ if(setting_busy) {
+ gnss_cmd_rsp_process(data, data_len);
+ }
+}
gnss_err_enum gnss_8122_set(int fd, const char *cmd, void *cmd_rsp, int cmd_rsp_len)
{
- return GNSS_ERR_OK;
+ if(setting_busy) {
+ return GNSS_ERR_SET_BUSY;
+ } else {
+ bool should_wait_rsp = TRUE;
+ setting_busy = TRUE;
+ gnss_set_rsp_ptr = cmd_rsp;
+ gnss_set_result = GNSS_ERR_OK;
+ mbtk_timer_set(gnss_set_timer_cb, GNSS_SET_TIMEOUT);
+
+ if(memcmp(cmd, "reset", 5) == 0) {
+ gnss_set_result = gnss_8122_reset(fd, atoi(cmd + 6));
+ if(gnss_set_result != GNSS_ERR_OK) {
+ goto set_fail;
+ }
+ should_wait_rsp = FALSE;
+ }
+ else
+ {
+ LOGW("Unknown cmd:%s", cmd);
+ gnss_set_result = GNSS_ERR_UNSUPPORT;
+ goto set_fail;
+ }
+
+set_success:
+ if(should_wait_rsp) {
+ pthread_mutex_lock(&read_mutex);
+ pthread_cond_wait(&read_cond, &read_mutex);
+ pthread_mutex_unlock(&read_mutex);
+ } else {
+ mbtk_timer_clear();
+ }
+
+ setting_busy = FALSE;
+ return gnss_set_result;
+set_fail:
+ setting_busy = FALSE;
+ mbtk_timer_clear();
+ return gnss_set_result;
+ }
}
+
diff --git a/mbtk/mbtk_gnssd/gnss_hd8122.h b/mbtk/mbtk_gnssd/gnss_hd8122.h
index ca938f3..fb9c1b8 100755
--- a/mbtk/mbtk_gnssd/gnss_hd8122.h
+++ b/mbtk/mbtk_gnssd/gnss_hd8122.h
@@ -11,6 +11,96 @@
#include "gnss_info.h"
#include "mbtk_type.h"
+#define HD8122_PACK_LEN_MIN 8
+#define HD8122_PACK_HEAD 0xD9F1
+
+typedef enum {
+ HD8122_ID_TYPE_NAV = 0x01,
+ HD8122_ID_TYPE_ACK = 0x05,
+ HD8122_ID_TYPE_CFG = 0x06,
+ HD8122_ID_TYPE_MON = 0x0A,
+ HD8122_ID_TYPE_AID = 0x0B
+} hd8122_id_type_enum;
+
+typedef enum {
+ HD8122_ID_NAV_POSECEF = 0x01,
+ HD8122_ID_NAV_POSLLH = 0x02,
+ HD8122_ID_NAV_DOP = 0x04,
+ HD8122_ID_NAV_TIME = 0x05,
+ HD8122_ID_NAV_VELECEF = 0x11,
+ HD8122_ID_NAV_VELNED = 0x12,
+ HD8122_ID_NAV_TIMEUTC = 0x21,
+ HD8122_ID_NAV_CLOCK = 0x22,
+ HD8122_ID_NAV_CLOCK2 = 0x23,
+ HD8122_ID_NAV_PVERR = 0x26,
+ HD8122_ID_NAV_SVINFO = 0x30,
+ HD8122_ID_NAV_SVSTATE = 0x32,
+ HD8122_ID_NAV_AUTO = 0xC0,
+ HD8122_ID_NAV_PVT = 0xC1
+} hd8122_id_nav_enum;
+
+typedef enum {
+ HD8122_ID_ACK_NAK = 0x00,
+ HD8122_ID_ACK_ACK = 0x01
+} hd8122_id_ack_enum;
+
+typedef enum {
+ HD8122_ID_CFG_PRT = 0x00,
+ HD8122_ID_CFG_MSG = 0x01,
+ HD8122_ID_CFG_PPS = 0x07,
+ HD8122_ID_CFG_CFG = 0x09,
+ HD8122_ID_CFG_DOP = 0x0A,
+ HD8122_ID_CFG_ELEV = 0x0B,
+ HD8122_ID_CFG_NAVSAT = 0x0C,
+ HD8122_ID_CFG_HEIGHT = 0x0D,
+ HD8122_ID_CFG_SBAS = 0x0E,
+ HD8122_ID_CFG_SPDHOLD = 0x0F,
+ HD8122_ID_CFG_EPHSAVE = 0x10,
+ HD8122_ID_CFG_NUMSV = 0x11,
+ HD8122_ID_CFG_SURVEY = 0x12,
+ HD8122_ID_CFG_FIXEDLLA = 0x13,
+ HD8122_ID_CFG_FIXEDECEF = 0x14,
+ HD8122_ID_CFG_ANTIJAM = 0x15,
+ HD8122_ID_CFG_BDGEO = 0x16,
+ HD8122_ID_CFG_CARRSMOOTH = 0x17,
+ HD8122_ID_CFG_GEOFENCE = 0x18,
+ HD8122_ID_CFG_SIMPLERST = 0x40,
+ HD8122_ID_CFG_SLEEP = 0x41,
+ HD8122_ID_CFG_PWRCTL = 0x42,
+ HD8122_ID_CFG_PWRCTL2 = 0x44,
+ HD8122_ID_CFG_NMEAVER = 0x43,
+ HD8122_ID_CFG_FWUP = 0x50
+} hd8122_id_cfg_enum;
+
+typedef enum {
+ HD8122_ID_MON_VER = 0x04,
+ HD8122_ID_MON_INFO = 0x05,
+ HD8122_ID_MON_TRKCHAN = 0x08,
+ HD8122_ID_MON_RCVCLK = 0x09,
+ HD8122_ID_MON_CWI = 0x0A,
+} hd8122_id_mon_enum;
+
+typedef enum {
+ HD8122_ID_AID_INI = 0x01,
+ HD8122_ID_AID_POS = 0x10,
+ HD8122_ID_AID_TIME = 0x11,
+ HD8122_ID_AID_PEPH_GPS = 0x32,
+ HD8122_ID_AID_PEPH_BDS = 0x33,
+ HD8122_ID_AID_PALM_GPS = 0x22,
+ HD8122_ID_AID_PALM_BD = 0x23,
+ HD8122_ID_AID_PALM_GLN = 0x24,
+ HD8122_ID_AID_PALM_GAL = 0x25,
+ HD8122_ID_AID_PALM_QZSS = 0x26
+} hd8122_id_aid_enum;
+
+typedef struct {
+ uint16 head;
+ uint8 id_type;
+ uint8 id;
+ uint16 data_len;
+ uint8 *data;
+} hd8122_pack_info_t;
+
int gnss_8122_dev_open();
int gnss_8122_dev_close();
@@ -25,7 +115,7 @@
gnss_err_enum gnss_8122_set(int fd, const char *cmd, void *cmd_rsp, int cmd_rsp_len);
-//void gnss_8122_set_cb(const void *data, int data_len);
+void gnss_8122_set_cb(const void *data, int data_len);
#endif /* _GNSS_HD8122_H */
diff --git a/mbtk/mbtk_gnssd/gnss_info.h b/mbtk/mbtk_gnssd/gnss_info.h
index a292db7..a6b64c9 100755
--- a/mbtk/mbtk_gnssd/gnss_info.h
+++ b/mbtk/mbtk_gnssd/gnss_info.h
@@ -25,6 +25,7 @@
GNSS_ERR_TIMEOUT,
GNSS_ERR_ARG,
GNSS_ERR_CHECKSUM,
+ GNSS_ERR_SET_BUSY,
GNSS_ERR_UNKNOWN
} gnss_err_enum;
@@ -74,4 +75,10 @@
gnss_set_cb_func gnss_set_cb;
} gnss_info_t;
+int gnss_init(uint32 print_port);
+
+int gnss_deinit();
+
+int gnss_set(const void* buf, unsigned int buf_len, void *cmd_rsp, int cmd_rsp_len);
+
#endif /* _GNSS_INFO_H */
diff --git a/mbtk/mbtk_gnssd/gnss_ipc.c b/mbtk/mbtk_gnssd/gnss_ipc.c
new file mode 100755
index 0000000..a8dece8
--- /dev/null
+++ b/mbtk/mbtk_gnssd/gnss_ipc.c
@@ -0,0 +1,276 @@
+/*
+* gnss_ipc.c
+*
+* MBTK GNSS IPC service source.
+*
+*/
+/******************************************************************************
+
+ EDIT HISTORY FOR FILE
+
+ WHEN WHO WHAT,WHERE,WHY
+-------- -------- -------------------------------------------------------
+2024/6/15 LiuBin Initial version
+
+******************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <sys/epoll.h>
+
+#include "mbtk_log.h"
+#include "mbtk_type.h"
+#include "gnss_info.h"
+
+#define GNSS_SOCK_PATH "/tmp/mbtk_gnss_sock"
+#define SOCK_CLIENT_MAX 3
+#define EPOLL_LISTEN_MAX 100
+
+static int sock_listen_fd = -1;
+static int sock_cli_fds[SOCK_CLIENT_MAX];
+
+int gnss_write(int fd, const void* buf, unsigned int buf_len);
+
+static int gnss_cli_fd_find(int fd)
+{
+ int i = 0;
+ while(i < SOCK_CLIENT_MAX) {
+ if(fd == sock_cli_fds[i])
+ return i;
+ i++;
+ }
+
+ return -1;
+}
+
+static void gnss_msg_process(int fd, const char *msg, int msg_len)
+{
+ // gnss_init:x
+ if(memcmp(msg, "gnss_init", 9) == 0) {
+ int init_mode = atoi(msg + 10);
+ LOGD("init_mode=%d", init_mode);
+ int ret = 0;
+ if(init_mode == 0) { // Close gnss.
+ ret = gnss_deinit();
+ } else {
+ if(((GNSS_PRINT_PORT_UART1 | GNSS_PRINT_PORT_USB_NMEA | GNSS_PRINT_PORT_USB_AT | GNSS_PRINT_PORT_TTY_AT) & init_mode) == init_mode) {
+ ret = gnss_init(init_mode);
+ } else { // ARG error, no print nmea.
+ ret = gnss_init(0);
+ }
+ }
+
+ char rsp[100] = {0};
+ sprintf(rsp, "gnss_init:%d", ret);
+ gnss_write(fd, rsp, strlen(rsp));
+ } else if(memcmp(msg, "gnss_deinit", 11) == 0) {
+ LOGD("gnss_deinit");
+ int ret = gnss_deinit();
+
+ char rsp[100] = {0};
+ sprintf(rsp, "gnss_deinit:%d", ret);
+ gnss_write(fd, rsp, strlen(rsp));
+ } else {
+ LOGW("Unknown gnss msg : %s", msg);
+ }
+}
+
+static void* gnss_ser_pthread(void* arg)
+{
+ UNUSED(arg);
+ int epoll_fd = epoll_create(SOCK_CLIENT_MAX + 1);
+ if(epoll_fd < 0)
+ {
+ LOGE("epoll_create() fail[%d].", errno);
+ return NULL;
+ }
+
+ int i = 0;
+ while(i < SOCK_CLIENT_MAX) {
+ sock_cli_fds[i++] = -1;
+ }
+
+ uint32 event = EPOLLIN | EPOLLET;
+ struct epoll_event ev;
+ ev.data.fd = sock_listen_fd;
+ ev.events = event; //EPOLLIN | EPOLLERR | EPOLLET;
+ epoll_ctl(epoll_fd, EPOLL_CTL_ADD, sock_listen_fd, &ev);
+
+ int nready = -1;
+ struct epoll_event epoll_events[EPOLL_LISTEN_MAX];
+ while(1)
+ {
+ nready = epoll_wait(epoll_fd, epoll_events, EPOLL_LISTEN_MAX, -1);
+ if(nready > 0)
+ {
+ for(i = 0; i < nready; i++)
+ {
+ LOGD("fd[%d] event = %x",epoll_events[i].data.fd, epoll_events[i].events);
+ if(epoll_events[i].events & EPOLLHUP) // Client Close.
+ {
+ int index = gnss_cli_fd_find(epoll_events[i].data.fd);
+ if(index != -1)
+ {
+ memset(&ev,0,sizeof(struct epoll_event));
+ ev.data.fd = epoll_events[i].data.fd;
+ ev.events = EPOLLIN | EPOLLERR | EPOLLET;
+ epoll_ctl(epoll_fd, EPOLL_CTL_DEL, epoll_events[i].data.fd, &ev);
+
+ close(epoll_events[i].data.fd);
+ sock_cli_fds[index] = -1;
+ }
+ else
+ {
+ LOGE("Unknown client[fd = %d].", epoll_events[i].data.fd);
+ }
+ }
+ else if(epoll_events[i].events & EPOLLIN)
+ {
+ if(epoll_events[i].data.fd == sock_listen_fd) // New clients connected.
+ {
+ int client_fd = -1;
+ while(1)
+ {
+ struct sockaddr_in cliaddr;
+ socklen_t clilen = sizeof(cliaddr);
+ client_fd = accept(epoll_events[i].data.fd, (struct sockaddr *) &cliaddr, &clilen);
+ if(client_fd <= 0)
+ {
+ if(errno == EAGAIN)
+ {
+ LOGE("All client connect get.");
+ }
+ else
+ {
+ LOGE("accept() error[%d].", errno);
+ }
+ break;
+ } else {
+ i = 0;
+ while(i < SOCK_CLIENT_MAX) {
+ if(sock_cli_fds[i] <= 0) {
+ sock_cli_fds[i] = client_fd;
+ break;
+ }
+ i++;
+ }
+
+ if(i >= SOCK_CLIENT_MAX) {
+ LOGE("Client is full.");
+ break;
+ }
+ }
+ // Set O_NONBLOCK
+ int flags = fcntl(client_fd, F_GETFL, 0);
+ if (flags > 0)
+ {
+ flags |= O_NONBLOCK;
+ if (fcntl(client_fd, F_SETFL, flags) < 0)
+ {
+ LOGE("Set flags error:%d", errno);
+ }
+ }
+
+ memset(&ev,0,sizeof(struct epoll_event));
+ ev.data.fd = client_fd;
+ ev.events = event;//EPOLLIN | EPOLLERR | EPOLLET;
+ epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &ev);
+ }
+ }
+ else if(epoll_events[i].data.fd > 0) // Client data arrive.
+ {
+ char buff[1024] = {0};
+ int len = read(epoll_events[i].data.fd, buff, sizeof(buff));
+ if(len > 0) {
+ gnss_msg_process(epoll_events[i].data.fd, buff, len);
+ }
+ }
+ else
+ {
+ LOGE("Unknown socket : %d", epoll_events[i].data.fd);
+ }
+ }
+ else
+ {
+ LOGE("Unknown event : %x", epoll_events[i].events);
+ }
+ }
+ }
+ else
+ {
+ LOGE("epoll_wait() fail[%d].", errno);
+ }
+ }
+
+ return NULL;
+}
+
+
+int gnss_ipc_service_start()
+{
+ struct sockaddr_un server_addr;
+ sock_listen_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+ if(sock_listen_fd < 0)
+ {
+ LOGE("socket() fail[%d].", errno);
+ return -1;
+ }
+
+ // Set O_NONBLOCK
+ int flags = fcntl(sock_listen_fd, F_GETFL, 0);
+ if (flags < 0)
+ {
+ LOGE("Get flags error:%d", errno);
+ goto error;
+ }
+ flags |= O_NONBLOCK;
+ if (fcntl(sock_listen_fd, F_SETFL, flags) < 0)
+ {
+ LOGE("Set flags error:%d", errno);
+ goto error;
+ }
+
+ unlink(GNSS_SOCK_PATH);
+ memset(&server_addr, 0, sizeof(struct sockaddr_un));
+ server_addr.sun_family = AF_LOCAL;
+ strcpy(server_addr.sun_path, GNSS_SOCK_PATH);
+ if(bind(sock_listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)))
+ {
+ LOGE("bind() fail[%d].", errno);
+ goto error;
+ }
+
+ if(listen(sock_listen_fd, SOCK_CLIENT_MAX))
+ {
+ LOGE("listen() fail[%d].", errno);
+ goto error;
+ }
+
+ pthread_t pid;
+ pthread_attr_t thread_attr;
+ pthread_attr_init(&thread_attr);
+ if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
+ {
+ LOGE("pthread_attr_setdetachstate() fail.");
+ goto error;
+ }
+
+ if(pthread_create(&pid, &thread_attr, gnss_ser_pthread, NULL))
+ {
+ LOGE("pthread_create() fail.");
+ goto error;
+ }
+
+ LOGD("GNSS IPC service is running...");
+ return 0;
+error:
+ close(sock_listen_fd);
+ return -1;
+}
+
diff --git a/mbtk/mbtk_gnssd/gnss_main.c b/mbtk/mbtk_gnssd/gnss_main.c
index 3922f8f..b3ab5c6 100755
--- a/mbtk/mbtk_gnssd/gnss_main.c
+++ b/mbtk/mbtk_gnssd/gnss_main.c
@@ -17,6 +17,7 @@
#include "gnss_hd8122.h"
#define GNSS_DEBUG 1
+#define GNSS_UBUS_ENABLE 0
#define GNSS_TAG "MBTK_GNSS"
#define GNSS_BUFF_SIZE 2048
@@ -36,7 +37,12 @@
gnss_info_t gnss_info;
+#if GNSS_UBUS_ENABLE
struct ubus_context *gnss_ubus_init(void);
+#else
+int gnss_ipc_service_start();
+#endif
+
int gnss_init_config(int fd);
static char gnss_buff[GNSS_BUFF_SIZE*2] = {0};
@@ -742,7 +748,7 @@
gnss_info.gnss_fw_dl = gnss_8122_fw_dl;
gnss_info.gnss_dl_read_cb = NULL;
gnss_info.gnss_set = gnss_8122_set;
- gnss_info.gnss_set_cb = NULL;
+ gnss_info.gnss_set_cb = gnss_8122_set_cb;
} else {
LOGE("No support : %s", argv[1]);
return -1;
@@ -758,12 +764,23 @@
}
// Init ubus and waitting IPC commands.
+#if GNSS_UBUS_ENABLE
if(gnss_ubus_init()) {
LOGD("main() run...");
uloop_run();
} else {
LOGE("gnss_ubus_init() fail.");
}
+#else
+ if(!gnss_ipc_service_start()) {
+ LOGD("main() run...");
+ while(1) {
+ sleep(24 * 60 * 60);
+ }
+ } else {
+ LOGE("gnss_ipc_service_start() fail.");
+ }
+#endif
LOGD("main() exit.");
return 0;
diff --git a/mbtk/mbtk_gnssd/gnss_ubus.c b/mbtk/mbtk_gnssd/gnss_ubus.c
index 30de33a..ff877a1 100755
--- a/mbtk/mbtk_gnssd/gnss_ubus.c
+++ b/mbtk/mbtk_gnssd/gnss_ubus.c
@@ -14,10 +14,6 @@
//static struct blob_buf b;
static struct blob_buf gps_blob;
-int gnss_init(uint32 print_port);
-int gnss_deinit();
-int gnss_set(const void* buf, unsigned int buf_len, void *cmd_rsp, int cmd_rsp_len);
-
const struct blobmsg_policy gnss_init_policy[] ={
[0] = {
.name = "gnss_init_param",
diff --git a/mbtk/test/others/mbtk_gnss_cli.c b/mbtk/test/others/mbtk_gnss_cli.c
new file mode 100755
index 0000000..d830e0c
--- /dev/null
+++ b/mbtk/test/others/mbtk_gnss_cli.c
@@ -0,0 +1,140 @@
+/*
+* gnss_ipc.c
+*
+* MBTK GNSS IPC service source.
+*
+*/
+/******************************************************************************
+
+ EDIT HISTORY FOR FILE
+
+ WHEN WHO WHAT,WHERE,WHY
+-------- -------- -------------------------------------------------------
+2024/6/15 LiuBin Initial version
+
+******************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <sys/epoll.h>
+
+#include "mbtk_log.h"
+#include "mbtk_type.h"
+
+#define GNSS_SOCK_PATH "/tmp/mbtk_gnss_sock"
+
+static int sock_listen_fd = -1;
+
+typedef enum {
+ GNSS_CMD_INIT = 0,
+ GNSS_CMD_DEINIT
+} gnss_cmd_enum;
+
+static void help()
+{
+ printf("gnss_cli gnss_init xxx\n");
+ printf("gnss_cli gnss_deinit\n");
+}
+
+static int cmd_process(gnss_cmd_enum cmd, void *arg)
+{
+ if(sock_listen_fd < 0) {
+ sock_listen_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+ if(sock_listen_fd < 0)
+ {
+ printf("socket() fail[%d].\n", errno);
+ return -1;
+ }
+
+ struct sockaddr_un cli_addr;
+ memset(&cli_addr, 0, sizeof(cli_addr));
+ cli_addr.sun_family = AF_LOCAL;
+ strcpy(cli_addr.sun_path, GNSS_SOCK_PATH);
+ if(connect(sock_listen_fd, (struct sockaddr *)&cli_addr, sizeof(cli_addr)))
+ {
+ printf("connect() fail[%d].\n", errno);
+ close(sock_listen_fd);
+ sock_listen_fd = -1;
+ return -1;
+ }
+ }
+
+ char buff[100] = {0};
+ if(cmd == GNSS_CMD_INIT) {
+ if(arg) {
+ int type = atoi((char*)arg);
+ sprintf(buff, "gnss_init:%d", type);
+ } else {
+ return -1;
+ }
+ } else if(cmd == GNSS_CMD_DEINIT) {
+ sprintf(buff, "gnss_deinit");
+ } else {
+ printf("Unknown cmd.\n");
+ return -1;
+ }
+
+ write(sock_listen_fd, buff, strlen(buff));
+
+ int len = 0;
+ while(1) {
+ memset(buff, 0, sizeof(buff));
+ len = read(sock_listen_fd, buff, sizeof(buff));
+ if(len > 0) {
+ printf("RSP : %s\n", buff);
+ if(cmd == GNSS_CMD_INIT) {
+ if(memcmp(buff, "gnss_init", 9) == 0) {
+ return atoi(buff + 10);
+ } else {
+ printf("gnss_init response error.\n");
+ return -1;
+ }
+ } else if(cmd == GNSS_CMD_DEINIT) {
+ if(memcmp(buff, "gnss_deinit", 11) == 0) {
+ return atoi(buff + 12);
+ } else {
+ printf("gnss_deinit response error.\n");
+ return -1;
+ }
+ } else {
+ printf("Unknown response.\n");
+ return -1;
+ }
+ } else {
+ printf("read = %d:errno = %d\n", len, errno);
+ }
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ int ret = 0;
+ if(argc == 2) {
+ if(strcmp(argv[1], "gnss_deinit")) {
+ help();
+ return -1;
+ }
+
+ ret = cmd_process(GNSS_CMD_DEINIT, NULL);
+ } else if(argc == 3) {
+ if(strcmp(argv[1], "gnss_init")) {
+ help();
+ return -1;
+ }
+
+ ret = cmd_process(GNSS_CMD_INIT, argv[2]);
+ } else {
+ help();
+ return -1;
+ }
+
+ printf("Result : %d\n", ret);
+ return 0;
+}
+