/* Upper half does the polling. */ static uint16_t slip_poll_handler(uint8_t *outbuf, uint16_t blen) { /* This is a hack and won't work across buffer edge! */ if(rxbuf[begin] == 'C') { int i; if(begin < end && (end - begin) >= 6 && memcmp(&rxbuf[begin], "CLIENT", 6) == 0) { state = STATE_TWOPACKETS; /* Interrupts do nothing. */ memset(&rxbuf[begin], 0x0, 6); rxbuf_init(); for(i = 0; i < 13; i++) { slip_arch_writeb("CLIENTSERVER\300"[i]); } return 0; } } else if(rxbuf[begin] == '?') { int i, j; char* hexchar = "0123456789abcdef"; if(begin < end && (end - begin) >= 2 && rxbuf[begin + 1] == 'M') { state = STATE_TWOPACKETS; /* Interrupts do nothing. */ rxbuf[begin] = 0; rxbuf[begin + 1] = 0; rxbuf_init(); /* this is just a test so far... just to see if it works */ slip_arch_writeb('!'); slip_arch_writeb('M'); //MF #if 0 for(j = 0; j < 8; j++) { slip_arch_writeb(hexchar[ds2411_id[j] >> 4]); slip_arch_writeb(hexchar[ds2411_id[j] & 15]); } #else for(j = 0; j < 8; j++) { slip_arch_writeb(0); slip_arch_writeb(0); } #endif slip_arch_writeb(SLIP_END); return 0; }
/* Upper half does the polling. */ static uint16_t slip_poll_handler(uint8_t *outbuf, uint16_t blen) { /* This is a hack and won't work across buffer edge! */ if(rxbuf[begin] == 'C') { int i; if(begin < end && (end - begin) >= 6 && memcmp(&rxbuf[begin], "CLIENT", 6) == 0) { state = STATE_TWOPACKETS; /* Interrupts do nothing. */ memset(&rxbuf[begin], 0x0, 6); rxbuf_init(); for(i = 0; i < 13; i++) { slip_arch_writeb("CLIENTSERVER\300"[i]); } return 0; } } #ifdef SLIP_CONF_ANSWER_MAC_REQUEST else if(rxbuf[begin] == '?') { /* Used by tapslip6 to request mac for auto configure */ int i, j; char* hexchar = "0123456789abcdef"; if(begin < end && (end - begin) >= 2 && rxbuf[begin + 1] == 'M') { state = STATE_TWOPACKETS; /* Interrupts do nothing. */ rxbuf[begin] = 0; rxbuf[begin + 1] = 0; rxbuf_init(); rimeaddr_t addr = get_mac_addr(); /* this is just a test so far... just to see if it works */ slip_arch_writeb('!'); slip_arch_writeb('M'); for(j = 0; j < 8; j++) { slip_arch_writeb(hexchar[addr.u8[j] >> 4]); slip_arch_writeb(hexchar[addr.u8[j] & 15]); } slip_arch_writeb(SLIP_END); return 0; }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(slip_process, ev, data) { PROCESS_BEGIN(); rxbuf_init(); while(1) { PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); slip_active = 1; /* Move packet from rxbuf to buffer provided by uIP. */ uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN], UIP_BUFSIZE - UIP_LLH_LEN); #if !UIP_CONF_IPV6 if(uip_len == 4 && strncmp((char*)&uip_buf[UIP_LLH_LEN], "?IPA", 4) == 0) { char buf[8]; memcpy(&buf[0], "=IPA", 4); memcpy(&buf[4], &uip_hostaddr, 4); if(input_callback) { input_callback(); } slip_write(buf, 8); } else if(uip_len > 0 && uip_len == (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) && uip_ipchksum() == 0xffff) { #define IP_DF 0x40 if(BUF->ipid[0] == 0 && BUF->ipid[1] == 0 && BUF->ipoffset[0] & IP_DF) { static u16_t ip_id; u16_t nid = ip_id++; BUF->ipid[0] = nid >> 8; BUF->ipid[1] = nid; nid = uip_htons(nid); nid = ~nid; /* negate */ BUF->ipchksum += nid; /* add */ if(BUF->ipchksum < nid) { /* 1-complement overflow? */ BUF->ipchksum++; } } tcpip_input(); } else { uip_len = 0; SLIP_STATISTICS(slip_ip_drop++); } #else /* UIP_CONF_IPV6 */ if(uip_len > 0) { if(input_callback) { input_callback(); } tcpip_input(); } #endif /* UIP_CONF_IPV6 */ }
/* Upper half does the polling. */ static uint16_t slip_poll_handler(uint8_t *outbuf, uint16_t blen) { /* This is a hack and won't work across buffer edge! */ #if 0 if(rxbuf[begin] == 'C') { int i; if(begin < end && (end - begin) >= 6 && memcmp(&rxbuf[begin], "CLIENT", 6) == 0) { state = STATE_TWOPACKETS; /* Interrupts do nothing. */ memset(&rxbuf[begin], 0x0, 6); rxbuf_init(); for(i = 0; i < 13; i++) { slip_arch_writeb("CLIENTSERVER\300"[i]); } return 0; } } #endif if(rxbuf[begin] == '?' || rxbuf[begin] == '!') { // Should this characters be escaped? uint8_t tmpbuf[14]; from_slipbuffer(tmpbuf, 14); if(tmpbuf[0] == '?') { int j; char* hexchar = "0123456789abcdef"; if(tmpbuf[1] == 'M') { /* this is just a test so far... just to see if it works */ slip_arch_writeb('!'); slip_arch_writeb('M'); for(j = 0; j < LINKADDR_SIZE; j++) { slip_arch_writeb(hexchar[linkaddr_node_addr.u8[j] >> 4]); slip_arch_writeb(hexchar[linkaddr_node_addr.u8[j] & 15]); } slip_arch_writeb(SLIP_END); return 0; }
/* Upper half does the polling. */ static u16_t slip_poll_handler(u8_t *outbuf, u16_t blen) { /* This is a hack and won't work across buffer edge! */ if(rxbuf[begin] == 'C') { int i; if(begin < end && (end - begin) >= 6 && memcmp(&rxbuf[begin], "CLIENT", 6) == 0) { state = STATE_TWOPACKETS; /* Interrupts do nothing. */ memset(&rxbuf[begin], 0x0, 6); rxbuf_init(); for(i = 0; i < 13; i++) { slip_arch_writeb("CLIENTSERVER\300"[i]); } return 0; } } /* * Interrupt can not change begin but may change pkt_end. * If pkt_end != begin it will not change again. */ if(begin != pkt_end) { u16_t len; if(begin < pkt_end) { len = pkt_end - begin; if(len > blen) { len = 0; } else { memcpy(outbuf, &rxbuf[begin], len); } } else { len = (RX_BUFSIZE - begin) + (pkt_end - 0); if(len > blen) { len = 0; } else { unsigned i; for(i = begin; i < RX_BUFSIZE; i++) { *outbuf++ = rxbuf[i]; } for(i = 0; i < pkt_end; i++) { *outbuf++ = rxbuf[i]; } } } /* Remove data from buffer together with the copied packet. */ begin = pkt_end; if(state == STATE_TWOPACKETS) { pkt_end = end; state = STATE_OK; /* Assume no bytes where lost! */ /* One more packet is buffered, need to be polled again! */ process_poll(&slip_process); } return len; } return 0; }