/*---------------------------------------------------------------------------*/ static void packet_input(void) { LOG6LBR_PRINTF(PACKET, RADIO_IN, "read: %d\n", packetbuf_datalen()); if (LOG6LBR_COND(DUMP, RADIO_IN)) { uint8_t *data = packetbuf_dataptr(); int len = packetbuf_datalen(); int i; #if WIRESHARK_IMPORT_FORMAT printf("0000"); for(i = 0; i < len; i++) printf(" %02x", data[i]); #else printf(" "); for(i = 0; i < len; i++) { printf("%02x", data[i]); if((i & 3) == 3) printf(" "); if((i & 15) == 15) printf("\n "); } #endif printf("\n"); } if(NETSTACK_FRAMER.parse() < 0) { LOG6LBR_ERROR("br-rdc: failed to parse %u\n", packetbuf_datalen()); } else { NETSTACK_MAC.input(); } }
/*---------------------------------------------------------------------------*/ static void write_to_serial(int outfd, const uint8_t * inbuf, int len) { const uint8_t *p = inbuf; int i; slip_message_sent++; LOG6LBR_PRINTF(PACKET, SLIP_OUT, "write: %d\n", len); if (LOG6LBR_COND(DUMP, SLIP_OUT)) { printf(" "); for(i = 0; i < len; i++) { printf("%02x", p[i]); if((i & 3) == 3) printf(" "); if((i & 15) == 15) printf("\n "); } printf("\n"); } /* It would be ``nice'' to send a SLIP_END here but it's not * really necessary. */ /* slip_send(outfd, SLIP_END); */ for(i = 0; i < len; i++) { switch (p[i]) { case SLIP_END: slip_send(outfd, SLIP_ESC); slip_send(outfd, SLIP_ESC_END); break; case SLIP_ESC: slip_send(outfd, SLIP_ESC); slip_send(outfd, SLIP_ESC_ESC); break; default: slip_send(outfd, p[i]); break; } } slip_send(outfd, SLIP_END); PROGRESS("t"); }
/*---------------------------------------------------------------------------*/ static void send_packet(mac_callback_t sent, void *ptr) { int size; /* 3 bytes per packet attribute is required for serialization */ uint8_t buf[PACKETBUF_NUM_ATTRS * 3 + PACKETBUF_SIZE + 3]; uint8_t sid; packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &rimeaddr_node_addr); /* ack or not ? */ packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); if(NETSTACK_FRAMER.create() < 0) { /* Failed to allocate space for headers */ LOG6LBR_ERROR("br-rdc: send failed, too large header\n"); mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1); } else { /* here we send the data over SLIP to the radio-chip */ size = 0; #if SERIALIZE_ATTRIBUTES size = packetutils_serialize_atts(&buf[3], sizeof(buf) - 3); #endif if(size < 0 || size + packetbuf_totlen() + 3 > sizeof(buf)) { LOG6LBR_ERROR("br-rdc: send failed, too large header\n"); mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1); } else { LOG6LBR_PRINTF(PACKET, RADIO_OUT, "write: %d\n", packetbuf_datalen()); if (LOG6LBR_COND(DUMP, RADIO_OUT)) { uint8_t *data = packetbuf_dataptr(); int len = packetbuf_datalen(); int i; #if WIRESHARK_IMPORT_FORMAT printf("0000"); for(i = 0; i < len; i++) printf(" %02x", data[i]); #else printf(" "); for(i = 0; i < len; i++) { printf("%02x", data[i]); if((i & 3) == 3) printf(" "); if((i & 15) == 15) printf("\n "); } #endif printf("\n"); } sid = setup_callback(sent, ptr); buf[0] = '!'; buf[1] = 'S'; buf[2] = sid; /* sequence or session number for this packet */ /* Copy packet data */ memcpy(&buf[3 + size], packetbuf_hdrptr(), packetbuf_totlen()); write_to_slip(buf, packetbuf_totlen() + size + 3); } } }
/* * Read from serial, when we have a packet call slip_packet_input. No output * buffering, input buffered by stdio. */ void serial_input(FILE * inslip) { static unsigned char inbuf[2048]; static int inbufptr = 0; int ret, i; unsigned char c; #ifdef linux ret = fread(&c, 1, 1, inslip); if(ret == -1 || ret == 0) { LOG6LBR_FATAL("read() : %s\n", strerror(errno)); exit(1); } goto after_fread; #endif read_more: if(inbufptr >= sizeof(inbuf)) { LOG6LBR_ERROR("*** dropping large %d byte packet\n", inbufptr); inbufptr = 0; } ret = fread(&c, 1, 1, inslip); #ifdef linux after_fread: #endif if(ret == -1) { LOG6LBR_FATAL("read() : %s\n", strerror(errno)); exit(1); } if(ret == 0) { clearerr(inslip); return; } slip_received++; switch (c) { case SLIP_END: if(inbufptr > 0) { slip_message_received++; LOG6LBR_PRINTF(PACKET, SLIP_IN, "read: %d\n", inbufptr); if (LOG6LBR_COND(DUMP, SLIP_IN)) { printf(" "); for(i = 0; i < inbufptr; i++) { printf("%02x", inbuf[i]); if((i & 3) == 3) printf(" "); if((i & 15) == 15) printf("\n "); } printf("\n"); } if(inbuf[0] == '!') { command_context = CMD_CONTEXT_RADIO; cmd_input(inbuf, inbufptr); } else if(inbuf[0] == '?') { } else if(inbuf[0] == DEBUG_LINE_MARKER) { LOG6LBR_WRITE(INFO, SLIP_DBG, inbuf + 1, inbufptr - 1); } else if(inbuf[0] == 'E' && is_sensible_string(inbuf, inbufptr) ) { LOG6LBR_WRITE(ERROR, GLOBAL, inbuf + 1, inbufptr - 1); LOG6LBR_APPEND(ERROR, GLOBAL, "\n"); } else if(is_sensible_string(inbuf, inbufptr)) { LOG6LBR_WRITE(INFO, SLIP_DBG, inbuf, inbufptr); } else { slip_packet_input(inbuf, inbufptr); } inbufptr = 0; } break; case SLIP_ESC: if(fread(&c, 1, 1, inslip) != 1) { clearerr(inslip); /* Put ESC back and give up! */ ungetc(SLIP_ESC, inslip); return; } switch (c) { case SLIP_ESC_END: c = SLIP_END; break; case SLIP_ESC_ESC: c = SLIP_ESC; break; } /* FALLTHROUGH */ default: inbuf[inbufptr++] = c; break; } goto read_more; }