|
@@ -0,0 +1,273 @@
|
|
|
|
+
|
|
|
|
+#include "oem.h"
|
|
|
|
+#include <stdio.h>
|
|
|
|
+#include <stdarg.h>
|
|
|
|
+#include <netdb.h>
|
|
|
|
+#include "sockets.h"
|
|
|
|
+#include "ql_rtos.h"
|
|
|
|
+#include "ql_data_call.h"
|
|
|
|
+
|
|
|
|
+int w_profile_id=1;
|
|
|
|
+OEM_SYS_LOG_FUN oem_usr_log=NULL;
|
|
|
|
+char oem_log_buf[256];
|
|
|
|
+#define THIS_LOG(...) OEM_sys_log_print("OEM","msg", ##__VA_ARGS__)
|
|
|
|
+
|
|
|
|
+void *OEM_sys_malloc(unsigned int byteSize){
|
|
|
|
+ return malloc(byteSize);
|
|
|
|
+}
|
|
|
|
+void OEM_sys_free(void *data){
|
|
|
|
+ if(data==NULL) return;
|
|
|
|
+ free(data);
|
|
|
|
+}
|
|
|
|
+void OEM_sys_set_pcid(int pcid){
|
|
|
|
+ w_profile_id=pcid;
|
|
|
|
+}
|
|
|
|
+void OEM_sys_sleep_ms(int ms){
|
|
|
|
+ ql_rtos_task_sleep_ms(ms);
|
|
|
|
+}
|
|
|
|
+int OEM_sys_get_hid(char *outmsg, int msglen){
|
|
|
|
+ return ql_dev_get_sn(outmsg, msglen);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int OEM_sys_task_new(OEM_SYS_TASK_FUN fun, int task_stack_k, int priority, const char *taskName,void *param){
|
|
|
|
+ ql_task_t thisTask;
|
|
|
|
+ return ql_rtos_task_create(&thisTask, task_stack_k*1024, priority,taskName, fun, param, 0);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int OEM_sys_log_init(OEM_SYS_LOG_FUN fun){
|
|
|
|
+ oem_usr_log=fun;
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void OEM_sys_log_print(const char *mark,const char *level,char * fmt, ...){
|
|
|
|
+ va_list va;
|
|
|
|
+ int n;
|
|
|
|
+ snprintf(oem_log_buf, sizeof(oem_log_buf), "<%s>%s:", mark, level);
|
|
|
|
+ n=strlen(oem_log_buf);
|
|
|
|
+ va_start(va, fmt);
|
|
|
|
+ vsnprintf(oem_log_buf+n, sizeof(oem_log_buf)-n, fmt, va);
|
|
|
|
+ va_end(va);
|
|
|
|
+ strcat(oem_log_buf, "\r\n");
|
|
|
|
+ if(oem_usr_log==NULL) {}//可考虑使用系统打印
|
|
|
|
+ else oem_usr_log(oem_log_buf);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int OEM_sys_ppp_ready(void){
|
|
|
|
+ struct ql_data_call_info info = {0};
|
|
|
|
+ if(0!=ql_get_data_call_info(w_profile_id, 0, &info)) return -1;
|
|
|
|
+ if(info.v4.state==0) return -2;
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+int OEM_sys_dns(char *dns, char *outIp, int outIpSize){
|
|
|
|
+ if(dns==NULL) return -1;
|
|
|
|
+ if(outIp==NULL) return -2;
|
|
|
|
+ if(outIpSize<15) return -3;
|
|
|
|
+ struct addrinfo * res,hints;
|
|
|
|
+ memset(&hints, 0, sizeof(struct addrinfo));
|
|
|
|
+ hints.ai_family = AF_INET;
|
|
|
|
+ hints.ai_socktype = SOCK_STREAM;
|
|
|
|
+ if(getaddrinfo_with_pcid(dns, NULL, &hints, &res, w_profile_id) != 0) return -4;
|
|
|
|
+ struct sockaddr_in *sin;
|
|
|
|
+ if(res==NULL) return -5;
|
|
|
|
+ sin=(struct sockaddr_in *)res->ai_addr;
|
|
|
|
+ snprintf(outIp, outIpSize,"%s",inet_ntoa(sin->sin_addr));
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+typedef struct{
|
|
|
|
+ int fd;
|
|
|
|
+ struct sockaddr_in sockAddr;
|
|
|
|
+ OEM_SYS_SOCK_FUN fun;
|
|
|
|
+ void *usr_data;
|
|
|
|
+ unsigned char ctl;
|
|
|
|
+ fd_set read_fds;
|
|
|
|
+ struct timeval t;
|
|
|
|
+ OEM_TUP_ENUM tup;
|
|
|
|
+ char name[20];
|
|
|
|
+}OEM_SYS_SOCK_DEF;
|
|
|
|
+void OEM_sys_sock_entry(void *param){
|
|
|
|
+ char recbuf[1024];
|
|
|
|
+ int ret,tlen;
|
|
|
|
+ OEM_SYS_SOCK_DEF *sock_param=(OEM_SYS_SOCK_DEF *)param;
|
|
|
|
+ if(sock_param->fun!=NULL) sock_param->fun(OEM_SYS_SOCK_EVENT_CONNECT_OK,sock_param->name,NULL, 0, sock_param->usr_data);
|
|
|
|
+ sock_param->ctl=0;
|
|
|
|
+ THIS_LOG("sock<%s>%s start", sock_param->name,sock_param->tup==OEM_TUP_TCP?"TCP":"UDP");
|
|
|
|
+ for(;;){
|
|
|
|
+ if(sock_param->ctl==0){
|
|
|
|
+ sock_param->t.tv_sec=10;
|
|
|
|
+ sock_param->t.tv_usec=0;
|
|
|
|
+ FD_ZERO(&sock_param->read_fds);
|
|
|
|
+ FD_SET(sock_param->fd, &sock_param->read_fds);
|
|
|
|
+
|
|
|
|
+ ret = select(sock_param->fd + 1, &sock_param->read_fds, NULL, NULL, &sock_param->t);
|
|
|
|
+ if(ret==0) continue;//timeout
|
|
|
|
+ else if(ret<0){
|
|
|
|
+ sock_param->ctl=1;
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ if(FD_ISSET(sock_param->fd, &sock_param->read_fds)){
|
|
|
|
+ if(sock_param->tup==OEM_TUP_TCP) ret=recv(sock_param->fd, recbuf, sizeof(recbuf), 0);
|
|
|
|
+ else{
|
|
|
|
+ tlen=sizeof(sock_param->sockAddr);
|
|
|
|
+ ret=recvfrom(sock_param->fd, recbuf, sizeof(recbuf), 0, &sock_param->sockAddr,&tlen);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(ret>0){
|
|
|
|
+ THIS_LOG("sock<%s>get data<%d>", sock_param->name,ret);
|
|
|
|
+ if(sock_param->fun!=NULL) sock_param->fun(OEM_SYS_SOCK_EVENT_RECV_DATA, sock_param->name,recbuf, ret,sock_param->usr_data);
|
|
|
|
+ }else if(ret==0){//关闭
|
|
|
|
+ THIS_LOG("sock<%s>shut", sock_param->name);
|
|
|
|
+ if(sock_param->fun!=NULL) sock_param->fun(OEM_SYS_SOCK_EVENT_SHUT_IND, sock_param->name,NULL, 0, sock_param->usr_data);
|
|
|
|
+ sock_param->ctl=2;
|
|
|
|
+ }else{
|
|
|
|
+ if(!(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)){//异常
|
|
|
|
+ THIS_LOG("sock<%s>error", sock_param->name);
|
|
|
|
+ if(sock_param->fun!=NULL) sock_param->fun(OEM_SYS_SOCK_EVENT_ERROR_IND, sock_param->name,NULL, 0, sock_param->usr_data);
|
|
|
|
+ sock_param->ctl=3;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }else{
|
|
|
|
+ OEM_sys_sleep_ms(50);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ THIS_LOG("sock<%s>exit", sock_param->name);
|
|
|
|
+ if(sock_param!=NULL) free(sock_param);
|
|
|
|
+}
|
|
|
|
+OEM_sock* OEM_sys_sock_connect(OEM_TUP_ENUM tup, char *ip, unsigned short port,OEM_SYS_SOCK_FUN fun,int *ret,int task_stack_k,int priority,const char *taskName, void *usr_data){
|
|
|
|
+ int sock=-1;
|
|
|
|
+ int sock_error=0;
|
|
|
|
+ OEM_SYS_SOCK_DEF *sock_param=NULL;
|
|
|
|
+ if(ip==NULL){
|
|
|
|
+ *ret=-1;
|
|
|
|
+ goto OEM_SOCK_END;
|
|
|
|
+ }
|
|
|
|
+ THIS_LOG("sock<%s>connect %s:%d", taskName, ip, port);
|
|
|
|
+ if(tup==OEM_TUP_UDP) sock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
|
|
+ else sock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
|
|
+ if(sock<0){
|
|
|
|
+ *ret=-2;
|
|
|
|
+ goto OEM_SOCK_END;
|
|
|
|
+ }
|
|
|
|
+ int sock_nbio = 1;
|
|
|
|
+ struct ql_data_call_info info = {0};
|
|
|
|
+ ioctl(sock, FIONBIO, &sock_nbio);
|
|
|
|
+ if(0!=ql_get_data_call_info(w_profile_id, 0, &info)){
|
|
|
|
+ *ret=-3;
|
|
|
|
+ goto OEM_SOCK_END;
|
|
|
|
+ }
|
|
|
|
+ if(info.v4.state==0){
|
|
|
|
+ *ret=-4;
|
|
|
|
+ goto OEM_SOCK_END;
|
|
|
|
+ }
|
|
|
|
+ sock_param=(OEM_SYS_SOCK_DEF *)malloc(sizeof(OEM_SYS_SOCK_DEF));
|
|
|
|
+ if(sock_param==NULL){
|
|
|
|
+ *ret=-5;
|
|
|
|
+ goto OEM_SOCK_END;
|
|
|
|
+ }
|
|
|
|
+ struct sockaddr_in ip4_local_addr = {0};
|
|
|
|
+ ip4_local_addr.sin_family = AF_INET;
|
|
|
|
+ ip4_local_addr.sin_port = htons(ql_soc_generate_port());
|
|
|
|
+ ip4_local_addr.sin_addr = info.v4.addr.ip;
|
|
|
|
+
|
|
|
|
+ if(0!=bind(sock, (struct sockaddr *)&ip4_local_addr, sizeof(ip4_local_addr))){
|
|
|
|
+ *ret=-6;
|
|
|
|
+ goto OEM_SOCK_END;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ struct sockaddr_in *ip4_svr_addr=&sock_param->sockAddr;
|
|
|
|
+ ip4_svr_addr->sin_family = AF_INET;
|
|
|
|
+ ip4_svr_addr->sin_port = htons(port);
|
|
|
|
+ ip4_svr_addr->sin_addr.s_addr = inet_addr(ip);
|
|
|
|
+
|
|
|
|
+ if(-1==connect(sock, (struct sockaddr *)ip4_svr_addr, sizeof(struct sockaddr)) && EINPROGRESS!=errno){
|
|
|
|
+ *ret=-7;
|
|
|
|
+ goto OEM_SOCK_END;
|
|
|
|
+ }
|
|
|
|
+ sock_param->t.tv_sec=10;
|
|
|
|
+ sock_param->t.tv_usec=0;
|
|
|
|
+ fd_set write_fds;
|
|
|
|
+ FD_ZERO(&sock_param->read_fds);
|
|
|
|
+ FD_ZERO(&write_fds);
|
|
|
|
+
|
|
|
|
+ FD_SET(sock, &sock_param->read_fds);
|
|
|
|
+ FD_SET(sock, &write_fds);
|
|
|
|
+
|
|
|
|
+ if(select(sock + 1, &sock_param->read_fds, &write_fds, NULL, &sock_param->t)<=0){
|
|
|
|
+ *ret=-8;
|
|
|
|
+ goto OEM_SOCK_END;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(!FD_ISSET(sock, &sock_param->read_fds) && !FD_ISSET(sock, &write_fds)){
|
|
|
|
+ *ret=-9;
|
|
|
|
+ goto OEM_SOCK_END;
|
|
|
|
+ }else if(FD_ISSET(sock, &sock_param->read_fds) && FD_ISSET(sock, &write_fds)){
|
|
|
|
+ socklen_t optlen = sizeof(sock_error);
|
|
|
|
+ if(0!=getsockopt(sock, SOL_SOCKET, SO_ERROR, &sock_error, &optlen) || sock_error != 0){
|
|
|
|
+ *ret=-10;
|
|
|
|
+ goto OEM_SOCK_END;
|
|
|
|
+ }
|
|
|
|
+ }else if(!FD_ISSET(sock, &sock_param->read_fds) && FD_ISSET(sock, &write_fds)){
|
|
|
|
+ //connect ok
|
|
|
|
+ }else if(FD_ISSET(sock, &sock_param->read_fds) && !FD_ISSET(sock, &write_fds)){
|
|
|
|
+ *ret=-11;
|
|
|
|
+ goto OEM_SOCK_END;
|
|
|
|
+ }else{
|
|
|
|
+ *ret=-12;
|
|
|
|
+ goto OEM_SOCK_END;
|
|
|
|
+ }
|
|
|
|
+ //connec ok
|
|
|
|
+ sock_param->fd=sock;
|
|
|
|
+ sock_param->fun=fun;
|
|
|
|
+ sock_param->usr_data=usr_data;
|
|
|
|
+ sock_param->tup=tup;
|
|
|
|
+ snprintf(sock_param->name,sizeof(sock_param->name), "%s", taskName);
|
|
|
|
+ if(0!=OEM_sys_task_new(OEM_sys_sock_entry, task_stack_k, priority, taskName,sock_param)){
|
|
|
|
+ *ret=-13;
|
|
|
|
+ goto OEM_SOCK_END;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ *ret=0;
|
|
|
|
+ THIS_LOG("sock<%s>ok", taskName);
|
|
|
|
+ return (OEM_sock *)sock_param;
|
|
|
|
+
|
|
|
|
+ OEM_SOCK_END:
|
|
|
|
+ THIS_LOG("sock<%s>fail:%d", taskName, *ret);
|
|
|
|
+ if(sock>0) close(sock);
|
|
|
|
+ if(sock_param!=NULL) free(sock_param);
|
|
|
|
+ return NULL;
|
|
|
|
+}
|
|
|
|
+int OEM_sys_sock_close(OEM_sock *handle){
|
|
|
|
+ OEM_SYS_SOCK_DEF *sock_param=(OEM_SYS_SOCK_DEF *)handle;
|
|
|
|
+ if(sock_param==NULL) return -1;
|
|
|
|
+ if(sock_param->fd>0){
|
|
|
|
+ close(sock_param->fd);
|
|
|
|
+ sock_param->fd=-1;
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+int OEM_sys_sock_send_data(OEM_sock *handle, unsigned char *data, int datalen){
|
|
|
|
+ OEM_SYS_SOCK_DEF *sock_param=(OEM_SYS_SOCK_DEF *)handle;
|
|
|
|
+ if(sock_param==NULL) return -1;
|
|
|
|
+ if(sock_param->fd<0) return -2;
|
|
|
|
+ if(sock_param->tup==OEM_TUP_TCP) return send(sock_param->fd,data,datalen,0);
|
|
|
|
+ else return sendto(sock_param->fd,data,datalen,0, &sock_param->sockAddr, sizeof(struct sockaddr_in));
|
|
|
|
+}
|
|
|
|
+unsigned int OEM_sys_get_tick(void){
|
|
|
|
+ return ql_rtos_get_systicks();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int OEM_sys_queue_new(OEM_que *handle,unsigned int msgsize, unsigned int msgnum){
|
|
|
|
+ return ql_rtos_queue_create(handle, msgsize, msgnum);
|
|
|
|
+}
|
|
|
|
+int OEM_sys_queue_wait(OEM_que handle, unsigned char *msgBuf, unsigned int msgBufSize){
|
|
|
|
+ return ql_rtos_queue_wait(handle, msgBuf, msgBufSize, QL_WAIT_FOREVER);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int OEM_sys_queue_send(OEM_que handle, unsigned char *msgBuf, unsigned int msgBufSize){
|
|
|
|
+ return ql_rtos_queue_release(handle, msgBufSize, msgBuf, QL_NO_WAIT);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int OEM_sys_queue_del(OEM_que handle){
|
|
|
|
+ return ql_rtos_queue_delete(handle);
|
|
|
|
+}
|