硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1030|回复: 4
收起左侧

RL-USB的RNDIS虚拟网口接口文件版本备份

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106828
QQ
发表于 2020-7-4 13:41:25 | 显示全部楼层 |阅读模式
最近这个文件根据比较频繁,得备份下,方便以后测试各个版本时需要:

V1.0.0:

  1. /*------------------------------------------------------------------------------
  2. * MDK Middleware - Component ::USB:Device
  3. * Copyright (c) 2018 ARM Germany GmbH. All rights reserved.
  4. *------------------------------------------------------------------------------
  5. * Name:    USBD_User_CDC_ACM_RNDIS_VETH_%Instance%.c
  6. * Purpose: USB Device Communication Device Class (CDC)
  7. *          Abstract Control Model (ACM)
  8. *          Remote Network Driver Interface Specification (RNDIS)
  9. *          User Module for a Virtual Ethernet
  10. * Rev.:    V1.0.0
  11. *----------------------------------------------------------------------------*/
  12. /**
  13. * \addtogroup usbd_cdcFunctions
  14. *
  15. * USBD_User_CDC_ACM_RNDIS_VETH_%Instance%.c implements the application specific
  16. * functionality of the CDC ACM class using RNDIS protocol and is used
  17. * to implement Network Interface Card (NIC) to the USB Host.
  18. * This user module works together with EMAC_CDC_ACM_RNDIS.c driver
  19. * to provide USB Host network access to Embedded Device over USB.
  20. *
  21. * The implementation depends on the configuration file USBD_Config_CDC_%Instance%.h.
  22. *
  23. */


  24. //! [code_USBD_User_CDC_ACM_RNDIS_VETH]

  25. #include <stdint.h>
  26. #include <stdbool.h>
  27. #include <string.h>

  28. #include "rl_usb.h"

  29. #include "Driver_ETH.h"
  30. #include "Driver_ETH_MAC.h"
  31. #include "Driver_ETH_PHY.h"
  32. #include "RTE/USB/USBD_Config_CDC_%Instance%.h"


  33. //-------- <<< Use Configuration Wizard in Context Menu >>> --------------------

  34. // Configuration defines

  35. //   <s.17>MAC Address
  36. //     <i>Ethernet MAC Address in text representation
  37. //     <i>Value FF-FF-FF-FF-FF-FF is not allowed,
  38. //     <i>LSB of first byte must be 0 (an ethernet Multicast bit).
  39. //     <i>Default: "1E-30-6C-A2-45-5E"
  40. #define RNDIS_MAC_ADDR    "1E-30-6C-A2-45-5E"           // RNDIS MAC Address

  41. //   <o.0..5>Maximum number of multicast addresses <1-32>
  42. #define RNDIS_MCAST_NUM   16                            // RNDIS Number of Multicast Addresses supported

  43. //   <s.32>RNDIS Vendor Description
  44. #define RNDIS_VENDOR_DESC "Keil NIC (USB <-> ETH)"      // RNDIS Vendor Description

  45. //   <o.0..23>RNDIS Vendor Id Code <0x000000-0xFFFFFF>
  46. #define RNDIS_VENDOR_ID   0xFFFFFF                      // RNDIS three-byte IEEE-registered Vendor Code

  47. //------------- <<< end of configuration section >>> ---------------------------


  48. // Global functions exported by this module
  49.        ARM_ETH_LINK_STATE RNDIS%Instance%_GetLinkState  (void);
  50.        int32_t            RNDIS%Instance%_SendFrame     (const uint8_t *frame, uint32_t len);
  51.        int32_t            RNDIS%Instance%_ReadFrame     (      uint8_t *frame, uint32_t len);
  52.        uint32_t           RNDIS%Instance%_GetRxFrameSize(void);

  53. // Local functions
  54. static void               MAC_str_to_addr (const char *mac_str, uint8_t *mac_addr);
  55. static void               InitVars        (void);
  56. static void               ResetVars       (void);

  57. // Local variables
  58. static uint32_t           rndis_state;
  59. static ARM_ETH_LINK_STATE link_state;

  60. static bool               link_state_up;
  61. static bool               link_state_down;

  62. static uint32_t           packet_filter;
  63. static ARM_ETH_MAC_ADDR   mac_address;
  64. static ARM_ETH_MAC_ADDR   mcast_address[RNDIS_MCAST_NUM];

  65. static uint16_t           get_encapsulated_response_len;
  66. static uint32_t           get_encapsulated_response_buf[sizeof(REMOTE_NDIS_INITIALIZE_CMPLT_t)];

  67. static uint32_t           xmit_ok;
  68. static uint32_t           rcv_ok;
  69. static uint32_t           xmit_error;
  70. static uint32_t           rcv_error;
  71. static uint32_t           rcv_no_buffer;

  72. static uint32_t           packet_in [(USBD_CDC%Instance%_ACM_SEND_BUF_SIZE   +3)/4];
  73. static uint32_t           packet_out[(USBD_CDC%Instance%_ACM_RECEIVE_BUF_SIZE+3)/4];


  74. // Local functions

  75. // MAC Address conversion from string
  76. // \param[in]   mac_str   Pointer to wide string.
  77. // \param[out]  mac_addr  Pointer to address.
  78. static void MAC_str_to_addr (const char *mac_str, uint8_t *mac_addr) {
  79.   uint8_t c;
  80.   uint8_t n;
  81.   uint8_t i;
  82.   uint8_t str_len;

  83.   str_len = strlen(mac_str);
  84.   for (i = 0U; i < str_len; i++) {
  85.     c = mac_str[i];
  86.     if         (c == '-') {
  87.       continue;
  88.     } else if ((c >= '0') && (c <= '9')) {
  89.       n = c - '0';
  90.     } else if ((c >= 'A') && (c <= 'F')) {
  91.       n = c - 'A' + 10U;
  92.     } else if ((c >= 'a') && (c <= 'f')) {
  93.       n = c - 'a' + 10U;
  94.     } else {
  95.       n = 0U;
  96.     }
  97.     if ((i & 1U) != 0U) {
  98.       mac_addr[i>>1] |= n;
  99.     } else {
  100.       mac_addr[i>>1]  = n << 4;
  101.     }
  102.   }
  103. }

  104. // Initialize variables
  105. void InitVars (void) {

  106.   rndis_state      = RNDIS_UNINITIALIZED;
  107.   link_state       = ARM_ETH_LINK_DOWN;

  108.   packet_filter    = 0U;

  109.   MAC_str_to_addr(RNDIS_MAC_ADDR, (uint8_t *)&mac_address);
  110.   memset((void *)mcast_address, 0, sizeof(mcast_address));

  111.   ResetVars();
  112. }

  113. // Reset variables
  114. static void ResetVars (void) {
  115.   link_state_up    = false;
  116.   link_state_down  = false;

  117.   get_encapsulated_response_len = 0U;

  118.   xmit_ok          = 0U;
  119.   rcv_ok           = 0U;
  120.   xmit_error       = 0U;
  121.   rcv_error        = 0U;
  122.   rcv_no_buffer    = 0U;
  123. }


  124. // USB CDC ACM callback global functions

  125. // Called during USBD_Initialize to initialize the USB CDC class instance (ACM).
  126. void USBD_CDC%Instance%_ACM_Initialize (void) {
  127.   InitVars();
  128. }


  129. // Called during USBD_Uninitialize to de-initialize the USB CDC class instance (ACM).
  130. void USBD_CDC%Instance%_ACM_Uninitialize (void) {
  131.   InitVars();
  132. }


  133. // Called upon USB Bus Reset Event.
  134. void USBD_CDC%Instance%_ACM_Reset (void) {
  135.   InitVars();
  136. }


  137. // Callback function called upon reception of request send encapsulated command sent by the USB Host.
  138. // \param[in]   buf           buffer that contains send encapsulated command request.
  139. // \param[in]   len           length of send encapsulated command request.
  140. // \return      true          send encapsulated command request processed.
  141. // \return      false         send encapsulated command request not supported or not processed.
  142. bool USBD_CDC%Instance%_ACM_SendEncapsulatedCommand (const uint8_t *buf, uint16_t len) {
  143.   REMOTE_NDIS_INITIALIZE_MSG_t   *ptr_init_msg;
  144.   REMOTE_NDIS_INITIALIZE_CMPLT_t *ptr_init_cmplt;
  145.   REMOTE_NDIS_HALT_MSG_t         *ptr_halt_msg;
  146.   REMOTE_NDIS_QUERY_MSG_t        *ptr_query_msg;
  147.   REMOTE_NDIS_QUERY_CMPLT_t      *ptr_query_cmplt;
  148.   REMOTE_NDIS_SET_MSG_t          *ptr_set_msg;
  149.   REMOTE_NDIS_SET_CMPLT_t        *ptr_set_cmplt;
  150.   REMOTE_NDIS_RESET_MSG_t        *ptr_reset_msg;
  151.   REMOTE_NDIS_RESET_CMPLT_t      *ptr_reset_cmplt;
  152.   REMOTE_NDIS_KEEPALIVE_MSG_t    *ptr_keepalive_msg;
  153.   REMOTE_NDIS_KEEPALIVE_CMPLT_t  *ptr_keepalive_cmplt;
  154.   uint32_t                        status, val;
  155.    int32_t                        i;
  156.   uint32_t                        num, by;
  157.   uint16_t                        msg_type;

  158.   msg_type = __UNALIGNED_UINT16_READ(buf);  // Extract message type of received message

  159.   // In uninitialized state only allowed messages are INITALIZE and HALT
  160.   if ((rndis_state == RNDIS_UNINITIALIZED)     &&
  161.       (msg_type != REMOTE_NDIS_INITIALIZE_MSG) &&
  162.       (msg_type != REMOTE_NDIS_HALT_MSG))       {
  163.     return false;
  164.   }

  165.   status = RNDIS_STATUS_SUCCESS;            // Default message processing status
  166.   get_encapsulated_response_len = 0U;       // Prepare default no response size

  167.   switch (msg_type) {                       // MessageType
  168.     case REMOTE_NDIS_INITIALIZE_MSG:
  169.       // Check message is valid
  170.       ptr_init_msg = (REMOTE_NDIS_INITIALIZE_MSG_t *)buf;
  171.       if (ptr_init_msg->MessageLength       != sizeof(REMOTE_NDIS_INITIALIZE_MSG_t)) { return false; }
  172.       if (ptr_init_msg->MajorVersion        != RNDIS_MAJOR_VERSION)                  { return false; }
  173.       if (ptr_init_msg->MinorVersion        != RNDIS_MINOR_VERSION)                  { return false; }
  174.       if (ptr_init_msg->MaxTransferSize     != 16384U)                               { return false; }

  175.       rndis_state = RNDIS_INITIALIZED;

  176.       // Prepare response
  177.       ptr_init_cmplt = (REMOTE_NDIS_INITIALIZE_CMPLT_t *)get_encapsulated_response_buf;
  178.       ptr_init_cmplt->MessageType            = REMOTE_NDIS_INITIALIZE_CMPLT;
  179.       ptr_init_cmplt->MessageLength          = sizeof(REMOTE_NDIS_INITIALIZE_CMPLT_t);
  180.       ptr_init_cmplt->RequestID              = ptr_init_msg->RequestID;
  181.       ptr_init_cmplt->Status                 = status;
  182.       ptr_init_cmplt->MajorVersion           = RNDIS_MAJOR_VERSION;
  183.       ptr_init_cmplt->MinorVersion           = RNDIS_MINOR_VERSION;
  184.       ptr_init_cmplt->DeviceFlags            = RNDIS_DF_CONNECTIONLESS;
  185.       ptr_init_cmplt->Medium                 = NdisMedium802_3;
  186.       ptr_init_cmplt->MaxPacketsPerTransfer  = 1U;
  187.       ptr_init_cmplt->MaxTransferSize        = USBD_CDC%Instance%_ACM_RECEIVE_BUF_SIZE;
  188.       ptr_init_cmplt->PacketAlignmentFactor  = 2U;
  189.       ptr_init_cmplt->Reserved[0]            = 0U;
  190.       ptr_init_cmplt->Reserved[1]            = 0U;
  191.       get_encapsulated_response_len          = ptr_init_cmplt->MessageLength;
  192.       break;

  193.     case REMOTE_NDIS_HALT_MSG:
  194.       // Check message is valid
  195.       ptr_halt_msg = (REMOTE_NDIS_HALT_MSG_t *)buf;
  196.       if (ptr_halt_msg->MessageLength != sizeof(REMOTE_NDIS_HALT_MSG_t)) { return false; }

  197.       rndis_state = RNDIS_UNINITIALIZED;

  198.       // This message does not have a response
  199.       return true;

  200.     case REMOTE_NDIS_QUERY_MSG:
  201.       // Check message is valid
  202.       ptr_query_msg = (REMOTE_NDIS_QUERY_MSG_t *)buf;
  203.       if (ptr_query_msg->MessageLength < 28U) { return false; }

  204.       // Prepare response
  205.       ptr_query_cmplt = (REMOTE_NDIS_QUERY_CMPLT_t *)get_encapsulated_response_buf;
  206.       ptr_query_cmplt->MessageType             = REMOTE_NDIS_QUERY_CMPLT;
  207.       ptr_query_cmplt->RequestID               = ptr_query_msg->RequestID;
  208.       ptr_query_cmplt->InformationBufferOffset = 16U;
  209.       switch (ptr_query_msg->Oid) {             // Handle OID
  210.         case OID_GEN_SUPPORTED_LIST:
  211.           ptr_query_cmplt->InformationBufferLength = 23U * 4U;
  212.           ptr_query_cmplt->OIDInputBuffer[0]       = OID_GEN_SUPPORTED_LIST;
  213.           ptr_query_cmplt->OIDInputBuffer[1]       = OID_GEN_HARDWARE_STATUS;
  214.           ptr_query_cmplt->OIDInputBuffer[2]       = OID_GEN_MEDIA_SUPPORTED;
  215.           ptr_query_cmplt->OIDInputBuffer[3]       = OID_GEN_MEDIA_IN_USE;
  216.           ptr_query_cmplt->OIDInputBuffer[4]       = OID_GEN_MAXIMUM_FRAME_SIZE;
  217.           ptr_query_cmplt->OIDInputBuffer[5]       = OID_GEN_LINK_SPEED;
  218.           ptr_query_cmplt->OIDInputBuffer[6]       = OID_GEN_TRANSMIT_BLOCK_SIZE;
  219.           ptr_query_cmplt->OIDInputBuffer[7]       = OID_GEN_RECEIVE_BLOCK_SIZE;
  220.           ptr_query_cmplt->OIDInputBuffer[8]       = OID_GEN_VENDOR_ID;
  221.           ptr_query_cmplt->OIDInputBuffer[9]       = OID_GEN_VENDOR_DESCRIPTION;
  222.           ptr_query_cmplt->OIDInputBuffer[10]      = OID_GEN_CURRENT_PACKET_FILTER;
  223.           ptr_query_cmplt->OIDInputBuffer[11]      = OID_GEN_MAXIMUM_TOTAL_SIZE;
  224.           ptr_query_cmplt->OIDInputBuffer[12]      = OID_GEN_MEDIA_CONNECT_STATUS;
  225.           ptr_query_cmplt->OIDInputBuffer[13]      = OID_GEN_PHYSICAL_MEDIUM;
  226.           ptr_query_cmplt->OIDInputBuffer[14]      = OID_GEN_XMIT_OK;
  227.           ptr_query_cmplt->OIDInputBuffer[15]      = OID_GEN_RCV_OK;
  228.           ptr_query_cmplt->OIDInputBuffer[16]      = OID_GEN_XMIT_ERROR;
  229.           ptr_query_cmplt->OIDInputBuffer[17]      = OID_GEN_RCV_ERROR;
  230.           ptr_query_cmplt->OIDInputBuffer[18]      = OID_GEN_RCV_NO_BUFFER;
  231.           ptr_query_cmplt->OIDInputBuffer[19]      = OID_802_3_PERMANENT_ADDRESS;
  232.           ptr_query_cmplt->OIDInputBuffer[20]      = OID_802_3_CURRENT_ADDRESS;
  233.           ptr_query_cmplt->OIDInputBuffer[21]      = OID_802_3_MULTICAST_LIST;
  234.           ptr_query_cmplt->OIDInputBuffer[22]      = OID_802_3_MAXIMUM_LIST_SIZE;
  235.           break;
  236.         case OID_GEN_HARDWARE_STATUS:
  237.           ptr_query_cmplt->InformationBufferLength = 4U;
  238.           if (link_state == ARM_ETH_LINK_UP) {
  239.             ptr_query_cmplt->OIDInputBuffer[0]     = NdisHardwareStatusReady;
  240.           } else {
  241.             ptr_query_cmplt->OIDInputBuffer[0]     = NdisHardwareStatusNotReady;
  242.           }
  243.           break;
  244.         case OID_GEN_MEDIA_SUPPORTED:
  245.         case OID_GEN_MEDIA_IN_USE:
  246.           ptr_query_cmplt->InformationBufferLength = 4U;
  247.           ptr_query_cmplt->OIDInputBuffer[0]       = NdisMedium802_3;
  248.           break;
  249.         case OID_GEN_MAXIMUM_FRAME_SIZE:
  250.           ptr_query_cmplt->InformationBufferLength = 4U;
  251.           ptr_query_cmplt->OIDInputBuffer[0]       = ETH_MTU_SIZE;
  252.           break;
  253.         case OID_GEN_LINK_SPEED:
  254.           ptr_query_cmplt->InformationBufferLength = 4U;
  255.           ptr_query_cmplt->OIDInputBuffer[0]       = 100000000U / 100U; // 100 MBit/s
  256.           break;
  257.         case OID_GEN_TRANSMIT_BLOCK_SIZE:
  258.           ptr_query_cmplt->InformationBufferLength = 4U;
  259.           ptr_query_cmplt->OIDInputBuffer[0]       = USBD_CDC%Instance%_ACM_SEND_BUF_SIZE;
  260.           break;
  261.         case OID_GEN_RECEIVE_BLOCK_SIZE:
  262.           ptr_query_cmplt->InformationBufferLength = 4U;
  263.           ptr_query_cmplt->OIDInputBuffer[0]       = USBD_CDC%Instance%_ACM_RECEIVE_BUF_SIZE;
  264.           break;
  265.         case OID_GEN_VENDOR_ID:
  266.           ptr_query_cmplt->InformationBufferLength = 4U;
  267.           ptr_query_cmplt->OIDInputBuffer[0]       = RNDIS_VENDOR_ID;
  268.           break;
  269.         case OID_GEN_VENDOR_DESCRIPTION:
  270.           ptr_query_cmplt->InformationBufferLength = strlen(RNDIS_VENDOR_DESC) + 1;
  271.           memset((void *)&ptr_query_cmplt->OIDInputBuffer[0], 0, ptr_query_cmplt->InformationBufferLength + 1U);
  272.           memcpy((void *)&ptr_query_cmplt->OIDInputBuffer[0], RNDIS_VENDOR_DESC, strlen(RNDIS_VENDOR_DESC));
  273.           break;
  274.         case OID_GEN_CURRENT_PACKET_FILTER:
  275.           ptr_query_cmplt->InformationBufferLength = 4U;
  276.           val = 0U;
  277.           if ((packet_filter & ARM_ETH_MAC_ADDRESS_MULTICAST) != 0U) { val |= RNDIS_FILTER_ALL_MULTICAST; }
  278.           if ((packet_filter & ARM_ETH_MAC_ADDRESS_BROADCAST) != 0U) { val |= RNDIS_FILTER_BROADCAST;     }
  279.           if ((packet_filter & ARM_ETH_MAC_ADDRESS_ALL)       != 0U) { val |= RNDIS_FILTER_PROMISCUOUS;   }
  280.           ptr_query_cmplt->OIDInputBuffer[0]       = val;
  281.           break;
  282.         case OID_GEN_MAXIMUM_TOTAL_SIZE:
  283.           ptr_query_cmplt->InformationBufferLength = 4U;
  284.           ptr_query_cmplt->OIDInputBuffer[0]       = sizeof(REMOTE_NDIS_PACKET_MSG_t) - 4U + ETH_MAX_SIZE;
  285.           break;
  286.         case OID_GEN_MEDIA_CONNECT_STATUS:
  287.           ptr_query_cmplt->InformationBufferLength = 4U;
  288.           if (link_state == ARM_ETH_LINK_UP) {
  289.             ptr_query_cmplt->OIDInputBuffer[0]     = NdisMediaStateConnected;
  290.           } else {
  291.             ptr_query_cmplt->OIDInputBuffer[0]     = NdisMediaStateDisconnected;
  292.           }
  293.           break;

  294.         case OID_GEN_PHYSICAL_MEDIUM:
  295.           ptr_query_cmplt->InformationBufferLength = 4U;
  296.           ptr_query_cmplt->OIDInputBuffer[0]       = NdisPhysicalMediumUnspecified;
  297.           break;

  298.         case OID_GEN_XMIT_OK:
  299.           ptr_query_cmplt->InformationBufferLength = 4U;
  300.           ptr_query_cmplt->OIDInputBuffer[0]       = xmit_ok;
  301.           break;
  302.         case OID_GEN_RCV_OK:
  303.           ptr_query_cmplt->InformationBufferLength = 4U;
  304.           ptr_query_cmplt->OIDInputBuffer[0]       = rcv_ok;
  305.           break;
  306.         case OID_GEN_XMIT_ERROR:
  307.           ptr_query_cmplt->InformationBufferLength = 4U;
  308.           ptr_query_cmplt->OIDInputBuffer[0]       = xmit_error;
  309.           break;
  310.         case OID_GEN_RCV_ERROR:
  311.           ptr_query_cmplt->InformationBufferLength = 4U;
  312.           ptr_query_cmplt->OIDInputBuffer[0]       = rcv_error;
  313.           break;
  314.         case OID_GEN_RCV_NO_BUFFER:
  315.           ptr_query_cmplt->InformationBufferLength = 4U;
  316.           ptr_query_cmplt->OIDInputBuffer[0]       = rcv_no_buffer;
  317.           break;

  318.         case OID_802_3_PERMANENT_ADDRESS:
  319.         case OID_802_3_CURRENT_ADDRESS:
  320.           ptr_query_cmplt->InformationBufferLength = 6U;
  321.           memcpy((void *)&ptr_query_cmplt->OIDInputBuffer[0], &mac_address, sizeof(ARM_ETH_MAC_ADDR));
  322.           break;
  323.         case OID_802_3_MULTICAST_LIST:
  324.           for (i = 0U; i < RNDIS_MCAST_NUM; i++) {
  325.             if (memcmp(&mcast_address[i], "\0\0\0\0\0\0", 6) == 0) {
  326.               break;
  327.             }
  328.           }
  329.           if (i == 0U) {
  330.             num = 0U;
  331.             ptr_query_cmplt->InformationBufferOffset = 0U;
  332.           } else {
  333.             num = i + 1U;
  334.             memcpy((void *)&ptr_query_cmplt->OIDInputBuffer[0], mcast_address, num * sizeof(ARM_ETH_MAC_ADDR));
  335.           }
  336.           ptr_query_cmplt->InformationBufferLength = num * sizeof(ARM_ETH_MAC_ADDR);
  337.           break;
  338.         case OID_802_3_MAXIMUM_LIST_SIZE:
  339.           ptr_query_cmplt->InformationBufferLength = 4U;
  340.           ptr_query_cmplt->OIDInputBuffer[0]       = RNDIS_MCAST_NUM;
  341.           break;

  342.         default:
  343.           ptr_query_cmplt->InformationBufferOffset = 0U;
  344.           ptr_query_cmplt->InformationBufferLength = 0U;
  345.           status = RNDIS_STATUS_NOT_SUPPORTED;
  346.           break;
  347.       }
  348.       ptr_query_cmplt->Status        = status;
  349.       ptr_query_cmplt->MessageLength = ptr_query_cmplt->InformationBufferLength + 24U;
  350.       get_encapsulated_response_len  = ptr_query_cmplt->MessageLength;
  351.       break;

  352.     case REMOTE_NDIS_SET_MSG:
  353.       // Check message is valid
  354.       ptr_set_msg = (REMOTE_NDIS_SET_MSG_t *)buf;
  355.       if (ptr_set_msg->MessageLength < 28U) { return false; }

  356.       // Prepare response
  357.       ptr_set_cmplt = (REMOTE_NDIS_SET_CMPLT_t *)get_encapsulated_response_buf;
  358.       ptr_set_cmplt->MessageType               = REMOTE_NDIS_SET_CMPLT;
  359.       ptr_set_cmplt->MessageLength             = sizeof(REMOTE_NDIS_SET_CMPLT_t);
  360.       ptr_set_cmplt->RequestID                 = ptr_set_msg->RequestID;

  361.       switch (ptr_set_msg->Oid) {               // Handle OID
  362.         case OID_802_3_MULTICAST_LIST:
  363.           by = ptr_set_msg->InformationBufferLength;
  364.           if (by > (sizeof(ARM_ETH_MAC_ADDR) * RNDIS_MCAST_NUM)) {
  365.             by = sizeof(ARM_ETH_MAC_ADDR) * RNDIS_MCAST_NUM;
  366.           }
  367.           if (by > 0U) {
  368.             memcpy(mcast_address, (void *)&ptr_set_msg->OIDInputBuffer[0], by);
  369.             num = by / sizeof(ARM_ETH_MAC_ADDR);
  370.           }
  371.           break;
  372.         case OID_GEN_CURRENT_PACKET_FILTER:
  373.           if ((ptr_set_msg->InformationBufferLength == 4U) &&
  374.               (ptr_set_msg->InformationBufferOffset != 0U)) {
  375.             val = *(uint32_t *)(((uint8_t *)&ptr_set_msg->RequestID) + ptr_set_msg->InformationBufferOffset);
  376.             if (val != 0U) {
  377.               if ((val & RNDIS_FILTER_ALL_MULTICAST) != 0U) { packet_filter |= ARM_ETH_MAC_ADDRESS_MULTICAST; }
  378.               if ((val & RNDIS_FILTER_BROADCAST)     != 0U) { packet_filter |= ARM_ETH_MAC_ADDRESS_BROADCAST; }
  379.               if ((val & RNDIS_FILTER_PROMISCUOUS)   != 0U) { packet_filter |= ARM_ETH_MAC_ADDRESS_ALL;       }
  380.               if (link_state == ARM_ETH_LINK_DOWN) {
  381.                 link_state    = ARM_ETH_LINK_UP;
  382.                 link_state_up = true;
  383.               }
  384.               rndis_state = RNDIS_DATA_INITIALIZED;
  385.             } else {
  386.               if (rndis_state == RNDIS_DATA_INITIALIZED) {
  387.                 rndis_state = RNDIS_INITIALIZED;
  388.               }
  389.             }
  390.           } else {
  391.             status = RNDIS_STATUS_FAILURE;
  392.           }
  393.           break;
  394.         default:
  395.           status = RNDIS_STATUS_NOT_SUPPORTED;
  396.           break;
  397.       }

  398.       ptr_set_cmplt->Status         = status;
  399.       get_encapsulated_response_len = ptr_set_cmplt->MessageLength;
  400.       break;

  401.     case REMOTE_NDIS_RESET_MSG:
  402.       // Check message is valid
  403.       ptr_reset_msg = (REMOTE_NDIS_RESET_MSG_t *)buf;
  404.       if (ptr_reset_msg->MessageLength != sizeof(REMOTE_NDIS_RESET_MSG_t)) { return false; }

  405.       ResetVars();

  406.       // Prepare response
  407.       ptr_reset_cmplt = (REMOTE_NDIS_RESET_CMPLT_t *)get_encapsulated_response_buf;
  408.       ptr_reset_cmplt->MessageType             = REMOTE_NDIS_RESET_CMPLT;
  409.       ptr_reset_cmplt->MessageLength           = sizeof(REMOTE_NDIS_RESET_CMPLT_t);
  410.       ptr_reset_cmplt->Status                  = status;
  411.       ptr_reset_cmplt->AddressingReset         = 0U;
  412.       get_encapsulated_response_len            = ptr_reset_cmplt->MessageLength;
  413.       break;

  414.     case REMOTE_NDIS_KEEPALIVE_MSG:
  415.       // Check message is valid
  416.       ptr_keepalive_msg = (REMOTE_NDIS_KEEPALIVE_MSG_t *)buf;
  417.       if (ptr_keepalive_msg->MessageLength != sizeof(REMOTE_NDIS_KEEPALIVE_MSG_t)) { return false; }

  418.       // Prepare response
  419.       ptr_keepalive_cmplt = (REMOTE_NDIS_KEEPALIVE_CMPLT_t *)get_encapsulated_response_buf;
  420.       ptr_keepalive_cmplt->MessageType         = REMOTE_NDIS_KEEPALIVE_CMPLT;
  421.       ptr_keepalive_cmplt->MessageLength       = sizeof(REMOTE_NDIS_KEEPALIVE_CMPLT_t);
  422.       ptr_keepalive_cmplt->RequestID           = ptr_keepalive_msg->RequestID;
  423.       ptr_keepalive_cmplt->Status              = status;
  424.       get_encapsulated_response_len            = ptr_keepalive_cmplt->MessageLength;
  425.       break;

  426.     default:
  427.       return false;
  428.   }

  429.   if (get_encapsulated_response_len != 0U) {
  430.     // If response is prepared send notification over Interrupt Endpoint
  431.     USBD_CDC_ACM_Notify_ResponseAvailable (%Instance%);
  432.   }

  433.   return true;
  434. }


  435. // Callback function called upon reception of request to get encapsulated response sent by the USB Host.
  436. // \param[in]   max_len       maximum number of data bytes that USB Host expects to receive
  437. // \param[out]  buf           pointer to buffer containing get encapsulated response to be returned to USB Host.
  438. // \param[out]  len           pointer to number of data bytes to be returned to USB Host.
  439. // \return      true          get encapsulated response request processed.
  440. // \return      false         get encapsulated response request not supported or not processed.
  441. bool USBD_CDC%Instance%_ACM_GetEncapsulatedResponse (uint16_t max_len, uint8_t **buf, uint16_t *len) {
  442.   REMOTE_NDIS_INDICATE_STATUS_MSG_t *ptr_indicate_status_msg;
  443.   uint32_t                           status;

  444.   if (link_state_up || link_state_down) {   // Generate unsolicited INDICATE STATUS message if link status has changed
  445.     if (link_state_up) {
  446.       status = RNDIS_STATUS_MEDIA_CONNECT;
  447.     } else {
  448.       status = RNDIS_STATUS_MEDIA_DISCONNECT;
  449.     }

  450.     // Prepare INDICATE STATUS message
  451.     ptr_indicate_status_msg = (REMOTE_NDIS_INDICATE_STATUS_MSG_t *)get_encapsulated_response_buf;
  452.     ptr_indicate_status_msg->MessageType        = REMOTE_NDIS_INDICATE_STATUS_MSG;
  453.     ptr_indicate_status_msg->MessageLength      = 20U;
  454.     ptr_indicate_status_msg->Status             = status;
  455.     ptr_indicate_status_msg->StatusBufferLength = 0U;
  456.     ptr_indicate_status_msg->StatusBufferOffset = 0U;
  457.     get_encapsulated_response_len               = 20U;

  458.     link_state_up   = false;
  459.     link_state_down = false;
  460.   }

  461.   if (get_encapsulated_response_len != 0U) {    // If response is available return it
  462.     *buf = (uint8_t *)get_encapsulated_response_buf;
  463.     *len =  get_encapsulated_response_len;
  464.     get_encapsulated_response_len = 0U;
  465.   }

  466.   return true;
  467. }


  468. // Callback function called when all data was sent
  469. // \return                    none.
  470. void USBD_CDC%Instance%_ACM_DataSent (void) {
  471. }


  472. // Callback function called when new data was received
  473. // \param[in]   len           number of bytes available to read.
  474. // \return                    none.
  475. void USBD_CDC%Instance%_ACM_DataReceived (uint32_t len) {
  476. }


  477. //! [code_USBD_User_CDC_ACM_RNDIS_VETH]


  478. // Global functions exported for Virtual Ethernet driver

  479. /**
  480.   \fn          ARM_ETH_LINK_STATE RNDIS%Instance%_GetLinkState (void)
  481.   \brief       Get RNDIS Device Link state (data initialized means link is up).
  482.   \return      current link status \ref ARM_ETH_LINK_STATE
  483. */
  484. ARM_ETH_LINK_STATE RNDIS%Instance%_GetLinkState (void) {
  485.   if (rndis_state == RNDIS_DATA_INITIALIZED) {
  486.     return ARM_ETH_LINK_UP;
  487.   }

  488.   return ARM_ETH_LINK_DOWN;
  489. }

  490. /**
  491.   \fn          int32_t RNDIS%Instance%_SendFrame (const uint8_t *frame, uint32_t len, uint32_t flags)
  492.   \brief       Send Ethernet frame over USB CDC ACM RNDIS.
  493.   \param[in]   frame  Pointer to frame buffer with data to send
  494.   \param[in]   len    Frame buffer length in bytes
  495.   \return      \ref execution_status
  496. */
  497. int32_t RNDIS%Instance%_SendFrame (const uint8_t *frame, uint32_t len) {
  498.   REMOTE_NDIS_PACKET_MSG_t *ptr_packet_msg;
  499.    int32_t                  usb_cdc_acm_status;

  500.   ptr_packet_msg = (REMOTE_NDIS_PACKET_MSG_t *)packet_in;

  501.   if ((rndis_state == RNDIS_DATA_INITIALIZED) &&
  502.       (len >= ETH_MIN_SIZE)                   &&
  503.       (len <= ETH_MAX_SIZE))                   {
  504.     memcpy((void *)&ptr_packet_msg->PayLoad[0], (void *)frame, len);
  505.     ptr_packet_msg->MessageType              = REMOTE_NDIS_PACKET_MSG;
  506.     ptr_packet_msg->MessageLength            = len + sizeof(REMOTE_NDIS_PACKET_MSG_t) - 4U;
  507.     ptr_packet_msg->DataOffset               = sizeof(REMOTE_NDIS_PACKET_MSG_t) - 12U;
  508.     ptr_packet_msg->DataLength               = len;
  509.     ptr_packet_msg->OutOfBandDataOffset      = 0U;
  510.     ptr_packet_msg->OutOfBandDataLength      = 0U;
  511.     ptr_packet_msg->NumOutOfBandDataElements = 0U;
  512.     ptr_packet_msg->PerPacketInfoOffset      = 0U;
  513.     ptr_packet_msg->PerPacketInfoLength      = 0U;
  514.     ptr_packet_msg->Reserved[0]              = 0U;
  515.     ptr_packet_msg->Reserved[1]              = 0U;
  516.     usb_cdc_acm_status = USBD_CDC_ACM_WriteData (%Instance%, (const uint8_t *)ptr_packet_msg, ptr_packet_msg->MessageLength);
  517.     if (usb_cdc_acm_status == ptr_packet_msg->MessageLength) {
  518.       rcv_ok++;
  519.       return ARM_DRIVER_OK;
  520.     }
  521.     if (usb_cdc_acm_status < 0) {
  522.       rcv_error++;
  523.       return ARM_DRIVER_ERROR;
  524.     }
  525.     if (usb_cdc_acm_status == 0) {
  526.       return ARM_DRIVER_ERROR_BUSY;
  527.     }
  528.   }

  529.   return ARM_DRIVER_ERROR;
  530. }

  531. /**
  532.   \fn          int32_t RNDIS%Instance%_ReadFrame (uint8_t *frame, uint32_t len)
  533.   \brief       Read data of Ethernet frame received over USB CDC ACM RNDIS.
  534.   \param[in]   frame  Pointer to frame buffer for data to read into
  535.   \param[in]   len    Frame buffer length in bytes
  536.   \return      number of data bytes read or execution status
  537.                  - value >= 0: number of data bytes read
  538.                  - value < 0: error occurred, value is execution status as defined with \ref execution_status
  539. */
  540. int32_t RNDIS%Instance%_ReadFrame (uint8_t *frame, uint32_t len) {
  541.   REMOTE_NDIS_PACKET_MSG_t *ptr_packet_msg;
  542.    int32_t                  usb_cdc_acm_status, data_len;

  543.   ptr_packet_msg = (REMOTE_NDIS_PACKET_MSG_t *)packet_out;

  544.   if ((rndis_state == RNDIS_DATA_INITIALIZED) &&
  545.       (len >= ETH_MIN_SIZE)                   &&
  546.       (len <= ETH_MAX_SIZE))                   {
  547.     usb_cdc_acm_status = USBD_CDC_ACM_ReadData (%Instance%, (uint8_t *)ptr_packet_msg, USBD_CDC%Instance%_ACM_RECEIVE_BUF_SIZE);
  548.     if ((usb_cdc_acm_status != 0) && (usb_cdc_acm_status == ptr_packet_msg->MessageLength)) {
  549.       data_len = len;
  550.       if (data_len > ptr_packet_msg->DataLength) {
  551.         data_len = ptr_packet_msg->DataLength;
  552.       }
  553.       memcpy((void *)frame, (void *)&ptr_packet_msg->PayLoad[0], data_len);
  554.       xmit_ok++;
  555.       return data_len;
  556.     }
  557.     if (usb_cdc_acm_status < 0) {
  558.       xmit_error++;
  559.       return ARM_DRIVER_ERROR;
  560.     }
  561.     if (usb_cdc_acm_status == 0) {
  562.       return ARM_DRIVER_ERROR_BUSY;
  563.     }
  564.   }

  565.   return 0;
  566. }

  567. /**
  568.   \fn          uint32_t RNDIS%Instance%_GetRxFrameSize (void)
  569.   \brief       Get size of Ethernet frame received over USB CDC ACM RNDIS.
  570.   \return      number of bytes in received frame
  571. */
  572. uint32_t RNDIS%Instance%_GetRxFrameSize (void) {
  573.   uint32_t avail_data_len;

  574.   avail_data_len = USBD_CDC_ACM_DataAvailable (%Instance%);

  575.   if (avail_data_len > (sizeof(REMOTE_NDIS_PACKET_MSG_t) - 4U)) {
  576.     avail_data_len -= (sizeof(REMOTE_NDIS_PACKET_MSG_t) - 4U);
  577.   }

  578.   return avail_data_len;
  579. }
复制代码


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106828
QQ
 楼主| 发表于 2020-7-4 13:41:58 | 显示全部楼层
V1.0.1:

  1. /*------------------------------------------------------------------------------
  2. * MDK Middleware - Component ::USB:Device:CDC
  3. * Copyright (c) 2018-2019 Arm Limited (or its affiliates). All rights reserved.
  4. *------------------------------------------------------------------------------
  5. * Name:    USBD_User_CDC_ACM_RNDIS_VETH_%Instance%.c
  6. * Purpose: USB Device Communication Device Class (CDC)
  7. *          Abstract Control Model (ACM)
  8. *          Remote Network Driver Interface Specification (RNDIS)
  9. *          User Module for a Virtual Ethernet
  10. * Rev.:    V1.0.1
  11. *----------------------------------------------------------------------------*/
  12. /**
  13. * \addtogroup usbd_cdcFunctions
  14. *
  15. * USBD_User_CDC_ACM_RNDIS_VETH_%Instance%.c implements the application specific
  16. * functionality of the CDC ACM class using RNDIS protocol and is used
  17. * to implement Network Interface Card (NIC) to the USB Host.
  18. * This user module works together with EMAC_CDC_ACM_RNDIS.c driver
  19. * to provide USB Host network access to Embedded Device over USB.
  20. *
  21. * The implementation depends on the configuration file USBD_Config_CDC_%Instance%.h.
  22. *
  23. */


  24. //! [code_USBD_User_CDC_ACM_RNDIS_VETH]

  25. #include <stdint.h>
  26. #include <stdbool.h>
  27. #include <string.h>

  28. #include "rl_usb.h"

  29. #include "Driver_ETH.h"
  30. #include "Driver_ETH_MAC.h"
  31. #include "Driver_ETH_PHY.h"
  32. #include "RTE/USB/USBD_Config_CDC_%Instance%.h"


  33. //-------- <<< Use Configuration Wizard in Context Menu >>> --------------------

  34. // Configuration defines

  35. //   <s.17>MAC Address
  36. //     <i>Ethernet MAC Address in text representation
  37. //     <i>Value FF-FF-FF-FF-FF-FF is not allowed,
  38. //     <i>LSB of first byte must be 0 (an ethernet Multicast bit).
  39. //     <i>Default: "1E-30-6C-A2-45-5E"
  40. #define RNDIS_MAC_ADDR    "1E-30-6C-A2-45-5E"           // RNDIS MAC Address

  41. //   <o.0..5>Maximum number of multicast addresses <1-32>
  42. #define RNDIS_MCAST_NUM   16                            // RNDIS Number of Multicast Addresses supported

  43. //   <s.32>RNDIS Vendor Description
  44. #define RNDIS_VENDOR_DESC "Keil NIC (USB <-> ETH)"      // RNDIS Vendor Description

  45. //   <o.0..23>RNDIS Vendor Id Code <0x000000-0xFFFFFF>
  46. #define RNDIS_VENDOR_ID   0xFFFFFF                      // RNDIS three-byte IEEE-registered Vendor Code

  47. //------------- <<< end of configuration section >>> ---------------------------


  48. // Global functions exported by this module
  49.        ARM_ETH_LINK_STATE RNDIS%Instance%_GetLinkState  (void);
  50.        int32_t            RNDIS%Instance%_SendFrame     (const uint8_t *frame, uint32_t len);
  51.        int32_t            RNDIS%Instance%_ReadFrame     (      uint8_t *frame, uint32_t len);
  52.        uint32_t           RNDIS%Instance%_GetRxFrameSize(void);

  53. // Local functions
  54. static void               MAC_str_to_addr (const char *mac_str, uint8_t *mac_addr);
  55. static void               InitVars        (void);
  56. static void               ResetVars       (void);

  57. // Local variables
  58. static uint32_t           rndis_state;
  59. static ARM_ETH_LINK_STATE link_state;

  60. static bool               link_state_up;
  61. static bool               link_state_down;

  62. static uint32_t           packet_filter;
  63. static ARM_ETH_MAC_ADDR   mac_address;
  64. static ARM_ETH_MAC_ADDR   mcast_address[RNDIS_MCAST_NUM];

  65. static uint16_t           get_encapsulated_response_len;
  66. static uint32_t           get_encapsulated_response_buf[sizeof(REMOTE_NDIS_INITIALIZE_CMPLT_t)];

  67. static uint32_t           xmit_ok;
  68. static uint32_t           rcv_ok;
  69. static uint32_t           xmit_error;
  70. static uint32_t           rcv_error;
  71. static uint32_t           rcv_no_buffer;

  72. static uint32_t           packet_in [(USBD_CDC%Instance%_ACM_SEND_BUF_SIZE   +3)/4];
  73. static uint32_t           packet_out[(USBD_CDC%Instance%_ACM_RECEIVE_BUF_SIZE+3)/4];


  74. // Local functions

  75. // MAC Address conversion from string
  76. // \param[in]   mac_str   Pointer to wide string.
  77. // \param[out]  mac_addr  Pointer to address.
  78. static void MAC_str_to_addr (const char *mac_str, uint8_t *mac_addr) {
  79.   uint8_t c;
  80.   uint8_t n;
  81.   uint8_t i, j;
  82.   uint8_t str_len;

  83.   str_len = strlen(mac_str);
  84.   j = 0U;
  85.   for (i = 0U; i < str_len; i++) {
  86.     c = mac_str[i];
  87.     if         (c == '-') {
  88.       continue;
  89.     } else if ((c >= '0') && (c <= '9')) {
  90.       n = c - '0';
  91.     } else if ((c >= 'A') && (c <= 'F')) {
  92.       n = c - 'A' + 10U;
  93.     } else if ((c >= 'a') && (c <= 'f')) {
  94.       n = c - 'a' + 10U;
  95.     } else {
  96.       n = 0U;
  97.     }
  98.     if ((j & 1U) != 0U) {
  99.       mac_addr[j>>1] |= n;
  100.     } else {
  101.       mac_addr[j>>1]  = n << 4;
  102.     }
  103.     j++;
  104.   }
  105. }

  106. // Initialize variables
  107. void InitVars (void) {

  108.   rndis_state      = RNDIS_UNINITIALIZED;
  109.   link_state       = ARM_ETH_LINK_DOWN;

  110.   packet_filter    = 0U;

  111.   MAC_str_to_addr(RNDIS_MAC_ADDR, (uint8_t *)&mac_address);
  112.   memset((void *)mcast_address, 0, sizeof(mcast_address));

  113.   ResetVars();
  114. }

  115. // Reset variables
  116. static void ResetVars (void) {
  117.   link_state_up    = false;
  118.   link_state_down  = false;

  119.   get_encapsulated_response_len = 0U;

  120.   xmit_ok          = 0U;
  121.   rcv_ok           = 0U;
  122.   xmit_error       = 0U;
  123.   rcv_error        = 0U;
  124.   rcv_no_buffer    = 0U;
  125. }


  126. // USB CDC ACM callback global functions

  127. // Called during USBD_Initialize to initialize the USB CDC class instance (ACM).
  128. void USBD_CDC%Instance%_ACM_Initialize (void) {
  129.   InitVars();
  130. }


  131. // Called during USBD_Uninitialize to de-initialize the USB CDC class instance (ACM).
  132. void USBD_CDC%Instance%_ACM_Uninitialize (void) {
  133.   InitVars();
  134. }


  135. // Called upon USB Bus Reset Event.
  136. void USBD_CDC%Instance%_ACM_Reset (void) {
  137.   InitVars();
  138. }


  139. // Callback function called upon reception of request send encapsulated command sent by the USB Host.
  140. // \param[in]   buf           buffer that contains send encapsulated command request.
  141. // \param[in]   len           length of send encapsulated command request.
  142. // \return      true          send encapsulated command request processed.
  143. // \return      false         send encapsulated command request not supported or not processed.
  144. bool USBD_CDC%Instance%_ACM_SendEncapsulatedCommand (const uint8_t *buf, uint16_t len) {
  145.   REMOTE_NDIS_INITIALIZE_MSG_t   *ptr_init_msg;
  146.   REMOTE_NDIS_INITIALIZE_CMPLT_t *ptr_init_cmplt;
  147.   REMOTE_NDIS_HALT_MSG_t         *ptr_halt_msg;
  148.   REMOTE_NDIS_QUERY_MSG_t        *ptr_query_msg;
  149.   REMOTE_NDIS_QUERY_CMPLT_t      *ptr_query_cmplt;
  150.   REMOTE_NDIS_SET_MSG_t          *ptr_set_msg;
  151.   REMOTE_NDIS_SET_CMPLT_t        *ptr_set_cmplt;
  152.   REMOTE_NDIS_RESET_MSG_t        *ptr_reset_msg;
  153.   REMOTE_NDIS_RESET_CMPLT_t      *ptr_reset_cmplt;
  154.   REMOTE_NDIS_KEEPALIVE_MSG_t    *ptr_keepalive_msg;
  155.   REMOTE_NDIS_KEEPALIVE_CMPLT_t  *ptr_keepalive_cmplt;
  156.   uint32_t                        status, val;
  157.    int32_t                        i;
  158.   uint32_t                        num, by;
  159.   uint16_t                        msg_type;

  160.   msg_type = __UNALIGNED_UINT16_READ(buf);  // Extract message type of received message

  161.   // In uninitialized state only allowed messages are INITALIZE and HALT
  162.   if ((rndis_state == RNDIS_UNINITIALIZED)     &&
  163.       (msg_type != REMOTE_NDIS_INITIALIZE_MSG) &&
  164.       (msg_type != REMOTE_NDIS_HALT_MSG))       {
  165.     return false;
  166.   }

  167.   status = RNDIS_STATUS_SUCCESS;            // Default message processing status
  168.   get_encapsulated_response_len = 0U;       // Prepare default no response size

  169.   switch (msg_type) {                       // MessageType
  170.     case REMOTE_NDIS_INITIALIZE_MSG:
  171.       // Check message is valid
  172.       ptr_init_msg = (REMOTE_NDIS_INITIALIZE_MSG_t *)buf;
  173.       if (ptr_init_msg->MessageLength       != sizeof(REMOTE_NDIS_INITIALIZE_MSG_t)) { return false; }
  174.       if (ptr_init_msg->MajorVersion        != RNDIS_MAJOR_VERSION)                  { return false; }
  175.       if (ptr_init_msg->MinorVersion        != RNDIS_MINOR_VERSION)                  { return false; }
  176.       if (ptr_init_msg->MaxTransferSize     != 16384U)                               { return false; }

  177.       rndis_state = RNDIS_INITIALIZED;

  178.       // Prepare response
  179.       ptr_init_cmplt = (REMOTE_NDIS_INITIALIZE_CMPLT_t *)get_encapsulated_response_buf;
  180.       ptr_init_cmplt->MessageType            = REMOTE_NDIS_INITIALIZE_CMPLT;
  181.       ptr_init_cmplt->MessageLength          = sizeof(REMOTE_NDIS_INITIALIZE_CMPLT_t);
  182.       ptr_init_cmplt->RequestID              = ptr_init_msg->RequestID;
  183.       ptr_init_cmplt->Status                 = status;
  184.       ptr_init_cmplt->MajorVersion           = RNDIS_MAJOR_VERSION;
  185.       ptr_init_cmplt->MinorVersion           = RNDIS_MINOR_VERSION;
  186.       ptr_init_cmplt->DeviceFlags            = RNDIS_DF_CONNECTIONLESS;
  187.       ptr_init_cmplt->Medium                 = NdisMedium802_3;
  188.       ptr_init_cmplt->MaxPacketsPerTransfer  = 1U;
  189.       ptr_init_cmplt->MaxTransferSize        = USBD_CDC%Instance%_ACM_RECEIVE_BUF_SIZE;
  190.       ptr_init_cmplt->PacketAlignmentFactor  = 2U;
  191.       ptr_init_cmplt->Reserved[0]            = 0U;
  192.       ptr_init_cmplt->Reserved[1]            = 0U;
  193.       get_encapsulated_response_len          = ptr_init_cmplt->MessageLength;
  194.       break;

  195.     case REMOTE_NDIS_HALT_MSG:
  196.       // Check message is valid
  197.       ptr_halt_msg = (REMOTE_NDIS_HALT_MSG_t *)buf;
  198.       if (ptr_halt_msg->MessageLength != sizeof(REMOTE_NDIS_HALT_MSG_t)) { return false; }

  199.       rndis_state = RNDIS_UNINITIALIZED;

  200.       // This message does not have a response
  201.       return true;

  202.     case REMOTE_NDIS_QUERY_MSG:
  203.       // Check message is valid
  204.       ptr_query_msg = (REMOTE_NDIS_QUERY_MSG_t *)buf;
  205.       if (ptr_query_msg->MessageLength < 28U) { return false; }

  206.       // Prepare response
  207.       ptr_query_cmplt = (REMOTE_NDIS_QUERY_CMPLT_t *)get_encapsulated_response_buf;
  208.       ptr_query_cmplt->MessageType             = REMOTE_NDIS_QUERY_CMPLT;
  209.       ptr_query_cmplt->RequestID               = ptr_query_msg->RequestID;
  210.       ptr_query_cmplt->InformationBufferOffset = 16U;
  211.       switch (ptr_query_msg->Oid) {             // Handle OID
  212.         case OID_GEN_SUPPORTED_LIST:
  213.           ptr_query_cmplt->InformationBufferLength = 23U * 4U;
  214.           ptr_query_cmplt->OIDInputBuffer[0]       = OID_GEN_SUPPORTED_LIST;
  215.           ptr_query_cmplt->OIDInputBuffer[1]       = OID_GEN_HARDWARE_STATUS;
  216.           ptr_query_cmplt->OIDInputBuffer[2]       = OID_GEN_MEDIA_SUPPORTED;
  217.           ptr_query_cmplt->OIDInputBuffer[3]       = OID_GEN_MEDIA_IN_USE;
  218.           ptr_query_cmplt->OIDInputBuffer[4]       = OID_GEN_MAXIMUM_FRAME_SIZE;
  219.           ptr_query_cmplt->OIDInputBuffer[5]       = OID_GEN_LINK_SPEED;
  220.           ptr_query_cmplt->OIDInputBuffer[6]       = OID_GEN_TRANSMIT_BLOCK_SIZE;
  221.           ptr_query_cmplt->OIDInputBuffer[7]       = OID_GEN_RECEIVE_BLOCK_SIZE;
  222.           ptr_query_cmplt->OIDInputBuffer[8]       = OID_GEN_VENDOR_ID;
  223.           ptr_query_cmplt->OIDInputBuffer[9]       = OID_GEN_VENDOR_DESCRIPTION;
  224.           ptr_query_cmplt->OIDInputBuffer[10]      = OID_GEN_CURRENT_PACKET_FILTER;
  225.           ptr_query_cmplt->OIDInputBuffer[11]      = OID_GEN_MAXIMUM_TOTAL_SIZE;
  226.           ptr_query_cmplt->OIDInputBuffer[12]      = OID_GEN_MEDIA_CONNECT_STATUS;
  227.           ptr_query_cmplt->OIDInputBuffer[13]      = OID_GEN_PHYSICAL_MEDIUM;
  228.           ptr_query_cmplt->OIDInputBuffer[14]      = OID_GEN_XMIT_OK;
  229.           ptr_query_cmplt->OIDInputBuffer[15]      = OID_GEN_RCV_OK;
  230.           ptr_query_cmplt->OIDInputBuffer[16]      = OID_GEN_XMIT_ERROR;
  231.           ptr_query_cmplt->OIDInputBuffer[17]      = OID_GEN_RCV_ERROR;
  232.           ptr_query_cmplt->OIDInputBuffer[18]      = OID_GEN_RCV_NO_BUFFER;
  233.           ptr_query_cmplt->OIDInputBuffer[19]      = OID_802_3_PERMANENT_ADDRESS;
  234.           ptr_query_cmplt->OIDInputBuffer[20]      = OID_802_3_CURRENT_ADDRESS;
  235.           ptr_query_cmplt->OIDInputBuffer[21]      = OID_802_3_MULTICAST_LIST;
  236.           ptr_query_cmplt->OIDInputBuffer[22]      = OID_802_3_MAXIMUM_LIST_SIZE;
  237.           break;
  238.         case OID_GEN_HARDWARE_STATUS:
  239.           ptr_query_cmplt->InformationBufferLength = 4U;
  240.           if (link_state == ARM_ETH_LINK_UP) {
  241.             ptr_query_cmplt->OIDInputBuffer[0]     = NdisHardwareStatusReady;
  242.           } else {
  243.             ptr_query_cmplt->OIDInputBuffer[0]     = NdisHardwareStatusNotReady;
  244.           }
  245.           break;
  246.         case OID_GEN_MEDIA_SUPPORTED:
  247.         case OID_GEN_MEDIA_IN_USE:
  248.           ptr_query_cmplt->InformationBufferLength = 4U;
  249.           ptr_query_cmplt->OIDInputBuffer[0]       = NdisMedium802_3;
  250.           break;
  251.         case OID_GEN_MAXIMUM_FRAME_SIZE:
  252.           ptr_query_cmplt->InformationBufferLength = 4U;
  253.           ptr_query_cmplt->OIDInputBuffer[0]       = ETH_MTU_SIZE;
  254.           break;
  255.         case OID_GEN_LINK_SPEED:
  256.           ptr_query_cmplt->InformationBufferLength = 4U;
  257.           ptr_query_cmplt->OIDInputBuffer[0]       = 100000000U / 100U; // 100 MBit/s
  258.           break;
  259.         case OID_GEN_TRANSMIT_BLOCK_SIZE:
  260.           ptr_query_cmplt->InformationBufferLength = 4U;
  261.           ptr_query_cmplt->OIDInputBuffer[0]       = USBD_CDC%Instance%_ACM_SEND_BUF_SIZE;
  262.           break;
  263.         case OID_GEN_RECEIVE_BLOCK_SIZE:
  264.           ptr_query_cmplt->InformationBufferLength = 4U;
  265.           ptr_query_cmplt->OIDInputBuffer[0]       = USBD_CDC%Instance%_ACM_RECEIVE_BUF_SIZE;
  266.           break;
  267.         case OID_GEN_VENDOR_ID:
  268.           ptr_query_cmplt->InformationBufferLength = 4U;
  269.           ptr_query_cmplt->OIDInputBuffer[0]       = RNDIS_VENDOR_ID;
  270.           break;
  271.         case OID_GEN_VENDOR_DESCRIPTION:
  272.           ptr_query_cmplt->InformationBufferLength = strlen(RNDIS_VENDOR_DESC) + 1;
  273.           memset((void *)&ptr_query_cmplt->OIDInputBuffer[0], 0, ptr_query_cmplt->InformationBufferLength + 1U);
  274.           memcpy((void *)&ptr_query_cmplt->OIDInputBuffer[0], RNDIS_VENDOR_DESC, strlen(RNDIS_VENDOR_DESC));
  275.           break;
  276.         case OID_GEN_CURRENT_PACKET_FILTER:
  277.           ptr_query_cmplt->InformationBufferLength = 4U;
  278.           val = 0U;
  279.           if ((packet_filter & ARM_ETH_MAC_ADDRESS_MULTICAST) != 0U) { val |= RNDIS_FILTER_ALL_MULTICAST; }
  280.           if ((packet_filter & ARM_ETH_MAC_ADDRESS_BROADCAST) != 0U) { val |= RNDIS_FILTER_BROADCAST;     }
  281.           if ((packet_filter & ARM_ETH_MAC_ADDRESS_ALL)       != 0U) { val |= RNDIS_FILTER_PROMISCUOUS;   }
  282.           ptr_query_cmplt->OIDInputBuffer[0]       = val;
  283.           break;
  284.         case OID_GEN_MAXIMUM_TOTAL_SIZE:
  285.           ptr_query_cmplt->InformationBufferLength = 4U;
  286.           ptr_query_cmplt->OIDInputBuffer[0]       = sizeof(REMOTE_NDIS_PACKET_MSG_t) - 4U + ETH_MAX_SIZE;
  287.           break;
  288.         case OID_GEN_MEDIA_CONNECT_STATUS:
  289.           ptr_query_cmplt->InformationBufferLength = 4U;
  290.           if (link_state == ARM_ETH_LINK_UP) {
  291.             ptr_query_cmplt->OIDInputBuffer[0]     = NdisMediaStateConnected;
  292.           } else {
  293.             ptr_query_cmplt->OIDInputBuffer[0]     = NdisMediaStateDisconnected;
  294.           }
  295.           break;

  296.         case OID_GEN_PHYSICAL_MEDIUM:
  297.           ptr_query_cmplt->InformationBufferLength = 4U;
  298.           ptr_query_cmplt->OIDInputBuffer[0]       = NdisPhysicalMediumUnspecified;
  299.           break;

  300.         case OID_GEN_XMIT_OK:
  301.           ptr_query_cmplt->InformationBufferLength = 4U;
  302.           ptr_query_cmplt->OIDInputBuffer[0]       = xmit_ok;
  303.           break;
  304.         case OID_GEN_RCV_OK:
  305.           ptr_query_cmplt->InformationBufferLength = 4U;
  306.           ptr_query_cmplt->OIDInputBuffer[0]       = rcv_ok;
  307.           break;
  308.         case OID_GEN_XMIT_ERROR:
  309.           ptr_query_cmplt->InformationBufferLength = 4U;
  310.           ptr_query_cmplt->OIDInputBuffer[0]       = xmit_error;
  311.           break;
  312.         case OID_GEN_RCV_ERROR:
  313.           ptr_query_cmplt->InformationBufferLength = 4U;
  314.           ptr_query_cmplt->OIDInputBuffer[0]       = rcv_error;
  315.           break;
  316.         case OID_GEN_RCV_NO_BUFFER:
  317.           ptr_query_cmplt->InformationBufferLength = 4U;
  318.           ptr_query_cmplt->OIDInputBuffer[0]       = rcv_no_buffer;
  319.           break;

  320.         case OID_802_3_PERMANENT_ADDRESS:
  321.         case OID_802_3_CURRENT_ADDRESS:
  322.           ptr_query_cmplt->InformationBufferLength = 6U;
  323.           memcpy((void *)&ptr_query_cmplt->OIDInputBuffer[0], &mac_address, sizeof(ARM_ETH_MAC_ADDR));
  324.           break;
  325.         case OID_802_3_MULTICAST_LIST:
  326.           for (i = 0U; i < RNDIS_MCAST_NUM; i++) {
  327.             if (memcmp(&mcast_address[i], "\0\0\0\0\0\0", 6) == 0) {
  328.               break;
  329.             }
  330.           }
  331.           if (i == 0U) {
  332.             num = 0U;
  333.             ptr_query_cmplt->InformationBufferOffset = 0U;
  334.           } else {
  335.             num = i + 1U;
  336.             memcpy((void *)&ptr_query_cmplt->OIDInputBuffer[0], mcast_address, num * sizeof(ARM_ETH_MAC_ADDR));
  337.           }
  338.           ptr_query_cmplt->InformationBufferLength = num * sizeof(ARM_ETH_MAC_ADDR);
  339.           break;
  340.         case OID_802_3_MAXIMUM_LIST_SIZE:
  341.           ptr_query_cmplt->InformationBufferLength = 4U;
  342.           ptr_query_cmplt->OIDInputBuffer[0]       = RNDIS_MCAST_NUM;
  343.           break;

  344.         default:
  345.           ptr_query_cmplt->InformationBufferOffset = 0U;
  346.           ptr_query_cmplt->InformationBufferLength = 0U;
  347.           status = RNDIS_STATUS_NOT_SUPPORTED;
  348.           break;
  349.       }
  350.       ptr_query_cmplt->Status        = status;
  351.       ptr_query_cmplt->MessageLength = ptr_query_cmplt->InformationBufferLength + 24U;
  352.       get_encapsulated_response_len  = ptr_query_cmplt->MessageLength;
  353.       break;

  354.     case REMOTE_NDIS_SET_MSG:
  355.       // Check message is valid
  356.       ptr_set_msg = (REMOTE_NDIS_SET_MSG_t *)buf;
  357.       if (ptr_set_msg->MessageLength < 28U) { return false; }

  358.       // Prepare response
  359.       ptr_set_cmplt = (REMOTE_NDIS_SET_CMPLT_t *)get_encapsulated_response_buf;
  360.       ptr_set_cmplt->MessageType               = REMOTE_NDIS_SET_CMPLT;
  361.       ptr_set_cmplt->MessageLength             = sizeof(REMOTE_NDIS_SET_CMPLT_t);
  362.       ptr_set_cmplt->RequestID                 = ptr_set_msg->RequestID;

  363.       switch (ptr_set_msg->Oid) {               // Handle OID
  364.         case OID_802_3_MULTICAST_LIST:
  365.           by = ptr_set_msg->InformationBufferLength;
  366.           if (by > (sizeof(ARM_ETH_MAC_ADDR) * RNDIS_MCAST_NUM)) {
  367.             by = sizeof(ARM_ETH_MAC_ADDR) * RNDIS_MCAST_NUM;
  368.           }
  369.           if (by > 0U) {
  370.             memcpy(mcast_address, (void *)&ptr_set_msg->OIDInputBuffer[0], by);
  371.             num = by / sizeof(ARM_ETH_MAC_ADDR);
  372.           }
  373.           break;
  374.         case OID_GEN_CURRENT_PACKET_FILTER:
  375.           if ((ptr_set_msg->InformationBufferLength == 4U) &&
  376.               (ptr_set_msg->InformationBufferOffset != 0U)) {
  377.             val = *(uint32_t *)(((uint8_t *)&ptr_set_msg->RequestID) + ptr_set_msg->InformationBufferOffset);
  378.             if (val != 0U) {
  379.               if ((val & RNDIS_FILTER_ALL_MULTICAST) != 0U) { packet_filter |= ARM_ETH_MAC_ADDRESS_MULTICAST; }
  380.               if ((val & RNDIS_FILTER_BROADCAST)     != 0U) { packet_filter |= ARM_ETH_MAC_ADDRESS_BROADCAST; }
  381.               if ((val & RNDIS_FILTER_PROMISCUOUS)   != 0U) { packet_filter |= ARM_ETH_MAC_ADDRESS_ALL;       }
  382.               if (link_state == ARM_ETH_LINK_DOWN) {
  383.                 link_state    = ARM_ETH_LINK_UP;
  384.                 link_state_up = true;
  385.               }
  386.               rndis_state = RNDIS_DATA_INITIALIZED;
  387.             } else {
  388.               if (rndis_state == RNDIS_DATA_INITIALIZED) {
  389.                 rndis_state = RNDIS_INITIALIZED;
  390.               }
  391.             }
  392.           } else {
  393.             status = RNDIS_STATUS_FAILURE;
  394.           }
  395.           break;
  396.         default:
  397.           status = RNDIS_STATUS_NOT_SUPPORTED;
  398.           break;
  399.       }

  400.       ptr_set_cmplt->Status         = status;
  401.       get_encapsulated_response_len = ptr_set_cmplt->MessageLength;
  402.       break;

  403.     case REMOTE_NDIS_RESET_MSG:
  404.       // Check message is valid
  405.       ptr_reset_msg = (REMOTE_NDIS_RESET_MSG_t *)buf;
  406.       if (ptr_reset_msg->MessageLength != sizeof(REMOTE_NDIS_RESET_MSG_t)) { return false; }

  407.       ResetVars();

  408.       // Prepare response
  409.       ptr_reset_cmplt = (REMOTE_NDIS_RESET_CMPLT_t *)get_encapsulated_response_buf;
  410.       ptr_reset_cmplt->MessageType             = REMOTE_NDIS_RESET_CMPLT;
  411.       ptr_reset_cmplt->MessageLength           = sizeof(REMOTE_NDIS_RESET_CMPLT_t);
  412.       ptr_reset_cmplt->Status                  = status;
  413.       ptr_reset_cmplt->AddressingReset         = 0U;
  414.       get_encapsulated_response_len            = ptr_reset_cmplt->MessageLength;
  415.       break;

  416.     case REMOTE_NDIS_KEEPALIVE_MSG:
  417.       // Check message is valid
  418.       ptr_keepalive_msg = (REMOTE_NDIS_KEEPALIVE_MSG_t *)buf;
  419.       if (ptr_keepalive_msg->MessageLength != sizeof(REMOTE_NDIS_KEEPALIVE_MSG_t)) { return false; }

  420.       // Prepare response
  421.       ptr_keepalive_cmplt = (REMOTE_NDIS_KEEPALIVE_CMPLT_t *)get_encapsulated_response_buf;
  422.       ptr_keepalive_cmplt->MessageType         = REMOTE_NDIS_KEEPALIVE_CMPLT;
  423.       ptr_keepalive_cmplt->MessageLength       = sizeof(REMOTE_NDIS_KEEPALIVE_CMPLT_t);
  424.       ptr_keepalive_cmplt->RequestID           = ptr_keepalive_msg->RequestID;
  425.       ptr_keepalive_cmplt->Status              = status;
  426.       get_encapsulated_response_len            = ptr_keepalive_cmplt->MessageLength;
  427.       break;

  428.     default:
  429.       return false;
  430.   }

  431.   if (get_encapsulated_response_len != 0U) {
  432.     // If response is prepared send notification over Interrupt Endpoint
  433.     USBD_CDC_ACM_Notify_ResponseAvailable (%Instance%);
  434.   }

  435.   return true;
  436. }


  437. // Callback function called upon reception of request to get encapsulated response sent by the USB Host.
  438. // \param[in]   max_len       maximum number of data bytes that USB Host expects to receive
  439. // \param[out]  buf           pointer to buffer containing get encapsulated response to be returned to USB Host.
  440. // \param[out]  len           pointer to number of data bytes to be returned to USB Host.
  441. // \return      true          get encapsulated response request processed.
  442. // \return      false         get encapsulated response request not supported or not processed.
  443. bool USBD_CDC%Instance%_ACM_GetEncapsulatedResponse (uint16_t max_len, uint8_t **buf, uint16_t *len) {
  444.   REMOTE_NDIS_INDICATE_STATUS_MSG_t *ptr_indicate_status_msg;
  445.   uint32_t                           status;

  446.   if (link_state_up || link_state_down) {   // Generate unsolicited INDICATE STATUS message if link status has changed
  447.     if (link_state_up) {
  448.       status = RNDIS_STATUS_MEDIA_CONNECT;
  449.     } else {
  450.       status = RNDIS_STATUS_MEDIA_DISCONNECT;
  451.     }

  452.     // Prepare INDICATE STATUS message
  453.     ptr_indicate_status_msg = (REMOTE_NDIS_INDICATE_STATUS_MSG_t *)get_encapsulated_response_buf;
  454.     ptr_indicate_status_msg->MessageType        = REMOTE_NDIS_INDICATE_STATUS_MSG;
  455.     ptr_indicate_status_msg->MessageLength      = 20U;
  456.     ptr_indicate_status_msg->Status             = status;
  457.     ptr_indicate_status_msg->StatusBufferLength = 0U;
  458.     ptr_indicate_status_msg->StatusBufferOffset = 0U;
  459.     get_encapsulated_response_len               = 20U;

  460.     link_state_up   = false;
  461.     link_state_down = false;
  462.   }

  463.   if (get_encapsulated_response_len != 0U) {    // If response is available return it
  464.     *buf = (uint8_t *)get_encapsulated_response_buf;
  465.     *len =  get_encapsulated_response_len;
  466.     get_encapsulated_response_len = 0U;
  467.   }

  468.   return true;
  469. }


  470. // Callback function called when all data was sent
  471. // \return                    none.
  472. void USBD_CDC%Instance%_ACM_DataSent (void) {
  473. }


  474. // Callback function called when new data was received
  475. // \param[in]   len           number of bytes available to read.
  476. // \return                    none.
  477. void USBD_CDC%Instance%_ACM_DataReceived (uint32_t len) {
  478. }


  479. //! [code_USBD_User_CDC_ACM_RNDIS_VETH]


  480. // Global functions exported for Virtual Ethernet driver

  481. /**
  482.   \fn          ARM_ETH_LINK_STATE RNDIS%Instance%_GetLinkState (void)
  483.   \brief       Get RNDIS Device Link state (data initialized means link is up).
  484.   \return      current link status \ref ARM_ETH_LINK_STATE
  485. */
  486. ARM_ETH_LINK_STATE RNDIS%Instance%_GetLinkState (void) {
  487.   if (rndis_state == RNDIS_DATA_INITIALIZED) {
  488.     return ARM_ETH_LINK_UP;
  489.   }

  490.   return ARM_ETH_LINK_DOWN;
  491. }

  492. /**
  493.   \fn          int32_t RNDIS%Instance%_SendFrame (const uint8_t *frame, uint32_t len, uint32_t flags)
  494.   \brief       Send Ethernet frame over USB CDC ACM RNDIS.
  495.   \param[in]   frame  Pointer to frame buffer with data to send
  496.   \param[in]   len    Frame buffer length in bytes
  497.   \return      \ref execution_status
  498. */
  499. int32_t RNDIS%Instance%_SendFrame (const uint8_t *frame, uint32_t len) {
  500.   REMOTE_NDIS_PACKET_MSG_t *ptr_packet_msg;
  501.    int32_t                  usb_cdc_acm_status;

  502.   ptr_packet_msg = (REMOTE_NDIS_PACKET_MSG_t *)packet_in;

  503.   if ((rndis_state == RNDIS_DATA_INITIALIZED) &&
  504.       (len >= ETH_MIN_SIZE)                   &&
  505.       (len <= ETH_MAX_SIZE))                   {
  506.     memcpy((void *)&ptr_packet_msg->PayLoad[0], (void *)frame, len);
  507.     ptr_packet_msg->MessageType              = REMOTE_NDIS_PACKET_MSG;
  508.     ptr_packet_msg->MessageLength            = len + sizeof(REMOTE_NDIS_PACKET_MSG_t) - 4U;
  509.     ptr_packet_msg->DataOffset               = sizeof(REMOTE_NDIS_PACKET_MSG_t) - 12U;
  510.     ptr_packet_msg->DataLength               = len;
  511.     ptr_packet_msg->OutOfBandDataOffset      = 0U;
  512.     ptr_packet_msg->OutOfBandDataLength      = 0U;
  513.     ptr_packet_msg->NumOutOfBandDataElements = 0U;
  514.     ptr_packet_msg->PerPacketInfoOffset      = 0U;
  515.     ptr_packet_msg->PerPacketInfoLength      = 0U;
  516.     ptr_packet_msg->Reserved[0]              = 0U;
  517.     ptr_packet_msg->Reserved[1]              = 0U;
  518.     usb_cdc_acm_status = USBD_CDC_ACM_WriteData (%Instance%, (const uint8_t *)ptr_packet_msg, ptr_packet_msg->MessageLength);
  519.     if (usb_cdc_acm_status == ptr_packet_msg->MessageLength) {
  520.       rcv_ok++;
  521.       return ARM_DRIVER_OK;
  522.     }
  523.     if (usb_cdc_acm_status < 0) {
  524.       rcv_error++;
  525.       return ARM_DRIVER_ERROR;
  526.     }
  527.     if (usb_cdc_acm_status == 0) {
  528.       return ARM_DRIVER_ERROR_BUSY;
  529.     }
  530.   }

  531.   return ARM_DRIVER_ERROR;
  532. }

  533. /**
  534.   \fn          int32_t RNDIS%Instance%_ReadFrame (uint8_t *frame, uint32_t len)
  535.   \brief       Read data of Ethernet frame received over USB CDC ACM RNDIS.
  536.   \param[in]   frame  Pointer to frame buffer for data to read into
  537.   \param[in]   len    Frame buffer length in bytes
  538.   \return      number of data bytes read or execution status
  539.                  - value >= 0: number of data bytes read
  540.                  - value < 0: error occurred, value is execution status as defined with \ref execution_status
  541. */
  542. int32_t RNDIS%Instance%_ReadFrame (uint8_t *frame, uint32_t len) {
  543.   REMOTE_NDIS_PACKET_MSG_t *ptr_packet_msg;
  544.    int32_t                  usb_cdc_acm_status, data_len;

  545.   ptr_packet_msg = (REMOTE_NDIS_PACKET_MSG_t *)packet_out;

  546.   if ((rndis_state == RNDIS_DATA_INITIALIZED) &&
  547.       (len >= ETH_MIN_SIZE)                   &&
  548.       (len <= ETH_MAX_SIZE))                   {
  549.     usb_cdc_acm_status = USBD_CDC_ACM_ReadData (%Instance%, (uint8_t *)ptr_packet_msg, USBD_CDC%Instance%_ACM_RECEIVE_BUF_SIZE);
  550.     if ((usb_cdc_acm_status != 0) && (usb_cdc_acm_status == ptr_packet_msg->MessageLength)) {
  551.       data_len = len;
  552.       if (data_len > ptr_packet_msg->DataLength) {
  553.         data_len = ptr_packet_msg->DataLength;
  554.       }
  555.       memcpy((void *)frame, (void *)&ptr_packet_msg->PayLoad[0], data_len);
  556.       xmit_ok++;
  557.       return data_len;
  558.     }
  559.     if (usb_cdc_acm_status < 0) {
  560.       xmit_error++;
  561.       return ARM_DRIVER_ERROR;
  562.     }
  563.     if (usb_cdc_acm_status == 0) {
  564.       return ARM_DRIVER_ERROR_BUSY;
  565.     }
  566.   }

  567.   return 0;
  568. }

  569. /**
  570.   \fn          uint32_t RNDIS%Instance%_GetRxFrameSize (void)
  571.   \brief       Get size of Ethernet frame received over USB CDC ACM RNDIS.
  572.   \return      number of bytes in received frame
  573. */
  574. uint32_t RNDIS%Instance%_GetRxFrameSize (void) {
  575.   uint32_t avail_data_len;

  576.   avail_data_len = USBD_CDC_ACM_DataAvailable (%Instance%);

  577.   if (avail_data_len > (sizeof(REMOTE_NDIS_PACKET_MSG_t) - 4U)) {
  578.     avail_data_len -= (sizeof(REMOTE_NDIS_PACKET_MSG_t) - 4U);
  579.   }

  580.   return avail_data_len;
  581. }
复制代码


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106828
QQ
 楼主| 发表于 2020-7-4 13:42:28 | 显示全部楼层
v1.0.2:

  1. /*------------------------------------------------------------------------------
  2. * MDK Middleware - Component ::USB:Device:CDC
  3. * Copyright (c) 2018-2019 Arm Limited (or its affiliates). All rights reserved.
  4. *------------------------------------------------------------------------------
  5. * Name:    USBD_User_CDC_ACM_RNDIS_VETH_%Instance%.c
  6. * Purpose: USB Device Communication Device Class (CDC)
  7. *          Abstract Control Model (ACM)
  8. *          Remote Network Driver Interface Specification (RNDIS)
  9. *          User Module for a Virtual Ethernet
  10. * Rev.:    V1.0.2
  11. *----------------------------------------------------------------------------*/
  12. /**
  13. * \addtogroup usbd_cdcFunctions
  14. *
  15. * USBD_User_CDC_ACM_RNDIS_VETH_%Instance%.c implements the application specific
  16. * functionality of the CDC ACM class using RNDIS protocol and is used
  17. * to implement Network Interface Card (NIC) to the USB Host.
  18. * This user module works together with EMAC_CDC_ACM_RNDIS.c driver
  19. * to provide USB Host network access to Embedded Device over USB.
  20. *
  21. * The implementation depends on the configuration file USBD_Config_CDC_%Instance%.h.
  22. *
  23. */


  24. //! [code_USBD_User_CDC_ACM_RNDIS_VETH]

  25. #include <stdint.h>
  26. #include <stdbool.h>
  27. #include <string.h>

  28. #include "rl_usb.h"

  29. #include "Driver_ETH.h"
  30. #include "Driver_ETH_MAC.h"
  31. #include "Driver_ETH_PHY.h"
  32. #include "USBD_Config_CDC_%Instance%.h"


  33. //-------- <<< Use Configuration Wizard in Context Menu >>> --------------------

  34. // Configuration defines

  35. //   <s.17>MAC Address
  36. //     <i>Ethernet MAC Address in text representation
  37. //     <i>Value FF-FF-FF-FF-FF-FF is not allowed,
  38. //     <i>LSB of first byte must be 0 (an ethernet Multicast bit).
  39. //     <i>Default: "1E-30-6C-A2-45-5E"
  40. #define RNDIS_MAC_ADDR    "1E-30-6C-A2-45-5E"           // RNDIS MAC Address

  41. //   <o.0..5>Maximum number of multicast addresses <1-32>
  42. #define RNDIS_MCAST_NUM   16                            // RNDIS Number of Multicast Addresses supported

  43. //   <s.32>RNDIS Vendor Description
  44. #define RNDIS_VENDOR_DESC "Keil NIC (USB <-> ETH)"      // RNDIS Vendor Description

  45. //   <o.0..23>RNDIS Vendor Id Code <0x000000-0xFFFFFF>
  46. #define RNDIS_VENDOR_ID   0xFFFFFF                      // RNDIS three-byte IEEE-registered Vendor Code

  47. //------------- <<< end of configuration section >>> ---------------------------


  48. // Global functions exported by this module
  49.        ARM_ETH_LINK_STATE RNDIS%Instance%_GetLinkState  (void);
  50.        int32_t            RNDIS%Instance%_SendFrame     (const uint8_t *frame, uint32_t len);
  51.        int32_t            RNDIS%Instance%_ReadFrame     (      uint8_t *frame, uint32_t len);
  52.        uint32_t           RNDIS%Instance%_GetRxFrameSize(void);

  53. // Local functions
  54. static void               MAC_str_to_addr (const char *mac_str, uint8_t *mac_addr);
  55. static void               InitVars        (void);
  56. static void               ResetVars       (void);

  57. // Local variables
  58. static uint32_t           rndis_state;
  59. static ARM_ETH_LINK_STATE link_state;

  60. static bool               link_state_up;
  61. static bool               link_state_down;

  62. static uint32_t           packet_filter;
  63. static ARM_ETH_MAC_ADDR   mac_address;
  64. static ARM_ETH_MAC_ADDR   mcast_address[RNDIS_MCAST_NUM];

  65. static uint16_t           get_encapsulated_response_len;
  66. static uint32_t           get_encapsulated_response_buf[sizeof(REMOTE_NDIS_INITIALIZE_CMPLT_t)];

  67. static uint32_t           xmit_ok;
  68. static uint32_t           rcv_ok;
  69. static uint32_t           xmit_error;
  70. static uint32_t           rcv_error;
  71. static uint32_t           rcv_no_buffer;

  72. static uint32_t           packet_in [(USBD_CDC%Instance%_ACM_SEND_BUF_SIZE   +3)/4];
  73. static uint32_t           packet_out[(USBD_CDC%Instance%_ACM_RECEIVE_BUF_SIZE+3)/4];


  74. // Local functions

  75. // MAC Address conversion from string
  76. // \param[in]   mac_str   Pointer to wide string.
  77. // \param[out]  mac_addr  Pointer to address.
  78. static void MAC_str_to_addr (const char *mac_str, uint8_t *mac_addr) {
  79.   uint8_t c;
  80.   uint8_t n;
  81.   uint8_t i, j;
  82.   uint8_t str_len;

  83.   str_len = strlen(mac_str);
  84.   j = 0U;
  85.   for (i = 0U; i < str_len; i++) {
  86.     c = mac_str[i];
  87.     if         (c == '-') {
  88.       continue;
  89.     } else if ((c >= '0') && (c <= '9')) {
  90.       n = c - '0';
  91.     } else if ((c >= 'A') && (c <= 'F')) {
  92.       n = c - 'A' + 10U;
  93.     } else if ((c >= 'a') && (c <= 'f')) {
  94.       n = c - 'a' + 10U;
  95.     } else {
  96.       n = 0U;
  97.     }
  98.     if ((j & 1U) != 0U) {
  99.       mac_addr[j>>1] |= n;
  100.     } else {
  101.       mac_addr[j>>1]  = n << 4;
  102.     }
  103.     j++;
  104.   }
  105. }

  106. // Initialize variables
  107. void InitVars (void) {

  108.   rndis_state      = RNDIS_UNINITIALIZED;
  109.   link_state       = ARM_ETH_LINK_DOWN;

  110.   packet_filter    = 0U;

  111.   MAC_str_to_addr(RNDIS_MAC_ADDR, (uint8_t *)&mac_address);
  112.   memset((void *)mcast_address, 0, sizeof(mcast_address));

  113.   ResetVars();
  114. }

  115. // Reset variables
  116. static void ResetVars (void) {
  117.   link_state_up    = false;
  118.   link_state_down  = false;

  119.   get_encapsulated_response_len = 0U;

  120.   xmit_ok          = 0U;
  121.   rcv_ok           = 0U;
  122.   xmit_error       = 0U;
  123.   rcv_error        = 0U;
  124.   rcv_no_buffer    = 0U;
  125. }


  126. // USB CDC ACM callback global functions

  127. // Called during USBD_Initialize to initialize the USB CDC class instance (ACM).
  128. void USBD_CDC%Instance%_ACM_Initialize (void) {
  129.   InitVars();
  130. }


  131. // Called during USBD_Uninitialize to de-initialize the USB CDC class instance (ACM).
  132. void USBD_CDC%Instance%_ACM_Uninitialize (void) {
  133.   InitVars();
  134. }


  135. // Called upon USB Bus Reset Event.
  136. void USBD_CDC%Instance%_ACM_Reset (void) {
  137.   InitVars();
  138. }


  139. // Callback function called upon reception of request send encapsulated command sent by the USB Host.
  140. // \param[in]   buf           buffer that contains send encapsulated command request.
  141. // \param[in]   len           length of send encapsulated command request.
  142. // \return      true          send encapsulated command request processed.
  143. // \return      false         send encapsulated command request not supported or not processed.
  144. bool USBD_CDC%Instance%_ACM_SendEncapsulatedCommand (const uint8_t *buf, uint16_t len) {
  145.   REMOTE_NDIS_INITIALIZE_MSG_t   *ptr_init_msg;
  146.   REMOTE_NDIS_INITIALIZE_CMPLT_t *ptr_init_cmplt;
  147.   REMOTE_NDIS_HALT_MSG_t         *ptr_halt_msg;
  148.   REMOTE_NDIS_QUERY_MSG_t        *ptr_query_msg;
  149.   REMOTE_NDIS_QUERY_CMPLT_t      *ptr_query_cmplt;
  150.   REMOTE_NDIS_SET_MSG_t          *ptr_set_msg;
  151.   REMOTE_NDIS_SET_CMPLT_t        *ptr_set_cmplt;
  152.   REMOTE_NDIS_RESET_MSG_t        *ptr_reset_msg;
  153.   REMOTE_NDIS_RESET_CMPLT_t      *ptr_reset_cmplt;
  154.   REMOTE_NDIS_KEEPALIVE_MSG_t    *ptr_keepalive_msg;
  155.   REMOTE_NDIS_KEEPALIVE_CMPLT_t  *ptr_keepalive_cmplt;
  156.   uint32_t                        status, val;
  157.    int32_t                        i;
  158.   uint32_t                        num, by;
  159.   uint16_t                        msg_type;

  160.   msg_type = __UNALIGNED_UINT16_READ(buf);  // Extract message type of received message

  161.   // In uninitialized state only allowed messages are INITALIZE and HALT
  162.   if ((rndis_state == RNDIS_UNINITIALIZED)     &&
  163.       (msg_type != REMOTE_NDIS_INITIALIZE_MSG) &&
  164.       (msg_type != REMOTE_NDIS_HALT_MSG))       {
  165.     return false;
  166.   }

  167.   status = RNDIS_STATUS_SUCCESS;            // Default message processing status
  168.   get_encapsulated_response_len = 0U;       // Prepare default no response size

  169.   switch (msg_type) {                       // MessageType
  170.     case REMOTE_NDIS_INITIALIZE_MSG:
  171.       // Check message is valid
  172.       ptr_init_msg = (REMOTE_NDIS_INITIALIZE_MSG_t *)buf;
  173.       if (ptr_init_msg->MessageLength       != sizeof(REMOTE_NDIS_INITIALIZE_MSG_t)) { return false; }
  174.       if (ptr_init_msg->MajorVersion        != RNDIS_MAJOR_VERSION)                  { return false; }
  175.       if (ptr_init_msg->MinorVersion        != RNDIS_MINOR_VERSION)                  { return false; }
  176.       if (ptr_init_msg->MaxTransferSize     != 16384U)                               { return false; }

  177.       rndis_state = RNDIS_INITIALIZED;

  178.       // Prepare response
  179.       ptr_init_cmplt = (REMOTE_NDIS_INITIALIZE_CMPLT_t *)get_encapsulated_response_buf;
  180.       ptr_init_cmplt->MessageType            = REMOTE_NDIS_INITIALIZE_CMPLT;
  181.       ptr_init_cmplt->MessageLength          = sizeof(REMOTE_NDIS_INITIALIZE_CMPLT_t);
  182.       ptr_init_cmplt->RequestID              = ptr_init_msg->RequestID;
  183.       ptr_init_cmplt->Status                 = status;
  184.       ptr_init_cmplt->MajorVersion           = RNDIS_MAJOR_VERSION;
  185.       ptr_init_cmplt->MinorVersion           = RNDIS_MINOR_VERSION;
  186.       ptr_init_cmplt->DeviceFlags            = RNDIS_DF_CONNECTIONLESS;
  187.       ptr_init_cmplt->Medium                 = NdisMedium802_3;
  188.       ptr_init_cmplt->MaxPacketsPerTransfer  = 1U;
  189.       ptr_init_cmplt->MaxTransferSize        = USBD_CDC%Instance%_ACM_RECEIVE_BUF_SIZE;
  190.       ptr_init_cmplt->PacketAlignmentFactor  = 2U;
  191.       ptr_init_cmplt->Reserved[0]            = 0U;
  192.       ptr_init_cmplt->Reserved[1]            = 0U;
  193.       get_encapsulated_response_len          = ptr_init_cmplt->MessageLength;
  194.       break;

  195.     case REMOTE_NDIS_HALT_MSG:
  196.       // Check message is valid
  197.       ptr_halt_msg = (REMOTE_NDIS_HALT_MSG_t *)buf;
  198.       if (ptr_halt_msg->MessageLength != sizeof(REMOTE_NDIS_HALT_MSG_t)) { return false; }

  199.       rndis_state = RNDIS_UNINITIALIZED;

  200.       // This message does not have a response
  201.       return true;

  202.     case REMOTE_NDIS_QUERY_MSG:
  203.       // Check message is valid
  204.       ptr_query_msg = (REMOTE_NDIS_QUERY_MSG_t *)buf;
  205.       if (ptr_query_msg->MessageLength < 28U) { return false; }

  206.       // Prepare response
  207.       ptr_query_cmplt = (REMOTE_NDIS_QUERY_CMPLT_t *)get_encapsulated_response_buf;
  208.       ptr_query_cmplt->MessageType             = REMOTE_NDIS_QUERY_CMPLT;
  209.       ptr_query_cmplt->RequestID               = ptr_query_msg->RequestID;
  210.       ptr_query_cmplt->InformationBufferOffset = 16U;
  211.       switch (ptr_query_msg->Oid) {             // Handle OID
  212.         case OID_GEN_SUPPORTED_LIST:
  213.           ptr_query_cmplt->InformationBufferLength = 23U * 4U;
  214.           ptr_query_cmplt->OIDInputBuffer[0]       = OID_GEN_SUPPORTED_LIST;
  215.           ptr_query_cmplt->OIDInputBuffer[1]       = OID_GEN_HARDWARE_STATUS;
  216.           ptr_query_cmplt->OIDInputBuffer[2]       = OID_GEN_MEDIA_SUPPORTED;
  217.           ptr_query_cmplt->OIDInputBuffer[3]       = OID_GEN_MEDIA_IN_USE;
  218.           ptr_query_cmplt->OIDInputBuffer[4]       = OID_GEN_MAXIMUM_FRAME_SIZE;
  219.           ptr_query_cmplt->OIDInputBuffer[5]       = OID_GEN_LINK_SPEED;
  220.           ptr_query_cmplt->OIDInputBuffer[6]       = OID_GEN_TRANSMIT_BLOCK_SIZE;
  221.           ptr_query_cmplt->OIDInputBuffer[7]       = OID_GEN_RECEIVE_BLOCK_SIZE;
  222.           ptr_query_cmplt->OIDInputBuffer[8]       = OID_GEN_VENDOR_ID;
  223.           ptr_query_cmplt->OIDInputBuffer[9]       = OID_GEN_VENDOR_DESCRIPTION;
  224.           ptr_query_cmplt->OIDInputBuffer[10]      = OID_GEN_CURRENT_PACKET_FILTER;
  225.           ptr_query_cmplt->OIDInputBuffer[11]      = OID_GEN_MAXIMUM_TOTAL_SIZE;
  226.           ptr_query_cmplt->OIDInputBuffer[12]      = OID_GEN_MEDIA_CONNECT_STATUS;
  227.           ptr_query_cmplt->OIDInputBuffer[13]      = OID_GEN_PHYSICAL_MEDIUM;
  228.           ptr_query_cmplt->OIDInputBuffer[14]      = OID_GEN_XMIT_OK;
  229.           ptr_query_cmplt->OIDInputBuffer[15]      = OID_GEN_RCV_OK;
  230.           ptr_query_cmplt->OIDInputBuffer[16]      = OID_GEN_XMIT_ERROR;
  231.           ptr_query_cmplt->OIDInputBuffer[17]      = OID_GEN_RCV_ERROR;
  232.           ptr_query_cmplt->OIDInputBuffer[18]      = OID_GEN_RCV_NO_BUFFER;
  233.           ptr_query_cmplt->OIDInputBuffer[19]      = OID_802_3_PERMANENT_ADDRESS;
  234.           ptr_query_cmplt->OIDInputBuffer[20]      = OID_802_3_CURRENT_ADDRESS;
  235.           ptr_query_cmplt->OIDInputBuffer[21]      = OID_802_3_MULTICAST_LIST;
  236.           ptr_query_cmplt->OIDInputBuffer[22]      = OID_802_3_MAXIMUM_LIST_SIZE;
  237.           break;
  238.         case OID_GEN_HARDWARE_STATUS:
  239.           ptr_query_cmplt->InformationBufferLength = 4U;
  240.           if (link_state == ARM_ETH_LINK_UP) {
  241.             ptr_query_cmplt->OIDInputBuffer[0]     = NdisHardwareStatusReady;
  242.           } else {
  243.             ptr_query_cmplt->OIDInputBuffer[0]     = NdisHardwareStatusNotReady;
  244.           }
  245.           break;
  246.         case OID_GEN_MEDIA_SUPPORTED:
  247.         case OID_GEN_MEDIA_IN_USE:
  248.           ptr_query_cmplt->InformationBufferLength = 4U;
  249.           ptr_query_cmplt->OIDInputBuffer[0]       = NdisMedium802_3;
  250.           break;
  251.         case OID_GEN_MAXIMUM_FRAME_SIZE:
  252.           ptr_query_cmplt->InformationBufferLength = 4U;
  253.           ptr_query_cmplt->OIDInputBuffer[0]       = ETH_MTU_SIZE;
  254.           break;
  255.         case OID_GEN_LINK_SPEED:
  256.           ptr_query_cmplt->InformationBufferLength = 4U;
  257.           ptr_query_cmplt->OIDInputBuffer[0]       = 100000000U / 100U; // 100 MBit/s
  258.           break;
  259.         case OID_GEN_TRANSMIT_BLOCK_SIZE:
  260.           ptr_query_cmplt->InformationBufferLength = 4U;
  261.           ptr_query_cmplt->OIDInputBuffer[0]       = USBD_CDC%Instance%_ACM_SEND_BUF_SIZE;
  262.           break;
  263.         case OID_GEN_RECEIVE_BLOCK_SIZE:
  264.           ptr_query_cmplt->InformationBufferLength = 4U;
  265.           ptr_query_cmplt->OIDInputBuffer[0]       = USBD_CDC%Instance%_ACM_RECEIVE_BUF_SIZE;
  266.           break;
  267.         case OID_GEN_VENDOR_ID:
  268.           ptr_query_cmplt->InformationBufferLength = 4U;
  269.           ptr_query_cmplt->OIDInputBuffer[0]       = RNDIS_VENDOR_ID;
  270.           break;
  271.         case OID_GEN_VENDOR_DESCRIPTION:
  272.           ptr_query_cmplt->InformationBufferLength = strlen(RNDIS_VENDOR_DESC) + 1;
  273.           memset((void *)&ptr_query_cmplt->OIDInputBuffer[0], 0, ptr_query_cmplt->InformationBufferLength + 1U);
  274.           memcpy((void *)&ptr_query_cmplt->OIDInputBuffer[0], RNDIS_VENDOR_DESC, strlen(RNDIS_VENDOR_DESC));
  275.           break;
  276.         case OID_GEN_CURRENT_PACKET_FILTER:
  277.           ptr_query_cmplt->InformationBufferLength = 4U;
  278.           val = 0U;
  279.           if ((packet_filter & ARM_ETH_MAC_ADDRESS_MULTICAST) != 0U) { val |= RNDIS_FILTER_ALL_MULTICAST; }
  280.           if ((packet_filter & ARM_ETH_MAC_ADDRESS_BROADCAST) != 0U) { val |= RNDIS_FILTER_BROADCAST;     }
  281.           if ((packet_filter & ARM_ETH_MAC_ADDRESS_ALL)       != 0U) { val |= RNDIS_FILTER_PROMISCUOUS;   }
  282.           ptr_query_cmplt->OIDInputBuffer[0]       = val;
  283.           break;
  284.         case OID_GEN_MAXIMUM_TOTAL_SIZE:
  285.           ptr_query_cmplt->InformationBufferLength = 4U;
  286.           ptr_query_cmplt->OIDInputBuffer[0]       = sizeof(REMOTE_NDIS_PACKET_MSG_t) - 4U + ETH_MAX_SIZE;
  287.           break;
  288.         case OID_GEN_MEDIA_CONNECT_STATUS:
  289.           ptr_query_cmplt->InformationBufferLength = 4U;
  290.           if (link_state == ARM_ETH_LINK_UP) {
  291.             ptr_query_cmplt->OIDInputBuffer[0]     = NdisMediaStateConnected;
  292.           } else {
  293.             ptr_query_cmplt->OIDInputBuffer[0]     = NdisMediaStateDisconnected;
  294.           }
  295.           break;

  296.         case OID_GEN_PHYSICAL_MEDIUM:
  297.           ptr_query_cmplt->InformationBufferLength = 4U;
  298.           ptr_query_cmplt->OIDInputBuffer[0]       = NdisPhysicalMediumUnspecified;
  299.           break;

  300.         case OID_GEN_XMIT_OK:
  301.           ptr_query_cmplt->InformationBufferLength = 4U;
  302.           ptr_query_cmplt->OIDInputBuffer[0]       = xmit_ok;
  303.           break;
  304.         case OID_GEN_RCV_OK:
  305.           ptr_query_cmplt->InformationBufferLength = 4U;
  306.           ptr_query_cmplt->OIDInputBuffer[0]       = rcv_ok;
  307.           break;
  308.         case OID_GEN_XMIT_ERROR:
  309.           ptr_query_cmplt->InformationBufferLength = 4U;
  310.           ptr_query_cmplt->OIDInputBuffer[0]       = xmit_error;
  311.           break;
  312.         case OID_GEN_RCV_ERROR:
  313.           ptr_query_cmplt->InformationBufferLength = 4U;
  314.           ptr_query_cmplt->OIDInputBuffer[0]       = rcv_error;
  315.           break;
  316.         case OID_GEN_RCV_NO_BUFFER:
  317.           ptr_query_cmplt->InformationBufferLength = 4U;
  318.           ptr_query_cmplt->OIDInputBuffer[0]       = rcv_no_buffer;
  319.           break;

  320.         case OID_802_3_PERMANENT_ADDRESS:
  321.         case OID_802_3_CURRENT_ADDRESS:
  322.           ptr_query_cmplt->InformationBufferLength = 6U;
  323.           memcpy((void *)&ptr_query_cmplt->OIDInputBuffer[0], &mac_address, sizeof(ARM_ETH_MAC_ADDR));
  324.           break;
  325.         case OID_802_3_MULTICAST_LIST:
  326.           for (i = 0U; i < RNDIS_MCAST_NUM; i++) {
  327.             if (memcmp(&mcast_address[i], "\0\0\0\0\0\0", 6) == 0) {
  328.               break;
  329.             }
  330.           }
  331.           if (i == 0U) {
  332.             num = 0U;
  333.             ptr_query_cmplt->InformationBufferOffset = 0U;
  334.           } else {
  335.             num = i + 1U;
  336.             memcpy((void *)&ptr_query_cmplt->OIDInputBuffer[0], mcast_address, num * sizeof(ARM_ETH_MAC_ADDR));
  337.           }
  338.           ptr_query_cmplt->InformationBufferLength = num * sizeof(ARM_ETH_MAC_ADDR);
  339.           break;
  340.         case OID_802_3_MAXIMUM_LIST_SIZE:
  341.           ptr_query_cmplt->InformationBufferLength = 4U;
  342.           ptr_query_cmplt->OIDInputBuffer[0]       = RNDIS_MCAST_NUM;
  343.           break;

  344.         default:
  345.           ptr_query_cmplt->InformationBufferOffset = 0U;
  346.           ptr_query_cmplt->InformationBufferLength = 0U;
  347.           status = RNDIS_STATUS_NOT_SUPPORTED;
  348.           break;
  349.       }
  350.       ptr_query_cmplt->Status        = status;
  351.       ptr_query_cmplt->MessageLength = ptr_query_cmplt->InformationBufferLength + 24U;
  352.       get_encapsulated_response_len  = ptr_query_cmplt->MessageLength;
  353.       break;

  354.     case REMOTE_NDIS_SET_MSG:
  355.       // Check message is valid
  356.       ptr_set_msg = (REMOTE_NDIS_SET_MSG_t *)buf;
  357.       if (ptr_set_msg->MessageLength < 28U) { return false; }

  358.       // Prepare response
  359.       ptr_set_cmplt = (REMOTE_NDIS_SET_CMPLT_t *)get_encapsulated_response_buf;
  360.       ptr_set_cmplt->MessageType               = REMOTE_NDIS_SET_CMPLT;
  361.       ptr_set_cmplt->MessageLength             = sizeof(REMOTE_NDIS_SET_CMPLT_t);
  362.       ptr_set_cmplt->RequestID                 = ptr_set_msg->RequestID;

  363.       switch (ptr_set_msg->Oid) {               // Handle OID
  364.         case OID_802_3_MULTICAST_LIST:
  365.           by = ptr_set_msg->InformationBufferLength;
  366.           if (by > (sizeof(ARM_ETH_MAC_ADDR) * RNDIS_MCAST_NUM)) {
  367.             by = sizeof(ARM_ETH_MAC_ADDR) * RNDIS_MCAST_NUM;
  368.           }
  369.           if (by > 0U) {
  370.             memcpy(mcast_address, (void *)&ptr_set_msg->OIDInputBuffer[0], by);
  371.             num = by / sizeof(ARM_ETH_MAC_ADDR);
  372.           }
  373.           break;
  374.         case OID_GEN_CURRENT_PACKET_FILTER:
  375.           if ((ptr_set_msg->InformationBufferLength == 4U) &&
  376.               (ptr_set_msg->InformationBufferOffset != 0U)) {
  377.             val = *(uint32_t *)(((uint8_t *)&ptr_set_msg->RequestID) + ptr_set_msg->InformationBufferOffset);
  378.             if (val != 0U) {
  379.               if ((val & RNDIS_FILTER_ALL_MULTICAST) != 0U) { packet_filter |= ARM_ETH_MAC_ADDRESS_MULTICAST; }
  380.               if ((val & RNDIS_FILTER_BROADCAST)     != 0U) { packet_filter |= ARM_ETH_MAC_ADDRESS_BROADCAST; }
  381.               if ((val & RNDIS_FILTER_PROMISCUOUS)   != 0U) { packet_filter |= ARM_ETH_MAC_ADDRESS_ALL;       }
  382.               if (link_state == ARM_ETH_LINK_DOWN) {
  383.                 link_state    = ARM_ETH_LINK_UP;
  384.                 link_state_up = true;
  385.               }
  386.               rndis_state = RNDIS_DATA_INITIALIZED;
  387.             } else {
  388.               if (rndis_state == RNDIS_DATA_INITIALIZED) {
  389.                 rndis_state = RNDIS_INITIALIZED;
  390.               }
  391.             }
  392.           } else {
  393.             status = RNDIS_STATUS_FAILURE;
  394.           }
  395.           break;
  396.         default:
  397.           status = RNDIS_STATUS_NOT_SUPPORTED;
  398.           break;
  399.       }

  400.       ptr_set_cmplt->Status         = status;
  401.       get_encapsulated_response_len = ptr_set_cmplt->MessageLength;
  402.       break;

  403.     case REMOTE_NDIS_RESET_MSG:
  404.       // Check message is valid
  405.       ptr_reset_msg = (REMOTE_NDIS_RESET_MSG_t *)buf;
  406.       if (ptr_reset_msg->MessageLength != sizeof(REMOTE_NDIS_RESET_MSG_t)) { return false; }

  407.       ResetVars();

  408.       // Prepare response
  409.       ptr_reset_cmplt = (REMOTE_NDIS_RESET_CMPLT_t *)get_encapsulated_response_buf;
  410.       ptr_reset_cmplt->MessageType             = REMOTE_NDIS_RESET_CMPLT;
  411.       ptr_reset_cmplt->MessageLength           = sizeof(REMOTE_NDIS_RESET_CMPLT_t);
  412.       ptr_reset_cmplt->Status                  = status;
  413.       ptr_reset_cmplt->AddressingReset         = 0U;
  414.       get_encapsulated_response_len            = ptr_reset_cmplt->MessageLength;
  415.       break;

  416.     case REMOTE_NDIS_KEEPALIVE_MSG:
  417.       // Check message is valid
  418.       ptr_keepalive_msg = (REMOTE_NDIS_KEEPALIVE_MSG_t *)buf;
  419.       if (ptr_keepalive_msg->MessageLength != sizeof(REMOTE_NDIS_KEEPALIVE_MSG_t)) { return false; }

  420.       // Prepare response
  421.       ptr_keepalive_cmplt = (REMOTE_NDIS_KEEPALIVE_CMPLT_t *)get_encapsulated_response_buf;
  422.       ptr_keepalive_cmplt->MessageType         = REMOTE_NDIS_KEEPALIVE_CMPLT;
  423.       ptr_keepalive_cmplt->MessageLength       = sizeof(REMOTE_NDIS_KEEPALIVE_CMPLT_t);
  424.       ptr_keepalive_cmplt->RequestID           = ptr_keepalive_msg->RequestID;
  425.       ptr_keepalive_cmplt->Status              = status;
  426.       get_encapsulated_response_len            = ptr_keepalive_cmplt->MessageLength;
  427.       break;

  428.     default:
  429.       return false;
  430.   }

  431.   if (get_encapsulated_response_len != 0U) {
  432.     // If response is prepared send notification over Interrupt Endpoint
  433.     USBD_CDC_ACM_Notify_ResponseAvailable (%Instance%);
  434.   }

  435.   return true;
  436. }


  437. // Callback function called upon reception of request to get encapsulated response sent by the USB Host.
  438. // \param[in]   max_len       maximum number of data bytes that USB Host expects to receive
  439. // \param[out]  buf           pointer to buffer containing get encapsulated response to be returned to USB Host.
  440. // \param[out]  len           pointer to number of data bytes to be returned to USB Host.
  441. // \return      true          get encapsulated response request processed.
  442. // \return      false         get encapsulated response request not supported or not processed.
  443. bool USBD_CDC%Instance%_ACM_GetEncapsulatedResponse (uint16_t max_len, uint8_t **buf, uint16_t *len) {
  444.   REMOTE_NDIS_INDICATE_STATUS_MSG_t *ptr_indicate_status_msg;
  445.   uint32_t                           status;

  446.   if (link_state_up || link_state_down) {   // Generate unsolicited INDICATE STATUS message if link status has changed
  447.     if (link_state_up) {
  448.       status = RNDIS_STATUS_MEDIA_CONNECT;
  449.     } else {
  450.       status = RNDIS_STATUS_MEDIA_DISCONNECT;
  451.     }

  452.     // Prepare INDICATE STATUS message
  453.     ptr_indicate_status_msg = (REMOTE_NDIS_INDICATE_STATUS_MSG_t *)get_encapsulated_response_buf;
  454.     ptr_indicate_status_msg->MessageType        = REMOTE_NDIS_INDICATE_STATUS_MSG;
  455.     ptr_indicate_status_msg->MessageLength      = 20U;
  456.     ptr_indicate_status_msg->Status             = status;
  457.     ptr_indicate_status_msg->StatusBufferLength = 0U;
  458.     ptr_indicate_status_msg->StatusBufferOffset = 0U;
  459.     get_encapsulated_response_len               = 20U;

  460.     link_state_up   = false;
  461.     link_state_down = false;
  462.   }

  463.   if (get_encapsulated_response_len != 0U) {    // If response is available return it
  464.     *buf = (uint8_t *)get_encapsulated_response_buf;
  465.     *len =  get_encapsulated_response_len;
  466.     get_encapsulated_response_len = 0U;
  467.   }

  468.   return true;
  469. }


  470. // Callback function called when all data was sent
  471. // \return                    none.
  472. void USBD_CDC%Instance%_ACM_DataSent (void) {
  473. }


  474. // Callback function called when new data was received
  475. // \param[in]   len           number of bytes available to read.
  476. // \return                    none.
  477. void USBD_CDC%Instance%_ACM_DataReceived (uint32_t len) {
  478. }


  479. //! [code_USBD_User_CDC_ACM_RNDIS_VETH]


  480. // Global functions exported for Virtual Ethernet driver

  481. /**
  482.   \fn          ARM_ETH_LINK_STATE RNDIS%Instance%_GetLinkState (void)
  483.   \brief       Get RNDIS Device Link state (data initialized means link is up).
  484.   \return      current link status \ref ARM_ETH_LINK_STATE
  485. */
  486. ARM_ETH_LINK_STATE RNDIS%Instance%_GetLinkState (void) {
  487.   if (rndis_state == RNDIS_DATA_INITIALIZED) {
  488.     return ARM_ETH_LINK_UP;
  489.   }

  490.   return ARM_ETH_LINK_DOWN;
  491. }

  492. /**
  493.   \fn          int32_t RNDIS%Instance%_SendFrame (const uint8_t *frame, uint32_t len, uint32_t flags)
  494.   \brief       Send Ethernet frame over USB CDC ACM RNDIS.
  495.   \param[in]   frame  Pointer to frame buffer with data to send
  496.   \param[in]   len    Frame buffer length in bytes
  497.   \return      \ref execution_status
  498. */
  499. int32_t RNDIS%Instance%_SendFrame (const uint8_t *frame, uint32_t len) {
  500.   REMOTE_NDIS_PACKET_MSG_t *ptr_packet_msg;
  501.    int32_t                  usb_cdc_acm_status;

  502.   ptr_packet_msg = (REMOTE_NDIS_PACKET_MSG_t *)packet_in;

  503.   if ((rndis_state == RNDIS_DATA_INITIALIZED) &&
  504.       (len >= ETH_MIN_SIZE)                   &&
  505.       (len <= ETH_MAX_SIZE))                   {
  506.     memcpy((void *)&ptr_packet_msg->PayLoad[0], (void *)frame, len);
  507.     ptr_packet_msg->MessageType              = REMOTE_NDIS_PACKET_MSG;
  508.     ptr_packet_msg->MessageLength            = len + sizeof(REMOTE_NDIS_PACKET_MSG_t) - 4U;
  509.     ptr_packet_msg->DataOffset               = sizeof(REMOTE_NDIS_PACKET_MSG_t) - 12U;
  510.     ptr_packet_msg->DataLength               = len;
  511.     ptr_packet_msg->OutOfBandDataOffset      = 0U;
  512.     ptr_packet_msg->OutOfBandDataLength      = 0U;
  513.     ptr_packet_msg->NumOutOfBandDataElements = 0U;
  514.     ptr_packet_msg->PerPacketInfoOffset      = 0U;
  515.     ptr_packet_msg->PerPacketInfoLength      = 0U;
  516.     ptr_packet_msg->Reserved[0]              = 0U;
  517.     ptr_packet_msg->Reserved[1]              = 0U;
  518.     usb_cdc_acm_status = USBD_CDC_ACM_WriteData (%Instance%, (const uint8_t *)ptr_packet_msg, ptr_packet_msg->MessageLength);
  519.     if (usb_cdc_acm_status == ptr_packet_msg->MessageLength) {
  520.       rcv_ok++;
  521.       return ARM_DRIVER_OK;
  522.     }
  523.     if (usb_cdc_acm_status < 0) {
  524.       rcv_error++;
  525.       return ARM_DRIVER_ERROR;
  526.     }
  527.     if (usb_cdc_acm_status == 0) {
  528.       return ARM_DRIVER_ERROR_BUSY;
  529.     }
  530.   }

  531.   return ARM_DRIVER_ERROR;
  532. }

  533. /**
  534.   \fn          int32_t RNDIS%Instance%_ReadFrame (uint8_t *frame, uint32_t len)
  535.   \brief       Read data of Ethernet frame received over USB CDC ACM RNDIS.
  536.   \param[in]   frame  Pointer to frame buffer for data to read into
  537.   \param[in]   len    Frame buffer length in bytes
  538.   \return      number of data bytes read or execution status
  539.                  - value >= 0: number of data bytes read
  540.                  - value < 0: error occurred, value is execution status as defined with \ref execution_status
  541. */
  542. int32_t RNDIS%Instance%_ReadFrame (uint8_t *frame, uint32_t len) {
  543.   REMOTE_NDIS_PACKET_MSG_t *ptr_packet_msg;
  544.    int32_t                  usb_cdc_acm_status, data_len;

  545.   ptr_packet_msg = (REMOTE_NDIS_PACKET_MSG_t *)packet_out;

  546.   if ((rndis_state == RNDIS_DATA_INITIALIZED) &&
  547.       (len >= ETH_MIN_SIZE)                   &&
  548.       (len <= ETH_MAX_SIZE))                   {
  549.     usb_cdc_acm_status = USBD_CDC_ACM_ReadData (%Instance%, (uint8_t *)ptr_packet_msg, USBD_CDC%Instance%_ACM_RECEIVE_BUF_SIZE);
  550.     if ((usb_cdc_acm_status != 0) && (usb_cdc_acm_status == ptr_packet_msg->MessageLength)) {
  551.       data_len = len;
  552.       if (data_len > ptr_packet_msg->DataLength) {
  553.         data_len = ptr_packet_msg->DataLength;
  554.       }
  555.       memcpy((void *)frame, (void *)&ptr_packet_msg->PayLoad[0], data_len);
  556.       xmit_ok++;
  557.       return data_len;
  558.     }
  559.     if (usb_cdc_acm_status < 0) {
  560.       xmit_error++;
  561.       return ARM_DRIVER_ERROR;
  562.     }
  563.     if (usb_cdc_acm_status == 0) {
  564.       return ARM_DRIVER_ERROR_BUSY;
  565.     }
  566.   }

  567.   return 0;
  568. }

  569. /**
  570.   \fn          uint32_t RNDIS%Instance%_GetRxFrameSize (void)
  571.   \brief       Get size of Ethernet frame received over USB CDC ACM RNDIS.
  572.   \return      number of bytes in received frame
  573. */
  574. uint32_t RNDIS%Instance%_GetRxFrameSize (void) {
  575.   uint32_t avail_data_len;

  576.   avail_data_len = USBD_CDC_ACM_DataAvailable (%Instance%);

  577.   if (avail_data_len > (sizeof(REMOTE_NDIS_PACKET_MSG_t) - 4U)) {
  578.     avail_data_len -= (sizeof(REMOTE_NDIS_PACKET_MSG_t) - 4U);
  579.   }

  580.   return avail_data_len;
  581. }
复制代码


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106828
QQ
 楼主| 发表于 2020-7-4 13:43:03 | 显示全部楼层
V1.0.3:

  1. /*------------------------------------------------------------------------------
  2. * MDK Middleware - Component ::USB:Device:CDC
  3. * Copyright (c) 2018-2020 Arm Limited (or its affiliates). All rights reserved.
  4. *------------------------------------------------------------------------------
  5. * Name:    USBD_User_CDC_ACM_RNDIS_VETH_%Instance%.c
  6. * Purpose: USB Device Communication Device Class (CDC)
  7. *          Abstract Control Model (ACM)
  8. *          Remote Network Driver Interface Specification (RNDIS)
  9. *          User Module for a Virtual Ethernet
  10. * Rev.:    V1.0.3
  11. *----------------------------------------------------------------------------*/
  12. /**
  13. * \addtogroup usbd_cdcFunctions
  14. *
  15. * USBD_User_CDC_ACM_RNDIS_VETH_%Instance%.c implements the application specific
  16. * functionality of the CDC ACM class using RNDIS protocol and is used
  17. * to implement Network Interface Card (NIC) to the USB Host.
  18. * This user module works together with EMAC_CDC_ACM_RNDIS.c driver
  19. * to provide USB Host network access to Embedded Device over USB.
  20. *
  21. * The implementation depends on the configuration file USBD_Config_CDC_%Instance%.h.
  22. *
  23. */


  24. //! [code_USBD_User_CDC_ACM_RNDIS_VETH]

  25. #include <stdint.h>
  26. #include <stdbool.h>
  27. #include <string.h>

  28. #include "rl_usb.h"

  29. #include "Driver_ETH.h"
  30. #include "Driver_ETH_MAC.h"
  31. #include "Driver_ETH_PHY.h"
  32. #include "USBD_Config_CDC_%Instance%.h"


  33. //-------- <<< Use Configuration Wizard in Context Menu >>> --------------------

  34. // Configuration defines

  35. //   <s.17>MAC Address
  36. //     <i>Ethernet MAC Address in text representation
  37. //     <i>Value FF-FF-FF-FF-FF-FF is not allowed,
  38. //     <i>LSB of first byte must be 0 (an ethernet Multicast bit).
  39. //     <i>Default: "1E-30-6C-A2-45-5E"
  40. #define RNDIS_MAC_ADDR    "1E-30-6C-A2-45-5E"           // RNDIS MAC Address

  41. //   <o.0..5>Maximum number of multicast addresses <1-32>
  42. #define RNDIS_MCAST_NUM   16                            // RNDIS Number of Multicast Addresses supported

  43. //   <s.32>RNDIS Vendor Description
  44. #define RNDIS_VENDOR_DESC "Keil NIC (USB <-> ETH)"      // RNDIS Vendor Description

  45. //   <o.0..23>RNDIS Vendor Id Code <0x000000-0xFFFFFF>
  46. #define RNDIS_VENDOR_ID   0xFFFFFF                      // RNDIS three-byte IEEE-registered Vendor Code

  47. //------------- <<< end of configuration section >>> ---------------------------


  48. // Global functions exported by this module
  49.        ARM_ETH_LINK_STATE RNDIS%Instance%_GetLinkState  (void);
  50.        int32_t            RNDIS%Instance%_SendFrame     (const uint8_t *frame, uint32_t len);
  51.        int32_t            RNDIS%Instance%_ReadFrame     (      uint8_t *frame, uint32_t len);
  52.        uint32_t           RNDIS%Instance%_GetRxFrameSize(void);

  53. // Local functions
  54. static void               MAC_str_to_addr (const char *mac_str, uint8_t *mac_addr);
  55. static void               InitVars        (void);
  56. static void               ResetVars       (void);

  57. // Local variables
  58. static uint32_t           rndis_state;
  59. static ARM_ETH_LINK_STATE link_state;

  60. static bool               link_state_up;
  61. static bool               link_state_down;

  62. static uint32_t           packet_filter;
  63. static ARM_ETH_MAC_ADDR   mac_address;
  64. static ARM_ETH_MAC_ADDR   mcast_address[RNDIS_MCAST_NUM];

  65. static uint32_t           get_encapsulated_response_len;
  66. static uint32_t           get_encapsulated_response_buf[128/4];

  67. static uint32_t           xmit_ok;
  68. static uint32_t           rcv_ok;
  69. static uint32_t           xmit_error;
  70. static uint32_t           rcv_error;
  71. static uint32_t           rcv_no_buffer;

  72. static uint32_t           packet_in [(USBD_CDC%Instance%_ACM_SEND_BUF_SIZE   +3)/4];
  73. static uint32_t           packet_out[(USBD_CDC%Instance%_ACM_RECEIVE_BUF_SIZE+3)/4];


  74. // Local functions

  75. // MAC Address conversion from string
  76. // \param[in]   mac_str   Pointer to wide string.
  77. // \param[out]  mac_addr  Pointer to address.
  78. static void MAC_str_to_addr (const char *mac_str, uint8_t *mac_addr) {
  79.   uint8_t  c;
  80.   uint8_t  n;
  81.   uint32_t i, j;
  82.   uint32_t str_len;

  83.   str_len = strlen(mac_str);
  84.   j = 0U;
  85.   for (i = 0U; i < str_len; i++) {
  86.     c = (uint8_t)mac_str[i];
  87.     if         (c == '-') {
  88.       continue;
  89.     } else if ((c >= '0') && (c <= '9')) {
  90.       n = c - '0';
  91.     } else if ((c >= 'A') && (c <= 'F')) {
  92.       n = c - ('A' + 10U);
  93.     } else if ((c >= 'a') && (c <= 'f')) {
  94.       n = c - ('a' + 10U);
  95.     } else {
  96.       n = 0U;
  97.     }
  98.     if ((j & 1U) != 0U) {
  99.       mac_addr[j>>1] |= n;
  100.     } else {
  101.       mac_addr[j>>1]  = (uint8_t)((uint32_t)n << 4);
  102.     }
  103.     j++;
  104.   }
  105. }

  106. // Initialize variables
  107. static void InitVars (void) {

  108.   rndis_state      = RNDIS_UNINITIALIZED;
  109.   link_state       = ARM_ETH_LINK_DOWN;

  110.   packet_filter    = 0U;

  111.   MAC_str_to_addr(RNDIS_MAC_ADDR, (uint8_t *)&mac_address);
  112.   memset((void *)mcast_address, 0, sizeof(mcast_address));

  113.   ResetVars();
  114. }

  115. // Reset variables
  116. static void ResetVars (void) {
  117.   link_state_up    = false;
  118.   link_state_down  = false;

  119.   get_encapsulated_response_len = 0U;

  120.   xmit_ok          = 0U;
  121.   rcv_ok           = 0U;
  122.   xmit_error       = 0U;
  123.   rcv_error        = 0U;
  124.   rcv_no_buffer    = 0U;
  125. }


  126. // USB CDC ACM callback global functions

  127. // Called during USBD_Initialize to initialize the USB CDC class instance (ACM).
  128. void USBD_CDC%Instance%_ACM_Initialize (void) {
  129.   InitVars();
  130. }


  131. // Called during USBD_Uninitialize to de-initialize the USB CDC class instance (ACM).
  132. void USBD_CDC%Instance%_ACM_Uninitialize (void) {
  133.   InitVars();
  134. }


  135. // Called upon USB Bus Reset Event.
  136. void USBD_CDC%Instance%_ACM_Reset (void) {
  137.   InitVars();
  138. }


  139. // Callback function called upon reception of request send encapsulated command sent by the USB Host.
  140. // \param[in]   buf           buffer that contains send encapsulated command request.
  141. // \param[in]   len           length of send encapsulated command request.
  142. // \return      true          send encapsulated command request processed.
  143. // \return      false         send encapsulated command request not supported or not processed.
  144. bool USBD_CDC%Instance%_ACM_SendEncapsulatedCommand (const uint8_t *buf, uint16_t len) {
  145.   const REMOTE_NDIS_INITIALIZE_MSG_t   *ptr_init_msg;
  146.         REMOTE_NDIS_INITIALIZE_CMPLT_t *ptr_init_cmplt;
  147.   const REMOTE_NDIS_HALT_MSG_t         *ptr_halt_msg;
  148.   const REMOTE_NDIS_QUERY_MSG_t        *ptr_query_msg;
  149.         REMOTE_NDIS_QUERY_CMPLT_t      *ptr_query_cmplt;
  150.   const REMOTE_NDIS_SET_MSG_t          *ptr_set_msg;
  151.         REMOTE_NDIS_SET_CMPLT_t        *ptr_set_cmplt;
  152.   const REMOTE_NDIS_RESET_MSG_t        *ptr_reset_msg;
  153.         REMOTE_NDIS_RESET_CMPLT_t      *ptr_reset_cmplt;
  154.   const REMOTE_NDIS_KEEPALIVE_MSG_t    *ptr_keepalive_msg;
  155.         REMOTE_NDIS_KEEPALIVE_CMPLT_t  *ptr_keepalive_cmplt;
  156.         uint32_t                        status, val;
  157.         uint32_t                        i;
  158.         uint32_t                        num, by;
  159.         uint16_t                        msg_type;

  160.   (void)len;

  161.   msg_type = __UNALIGNED_UINT16_READ(buf);  // Extract message type of received message

  162.   // In uninitialized state only allowed messages are INITALIZE and HALT
  163.   if ((rndis_state == RNDIS_UNINITIALIZED)     &&
  164.       (msg_type != REMOTE_NDIS_INITIALIZE_MSG) &&
  165.       (msg_type != REMOTE_NDIS_HALT_MSG))       {
  166.     return false;
  167.   }

  168.   if (((uint32_t)buf & 3) != 0) {           // buf has to be 32 bit aligned
  169.     return false;
  170.   }

  171.   status = RNDIS_STATUS_SUCCESS;            // Default message processing status
  172.   get_encapsulated_response_len = 0U;       // Prepare default no response size

  173.   switch (msg_type) {                       // MessageType
  174.     case REMOTE_NDIS_INITIALIZE_MSG:
  175.       // Check message is valid
  176.       ptr_init_msg = (const REMOTE_NDIS_INITIALIZE_MSG_t *)((const void *)buf);
  177.       if (ptr_init_msg->MessageLength       != sizeof(REMOTE_NDIS_INITIALIZE_MSG_t)) { return false; }
  178.       if (ptr_init_msg->MajorVersion        != RNDIS_MAJOR_VERSION)                  { return false; }
  179.       if (ptr_init_msg->MinorVersion        != RNDIS_MINOR_VERSION)                  { return false; }
  180.       if (ptr_init_msg->MaxTransferSize     != 16384U)                               { return false; }

  181.       rndis_state = RNDIS_INITIALIZED;

  182.       // Prepare response
  183.       ptr_init_cmplt = (REMOTE_NDIS_INITIALIZE_CMPLT_t *)((void *)get_encapsulated_response_buf);
  184.       ptr_init_cmplt->MessageType            = REMOTE_NDIS_INITIALIZE_CMPLT;
  185.       ptr_init_cmplt->MessageLength          = sizeof(REMOTE_NDIS_INITIALIZE_CMPLT_t);
  186.       ptr_init_cmplt->RequestID              = ptr_init_msg->RequestID;
  187.       ptr_init_cmplt->Status                 = status;
  188.       ptr_init_cmplt->MajorVersion           = RNDIS_MAJOR_VERSION;
  189.       ptr_init_cmplt->MinorVersion           = RNDIS_MINOR_VERSION;
  190.       ptr_init_cmplt->DeviceFlags            = RNDIS_DF_CONNECTIONLESS;
  191.       ptr_init_cmplt->Medium                 = (uint32_t)NdisMedium802_3;
  192.       ptr_init_cmplt->MaxPacketsPerTransfer  = 1U;
  193.       ptr_init_cmplt->MaxTransferSize        = USBD_CDC%Instance%_ACM_RECEIVE_BUF_SIZE;
  194.       ptr_init_cmplt->PacketAlignmentFactor  = 2U;
  195.       ptr_init_cmplt->Reserved[0]            = 0U;
  196.       ptr_init_cmplt->Reserved[1]            = 0U;
  197.       get_encapsulated_response_len          = ptr_init_cmplt->MessageLength;
  198.       break;

  199.     case REMOTE_NDIS_HALT_MSG:
  200.       // Check message is valid
  201.       ptr_halt_msg = (const REMOTE_NDIS_HALT_MSG_t *)((const void *)buf);
  202.       if (ptr_halt_msg->MessageLength != sizeof(REMOTE_NDIS_HALT_MSG_t)) { return false; }

  203.       rndis_state = RNDIS_UNINITIALIZED;

  204.       // This message does not have a response
  205.       return true;

  206.     case REMOTE_NDIS_QUERY_MSG:
  207.       // Check message is valid
  208.       ptr_query_msg = (const REMOTE_NDIS_QUERY_MSG_t *)((const void *)buf);
  209.       if (ptr_query_msg->MessageLength < 28U) { return false; }

  210.       // Prepare response
  211.       ptr_query_cmplt = (REMOTE_NDIS_QUERY_CMPLT_t *)((void *)get_encapsulated_response_buf);
  212.       ptr_query_cmplt->MessageType             = REMOTE_NDIS_QUERY_CMPLT;
  213.       ptr_query_cmplt->RequestID               = ptr_query_msg->RequestID;
  214.       ptr_query_cmplt->InformationBufferOffset = 16U;
  215.       switch (ptr_query_msg->Oid) {             // Handle OID
  216.         case OID_GEN_SUPPORTED_LIST:
  217.           ptr_query_cmplt->InformationBufferLength = 23U * 4U;
  218.           ptr_query_cmplt->OIDInputBuffer[0]       = OID_GEN_SUPPORTED_LIST;
  219.           ptr_query_cmplt->OIDInputBuffer[1]       = OID_GEN_HARDWARE_STATUS;
  220.           ptr_query_cmplt->OIDInputBuffer[2]       = OID_GEN_MEDIA_SUPPORTED;
  221.           ptr_query_cmplt->OIDInputBuffer[3]       = OID_GEN_MEDIA_IN_USE;
  222.           ptr_query_cmplt->OIDInputBuffer[4]       = OID_GEN_MAXIMUM_FRAME_SIZE;
  223.           ptr_query_cmplt->OIDInputBuffer[5]       = OID_GEN_LINK_SPEED;
  224.           ptr_query_cmplt->OIDInputBuffer[6]       = OID_GEN_TRANSMIT_BLOCK_SIZE;
  225.           ptr_query_cmplt->OIDInputBuffer[7]       = OID_GEN_RECEIVE_BLOCK_SIZE;
  226.           ptr_query_cmplt->OIDInputBuffer[8]       = OID_GEN_VENDOR_ID;
  227.           ptr_query_cmplt->OIDInputBuffer[9]       = OID_GEN_VENDOR_DESCRIPTION;
  228.           ptr_query_cmplt->OIDInputBuffer[10]      = OID_GEN_CURRENT_PACKET_FILTER;
  229.           ptr_query_cmplt->OIDInputBuffer[11]      = OID_GEN_MAXIMUM_TOTAL_SIZE;
  230.           ptr_query_cmplt->OIDInputBuffer[12]      = OID_GEN_MEDIA_CONNECT_STATUS;
  231.           ptr_query_cmplt->OIDInputBuffer[13]      = OID_GEN_PHYSICAL_MEDIUM;
  232.           ptr_query_cmplt->OIDInputBuffer[14]      = OID_GEN_XMIT_OK;
  233.           ptr_query_cmplt->OIDInputBuffer[15]      = OID_GEN_RCV_OK;
  234.           ptr_query_cmplt->OIDInputBuffer[16]      = OID_GEN_XMIT_ERROR;
  235.           ptr_query_cmplt->OIDInputBuffer[17]      = OID_GEN_RCV_ERROR;
  236.           ptr_query_cmplt->OIDInputBuffer[18]      = OID_GEN_RCV_NO_BUFFER;
  237.           ptr_query_cmplt->OIDInputBuffer[19]      = OID_802_3_PERMANENT_ADDRESS;
  238.           ptr_query_cmplt->OIDInputBuffer[20]      = OID_802_3_CURRENT_ADDRESS;
  239.           ptr_query_cmplt->OIDInputBuffer[21]      = OID_802_3_MULTICAST_LIST;
  240.           ptr_query_cmplt->OIDInputBuffer[22]      = OID_802_3_MAXIMUM_LIST_SIZE;
  241.           break;
  242.         case OID_GEN_HARDWARE_STATUS:
  243.           ptr_query_cmplt->InformationBufferLength = 4U;
  244.           if (link_state == ARM_ETH_LINK_UP) {
  245.             ptr_query_cmplt->OIDInputBuffer[0]     = (uint32_t)NdisHardwareStatusReady;
  246.           } else {
  247.             ptr_query_cmplt->OIDInputBuffer[0]     = (uint32_t)NdisHardwareStatusNotReady;
  248.           }
  249.           break;
  250.         case OID_GEN_MEDIA_SUPPORTED:
  251.         case OID_GEN_MEDIA_IN_USE:
  252.           ptr_query_cmplt->InformationBufferLength = 4U;
  253.           ptr_query_cmplt->OIDInputBuffer[0]       = (uint32_t)NdisMedium802_3;
  254.           break;
  255.         case OID_GEN_MAXIMUM_FRAME_SIZE:
  256.           ptr_query_cmplt->InformationBufferLength = 4U;
  257.           ptr_query_cmplt->OIDInputBuffer[0]       = ETH_MTU_SIZE;
  258.           break;
  259.         case OID_GEN_LINK_SPEED:
  260.           ptr_query_cmplt->InformationBufferLength = 4U;
  261.           ptr_query_cmplt->OIDInputBuffer[0]       = 100000000U / 100U; // 100 MBit/s
  262.           break;
  263.         case OID_GEN_TRANSMIT_BLOCK_SIZE:
  264.           ptr_query_cmplt->InformationBufferLength = 4U;
  265.           ptr_query_cmplt->OIDInputBuffer[0]       = USBD_CDC%Instance%_ACM_SEND_BUF_SIZE;
  266.           break;
  267.         case OID_GEN_RECEIVE_BLOCK_SIZE:
  268.           ptr_query_cmplt->InformationBufferLength = 4U;
  269.           ptr_query_cmplt->OIDInputBuffer[0]       = USBD_CDC%Instance%_ACM_RECEIVE_BUF_SIZE;
  270.           break;
  271.         case OID_GEN_VENDOR_ID:
  272.           ptr_query_cmplt->InformationBufferLength = 4U;
  273.           ptr_query_cmplt->OIDInputBuffer[0]       = RNDIS_VENDOR_ID;
  274.           break;
  275.         case OID_GEN_VENDOR_DESCRIPTION:
  276.           ptr_query_cmplt->InformationBufferLength = strlen(RNDIS_VENDOR_DESC) + 1;
  277.           memset((void *)&ptr_query_cmplt->OIDInputBuffer[0], 0, ptr_query_cmplt->InformationBufferLength + 1U);
  278.           memcpy((void *)&ptr_query_cmplt->OIDInputBuffer[0], RNDIS_VENDOR_DESC, strlen(RNDIS_VENDOR_DESC));
  279.           break;
  280.         case OID_GEN_CURRENT_PACKET_FILTER:
  281.           ptr_query_cmplt->InformationBufferLength = 4U;
  282.           val = 0U;
  283.           if ((packet_filter & ARM_ETH_MAC_ADDRESS_MULTICAST) != 0U) { val |= RNDIS_FILTER_ALL_MULTICAST; }
  284.           if ((packet_filter & ARM_ETH_MAC_ADDRESS_BROADCAST) != 0U) { val |= RNDIS_FILTER_BROADCAST;     }
  285.           if ((packet_filter & ARM_ETH_MAC_ADDRESS_ALL)       != 0U) { val |= RNDIS_FILTER_PROMISCUOUS;   }
  286.           ptr_query_cmplt->OIDInputBuffer[0]       = val;
  287.           break;
  288.         case OID_GEN_MAXIMUM_TOTAL_SIZE:
  289.           ptr_query_cmplt->InformationBufferLength = 4U;
  290.           ptr_query_cmplt->OIDInputBuffer[0]       = sizeof(REMOTE_NDIS_PACKET_MSG_t) + ETH_MAX_SIZE;
  291.           break;
  292.         case OID_GEN_MEDIA_CONNECT_STATUS:
  293.           ptr_query_cmplt->InformationBufferLength = 4U;
  294.           if (link_state == ARM_ETH_LINK_UP) {
  295.             ptr_query_cmplt->OIDInputBuffer[0]     = (uint32_t)NdisMediaStateConnected;
  296.           } else {
  297.             ptr_query_cmplt->OIDInputBuffer[0]     = (uint32_t)NdisMediaStateDisconnected;
  298.           }
  299.           break;

  300.         case OID_GEN_PHYSICAL_MEDIUM:
  301.           ptr_query_cmplt->InformationBufferLength = 4U;
  302.           ptr_query_cmplt->OIDInputBuffer[0]       = (uint32_t)NdisPhysicalMediumUnspecified;
  303.           break;

  304.         case OID_GEN_XMIT_OK:
  305.           ptr_query_cmplt->InformationBufferLength = 4U;
  306.           ptr_query_cmplt->OIDInputBuffer[0]       = xmit_ok;
  307.           break;
  308.         case OID_GEN_RCV_OK:
  309.           ptr_query_cmplt->InformationBufferLength = 4U;
  310.           ptr_query_cmplt->OIDInputBuffer[0]       = rcv_ok;
  311.           break;
  312.         case OID_GEN_XMIT_ERROR:
  313.           ptr_query_cmplt->InformationBufferLength = 4U;
  314.           ptr_query_cmplt->OIDInputBuffer[0]       = xmit_error;
  315.           break;
  316.         case OID_GEN_RCV_ERROR:
  317.           ptr_query_cmplt->InformationBufferLength = 4U;
  318.           ptr_query_cmplt->OIDInputBuffer[0]       = rcv_error;
  319.           break;
  320.         case OID_GEN_RCV_NO_BUFFER:
  321.           ptr_query_cmplt->InformationBufferLength = 4U;
  322.           ptr_query_cmplt->OIDInputBuffer[0]       = rcv_no_buffer;
  323.           break;

  324.         case OID_802_3_PERMANENT_ADDRESS:
  325.         case OID_802_3_CURRENT_ADDRESS:
  326.           ptr_query_cmplt->InformationBufferLength = 6U;
  327.           memcpy((void *)&ptr_query_cmplt->OIDInputBuffer[0], &mac_address, sizeof(ARM_ETH_MAC_ADDR));
  328.           break;
  329.         case OID_802_3_MULTICAST_LIST:
  330.           for (i = 0U; i < RNDIS_MCAST_NUM; i++) {
  331.             if ((__UNALIGNED_UINT32_READ(&mcast_address[0]) == 0U) &&
  332.                 (__UNALIGNED_UINT16_READ(&mcast_address[4]) == 0U)) {
  333.               break;
  334.             }
  335.           }
  336.           if (i == 0U) {
  337.             num = 0U;
  338.             ptr_query_cmplt->InformationBufferOffset = 0U;
  339.           } else {
  340.             num = i;
  341.             if (i < RNDIS_MCAST_NUM) {
  342.               num = i + 1U;
  343.             } else {
  344.               num = i;
  345.             }
  346.             memcpy((void *)&ptr_query_cmplt->OIDInputBuffer[0], mcast_address, num * sizeof(ARM_ETH_MAC_ADDR));
  347.           }
  348.           ptr_query_cmplt->InformationBufferLength = num * sizeof(ARM_ETH_MAC_ADDR);
  349.           break;
  350.         case OID_802_3_MAXIMUM_LIST_SIZE:
  351.           ptr_query_cmplt->InformationBufferLength = 4U;
  352.           ptr_query_cmplt->OIDInputBuffer[0]       = RNDIS_MCAST_NUM;
  353.           break;

  354.         default:
  355.           ptr_query_cmplt->InformationBufferOffset = 0U;
  356.           ptr_query_cmplt->InformationBufferLength = 0U;
  357.           status = RNDIS_STATUS_NOT_SUPPORTED;
  358.           break;
  359.       }
  360.       ptr_query_cmplt->Status        = status;
  361.       ptr_query_cmplt->MessageLength = ptr_query_cmplt->InformationBufferLength + 24U;
  362.       get_encapsulated_response_len  = ptr_query_cmplt->MessageLength;
  363.       break;

  364.     case REMOTE_NDIS_SET_MSG:
  365.       // Check message is valid
  366.       ptr_set_msg = (const REMOTE_NDIS_SET_MSG_t *)((const void *)buf);
  367.       if (ptr_set_msg->MessageLength < 28U) { return false; }

  368.       // Prepare response
  369.       ptr_set_cmplt = (REMOTE_NDIS_SET_CMPLT_t *)((void *)get_encapsulated_response_buf);
  370.       ptr_set_cmplt->MessageType               = REMOTE_NDIS_SET_CMPLT;
  371.       ptr_set_cmplt->MessageLength             = sizeof(REMOTE_NDIS_SET_CMPLT_t);
  372.       ptr_set_cmplt->RequestID                 = ptr_set_msg->RequestID;

  373.       switch (ptr_set_msg->Oid) {               // Handle OID
  374.         case OID_802_3_MULTICAST_LIST:
  375.           by = ptr_set_msg->InformationBufferLength;
  376.           if (by > (sizeof(ARM_ETH_MAC_ADDR) * RNDIS_MCAST_NUM)) {
  377.             by = sizeof(ARM_ETH_MAC_ADDR) * RNDIS_MCAST_NUM;
  378.           }
  379.           if (by > 0U) {
  380.             memcpy(mcast_address, (const void *)&ptr_set_msg->OIDInputBuffer[0], by);
  381.           }
  382.           break;
  383.         case OID_GEN_CURRENT_PACKET_FILTER:
  384.           if ((ptr_set_msg->InformationBufferLength == 4U) &&
  385.               (ptr_set_msg->InformationBufferOffset != 0U)) {
  386.             val = __UNALIGNED_UINT32_READ(((const uint8_t *)&ptr_set_msg->RequestID) + ptr_set_msg->InformationBufferOffset);
  387.             if (val != 0U) {
  388.               if ((val & RNDIS_FILTER_ALL_MULTICAST) != 0U) { packet_filter |= ARM_ETH_MAC_ADDRESS_MULTICAST; }
  389.               if ((val & RNDIS_FILTER_BROADCAST)     != 0U) { packet_filter |= ARM_ETH_MAC_ADDRESS_BROADCAST; }
  390.               if ((val & RNDIS_FILTER_PROMISCUOUS)   != 0U) { packet_filter |= ARM_ETH_MAC_ADDRESS_ALL;       }
  391.               if (link_state == ARM_ETH_LINK_DOWN) {
  392.                 link_state    = ARM_ETH_LINK_UP;
  393.                 link_state_up = true;
  394.               }
  395.               rndis_state = RNDIS_DATA_INITIALIZED;
  396.             } else {
  397.               if (rndis_state == RNDIS_DATA_INITIALIZED) {
  398.                 rndis_state = RNDIS_INITIALIZED;
  399.               }
  400.             }
  401.           } else {
  402.             status = RNDIS_STATUS_FAILURE;
  403.           }
  404.           break;
  405.         default:
  406.           status = RNDIS_STATUS_NOT_SUPPORTED;
  407.           break;
  408.       }

  409.       ptr_set_cmplt->Status         = status;
  410.       get_encapsulated_response_len = ptr_set_cmplt->MessageLength;
  411.       break;

  412.     case REMOTE_NDIS_RESET_MSG:
  413.       // Check message is valid
  414.       ptr_reset_msg = (const REMOTE_NDIS_RESET_MSG_t *)((const void *)buf);
  415.       if (ptr_reset_msg->MessageLength != sizeof(REMOTE_NDIS_RESET_MSG_t)) { return false; }

  416.       ResetVars();

  417.       // Prepare response
  418.       ptr_reset_cmplt = (REMOTE_NDIS_RESET_CMPLT_t *)((void *)get_encapsulated_response_buf);
  419.       ptr_reset_cmplt->MessageType             = REMOTE_NDIS_RESET_CMPLT;
  420.       ptr_reset_cmplt->MessageLength           = sizeof(REMOTE_NDIS_RESET_CMPLT_t);
  421.       ptr_reset_cmplt->Status                  = status;
  422.       ptr_reset_cmplt->AddressingReset         = 0U;
  423.       get_encapsulated_response_len            = ptr_reset_cmplt->MessageLength;
  424.       break;

  425.     case REMOTE_NDIS_KEEPALIVE_MSG:
  426.       // Check message is valid
  427.       ptr_keepalive_msg = (const REMOTE_NDIS_KEEPALIVE_MSG_t *)((const void *)buf);
  428.       if (ptr_keepalive_msg->MessageLength != sizeof(REMOTE_NDIS_KEEPALIVE_MSG_t)) { return false; }

  429.       // Prepare response
  430.       ptr_keepalive_cmplt = (REMOTE_NDIS_KEEPALIVE_CMPLT_t *)((void *)get_encapsulated_response_buf);
  431.       ptr_keepalive_cmplt->MessageType         = REMOTE_NDIS_KEEPALIVE_CMPLT;
  432.       ptr_keepalive_cmplt->MessageLength       = sizeof(REMOTE_NDIS_KEEPALIVE_CMPLT_t);
  433.       ptr_keepalive_cmplt->RequestID           = ptr_keepalive_msg->RequestID;
  434.       ptr_keepalive_cmplt->Status              = status;
  435.       get_encapsulated_response_len            = ptr_keepalive_cmplt->MessageLength;
  436.       break;

  437.     default:
  438.       return false;
  439.   }

  440.   if (get_encapsulated_response_len != 0U) {
  441.     // If response is prepared send notification over Interrupt Endpoint
  442.     (void)USBD_CDC_ACM_Notify_ResponseAvailable (%Instance%);
  443.   }

  444.   return true;
  445. }


  446. // Callback function called upon reception of request to get encapsulated response sent by the USB Host.
  447. // \param[in]   max_len       maximum number of data bytes that USB Host expects to receive
  448. // \param[out]  buf           pointer to buffer containing get encapsulated response to be returned to USB Host.
  449. // \param[out]  len           pointer to number of data bytes to be returned to USB Host.
  450. // \return      true          get encapsulated response request processed.
  451. // \return      false         get encapsulated response request not supported or not processed.
  452. bool USBD_CDC%Instance%_ACM_GetEncapsulatedResponse (uint16_t max_len, uint8_t **buf, uint16_t *len) {
  453.   REMOTE_NDIS_INDICATE_STATUS_MSG_t *ptr_indicate_status_msg;
  454.   uint32_t                           status;

  455.   (void)max_len;

  456.   if (link_state_up || link_state_down) {   // Generate unsolicited INDICATE STATUS message if link status has changed
  457.     if (link_state_up) {
  458.       status = RNDIS_STATUS_MEDIA_CONNECT;
  459.     } else {
  460.       status = RNDIS_STATUS_MEDIA_DISCONNECT;
  461.     }

  462.     // Prepare INDICATE STATUS message
  463.     ptr_indicate_status_msg = (REMOTE_NDIS_INDICATE_STATUS_MSG_t *)((void *)get_encapsulated_response_buf);
  464.     ptr_indicate_status_msg->MessageType        = REMOTE_NDIS_INDICATE_STATUS_MSG;
  465.     ptr_indicate_status_msg->MessageLength      = 20U;
  466.     ptr_indicate_status_msg->Status             = status;
  467.     ptr_indicate_status_msg->StatusBufferLength = 0U;
  468.     ptr_indicate_status_msg->StatusBufferOffset = 0U;
  469.     get_encapsulated_response_len               = 20U;

  470.     link_state_up   = false;
  471.     link_state_down = false;
  472.   }

  473.   if (get_encapsulated_response_len != 0U) {    // If response is available return it
  474.     *buf = (uint8_t *)get_encapsulated_response_buf;
  475.     *len = (uint16_t) get_encapsulated_response_len;
  476.     get_encapsulated_response_len = 0U;
  477.   }

  478.   return true;
  479. }


  480. // Callback function called when all data was sent
  481. // \return                    none.
  482. void USBD_CDC%Instance%_ACM_DataSent (void) {
  483. }


  484. // Callback function called when new data was received
  485. // \param[in]   len           number of bytes available to read.
  486. // \return                    none.
  487. void USBD_CDC%Instance%_ACM_DataReceived (uint32_t len) {
  488.   (void)len;
  489. }


  490. //! [code_USBD_User_CDC_ACM_RNDIS_VETH]


  491. // Global functions exported for Virtual Ethernet driver

  492. /**
  493.   \fn          ARM_ETH_LINK_STATE RNDIS%Instance%_GetLinkState (void)
  494.   \brief       Get RNDIS Device Link state (data initialized means link is up).
  495.   \return      current link status \ref ARM_ETH_LINK_STATE
  496. */
  497. ARM_ETH_LINK_STATE RNDIS%Instance%_GetLinkState (void) {
  498.   if (rndis_state == RNDIS_DATA_INITIALIZED) {
  499.     return ARM_ETH_LINK_UP;
  500.   }

  501.   return ARM_ETH_LINK_DOWN;
  502. }

  503. /**
  504.   \fn          int32_t RNDIS%Instance%_SendFrame (const uint8_t *frame, uint32_t len, uint32_t flags)
  505.   \brief       Send Ethernet frame over USB CDC ACM RNDIS.
  506.   \param[in]   frame  Pointer to frame buffer with data to send
  507.   \param[in]   len    Frame buffer length in bytes
  508.   \return      \ref execution_status
  509. */
  510. int32_t RNDIS%Instance%_SendFrame (const uint8_t *frame, uint32_t len) {
  511.   REMOTE_NDIS_PACKET_MSG_t *ptr_packet_msg;
  512.    int32_t                  usb_cdc_acm_status;

  513.   ptr_packet_msg = (REMOTE_NDIS_PACKET_MSG_t *)((void *)packet_in);

  514.   if ((rndis_state == RNDIS_DATA_INITIALIZED) &&
  515.       (len >= ETH_MIN_SIZE)                   &&
  516.       (len <= ETH_MAX_SIZE))                   {
  517.     memcpy((void *)&ptr_packet_msg->PayLoad[0], frame, len);
  518.     ptr_packet_msg->MessageType              = REMOTE_NDIS_PACKET_MSG;
  519.     ptr_packet_msg->MessageLength            = len + sizeof(REMOTE_NDIS_PACKET_MSG_t);
  520.     ptr_packet_msg->DataOffset               = sizeof(REMOTE_NDIS_PACKET_MSG_t) - 8U;
  521.     ptr_packet_msg->DataLength               = len;
  522.     ptr_packet_msg->OutOfBandDataOffset      = 0U;
  523.     ptr_packet_msg->OutOfBandDataLength      = 0U;
  524.     ptr_packet_msg->NumOutOfBandDataElements = 0U;
  525.     ptr_packet_msg->PerPacketInfoOffset      = 0U;
  526.     ptr_packet_msg->PerPacketInfoLength      = 0U;
  527.     ptr_packet_msg->Reserved[0]              = 0U;
  528.     ptr_packet_msg->Reserved[1]              = 0U;
  529.     usb_cdc_acm_status = USBD_CDC_ACM_WriteData (%Instance%, (const uint8_t *)ptr_packet_msg, (int32_t)ptr_packet_msg->MessageLength);
  530.     if (usb_cdc_acm_status == (int32_t)ptr_packet_msg->MessageLength) {
  531.       rcv_ok++;
  532.       return ARM_DRIVER_OK;
  533.     }
  534.     if (usb_cdc_acm_status < 0) {
  535.       rcv_error++;
  536.       return ARM_DRIVER_ERROR;
  537.     }
  538.     if (usb_cdc_acm_status == 0) {
  539.       return ARM_DRIVER_ERROR_BUSY;
  540.     }
  541.   }

  542.   return ARM_DRIVER_ERROR;
  543. }

  544. /**
  545.   \fn          int32_t RNDIS%Instance%_ReadFrame (uint8_t *frame, uint32_t len)
  546.   \brief       Read data of Ethernet frame received over USB CDC ACM RNDIS.
  547.   \param[in]   frame  Pointer to frame buffer for data to read into
  548.   \param[in]   len    Frame buffer length in bytes
  549.   \return      number of data bytes read or execution status
  550.                  - value >= 0: number of data bytes read
  551.                  - value < 0: error occurred, value is execution status as defined with \ref execution_status
  552. */
  553. int32_t RNDIS%Instance%_ReadFrame (uint8_t *frame, uint32_t len) {
  554.   REMOTE_NDIS_PACKET_MSG_t *ptr_packet_msg;
  555.   uint32_t                  data_len;
  556.    int32_t                  usb_cdc_acm_status;

  557.   ptr_packet_msg = (REMOTE_NDIS_PACKET_MSG_t *)((void *)packet_out);

  558.   if ((rndis_state == RNDIS_DATA_INITIALIZED) &&
  559.       (len >= ETH_MIN_SIZE)                   &&
  560.       (len <= ETH_MAX_SIZE))                   {
  561.     usb_cdc_acm_status = USBD_CDC_ACM_ReadData (%Instance%, (uint8_t *)ptr_packet_msg, USBD_CDC%Instance%_ACM_RECEIVE_BUF_SIZE);
  562.     if ((usb_cdc_acm_status != 0) && (usb_cdc_acm_status == (int32_t)ptr_packet_msg->MessageLength)) {
  563.       data_len = len;
  564.       if (data_len > ptr_packet_msg->DataLength) {
  565.         data_len = ptr_packet_msg->DataLength;
  566.       }
  567.       memcpy(frame, (const void *)&ptr_packet_msg->PayLoad[0], data_len);
  568.       xmit_ok++;
  569.       return (int32_t)data_len;
  570.     }
  571.     if (usb_cdc_acm_status < 0) {
  572.       xmit_error++;
  573.       return ARM_DRIVER_ERROR;
  574.     }
  575.     if (usb_cdc_acm_status == 0) {
  576.       return ARM_DRIVER_ERROR_BUSY;
  577.     }
  578.   }

  579.   return 0;
  580. }

  581. /**
  582.   \fn          uint32_t RNDIS%Instance%_GetRxFrameSize (void)
  583.   \brief       Get size of Ethernet frame received over USB CDC ACM RNDIS.
  584.   \return      number of bytes in received frame
  585. */
  586. uint32_t RNDIS%Instance%_GetRxFrameSize (void) {
  587.   uint32_t avail_data_len;

  588.   avail_data_len = (uint32_t)USBD_CDC_ACM_DataAvailable (%Instance%);

  589.   if (avail_data_len > sizeof(REMOTE_NDIS_PACKET_MSG_t)) {
  590.     avail_data_len -= sizeof(REMOTE_NDIS_PACKET_MSG_t);
  591.   }

  592.   return avail_data_len;
  593. }
复制代码


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106828
QQ
 楼主| 发表于 2020-7-4 13:43:44 | 显示全部楼层
V1.0.4:
  1. /*------------------------------------------------------------------------------
  2. * MDK Middleware - Component ::USB:Device:CDC
  3. * Copyright (c) 2018-2020 Arm Limited (or its affiliates). All rights reserved.
  4. *------------------------------------------------------------------------------
  5. * Name:    USBD_User_CDC_ACM_RNDIS_VETH_%Instance%.c
  6. * Purpose: USB Device Communication Device Class (CDC)
  7. *          Abstract Control Model (ACM)
  8. *          Remote Network Driver Interface Specification (RNDIS)
  9. *          User Module for a Virtual Ethernet
  10. * Rev.:    V1.0.4
  11. *----------------------------------------------------------------------------*/
  12. /**
  13. * \addtogroup usbd_cdcFunctions
  14. *
  15. * USBD_User_CDC_ACM_RNDIS_VETH_%Instance%.c implements the application specific
  16. * functionality of the CDC ACM class using RNDIS protocol and is used
  17. * to implement Network Interface Card (NIC) to the USB Host.
  18. * This user module works together with EMAC_CDC_ACM_RNDIS.c driver
  19. * to provide USB Host network access to Embedded Device over USB.
  20. *
  21. * The implementation depends on the configuration file USBD_Config_CDC_%Instance%.h.
  22. *
  23. */


  24. //! [code_USBD_User_CDC_ACM_RNDIS_VETH]

  25. #include <stdint.h>
  26. #include <stdbool.h>
  27. #include <string.h>

  28. #include "rl_usb.h"

  29. #include "Driver_ETH.h"
  30. #include "Driver_ETH_MAC.h"
  31. #include "Driver_ETH_PHY.h"
  32. #include "USBD_Config_CDC_%Instance%.h"


  33. //-------- <<< Use Configuration Wizard in Context Menu >>> --------------------

  34. // Configuration defines

  35. //   <s.17>MAC Address
  36. //     <i>Ethernet MAC Address in text representation
  37. //     <i>Value FF-FF-FF-FF-FF-FF is not allowed,
  38. //     <i>LSB of first byte must be 0 (an ethernet Multicast bit).
  39. //     <i>Default: "1E-30-6C-A2-45-5E"
  40. #define RNDIS_MAC_ADDR    "1E-30-6C-A2-45-5E"           // RNDIS MAC Address

  41. //   <o.0..5>Maximum number of multicast addresses <1-32>
  42. #define RNDIS_MCAST_NUM   16                            // RNDIS Number of Multicast Addresses supported

  43. //   <s.32>RNDIS Vendor Description
  44. #define RNDIS_VENDOR_DESC "Keil NIC (USB <-> ETH)"      // RNDIS Vendor Description

  45. //   <o.0..23>RNDIS Vendor Id Code <0x000000-0xFFFFFF>
  46. #define RNDIS_VENDOR_ID   0xFFFFFF                      // RNDIS three-byte IEEE-registered Vendor Code

  47. //------------- <<< end of configuration section >>> ---------------------------


  48. // Global functions exported by this module
  49.        ARM_ETH_LINK_STATE RNDIS%Instance%_GetLinkState  (void);
  50.        int32_t            RNDIS%Instance%_SendFrame     (const uint8_t *frame, uint32_t len);
  51.        int32_t            RNDIS%Instance%_ReadFrame     (      uint8_t *frame, uint32_t len);
  52.        uint32_t           RNDIS%Instance%_GetRxFrameSize(void);

  53. // Local functions
  54. static void               MAC_str_to_addr (const char *mac_str, uint8_t *mac_addr);
  55. static void               InitVars        (void);
  56. static void               ResetVars       (void);

  57. // Local variables
  58. static uint32_t           rndis_state;
  59. static ARM_ETH_LINK_STATE link_state;

  60. static bool               link_state_up;
  61. static bool               link_state_down;

  62. static uint32_t           packet_filter;
  63. static ARM_ETH_MAC_ADDR   mac_address;
  64. static ARM_ETH_MAC_ADDR   mcast_address[RNDIS_MCAST_NUM];

  65. static uint32_t           get_encapsulated_response_len;
  66. static uint32_t           get_encapsulated_response_buf[128/4];

  67. static uint32_t           xmit_ok;
  68. static uint32_t           rcv_ok;
  69. static uint32_t           xmit_error;
  70. static uint32_t           rcv_error;
  71. static uint32_t           rcv_no_buffer;

  72. static uint32_t           packet_in [(USBD_CDC%Instance%_ACM_SEND_BUF_SIZE   +3)/4];
  73. static uint32_t           packet_out[(USBD_CDC%Instance%_ACM_RECEIVE_BUF_SIZE+3)/4];


  74. // Local functions

  75. // MAC Address conversion from string
  76. // \param[in]   mac_str   Pointer to wide string.
  77. // \param[out]  mac_addr  Pointer to address.
  78. static void MAC_str_to_addr (const char *mac_str, uint8_t *mac_addr) {
  79.   uint8_t  c;
  80.   uint8_t  n;
  81.   uint32_t i, j;
  82.   uint32_t str_len;

  83.   str_len = strlen(mac_str);
  84.   j = 0U;
  85.   for (i = 0U; i < str_len; i++) {
  86.     c = (uint8_t)mac_str[i];
  87.     if         (c == '-') {
  88.       continue;
  89.     } else if ((c >= '0') && (c <= '9')) {
  90.       n = c - '0';
  91.     } else if ((c >= 'A') && (c <= 'F')) {
  92.       n = c - ('A' + 10U);
  93.     } else if ((c >= 'a') && (c <= 'f')) {
  94.       n = c - ('a' + 10U);
  95.     } else {
  96.       n = 0U;
  97.     }
  98.     if ((j & 1U) != 0U) {
  99.       mac_addr[j>>1] |= n;
  100.     } else {
  101.       mac_addr[j>>1]  = (uint8_t)((uint32_t)n << 4);
  102.     }
  103.     j++;
  104.   }
  105. }

  106. // Initialize variables
  107. static void InitVars (void) {

  108.   rndis_state      = RNDIS_UNINITIALIZED;
  109.   link_state       = ARM_ETH_LINK_DOWN;

  110.   packet_filter    = 0U;

  111.   MAC_str_to_addr(RNDIS_MAC_ADDR, (uint8_t *)&mac_address);
  112.   memset((void *)mcast_address, 0, sizeof(mcast_address));

  113.   ResetVars();
  114. }

  115. // Reset variables
  116. static void ResetVars (void) {
  117.   link_state_up    = false;
  118.   link_state_down  = false;

  119.   get_encapsulated_response_len = 0U;

  120.   xmit_ok          = 0U;
  121.   rcv_ok           = 0U;
  122.   xmit_error       = 0U;
  123.   rcv_error        = 0U;
  124.   rcv_no_buffer    = 0U;
  125. }


  126. // USB CDC ACM callback global functions

  127. // Called during USBD_Initialize to initialize the USB CDC class instance (ACM).
  128. void USBD_CDC%Instance%_ACM_Initialize (void) {
  129.   InitVars();
  130. }


  131. // Called during USBD_Uninitialize to de-initialize the USB CDC class instance (ACM).
  132. void USBD_CDC%Instance%_ACM_Uninitialize (void) {
  133.   InitVars();
  134. }


  135. // Called upon USB Bus Reset Event.
  136. void USBD_CDC%Instance%_ACM_Reset (void) {
  137.   InitVars();
  138. }


  139. // Callback function called upon reception of request send encapsulated command sent by the USB Host.
  140. // \param[in]   buf           buffer that contains send encapsulated command request.
  141. // \param[in]   len           length of send encapsulated command request.
  142. // \return      true          send encapsulated command request processed.
  143. // \return      false         send encapsulated command request not supported or not processed.
  144. bool USBD_CDC%Instance%_ACM_SendEncapsulatedCommand (const uint8_t *buf, uint16_t len) {
  145.   const REMOTE_NDIS_INITIALIZE_MSG_t   *ptr_init_msg;
  146.         REMOTE_NDIS_INITIALIZE_CMPLT_t *ptr_init_cmplt;
  147.   const REMOTE_NDIS_HALT_MSG_t         *ptr_halt_msg;
  148.   const REMOTE_NDIS_QUERY_MSG_t        *ptr_query_msg;
  149.         REMOTE_NDIS_QUERY_CMPLT_t      *ptr_query_cmplt;
  150.   const REMOTE_NDIS_SET_MSG_t          *ptr_set_msg;
  151.         REMOTE_NDIS_SET_CMPLT_t        *ptr_set_cmplt;
  152.   const REMOTE_NDIS_RESET_MSG_t        *ptr_reset_msg;
  153.         REMOTE_NDIS_RESET_CMPLT_t      *ptr_reset_cmplt;
  154.   const REMOTE_NDIS_KEEPALIVE_MSG_t    *ptr_keepalive_msg;
  155.         REMOTE_NDIS_KEEPALIVE_CMPLT_t  *ptr_keepalive_cmplt;
  156.         uint32_t                        status, val;
  157.         uint32_t                        i;
  158.         uint32_t                        num, by;
  159.         uint16_t                        msg_type;

  160.   (void)len;

  161.   msg_type = __UNALIGNED_UINT16_READ(buf);  // Extract message type of received message

  162.   // In uninitialized state only allowed messages are INITALIZE and HALT
  163.   if ((rndis_state == RNDIS_UNINITIALIZED)     &&
  164.       (msg_type != REMOTE_NDIS_INITIALIZE_MSG) &&
  165.       (msg_type != REMOTE_NDIS_HALT_MSG))       {
  166.     return false;
  167.   }

  168.   if (((uint32_t)buf & 3) != 0) {           // buf has to be 32 bit aligned
  169.     return false;
  170.   }

  171.   status = RNDIS_STATUS_SUCCESS;            // Default message processing status
  172.   get_encapsulated_response_len = 0U;       // Prepare default no response size

  173.   switch (msg_type) {                       // MessageType
  174.     case REMOTE_NDIS_INITIALIZE_MSG:
  175.       // Check message is valid
  176.       ptr_init_msg = (const REMOTE_NDIS_INITIALIZE_MSG_t *)((const void *)buf);
  177.       if (ptr_init_msg->MessageLength       != sizeof(REMOTE_NDIS_INITIALIZE_MSG_t)) { return false; }
  178.       if (ptr_init_msg->MajorVersion        != RNDIS_MAJOR_VERSION)                  { return false; }
  179.       if (ptr_init_msg->MinorVersion        != RNDIS_MINOR_VERSION)                  { return false; }
  180.       if (ptr_init_msg->MaxTransferSize     != 16384U)                               { return false; }

  181.       rndis_state = RNDIS_INITIALIZED;

  182.       // Prepare response
  183.       ptr_init_cmplt = (REMOTE_NDIS_INITIALIZE_CMPLT_t *)((void *)get_encapsulated_response_buf);
  184.       ptr_init_cmplt->MessageType            = REMOTE_NDIS_INITIALIZE_CMPLT;
  185.       ptr_init_cmplt->MessageLength          = sizeof(REMOTE_NDIS_INITIALIZE_CMPLT_t);
  186.       ptr_init_cmplt->RequestID              = ptr_init_msg->RequestID;
  187.       ptr_init_cmplt->Status                 = status;
  188.       ptr_init_cmplt->MajorVersion           = RNDIS_MAJOR_VERSION;
  189.       ptr_init_cmplt->MinorVersion           = RNDIS_MINOR_VERSION;
  190.       ptr_init_cmplt->DeviceFlags            = RNDIS_DF_CONNECTIONLESS;
  191.       ptr_init_cmplt->Medium                 = (uint32_t)NdisMedium802_3;
  192.       ptr_init_cmplt->MaxPacketsPerTransfer  = 1U;
  193.       ptr_init_cmplt->MaxTransferSize        = USBD_CDC%Instance%_ACM_RECEIVE_BUF_SIZE;
  194.       ptr_init_cmplt->PacketAlignmentFactor  = 2U;
  195.       ptr_init_cmplt->Reserved[0]            = 0U;
  196.       ptr_init_cmplt->Reserved[1]            = 0U;
  197.       get_encapsulated_response_len          = ptr_init_cmplt->MessageLength;
  198.       break;

  199.     case REMOTE_NDIS_HALT_MSG:
  200.       // Check message is valid
  201.       ptr_halt_msg = (const REMOTE_NDIS_HALT_MSG_t *)((const void *)buf);
  202.       if (ptr_halt_msg->MessageLength != sizeof(REMOTE_NDIS_HALT_MSG_t)) { return false; }

  203.       rndis_state = RNDIS_UNINITIALIZED;

  204.       // This message does not have a response
  205.       return true;

  206.     case REMOTE_NDIS_QUERY_MSG:
  207.       // Check message is valid
  208.       ptr_query_msg = (const REMOTE_NDIS_QUERY_MSG_t *)((const void *)buf);
  209.       if (ptr_query_msg->MessageLength < 28U) { return false; }

  210.       // Prepare response
  211.       ptr_query_cmplt = (REMOTE_NDIS_QUERY_CMPLT_t *)((void *)get_encapsulated_response_buf);
  212.       ptr_query_cmplt->MessageType             = REMOTE_NDIS_QUERY_CMPLT;
  213.       ptr_query_cmplt->RequestID               = ptr_query_msg->RequestID;
  214.       ptr_query_cmplt->InformationBufferOffset = 16U;
  215.       switch (ptr_query_msg->Oid) {             // Handle OID
  216.         case OID_GEN_SUPPORTED_LIST:
  217.           ptr_query_cmplt->InformationBufferLength = 23U * 4U;
  218.           ptr_query_cmplt->OIDInputBuffer[0]       = OID_GEN_SUPPORTED_LIST;
  219.           ptr_query_cmplt->OIDInputBuffer[1]       = OID_GEN_HARDWARE_STATUS;
  220.           ptr_query_cmplt->OIDInputBuffer[2]       = OID_GEN_MEDIA_SUPPORTED;
  221.           ptr_query_cmplt->OIDInputBuffer[3]       = OID_GEN_MEDIA_IN_USE;
  222.           ptr_query_cmplt->OIDInputBuffer[4]       = OID_GEN_MAXIMUM_FRAME_SIZE;
  223.           ptr_query_cmplt->OIDInputBuffer[5]       = OID_GEN_LINK_SPEED;
  224.           ptr_query_cmplt->OIDInputBuffer[6]       = OID_GEN_TRANSMIT_BLOCK_SIZE;
  225.           ptr_query_cmplt->OIDInputBuffer[7]       = OID_GEN_RECEIVE_BLOCK_SIZE;
  226.           ptr_query_cmplt->OIDInputBuffer[8]       = OID_GEN_VENDOR_ID;
  227.           ptr_query_cmplt->OIDInputBuffer[9]       = OID_GEN_VENDOR_DESCRIPTION;
  228.           ptr_query_cmplt->OIDInputBuffer[10]      = OID_GEN_CURRENT_PACKET_FILTER;
  229.           ptr_query_cmplt->OIDInputBuffer[11]      = OID_GEN_MAXIMUM_TOTAL_SIZE;
  230.           ptr_query_cmplt->OIDInputBuffer[12]      = OID_GEN_MEDIA_CONNECT_STATUS;
  231.           ptr_query_cmplt->OIDInputBuffer[13]      = OID_GEN_PHYSICAL_MEDIUM;
  232.           ptr_query_cmplt->OIDInputBuffer[14]      = OID_GEN_XMIT_OK;
  233.           ptr_query_cmplt->OIDInputBuffer[15]      = OID_GEN_RCV_OK;
  234.           ptr_query_cmplt->OIDInputBuffer[16]      = OID_GEN_XMIT_ERROR;
  235.           ptr_query_cmplt->OIDInputBuffer[17]      = OID_GEN_RCV_ERROR;
  236.           ptr_query_cmplt->OIDInputBuffer[18]      = OID_GEN_RCV_NO_BUFFER;
  237.           ptr_query_cmplt->OIDInputBuffer[19]      = OID_802_3_PERMANENT_ADDRESS;
  238.           ptr_query_cmplt->OIDInputBuffer[20]      = OID_802_3_CURRENT_ADDRESS;
  239.           ptr_query_cmplt->OIDInputBuffer[21]      = OID_802_3_MULTICAST_LIST;
  240.           ptr_query_cmplt->OIDInputBuffer[22]      = OID_802_3_MAXIMUM_LIST_SIZE;
  241.           break;
  242.         case OID_GEN_HARDWARE_STATUS:
  243.           ptr_query_cmplt->InformationBufferLength = 4U;
  244.           if (link_state == ARM_ETH_LINK_UP) {
  245.             ptr_query_cmplt->OIDInputBuffer[0]     = (uint32_t)NdisHardwareStatusReady;
  246.           } else {
  247.             ptr_query_cmplt->OIDInputBuffer[0]     = (uint32_t)NdisHardwareStatusNotReady;
  248.           }
  249.           break;
  250.         case OID_GEN_MEDIA_SUPPORTED:
  251.         case OID_GEN_MEDIA_IN_USE:
  252.           ptr_query_cmplt->InformationBufferLength = 4U;
  253.           ptr_query_cmplt->OIDInputBuffer[0]       = (uint32_t)NdisMedium802_3;
  254.           break;
  255.         case OID_GEN_MAXIMUM_FRAME_SIZE:
  256.           ptr_query_cmplt->InformationBufferLength = 4U;
  257.           ptr_query_cmplt->OIDInputBuffer[0]       = ETH_MTU_SIZE;
  258.           break;
  259.         case OID_GEN_LINK_SPEED:
  260.           ptr_query_cmplt->InformationBufferLength = 4U;
  261.           ptr_query_cmplt->OIDInputBuffer[0]       = 100000000U / 100U; // 100 MBit/s
  262.           break;
  263.         case OID_GEN_TRANSMIT_BLOCK_SIZE:
  264.           ptr_query_cmplt->InformationBufferLength = 4U;
  265.           ptr_query_cmplt->OIDInputBuffer[0]       = USBD_CDC%Instance%_ACM_SEND_BUF_SIZE;
  266.           break;
  267.         case OID_GEN_RECEIVE_BLOCK_SIZE:
  268.           ptr_query_cmplt->InformationBufferLength = 4U;
  269.           ptr_query_cmplt->OIDInputBuffer[0]       = USBD_CDC%Instance%_ACM_RECEIVE_BUF_SIZE;
  270.           break;
  271.         case OID_GEN_VENDOR_ID:
  272.           ptr_query_cmplt->InformationBufferLength = 4U;
  273.           ptr_query_cmplt->OIDInputBuffer[0]       = RNDIS_VENDOR_ID;
  274.           break;
  275.         case OID_GEN_VENDOR_DESCRIPTION:
  276.           ptr_query_cmplt->InformationBufferLength = strlen(RNDIS_VENDOR_DESC) + 1;
  277.           memset((void *)&ptr_query_cmplt->OIDInputBuffer[0], 0, ptr_query_cmplt->InformationBufferLength + 1U);
  278.           memcpy((void *)&ptr_query_cmplt->OIDInputBuffer[0], RNDIS_VENDOR_DESC, strlen(RNDIS_VENDOR_DESC));
  279.           break;
  280.         case OID_GEN_CURRENT_PACKET_FILTER:
  281.           ptr_query_cmplt->InformationBufferLength = 4U;
  282.           val = 0U;
  283.           if ((packet_filter & ARM_ETH_MAC_ADDRESS_MULTICAST) != 0U) { val |= RNDIS_FILTER_ALL_MULTICAST; }
  284.           if ((packet_filter & ARM_ETH_MAC_ADDRESS_BROADCAST) != 0U) { val |= RNDIS_FILTER_BROADCAST;     }
  285.           if ((packet_filter & ARM_ETH_MAC_ADDRESS_ALL)       != 0U) { val |= RNDIS_FILTER_PROMISCUOUS;   }
  286.           ptr_query_cmplt->OIDInputBuffer[0]       = val;
  287.           break;
  288.         case OID_GEN_MAXIMUM_TOTAL_SIZE:
  289.           ptr_query_cmplt->InformationBufferLength = 4U;
  290.           ptr_query_cmplt->OIDInputBuffer[0]       = 44U + ETH_MAX_SIZE;
  291.           break;
  292.         case OID_GEN_MEDIA_CONNECT_STATUS:
  293.           ptr_query_cmplt->InformationBufferLength = 4U;
  294.           if (link_state == ARM_ETH_LINK_UP) {
  295.             ptr_query_cmplt->OIDInputBuffer[0]     = (uint32_t)NdisMediaStateConnected;
  296.           } else {
  297.             ptr_query_cmplt->OIDInputBuffer[0]     = (uint32_t)NdisMediaStateDisconnected;
  298.           }
  299.           break;

  300.         case OID_GEN_PHYSICAL_MEDIUM:
  301.           ptr_query_cmplt->InformationBufferLength = 4U;
  302.           ptr_query_cmplt->OIDInputBuffer[0]       = (uint32_t)NdisPhysicalMediumUnspecified;
  303.           break;

  304.         case OID_GEN_XMIT_OK:
  305.           ptr_query_cmplt->InformationBufferLength = 4U;
  306.           ptr_query_cmplt->OIDInputBuffer[0]       = xmit_ok;
  307.           break;
  308.         case OID_GEN_RCV_OK:
  309.           ptr_query_cmplt->InformationBufferLength = 4U;
  310.           ptr_query_cmplt->OIDInputBuffer[0]       = rcv_ok;
  311.           break;
  312.         case OID_GEN_XMIT_ERROR:
  313.           ptr_query_cmplt->InformationBufferLength = 4U;
  314.           ptr_query_cmplt->OIDInputBuffer[0]       = xmit_error;
  315.           break;
  316.         case OID_GEN_RCV_ERROR:
  317.           ptr_query_cmplt->InformationBufferLength = 4U;
  318.           ptr_query_cmplt->OIDInputBuffer[0]       = rcv_error;
  319.           break;
  320.         case OID_GEN_RCV_NO_BUFFER:
  321.           ptr_query_cmplt->InformationBufferLength = 4U;
  322.           ptr_query_cmplt->OIDInputBuffer[0]       = rcv_no_buffer;
  323.           break;

  324.         case OID_802_3_PERMANENT_ADDRESS:
  325.         case OID_802_3_CURRENT_ADDRESS:
  326.           ptr_query_cmplt->InformationBufferLength = 6U;
  327.           memcpy((void *)&ptr_query_cmplt->OIDInputBuffer[0], &mac_address, sizeof(ARM_ETH_MAC_ADDR));
  328.           break;
  329.         case OID_802_3_MULTICAST_LIST:
  330.           for (i = 0U; i < RNDIS_MCAST_NUM; i++) {
  331.             if ((__UNALIGNED_UINT32_READ(&mcast_address[0]) == 0U) &&
  332.                 (__UNALIGNED_UINT16_READ(&mcast_address[4]) == 0U)) {
  333.               break;
  334.             }
  335.           }
  336.           if (i == 0U) {
  337.             num = 0U;
  338.             ptr_query_cmplt->InformationBufferOffset = 0U;
  339.           } else {
  340.             num = i;
  341.             if (i < RNDIS_MCAST_NUM) {
  342.               num = i + 1U;
  343.             } else {
  344.               num = i;
  345.             }
  346.             memcpy((void *)&ptr_query_cmplt->OIDInputBuffer[0], mcast_address, num * sizeof(ARM_ETH_MAC_ADDR));
  347.           }
  348.           ptr_query_cmplt->InformationBufferLength = num * sizeof(ARM_ETH_MAC_ADDR);
  349.           break;
  350.         case OID_802_3_MAXIMUM_LIST_SIZE:
  351.           ptr_query_cmplt->InformationBufferLength = 4U;
  352.           ptr_query_cmplt->OIDInputBuffer[0]       = RNDIS_MCAST_NUM;
  353.           break;

  354.         default:
  355.           ptr_query_cmplt->InformationBufferOffset = 0U;
  356.           ptr_query_cmplt->InformationBufferLength = 0U;
  357.           status = RNDIS_STATUS_NOT_SUPPORTED;
  358.           break;
  359.       }
  360.       ptr_query_cmplt->Status        = status;
  361.       ptr_query_cmplt->MessageLength = ptr_query_cmplt->InformationBufferLength + 24U;
  362.       get_encapsulated_response_len  = ptr_query_cmplt->MessageLength;
  363.       break;

  364.     case REMOTE_NDIS_SET_MSG:
  365.       // Check message is valid
  366.       ptr_set_msg = (const REMOTE_NDIS_SET_MSG_t *)((const void *)buf);
  367.       if (ptr_set_msg->MessageLength < 28U) { return false; }

  368.       // Prepare response
  369.       ptr_set_cmplt = (REMOTE_NDIS_SET_CMPLT_t *)((void *)get_encapsulated_response_buf);
  370.       ptr_set_cmplt->MessageType               = REMOTE_NDIS_SET_CMPLT;
  371.       ptr_set_cmplt->MessageLength             = sizeof(REMOTE_NDIS_SET_CMPLT_t);
  372.       ptr_set_cmplt->RequestID                 = ptr_set_msg->RequestID;

  373.       switch (ptr_set_msg->Oid) {               // Handle OID
  374.         case OID_802_3_MULTICAST_LIST:
  375.           by = ptr_set_msg->InformationBufferLength;
  376.           if (by > (sizeof(ARM_ETH_MAC_ADDR) * RNDIS_MCAST_NUM)) {
  377.             by = sizeof(ARM_ETH_MAC_ADDR) * RNDIS_MCAST_NUM;
  378.           }
  379.           if (by > 0U) {
  380.             memcpy(mcast_address, (const void *)&ptr_set_msg->OIDInputBuffer[0], by);
  381.           }
  382.           break;
  383.         case OID_GEN_CURRENT_PACKET_FILTER:
  384.           if ((ptr_set_msg->InformationBufferLength == 4U) &&
  385.               (ptr_set_msg->InformationBufferOffset != 0U)) {
  386.             val = __UNALIGNED_UINT32_READ(((const uint8_t *)&ptr_set_msg->RequestID) + ptr_set_msg->InformationBufferOffset);
  387.             if (val != 0U) {
  388.               if ((val & RNDIS_FILTER_ALL_MULTICAST) != 0U) { packet_filter |= ARM_ETH_MAC_ADDRESS_MULTICAST; }
  389.               if ((val & RNDIS_FILTER_BROADCAST)     != 0U) { packet_filter |= ARM_ETH_MAC_ADDRESS_BROADCAST; }
  390.               if ((val & RNDIS_FILTER_PROMISCUOUS)   != 0U) { packet_filter |= ARM_ETH_MAC_ADDRESS_ALL;       }
  391.               if (link_state == ARM_ETH_LINK_DOWN) {
  392.                 link_state    = ARM_ETH_LINK_UP;
  393.                 link_state_up = true;
  394.               }
  395.               rndis_state = RNDIS_DATA_INITIALIZED;
  396.             } else {
  397.               if (rndis_state == RNDIS_DATA_INITIALIZED) {
  398.                 rndis_state = RNDIS_INITIALIZED;
  399.               }
  400.             }
  401.           } else {
  402.             status = RNDIS_STATUS_FAILURE;
  403.           }
  404.           break;
  405.         default:
  406.           status = RNDIS_STATUS_NOT_SUPPORTED;
  407.           break;
  408.       }

  409.       ptr_set_cmplt->Status         = status;
  410.       get_encapsulated_response_len = ptr_set_cmplt->MessageLength;
  411.       break;

  412.     case REMOTE_NDIS_RESET_MSG:
  413.       // Check message is valid
  414.       ptr_reset_msg = (const REMOTE_NDIS_RESET_MSG_t *)((const void *)buf);
  415.       if (ptr_reset_msg->MessageLength != sizeof(REMOTE_NDIS_RESET_MSG_t)) { return false; }

  416.       ResetVars();

  417.       // Prepare response
  418.       ptr_reset_cmplt = (REMOTE_NDIS_RESET_CMPLT_t *)((void *)get_encapsulated_response_buf);
  419.       ptr_reset_cmplt->MessageType             = REMOTE_NDIS_RESET_CMPLT;
  420.       ptr_reset_cmplt->MessageLength           = sizeof(REMOTE_NDIS_RESET_CMPLT_t);
  421.       ptr_reset_cmplt->Status                  = status;
  422.       ptr_reset_cmplt->AddressingReset         = 0U;
  423.       get_encapsulated_response_len            = ptr_reset_cmplt->MessageLength;
  424.       break;

  425.     case REMOTE_NDIS_KEEPALIVE_MSG:
  426.       // Check message is valid
  427.       ptr_keepalive_msg = (const REMOTE_NDIS_KEEPALIVE_MSG_t *)((const void *)buf);
  428.       if (ptr_keepalive_msg->MessageLength != sizeof(REMOTE_NDIS_KEEPALIVE_MSG_t)) { return false; }

  429.       // Prepare response
  430.       ptr_keepalive_cmplt = (REMOTE_NDIS_KEEPALIVE_CMPLT_t *)((void *)get_encapsulated_response_buf);
  431.       ptr_keepalive_cmplt->MessageType         = REMOTE_NDIS_KEEPALIVE_CMPLT;
  432.       ptr_keepalive_cmplt->MessageLength       = sizeof(REMOTE_NDIS_KEEPALIVE_CMPLT_t);
  433.       ptr_keepalive_cmplt->RequestID           = ptr_keepalive_msg->RequestID;
  434.       ptr_keepalive_cmplt->Status              = status;
  435.       get_encapsulated_response_len            = ptr_keepalive_cmplt->MessageLength;
  436.       break;

  437.     default:
  438.       return false;
  439.   }

  440.   if (get_encapsulated_response_len != 0U) {
  441.     // If response is prepared send notification over Interrupt Endpoint
  442.     (void)USBD_CDC_ACM_Notify_ResponseAvailable (%Instance%);
  443.   }

  444.   return true;
  445. }


  446. // Callback function called upon reception of request to get encapsulated response sent by the USB Host.
  447. // \param[in]   max_len       maximum number of data bytes that USB Host expects to receive
  448. // \param[out]  buf           pointer to buffer containing get encapsulated response to be returned to USB Host.
  449. // \param[out]  len           pointer to number of data bytes to be returned to USB Host.
  450. // \return      true          get encapsulated response request processed.
  451. // \return      false         get encapsulated response request not supported or not processed.
  452. bool USBD_CDC%Instance%_ACM_GetEncapsulatedResponse (uint16_t max_len, uint8_t **buf, uint16_t *len) {
  453.   REMOTE_NDIS_INDICATE_STATUS_MSG_t *ptr_indicate_status_msg;
  454.   uint32_t                           status;

  455.   (void)max_len;

  456.   if (link_state_up || link_state_down) {   // Generate unsolicited INDICATE STATUS message if link status has changed
  457.     if (link_state_up) {
  458.       status = RNDIS_STATUS_MEDIA_CONNECT;
  459.     } else {
  460.       status = RNDIS_STATUS_MEDIA_DISCONNECT;
  461.     }

  462.     // Prepare INDICATE STATUS message
  463.     ptr_indicate_status_msg = (REMOTE_NDIS_INDICATE_STATUS_MSG_t *)((void *)get_encapsulated_response_buf);
  464.     ptr_indicate_status_msg->MessageType        = REMOTE_NDIS_INDICATE_STATUS_MSG;
  465.     ptr_indicate_status_msg->MessageLength      = 20U;
  466.     ptr_indicate_status_msg->Status             = status;
  467.     ptr_indicate_status_msg->StatusBufferLength = 0U;
  468.     ptr_indicate_status_msg->StatusBufferOffset = 0U;
  469.     get_encapsulated_response_len               = 20U;

  470.     link_state_up   = false;
  471.     link_state_down = false;
  472.   }

  473.   if (get_encapsulated_response_len != 0U) {    // If response is available return it
  474.     *buf = (uint8_t *)get_encapsulated_response_buf;
  475.     *len = (uint16_t) get_encapsulated_response_len;
  476.     get_encapsulated_response_len = 0U;
  477.   }

  478.   return true;
  479. }


  480. // Callback function called when all data was sent
  481. // \return                    none.
  482. void USBD_CDC%Instance%_ACM_DataSent (void) {
  483. }


  484. // Callback function called when new data was received
  485. // \param[in]   len           number of bytes available to read.
  486. // \return                    none.
  487. void USBD_CDC%Instance%_ACM_DataReceived (uint32_t len) {
  488.   (void)len;
  489. }


  490. //! [code_USBD_User_CDC_ACM_RNDIS_VETH]


  491. // Global functions exported for Virtual Ethernet driver

  492. /**
  493.   \fn          ARM_ETH_LINK_STATE RNDIS%Instance%_GetLinkState (void)
  494.   \brief       Get RNDIS Device Link state (data initialized means link is up).
  495.   \return      current link status \ref ARM_ETH_LINK_STATE
  496. */
  497. ARM_ETH_LINK_STATE RNDIS%Instance%_GetLinkState (void) {
  498.   if (rndis_state == RNDIS_DATA_INITIALIZED) {
  499.     return ARM_ETH_LINK_UP;
  500.   }

  501.   return ARM_ETH_LINK_DOWN;
  502. }

  503. /**
  504.   \fn          int32_t RNDIS%Instance%_SendFrame (const uint8_t *frame, uint32_t len, uint32_t flags)
  505.   \brief       Send Ethernet frame over USB CDC ACM RNDIS.
  506.   \param[in]   frame  Pointer to frame buffer with data to send
  507.   \param[in]   len    Frame buffer length in bytes
  508.   \return      \ref execution_status
  509. */
  510. int32_t RNDIS%Instance%_SendFrame (const uint8_t *frame, uint32_t len) {
  511.   REMOTE_NDIS_PACKET_MSG_t *ptr_packet_msg;
  512.    int32_t                  usb_cdc_acm_status;

  513.   ptr_packet_msg = (REMOTE_NDIS_PACKET_MSG_t *)((void *)packet_in);

  514.   if ((rndis_state == RNDIS_DATA_INITIALIZED) &&
  515.       (len >= ETH_MIN_SIZE)                   &&
  516.       (len <= ETH_MAX_SIZE))                   {
  517.     memcpy((void *)&ptr_packet_msg->PayLoad[0], frame, len);
  518.     ptr_packet_msg->MessageType              = REMOTE_NDIS_PACKET_MSG;
  519.     ptr_packet_msg->MessageLength            = len + 44U;
  520.     ptr_packet_msg->DataOffset               = 36U;
  521.     ptr_packet_msg->DataLength               = len;
  522.     ptr_packet_msg->OutOfBandDataOffset      = 0U;
  523.     ptr_packet_msg->OutOfBandDataLength      = 0U;
  524.     ptr_packet_msg->NumOutOfBandDataElements = 0U;
  525.     ptr_packet_msg->PerPacketInfoOffset      = 0U;
  526.     ptr_packet_msg->PerPacketInfoLength      = 0U;
  527.     ptr_packet_msg->Reserved[0]              = 0U;
  528.     ptr_packet_msg->Reserved[1]              = 0U;
  529.     usb_cdc_acm_status = USBD_CDC_ACM_WriteData (%Instance%, (const uint8_t *)ptr_packet_msg, (int32_t)ptr_packet_msg->MessageLength);
  530.     if (usb_cdc_acm_status == (int32_t)ptr_packet_msg->MessageLength) {
  531.       rcv_ok++;
  532.       return ARM_DRIVER_OK;
  533.     }
  534.     if (usb_cdc_acm_status < 0) {
  535.       rcv_error++;
  536.       return ARM_DRIVER_ERROR;
  537.     }
  538.     if (usb_cdc_acm_status == 0) {
  539.       return ARM_DRIVER_ERROR_BUSY;
  540.     }
  541.   }

  542.   return ARM_DRIVER_ERROR;
  543. }

  544. /**
  545.   \fn          int32_t RNDIS%Instance%_ReadFrame (uint8_t *frame, uint32_t len)
  546.   \brief       Read data of Ethernet frame received over USB CDC ACM RNDIS.
  547.   \param[in]   frame  Pointer to frame buffer for data to read into
  548.   \param[in]   len    Frame buffer length in bytes
  549.   \return      number of data bytes read or execution status
  550.                  - value >= 0: number of data bytes read
  551.                  - value < 0: error occurred, value is execution status as defined with \ref execution_status
  552. */
  553. int32_t RNDIS%Instance%_ReadFrame (uint8_t *frame, uint32_t len) {
  554.   REMOTE_NDIS_PACKET_MSG_t *ptr_packet_msg;
  555.   uint32_t                  data_len;
  556.    int32_t                  usb_cdc_acm_status;

  557.   ptr_packet_msg = (REMOTE_NDIS_PACKET_MSG_t *)((void *)packet_out);

  558.   if ((rndis_state == RNDIS_DATA_INITIALIZED) &&
  559.       (len >= ETH_MIN_SIZE)                   &&
  560.       (len <= ETH_MAX_SIZE))                   {
  561.     usb_cdc_acm_status = USBD_CDC_ACM_ReadData (%Instance%, (uint8_t *)ptr_packet_msg, USBD_CDC%Instance%_ACM_RECEIVE_BUF_SIZE);
  562.     if ((usb_cdc_acm_status != 0) && (usb_cdc_acm_status == (int32_t)ptr_packet_msg->MessageLength)) {
  563.       data_len = len;
  564.       if (data_len > ptr_packet_msg->DataLength) {
  565.         data_len = ptr_packet_msg->DataLength;
  566.       }
  567.       memcpy(frame, (const void *)&ptr_packet_msg->PayLoad[0], data_len);
  568.       xmit_ok++;
  569.       return (int32_t)data_len;
  570.     }
  571.     if (usb_cdc_acm_status < 0) {
  572.       xmit_error++;
  573.       return ARM_DRIVER_ERROR;
  574.     }
  575.     if (usb_cdc_acm_status == 0) {
  576.       return ARM_DRIVER_ERROR_BUSY;
  577.     }
  578.   }

  579.   return 0;
  580. }

  581. /**
  582.   \fn          uint32_t RNDIS%Instance%_GetRxFrameSize (void)
  583.   \brief       Get size of Ethernet frame received over USB CDC ACM RNDIS.
  584.   \return      number of bytes in received frame
  585. */
  586. uint32_t RNDIS%Instance%_GetRxFrameSize (void) {
  587.   uint32_t avail_data_len;

  588.   avail_data_len = (uint32_t)USBD_CDC_ACM_DataAvailable (%Instance%);

  589.   if (avail_data_len > 44U) {
  590.     avail_data_len -= 44U;
  591.   }

  592.   return avail_data_len;
  593. }
复制代码


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-6 11:15 , Processed in 0.227741 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表