Exemplo n.º 1
0
void usb_cdc_ecm_rx(uint8_t ep, uint8_t stat) {
  int len;
  int ip_length;
  int i;
  uint16_t eth_hdr_type;

  //printf("cdc ecm rx ep-state=%x state=%d transferred=%d",stat,rndisRxState,rndisRxTransferCount);

  switch (rndisRxState) {
  case RNDIS_RX_IDLE:
    rndisRxTransferCount = 0;
    rndisRxPacketSize    = 0; /* it may increase later */
    /* hopefully, it follows the header immediately... */

    if (receive_packet == 0) {
      if (RING_IS_FULL(receive_ring_head, receive_ring_tail, RECEIVE_RING_SIZE)) {
        rndisRxState = RNDIS_RX_DROP;
        DBG("usb_eth_rx: receive ring is full, head=%d, tail=%d",receive_ring_head, receive_ring_tail);
        len = usbRead(ep, NULL, 64);
      } else {
        rndisRxState = RNDIS_RX_RECV;

        receive_packet = &receive_ring[receive_ring_tail];
        packet_init(receive_packet);

        len = usbRead(ep, receive_packet->data , 64);
        rndisRxTransferCount += len;
      }
    }
    break;

  case RNDIS_RX_DROP:
    len = usbRead(ep, NULL, 64);
    //ETH_DEV_DBG_INFO("rndis rx read %d bytes more in drop state",len);
    if (len >= 0) rndisRxTransferCount += len;
    break;

  case RNDIS_RX_RECV:
    len = usbRead(ep, (receive_packet->data) + rndisRxTransferCount, 64 /* maybe we need to limit this */);

    if (len >= 0) rndisRxTransferCount += len;
    break;
  }

  if (len < 64) { /* a short packet terminates the Ethernet frame */
    rndisRxPackets++;
    DBG("cdc ecm rx done with a packet (%d bytes)",rndisRxTransferCount);
    //for (i=0; i<rndisRxPacketSize; i++) DBG("%d %02x",i,(receive_packet->data)[i]);
    //if (rndisRxPacketSize==54) while(1);
    if (rndisRxState == RNDIS_RX_RECV) {
      receive_packet->size = rndisRxTransferCount;
      receive_packet = 0;
      RING_INC(receive_ring_tail, RECEIVE_RING_SIZE);
    }
    rndisRxState = RNDIS_RX_IDLE;
  }
}
Exemplo n.º 2
0
void usb_eth_rx(uint8_t ep, uint8_t stat)
{
  int len;
  int ip_length;
  uint16_t eth_hdr_type;

  if (receive_packet == 0) {
    if (RING_IS_FULL(receive_ring_head, receive_ring_tail, RECEIVE_RING_SIZE)) {
      ETH_DEV_DBG_ERROR("usb_eth_rx: receive ring is full, head=%d, tail=%d",
                        receive_ring_head, receive_ring_tail);
      return;
    }
    receive_packet = &receive_ring[receive_ring_tail];
    packet_init(receive_packet);
  }

  if (receive_packet->transferred < PACKET_SIZE) {
    len = usbRead(ep,
                  &receive_packet->data[0] + receive_packet->transferred,
                  PACKET_SIZE - receive_packet->transferred);
  }
  else {
    /* discard the bytes */
    len = usbRead(ep, 0, 0);
  }
  receive_packet->transferred += len;
  
  ETH_DEV_DBG_INFO("usb_eth_rx: read %d bytes, head=%d, tail=%d",
                   len,
                   receive_ring_head,
                   receive_ring_tail);

  if (receive_packet->transferred < UIP_LLH_LEN) {
    /* ethernet header was not received yet got some garbage which we need
     to ignore */
    ETH_DEV_DBG_ERROR("got part of packet with %d bytes", receive_packet->transferred);
    receive_packet->transferred = 0;
    return;
  }

  if (receive_packet->size == 0) {
    eth_hdr_type = (receive_packet->data[0xc] << 8) | receive_packet->data[0xd];
  
    if (eth_hdr_type == UIP_ETHTYPE_IP) {
      ip_length = receive_packet->data[0x10]*0xff + receive_packet->data[0x11];
      receive_packet->size = ip_length + UIP_LLH_LEN;
    }
    else if (eth_hdr_type == UIP_ETHTYPE_ARP) {
      receive_packet->size = receive_packet->transferred;
    }
    else {
      ETH_DEV_DBG_ERROR("Unknown ethernet frame 0x%x", eth_hdr_type);
      receive_packet->size = receive_packet->transferred;
    }
  }

  if (receive_packet->transferred >= receive_packet->size) {
    if (receive_packet->transferred >= receive_packet->size) {
      if (receive_packet->transferred >= PACKET_SIZE) {
        ETH_DEV_DBG_ERROR("Discarding packet of size %d", receive_packet->transferred);
        packet_init(receive_packet);
        receive_packet = 0;
      }
      else {
        ETH_DEV_DBG_INFO("Received packet of size %d", receive_packet->transferred);
        receive_packet = 0;
        RING_INC(receive_ring_tail, RECEIVE_RING_SIZE);
      }
    }
  }
}
Exemplo n.º 3
0
void usb_rndis_rx(uint8_t ep, uint8_t stat) {
  int len;
  int ip_length;
  int i;
  uint16_t eth_hdr_type;

  if (!(stat & EP_STATUS_DATA)) {
    ETH_DEV_DBG_ERROR("rndis rx, no data...");
    return;
  }

  //DBG("rndis rx ep-state=%x state=%d packetsize=%d transferred=%d",stat,rndisRxState,rndisRxPacketSize,rndisRxTransferCount);

  switch (rndisRxState) {
  case RNDIS_RX_IDLE:
  //if (rndisRxState == RNDIS_RX_IDLE) {
    len = usbRead(ep, rndisPacketHeader, 64);
    if (len==1 && rndisPacketHeader[0] == 0) {
      DBG("single byte USB packet (this is normal for rndis");
      return;
    }

    if (len < 44) {
      ETH_DEV_DBG_ERROR("Whoops, USB packet length shorter than RNDIS message header (only %d bytes)",len);
      return;
    }

    uint32_t type     = uint32FromLittleEndian(rndisPacketHeader);
    uint32_t rndislen = uint32FromLittleEndian(rndisPacketHeader+4);
    uint32_t dataoff  = uint32FromLittleEndian(rndisPacketHeader+8);
    uint32_t datalen  = uint32FromLittleEndian(rndisPacketHeader+12);
    uint32_t ooboff   = uint32FromLittleEndian(rndisPacketHeader+16);
    uint32_t ooblen   = uint32FromLittleEndian(rndisPacketHeader+20);
    uint32_t numoob   = uint32FromLittleEndian(rndisPacketHeader+24);
    uint32_t perpacket_infooff = uint32FromLittleEndian(rndisPacketHeader+28);
    uint32_t perpacket_infolen = uint32FromLittleEndian(rndisPacketHeader+32);

    //DBG("rndis rx type=%x len=%d dataoff=%d datalen=%d ooblen=%d numoob=%d perpacket_infooff=%d perpacket_infolen=%d",
    //    type,len,dataoff,datalen,ooblen,numoob,perpacket_infooff,perpacket_infolen);

    if (type != 1) while(1);

    rndisRxTransferCount = 0;
    rndisRxPacketSize    = datalen;
    /* hopefully, it follows the header immediately... */

    if (receive_packet == 0) {
      if (RING_IS_FULL(receive_ring_head, receive_ring_tail, RECEIVE_RING_SIZE)) {
        DBG("usb_eth_rx: receive ring is full, head=%d, tail=%d",receive_ring_head, receive_ring_tail);
        rndisRxState = RNDIS_RX_DROP;
        for (i=0; i<(len-44); i++) {
           rndisRxTransferCount++;
        }
      } else {
        rndisRxState = RNDIS_RX_RECV;
        receive_packet = &receive_ring[receive_ring_tail];
        packet_init(receive_packet);

        for (i=0; i<(len-44); i++) {
          (receive_packet->data)[ rndisRxTransferCount ] = rndisPacketHeader[44+i];
           rndisRxTransferCount++;
        }
      }
    }
    break;

  case RNDIS_RX_DROP:
  //if (rndisRxState == RNDIS_RX_DROP) {
    len = usbRead(ep, NULL, rndisRxPacketSize - rndisRxTransferCount);
    //ETH_DEV_DBG_INFO("rndis rx read %d bytes more in drop state",len);

    if (len >= 0)
      rndisRxTransferCount += len;
    break;
//  }

  case RNDIS_RX_RECV:
  //if (rndisRxState == RNDIS_RX_RECV) {
    //DBG("rndis rx recv read from endpoint");
    len = usbRead(ep, (receive_packet->data) + rndisRxTransferCount, rndisRxPacketSize - rndisRxTransferCount);
    //DBG("rndis rx read %d bytes more in recv state",len);

    if (len >= 0)
      rndisRxTransferCount += len;
    break;
  }

  if (rndisRxTransferCount == rndisRxPacketSize) {
    rndisRxPackets++;
    DBG("rndis rx done with a packet (%d bytes)",rndisRxPacketSize);
    //for (i=0; i<rndisRxPacketSize; i++) DBG("%d %02x",i,(receive_packet->data)[i]);
    //if (rndisRxPacketSize==54) while(1);
    if (rndisRxState == RNDIS_RX_RECV) {
      receive_packet->size = rndisRxPacketSize;
      receive_packet = 0;
      RING_INC(receive_ring_tail, RECEIVE_RING_SIZE);
      xxx = 1;
    }
    rndisRxState = RNDIS_RX_IDLE;
  }

}