/* The following code does: * receive address (2 bytes), add them to CRC * transmit anything from this address onwards until 0x8F is reached * send the 2 crc bytes. This is all very straightforward, except that the CRC calculation for the first byte to transmit is delayed somewhat: the time between recv_byte_in() and xmit_byte() is only a bit wide, which may not be enough time to add a CRC byte. */ void do_read_pio(void) { u_short crc = 0; u_short adr; u_char bcrc = 1; u_char b; recv_byte(); crc = crc16(crc,0xF0); b = recv_byte_in(); // address low byte recv_byte(); crc = crc16(crc, b); adr = b; b = recv_byte_in(); // address high byte adr |= b<<8; /* note: bcrc is only true for the first byte to transmit */ #define XMIT(val) do { \ xmit_byte(val); \ if(bcrc) { crc = crc16(crc, b); bcrc = 0; } \ crc = crc16(crc,val); \ } while(0) while(adr < 0x88) { XMIT(0); adr++; } switch(adr) { case 0x88: XMIT(pio_logic); case 0x89: XMIT(pio_output_latch); case 0x8A: XMIT(pio_activity_latch); case 0x8B: XMIT(cond_search_mask); case 0x8C: XMIT(cond_polarity_mask); case 0x8D: XMIT(control_status); case 0x8E: XMIT(0xFF); case 0x8F: XMIT(0xFF); crc = ~crc; xmit_byte(crc); xmit_byte(crc >> 8); default: while(1) XMIT(0xFF); } }
int NSCLASS dsr_ack_req_send(struct in_addr neigh_addr, unsigned short id) { struct dsr_pkt *dp; struct dsr_ack_req_opt *ack_req; int len = DSR_OPT_HDR_LEN + DSR_ACK_REQ_HDR_LEN; char *buf; dp = dsr_pkt_alloc(NULL); dp->dst = neigh_addr; dp->nxt_hop = neigh_addr; dp->src = my_addr(); buf = dsr_pkt_alloc_opts(dp, len); if (!buf) goto out_err; dp->nh.iph = dsr_build_ip(dp, dp->src, dp->dst, IP_HDR_LEN, IP_HDR_LEN + len, IPPROTO_DSR, 1); if (!dp->nh.iph) { LOG_DBG("Could not create IP header\n"); goto out_err; } dp->dh.opth = dsr_opt_hdr_add(buf, len, DSR_NO_NEXT_HDR_TYPE); if (!dp->dh.opth) { LOG_DBG("Could not create DSR opt header\n"); goto out_err; } buf += DSR_OPT_HDR_LEN; len -= DSR_OPT_HDR_LEN; ack_req = dsr_ack_req_opt_create(buf, len, id); if (!ack_req) { LOG_DBG("Could not create ACK REQ opt\n"); goto out_err; } LOG_DBG("Sending ACK REQ for %s id=%u\n", print_ip(neigh_addr), id); XMIT(dp); return 1; out_err: dsr_pkt_free(dp); return -1; }
void NSCLASS dsr_start_xmit(struct dsr_pkt *dp) { int res; if (!dp) { DEBUG("Could not allocate DSR packet\n"); return; } dp->srt = dsr_rtc_find(dp->src, dp->dst); if (dp->srt) { if (dsr_srt_add(dp) < 0) { DEBUG("Could not add source route\n"); goto out; } /* Send packet */ XMIT(dp); return; } else { res = send_buf_enqueue_packet(dp, &dsr_dev_xmit); if (res < 0) { DEBUG("Queueing failed!\n"); goto out; } res = dsr_rreq_route_discovery(dp->dst); if (res < 0) DEBUG("RREQ Transmission failed..."); return; } out: dsr_pkt_free(dp); }
int NSCLASS dsr_ack_send(struct in_addr dst, unsigned short id) { struct dsr_pkt *dp; struct dsr_ack_opt *ack_opt; int len; char *buf; /* srt = dsr_rtc_find(my_addr(), dst); */ /* if (!srt) { */ /* LOG_DBG("No source route to %s\n", print_ip(dst.s_addr)); */ /* return -1; */ /* } */ len = DSR_OPT_HDR_LEN + /* DSR_SRT_OPT_LEN(srt) + */ DSR_ACK_HDR_LEN; dp = dsr_pkt_alloc(NULL); dp->dst = dst; /* dp->srt = srt; */ dp->nxt_hop = dst; //dsr_srt_next_hop(dp->srt, 0); dp->src = my_addr(); buf = dsr_pkt_alloc_opts(dp, len); if (!buf) goto out_err; dp->nh.iph = dsr_build_ip(dp, dp->src, dp->dst, IP_HDR_LEN, IP_HDR_LEN + len, IPPROTO_DSR, IPDEFTTL); if (!dp->nh.iph) { LOG_DBG("Could not create IP header\n"); goto out_err; } dp->dh.opth = dsr_opt_hdr_add(buf, len, DSR_NO_NEXT_HDR_TYPE); if (!dp->dh.opth) { LOG_DBG("Could not create DSR opt header\n"); goto out_err; } buf += DSR_OPT_HDR_LEN; len -= DSR_OPT_HDR_LEN; /* dp->srt_opt = dsr_srt_opt_add(buf, len, dp->srt); */ /* if (!dp->srt_opt) { */ /* LOG_DBG("Could not create Source Route option header\n"); */ /* goto out_err; */ /* } */ /* buf += DSR_SRT_OPT_LEN(dp->srt); */ /* len -= DSR_SRT_OPT_LEN(dp->srt); */ ack_opt = dsr_ack_opt_add(buf, len, dp->src, dp->dst, id); if (!ack_opt) { LOG_DBG("Could not create DSR ACK opt header\n"); goto out_err; } LOG_DBG("Sending ACK to %s id=%u\n", print_ip(dst), id); dp->flags |= PKT_XMIT_JITTER; XMIT(dp); return 1; out_err: dsr_pkt_free(dp); return -1; }
int NSCLASS dsr_recv(struct dsr_pkt *dp) { int i = 0, action; int mask = DSR_PKT_NONE; /* Process DSR Options */ action = dsr_opt_recv(dp); /* Add mac address of previous hop to the neighbor table */ if (dp->flags & PKT_PROMISC_RECV) { dsr_pkt_free(dp); return 0; } for (i = 0; i < DSR_PKT_ACTION_LAST; i++) { switch (action & mask) { case DSR_PKT_NONE: break; case DSR_PKT_DROP: case DSR_PKT_ERROR: DEBUG("DSR_PKT_DROP or DSR_PKT_ERROR\n"); dsr_pkt_free(dp); return 0; case DSR_PKT_SEND_ACK: /* Moved to dsr-ack.c */ break; case DSR_PKT_SRT_REMOVE: //DEBUG("Remove source route\n"); // Hmm, we remove the DSR options when we deliver a //packet //dsr_opt_remove(dp); break; case DSR_PKT_FORWARD: if (dp->nh.iph->ttl < 1) { DEBUG("ttl=0, dropping!\n"); dsr_pkt_free(dp); return 0; } else { DEBUG("Forwarding %s %s nh %s\n", print_ip(dp->src), print_ip(dp->dst), print_ip(dp->nxt_hop)); XMIT(dp); return 0; } break; case DSR_PKT_FORWARD_RREQ: XMIT(dp); return 0; case DSR_PKT_SEND_RREP: /* In dsr-rrep.c */ break; case DSR_PKT_SEND_ICMP: DEBUG("Send ICMP\n"); break; case DSR_PKT_SEND_BUFFERED: if (dp->rrep_opt) { struct in_addr rrep_srt_dst; int i; for (i = 0; i < dp->num_rrep_opts; i++) { rrep_srt_dst.s_addr = dp->rrep_opt[i]->addrs[DSR_RREP_ADDRS_LEN(dp->rrep_opt[i]) / sizeof(struct in_addr)]; send_buf_set_verdict(SEND_BUF_SEND, rrep_srt_dst); } } break; case DSR_PKT_DELIVER: DEBUG("Deliver to DSR device\n"); DELIVER(dp); return 0; case 0: break; default: DEBUG("Unknown pkt action\n"); } mask = (mask << 1); } dsr_pkt_free(dp); return 0; }