static int uart_send_stream(uart_socket_t *u, char* pbuf, int len) { int ret; if(!len || (!pbuf) || !u){ uart_printf("input error,size should not be null\r\n"); return -1; } #if UART_SOCKET_USE_DMA_TX while(RtlDownSema(&u->dma_tx_sema) == pdTRUE){ ret = serial_send_stream_dma(&u->sobj, pbuf, len); if(ret != HAL_OK){ RtlUpSema(&u->dma_tx_sema); return -1; }else{ return 0; } } #else while (len){ serial_putc(&u->sobj, *pbuf); len--; pbuf++; } #endif return 0; }
int uart_close(uart_socket_t *u) { if(!u){ uart_printf("uart_close(): u is NULL!\r\n"); return -1; } /* Close uart socket */ if(lwip_close(u->fd) == -1){ uart_printf("%s(): close uart failed!", __func__); } /* Delete uart_action task */ u->fd = -1; RtlUpSema(&u->action_sema); RtlMsleepOS(20); /* Free uart related semaphore */ RtlFreeSema(&u->action_sema); RtlFreeSema(&u->tx_sema); RtlFreeSema(&u->dma_tx_sema); /* Free serial */ serial_free(&u->sobj); RtlMfree((u8 *)u, sizeof(uart_socket_t)); return 0; }
static void uart_action_handler(void* param) { uart_socket_t *u = (uart_socket_t*)param; if(!u) goto Exit; while(RtlDownSema(&u->action_sema) == pdTRUE) { if(u->fd == -1) goto Exit; if(u->rx_start){ /* Blocked here to wait uart rx data completed */ uart_wait_rx_complete(u); /* As we did not register netconn callback function.,so call lwip_selectevindicate unblocking select */ lwip_setsockrcvevent(u->fd, 1); lwip_selectevindicate(u->fd); //unblocking select() u->rx_start = 0; } if(u->tx_start){ uart_print_data("TX:", u->send_buf, u->tx_bytes); //if(serial_send_stream_dma(&u->sobj, (char*)u->send_buf, u->tx_bytes) == -1){ if(uart_send_stream(u, (char*)u->send_buf, u->tx_bytes) == -1){ uart_printf("uart send data error!"); } else { #if (UART_SOCKET_USE_DMA_TX == 0) u->tx_start = 0; memset(u->send_buf,0, UART_SEND_BUFFER_LEN); //zero set uart_send_buf RtlUpSema(&u->tx_sema); #endif } } } Exit: vTaskDelete(NULL); }
/****************************************************************************** * Function: RtlMailboxSendToFront * Desc: To put a message block to the head of a mailbox. * Para: * MboxID: The identifier of the target mailbox. * pMsg: The pointer of the message block to be put into the mailbox. * MSToWait: If the mailbox is full, this value gives a time to wait to put * this message. The time unit is millisecond. * The special values are: * 0: no waiting; * 0xffffffff: wait without timeout. * If the waiting is timeout, the message sending is failed and * return _FAIL. * IsFromISR: Is this function is called from an ISR ? * Return: _SUCCESS or _FAIL. ******************************************************************************/ u8 RtlMailboxSendToFront( IN u8 MboxID, IN MSG_BLK *pMsg, IN u32 MSToWait, IN u8 IsFromISR ) { RTL_MAILBOX *pMbox=NULL; u32 wait_ticks; #ifdef PLATFORM_FREERTOS portBASE_TYPE ret; #endif pMbox = RtlMBoxIdToHdl(MboxID); if (NULL == pMbox) { MSG_MBOX_ERR("RtlMailboxSendToBack: Didn't find matched MBoxID=%d\n", MboxID); return _FAIL; } #ifdef PLATFORM_FREERTOS if (MBOX_WAIT_NO_TIMEOUT == MSToWait) { wait_ticks = portMAX_DELAY; } else if (MBOX_WAIT_NONE == MSToWait) { wait_ticks = 0; } else { wait_ticks = ((MSToWait/portTICK_RATE_MS)>0)?(MSToWait/portTICK_RATE_MS):(1); } if (IsFromISR) { ret = xQueueSendToFrontFromISR(pMbox->mbox_hdl, (void *)pMsg, NULL);//(portTickType) wait_ticks); } else { ret = xQueueSendToFront(pMbox->mbox_hdl, (void *)pMsg, (portTickType) wait_ticks); } if(ret != pdPASS ) { // send message to the queue failed MSG_MBOX_ERR("RtlMailboxSendToBack: Put Msg to Queue Failed, MBoxID=%d\n", MboxID); ret = _FAIL; } else { // try to give a semaphore to wake up the receiving task if (pMbox->pWakeSema) { RtlUpSema(pMbox->pWakeSema); } ret = _SUCCESS; } return ret; #endif #ifdef PLATFORM_ECOS // TODO: eCos has no API to put message to the head of a mailbox #endif }
int uart_write_my(void *pbuf, size_t size) { uart_socket_t *u = uart_socket_send; if(!size || !pbuf || !u){ uart_printf("input error,please check!"); return -1; } if(RtlDownSema(&u->tx_sema)){ //uart_printf("[%d]:uart_write %d!\n", xTaskGetTickCount(), size); uart_print_data("uart_write:", (uint8 *)pbuf, size); memcpy(u->send_buf, pbuf, size); u->tx_bytes = size; u->tx_start = 1; //set uart tx start RtlUpSema(&u->action_sema); // let uart_handle_run through } else { uart_printf("uart write buf error!"); return -1; } return size; }
int uart_write(uart_socket_t *u, void *pbuf, size_t size) { int i = 0; if(!size || !pbuf || !u){ uart_printf("input error,please check!"); return -1; } if(RtlDownSema(&u->tx_sema)){ //uart_printf("[%d]:uart_write %d!\n", xTaskGetTickCount(), size); while(i<3) { if (u->tx_start == 0) break; uart_printf("\nwait uart write buf error111!\n"); wait_ms(10); i++; } if (u->tx_start == 0) { //uart_print_data("uart_write:", (uint8 *)pbuf, size); //memcpy(u->send_buf, pbuf, size); mymemcpy(u->send_buf, pbuf, size); u->tx_bytes = size; u->tx_start = 1; //set uart tx start RtlUpSema(&u->action_sema); // let uart_handle_run through } else { uart_printf("\nuart write buf error111!\n"); } } else { uart_printf("uart write buf error!"); return -1; } return size; }
void uvc_entry_handle(void *param) { int i, ret, cnt; struct stream_context *stream_ctx = (struct stream_context *)param; struct uvc_buf_context buf; struct rtp_object *payload; /*initialize rtp payload*/ for(i = 0; i < VIDEO_MAX_FRAME; i++) { if(rtp_init_payload(stream_ctx, &rtp_payload[i]) < 0) { for(; i>=0; i--) { rtp_uninit_payload(stream_ctx, &rtp_payload[i]); } goto exit; } } if(uvc_set_param(stream_ctx, UVC_FORMAT_MJPEG, 640, 480, 30)<0) goto exit; if(uvc_stream_on(stream_ctx)<0) goto exit; /*do buffer queue & dequeue inside the loop*/ payload_queue.flush_err = 0; while(!(payload_queue.flush_err)) { memset(&buf, 0, sizeof(struct uvc_buf_context)); ret = uvc_dqbuf(stream_ctx, &buf); if(buf.index < 0) continue;//empty buffer retrieved if((uvc_buf_check(&buf)<0)||(ret < 0)){ RTSP_ERROR("\n\rbuffer error!"); ret = -ENOENT; goto exit; } rtp_payload[buf.index].index = buf.index; if(rtp_fill_payload(stream_ctx, &rtp_payload[buf.index], buf.data, buf.len) < 0) goto exit; /*add rtp_payload into payload queue*/ RtlDownMutex(&payload_queue.wait_mutex); list_add_tail(&rtp_payload[buf.index].rtp_list, &payload_queue.wait_queue); RtlUpMutex(&payload_queue.wait_mutex); RtlUpSema(&payload_queue.wait_sema); //check if any rtp payload is queued in done_queue while(RtlDownSemaWithTimeout(&payload_queue.done_sema, 5)==0) { if(payload_queue.flush_err) goto exit; } if(!list_empty(&payload_queue.done_queue)) { RtlDownMutex(&payload_queue.done_mutex); payload = list_first_entry(&payload_queue.done_queue, struct rtp_object, rtp_list); if(payload == NULL) { RtlUpMutex(&payload_queue.done_mutex); continue; } list_del_init(&payload->rtp_list); RtlUpMutex(&payload_queue.done_mutex); buf.index = payload->index; buf.data = payload->data; buf.len = payload->len; ret = uvc_qbuf(stream_ctx, &buf); if (ret < 0){ RTSP_ERROR("\n\rread_frame mmap method enqueue buffer failed"); ret = -ENOENT; goto exit; } } }
void uvc_rtsp_handle(void *param) { struct stream_context *stream_ctx = (struct stream_context *)param; struct rtsp_context *rtsp_ctx; u8 *request_header; //buffer to hold rtsp request struct sockaddr_in server_addr, client_addr; int client_socket; socklen_t client_addr_len = sizeof(struct sockaddr_in); fd_set read_fds; struct timeval timeout; int ok; rtsp_ctx = malloc(sizeof(struct rtsp_context)); if(rtsp_ctx == NULL) { RTSP_ERROR("\n\rrtsp context is NULL"); goto exit; } request_header = malloc(512); if(request_header == NULL) { RTSP_ERROR("\n\rallocate request header buffer failed"); goto exit; } // Delay to wait for IP by DHCP vTaskDelay(500); /*init rtsp context to unicast udp mode*/ if(rtsp_context_init(rtsp_ctx) < 0) goto exit; server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = *(uint32_t *)(rtsp_ctx->connect_ctx.server_ip)/*htonl(INADDR_ANY)*/; server_addr.sin_port = htons(rtsp_ctx->connect_ctx.port); if(bind(rtsp_ctx->connect_ctx.socket_id, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { RTSP_ERROR("\n\rCannot bind stream socket"); goto exit; } listen(rtsp_ctx->connect_ctx.socket_id, 1); printf("\n\rrtsp context initialized!"); stream_ctx->protoCtx = (void *)rtsp_ctx; rtsp_ctx->stream_ctx = (void *)stream_ctx; /*start rtp task*/ uvc_rtp_init(rtsp_ctx); while(stream_ctx->allowStream) { FD_ZERO(&read_fds); timeout.tv_sec = 1; timeout.tv_usec = 0; FD_SET(rtsp_ctx->connect_ctx.socket_id, &read_fds); if(select(1, &read_fds, NULL, NULL, &timeout)) { client_socket = accept(rtsp_ctx->connect_ctx.socket_id,(struct sockaddr *)&client_addr, &client_addr_len); if(client_socket < 0) { RTSP_ERROR("client_socket error:%d\r\n", client_socket); close(client_socket); continue; } *(rtsp_ctx->connect_ctx.remote_ip + 3) = (unsigned char) (client_addr.sin_addr.s_addr >> 24); *(rtsp_ctx->connect_ctx.remote_ip + 2) = (unsigned char) (client_addr.sin_addr.s_addr >> 16); *(rtsp_ctx->connect_ctx.remote_ip + 1) = (unsigned char) (client_addr.sin_addr.s_addr >> 8); *(rtsp_ctx->connect_ctx.remote_ip) = (unsigned char) (client_addr.sin_addr.s_addr ); while(stream_ctx->allowStream) { read(client_socket, request_header, 512); rtsp_readheader(request_header); if(*request_header == 0) { //Do I need to send error response to client? continue; } rtsp_getparam(rtsp_ctx, request_header); switch(rtsp_ctx->rtsp_cmd) { case(CMD_OPTIONS): RTSP_PRINTF("\n\rReceive options command!"); if(rtsp_ctx->state == RTSP_PLAYING) break; rtsp_cmd_options(rtsp_ctx); ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); if (ok <= 0) { RTSP_ERROR("\n\rsend OPTIONS response failed!"); goto exit; } break; case(CMD_DESCRIBE): RTSP_PRINTF("\n\rReceive describe command!"); if(rtsp_ctx->state == RTSP_PLAYING) break; rtsp_cmd_describe(rtsp_ctx); ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); if (ok <= 0) { RTSP_ERROR("\n\rsend DESCRIBE response failed!"); goto exit; } break; case(CMD_SETUP): RTSP_PRINTF("\n\rReceive setup command!"); if(rtsp_ctx->state == RTSP_PLAYING) break; //fill transport parameter rtsp_cmd_setup(rtsp_ctx); ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); if (ok <= 0) { RTSP_ERROR("\n\rsend SETUP response failed!"); goto exit; } if(rtsp_ctx->state == RTSP_INIT) { rtsp_ctx->state = RTSP_READY; RTSP_PRINTF("\n\rstate changed from RTSP_INIT to RTSP_READY"); }; break; case(CMD_TEARDOWN): RTSP_PRINTF("\n\rReceive teardown command!"); rtsp_ctx->state = RTSP_INIT; rtsp_cmd_teardown(rtsp_ctx); ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); if (ok <= 0) { RTSP_ERROR("\n\rsend TEARDOWN response failed!"); goto exit; } RTSP_PRINTF("\n\rstreaming teardown, state changed back to RTSP_INIT"); /*have to wait until rtp server reinit*/ vTaskDelay(1000); goto out; break; case(CMD_PLAY): RTSP_PRINTF("\n\rReceive play command!"); if(rtsp_ctx->state == RTSP_PLAYING) break; rtsp_cmd_play(rtsp_ctx); ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); if (ok <= 0) { RTSP_ERROR("\n\rsend PLAY response failed!"); goto exit; } if(rtsp_ctx->state == RTSP_READY) { rtsp_ctx->state = RTSP_PLAYING; RTSP_PRINTF("\n\rstate changed from RTSP_READY to RTSP_PLAYING"); rtsp_ctx->is_rtp_start = 1; RtlUpSema(&rtsp_ctx->start_rtp_sema); } break; case(CMD_PAUSE): RTSP_PRINTF("\n\rReceive pause command!"); rtsp_cmd_pause(rtsp_ctx); ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); if (ok <= 0) { RTSP_ERROR("\n\rsend PAUSE response failed!"); goto exit; } if(rtsp_ctx->state == RTSP_PLAYING) { rtsp_ctx->state = RTSP_READY; RTSP_PRINTF("\n\rstate changed from RTSP_PLAYING to RTSP_READY"); } break; default: RTSP_ERROR("\n\rReceive unrecognized command!"); rtsp_cmd_error(rtsp_ctx); ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); if (ok <= 0) { RTSP_ERROR("\n\rsend ERROR response failed!"); goto exit; } rtsp_ctx->state = RTSP_INIT; } if((rtsp_ctx->is_rtp_start == 0) && (rtsp_ctx->state == RTSP_PLAYING)) { rtsp_ctx->state = RTSP_INIT; RtlUpSema(&rtsp_ctx->start_rtp_sema); } } out: rtsp_ctx->state = RTSP_INIT; close(client_socket); } }