commit 7a49f811b1ed121c35c05673abdbd6ea64ed2c06 Author: Christian Vogel Date: Tue Apr 13 21:34:42 2010 +0200 Add CRC16 to HDLC frames. diff --git a/src/target/firmware/comm/sercomm.c b/src/target/firmware/comm/sercomm.c index b6bda50..b952a9c 100644 --- a/src/target/firmware/comm/sercomm.c +++ b/src/target/firmware/comm/sercomm.c @@ -25,6 +25,7 @@ #include #include +#include #ifdef HOST_BUILD #define SERCOMM_RX_MSG_SIZE 2048 @@ -63,6 +64,7 @@ static struct { struct llist_head dlci_queues[_SC_DLCI_MAX]; struct msgb *msg; enum rx_state state; + uint16_t crc16_dlci_mask; /* set 1<data+2,msg->len-2); + msgb_put_u16(msg,crc16_data); // put MSB, then LSB + hdr[1] |= HDLC_C_CRC16_BIT; + } + /* This functiion can be called from any context: FIQ, IRQ * and supervisor context. Proper locking is important! */ local_irq_save(flags); @@ -212,6 +233,42 @@ static void dispatch_rx_msg(uint8_t dlci, struct msgb *msg) sercomm.rx.dlci_handler[dlci](dlci, msg); } +/* check if crc16 of message msg is valid: If it is, strip + the two crc16 bytes and return 0, if it's invalid return 1 */ +static int sercomm_chk_strip_crc16(struct msgb *msg) +{ + uint16_t crc16_msg,crc16_data; + if(msg->len < 2) // too short to contain a crc16 + return 1; + + msg->len -= 2; /* this does the opposite of msgb_put(msg,2) */ + msg->tail -= 2; /* to trim the crc in the last two bytes */ + + crc16_data = osmocore_crc16(0,msg->data,msg->len); + crc16_msg = (msg->data[msg->len]<<8) + msg->data[msg->len+1]; + +#ifdef HOST_BUILD + if(crc16_msg != crc16_data){ + fprintf(stderr,"\r\033[0;31mBAD CRC\033[0m"); + fprintf(stderr," on dlci %d: recv %04x calc %04x\n", + sercomm.rx.dlci,crc16_msg,crc16_data); + } +#endif + + if(crc16_msg != crc16_data) // crc error + return 1; + + return 0; +} + +void +sercomm_tx_set_crc16(int dlci,int onoff){ + if(onoff) + sercomm.tx.crc16_dlci_mask |= (1<