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

📄 serialsource.c

📁 无线通信的主要编程软件,是无线通信工作人员的必备工具,关天相关教程我会在后续传上.
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <sys/types.h>#include <sys/stat.h>#include <termios.h>#include <unistd.h>#include <errno.h>#include <fcntl.h>#include <stdlib.h>#include <string.h>#include <sys/time.h>#include <stdio.h>#ifdef __CYGWIN__#include <windows.h>#include <io.h>#else#include <stdint.h>#endif/* C implementation of the mote serial protocol. See   net.tinyos.packet.Packetizer for more details */#undef DEBUG#include "serialsource.h"typedef int bool;enum {#ifndef __CYGWIN__  FALSE = 0,  TRUE = 1,#endif  BUFSIZE = 256,  MTU = 256,  ACK_TIMEOUT = 1000000, /* in us */  SYNC_BYTE = 0x7e,  ESCAPE_BYTE = 0x7d,  P_ACK = 64,  P_PACKET_ACK = 65,  P_PACKET_NO_ACK = 66,  P_UNKNOWN = 255};struct packet_list{  uint8_t *packet;  int len;  struct packet_list *next;};struct serial_source {  int fd;  bool non_blocking;  void (*message)(serial_source_msg problem);  /* Receive state */  struct {    uint8_t buffer[BUFSIZE];    int bufpos, bufused;    uint8_t packet[MTU];    bool in_sync, escaped;    int count;    struct packet_list *queue[256]; // indexed by protocol  } recv;  struct {    uint8_t seqno;    uint8_t *escaped;    int escapeptr;    uint16_t crc;  } send;};static tcflag_t parse_baudrate(int requested){  int baudrate;  switch (requested)    {#ifdef B50    case 50: baudrate = B50; break;#endif#ifdef B75    case 75: baudrate = B75; break;#endif#ifdef B110    case 110: baudrate = B110; break;#endif#ifdef B134    case 134: baudrate = B134; break;#endif#ifdef B150    case 150: baudrate = B150; break;#endif#ifdef B200    case 200: baudrate = B200; break;#endif#ifdef B300    case 300: baudrate = B300; break;#endif#ifdef B600    case 600: baudrate = B600; break;#endif#ifdef B1200    case 1200: baudrate = B1200; break;#endif#ifdef B1800    case 1800: baudrate = B1800; break;#endif#ifdef B2400    case 2400: baudrate = B2400; break;#endif#ifdef B4800    case 4800: baudrate = B4800; break;#endif#ifdef B9600    case 9600: baudrate = B9600; break;#endif#ifdef B19200    case 19200: baudrate = B19200; break;#endif#ifdef B38400    case 38400: baudrate = B38400; break;#endif#ifdef B57600    case 57600: baudrate = B57600; break;#endif#ifdef B115200    case 115200: baudrate = B115200; break;#endif#ifdef B230400    case 230400: baudrate = B230400; break;#endif#ifdef B460800    case 460800: baudrate = B460800; break;#endif#ifdef B500000    case 500000: baudrate = B500000; break;#endif#ifdef B576000    case 576000: baudrate = B576000; break;#endif#ifdef B921600    case 921600: baudrate = B921600; break;#endif#ifdef B1000000    case 1000000: baudrate = B1000000; break;#endif#ifdef B1152000    case 1152000: baudrate = B1152000; break;#endif#ifdef B1500000    case 1500000: baudrate = B1500000; break;#endif#ifdef B2000000    case 2000000: baudrate = B2000000; break;#endif#ifdef B2500000    case 2500000: baudrate = B2500000; break;#endif#ifdef B3000000    case 3000000: baudrate = B3000000; break;#endif#ifdef B3500000    case 3500000: baudrate = B3500000; break;#endif#ifdef B4000000    case 4000000: baudrate = B4000000; break;#endif    default:      baudrate = 0;    }  return baudrate;}#ifdef DEBUGstatic void dump(const char *msg, unsigned char *packet, int len){  int i;  printf("%s", msg);  for (i = 0; i < len; i++)    printf(" %02x", packet[i]);  putchar('\n');}#endifstatic void message(serial_source src, serial_source_msg msg){  if (src->message)    src->message(msg);}/* Work around buggy usb serial driver (returns 0 when no data is   available, independent of the blocking/non-blocking mode) */static int buggyread(serial_source src, void *buffer, int n){  fd_set fds;  int cnt;  if (src->non_blocking)    {      cnt = read(src->fd, buffer, n);      if (cnt == 0)	{	  cnt = -1;	  errno = EAGAIN;	}      return cnt;    }  else    for (;;)      {	FD_ZERO(&fds);	FD_SET(src->fd, &fds);	cnt = select(src->fd + 1, &fds, NULL, NULL, NULL);	if (cnt < 0)	  return -1;	cnt = read(src->fd, buffer, n);	if (cnt != 0)	  return cnt;      }}serial_source open_serial_source(const char *device, int baud_rate,				 int non_blocking,				 void (*message)(serial_source_msg problem))/* Effects: opens serial port device at specified baud_rate. If non_blocking     is true, read_serial_packet calls will be non-blocking (writes are     always blocking, for now at least)   Returns: descriptor for serial forwarder at host:port, or     NULL for failure (bad device or bad baud rate) */{  struct termios newtio;  int fd;  tcflag_t baudflag = parse_baudrate(baud_rate);  if (!baudflag)    return NULL;  fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK);  if (fd < 0)    return NULL;#ifdef __CYGWIN__  /* For some very mysterious reason, this incantation is necessary to make     the serial port work under some windows machines */  HANDLE handle = (HANDLE)get_osfhandle(fd);  DCB dcb;  if (!(GetCommState(handle, &dcb) && SetCommState(handle, &dcb)))    {      close(fd);      return NULL;    }#endif  /* Serial port setting */  memset(&newtio, 0, sizeof(newtio));  newtio.c_cflag = CS8 | CLOCAL | CREAD;  newtio.c_iflag = IGNPAR | IGNBRK;  cfsetispeed(&newtio, baudflag);  cfsetospeed(&newtio, baudflag);  /* Raw output_file */  newtio.c_oflag = 0;  if (tcflush(fd, TCIFLUSH) >= 0 &&      tcsetattr(fd, TCSANOW, &newtio) >= 0)    {      serial_source src = malloc(sizeof *src);      if (src)	{	  memset(src, 0, sizeof src);	  src->fd = fd;	  src->non_blocking = non_blocking;	  src->message = message;	  src->send.seqno = 37;	  return src;	}    }  close(fd);  return NULL;}int serial_source_fd(serial_source src)/* Returns: the file descriptor used by serial source src (useful when     non-blocking reads were requested)*/{  return src->fd;}int close_serial_source(serial_source src)/* Effects: closes serial source src   Returns: 0 if successful, -1 if some problem occured (but source is     considered closed anyway) */{  int ok = close(src->fd);  free(src);  return ok;}static int source_wait(serial_source src, struct timeval *deadline)/* Effects: waits until deadline for some data on source. deadline     can be NULL for indefinite waiting.   Returns: 0 if data is available, -1 if the deadline expires*/{  struct timeval tv;  fd_set fds;  int cnt;  if (src->recv.bufpos < src->recv.bufused)    return 0;  for (;;)    {      if (deadline)	{	  gettimeofday(&tv, NULL);	  tv.tv_sec = deadline->tv_sec - tv.tv_sec;	  tv.tv_usec = deadline->tv_usec - tv.tv_usec;	  if (tv.tv_usec < 0)	    {	      tv.tv_usec += 1000000;	      tv.tv_sec--;	    }	  if (tv.tv_sec < 0)	    return -1;	}      FD_ZERO(&fds);      FD_SET(src->fd, &fds);      cnt = select(src->fd + 1, &fds, NULL, NULL, deadline ? &tv : NULL);      if (cnt < 0)	{	  if (errno == EINTR)	    continue;	  message(src, msg_unix_error);	  return -1;	}      if (cnt == 0)	return -1;      return 0;    }}static int source_write(serial_source src, const void *buffer, int count){  int actual = 0;  if (fcntl(src->fd, F_SETFL, 0) < 0)    {      message(src, msg_unix_error);      return -1;    }  while (count > 0)    {      int n = write(src->fd, buffer, count);      if (n < 0 && errno == EINTR)	continue;      if (n < 0)	{	  message(src, msg_unix_error);	  actual = -1;	  break;	}      count -= n;      actual += n;      buffer += n;    }  if (fcntl(src->fd, F_SETFL, O_NONBLOCK) < 0)    {      message(src, msg_unix_error);      /* We're in trouble, but there's no obvious fix. */    }  return actual;}static void push_protocol_packet(serial_source src,

⌨️ 快捷键说明

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