SNIC UART Interface library for Murata Type-YD module

Dependents:   WebSocketServerTest

Fork of SNICInterface_mod by Toyomasa Watarai

SNIC/SNIC_Core.cpp

Committer:
kishino
Date:
2014-03-25
Revision:
12:0254eaccfda2
Child:
14:54378c96d285

File content as of revision 12:0254eaccfda2:

#include "mbed.h"
#include "SNIC_Core.h"
#include "SNIC_UartMsgUtil.h"
#include <string>

using namespace murata_wifi;

#define UART_RECVBUF_SIZE   2048
typedef struct
{
    unsigned char buf[UART_RECVBUF_SIZE];
    unsigned int  size;
    bool          is_receive;
}tagUART_RECVBUF_T;
tagUART_RECVBUF_T   gUART_RCVBUF;
unsigned char   gUART_TEMP_BUF[UART_RECVBUF_SIZE];

C_SNIC_Core *C_SNIC_Core::mInstance_p = NULL;

C_SNIC_Core *C_SNIC_Core::getInstance()
{
    if( mInstance_p == NULL )
    {
        mInstance_p = new C_SNIC_Core();
    }
    return mInstance_p;
}

C_SNIC_Core::C_SNIC_Core()
{
    int i;
    
    for( i = 0; i < MAX_SOCKET_ID+1; i++ )
    {
        mConnectInfo[i].recvbuf_p    = NULL;
        mConnectInfo[i].is_connected = false;
    }
    
    mUartRecvThread_p = NULL;
}

int C_SNIC_Core::initUart(PinName tx, PinName rx, int baud)
{
//    printf("[C_SNIC_Core::initUart]1\r\n");
    
    mUartRequestSeq   = 0;

    mUart_p = new RawSerial( tx, rx );
    mUart_p->baud( baud );
    mUart_p->format(8, SerialBase::None, 1);

//    printf("[C_SNIC_Core::initUart]2\r\n");
    // Initialize uart
    gUART_RCVBUF.is_receive = false;
    gUART_RCVBUF.size       = 0;

    // Create UART recv thread
    mUartRecvThread_p = new Thread( C_SNIC_Core::uartRecvThread );
//    printf("[C_SNIC_Core::initUart]3\r\n");
    if( mUartRecvThread_p == NULL )
    {
        printf("[C_SNIC_Core::initUart] thread cread failed\r\n");
        return -1;
    }

    return 0;
}

unsigned int C_SNIC_Core::preparationSendCommand( unsigned char cmd_id, unsigned char cmd_sid
                                            , unsigned char *req_buf_p,    unsigned int req_buf_len
                                            , unsigned char *response_buf_p, unsigned char *command_p )
{
    unsigned char  payload_array[UART_REQUEST_PAYLOAD_MAX];
    unsigned short payload_len;
    unsigned int   command_len = 0;
    
    // Make command payload
    payload_len = C_SNIC_UartMsgUtil::makePayload( req_buf_len, req_buf_p, payload_array );
    // Make all command request
    command_len = C_SNIC_UartMsgUtil::makeRequest( cmd_id, payload_array, payload_len, command_p );

    // Set data for response
    mUartCommand.setCommandID( cmd_id );
    mUartCommand.setCommandSID( cmd_sid | 0x80 );
    mUartCommand.setResponseBuf( response_buf_p );
    
    return command_len;
}

int C_SNIC_Core::sendUart( unsigned int len, unsigned char *data )
{
    int ret = 0;
    
    mUartMutex.lock();
    for( int i = 0; i < len; i++ )
    {
        // Write to UART
        ret = mUart_p->putc( data[i] );
        if( ret == -1 )
        {
            ret = -1;
            break;
        }
    }
    mUartMutex.unlock();
    return ret;
}

tagMEMPOOL_BLOCK_T *C_SNIC_Core::getAlocCmdBuf()
{
    // Get buffer from MemoryPool
    return mMemPoolPayload.alloc();
}

void C_SNIC_Core::freeCmdBuf( tagMEMPOOL_BLOCK_T *buf_p )
{
    mMemPoolPayload.free( buf_p );
}

tagCONNECT_INFO_T  *C_SNIC_Core::getConnectInfo( int socket_id )
{
    if( (socket_id < 0) || (socket_id > MAX_SOCKET_ID) )
    {
        return NULL;
    }
    return &mConnectInfo[socket_id];
}

DigitalOut led1(LED1);
void C_SNIC_Core::uartRecvThread (void const *args_p) {

    C_SNIC_Core *instance_p = C_SNIC_Core::getInstance();
    if ( instance_p == NULL )
    {
        printf("Socket constructor error: no wifly instance available!\r\n");
    }

    int recvdata = 0;
    int i;
    
    /* UART recv thread main loop */
    for (;;) 
    {
        while( instance_p->mUart_p->readable() )
        {
            // Receive data from UART.
            instance_p->mUartMutex.lock();
            recvdata = instance_p->mUart_p->getc();
            instance_p->mUartMutex.unlock();

            // Check UART receiving flg
            if( gUART_RCVBUF.is_receive )
            {
                gUART_RCVBUF.buf[ gUART_RCVBUF.size ] = (unsigned char)recvdata;
                gUART_RCVBUF.size++;
                // Check  received data is EOM.
                if( recvdata == UART_CMD_EOM )
                {
                    led1 = 0;
#if 0
                    printf("[recv]\r\n");
                    for( i = 0; i < gUART_RCVBUF.size; i++ )
                    {
                        printf("%02x ", gUART_RCVBUF.buf[i]);
                    }
                    printf("\r\n");
#endif
                    unsigned char command_id;
                    // Get payload from received data from UART.
                    int payload_len = C_SNIC_UartMsgUtil::getResponsePayload( gUART_RCVBUF.size, gUART_RCVBUF.buf
                                                            , &command_id, gUART_TEMP_BUF );

                    // Check receive a TCP or UDP packet
                    if( (command_id == UART_CMD_ID_SNIC) && (gUART_TEMP_BUF[0] == UART_CMD_SID_SNIC_CONNECTION_RECV_IND) )
                    {
                        // Packet buffering
                        instance_p->mUartCommand.bufferredPacket( gUART_TEMP_BUF, payload_len );
                    }

                    // Check scan results indication 
                    else if( (command_id == UART_CMD_ID_WIFI) && (gUART_TEMP_BUF[0] == UART_CMD_SID_WIFI_SCAN_RESULT_IND) )
                    {
                        // Scan result indicate
                        instance_p->mUartCommand.scanResultIndicate( gUART_TEMP_BUF, payload_len );
                    }
                    // Checks in the command which is waiting.
                    else if( instance_p->mUartCommand.isWaitingCommand(command_id, gUART_TEMP_BUF) )
                    {
                        // Get buffer for payload data
                        unsigned char *payload_buf_p = instance_p->mUartCommand.getResponseBuf();
                        if( payload_buf_p != NULL )
                        {
                            memcpy( payload_buf_p, gUART_TEMP_BUF, payload_len );
                            instance_p->mUartCommand.setResponseBuf( NULL );
                        }
                        // Set status
                        instance_p->mUartCommand.setCommandStatus( gUART_TEMP_BUF[2] );
                        // Set signal for command response wait.
                        instance_p->mUartCommand.signal();
                    }
                    
                    gUART_RCVBUF.size = 0;
                    gUART_RCVBUF.is_receive = false;
                }
            }
            else
            {
                // Check  received data is SOM.
                if( recvdata == UART_CMD_SOM )
                {
                    led1 = 1;
                    gUART_RCVBUF.size = 0;
                    gUART_RCVBUF.buf[ gUART_RCVBUF.size ] = (unsigned char)recvdata;
                    gUART_RCVBUF.size++;
                    gUART_RCVBUF.is_receive = true;
                }
            }
//            Thread::yield();
        }
        Thread::yield();
    }
}