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

📄 sf.c

📁 无线通信的主要编程软件,是无线通信工作人员的必备工具,关天相关教程我会在后续传上.
💻 C
字号:
#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <errno.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <signal.h>#include "sfsource.h"#include "serialsource.h"#include "platform.h"serial_source src;int server_socket;int packets_read, packets_written, num_clients;struct client_list{  struct client_list *next;  int fd;} *clients;int unix_check(const char *msg, int result){  if (result < 0)    {      perror(msg);      exit(2);    }  return result;}void *xmalloc(size_t s){  void *p = malloc(s);  if (!p)    {      fprintf(stderr, "out of memory\n");      exit(2);    }  return p;}void fd_wait(fd_set *fds, int *maxfd, int fd){  if (fd > *maxfd)    *maxfd = fd;  FD_SET(fd, fds);}void pstatus(void){  printf("clients %d, read %d, wrote %d\n", num_clients, packets_read,	 packets_written);}void forward_packet(const void *packet, int len);void add_client(int fd){  struct client_list *c = xmalloc(sizeof *c);  c->next = clients;  clients = c;  num_clients++;  pstatus();  c->fd = fd;}void rem_client(struct client_list **c){  struct client_list *dead = *c;  *c = dead->next;  num_clients--;  pstatus();  close(dead->fd);  free(dead);}void new_client(int fd){  if (init_sf_source(fd) < 0)    close(fd);  else    add_client(fd);}void check_clients(fd_set *fds){  struct client_list **c;  for (c = &clients; *c; )    {      int next = 1;      if (FD_ISSET((*c)->fd, fds))	{	  int len;	  const void *packet = read_sf_packet((*c)->fd, &len);	  if (packet)	    {	      forward_packet(packet, len);	      free((void *)packet);	    }	  else	    {	      rem_client(c);	      next = 0;	    }	}      if (next)	c = &(*c)->next;    }}void wait_clients(fd_set *fds, int *maxfd){  struct client_list *c;  for (c = clients; c; c = c->next)    fd_wait(fds, maxfd, c->fd);}void dispatch_packet(const void *packet, int len){  struct client_list **c;  for (c = &clients; *c; )    if (write_sf_packet((*c)->fd, packet, len) >= 0)      c = &(*c)->next;    else      rem_client(c);}void open_server_socket(int port){  struct sockaddr_in me;  int opt;  server_socket = unix_check("socket", socket(AF_INET, SOCK_STREAM, 0));  unix_check("socket", fcntl(server_socket, F_SETFL, O_NONBLOCK));  memset(&me, 0, sizeof me);  me.sin_family = AF_INET;  me.sin_port = htons(port);  opt = 1;  unix_check("setsockopt", setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR,				     (char *)&opt, sizeof(opt)));                                                                             unix_check("bind", bind(server_socket, (struct sockaddr *)&me, sizeof me));  unix_check("listen", listen(server_socket, 5));}void check_new_client(void){  int clientfd = accept(server_socket, NULL, NULL);  if (clientfd >= 0)    new_client(clientfd);}void stderr_msg(serial_source_msg problem){  static char *msgs[] = {    "unknown_packet_type",    "ack_timeout"	,    "sync"	,    "too_long"	,    "too_short"	,    "bad_sync"	,    "bad_crc"	,    "closed"	,    "no_memory"	,    "unix_error"  };  fprintf(stderr, "Note: %s\n", msgs[problem]);}void open_serial(const char *dev, int baud){    char ldev[80]; #ifdef __CYGWIN__    int portnum;    if (strncasecmp(dev, "COM", 3) == 0)      {	fprintf(stderr, "Warning: you're attempting to open a Windows rather that a Cygwin device.  Retrying with "); 	portnum=atoi(dev+3);	sprintf(ldev, "/dev/ttyS%d",portnum-1);	fprintf(stderr,ldev);	fprintf(stderr, "\n");      }     else#endif    strcpy(ldev, dev);   src = open_serial_source(ldev, baud, 1, stderr_msg);  if (!src)    {      fprintf(stderr, "Couldn't open serial port at %s:%d\n", dev, baud);      exit(1);    }}void check_serial(void){  int len;  const unsigned char *packet = read_serial_packet(src, &len);  if (packet)    {      packets_read++;      dispatch_packet(packet, len);      free((void *)packet);    }}void forward_packet(const void *packet, int len){  int ok = write_serial_packet(src, packet, len);  packets_written++;  if (ok < 0)    exit(2);  if (ok > 0)    fprintf(stderr, "Note: write failed\n");}int parsePlatform(char *platformName) {  int platformGuess = AVRMOTE;  if (strcasecmp(platformName, "mica2dot") == 0)    platformGuess = AVRMOTE;  else if (strcasecmp(platformName, "mica2") == 0)    platformGuess = AVRMOTE;  else if (strcasecmp(platformName, "mica") == 0)    platformGuess = AVRMOTE;  else if (strcasecmp(platformName, "telos") == 0)    platformGuess = TELOS;  else if (strcasecmp(platformName, "micaz") == 0)    platformGuess = MICAZ;  return platformGuess;}int main(int argc, char **argv){  int serfd;  if (argc != 5)    {      fprintf(stderr, "Usage: %s <port> <device> <rate> <platform> - act as a serial forwarder on <port>\n  (listens to serial port <device> at baud rate <rate>)\n assume that device connected to the serial port is a <platform> mote\nValid platforms: mica, mica2, mica2dot, avrmote, telos\n ", argv[0]);      exit(2);    }  if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)    fprintf(stderr, "Warning: failed to ignore SIGPIPE.\n");  open_serial(argv[2], atoi(argv[3]));  serfd = serial_source_fd(src);  open_server_socket(atoi(argv[1]));  platform = parsePlatform(argv[4]);  for (;;)    {      fd_set rfds;      int maxfd = -1;      struct timeval zero;      int serial_empty;      int ret;      zero.tv_sec = zero.tv_usec = 0;      FD_ZERO(&rfds);      fd_wait(&rfds, &maxfd, serfd);      fd_wait(&rfds, &maxfd, server_socket);      wait_clients(&rfds, &maxfd);      serial_empty = serial_source_empty(src);      if (serial_empty)	ret = select(maxfd + 1, &rfds, NULL, NULL, NULL);      else	{	  ret = select(maxfd + 1, &rfds, NULL, NULL, &zero);	  check_serial();	}      if (ret >= 0)	{	  if (FD_ISSET(serfd, &rfds))	    check_serial();	  if (FD_ISSET(server_socket, &rfds))	    check_new_client();	  check_clients(&rfds);	}    }}

⌨️ 快捷键说明

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