struct io * connectio( struct server *srv, int verify, const char *eol, int timeout, char **cause) { int fd = -1, error = 0; struct addrinfo hints; struct addrinfo *ai; const char *fn = NULL; SSL *ssl; if (srv->ai == NULL) { memset(&hints, 0, sizeof hints); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(srv->host, srv->port, &hints, &srv->ai); if (error != 0) { *cause = xstrdup(gai_strerror(error)); return (NULL); } } for (ai = srv->ai; ai != NULL; ai = ai->ai_next) { retry: fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (fd < 0) { fn = "socket"; continue; } if (connect(fd, ai->ai_addr, ai->ai_addrlen) < 0) { error = errno; close(fd); errno = error; if (errno == EINTR) goto retry; fd = -1; fn = "connect"; continue; } break; } if (fd < 0) { xasprintf(cause, "%s: %s", fn, strerror(errno)); return (NULL); } if (!srv->ssl) return (io_create(fd, NULL, eol)); ssl = makessl(srv, fd, verify && srv->verify, timeout, cause); if (ssl == NULL) { close(fd); return (NULL); } return (io_create(fd, ssl, eol)); }
int io_mem_create(char *buf, size_t size, int flags, io_t **pio) { io_mem_t *im = NULL; dbg_err_if (buf == NULL); dbg_err_if (pio == NULL); dbg_err_if(io_create(io_mem_t, (io_t**)&im)); im->io.type = IO_TYPE_MEM; im->buf = buf; im->size = size; im->flags = flags; im->off = 0; im->io.read = (io_read_op) io_mem_read; im->io.write = (io_write_op) io_mem_write; im->io.seek = (io_seek_op) io_mem_seek; im->io.tell = (io_tell_op) io_mem_tell; im->io.close = (io_close_op) io_mem_close; im->io.free = (io_free_op) io_mem_free; *pio = (io_t*)im; return 0; err: if(im) io_free((io_t *)im); return ~0; }
static void _tcp_accept(uv_stream_t *master, int status, bool tls) { if (status != 0) { return; } uv_stream_t *client = handle_alloc(master->loop); if (!client) { return; } memset(client, 0, sizeof(*client)); io_create(master->loop, (uv_handle_t *)client, SOCK_STREAM); if (uv_accept(master, client) != 0) { uv_close((uv_handle_t *)client, io_free); return; } /* Set deadlines for TCP connection and start reading. * It will re-check every half of a request time limit if the connection * is idle and should be terminated, this is an educated guess. */ struct session *session = client->data; session->has_tls = tls; if (tls && !session->tls_ctx) { session->tls_ctx = tls_new(master->loop->data); } uv_timer_t *timer = &session->timeout; uv_timer_init(master->loop, timer); timer->data = client; uv_timer_start(timer, tcp_timeout_trigger, KR_CONN_RTT_MAX/2, KR_CONN_RTT_MAX/2); io_start_read((uv_handle_t *)client); }
void vfss_resize_buf(VFSS_TYPE* vfss, unsigned int size) { if (size > vfss->io_size) { io_destroy(vfss->io); vfss->io = io_create(size + sizeof(STORAGE_STACK)); vfss->io_size = size; } }
static void init(LORA* lora) { memset(lora, 0, sizeof(LORA)); lora->spi.io = io_create(LORA_SPI_IO_SIZE); lora->timer_txrx_timeout = timer_create(LORA_TIMER_TXRX_TIMEOUT_ID, HAL_LORA); lora->timer_poll_timeout = timer_create(LORA_TIMER_POLL_TIMEOUT_ID, HAL_LORA); lora->opened = false; lora->sys_vars = NULL; }
void rndis_set_vendor_description(HANDLE usbd, unsigned int iface, const char* vendor) { IO* io; unsigned int size = strlen(vendor) + 1; io = io_create(size); strcpy(io_data(io), vendor); io->data_size = size; io_write_sync(usbd, HAL_IO_REQ(HAL_USBD_IFACE, RNDIS_SET_VENDOR_DESCRIPTION), iface, io); io_destroy(io); }
void hidd_kbd_class_configured(USBD* usbd, USB_CONFIGURATION_DESCRIPTOR* cfg) { USB_INTERFACE_DESCRIPTOR* iface; USB_ENDPOINT_DESCRIPTOR* ep; uint8_t in_ep, hid_iface; unsigned in_ep_size; in_ep = in_ep_size = hid_iface = 0; //check control/data ep here for (iface = usb_get_first_interface(cfg); iface != NULL; iface = usb_get_next_interface(cfg, iface)) { if (iface->bInterfaceClass == HID_INTERFACE_CLASS && iface->bInterfaceSubClass == HID_SUBCLASS_BOOT_INTERFACE && iface->bInterfaceProtocol == HID_PROTOCOL_KEYBOARD) { ep = (USB_ENDPOINT_DESCRIPTOR*)usb_interface_get_first_descriptor(cfg, iface, USB_ENDPOINT_DESCRIPTOR_TYPE); if (ep != NULL) { in_ep = USB_EP_NUM(ep->bEndpointAddress); in_ep_size = ep->wMaxPacketSize; hid_iface = iface->bInterfaceNumber; break; } } } //No HID descriptors in interface if (in_ep == 0) return; HIDD_KBD* hidd = (HIDD_KBD*)malloc(sizeof(HIDD_KBD)); if (hidd == NULL) return; hidd->io = io_create(in_ep_size); if (hidd->io == NULL) { hidd_kbd_destroy(hidd); return; } hidd->iface = hid_iface; hidd->in_ep = in_ep; hidd->suspended = false; hidd->over = false; hidd->idle = 0; hidd->boot_protocol = 1; hidd->state = USB_HID_KBD_IDLE; memset(&hidd->kbd, 0x00, sizeof(BOOT_KEYBOARD)); #if (USBD_HID_DEBUG_REQUESTS) printf("Found USB HID device class, EP%d, iface: %d\n", hidd->in_ep, hidd->iface); #endif //USBD_HID_DEBUG_REQUESTS usbd_register_interface(usbd, hidd->iface, &__HIDD_KBD_CLASS, hidd); usbd_register_endpoint(usbd, hidd->iface, hidd->in_ep); usbd_usb_ep_open(usbd, USB_EP_IN | hidd->in_ep, USB_EP_INTERRUPT, in_ep_size); }
static inline void vfss_init(VFSS_TYPE* vfss) { vfss->volume.process = INVALID_HANDLE; vfss->io = io_create(FAT_SECTOR_SIZE + sizeof(STORAGE_STACK)); vfss->io_size = FAT_SECTOR_SIZE; #if (VFS_BER) ber_init(vfss); #endif //VFS_BER #if (VFS_NO_FS == 0) #if (VFS_SFS) sfs_init(vfss); #else fat16_init(vfss); #endif // VFS_SFS #endif // VFS_NO_FS }
// sets errno on error int socket_create(Socket *socket) { if (io_create(&socket->base, "plain-socket", (IODestroyFunction)socket_destroy, (IOReadFunction)socket_receive, (IOWriteFunction)socket_send) < 0) { return -1; } socket->handle = IO_HANDLE_INVALID; socket->family = AF_UNSPEC; socket->create_allocated = NULL; socket->destroy = socket_destroy_platform; socket->receive = socket_receive_platform; socket->send = socket_send_platform; return 0; }
static void tcp_accept(uv_stream_t *master, int status) { if (status != 0) { return; } uv_stream_t *client = handle_alloc(master->loop, sizeof(*client)); if (!client) { return; } memset(client, 0, sizeof(*client)); io_create(master->loop, (uv_handle_t *)client, SOCK_STREAM); if (uv_accept(master, client) != 0) { handle_free((uv_handle_t *)client); return; } io_start_read((uv_handle_t *)client); }
/* Fetch mail from stdin. */ int fetch_stdin_state_mail(struct account *a, struct fetch_ctx *fctx) { struct mail *m = fctx->mail; struct io *io; char *line, *cause; /* Open io for stdin. */ io = io_create(STDIN_FILENO, NULL, IO_LF); if (conf.debug > 3 && !conf.syslog) io->dup_fd = STDOUT_FILENO; /* Initialise the mail. */ if (mail_open(m, IO_BLOCKSIZE) != 0) { log_warn("%s: failed to create mail", a->name); goto error; } m->size = 0; /* Add default tags. */ default_tags(&m->tags, NULL); /* Loop reading the mail. */ for (;;) { /* * There can only be one mail on stdin so reentrancy is * irrelevent. This is a good thing since we want to check for * close which means end of mail. */ switch (io_pollline2(io, &line, &fctx->lbuf, &fctx->llen, conf.timeout, &cause)) { case 0: /* Normal close is fine. */ goto out; case -1: if (errno == EAGAIN) continue; log_warnx("%s: %s", a->name, cause); xfree(cause); goto error; } if (append_line(m, line, strlen(line)) != 0) { log_warn("%s: failed to resize mail", a->name); goto error; } if (m->size > conf.max_size) break; } out: if (io != NULL) io_free(io); fctx->state = fetch_stdin_state_exit; return (FETCH_MAIL); error: if (io != NULL) io_free(io); return (FETCH_ERROR); }
int create_data(const struct object_descriptor *descr, int size, const void *buffer) { return io_create(descr, size, buffer); }
void mscd_class_configured(USBD* usbd, USB_CONFIGURATION_DESCRIPTOR* cfg) { USB_INTERFACE_DESCRIPTOR* iface; USB_ENDPOINT_DESCRIPTOR* ep; void* config; int i; unsigned int ep_num, ep_size, iface_num, lun_count; ep_num = 0; //check control/data ep here for (iface = usb_get_first_interface(cfg); iface != NULL; iface = usb_get_next_interface(cfg, iface)) { ep = (USB_ENDPOINT_DESCRIPTOR*)usb_interface_get_first_descriptor(cfg, iface, USB_ENDPOINT_DESCRIPTOR_TYPE); if (ep != NULL && iface->bInterfaceClass == MSC_INTERFACE_CLASS) { ep_num = USB_EP_NUM(ep->bEndpointAddress); ep_size = ep->wMaxPacketSize; iface_num = iface->bInterfaceNumber; break; } } //No MSC interface if (ep_num == 0) return; i = usbd_get_cfg(usbd, iface_num); config = usbd_get_cfg_data(usbd, i); lun_count = 0; if (usbd_get_cfg_data_size(usbd, i) > (int)sizeof(uint32_t)) lun_count = MSC_LUN_COUNT(config); if ((config == NULL) || (usbd_get_cfg_data_size(usbd, i) < (int)((sizeof(SCSI_STORAGE_DESCRIPTOR)) * lun_count + sizeof(uint32_t))) || (lun_count == 0)) { #if (USBD_MSC_DEBUG_ERRORS) printf("MSCD: Failed to read user configuration\n"); #endif //USBD_MSC_DEBUG_ERRORS return; } MSCD* mscd = (MSCD*)malloc(sizeof(MSCD) + sizeof(void*) * lun_count); if (mscd == NULL) return; mscd->iface_num = iface_num; mscd->ep_num = ep_num; mscd->ep_size = ep_size; mscd->usbd = usbd; mscd->control = io_create(ep_size); mscd->data = io_create(USBD_MSC_IO_SIZE + sizeof(STORAGE_STACK)); mscd->lun_count = lun_count; mscd->io_busy_mask = 0x00000000; mscd->io_owner = -1; mscd->cbw = io_data(mscd->control); for (i = 0; i < mscd->lun_count; ++i) MSCD_SCSI(mscd)[i] = scsis_create(mscd_host_cb, mscd, i, MSC_LUN_CONFIGURATION(config, i)); if (mscd->control == NULL || mscd->data == NULL || MSCD_SCSI(mscd)[mscd->lun_count - 1] == NULL) { #if (USBD_MSC_DEBUG_ERRORS) printf("MSCD: Out of memory\n"); #endif //USBD_MSC_DEBUG_ERRORS mscd_destroy(mscd); return; } for (i = 0; i < mscd->lun_count; ++i) scsis_init(MSCD_SCSI(mscd)[i]); #if (USBD_MSC_DEBUG_REQUESTS) printf("Found USB MSCD class, EP%d, size: %d, iface: %d\n", ep_num, ep_size, iface_num); #endif //USBD_MSC_DEBUG_REQUESTS usbd_register_interface(usbd, iface_num, &__MSCD_CLASS, mscd); usbd_register_endpoint(usbd, iface_num, ep_num); usbd_usb_ep_open(usbd, USB_EP_IN | ep_num, USB_EP_BULK, ep_size); usbd_usb_ep_open(usbd, ep_num, USB_EP_BULK, ep_size); mscd_read_cbw(usbd, mscd); }
/* * ======== dev_create_device ======== * Purpose: * Called by the operating system to load the PM Bridge Driver for a * PM board (device). */ int dev_create_device(struct dev_object **device_obj, const char *driver_file_name, struct cfg_devnode *dev_node_obj) { struct cfg_hostres *host_res; struct ldr_module *module_obj = NULL; struct bridge_drv_interface *drv_fxns = NULL; struct dev_object *dev_obj = NULL; struct chnl_mgrattrs mgr_attrs; struct io_attrs io_mgr_attrs; u32 num_windows; struct drv_object *hdrv_obj = NULL; struct drv_data *drv_datap = dev_get_drvdata(bridge); int status = 0; DBC_REQUIRE(refs > 0); DBC_REQUIRE(device_obj != NULL); DBC_REQUIRE(driver_file_name != NULL); status = drv_request_bridge_res_dsp((void *)&host_res); if (status) { dev_dbg(bridge, "%s: Failed to reserve bridge resources\n", __func__); goto leave; } /* Get the Bridge driver interface functions */ bridge_drv_entry(&drv_fxns, driver_file_name); /* Retrieve the Object handle from the driver data */ if (drv_datap && drv_datap->drv_object) { hdrv_obj = drv_datap->drv_object; } else { status = -EPERM; pr_err("%s: Failed to retrieve the object handle\n", __func__); } /* Create the device object, and pass a handle to the Bridge driver for * storage. */ if (!status) { DBC_ASSERT(drv_fxns); dev_obj = kzalloc(sizeof(struct dev_object), GFP_KERNEL); if (dev_obj) { /* Fill out the rest of the Dev Object structure: */ dev_obj->dev_node_obj = dev_node_obj; dev_obj->module_obj = module_obj; dev_obj->cod_mgr = NULL; dev_obj->hchnl_mgr = NULL; dev_obj->hdeh_mgr = NULL; dev_obj->lock_owner = NULL; dev_obj->word_size = DSPWORDSIZE; dev_obj->hdrv_obj = hdrv_obj; dev_obj->dev_type = DSP_UNIT; /* Store this Bridge's interface functions, based on its * version. */ store_interface_fxns(drv_fxns, &dev_obj->bridge_interface); /* Call fxn_dev_create() to get the Bridge's device * context handle. */ status = (dev_obj->bridge_interface.pfn_dev_create) (&dev_obj->hbridge_context, dev_obj, host_res); /* Assert bridge_dev_create()'s ensure clause: */ DBC_ASSERT(status || (dev_obj->hbridge_context != NULL)); } else { status = -ENOMEM; } } /* Attempt to create the COD manager for this device: */ if (!status) status = init_cod_mgr(dev_obj); /* Attempt to create the channel manager for this device: */ if (!status) { mgr_attrs.max_channels = CHNL_MAXCHANNELS; io_mgr_attrs.birq = host_res->birq_registers; io_mgr_attrs.irq_shared = (host_res->birq_attrib & CFG_IRQSHARED); io_mgr_attrs.word_size = DSPWORDSIZE; mgr_attrs.word_size = DSPWORDSIZE; num_windows = host_res->num_mem_windows; if (num_windows) { /* Assume last memory window is for CHNL */ io_mgr_attrs.shm_base = host_res->dw_mem_base[1] + host_res->dw_offset_for_monitor; io_mgr_attrs.usm_length = host_res->dw_mem_length[1] - host_res->dw_offset_for_monitor; } else { io_mgr_attrs.shm_base = 0; io_mgr_attrs.usm_length = 0; pr_err("%s: No memory reserved for shared structures\n", __func__); } status = chnl_create(&dev_obj->hchnl_mgr, dev_obj, &mgr_attrs); if (status == -ENOSYS) { /* It's OK for a device not to have a channel * manager: */ status = 0; } /* Create CMM mgr even if Msg Mgr not impl. */ status = cmm_create(&dev_obj->hcmm_mgr, (struct dev_object *)dev_obj, NULL); /* Only create IO manager if we have a channel manager */ if (!status && dev_obj->hchnl_mgr) { status = io_create(&dev_obj->hio_mgr, dev_obj, &io_mgr_attrs); } /* Only create DEH manager if we have an IO manager */ if (!status) { /* Instantiate the DEH module */ status = bridge_deh_create(&dev_obj->hdeh_mgr, dev_obj); } /* Create DMM mgr . */ status = dmm_create(&dev_obj->dmm_mgr, (struct dev_object *)dev_obj, NULL); } /* Add the new DEV_Object to the global list: */ if (!status) { lst_init_elem(&dev_obj->link); status = drv_insert_dev_object(hdrv_obj, dev_obj); } /* Create the Processor List */ if (!status) { dev_obj->proc_list = kzalloc(sizeof(struct lst_list), GFP_KERNEL); if (!(dev_obj->proc_list)) status = -EPERM; else INIT_LIST_HEAD(&dev_obj->proc_list->head); } leave: /* If all went well, return a handle to the dev object; * else, cleanup and return NULL in the OUT parameter. */ if (!status) { *device_obj = dev_obj; } else { if (dev_obj) { kfree(dev_obj->proc_list); if (dev_obj->cod_mgr) cod_delete(dev_obj->cod_mgr); if (dev_obj->dmm_mgr) dmm_destroy(dev_obj->dmm_mgr); kfree(dev_obj); } *device_obj = NULL; } DBC_ENSURE((!status && *device_obj) || (status && !*device_obj)); return status; }
void cdc_acmd_class_configured(USBD* usbd, USB_CONFIGURATION_DESCRIPTOR* cfg) { USB_INTERFACE_DESCRIPTOR* iface; USB_INTERFACE_DESCRIPTOR* diface; CDC_UNION_DESCRIPTOR* u; USB_ENDPOINT_DESCRIPTOR* ep; uint8_t data_ep, data_iface; uint16_t data_ep_size; uint8_t control_ep, control_iface; uint16_t control_ep_size; //check control/data ep here for (iface = usb_get_first_interface(cfg); iface != NULL; iface = usb_get_next_interface(cfg, iface)) { //also skip RNDIS if ((iface->bInterfaceClass != CDC_COMM_INTERFACE_CLASS) || (iface->bInterfaceSubClass != CDC_ACM) || (iface->bInterfaceProtocol == CDC_CP_VENDOR)) continue; #if (USBD_CDC_ACM_DEBUG) printf("Found USB CDC ACM interface: %d\n", iface->bInterfaceNumber); #endif //USBD_CDC_ACM_DEBUG //find union descriptor for (u = usb_interface_get_first_descriptor(cfg, iface, CS_INTERFACE); u != NULL; u = usb_interface_get_next_descriptor(cfg, u, CS_INTERFACE)) { if ((u->bDescriptorSybType == CDC_DESCRIPTOR_UNION) && (u->bControlInterface == iface->bInterfaceNumber) && (u->bFunctionLength > sizeof(CDC_UNION_DESCRIPTOR))) break; } if (u == NULL) { #if (USBD_CDC_ACM_DEBUG) printf("USB CDC ACM: Warning - no UNION descriptor, skipping interface\n"); #endif //USBD_CDC_ACM_DEBUG continue; } data_iface = ((uint8_t*)u)[sizeof(CDC_UNION_DESCRIPTOR)]; diface = usb_find_interface(cfg, data_iface); if (diface == NULL) { #if (USBD_CDC_ACM_DEBUG) printf("USB CDC ACM: Warning no data interface\n"); #endif //USBD_CDC_ACM_DEBUG continue; } #if (USBD_CDC_ACM_DEBUG) printf("Found USB CDC ACM data interface: %d\n", data_iface); #endif //USBD_CDC_ACM_DEBUG ep = (USB_ENDPOINT_DESCRIPTOR*)usb_interface_get_first_descriptor(cfg, diface, USB_ENDPOINT_DESCRIPTOR_TYPE); if (ep == NULL) { #if (USBD_CDC_ACM_DEBUG) printf("USB CDC ACM: Warning no data EP, skipping interface\n"); #endif //USBD_CDC_ACM_DEBUG continue; } data_ep = USB_EP_NUM(ep->bEndpointAddress); data_ep_size = ep->wMaxPacketSize; control_iface = iface->bInterfaceNumber; control_ep = control_ep_size = 0; ep = (USB_ENDPOINT_DESCRIPTOR*)usb_interface_get_first_descriptor(cfg, iface, USB_ENDPOINT_DESCRIPTOR_TYPE); if (ep != NULL) { control_ep = USB_EP_NUM(ep->bEndpointAddress); control_ep_size = ep->wMaxPacketSize; } //configuration is ok, applying CDC_ACMD* cdc_acmd = (CDC_ACMD*)malloc(sizeof(CDC_ACMD)); if (cdc_acmd == NULL) { #if (USBD_CDC_ACM_DEBUG) printf("USB CDC ACM: Out of memory\n"); #endif //USBD_CDC_ACM_DEBUG return; } cdc_acmd->data_iface = data_iface; cdc_acmd->data_ep = data_ep; cdc_acmd->data_ep_size = data_ep_size; cdc_acmd->tx = cdc_acmd->rx = NULL; cdc_acmd->tx_stream = cdc_acmd->rx_stream = cdc_acmd->tx_stream_handle = cdc_acmd->rx_stream_handle = INVALID_HANDLE; cdc_acmd->suspended = false; cdc_acmd->control_iface = control_iface; cdc_acmd->control_ep = control_ep; cdc_acmd->control_ep_size = control_ep_size; cdc_acmd->notify = NULL; cdc_acmd->notify_busy = cdc_acmd->notify_pending = false; #if (USBD_CDC_ACM_FLOW_CONTROL) cdc_acmd->flow_sending = false; cdc_acmd->flow_changed = false; cdc_acmd->break_count = 0; #endif //USBD_CDC_ACM_FLOW_CONTROL #if (USBD_CDC_ACM_TX_STREAM_SIZE) cdc_acmd->tx = io_create(cdc_acmd->data_ep_size); cdc_acmd->tx_stream = stream_create(USBD_CDC_ACM_RX_STREAM_SIZE); cdc_acmd->tx_stream_handle = stream_open(cdc_acmd->tx_stream); if (cdc_acmd->tx == NULL || cdc_acmd->tx_stream_handle == INVALID_HANDLE) { #if (USBD_CDC_ACM_DEBUG) printf("USB CDC ACM: Out of memory\n"); #endif //USBD_CDC_ACM_DEBUG cdc_acmd_destroy(cdc_acmd); return; } cdc_acmd->tx_size = 0; cdc_acmd->tx_idle = true; usbd_usb_ep_open(usbd, USB_EP_IN | cdc_acmd->data_ep, USB_EP_BULK, cdc_acmd->data_ep_size); stream_listen(cdc_acmd->tx_stream, USBD_IFACE(cdc_acmd->data_iface, 0), HAL_USBD_IFACE); #endif //USBD_CDC_ACM_TX_STREAM_SIZE #if (USBD_CDC_ACM_RX_STREAM_SIZE) cdc_acmd->rx = io_create(cdc_acmd->data_ep_size); cdc_acmd->rx_stream = stream_create(USBD_CDC_ACM_RX_STREAM_SIZE); cdc_acmd->rx_stream_handle = stream_open(cdc_acmd->rx_stream); if (cdc_acmd->rx == NULL || cdc_acmd->rx_stream_handle == INVALID_HANDLE) { #if (USBD_CDC_ACM_DEBUG) printf("USB CDC ACM: Out of memory\n"); #endif //USBD_CDC_ACM_DEBUG cdc_acmd_destroy(cdc_acmd); return; } cdc_acmd->rx_free = 0; usbd_usb_ep_open(usbd, cdc_acmd->data_ep, USB_EP_BULK, cdc_acmd->data_ep_size); usbd_usb_ep_read(usbd, cdc_acmd->data_ep, cdc_acmd->rx, cdc_acmd->data_ep_size); #endif //USBD_CDC_ACM_RX_STREAM_SIZE usbd_register_interface(usbd, cdc_acmd->data_iface, &__CDC_ACMD_CLASS, cdc_acmd); usbd_register_endpoint(usbd, cdc_acmd->data_iface, cdc_acmd->data_ep); if (control_ep_size) { if (cdc_acmd->control_ep_size < 16) { #if (USBD_CDC_ACM_DEBUG) printf("USB CDC ACM: Warning - control endpoint is too small(%d), 16 at least required to fit notify", cdc_acmd->control_ep_size); #endif //USBD_CDC_ACM_DEBUG cdc_acmd->notify = io_create(16); } else cdc_acmd->notify = io_create(cdc_acmd->control_ep_size); if (cdc_acmd->notify == NULL) { cdc_acmd_destroy(cdc_acmd); return; } usbd_usb_ep_open(usbd, USB_EP_IN | cdc_acmd->control_ep, USB_EP_INTERRUPT, cdc_acmd->control_ep_size); usbd_register_interface(usbd, cdc_acmd->control_iface, &__CDC_ACMD_CLASS, cdc_acmd); usbd_register_endpoint(usbd, cdc_acmd->control_iface, cdc_acmd->control_ep); cdc_acmd_notify_serial_state(usbd, cdc_acmd, CDC_SERIAL_STATE_DCD | CDC_SERIAL_STATE_DSR); } cdc_acmd->DTR = cdc_acmd->RTS = false; cdc_acmd->baud.baud = 115200; cdc_acmd->baud.data_bits = 8; cdc_acmd->baud.parity = 'N'; cdc_acmd->baud.stop_bits = 1; } }