43 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
54 stringRep.
add(
Link::LINK_TYPE_UNKNOWN,
N_("Unknown"));
59Link::
Link(const
char *fname,
int baud,
NCP *_ncp,
unsigned short _verbose, const
int cancellationFd)
69 linkType = LINK_TYPE_UNKNOWN;
70 for (
int i = 0; i < 256; i++)
76 p =
new packet(fname, baud,
this, _verbose, cancellationFd);
78 pthread_mutex_init(&queueMutex, NULL);
97 return ((
unsigned long)
getSpeed() * 1000 / 13200) + 200;
109 for (
int i = 0; i < 256; i++)
132 if (buff.
getLen() > 300) {
151 vector<ackWaitQueueElement>::iterator i;
153 if (i->data.getByte(0) ==
channel) {
157 vector<bufferStore>::iterator j;
159 if (j->getByte(0) ==
channel) {
173 lout <<
"Link: >> ack seq=" << seq << endl;
176 int lseq = (seq & 7) | 8;
177 seq = (hseq << 8) + lseq;
191 lout <<
"Link: >> con seq=4" << endl;
196 gettimeofday(&e.
stamp, NULL);
212 lout <<
"Link: >> con seq=1" << endl;
216 gettimeofday(&e.
stamp, NULL);
232 lout <<
"Link: >> con seq=1" << endl;
244 vector<ackWaitQueueElement>::iterator i;
248 int seq = type & 0x0f;
255 seq = (tseq << 3) + (seq & 0x07);
263 lout <<
"Link: << dat seq=" << seq ;
265 lout <<
" " << buff << endl;
282 lout <<
"Link: got XOFF for channel "
289 lout <<
"Link: got XON for channel "
303 lout <<
"Link: DUP\n";
311 struct timeval refstamp;
319 lout <<
"Link: << ack seq=" << seq ;
354 gettimeofday(&now, NULL);
355 bool nextFound =
false;
357 if (i->seq == seq+1) {
359 if (i->txcount-- == 0) {
362 lout <<
"Link: >> TRANSMIT timeout seq=" <<
370 lout <<
"Link: >> RETRANSMIT seq=" << i->seq
378 lout <<
"Link: << UNMATCHED ack seq=" << seq;
393 if ((i->seq == 0) && (i->data.getByte(0) == 0x21)) {
406 lout <<
"Link: << con seq=" << seq ;
421 lout <<
"Link: << req seq=" << seq;
458 lout <<
"Link: << DISC" << endl;
463 lerr <<
"Link: FATAL: Unknown packet type " << type << endl;
470 vector<bufferStore> tmpQueue;
471 vector<bufferStore>::iterator i;
476 if (i->getByte(0) ==
channel) {
477 tmpQueue.push_back(*i);
484 for (i = tmpQueue.begin(); i != tmpQueue.end(); i++)
491 vector<bufferStore> tmpQueue;
492 vector<bufferStore>::iterator i;
496 tmpQueue.push_back(*i);
500 for (i = tmpQueue.begin(); i != tmpQueue.end(); i++)
510 int remoteChan = buf.
getByte(0);
511 if (
xoff[remoteChan]) {
530 gettimeofday(&e.
stamp, NULL);
536 lout <<
"Link: >> req seq=" << e.
seq << endl;
541 lout <<
"Link: >> dat seq=" << e.
seq;
547 int hseq = e.
seq >> 3;
548 int lseq = 0x30 + ((e.
seq & 7) | 8);
549 int seq = (hseq << 8) + lseq;
563timesub(
struct timeval *tv,
unsigned long millisecs)
565 uint64_t micros = tv->tv_sec;
566 uint64_t sub = millisecs;
569 micros += tv->tv_usec;
570 micros -= (sub * 1000);
571 tv->tv_usec = micros & 0xffffffff;
572 tv->tv_sec = (micros >>= 32) & 0xffffffff;
578 uint64_t m1 = t1.tv_sec;
579 uint64_t m2 = t2.tv_sec;
590 vector<ackWaitQueueElement>::iterator i;
610 vector<ackWaitQueueElement>::iterator i;
612 gettimeofday(&now, NULL);
613 struct timeval expired = now;
617 if (i->txcount-- == 0) {
620 lout <<
"Link: >> TRANSMIT timeout seq=" << i->seq << endl;
628 lout <<
"Link: >> RETRANSMIT seq=" << i->seq << endl;
653 lout <<
"Link: hasFailed: " <<
failed <<
", " << lfailed << endl;
#define ENUM_DEFINITION_END(EnumName)
#define ENUM_DEFINITION_BEGIN(EnumName, initWith)
Helper macro to construct an enumeration wrapper Enum<E> for a specific enum type.
Wrapper class featuring range-checking and string representation of enumerated values.
void reset()
Reset connection and attempt to reconnect to the peer.
std::vector< bufferStore > waitQueue
unsigned short getVerbose()
Get current verbosity of Link.
void transmit(bufferStore buf)
std::vector< ackWaitQueueElement > ackWaitQueue
void flush()
Wait, until all outstanding packets are acknowledged or timed out.
void send(const bufferStore &buff)
Send a PLP packet to the Peer.
Enum< link_type > linkType
pthread_mutex_t queueMutex
~Link()
Disconnects from device and destroys instance.
Enum< link_type > getLinkType()
Get the current link type.
void purgeQueue(int channel)
Purge all outstanding packets for a specified remote channel.
int getSpeed()
Get current speed of the serial device.
void receive(bufferStore buf)
Effectively a delegate method that accepts data from our packet instance.
void transmitHoldQueue(int channel)
void multiAck(struct timeval)
bool hasFailed()
Query connection failure.
std::vector< bufferStore > holdQueue
unsigned long retransTimeout()
void setVerbose(unsigned short _verbose)
Set verbosity of Link and underlying packet instance.
bool stuffToSend()
Query outstanding packets.
void receive(bufferStore s)
A generic container for an array of bytes.
void discardFirstBytes(int len=0)
Removes bytes from the start of the buffer.
void addByte(unsigned char c)
Appends a byte to the content of this instance.
void prependByte(unsigned char c)
Prepends a byte to the content of this instance.
void prependWord(int w)
Prepends a word to the content of this instance.
bool empty() const
Tests if the bufferStore is empty.
void addDWord(long dw)
Appends a dword to the content of this instance.
unsigned long getLen() const
Retrieves the length of a bufferStore.
unsigned char getByte(long pos=0) const
Retrieves the byte at index pos.
void send(bufferStore &b)
Send a buffer out to serial line.
void setVerbose(short int)
stringRep add(Link::LINK_TYPE_UNKNOWN, N_("Unknown"))
static bool olderthan(struct timeval t1, struct timeval t2)
static void timesub(struct timeval *tv, unsigned long millisecs)
static void * expire_check(void *arg)
Describes a transmitted packet which has not yet been acknowledged by the peer.
struct timeval stamp
Time of last transmit.
int seq
Original sequence number.
bufferStore data
Packet content.
int txcount
Number of remaining transmit retries.