⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ul_l_drv_eth.c

📁 一个linux下rs485驱动程序的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************  uLan Communication - basic library  ul_l_drv_eth.c     - ethernet driver interface  (C) Copyright 1996,1999 by Pavel Pisa   The uLan driver is distributed under the Gnu General Public Licence.   See file COPYING for details. *******************************************************************/#include <stdio.h>#include <string.h>#include <stdlib.h>#ifndef _WIN32#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <signal.h>#define BAD_SOCKET(s) ((s) < 0)#define UL_SOCKET_INVALID -1#define SLEEP(x) sleep(x)#else#include <winsock.h>#include <fcntl.h>#define BAD_SOCKET(s) ((s) == INVALID_SOCKET)#define UL_SOCKET_INVALID INVALID_SOCKET#define SLEEP(x) Sleep(x*1000)#endif#include <ul_gavlcust.h>#include <ul_msg_buf.h>#include <ul_l_drv_eth.h>#include <ul_list.h>#ifdef CONFIG_OC_ULUT#include <ul_log.h>ul_log_domain_t ulogd_drv_eth   = {0, "drv_eth"};#define UL_LDOMAIN (&ulogd_drv_eth)#else#include <ul_lib/ul_l_log.h>#define UL_LDOMAIN NULL#endif#ifdef _WIN32 typedef SOCKET ul_fd_sock_t;#else /*_WIN32*/ typedef int ul_fd_sock_t; #define closesocket(s)  close(s)#endif /*_WIN32*/typedef struct msgbuff_inproc_item {  gavl_node_t node;  ul_msg_buf_t *msgbuff;  unsigned stamp;} msgbuff_inproc_item_t;typedef struct msgbuff_inproc_root {  gavl_cust_root_field_t root;} msgbuff_inproc_root_t; typedef unsigned msgbuff_inproc_key_t; GAVL_CUST_NODE_INT_DEC(msgbuff_inproc, msgbuff_inproc_root_t, msgbuff_inproc_item_t, msgbuff_inproc_key_t,	root, node, stamp, msgbuff_inproc_cmp_fnc) inline intmsgbuff_inproc_cmp_fnc(const msgbuff_inproc_key_t *a, const msgbuff_inproc_key_t *b){  if (*a>*b) return 1;  if (*a<*b) return -1;  return 0;} 	GAVL_CUST_NODE_INT_IMP(msgbuff_inproc, msgbuff_inproc_root_t, msgbuff_inproc_item_t, msgbuff_inproc_key_t,	root, node, stamp, msgbuff_inproc_cmp_fnc) typedef struct filter_inproc_item {  ul_list_node_t node;  ul_msginfo msginfo;} filter_inproc_item_t;typedef struct ul_fd_eth_context_t {  ul_fd_context_t context;  ul_fd_sock_t sock_fd;  FILE *sock_wfile;  uint32_t ipaddress;  uint16_t port;  ul_dbuff_t dev_name;  ul_dbuff_t rcvbuff;  ul_msg_buf_t *msgbuff_start;  ul_msg_buf_t *msgbuff_proc;  int msgbuff_idx;  int msg_received_flg;  unsigned stamp_eth_cnt;  msgbuff_inproc_root_t msgbuff_inproc_root;    ul_list_head_t filter_inproc_root;} ul_fd_eth_context_t;UL_LIST_CUST_DEC(filter_inproc,                 ul_fd_eth_context_t,filter_inproc_item_t,                 filter_inproc_root,node);/* forward declarations */int ul_eth_close(ul_fd_t ul_fd);int ul_eth_recv_responce_int(ul_fd_eth_context_t *eth_fd,const char *cmd,int sn,int *v);static inlineul_fd_eth_context_t *ul_fd2eth_context(ul_fd_t ul_fd){  return UL_CONTAINEROF(ul_fd, ul_fd_eth_context_t, context);}static inlineul_fd_sock_t ulop_eth_fd2sock_fd(ul_fd_t ul_fd){  if(ul_fd==UL_FD_INVALID)    return UL_FD_DIRECT_INVALID;  else    return ul_fd2eth_context(ul_fd)->sock_fd;}ul_fd_direct_t ulop_eth_fd2sys_fd(ul_fd_t ul_fd){  /*   * This is not fully correct on Windows, there does not exist handle   * type usable for both files and sockets   */  return ulop_eth_fd2sock_fd(ul_fd);}unsigned ul_eth_gen_stamp(ul_fd_eth_context_t *eth_fd){  eth_fd->stamp_eth_cnt++;  eth_fd->stamp_eth_cnt&=0x7fffffff;  if(!eth_fd->stamp_eth_cnt)eth_fd->stamp_eth_cnt++;  return eth_fd->stamp_eth_cnt; };ul_fd_sock_t ul_eth_sock_init(uint32_t net_ipaddr,uint16_t net_port) {  struct sockaddr_in name;  ul_fd_sock_t fd;  #ifdef _WIN32  WORD wVersionRequested;  WSADATA wsaData;  int sockopt = SO_SYNCHRONOUS_NONALERT;  #endif      #ifdef _WIN32    wVersionRequested = MAKEWORD(2, 0);    WSAStartup(wVersionRequested, &wsaData);    setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&sockopt, sizeof(sockopt));     #endif  #ifndef _WIN32    signal(SIGPIPE, SIG_IGN);  #endif  if (BAD_SOCKET(fd=socket(AF_INET, SOCK_STREAM, 0)))     return UL_SOCKET_INVALID;  name.sin_family=AF_INET;  name.sin_addr.s_addr=net_ipaddr;  name.sin_port=net_port;  if (BAD_SOCKET(connect(fd, (struct sockaddr *) &name, sizeof(name)))) {    closesocket(fd);    return UL_SOCKET_INVALID;  }  return fd;}intul_eth_sock_init_file(ul_fd_eth_context_t *eth_fd){ int f; #ifndef _WIN32  f=eth_fd->sock_fd; #else  f=_open_osfhandle(eth_fd->sock_fd,0);  if (f<0)     return -1; #endif /* _WIN32 */  eth_fd->sock_wfile=fdopen(f,"w");  if (!eth_fd->sock_wfile)     return -1;  return 0;}int ul_eth_sock_close(ul_fd_eth_context_t *eth_fd){  if (eth_fd->sock_wfile)     fclose(eth_fd->sock_wfile);  eth_fd->sock_wfile=0;  if (eth_fd->sock_fd!=UL_SOCKET_INVALID)    closesocket(eth_fd->sock_fd);  eth_fd->sock_fd=UL_SOCKET_INVALID;  return 0;}intul_eth_sock_reinit(ul_fd_eth_context_t *eth_fd){  int i,v;  unsigned eth_stamp;  filter_inproc_item_t *fitem;  if (eth_fd->sock_fd!=UL_SOCKET_INVALID)    return 0;  eth_fd->sock_fd=ul_eth_sock_init(eth_fd->ipaddress,eth_fd->port);  if (eth_fd->sock_fd==UL_SOCKET_INVALID)    return -1;  if (ul_eth_sock_init_file(eth_fd))     return -1;  /* send command to server request */  eth_stamp=ul_eth_gen_stamp(eth_fd);  fprintf(eth_fd->sock_wfile,"usc %d open %s\n",eth_stamp,eth_fd->dev_name.data);  fflush(eth_fd->sock_wfile);  /* wait for responce */  i=ul_eth_recv_responce_int(eth_fd,"open",eth_stamp,&v);  if ((i!=1) || (v==0)) {    ul_eth_sock_close(eth_fd);    return -1;  }  /* create filters */  ul_list_for_each(filter_inproc,eth_fd,fitem) {    ul_msginfo *msginfo=&fitem->msginfo;    eth_stamp=ul_eth_gen_stamp(eth_fd);    fprintf(eth_fd->sock_wfile,"usc %d addfilt %02x%02x%02x\n",eth_stamp,msginfo->sadr,msginfo->dadr,msginfo->cmd);    fflush(eth_fd->sock_wfile);    /* wait for responce */    if (ul_eth_recv_responce_int(eth_fd,"addfilt",eth_stamp,&v)!=1) {      ul_eth_sock_close(eth_fd);      return -1;    }  }  return 0;}static inline intul_eth_sock_check(ul_fd_eth_context_t *eth_fd){  return ul_eth_sock_reinit(eth_fd);}/** * ul_eth_recv_msg -  * @fd:  * @rcvbuff:  * @timeout: * * Returns number of received bytes or negative error code *  Error codes: -1 connection was terminated by server *               -2 xxx *               -3 memory allocation error *               -4 timeout *               -5 terminated  */intul_eth_recv_msg(int fd,ul_dbuff_t *rcvbuff,int timeout, int *terminated){  ul_dbuff_set_len(rcvbuff, 0);  while ((*terminated)==0) {    struct timeval stimeout = {1, 0};    int r,nread;    fd_set fds;    FD_ZERO(&fds);    FD_SET(fd,&fds);    r=select(FD_SETSIZE,&fds,NULL,NULL,&stimeout);    if (timeout>0) {      timeout--;      if (!timeout)        return -4;     }    if (r<0) {      return -1;    }    if (r==0)       continue;    if(FD_ISSET(fd, &fds)) {      #ifndef _WIN32        ioctl(fd, FIONREAD, &nread);      #else        u_long unread;        ioctlsocket(fd, FIONREAD, &unread);        nread=unread;      #endif /* _WIN32 */      if(nread != 0) {        int n;        int old_len = rcvbuff->len;        int new_len = old_len + nread;        int eofmsg = 0;        if(ul_dbuff_set_len(rcvbuff, new_len) == new_len) {          nread = recv(fd, rcvbuff->data + old_len, nread,0);          // try to find '\10' in new data to check out the on of message          for(n = nread-1; n>=0; n--) {             if((rcvbuff->data + old_len)[n] == 10) {              eofmsg = 1;               break;            }          }        } else {          /* Can't allocate memory */          return -3;        }        if(eofmsg) {          // if you got the whole message append terminating 0 & process it          ul_dbuff_append_byte(rcvbuff, '\0');          ul_dbuff_trim(rcvbuff);          return rcvbuff->len;        }       } else         return -1;    } else {      // this should never happen if the program work well      // outread unexpected data from buffer      int fd;      for(fd = 0; fd < FD_SETSIZE; fd++) {        if(FD_ISSET(fd, &fds)) {          ul_dbuff_set_len(rcvbuff, 128);          nread = recv(fd, rcvbuff->data, rcvbuff->len-1,0);          rcvbuff->data[nread] = '\0';        }      }    }  }  return -5;}intul_eth_send_msg(FILE *fd,ul_msg_buf_t *sndbuff){  ul_msginfo *msginfo;  int i;  do{    msginfo=&sndbuff->msginfo;    fprintf(fd,"%02x%02x%02x%04x%08x%04x",    	        msginfo->sadr,msginfo->dadr,msginfo->cmd,                msginfo->flg,msginfo->stamp,msginfo->len);    ul_log(UL_LDOMAIN,UL_LOGL_DEB|UL_LOGL_CONT,"%02x%02x%02x%04x%08x%04x",    	        msginfo->sadr,msginfo->dadr,msginfo->cmd,                msginfo->flg,msginfo->stamp,msginfo->len);    i=0;    while(i<msginfo->len) {      fprintf(fd,"%02x",sndbuff->data.data[i]);      ul_log(UL_LDOMAIN,UL_LOGL_DEB|UL_LOGL_CONT,"%02x",sndbuff->data.data[i]);      i++;    }    if (!sndbuff->tail)       return 0;    sndbuff=sndbuff->tail;  }while(1);}intul_eth_demarshal_stream(ul_msg_buf_t *msg_buf,char *stream,int stream_len){  ul_msg_buf_t *tail;  ul_msginfo *msginfo;  int r,i,v;  ul_msg_buf_destroy(msg_buf);  do {    /* header */    msginfo=&msg_buf->msginfo;    if (stream_len<22) return -1;    r=sscanf(stream,"%02x%02x%02x%04x%08x%04x",  	     &msginfo->sadr,&msginfo->dadr,&msginfo->cmd,             &msginfo->flg,&msginfo->stamp,&msginfo->len);    stream+=22;    stream_len-=22;    if ((stream_len/2)<msginfo->len) return -1;    if (ul_dbuff_prep(&msg_buf->data,msginfo->len)<msginfo->len)      return -1;    /* copy data from txt stream to ul_msg_buf */    i=0;    while (i<msginfo->len) {      sscanf(stream,"%02x",&v);      *(msg_buf->data.data+i)=v;      stream+=2;      i++;    }    stream_len-=2*i;        /* prepare tail */    if (stream_len>0) {      if(!(tail=malloc(sizeof(ul_msg_buf_t))))        return -1;      ul_msg_buf_init(tail);      msg_buf->tail=tail;      msg_buf=tail;    }  } while(stream_len>0);  return 1;} intul_eth_recv_responce_int(ul_fd_eth_context_t *eth_fd,const char *cmd,int sn,int *v){  char buff[64];  int r,t=0;    r=ul_eth_recv_msg(eth_fd->sock_fd,&eth_fd->rcvbuff,UL_ETH_SOCK_TIMEOUT,&t);  if (r<0) {    if (r==-1)      ul_eth_sock_close(eth_fd);    return r;  }  sprintf(buff,"usr %d %s %%d",sn,cmd);  return sscanf((char*)eth_fd->rcvbuff.data,buff,v);}intul_eth_recv_responce_msgbuf(ul_fd_eth_context_t *eth_fd,const char *cmd,int sn,ul_msg_buf_t *rdbuf){  char *msg_header,*msg_sn,*msg_cmd,*msg_data;  int msg_data_len,i,r,t=0;  r=ul_eth_recv_msg(eth_fd->sock_fd,&eth_fd->rcvbuff,UL_ETH_SOCK_TIMEOUT,&t);  if (r<0) {    if (r==-1)      ul_eth_sock_close(eth_fd);    return r;  }    msg_header = strtok ((char*)eth_fd->rcvbuff.data," ");  if (msg_header!=NULL) {    msg_sn = strtok (NULL," ");    if (msg_sn!=NULL) {      msg_cmd = strtok (NULL," ");      if (msg_cmd!=NULL) {        msg_data = strtok (NULL," ");        msg_data_len=0;        if (msg_data!=NULL)           msg_data_len=eth_fd->rcvbuff.len-(msg_data-(char*)eth_fd->rcvbuff.data)-1;        if (strcmp(cmd,msg_cmd)!=0)           return -1;        i=strtol(msg_sn,NULL,0);        if (sn!=i)          return -1;        return ul_eth_demarshal_stream(rdbuf,msg_data,msg_data_len);      }    }      }  return -1;}ul_fd_ops_t ul_fd_eth_ops;static inline ul_fd_t ul_fd_direct2ul_fd(ul_fd_sock_t fd){  ul_fd_eth_context_t *eth_fd;  if (fd==UL_SOCKET_INVALID)     return UL_FD_INVALID;     eth_fd=malloc(sizeof(*eth_fd));  if(!eth_fd)    return UL_FD_INVALID;  memset(eth_fd,0,sizeof(*eth_fd));  eth_fd->sock_fd=fd;  eth_fd->context.fd_ops=&ul_fd_eth_ops;  ul_dbuff_init(&eth_fd->rcvbuff, 0);  ul_dbuff_init(&eth_fd->dev_name, 0);  filter_inproc_init_head(eth_fd);  msgbuff_inproc_init_root_field(&eth_fd->msgbuff_inproc_root);  return &eth_fd->context;}ul_fd_t ul_eth_open(const char *dev_name, const char *options){  ul_fd_eth_context_t *eth_fd;  ul_fd_t r;  char buff[128],*d;  uint32_t eth_ipaddr;  uint16_t eth_port;  int i,v,l;  unsigned eth_stamp;  ul_fd_sock_t sock_fd;  if(dev_name==NULL) dev_name=UL_DEV_NAME;  else if(!strncmp(dev_name,"eth:",4)) dev_name+=4;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -