static vsf_err_t embflash_maldrv_erase(struct vsfsm_pt_t *pt, vsfsm_evt_t evt, uint64_t addr, uint32_t size) { struct embflash_mal_t *embflash = (struct embflash_mal_t *)pt->user_data; uint32_t pos = (uint32_t)addr + embflash->cursize; vsfsm_pt_begin(pt); pos = (uint32_t)addr; embflash->cursize = 0; embflash->notifier = pt->sm; while (embflash->cursize < size) { embflash->pagesize = vsfhal_flash_blocksize(embflash->index, pos, size - embflash->cursize, VSFMAL_OP_ERASE); if (vsfhal_flash_erase(embflash->index, pos)) return VSFERR_FAIL; vsfsm_pt_wfe(pt, VSFSM_EVT_USER); if (embflash->err) return embflash->err; embflash->cursize += embflash->pagesize; } vsfsm_pt_end(pt); return VSFERR_NONE; }
static vsf_err_t embflash_maldrv_read(struct vsfsm_pt_t *pt, vsfsm_evt_t evt, uint64_t addr, uint8_t *buff, uint32_t size) { struct embflash_mal_t *embflash = (struct embflash_mal_t *)pt->user_data; uint32_t pos = (uint32_t)addr + embflash->cursize; vsfsm_pt_begin(pt); if (vsfhal_flash_direct_read) { uint32_t base = vsfhal_flash_baseaddr(embflash->index); memcpy(buff, (uint8_t *)base + addr, size); return VSFERR_NONE; } pos = (uint32_t)addr; embflash->cursize = 0; embflash->notifier = pt->sm; while (embflash->cursize < size) { embflash->pagesize = vsfhal_flash_blocksize(embflash->index, pos, size - embflash->cursize, VSFMAL_OP_READ); if (vsfhal_flash_read(embflash->index, pos, buff + embflash->cursize)) return VSFERR_FAIL; vsfsm_pt_wfe(pt, VSFSM_EVT_USER); if (embflash->err) return embflash->err; embflash->cursize += embflash->pagesize; } vsfsm_pt_end(pt); return VSFERR_NONE; }
static vsf_err_t app_led_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt) { struct app_led_t *led = (struct app_led_t *)pt->user_data; struct vsfapp_t *app = led->app; struct interfaces_info_t const *ifs = app->sys.vsf->ifs; struct vsf_framework_t const *framework = &app->sys.vsf->framework; vsfsm_pt_begin(pt); while (1) { vsfsm_pt_wfe(pt, LED_EVT_CARRY); if (led->on) { ifs->gpio.clear(led->hw->hport, 1 << led->hw->hpin); if (led->sm_carry != NULL) { framework->post_evt(led->sm_carry, LED_EVT_CARRY); } } else { ifs->gpio.set(led->hw->hport, 1 << led->hw->hpin); } led->on = !led->on; } vsfsm_pt_end(pt); return VSFERR_NONE; }
static vsf_err_t vsf_malstream_write_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt) { struct vsf_malstream_t *malstream = (struct vsf_malstream_t *)pt->user_data; struct vsfmal_t *mal = malstream->mal; struct vsf_stream_t *stream = (struct vsf_stream_t *)malstream->mbufstream; uint64_t cur_addr; vsf_err_t err; vsfsm_pt_begin(pt); mal->op_block_size = mal->drv->block_size(mal, malstream->addr, 0, VSFMAL_OP_WRITE); if (mal->op_block_size != malstream->mbufstream->mem.multibuf.size) { return VSFERR_BUG; } mal->pt.user_data = mal; malstream->offset = 0; while (malstream->offset < malstream->size) { while (stream_get_data_size(stream) < mal->op_block_size) { vsfsm_pt_wfe(pt, VSF_MALSTREAM_ON_INOUT); } mal->pt.state = 0; vsfsm_pt_entry(pt); cur_addr = malstream->addr + malstream->offset; err = mal->drv->write(&mal->pt, evt, cur_addr, vsf_multibuf_get_payload(&malstream->mbufstream->mem.multibuf), mal->op_block_size); if (err > 0) return err; else if (err < 0) goto end; vsf_multibuf_pop(&malstream->mbufstream->mem.multibuf); malstream->offset += mal->op_block_size; if (malstream->offset >= malstream->size) { // fix before callback stream->callback_tx.on_inout = NULL; } if (stream->tx_ready && (stream->callback_tx.on_inout != NULL)) { stream->callback_tx.on_inout(stream->callback_tx.param); } } end: if (malstream->cb.on_finish != NULL) { malstream->cb.on_finish(malstream->cb.param); } vsfsm_pt_end(pt); return VSFERR_NONE; }
static vsf_err_t vsfip_telnetd_session_rx_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt) { struct vsfip_telnetd_session_t *session = (struct vsfip_telnetd_session_t *)pt->user_data; uint32_t len; vsf_err_t err; vsfsm_pt_begin(pt); session->caller_rxpt.sm = pt->sm; while (!session->disconnect) { session->caller_rxpt.state = 0; vsfsm_pt_entry(pt); err = vsfip_tcp_recv(&session->caller_rxpt, evt, session->so, &session->so->remote_sockaddr, &session->inbuf); if (err > 0) return err; else if (err < 0) { session->disconnect = true; // fake on_in event, just to wakeup tx_thread to exit vsfip_telnetd_session_stream_on_in(session); break; } while (session->inbuf->app.size > 0) { len = stream_write(session->stream_rx, &session->inbuf->app); if (!len && vsfsm_sem_pend(&session->stream_rx_sem, pt->sm)) { vsfsm_pt_wfe(pt, VSFIP_TELNETD_EVT_STREAM_OUT); continue; } session->inbuf->app.buffer += len; session->inbuf->app.size -= len; } vsfip_buffer_release(session->inbuf); } vsfsm_pt_end(pt); return VSFERR_NONE; }
static vsf_err_t uvc_init_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt) { vsf_err_t err; struct vsfusbh_uvc_t *hdata = (struct vsfusbh_uvc_t *)pt->user_data; struct vsfusbh_urb_t *vsfurb = &hdata->ctrl_urb; vsfsm_pt_begin(pt); // reset interfaces 1 (video) vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = vsfusbh_set_interface(hdata->usbh, vsfurb, 1, 0); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; vsfsm_pt_end(pt); return VSFERR_NONE; }
static vsf_err_t hub_reset_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt) { struct vsfusbh_hub_t *hub = (struct vsfusbh_hub_t *)pt->user_data; struct vsfusbh_urb_t *vsfurb = hub->vsfurb; vsf_err_t err; vsfsm_pt_begin(pt); hub->retry = 0; do { /* send command to reset port */ vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = hub_set_port_feature(hub->usbh, vsfurb, hub->counter, USB_PORT_FEAT_RESET); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; /* delay 100ms after port reset*/ vsfsm_pt_delay(pt, 100); // clear reset vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = hub_clear_port_feature(hub->usbh, vsfurb, hub->counter, USB_PORT_FEAT_C_RESET); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; /* delay 100ms after port reset*/ vsfsm_pt_delay(pt, 50); /* get port status for check */ vsfurb->transfer_buffer = &hub->hub_portsts; vsfurb->transfer_length = sizeof(hub->hub_portsts); err = hub_get_port_status(hub->usbh, vsfurb, hub->counter); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; /* check port status after reset */ if (hub->hub_portsts.wPortStatus & USB_PORT_STAT_ENABLE) { return VSFERR_NONE; } else { /* delay 200ms for next reset*/ vsfsm_pt_delay(pt, 200); } } while (hub->retry++ <= 3); vsfsm_pt_end(pt); return VSFERR_FAIL; }
static vsf_err_t hub_init_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt) { vsf_err_t err; struct vsfusbh_hub_t *hub = (struct vsfusbh_hub_t *)pt->user_data; struct vsfusbh_urb_t *vsfurb = hub->vsfurb; vsfsm_pt_begin(pt); vsfurb->sm = &hub->sm; // init hub err = hub_class_check(hub); if (err != VSFERR_NONE) return err; vsfurb->transfer_buffer = &hub->hub_desc; vsfurb->transfer_length = 4; err = hub_get_descriptor(hub->usbh, vsfurb); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; if (hub->hub_desc.bDescLength > sizeof(hub->hub_desc)) { return VSFERR_FAIL; } vsfurb->transfer_buffer = &hub->hub_desc; vsfurb->transfer_length = hub->hub_desc.bDescLength; err = hub_get_descriptor(hub->usbh, vsfurb); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; hub->dev->maxchild = min(hub->hub_desc.bNbrPorts, USB_MAXCHILDREN); vsfurb->transfer_buffer = &hub->hub_status; vsfurb->transfer_length = sizeof(hub->hub_status); err = hub_get_status(hub->usbh, vsfurb); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; hub->counter = 0; do { hub->counter++; hub->vsfurb->transfer_buffer = NULL; hub->vsfurb->transfer_length = 0; err = hub_set_port_feature(hub->usbh, hub->vsfurb, hub->counter, USB_PORT_FEAT_POWER); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; vsfsm_pt_delay(pt, hub->hub_desc.bPwrOn2PwrGood * 2); } while (hub->counter < hub->dev->maxchild); vsfsm_pt_end(pt); return VSFERR_NONE; }
static vsf_err_t hub_scan_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt) { vsf_err_t err; struct vsfusbh_hub_t *hub = (struct vsfusbh_hub_t *)pt->user_data; struct vsfusbh_urb_t *vsfurb = hub->vsfurb; vsfsm_pt_begin(pt); do { hub->counter = 1; do { // get port status vsfurb->transfer_buffer = &hub->hub_portsts; vsfurb->transfer_length = sizeof(hub->hub_portsts); err = hub_get_port_status(hub->usbh, vsfurb, hub->counter); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; if (hub->hub_portsts.wPortChange & USB_PORT_STAT_C_CONNECTION) { // try to connect vsfsm_pt_wfpt(pt, &hub->drv_connect_pt); } else if (hub->hub_portsts.wPortChange & USB_PORT_STAT_C_ENABLE) { vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = hub_clear_port_feature(hub->usbh, vsfurb, hub->counter, USB_PORT_FEAT_C_ENABLE); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; hub->hub_portsts.wPortChange &= ~USB_PORT_STAT_C_ENABLE; } if (hub->hub_portsts.wPortChange & USB_PORT_STAT_C_SUSPEND) { vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = hub_clear_port_feature(hub->usbh, vsfurb, hub->counter, USB_PORT_FEAT_C_SUSPEND); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; hub->hub_portsts.wPortChange &= ~USB_PORT_STAT_C_SUSPEND; } if (hub->hub_portsts.wPortChange & USB_PORT_STAT_C_OVERCURRENT) { vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = hub_clear_port_feature(hub->usbh, vsfurb, hub->counter, USB_PORT_FEAT_C_OVER_CURRENT); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; hub->hub_portsts.wPortChange &= ~USB_PORT_FEAT_C_OVER_CURRENT; // TODO : power every port } if (hub->hub_portsts.wPortChange & USB_PORT_STAT_C_RESET) { vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = hub_clear_port_feature(hub->usbh, vsfurb, hub->counter, USB_PORT_FEAT_C_RESET); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; hub->hub_portsts.wPortChange &= ~USB_PORT_FEAT_C_RESET; } } while (hub->counter++ < hub->dev->maxchild); // TODO : poll hub status vsfsm_pt_delay(pt, 500); } while (1); vsfsm_pt_end(pt); return VSFERR_NONE; }
static vsf_err_t hub_connect_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt) { vsf_err_t err; struct vsfusbh_hub_t *hub = (struct vsfusbh_hub_t *)pt->user_data; struct vsfusbh_urb_t *vsfurb = hub->vsfurb; struct vsfusbh_device_t *dev; vsfsm_pt_begin(pt); /* clear the cnnection change state */ vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = hub_clear_port_feature(hub->usbh, vsfurb, hub->counter, USB_PORT_FEAT_C_CONNECTION); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; if (hub->dev->children[hub->counter - 1] != NULL) { vsfusbh_disconnect_device(hub->usbh, &hub->dev->children[hub->counter - 1]); } if (!(hub->hub_portsts.wPortStatus & USB_PORT_STAT_CONNECTION)) { if (hub->hub_portsts.wPortStatus & USB_PORT_STAT_ENABLE) { vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = hub_clear_port_feature(hub->usbh, vsfurb, hub->counter, USB_PORT_FEAT_ENABLE); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; } return VSFERR_NONE; } if (hub->hub_portsts.wPortStatus & USB_PORT_STAT_LOW_SPEED) { vsfsm_pt_delay(pt, 200); } vsfsm_pt_wfpt(pt, &hub->drv_reset_pt); vsfsm_pt_delay(pt, 200); // wait for new_dev free while (hub->usbh->new_dev != NULL) { vsfsm_pt_delay(pt, 200); } dev = vsfusbh_alloc_device(hub->usbh); if (NULL == dev) return VSFERR_FAIL; if (hub->hub_portsts.wPortStatus & USB_PORT_STAT_LOW_SPEED) { dev->speed = USB_SPEED_LOW; dev->slow = 1; } else if (hub->hub_portsts.wPortStatus & USB_PORT_STAT_HIGH_SPEED) dev->speed = USB_SPEED_HIGH; else dev->speed = USB_SPEED_FULL; hub->dev->children[hub->counter - 1] = dev; dev->parent = hub->dev; hub->usbh->new_dev = dev; vsfsm_post_evt_pending(&hub->usbh->sm, VSFSM_EVT_NEW_DEVICE); vsfsm_pt_end(pt); return VSFERR_NONE; }
vsf_err_t vsfusbh_probe_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt) { vsf_err_t err; uint32_t len; struct vsfusbh_t *usbh = (struct vsfusbh_t *)pt->user_data; struct vsfusbh_urb_t *probe_urb = usbh->probe_urb; struct vsfusbh_device_t *dev = usbh->new_dev; vsfsm_pt_begin(pt); dev->devnum_temp = dev->devnum; dev->devnum = 0; dev->epmaxpacketin[0] = 8; dev->epmaxpacketout[0] = 8; probe_urb->vsfdev = dev; probe_urb->sm = &usbh->sm; probe_urb->timeout = DEFAULT_TIMEOUT; // get 8 bytes device descriptor probe_urb->transfer_buffer = &dev->descriptor; probe_urb->transfer_length = 8; err = vsfusbh_get_descriptor(usbh, probe_urb, USB_DT_DEVICE, 0); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (probe_urb->status != URB_OK) return VSFERR_FAIL; dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0; dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0; // set address dev->devnum = dev->devnum_temp; probe_urb->transfer_buffer = NULL; probe_urb->transfer_length = 0; err = vsfusbh_set_address(usbh, probe_urb); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (probe_urb->status != URB_OK) return VSFERR_FAIL; vsfsm_pt_delay(pt, 10); // get full device descriptor probe_urb->transfer_buffer = &dev->descriptor; probe_urb->transfer_length = sizeof(dev->descriptor); err = vsfusbh_get_descriptor(usbh, probe_urb, USB_DT_DEVICE, 0); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (probe_urb->status != URB_OK) return VSFERR_FAIL; // NOTE: only probe first configuration if (dev->descriptor.bNumConfigurations < 1) return VSFERR_FAIL; dev->num_config = 1; // NOTE: not min(USB_MAXCONFIG, dev->descriptor.bNumConfigurations) len = sizeof(struct usb_config_t) * dev->num_config; dev->config = vsf_bufmgr_malloc_aligned(len, 4); if (dev->config == NULL) { vsf_bufmgr_free(probe_urb->transfer_buffer); return VSFERR_FAIL; } memset(dev->config, 0, sizeof(struct usb_config_t) * dev->num_config); for (dev->temp_u8 = 0; dev->temp_u8 < dev->num_config; dev->temp_u8++) { // get 9 bytes configuration probe_urb->transfer_buffer = vsf_bufmgr_malloc(9); if (probe_urb->transfer_buffer == NULL) goto get_config_fail; probe_urb->transfer_length = 9; err = vsfusbh_get_descriptor(usbh, probe_urb, USB_DT_CONFIG, dev->temp_u8); if (err != VSFERR_NONE) goto get_config_fail; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (probe_urb->status != URB_OK) goto get_config_fail; // get wTotalLength len = GET_U16_LSBFIRST(&((uint8_t *)(probe_urb->transfer_buffer))[2]); vsf_bufmgr_free(probe_urb->transfer_buffer); // get full configuation probe_urb->transfer_buffer = vsf_bufmgr_malloc(len); if (probe_urb->transfer_buffer == NULL) goto get_config_fail; probe_urb->transfer_length = len; err = vsfusbh_get_descriptor(usbh, probe_urb, USB_DT_CONFIG, dev->temp_u8); if (err != VSFERR_NONE) goto get_config_fail; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (probe_urb->status != URB_OK) goto get_config_fail; // check wTotalLength len = GET_U16_LSBFIRST(&((uint8_t *)(probe_urb->transfer_buffer))[2]); if (probe_urb->actual_length != len) goto get_config_fail; err = parse_configuration(dev->config + dev->temp_u8, probe_urb->transfer_buffer); if (err != VSFERR_NONE) goto get_config_fail; dev->config[dev->temp_u8].config_buffer = probe_urb->transfer_buffer; probe_urb->transfer_buffer = NULL; continue; get_config_fail: if (probe_urb->transfer_buffer != NULL) { vsf_bufmgr_free(probe_urb->transfer_buffer); probe_urb->transfer_buffer = NULL; } // NOTE: do not free dev->config here !!! return VSFERR_FAIL; } // set the default configuration probe_urb->transfer_buffer = NULL; probe_urb->transfer_length = 0; err = vsfusbh_set_configuration(usbh, probe_urb, dev->config->bConfigurationValue); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (probe_urb->status != URB_OK) return VSFERR_FAIL; dev->actconfig = dev->config; vsfusbh_set_maxpacket_ep(dev); vsfsm_pt_end(pt); return VSFERR_NONE; }
static vsf_err_t uvc_ctrl_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt) { vsf_err_t err; struct vsfusbh_uvc_t *hdata = (struct vsfusbh_uvc_t *)pt->user_data; struct vsfusbh_urb_t *vsfurb = &hdata->ctrl_urb; vsfsm_pt_begin(pt); // reset interfaces 1 (video) vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = vsfusbh_set_interface(hdata->usbh, vsfurb, 1, 0); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; // reset interfaces 3 (audio) vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = vsfusbh_set_interface(hdata->usbh, vsfurb, 3, 0); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; if (hdata->set_param.connected == 0) { vsfsm_post_evt_pending(&hdata->video_sm, UAV_ISO_DISABLE); vsfsm_post_evt_pending(&hdata->audio_sm, UAV_ISO_DISABLE); return VSFERR_NONE; } if (hdata->set_param.video_enable) { // negotiate hdata->video_iso_packet_len = 800; hdata->video_iso_ep = 1; // commit param vsfurb->transfer_buffer = hdata->ctrl_urb_buf; memcpy(vsfurb->transfer_buffer, negotiate_temp, 26); vsfurb->transfer_length = 26; vsfurb->pipe = usb_sndctrlpipe(vsfurb->vsfdev, 0); err = vsfusbh_control_msg(hdata->usbh, vsfurb, USB_RECIP_INTERFACE | USB_DIR_OUT, SET_CUR, 0x0200, 0x0001); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; // set interfaces vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = vsfusbh_set_interface(hdata->usbh, vsfurb, 1, 3); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; // enable video vsfsm_post_evt_pending(&hdata->video_sm, UAV_ISO_ENABLE); } if (hdata->set_param.audio_enable) { // TODO // enable audio vsfsm_post_evt_pending(&hdata->audio_sm, UAV_ISO_ENABLE); } vsfsm_pt_end(pt); return VSFERR_NONE; }
static vsf_err_t vsfip_telnetd_session_tx_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt) { struct vsfip_telnetd_session_t *session = (struct vsfip_telnetd_session_t *)pt->user_data; uint32_t len; vsf_err_t err; vsfsm_pt_begin(pt); session->caller_txpt.sm = pt->sm; while (!session->disconnect) { len = stream_get_data_size(session->stream_tx); if (!len && vsfsm_sem_pend(&session->stream_tx_sem, pt->sm)) { vsfsm_pt_wfe(pt, VSFIP_TELNETD_EVT_STREAM_IN); if (session->disconnect) break; continue; } retry_alloc_buf: session->outbuf = VSFIP_TCPBUF_GET(len); if (NULL == session->outbuf) { vsfsm_pt_delay(pt, 5); if (session->disconnect) break; goto retry_alloc_buf; } session->outbuf->app.size = stream_read(session->stream_tx, &session->outbuf->app); if (!session->outbuf->app.size) { vsfip_buffer_release(session->outbuf); continue; } session->caller_txpt.state = 0; vsfsm_pt_entry(pt); err = vsfip_tcp_send(&session->caller_txpt, evt, session->so, &session->so->remote_sockaddr, session->outbuf, false); if (err > 0) return err; else if (err < 0) { session->disconnect = true; } } // close tcp socket session->caller_txpt.state = 0; vsfsm_pt_entry(pt); err = vsfip_tcp_close(&session->caller_txpt, evt, session->so); if (err > 0) return err; // close socket no matter if tcp closed OK or not vsfip_close(session->so); session->connected = false; vsfsm_pt_end(pt); return VSFERR_NONE; }
// vsfshell_output_thread is used to process the events // from the receiver of the stream_tx vsf_err_t vsfshell_output_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt, const char *format, ...) { struct vsfshell_t *shell = (struct vsfshell_t *)pt->user_data; uint32_t str_len, size_avail; struct vsf_buffer_t buffer; va_list ap; char *printf_buff; uint32_t printf_size; vsfsm_pt_begin(pt); // get lock here if (vsfsm_crit_enter(&shell->output_crit, pt->sm)) { vsfsm_pt_wfe(pt, VSFSHELL_EVT_OUTPUT_CRIT_AVAIL); } shell->output_sm = pt->sm; if (shell->output_interrupted && (pt->sm == &shell->sm)) { // is vsfshell_input_thread is interrupted // and current pt is vsfshell_input_thread // then output the VSFSHELL_PROMPT and the original commandline shell->output_interrupted = false; size_avail = stream_get_free_size(shell->stream_tx); while (size_avail < strlen(VSFSHELL_PROMPT)) { vsfsm_pt_wfe(pt, VSFSHELL_EVT_STREAMTX_ONOUT); size_avail = stream_get_free_size(shell->stream_tx); } buffer.buffer = (uint8_t *)VSFSHELL_PROMPT; buffer.size = strlen(VSFSHELL_PROMPT); stream_write(shell->stream_tx, &buffer); shell->prompted = true; shell->tbuffer.buffer.buffer[shell->tbuffer.position] = '\0'; shell->printf_pos = (char *)shell->tbuffer.buffer.buffer; str_len = strlen(shell->printf_pos); while (str_len > 0) { size_avail = stream_get_free_size(shell->stream_tx); if (!size_avail) { vsfsm_pt_wfe(pt, VSFSHELL_EVT_STREAMTX_ONOUT); size_avail = stream_get_free_size(shell->stream_tx); str_len = strlen(shell->printf_pos); } if (size_avail) { buffer.buffer = (uint8_t *)shell->printf_pos; buffer.size = min(str_len, size_avail); buffer.size = stream_write(shell->stream_tx, &buffer); shell->printf_pos += buffer.size; str_len = strlen(shell->printf_pos); } } } va_start(ap, format); printf_size = sizeof(shell->printf_buff); printf_buff = shell->printf_buff; if (pt->sm != shell->input_sm) { // if current pt is not frontend, then add a new line if (shell->input_sm == &shell->sm) { // if current frontend pt is vsfshell_input_thread // then set output_interrupted, so that current command line // input will be recovered later shell->output_interrupted = true; } if (shell->prompted) { // add a new line if prompt is outputed strcpy(shell->printf_buff, VSFSHELL_LINEEND); printf_size -= strlen(VSFSHELL_LINEEND); printf_buff += strlen(VSFSHELL_LINEEND); shell->prompted = false; } } str_len = vsnprintf(printf_buff, printf_size, format, ap); va_end(ap); shell->printf_pos = shell->printf_buff; while (str_len > 0) { size_avail = stream_get_free_size(shell->stream_tx); if (!size_avail) { vsfsm_pt_wfe(pt, VSFSHELL_EVT_STREAMTX_ONOUT); size_avail = stream_get_free_size(shell->stream_tx); str_len = strlen(shell->printf_pos); } if (size_avail) { buffer.buffer = (uint8_t *)shell->printf_pos; buffer.size = min(str_len, size_avail); buffer.size = stream_write(shell->stream_tx, &buffer); shell->printf_pos += buffer.size; str_len = strlen(shell->printf_pos); } } shell->output_sm = NULL; vsfsm_crit_leave(&shell->output_crit); vsfsm_pt_end(pt); return VSFERR_NONE; }
// vsfshell_input_thread is used to process the events // from the sender of the stream_rx vsf_err_t vsfshell_input_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt) { struct vsfshell_t *shell = (struct vsfshell_t *)pt->user_data; struct vsfsm_pt_t *output_pt = &shell->output_pt; char *cmd = (char *)shell->tbuffer.buffer.buffer; struct vsf_buffer_t buffer; vsfsm_pt_begin(pt); vsfsm_pt_wfe(pt, VSFSHELL_EVT_STREAMTX_ONCONN); vsfshell_printf(output_pt, "vsfshell 0.1 beta by SimonQian" VSFSHELL_LINEEND); vsfshell_printf(output_pt, VSFSHELL_PROMPT); shell->prompted = true; while (1) { vsfsm_pt_wfe(pt, VSFSHELL_EVT_STREAMRX_ONIN); do { buffer.buffer = (uint8_t *)&shell->ch; buffer.size = 1; buffer.size = stream_read(shell->stream_rx, &buffer); if (0 == buffer.size) { break; } if (shell->echo) { if ('\r' == shell->ch) { vsfshell_printf(output_pt, VSFSHELL_LINEEND); } else if ('\b' == shell->ch) { if (shell->tbuffer.position) { vsfshell_printf(output_pt, "\b \b"); shell->tbuffer.position--; } continue; } else if (//!((shell->ch >= ' ') && (shell->ch <= '~')) || (shell->tbuffer.position >= shell->tbuffer.buffer.size - 1)) { continue; } else { vsfshell_printf(output_pt, "%c", shell->ch); } } if ('\r' == shell->ch) { if (shell->tbuffer.position > 0) { // create new handler thread cmd[shell->tbuffer.position] = '\0'; if (vsfshell_new_handler_thread(shell, cmd)) { vsfshell_printf(output_pt, "Fail to execute : %s" VSFSHELL_LINEEND, cmd); vsfshell_printf(output_pt, VSFSHELL_PROMPT); } shell->tbuffer.position = 0; } else { vsfshell_printf(output_pt, VSFSHELL_PROMPT); } shell->prompted = true; break; } else if (shell->ch != '\n') { cmd[shell->tbuffer.position++] = shell->ch; } } while (buffer.size > 0); } vsfsm_pt_end(pt); return VSFERR_NOT_READY; }
static vsf_err_t uvc_ctrl_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt) { vsf_err_t err; struct vsfusbh_uvc_t *hdata = (struct vsfusbh_uvc_t *)pt->user_data; struct vsfusbh_urb_t *vsfurb = &hdata->ctrl_urb; vsfsm_pt_begin(pt); if (hdata->set_param.video_enable) { // negotiate hdata->video_iso_packet_len = 1024; hdata->video_iso_ep = 1; // commit param vsfurb->transfer_buffer = hdata->ctrl_urb_buf; memcpy(vsfurb->transfer_buffer, negotiate_temp, 26); vsfurb->transfer_length = 26; vsfurb->pipe = usb_sndctrlpipe(vsfurb->vsfdev, 0); err = vsfusbh_control_msg(hdata->usbh, vsfurb, USB_TYPE_CLASS |USB_RECIP_INTERFACE | USB_DIR_OUT, SET_CUR, 0x0200, 0x0001); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; // set interfaces vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = vsfusbh_set_interface(hdata->usbh, vsfurb, 1, 4); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; // enable video vsfsm_post_evt_pending(&hdata->video_sm, UAV_ISO_ENABLE); } else { vsfurb->transfer_buffer = NULL; vsfurb->transfer_length = 0; err = vsfusbh_set_interface(hdata->usbh, vsfurb, 1, 0); if (err != VSFERR_NONE) return err; vsfsm_pt_wfe(pt, VSFSM_EVT_URB_COMPLETE); if (vsfurb->status != URB_OK) return VSFERR_FAIL; } vsf_bufmgr_free(hdata->ctrl_urb_buf); hdata->ctrl_urb_buf = NULL; memcpy(&hdata->cur_param, &hdata->set_param, sizeof(struct vsfusbh_uvc_param_t)); vsfusbh_uvc_report(hdata, &hdata->cur_param, NULL); vsfsm_pt_end(pt); return VSFERR_NONE; }