Small demo to purely test UDP, depends on the module already being configured to auto connect to an access point

Dependencies:   USBDevice cc3000_hostdriver_mbedsocket mbed

Fork of WifiDipCortex-UDPDemo by Carl - SolderSplash Labs

Wifi-DipCortex - Test application that shows you how to listen for UDP message on one port while sending messages on another

- Listens on UDP_LISTEN_PORT, upon data being recvied it can be found in UDP_RecvBuffer - Transmits UDP_TX_Buffer on UDP_TARGET_PORT to UDP_TARGET_IP

main.cpp

Committer:
SolderSplashLabs
Date:
2014-08-07
Revision:
3:3fd4a328c7cf
Parent:
2:6813713a64e1

File content as of revision 3:3fd4a328c7cf:

/* ------------------------------------------------------------------------------------------------------------
    SolderSplash Labs - Wifi-DipCortex
    Test application that shows you how to listen for UDP message on one port while sending messages on another
    
    - Listens on UDP_LISTEN_PORT, upon data being recvied it can be found in UDP_RecvBuffer
    - Transmits UDP_TX_Buffer on UDP_TARGET_PORT to UDP_TARGET_IP
    
    Note : V1.28 firmware has an issue sending UDP data to 224.0.0.251
            http://forum.soldersplash.co.uk/viewtopic.php?f=15&t=97
----------------------------------------------------------------------------------------------------------- */

#include "mbed.h"
#include "cc3000.h"
#include "wifi.h"
#include "UDPSocket.h"
#include "USBSerial.h"

using namespace mbed_cc3000;

#define SERIAL_BAUD_RATE        115200
#define SOCKOPT_RECV_NONBLOCK   0

cc3000 wifi(p28, p27, p30, SPI(p21, p14, p37));
Serial uart(p19, p20);

DigitalIn Button(P0_1);

// USB CDC serial port
USBSerial pc;

char LOCALHOST[] = "localhost";
const char UDP_TX_Buffer[] = {0,0,0,0,0,1,0,0,0,0,0,0,6,0x61,0x61,0x61,0x61,0x61,0x61,5,0x6c,0x6f,0x63,0x61,0x6c,0,0,1,0,1};

// Multicast address - this causes issues with firmware version 1.28
const char* UDP_TARGET_IP = "224.0.0.251";

// This is the broadcast address for the subnet 192.168.0.x
//const char* UDP_TARGET_IP = "192.168.0.255";

const int UDP_TARGET_PORT = 1900;
UDPSocket UDP_TransmitSocket;

const int UDP_LISTEN_PORT = 1900;
UDPSocket UDP_RecvSocket;

#define UDP_RECV_BUF_LEN 1400
uint8_t UDP_RecvBuffer[ UDP_RECV_BUF_LEN ];


// ------------------------------------------------------------------------------------------------------------
/*!
    @brief WaitForConnection
*/
// ------------------------------------------------------------------------------------------------------------
void SmartConfig ( void )
{
    pc.printf("\r\nStarting Smart config, waiting for message from smartphone app ....\r\n");
    
    // We dont want to auto reconnect to an access point
    wifi._wlan.ioctl_set_connection_policy(0, 0, 0);
    
    // start smart config will disconnect, set the prefix
    // wait for a message via a SmartConfig app, store it to the profile list
    // finally it will reenable auto connection, triggering the module to connect to the new access point
    wifi.start_smart_config(0);
    
    pc.printf("\r\nSmartConfig complete\r\n");
    
    while (! Button )
    {
        // Wait for release
        pc.printf("Release the button\r\n");
        wait(1);
    }
    
    // NOTE : normal once connected using SmartConfig you would enable the mdns server to tell the app your connected
    // but that would interfere with this example using the mdns port
}

// ------------------------------------------------------------------------------------------------------------
/*!
    @brief WaitForConnection
*/
// ------------------------------------------------------------------------------------------------------------
void WaitForConnection ( void )
{
uint8_t buffer[8];
tNetappIpconfigRetArgs ipinfo;
    
    while (! ( wifi.is_connected() ) )
    {
        // Still not connected
        pc.printf("No Connection - hold button for smartconfig\r\n");
        wait(1);
        
        if (! Button )
        {
            // Button has been pressed
            SmartConfig();
        }
    }
    
    if (( wifi.is_enabled() ) && ( wifi.is_dhcp_configured() ))
    {
        wifi.get_ip_config(&ipinfo);
    }
    
    pc.printf("Connected to (%s) %s \r\n", ipinfo.uaSSID, wifi.getIPAddress());
    
    wifi.get_mac_address(buffer);
    pc.printf(" MAC address : %02x:%02x:%02x:%02x:%02x:%02x\r\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
    
    if (! wifi._nvmem.read_sp_version( (unsigned char*)&buffer[0] ) )
    {
        pc.printf(" CC3000 Firmware Version : %u.%u \r\n", buffer[0], buffer[1]);
    }

}

// ------------------------------------------------------------------------------------------------------------
/*!
    @brief WaitForUser
*/
// ------------------------------------------------------------------------------------------------------------
void WaitForUser ( void )
{
char charIn;

    pc.printf("Press Enter to Continue\r\n");
    
    while (1)
    {
        charIn = pc.getc();
        
        pc.printf("%c", charIn);
        if ((charIn == '\n') || (charIn == '\r'))
        {
            break;
        }
    }
}

// ------------------------------------------------------------------------------------------------------------
/*!
    @brief UdpTx_Init
*/
// ------------------------------------------------------------------------------------------------------------
void UdpTx_Init ( void )
{
    // Creating the socket once and then re-using it is quicker than creating it everytime
    // but it does tie up a 1 of the 4 sockets
    UDP_TransmitSocket.init();   
}

// ------------------------------------------------------------------------------------------------------------
/*!
    @brief UdpTx
*/
// ------------------------------------------------------------------------------------------------------------
void UdpTx ( void )
{
Endpoint target;
int returnVal;
 
 
    target.set_address(UDP_TARGET_IP, UDP_TARGET_PORT);
    
    pc.printf("Sending UDP Message to port (%i)..\r\n", UDP_TARGET_PORT);
    
    returnVal = UDP_TransmitSocket.sendTo(target, (char *)UDP_TX_Buffer, sizeof(UDP_TX_Buffer));
        
    if ( returnVal < 0 )
    {
        pc.printf("UdpTx : failed to send UDP message ReturnVal : %i\r\n", returnVal);
    }
    else
    {
         pc.printf("UDP Message Sent (%i)..\r\n", returnVal);
    }
}
    
// ------------------------------------------------------------------------------------------------------------
/*!
    @brief UdpRxTx_Init - Set up a non blocking UDP port for incoming messages
*/
// ------------------------------------------------------------------------------------------------------------
void UdpRx_Init ( void )
{
long optvalue_block = 0;

    // Note : This seems wrong but .. we are using a socket option that stops the cc3000 blocking
    // this lets us call recvfrom and not wait for a message, if it has any data it returns with it, if theres no data it returns immediately
    UDP_RecvSocket.set_blocking(true, 0);

    if ( 0 == UDP_RecvSocket.bind(UDP_LISTEN_PORT) )
    {
        // Socket bound to the port
        // Configure the module to not block when checking for UDP data
        UDP_RecvSocket.set_option(SOL_SOCKET, SOCKOPT_RECV_NONBLOCK, &optvalue_block, 1);
        pc.printf("UDP Socket open and listening\r\n");
    }
    else
    {
        pc.printf("Failed to bind to UDP port\r\n");
    }
}

// ------------------------------------------------------------------------------------------------------------
/*!
    @brief UdpRx
*/
// ------------------------------------------------------------------------------------------------------------
void UdpRx ( void )
{
Endpoint client;
int returnVal = 0;

    do
    {
        returnVal = UDP_RecvSocket.receiveFrom(client, (char *)UDP_RecvBuffer, UDP_RECV_BUF_LEN);
        
        if ( returnVal > 0 )
        {
            pc.printf("UDP Message Recv'd %i bytes from : %s \r\n", returnVal, client.get_address());
        
            // TODO : Process your UDP message here  
            // NOTE : a message larger than your CC3000 SPI buffer and the UDP_RECV_BUF_LEN will be split up into multiple receiveFrom calls
            // NOTE : multiple messages on a UDP port seem to get merged.       
        }
        
    } while ( returnVal > 0 );
}

// ------------------------------------------------------------------------------------------------------------
/*!
    @brief Init
*/
// ------------------------------------------------------------------------------------------------------------
void init() 
{
    NVIC_SetPriority(SSP1_IRQn, 0x0); 
    NVIC_SetPriority(PIN_INT0_IRQn, 0x1);
    
    // SysTick set to lower priority than Wi-Fi SPI bus interrupt
    NVIC_SetPriority(SysTick_IRQn, 0x2); 
    
    // Enable RAM1
    LPC_SYSCON->SYSAHBCLKCTRL |= (0x1 << 26);
    
    uart.baud(SERIAL_BAUD_RATE);
    
    Button.mode(PullUp);
    
    wait(1);
}

// ------------------------------------------------------------------------------------------------------------
/*!
    @brief SetupSockets - Sets up the UDP sockets and resolves localhost to work around internal CC3000 issues
*/
// ------------------------------------------------------------------------------------------------------------
void SetupSockets ( void )
{
uint32_t ip;

    // Connected, v1.28 firmware workaround, ask for localhost to be resolved
    wifi._socket.gethostbyname((uint8_t *)LOCALHOST,strlen((const char *)LOCALHOST), &ip);
    
    // Ignore the result, ask again
    wifi._socket.gethostbyname((uint8_t *)LOCALHOST,strlen((const char *)LOCALHOST), &ip);
    
    // Ignore the result
    
    // set up a lisening socket
    UdpRx_Init();
    UdpTx_Init();

}

// ------------------------------------------------------------------------------------------------------------
/*!
    @brief main loop
*/
// ------------------------------------------------------------------------------------------------------------
int main( void ) 
{  
int tickCnt = 0;

    // Initalise the WiFi Module
    init(); 
    
    WaitForUser();
    
    pc.printf("Starting CC3000 module\r\n");
    
    wifi.start(0);
    
    WaitForConnection();
    
    SetupSockets();
    
    while (1)
    {        
    
        if ( wifi.is_connected() )
        {
            // Check for UDP coms, non blocking
            UdpRx();
                    
            if ( tickCnt > 100 )
            {
                tickCnt = 0;
                // And then send a UDP message
                UdpTx();
            }
            
            tickCnt ++;
        }
        else
        {
            // We have lost connection, tell the objects to close the sockets
            // this clears down the socket handles
            UDP_RecvSocket.close();
            UDP_TransmitSocket.close();
            
            wifi.restart(0);
            
            wifi._wlan.ioctl_set_connection_policy(0, 1, 1);
            
            // Block and wait for re-connection
            WaitForConnection();
    
            // set up a lisening and transmit socket
            SetupSockets();
        }
        
        // TODO : Do other things, like service sensors etc..
        // For now lets simulate a task that lasts for 100ms
        wait(0.1);
        pc.printf(".");
        
        // If the user presses the button, send a message
        if (! Button )
        {
            UdpTx();
        }
    }
   
}