static vsf_err_t vsfusbd_HID_GetReport_prepare( struct vsfusbd_device_t *device, struct vsf_buffer_t *buffer, uint8_t* (*data_io)(void *param)) { struct vsfusbd_ctrl_request_t *request = &device->ctrl_handler.request; uint8_t iface = request->index; struct vsfusbd_config_t *config = &device->config[device->configuration]; struct vsfusbd_HID_param_t *param = (struct vsfusbd_HID_param_t *)config->iface[iface].protocol_param; uint8_t type = request->value >> 8, id = request->value; struct vsfusbd_HID_report_t *report = vsfusbd_HID_find_report(param, type, id); if ((NULL == param) || (NULL == report) || (type != report->type)) { return VSFERR_FAIL; } buffer->size = report->buffer.size; if (report->lock) { buffer->buffer = param->temp_buffer.buffer; } else { buffer->buffer = report->buffer.buffer; } return VSFERR_NONE; }
static vsf_err_t vsfusbd_HID_SetIdle_prepare( struct vsfusbd_device_t *device, struct vsf_buffer_t *buffer, uint8_t* (*data_io)(void *param)) { struct vsfusbd_ctrl_request_t *request = &device->ctrl_handler.request; uint8_t id = request->value; uint8_t iface = request->index; struct vsfusbd_config_t *config = &device->config[device->configuration]; struct vsfusbd_HID_param_t *param = (struct vsfusbd_HID_param_t *)config->iface[iface].protocol_param; struct vsfusbd_HID_report_t *report = vsfusbd_HID_find_report(param, USB_HID_REPORT_INPUT, id); if ((NULL == param) || (NULL == report) || (request->length != 0)) { return VSFERR_FAIL; } report->idle = request->value >> 8; return VSFERR_NONE; }
static vsf_err_t vsfusbd_HID_SetReport_process( struct vsfusbd_device_t *device, struct vsf_buffer_t *buffer) { struct vsfusbd_ctrl_request_t *request = &device->ctrl_handler.request; uint8_t type = request->value >> 8, id = request->value; uint8_t iface = request->index; struct vsfusbd_config_t *config = &device->config[device->configuration]; struct vsfusbd_HID_param_t *param = (struct vsfusbd_HID_param_t *)config->iface[iface].protocol_param; struct vsfusbd_HID_report_t *report = vsfusbd_HID_find_report(param, type, id); if ((NULL == param) || (NULL == report) || (type != report->type)) { return VSFERR_FAIL; } if (report->on_set_get_report != NULL) { return report->on_set_get_report(report); } return VSFERR_NONE; }
static vsf_err_t vsfusbd_HID_OUT_hanlder(struct vsfusbd_device_t *device, uint8_t ep) { struct interface_usbd_t *drv = device->drv; struct vsfusbd_config_t *config = &device->config[device->configuration]; int8_t iface = config->ep_OUT_iface_map[ep]; struct vsfusbd_HID_param_t *param; uint16_t pkg_size, ep_size; uint8_t buffer[64], *pbuffer = buffer; uint8_t report_id; struct vsfusbd_HID_report_t *report; if (iface < 0) { return VSFERR_FAIL; } param = (struct vsfusbd_HID_param_t *)config->iface[iface].protocol_param; if (NULL == param) { return VSFERR_FAIL; } ep_size = drv->ep.get_OUT_epsize(ep); pkg_size = drv->ep.get_OUT_count(ep); if (pkg_size > ep_size) { return VSFERR_FAIL; } drv->ep.read_OUT_buffer(ep, buffer, pkg_size); switch (param->output_state) { case HID_OUTPUT_STATE_WAIT: if (1 == param->num_of_OUTPUT_report) { report_id = 0; } else { report_id = buffer[0]; pbuffer++; pkg_size--; } report = vsfusbd_HID_find_report(param, USB_HID_REPORT_OUTPUT, report_id); if ((NULL == report) || (pkg_size > report->buffer.size)) { return VSFERR_FAIL; } memcpy(report->buffer.buffer, pbuffer, pkg_size); if (pkg_size < report->buffer.size) { report->pos = pkg_size; param->output_state = HID_OUTPUT_STATE_RECEIVING; param->current_output_report_id = report_id; } else if (report->on_set_get_report != NULL) { report->on_set_get_report(report); } break; case HID_OUTPUT_STATE_RECEIVING: report_id = param->current_output_report_id; report = vsfusbd_HID_find_report(param, USB_HID_REPORT_OUTPUT, report_id); if ((NULL == report) || ((pkg_size + report->pos) > report->buffer.size)) { return VSFERR_FAIL; } memcpy(report->buffer.buffer + report->pos, pbuffer, pkg_size); report->pos += pkg_size; if (report->pos == report->buffer.size) { report->pos = 0; if (report->on_set_get_report != NULL) { report->on_set_get_report(report); } param->output_state = HID_OUTPUT_STATE_WAIT; } break; default: return VSFERR_NONE; } return drv->ep.enable_OUT(param->ep_out); }
vsf_err_t vsfusbd_HID_request_prepare(struct vsfusbd_device_t *device) { struct vsfusbd_ctrl_handler_t *ctrl_handler = &device->ctrl_handler; struct vsf_buffer_t *buffer = &ctrl_handler->bufstream.mem.buffer; struct usb_ctrlrequest_t *request = &ctrl_handler->request; uint8_t iface = request->wIndex; struct vsfusbd_config_t *config = &device->config[device->configuration]; struct vsfusbd_HID_param_t *param = (struct vsfusbd_HID_param_t *)config->iface[iface].protocol_param; uint8_t type = request->wValue >> 8, id = request->wValue; struct vsfusbd_HID_report_t *report = vsfusbd_HID_find_report(param, type, id); switch (request->bRequest) { case USB_HIDREQ_GET_REPORT: if ((NULL == report) || (type != report->type)) { return VSFERR_FAIL; } buffer->size = report->buffer.size; buffer->buffer = report->buffer.buffer; break; case USB_HIDREQ_GET_IDLE: if ((NULL == report) || (request->wLength != 1)) { return VSFERR_FAIL; } buffer->size = 1; buffer->buffer = &report->idle; break; case USB_HIDREQ_GET_PROTOCOL: if ((request->wValue != 0) || (request->wLength != 1)) { return VSFERR_FAIL; } buffer->size = 1; buffer->buffer = ¶m->protocol; break; case USB_HIDREQ_SET_REPORT: if ((NULL == report) || (type != report->type)) { return VSFERR_FAIL; } buffer->size = report->buffer.size; buffer->buffer = report->buffer.buffer; break; case USB_HIDREQ_SET_IDLE: if (request->wLength != 0) { return VSFERR_FAIL; } for(uint8_t i = 0; i < param->num_of_report; i++) { if ((param->reports[i].type == USB_HID_REPORT_INPUT) && ((0 == id) || (param->reports[i].id == id))) { param->reports[i].idle = request->wValue >> 8; } } break; case USB_HIDREQ_SET_PROTOCOL: if ((request->wLength != 1) || ((request->wValue != USB_HID_PROTOCOL_BOOT) && (request->wValue != USB_HID_PROTOCOL_REPORT))) { return VSFERR_FAIL; } param->protocol = request->wValue; break; default: return VSFERR_FAIL; }