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

src/tcp_task.cpp

Committer:
aos
Date:
2014-02-13
Revision:
5:12a48b7c41bf
Parent:
4:2df863d484a1

File content as of revision 5:12a48b7c41bf:

/* FILE: tcp_task.cpp by Chu Van Thiem
*/
#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);
                                        // Reload filenames
                                        u->listdir("/");
                                        play_en = 1;
                                    }
                                    cmd_state = STATE_IDLE;
                                }
                            }
                            idx++;
                        break;
                        
                        default:
                            cmd_state = STATE_IDLE;
                        break;
                    }
                }
            }
        }
        else
        {
            cmd_state = STATE_IDLE;
            Thread::wait(5);
        }
    }
}