cdc-acm.c
00001 #include <cdc-acm.h>
00002 #include <cdc.h>
00003 #include <usb-api.h>
00004 #include <usb-core.h>
00005 #include <stdio.h>
00006
00007 static uint8_t usb_ctrl_data_buffer[32];
00008
00009 static void
00010 encapsulated_command(uint8_t *data, unsigned int length)
00011 {
00012 printf("Got CDC command: length %d\n", length);
00013 usb_send_ctrl_status();
00014 }
00015 static void
00016 set_line_encoding(uint8_t *data, unsigned int length)
00017 {
00018 if (length == 7) {
00019 static const char parity_char[] = {'N', 'O', 'E', 'M', 'S'};
00020 static const char *stop_bits_str[] = {"1","1.5","2"};
00021 const struct usb_cdc_line_coding *coding =
00022 (const struct usb_cdc_line_coding *)usb_ctrl_data_buffer;
00023 char parity = ((coding->bParityType > 4)
00024 ? '?' : parity_char[coding->bParityType]);
00025 const char *stop_bits = ((coding->bCharFormat > 2)
00026 ? "?" : stop_bits_str[coding->bCharFormat]);
00027 printf("Got CDC line coding: %ld/%d/%c/%s\n",
00028 coding->dwDTERate, coding->bDataBits, parity, stop_bits);
00029 usb_send_ctrl_status();
00030 } else {
00031 usb_error_stall();
00032 }
00033 }
00034
00035 static unsigned int
00036 handle_cdc_acm_requests()
00037 {
00038 printf("CDC request %02x %02x\n", usb_setup_buffer.bmRequestType, usb_setup_buffer.bRequest);
00039 switch(usb_setup_buffer.bmRequestType) {
00040 case 0x21:
00041
00042 if (usb_setup_buffer.wIndex != 0) return 0;
00043 switch(usb_setup_buffer.bRequest) {
00044 case SET_CONTROL_LINE_STATE:
00045 if (usb_setup_buffer.wValue & 0x02) {
00046 puts("Carrier on");
00047 } else {
00048 puts("Carrier off");
00049 }
00050 if (usb_setup_buffer.wValue & 0x01) {
00051 puts("DTE on");
00052 } else {
00053 puts("DTE off");
00054 }
00055 usb_send_ctrl_status();
00056 return 1;
00057
00058 case SEND_ENCAPSULATED_COMMAND:
00059 {
00060 unsigned int len = usb_setup_buffer.wLength;
00061 if (len > sizeof(usb_ctrl_data_buffer))
00062 len = sizeof(usb_ctrl_data_buffer);
00063 usb_get_ctrl_data(usb_ctrl_data_buffer, len,
00064 encapsulated_command);
00065 }
00066
00067 return 1;
00068
00069
00070 case SET_LINE_CODING:
00071 {
00072 unsigned int len = usb_setup_buffer.wLength;
00073 if (len > sizeof(usb_ctrl_data_buffer))
00074 len = sizeof(usb_ctrl_data_buffer);
00075 usb_get_ctrl_data(usb_ctrl_data_buffer, len,
00076 set_line_encoding);
00077 }
00078 return 1;
00079 }
00080 break;
00081 case 0xa1:
00082 if (usb_setup_buffer.wIndex != 0) return 0;
00083 switch(usb_setup_buffer.bRequest) {
00084 case GET_ENCAPSULATED_RESPONSE:
00085 printf("CDC response");
00086 usb_send_ctrl_status();
00087 return 1;
00088 }
00089 }
00090 return 0;
00091 }
00092
00093 static const struct USBRequestHandler cdc_acm_request_handler =
00094 {
00095 0x21, 0x7f,
00096 0x00, 0x00,
00097 handle_cdc_acm_requests
00098 };
00099
00100 static struct USBRequestHandlerHook cdc_acm_request_hook =
00101 {
00102 NULL,
00103 &cdc_acm_request_handler
00104 };
00105
00106 void
00107 usb_cdc_acm_setup()
00108 {
00109 usb_register_request_handler(&cdc_acm_request_hook);
00110 }