| #include <stdio.h> /* Standard input/output definitions */ | |
| #include <stdbool.h> /* Standard bool true/false definitions */ | |
| #include <string.h> /* String function definitions */ | |
| #include <unistd.h> /* UNIX standard function definitions */ | |
| #include <fcntl.h> /* File control definitions */ | |
| #include <errno.h> /* Error number definitions */ | |
| #include <termios.h> /* POSIX terminal control definitions */ | |
| #include <time.h> | |
| #include <pthread.h> | |
| #include <stdlib.h> | |
| #include <signal.h> | |
| #include <netdb.h> | |
| #include <sys/types.h> | |
| #include <sys/wait.h> | |
| #include <sys/socket.h> | |
| #include <sys/epoll.h> | |
| #include <netinet/in.h> | |
| #include <arpa/inet.h> | |
| #include <strings.h> | |
| #include <semaphore.h> | |
| #include "gpslog_log.h" | |
| #include "gpslog_utility.h" | |
| #include "gpslog_socket_utils.h" | |
| #include "gpslog_socket_data_coder.h" | |
| #define GPSLOG_UDP_ADDR "mtk_lbs_log_v2s" | |
| #define PRINT_TITLE(...) { printf("\E[0;30;43m"); printf(__VA_ARGS__); printf("\E[0m"); fflush(stdout); } | |
| #define PRINT_RAW(...) { printf(__VA_ARGS__); fflush(stdout);} | |
| #define GPSLOG_INTERFACE_BUFF_SIZE (80*1024) | |
| #define GPSLOG_PATH_SIZE (256) | |
| typedef enum { | |
| GPSLOG_OPEN_LOG = 0, | |
| GPSLOG_CLOSE_LOG = 1, | |
| GPSLOG_WRITE_LOG = 2, | |
| } gpslog_msg_id; | |
| typedef struct { | |
| char* sock_addr; | |
| }log_db; | |
| log_db gpslog_db; | |
| typedef struct { | |
| bool (*create_logfile)(const char* path); | |
| bool (*write_logdata)(char* data, int len); | |
| bool (*close_logfile)(); | |
| } gpslog_inf; | |
| static bool gpslog_handle_open_logfile(const char* file_name) { | |
| time_t tm; | |
| struct tm *p = NULL; | |
| char full_file_name[256] = {0}; | |
| if (time(&tm)==((time_t)-1)) { | |
| LOGE("time() fail(%s)!!\r\n", strerror(errno)); | |
| } | |
| p = localtime(&tm); | |
| if(p == NULL) { | |
| LOGE("Get localtime fail:[%s]%d", strerror(errno), errno); | |
| return false; | |
| } | |
| snprintf(full_file_name, sizeof(full_file_name), "%s_%04d_%02d%02d_%02d%02d%02d", file_name, | |
| 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday, | |
| p->tm_hour, p->tm_min, p->tm_sec); | |
| PRINT_RAW("\r\n==============GPSLog start, %s=============\r\n", full_file_name); | |
| return true; | |
| } | |
| static bool gpslog_handle_write_logdata(char* data, int len) { | |
| //PRINT_RAW("%s", data); | |
| if(write(STDOUT_FILENO, data, len) != len) { | |
| LOGW("STDOUT print fail:[le:%d][%s]", len, data); | |
| return false; | |
| } | |
| return true; | |
| } | |
| static bool gpslog_handle_close_logfile() { | |
| PRINT_RAW("\r\n==============GPSLog end=============\r\n"); | |
| return true; | |
| } | |
| static gpslog_inf gpslog_handler_interface = { | |
| gpslog_handle_open_logfile, | |
| gpslog_handle_write_logdata, | |
| gpslog_handle_close_logfile | |
| }; | |
| char gpslog_buff[GPSLOG_INTERFACE_BUFF_SIZE] = {0}; | |
| static bool gpslog_hdlr(int fd, log_db* database, gpslog_inf* hdlr) { | |
| int offset = 0; | |
| gpslog_msg_id cmd; | |
| int ptype; | |
| int log_type; | |
| int read_len = 0; | |
| bool ret = true; | |
| if (NULL == database) { | |
| LOGE("gpslog_hdlr, database not valid"); | |
| return false; | |
| } | |
| if (NULL == hdlr) { | |
| LOGE("[%s]gpslog_hdlr, hdlr not valid", database->sock_addr); | |
| return false; | |
| } | |
| if (fd < 0) { | |
| LOGE("[%s]gpslog_hdlr, fd not valid", database->sock_addr); | |
| return false; | |
| } | |
| memset(gpslog_buff, 0, sizeof(gpslog_buff)); | |
| read_len = gpslog_safe_recv(fd, gpslog_buff, sizeof(gpslog_buff)-1); | |
| if (read_len <= 0) { | |
| LOGE("[%s]gpslog_hdlr() gpslog_safe_recv() failed read_len=%d", database->sock_addr, read_len); | |
| return false; | |
| } | |
| ptype = gpslog_socket_get_int(gpslog_buff, &offset); | |
| UNUSED(ptype); | |
| cmd = gpslog_socket_get_int(gpslog_buff, &offset); | |
| log_type = gpslog_socket_get_int(gpslog_buff, &offset); | |
| UNUSED(log_type); | |
| switch (cmd) { | |
| case GPSLOG_OPEN_LOG: { | |
| if (hdlr->create_logfile) { | |
| char path[GPSLOG_PATH_SIZE] = {0}; | |
| //gpslog_socket_get_string(gpslog_buff, &offset, path, sizeof(path)); | |
| sprintf(path, "GPSHostLog"); | |
| if (!hdlr->create_logfile(path)) { | |
| LOGE("[%s]gpslog_hdlr() create_logfile fail", database->sock_addr); | |
| } | |
| } else { | |
| LOGE("[%s]gpslog_hdlr() create_logfile is NULL", database->sock_addr); | |
| ret = false; | |
| } | |
| break; | |
| } | |
| case GPSLOG_WRITE_LOG: { | |
| if (hdlr->write_logdata) { | |
| unsigned int len_logdata = gpslog_socket_get_int(gpslog_buff, &offset); | |
| if (len_logdata <= GPSLOG_INTERFACE_BUFF_SIZE) { | |
| if (!hdlr->write_logdata(gpslog_buff+offset, len_logdata)) { | |
| LOGE("[%s]gpslog_hdlr() write_logdata fail", database->sock_addr); | |
| } | |
| } else { | |
| LOGE("[%s]gpslog_hdlr() len_logdata:%u overflow", database->sock_addr, len_logdata); | |
| ret = false; | |
| } | |
| } else { | |
| LOGE("[%s]gpslog_hdlr() write_logdata is NULL", database->sock_addr); | |
| ret = false; | |
| } | |
| break; | |
| } | |
| case GPSLOG_CLOSE_LOG: { | |
| if (hdlr->close_logfile) { | |
| if (!hdlr->close_logfile()) { | |
| LOGE("[%s]gpslog_hdlr() close_logfile fail", database->sock_addr); | |
| } | |
| } else { | |
| LOGE("[%s]gpslog_hdlr() close_logfile is NULL", database->sock_addr); | |
| ret = false; | |
| } | |
| break; | |
| } | |
| default: { | |
| LOGE("[%s]gpslog_hdlr() unknown cmd=%d", database->sock_addr, cmd); | |
| ret = false; | |
| break; | |
| } | |
| } | |
| return ret; | |
| } | |
| static void* gpslog_write_thread(void *database) | |
| { | |
| #define EPOLL_MAX_NUM 4 | |
| int fd = -1; | |
| int i = 0; | |
| int n = 0; | |
| int epfd = epoll_create(EPOLL_MAX_NUM); | |
| struct epoll_event events[EPOLL_MAX_NUM]; | |
| log_db* data = (log_db*)database; | |
| if (NULL == data) { | |
| LOGE("gpslog_write_thread exit, database not valid"); | |
| return 0; | |
| } | |
| LOGD("[%s]gpslog_write_thread created", data->sock_addr); | |
| if (-1 == epfd) { | |
| LOGE("[%s]gpslog_write_thread epoll_create failure, reason=[%s]", data->sock_addr, strerror(errno)); | |
| return 0; | |
| } | |
| //fd = gpslog_socket_bind_udp(data->sock_addr); | |
| fd = gpslog_socket_server_bind_local(data->sock_addr, SOCK_NS_ABSTRACT); | |
| if (fd < 0) { | |
| LOGE("[%s]gpslog_write_thread create fd failed, reason=[%s]", data->sock_addr, strerror(errno)); | |
| return 0; | |
| } | |
| if (gpslog_epoll_add_fd(epfd, fd) == -1) { | |
| LOGE("[%s]gpslog_write_thread failed for fd_hal failed, reason=[%s]", data->sock_addr, strerror(errno)); | |
| return 0; | |
| } | |
| while (1) { | |
| n = epoll_wait(epfd, events, EPOLL_MAX_NUM , -1); | |
| if (-1 == n) { | |
| if (errno == EINTR) { | |
| continue; | |
| } else { | |
| LOGE("[%s]gpslog_write_thread epoll_wait failure reason=[%s]", data->sock_addr, strerror(errno)); | |
| return 0; | |
| } | |
| } | |
| for (i = 0; i < n; i++) { | |
| if (events[i].data.fd == fd) { | |
| if (events[i].events & EPOLLIN) { | |
| if (!gpslog_hdlr(fd, data, &gpslog_handler_interface)) { | |
| LOGE("[%s]gpslog_hdlr failure reason=[%s]", data->sock_addr, strerror(errno)); | |
| } | |
| } | |
| } else { | |
| LOGE("[%s]mnld_main_thread() unknown fd=%d", data->sock_addr, events[i].data.fd); | |
| } | |
| } | |
| } | |
| LOGE("[%s]gpslog_write_thread exit", data->sock_addr); | |
| return 0; | |
| } | |
| static void gpslog_database_init() { | |
| memset(&gpslog_db, 0x0, sizeof(gpslog_db)); | |
| //GPS LOG config | |
| gpslog_db.sock_addr = GPSLOG_UDP_ADDR; | |
| } | |
| int gpslog_init() { | |
| pthread_t pthread_gps; | |
| LOGD("gpslog_init"); | |
| gpslog_database_init(); | |
| pthread_create(&pthread_gps, NULL, gpslog_write_thread, (char*)(&gpslog_db)); | |
| return 0; | |
| } | |
| int main(void) { | |
| LOGD("LBS debug daemon begin running"); | |
| if (gpslog_init() != 0) { | |
| LOGE("gpslog_init error, exit"); | |
| return -1; | |
| } | |
| gpslog_block_here(); | |
| return 0; | |
| } |