Advanced Operating Systems - Final Project A @ Tokyo Tech ////////////// Author: Chu Van Thiem and Sidik Soleman ////////////// A WAVE file player on the MBED Application Board with an interface to a software on PC via a TCP connection. ////////////// Main functions: 1. Browse files of an attached USB flash 2. The list of the files of the attached USB are displayed on the LCD 3. Use an joystick to select a WAVE file and give an instruction to play that file 4. Adjust the volume using a potentiometer 5. Output audio to the analog audio out jack ////////////// Software (https://github.com/thiemcv/VS/tree/master/Terminal): 1. Connect with the MBED application board via Ethernet connection 2. Read the list of files stored on the USB flash 3. Write files to the USB flash
Dependencies: C12832_lcd EthernetInterface USBHost mbed-rtos mbed wave_player
Diff: src/tcp_task.cpp
- Revision:
- 1:3b567aa3b09e
- Child:
- 2:5bc47e544b8d
diff -r 6a2537e4188b -r 3b567aa3b09e src/tcp_task.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/tcp_task.cpp Sun Feb 02 10:49:19 2014 +0000 @@ -0,0 +1,251 @@ +#include "tcp_task.h" + +TCPSocketConnection connect; +Queue<char, QUEUE_MAX_LEN> tcp_queue; +TCPSocketServer sock; +char tcp_buf[256]; +char data_frame[DATA_MAX_LEN]; +char ack[ACK_MAX_LEN]; +char fname[NAME_MAX_LEN]; +const char ack_wdata[4] = {ACK_1, ACK_2, ACK_MBED, ACK_WDATA}; +osEvent evt; +extern volatile int cmd_en; +extern volatile int play_en; + +void tcp_thread(void const *args) +{ + int n; + + sock.bind(TCP_PORT); + sock.listen(); + while (1) + { + sock.accept(connect); + printf("New connection\n"); + // Handle incoming connection + while (connect.is_connected()) + { + n = connect.receive(tcp_buf, 256); + if (n < 0) // Error or disconnected + { + printf("Connection error\n"); + break; + } + if (cmd_en) + { + for (int i = 0; i < n; i++) + { + tcp_queue.put(&tcp_buf[i]); + } + } + } + connect.close(); + play_en = 1; + } +} + +void cmd_thread(void const *args) +{ + char *c; + int cmd_state; + char d; + int i = 0; + int idx = 0; + char last_frame = 0; + + int data_len = 0; + int cnt = 0; + int fname_len = 0; + FILE *fp = NULL; + usb *u = (usb *)args; + + cmd_state = STATE_IDLE; + + while (1) + { + if (cmd_en && connect.is_connected()) + { + while (connect.is_connected()) + { + evt = tcp_queue.get(); + if (evt.status == osEventMessage) + { + c = (char *)evt.value.p; + d = *c; + switch (cmd_state) + { + case STATE_IDLE: + if (d == CMD_1) + { + cmd_state = STATE_1; + } + break; + + case STATE_1: + if (d == CMD_2) + { + cmd_state = STATE_2; + } + else + { + cmd_state = STATE_IDLE; + } + break; + + case STATE_2: + if (d == CMD_PC) + { + cmd_state = STATE_CMD; + } + else + { + cmd_state = STATE_IDLE; + } + break; + + case STATE_CMD: + if (d == CMD_READ) + { + play_en = 0; + // Read filenames + u->listdir("/"); + ack[0] = ACK_1; + ack[1] = ACK_2; + ack[2] = ACK_MBED; + ack[3] = ACK_READ; + ack[4] = (char)(u->filenames.size()); + cnt = 5; + for(vector<string>::iterator it = u->filenames.begin(); it < u->filenames.end(); it++) + { + //printf("%s\n", it->c_str()); + for (i = 0; i < it->length(); i++) + { + ack[cnt] = (*it)[i]; + cnt++; + if (cnt == ACK_MAX_LEN) + { + // Send + connect.send_all(ack, cnt); + // Reset counter + cnt = 0; + } + } + ack[cnt] = SPR_CHAR; + cnt++; + if (cnt == ACK_MAX_LEN) + { + // Send + connect.send_all(ack, cnt); + // Reset counter + cnt = 0; + } + } + connect.send_all(ack, cnt); + cmd_state = STATE_IDLE; + play_en = 1; + } + else if (d == CMD_WFILE) + { + cmd_state = STATE_WFILE; + i = 0; + play_en = 0; + } + else if (d == CMD_WDATA) + { + cmd_state = STATE_WDATA; + idx = 0; + } + else + { + cmd_state = STATE_IDLE; + } + break; + + case STATE_WFILE: + if (i == 0) + { + // Length of the filename + fname_len = d; + i++; + fname[0] = '/'; + fname[1] = 'u'; + fname[2] = 's'; + fname[3] = 'b'; + fname[4] = '/'; + } + else + { + if (i <= fname_len) + { + fname[i + 4] = d; + } + if (i == fname_len) + { + // Create a file named fname + fp = fopen(fname, "wb"); + //fprintf(fp, "Hello World!"); + // Send ACK to PC + ack[0] = ACK_1; + ack[1] = ACK_2; + ack[2] = ACK_MBED; + ack[3] = ACK_WFILE; + // Send + connect.send_all(ack, 4); + cmd_state = STATE_IDLE; + } + else + { + i++; + } + } + break; + + case STATE_WDATA: + if (idx == 0) + { + // Is last frame? + last_frame = d; + data_len = 0; + } + else if (idx == 1) + { + data_len = d * 256; + } + else if (idx == 2) + { + data_len = data_len + d; + cnt = 0; + } + else + { + data_frame[cnt] = d; + cnt++; + if (cnt == data_len) + { + fwrite(data_frame, sizeof(char), data_len, fp); + connect.send_all((char*)ack_wdata, 4); + if (last_frame) + { + fclose(fp); + play_en = 1; + } + cmd_state = STATE_IDLE; + } + } + idx++; + break; + + default: + cmd_state = STATE_IDLE; + break; + } + } + } + } + else + { + cmd_state = STATE_IDLE; + Thread::wait(5); + } + } +}