#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; | |
} |