blob: afade990eef72f46afb4cd1d67d6aba3a6a2e3b1 [file] [log] [blame]
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/types.h>
#include "mbtk_type.h"
#include "mbtk_utils.h"
#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "mbtk_utils"
#include "mbtk_log.h"
#define MBTK_AT_BUF_SIZE 2048
#define MBTK_AT_CLIENT_SOCKET "/data/sock_mbtk_at"
#define PROC_CMDLINE "/proc/cmdline"
#define TIME_FORMAT "%F %T"
static int at_fd = -1;
static bool at_timeout = FALSE;
static void
at_timer_alrm(int signo)
{
LOGW("AT Timeout.[%d]\n",signo);
at_timeout = TRUE;
}
/*
* Exec shell command.
*/
bool mbtk_cmd_line
(
const char *cmd,
char *buf,
int buf_size
)
{
FILE *fcmd;
bool result = FALSE;
fcmd = popen(cmd, "r");
memset(buf, 0, buf_size);
if(fcmd)
{
int pos = 0;
int len = 0;
while(!ferror(fcmd) && !feof(fcmd))
{
if(buf_size - pos == 0)
{
break;
}
len = fread(buf + pos,1,buf_size - pos,fcmd);
if(len > 0)
pos += len;
}
if(buf_size == pos)
buf[buf_size - 1] = '\0';
pclose(fcmd);
result = TRUE;
}
LOGV("%s [result:%d]: %s",cmd,result,buf);
return result;
}
bool mbtk_cmd_line_ex
(
const char *cmd,
mbtk_cmd_cb_func cb
)
{
#define BUFF_SIZE 1024
FILE *fcmd;
bool result = FALSE;
// Get stdout and stderr data.
// xxx 2>&1
char buff[BUFF_SIZE + 1] = {0};
snprintf(buff, BUFF_SIZE + 1, "%s 2>&1", cmd);
fcmd = popen(buff, "r");
if(!cb)
{
return FALSE;
}
if(fcmd)
{
int len = 0;
if(setvbuf(fcmd, NULL, _IOLBF, BUFF_SIZE)) {
LOGE("setvbuf() fail:%d", errno);
}
errno = 0;
LOGI("ferror - %d,feof - %d",ferror(fcmd),feof(fcmd));
while(!ferror(fcmd) && !feof(fcmd))
{
memset(buff, 0, BUFF_SIZE + 1);
len = fread(buff,1,BUFF_SIZE,fcmd);
if(len > 0)
{
cb(buff,len);
}
else
{
LOGE("len - %d,errno - %d",len,errno);
}
}
pclose(fcmd);
result = TRUE;
cb(NULL,0);
}
else
{
LOGE("popen() fail.[errno=%d]",errno);
cb(NULL,0);
}
return result;
}
#if 1
// Send msg to stanet_daemon
int mbtk_send_at(const void *at_req,void* at_rsp,int rsp_size,int timeout)
{
if(at_fd < 0)
{
struct sockaddr_un servaddr;
at_fd = socket(AF_LOCAL,SOCK_STREAM,0);
if(at_fd < 0)
{
LOGE("socket fail.(%d)\n",errno);
at_fd = -1;
return -1;
}
// Set O_NONBLOCK
// int flags = fcntl(at_fd, F_GETFL, 0);
// if (flags < 0) {
// LOGE("Get flags error:%s\n", strerror(errno));
// return -1;
// }
// flags |= O_NONBLOCK;
// if (fcntl(at_fd, F_SETFL, flags) < 0) {
// LOGE("Set flags error:%s\n", strerror(errno));
// return -1;
// }
memset(&servaddr,0x0,sizeof(servaddr));
servaddr.sun_family = AF_LOCAL;
strcpy(servaddr.sun_path,MBTK_AT_CLIENT_SOCKET);
if(connect(at_fd,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)
{
LOGE("connect fail.(%d)\n",errno);
close(at_fd);
at_fd = -1;
return -1;
}
}
at_timeout = FALSE;
int n = write(at_fd,at_req,strlen((char*)at_req));
if(n == -1)
{
LOGE("write fail[%d].\n",errno);
close(at_fd);
at_fd = -1;
return -1;
}
// Set timer
signal(SIGALRM, at_timer_alrm);
struct itimerval val;
// Only time
val.it_interval.tv_sec = 0;
val.it_interval.tv_usec = 0;
// Time
if(timeout >= 1000)
{
val.it_value.tv_sec = timeout/1000;
val.it_value.tv_usec = timeout%1000;
}
else
{
val.it_value.tv_sec = 0;
val.it_value.tv_usec = timeout;
}
if (setitimer(ITIMER_REAL, &val, NULL) == -1)
{
LOGE("setitimer fail.[%d]",errno);
return -1;
}
memset(at_rsp,0x0,rsp_size);
while(!at_timeout)
{
n = read(at_fd,at_rsp,rsp_size);
if(n < 0)
{
if(errno == EWOULDBLOCK)
{
usleep(50000);
continue;
}
else
{
LOGW("read error.[%d]",errno);
break;
}
}
else if (n > 0)
{
LOGI("RSP:%s",(char*)at_rsp);
break;
}
else
{
LOGW("read error.[%d]",errno);
break;
}
}
val.it_value.tv_sec = 0;
val.it_value.tv_usec = 0;
val.it_interval = val.it_value;
setitimer(ITIMER_REAL, &val, NULL);
if(n > 0)
return 0;
return -1;
}
#else
int mbtk_send_at(const void *at_req,void* at_rsp,int rsp_size,int timeout)
{
if(!at_req || !at_rsp || rsp_size <= 0)
{
LOGE("ARG error.");
return -1;
}
// Return "ERROR" if AT fail.
const char* result = sendCmd(0,(const char*)at_req);
memset(at_rsp,0x0,rsp_size);
snprintf(at_rsp,rsp_size,"%s",result);
return 0;
}
#endif
/*
* Set timer as microseconds.
*/
int mbtk_timer_set(mbtk_timer_alrm_func func,uint32 timeout_ms)
{
signal(SIGALRM, func);
struct itimerval val;
// Only time
val.it_interval.tv_sec = 0;
val.it_interval.tv_usec = 0;
// Time
if(timeout_ms >= 1000)
{
val.it_value.tv_sec = timeout_ms/1000;
val.it_value.tv_usec = timeout_ms%1000;
}
else
{
val.it_value.tv_sec = 0;
val.it_value.tv_usec = timeout_ms;
}
if (setitimer(ITIMER_REAL, &val, NULL) == -1)
{
LOGE("setitimer fail.[errno - %d]",errno);
return -1;
}
return 0;
}
/**
* Clear current timer.
*/
int mbtk_timer_clear()
{
struct itimerval value;
value.it_value.tv_sec = 0;
value.it_value.tv_usec = 0;
value.it_interval = value.it_value;
if (setitimer(ITIMER_REAL, &value, NULL) == -1)
{
LOGE("setitimer fail.[errno - %d]",errno);
return -1;
}
return 0;
}
/* MRD still need to read /proc/cmdline after we drop root permission,
* so cache it in this function */
int mbtk_get_kernel_cmdline(char *buf, int len)
{
static char cmdline[MBTK_CMDLINE_LEN];
static int is_init = 0;
int ret = -1;
int fd;
if(!buf || len <= 0) return -1;
if(is_init)
goto INITED;
fd = open(PROC_CMDLINE, O_RDONLY);
if (fd < 0)
goto ERR_RET;
ret = read(fd, cmdline, MBTK_CMDLINE_LEN);
close(fd);
if(ret <= 0 || ret > MBTK_CMDLINE_LEN)
goto ERR_RET;
cmdline[ret - 1] = '\0';
INITED:
ret = strlen(cmdline) + 1;
if(ret > len)
ret = len;
strncpy(buf, cmdline, ret);
buf[ret - 1] = '\0';
is_init = 1;
return ret;
ERR_RET:
return -1;
}
/** returns 1 if line starts with prefix, 0 if it does not */
int strStartsWith(const char *line, const char *prefix)
{
if(prefix == NULL || strlen(prefix) == 0) {
return 1;
}
for ( ; *line != '\0' && *prefix != '\0' ; line++, prefix++) {
if (*line != *prefix) {
return 0;
}
}
return *prefix == '\0';
}
char* mbtk_time_text_get(char *buff, size_t buff_size)
{
long now_nsec = 0;
if(buff == NULL || buff_size <= 0) {
return NULL;
}
memset(buff, 0x0, buff_size);
#if 0
time_t now;
now = time(&now);
if(now == -1) {
LOGE("time() fail.");
return NULL;
}
struct tm *now_tm = gmtime(&now);
#else
struct timespec now;
if(-1 == clock_gettime(CLOCK_REALTIME, &now)) {
LOGE("clock_gettime() fail.");
return NULL;
}
struct tm *now_tm = gmtime((time_t*)(&(now.tv_sec)));
now_nsec = now.tv_nsec;
#endif
if(now_tm == NULL) {
LOGE("gmtime() fail.");
return NULL;
}
if(0 == strftime(buff, buff_size, TIME_FORMAT, now_tm)) {
LOGE("strftime() fail.");
return NULL;
}
snprintf(buff + strlen(buff), buff_size - strlen(buff),
"-%03ld", now_nsec / 1000000);
return buff;
}
mbtk_byteorder_enum mbtk_byteorder_get()
{
union {
short a;
char c[sizeof(short)];
} un;
un.a = 0x0102;
if(sizeof(short) == 2) {
if(un.c[0] == 1 && un.c[1] == 2) {
return MBTK_BYTEORDER_BIG;
} else if(un.c[0] == 2 && un.c[1] == 1) {
return MBTK_BYTEORDER_LITTLE;
} else {
return MBTK_BYTEORDER_UNKNOWN;
}
} else {
LOGE("Unknown byte order.");
return MBTK_BYTEORDER_UNKNOWN;
}
}
uint16 byte_2_uint16(const void *buff, bool big_endian)
{
const uint8* ptr = (const uint8*)buff;
if(big_endian) {
return (uint16)((ptr[0] << 8) | ptr[1]);
} else {
return (uint16)((ptr[1] << 8) | ptr[0]);
}
}
int uint16_2_byte(uint16 a, void *buff, bool big_endian)
{
uint8* ptr = (uint8*)buff;
if(big_endian) {
ptr[0] = (uint8)(a >> 8);
ptr[1] = (uint8)a;
} else {
ptr[1] = (uint8)(a >> 8);
ptr[0] = (uint8)a;
}
return sizeof(uint16);
}
uint32 byte_2_uint32(const void *buff, bool big_endian)
{
const uint8* ptr = (const uint8*)buff;
if(big_endian) {
return (uint32)((ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3]);
} else {
return (uint32)((ptr[3] << 24) | (ptr[2] << 16) | (ptr[1] << 8) | ptr[0]);
}
}
int uint32_2_byte(uint32 a, void *buff, bool big_endian)
{
uint8* ptr = (uint8*)buff;
if(big_endian) {
ptr[0] = (uint8)(a >> 24);
ptr[1] = (uint8)(a >> 16);
ptr[2] = (uint8)(a >> 8);
ptr[3] = (uint8)a;
} else {
ptr[3] = (uint8)(a >> 24);
ptr[2] = (uint8)(a >> 16);
ptr[1] = (uint8)(a >> 8);
ptr[0] = (uint8)a;
}
return sizeof(uint32);
}
uint64 byte_2_uint64(const void *buff, bool big_endian)
{
const uint8* ptr = (const uint8*)buff;
if(big_endian) {
return (uint64)(((uint64)ptr[0] << 56) | ((uint64)ptr[1] << 48) | ((uint64)ptr[2] << 40) | ((uint64)ptr[3] << 32) | (ptr[4] << 24) | (ptr[5] << 16) | (ptr[6] << 8) | ptr[7]);
} else {
return (uint64)(uint64)(((uint64)ptr[7] << 56) | ((uint64)ptr[6] << 48) | ((uint64)ptr[5] << 40) | ((uint64)ptr[4] << 32) | (ptr[3] << 24) | (ptr[2] << 16) | (ptr[1] << 8) | ptr[0]);
}
}
int uint64_2_byte(uint64 a, void *buff, bool big_endian)
{
uint8* ptr = (uint8*)buff;
if(big_endian) {
ptr[0] = (uint8)(a >> 56);
ptr[1] = (uint8)(a >> 48);
ptr[2] = (uint8)(a >> 40);
ptr[3] = (uint8)(a >> 32);
ptr[4] = (uint8)(a >> 24);
ptr[5] = (uint8)(a >> 16);
ptr[6] = (uint8)(a >> 8);
ptr[7] = (uint8)a;
} else {
ptr[7] = (uint8)(a >> 56);
ptr[6] = (uint8)(a >> 48);
ptr[5] = (uint8)(a >> 40);
ptr[4] = (uint8)(a >> 32);
ptr[3] = (uint8)(a >> 24);
ptr[2] = (uint8)(a >> 16);
ptr[1] = (uint8)(a >> 8);
ptr[0] = (uint8)a;
}
return sizeof(uint64);
}
void* memdup(const void* data, int data_len)
{
if(data && data_len > 0)
{
uint8* result = (uint8*)malloc(data_len);
if(result == NULL)
{
return NULL;
}
memcpy(result, data, data_len);
return result;
}
else
{
return NULL;
}
}
int app_already_running(const char *pid_file)
{
int fd;
char buff[16];
fd = open(pid_file, O_RDWR | O_CREAT, 0644);
if(fd < 0) {
LOGE("Open %s fail:%d", pid_file, errno);
exit(1);
}
if(flock(fd, LOCK_EX | LOCK_NB)) {
if(EWOULDBLOCK == errno) {
LOGE("%s is running.", pid_file);
exit(1);
} else {
close(fd);
return 1;
}
}
if(ftruncate(fd, 0)) {
LOGE("ftruncate(0) fail.");
return -1;
}
sprintf(buff, "%ld", (long)getpid());
if(write(fd, buff, strlen(buff) + 1) == strlen(buff) + 1) {
return 0;
} else {
return -1;
}
}
void mbtk_system(const void* cmd)
{
if(cmd) {
int ret = system(cmd);
if(ret == -1 || ret == 127) {
LOGD("system(%s) fail.", cmd);
}
}
}
void mbtk_write(int fd,const void *buf, size_t len)
{
if(fd >= 0 && buf) {
int ret = write(fd, buf, len);
if(ret < 0) {
LOGD("write() fail:%d", errno);
}
}
}
void mbtk_read(int fd,void *buf, size_t len)
{
if(fd >= 0 && buf) {
int ret = read(fd, buf, len);
if(ret < 0) {
LOGD("read() fail:%d", errno);
}
}
}
void mbtk_close(int fd)
{
if(fd >= 0) {
int ret = close(fd);
if(ret < 0) {
LOGD("close() fail:%d", errno);
}
}
}