Contiki-NG
cdc-acm.c
1 #include <cdc-acm.h>
2 #include <cdc.h>
3 #include <usb-api.h>
4 #include <usb-core.h>
5 #include <stdio.h>
6 
7 static uint8_t usb_ctrl_data_buffer[32];
8 
9 static void
10 encapsulated_command(uint8_t *data, unsigned int length)
11 {
12  printf("Got CDC command: length %d\n", length);
13  usb_send_ctrl_status();
14 }
15 static void
16 set_line_encoding(uint8_t *data, unsigned int length)
17 {
18  if (length == 7) {
19  static const char parity_char[] = {'N', 'O', 'E', 'M', 'S'};
20  static const char *stop_bits_str[] = {"1","1.5","2"};
21  const struct usb_cdc_line_coding *coding =
22  (const struct usb_cdc_line_coding *)usb_ctrl_data_buffer;
23  char parity = ((coding->bParityType > 4)
24  ? '?' : parity_char[coding->bParityType]);
25  const char *stop_bits = ((coding->bCharFormat > 2)
26  ? "?" : stop_bits_str[coding->bCharFormat]);
27  printf("Got CDC line coding: %ld/%d/%c/%s\n",
28  coding->dwDTERate, coding->bDataBits, parity, stop_bits);
29  usb_send_ctrl_status();
30  } else {
31  usb_error_stall();
32  }
33 }
34 
35 static unsigned int
36 handle_cdc_acm_requests()
37 {
38  printf("CDC request %02x %02x\n", usb_setup_buffer.bmRequestType, usb_setup_buffer.bRequest);
39  switch(usb_setup_buffer.bmRequestType) {
40  case 0x21: /* CDC interface OUT requests */
41  /* Check if it's the right interface */
42  if (usb_setup_buffer.wIndex != 0) return 0;
43  switch(usb_setup_buffer.bRequest) {
44  case SET_CONTROL_LINE_STATE:
45  if (usb_setup_buffer.wValue & 0x02) {
46  puts("Carrier on");
47  } else {
48  puts("Carrier off");
49  }
50  if (usb_setup_buffer.wValue & 0x01) {
51  puts("DTE on");
52  } else {
53  puts("DTE off");
54  }
55  usb_send_ctrl_status();
56  return 1;
57 
58  case SEND_ENCAPSULATED_COMMAND:
59  {
60  unsigned int len = usb_setup_buffer.wLength;
61  if (len > sizeof(usb_ctrl_data_buffer))
62  len = sizeof(usb_ctrl_data_buffer);
63  usb_get_ctrl_data(usb_ctrl_data_buffer, len,
64  encapsulated_command);
65  }
66 
67  return 1;
68 
69 
70  case SET_LINE_CODING:
71  {
72  unsigned int len = usb_setup_buffer.wLength;
73  if (len > sizeof(usb_ctrl_data_buffer))
74  len = sizeof(usb_ctrl_data_buffer);
75  usb_get_ctrl_data(usb_ctrl_data_buffer, len,
76  set_line_encoding);
77  }
78  return 1;
79  }
80  break;
81  case 0xa1: /* CDC interface IN requests */
82  if (usb_setup_buffer.wIndex != 0) return 0;
83  switch(usb_setup_buffer.bRequest) {
84  case GET_ENCAPSULATED_RESPONSE:
85  printf("CDC response");
86  usb_send_ctrl_status();
87  return 1;
88  }
89  }
90  return 0;
91 }
92 
93 static const struct USBRequestHandler cdc_acm_request_handler =
94  {
95  0x21, 0x7f,
96  0x00, 0x00,
97  handle_cdc_acm_requests
98  };
99 
100 static struct USBRequestHandlerHook cdc_acm_request_hook =
101  {
102  NULL,
103  &cdc_acm_request_handler
104  };
105 
106 void
107 usb_cdc_acm_setup()
108 {
109  usb_register_request_handler(&cdc_acm_request_hook);
110 }