📄 bim.cc
字号:
/* * bim.{cc,hh} -- element reads and writes packets to/from * ABACOM BIM-4xx-RS232 radios * Robert Morris * * Copyright (c) 1999-2000 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */#include <click/config.h>#include "bim.hh"#include <click/error.hh>#include <click/packet.hh>#include <click/confparse.hh>#include <click/glue.hh>#include "bim-proto.hh"#include <click/standard/scheduleinfo.hh>#include <unistd.h>#include <termios.h>#include <fcntl.h>#include <sys/ioctl.h>CLICK_DECLSBIM::BIM() : Element(1, 1), _task(this){ _speed = 9600; _fd = -1; _len = _started = _escaped = 0;}BIM::~BIM(){ if(_fd >= 0) close(_fd);}intBIM::configure(Vector<String> &conf, ErrorHandler *errh){ if (cp_va_parse(conf, this, errh, cpString, "device name", &_dev, cpOptional, cpInteger, "baud rate", &_speed, cpEnd) < 0) return -1; if(_speed == 4800) _speed = B4800; else if(_speed == 9600) _speed = B9600; else if(_speed == 19200) _speed = B19200; else if(_speed == 38400) _speed = B38400; else { return errh->error("bad speed %d", _speed); } return 0;}intBIM::initialize(ErrorHandler *errh){ if (_fd >= 0) return 0; else if (!_dev) return errh->error("device name not set"); char *dname = _dev.mutable_c_str(); _fd = open(dname, O_RDWR|O_NONBLOCK, 0); if(_fd < 0) return errh->error("%s: %s", dname, strerror(errno)); ioctl(_fd, TIOCEXCL, 0); struct termios t; if(tcgetattr(_fd, &t) < 0) return errh->error("bad tcgetattr"); t.c_iflag = IGNBRK; t.c_oflag = 0; t.c_cflag = CS8|CREAD|HUPCL|CLOCAL; t.c_lflag = 0; cfsetispeed(&t, _speed); cfsetospeed(&t, _speed); if(tcsetattr(_fd, TCSANOW, &t) < 0) return errh->error("can't set terminal characteristics");#ifdef FIONBIO int yes = 1; if(ioctl(_fd, FIONBIO, &yes) < 0) return errh->error("can't set non-blocking IO");#else return errh->error("not configured for non-blocking IO");#endif#ifdef TCIOFLUSH tcflush(_fd, TCIOFLUSH);#elif defined(TIOCFLUSH) tcflush(_fd, TIOCFLUSH);#else return errh->error("this architecture has no TIOCFLUSH");#endif ScheduleInfo::join_scheduler(this, &_task, errh); add_select(_fd, SELECT_READ | SELECT_WRITE); return 0;}voidBIM::selected(int fd){ int cc, i; char b[128]; if (fd != _fd) return; cc = read(_fd, b, sizeof(b)); for(i = 0; i < cc; i++) got_char(b[i] & 0xff);}voidBIM::got_char(int c){ if(_started == 0 && _escaped == 0 && c == BIM_ESC){ _escaped = 1; } else if(_escaped && c == BIM_ESC_START){ _escaped = 0; _started = 1; _len = 0; } else if(_started && !_escaped && c == BIM_ESC){ _escaped = 1; } else if(_started && _escaped && c == BIM_ESC_END){ Packet *p = Packet::make(_buf, _len); output(0).push(p); _escaped = _started = _len = 0; } else if(_started && _escaped && c == BIM_ESC_ESC){ _buf[_len++] = BIM_ESC; _escaped = 0; } else if(_started && !_escaped && c != BIM_ESC){ _buf[_len++] = c; } else if(_started || _escaped){ fprintf(stderr, "bim: framing error, st %d es %d _len %d c %02x\n", _started, _escaped, _len, c); _started = _escaped = _len = 0; } if(_len > 1024){ fprintf(stderr, "bim: incoming packet too large\n"); _len = _started = 0; }}boolBIM::run_task(){ Packet *p = input(0).pull(); if (p) push(0, p); _task.fast_reschedule(); return p != 0;}voidBIM::push(int, Packet *p){ send_packet(p->data(), p->length()); p->kill();}voidBIM::send_packet(const unsigned char buf[], unsigned int len){ unsigned int i, j; char big[2048]; if(len > 1024){ fprintf(stderr, "bim: packet too large\n"); return; } j = 0; for(i = 0; i < 13; i++){ big[j++] = 'U'; /* preamble 01010101 */ } big[j++] = 0xff; /* sync */ big[j++] = BIM_ESC; big[j++] = BIM_ESC_START; for(i = 0; i < len; i++){ int c = buf[i] & 0xff; if(c == BIM_ESC){ big[j++] = BIM_ESC; big[j++] = BIM_ESC_ESC; } else { big[j++] = c; } } big[j++] = BIM_ESC; big[j++] = BIM_ESC_END; if(write(_fd, big, j) != (int) j){ perror("bim: write rs232"); }#if 0 { FILE *fp = fopen("foo", "a"); if(fp){ double a = 0.5; int by, bi; for(by = 0; by < j; by++){ for(bi = 0; bi < 8; bi++){ int bit = (big[by] >> bi) & 1; a = (a * 0.9) + (bit * 0.1); fprintf(fp, "%.5f\n", a); } } fprintf(fp, "\n"); fclose(fp); } }#endif}CLICK_ENDDECLSEXPORT_ELEMENT(BIM)ELEMENT_REQUIRES(userlevel)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -