Serial Line Internet Protocol (SLIP)As seguites funções em Linguagem C enviam e recebem pacotes SLIP. Elas são duas funções, send_char() e recv_char(), as quais enviam e recebem, respectivamente, um simples caracter sobre uma linha serial.
/*
SLIP special character codes
*/
#define END 0300 /* indicates end of packet */
#define ESC 0333 /* indicates byte stuffing */
#define ESC_END 0334 /* ESC ESC_END means END data byte */
#define ESC_ESC 0335 /* ESC ESC_ESC means ESC data byte */
/*
* SEND_PACKET: sends a packet of length "len", starting at
* location "p".
*/
void send_packet(p, len)
char *p;
int len;
{
/*
* send an initial END character to flush out any data that may
* have accumulated in the receiver due to line noise
*/
send_char(END);
/*
* for each byte in the packet, send the appropriate character
* sequence
*/
while (len--)
{
switch(*p)
{
/*
* if it's the same code as an END character, we send a
* special two character code so as not to make the
* receiver think we sent an END
*/
case END: send_char(ESC);
send_char(ESC_END);
break;
/*
* if it's the same code as an ESC character,
* we send a special two character code so as not
* to make the receiver think we sent an ESC
*/
case ESC: send_char(ESC);
send_char(ESC_ESC);
break;
/*
* otherwise, we just send the character
*/
default: send_char(*p);
}
p++;
}
/*
* tell the receiver that we're done sending the packet
*/
send_char(END);
}
/*
* RECV_PACKET: receives a packet into the buffer located at "p".
* If more than len bytes are received, the packet will
* be truncated.
* Returns the number of bytes stored in the buffer.
*/
int recv_packet(p, len)
char *p;
int len;
{
char c;
int received = 0;
/*
* sit in a loop reading bytes until we put together
* a whole packet.
* Make sure not to copy them into the packet if we
* run out of room.
*/
while(1)
{
/*
* get a character to process
*/
c = recv_char();
/*
* handle bytestuffing if necessary
*/
switch(c)
{
/*
* if it's an END character then we're done with
* the packet
*/
case END:/*
* a minor optimization: if there is no
* data in the packet, ignore it. This is
* meant to avoid bothering IP with all
* the empty packets generated by the
* duplicate END characters which are in
* turn sent to try to detect line noise.
*/
if (received)
return received;
else
break;
/*
* if it's the same code as an ESC character, wait
* and get another character and then figure out
* what to store in the packet based on that.
*/
case ESC: c = recv_char();
/*
* if "c" is not one of these two, then we
* have a protocol violation. The best bet
* seems to be to leave the byte alone and
* just stuff it into the packet
*/
switch(c)
{
case ESC_END: c = END;
break;
case ESC_ESC: c = ESC;
break;
}
/*
* here we fall into the default handler and let
* it store the character for us
*/
default: if (received < len)
p[received++] = c;
}
}
}