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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* ------------------------------------------------------------------------------------------------------------
00002     SolderSplash Labs - Wifi-DipCortex
00003     Test application that shows you how to listen for UDP message on one port while sending messages on another
00004     
00005     - Listens on UDP_LISTEN_PORT, upon data being recvied it can be found in UDP_RecvBuffer
00006     - Transmits UDP_TX_Buffer on UDP_TARGET_PORT to UDP_TARGET_IP
00007     
00008     Note : V1.28 firmware has an issue sending UDP data to 224.0.0.251
00009             http://forum.soldersplash.co.uk/viewtopic.php?f=15&t=97
00010 ----------------------------------------------------------------------------------------------------------- */
00011 
00012 #include "mbed.h"
00013 #include "cc3000.h"
00014 #include "wifi.h"
00015 #include "UDPSocket.h"
00016 #include "USBSerial.h"
00017 
00018 using namespace mbed_cc3000;
00019 
00020 #define SERIAL_BAUD_RATE        115200
00021 #define SOCKOPT_RECV_NONBLOCK   0
00022 
00023 cc3000 wifi(p28, p27, p30, SPI(p21, p14, p37));
00024 Serial uart(p19, p20);
00025 
00026 DigitalIn Button(P0_1);
00027 
00028 // USB CDC serial port
00029 USBSerial pc;
00030 
00031 char LOCALHOST[] = "localhost";
00032 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};
00033 
00034 // Multicast address - this causes issues with firmware version 1.28
00035 const char* UDP_TARGET_IP = "224.0.0.251";
00036 
00037 // This is the broadcast address for the subnet 192.168.0.x
00038 //const char* UDP_TARGET_IP = "192.168.0.255";
00039 
00040 const int UDP_TARGET_PORT = 1900;
00041 UDPSocket UDP_TransmitSocket;
00042 
00043 const int UDP_LISTEN_PORT = 1900;
00044 UDPSocket UDP_RecvSocket;
00045 
00046 #define UDP_RECV_BUF_LEN 1400
00047 uint8_t UDP_RecvBuffer[ UDP_RECV_BUF_LEN ];
00048 
00049 
00050 // ------------------------------------------------------------------------------------------------------------
00051 /*!
00052     @brief WaitForConnection
00053 */
00054 // ------------------------------------------------------------------------------------------------------------
00055 void SmartConfig ( void )
00056 {
00057     pc.printf("\r\nStarting Smart config, waiting for message from smartphone app ....\r\n");
00058     
00059     // We dont want to auto reconnect to an access point
00060     wifi._wlan.ioctl_set_connection_policy(0, 0, 0);
00061     
00062     // start smart config will disconnect, set the prefix
00063     // wait for a message via a SmartConfig app, store it to the profile list
00064     // finally it will reenable auto connection, triggering the module to connect to the new access point
00065     wifi.start_smart_config(0);
00066     
00067     pc.printf("\r\nSmartConfig complete\r\n");
00068     
00069     while (! Button )
00070     {
00071         // Wait for release
00072         pc.printf("Release the button\r\n");
00073         wait(1);
00074     }
00075     
00076     // NOTE : normal once connected using SmartConfig you would enable the mdns server to tell the app your connected
00077     // but that would interfere with this example using the mdns port
00078 }
00079 
00080 // ------------------------------------------------------------------------------------------------------------
00081 /*!
00082     @brief WaitForConnection
00083 */
00084 // ------------------------------------------------------------------------------------------------------------
00085 void WaitForConnection ( void )
00086 {
00087 uint8_t buffer[8];
00088 tNetappIpconfigRetArgs ipinfo;
00089     
00090     while (! ( wifi.is_connected() ) )
00091     {
00092         // Still not connected
00093         pc.printf("No Connection - hold button for smartconfig\r\n");
00094         wait(1);
00095         
00096         if (! Button )
00097         {
00098             // Button has been pressed
00099             SmartConfig();
00100         }
00101     }
00102     
00103     if (( wifi.is_enabled() ) && ( wifi.is_dhcp_configured() ))
00104     {
00105         wifi.get_ip_config(&ipinfo);
00106     }
00107     
00108     pc.printf("Connected to (%s) %s \r\n", ipinfo.uaSSID, wifi.getIPAddress());
00109     
00110     wifi.get_mac_address(buffer);
00111     pc.printf(" MAC address : %02x:%02x:%02x:%02x:%02x:%02x\r\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
00112     
00113     if (! wifi._nvmem.read_sp_version( (unsigned char*)&buffer[0] ) )
00114     {
00115         pc.printf(" CC3000 Firmware Version : %u.%u \r\n", buffer[0], buffer[1]);
00116     }
00117 
00118 }
00119 
00120 // ------------------------------------------------------------------------------------------------------------
00121 /*!
00122     @brief WaitForUser
00123 */
00124 // ------------------------------------------------------------------------------------------------------------
00125 void WaitForUser ( void )
00126 {
00127 char charIn;
00128 
00129     pc.printf("Press Enter to Continue\r\n");
00130     
00131     while (1)
00132     {
00133         charIn = pc.getc();
00134         
00135         pc.printf("%c", charIn);
00136         if ((charIn == '\n') || (charIn == '\r'))
00137         {
00138             break;
00139         }
00140     }
00141 }
00142 
00143 // ------------------------------------------------------------------------------------------------------------
00144 /*!
00145     @brief UdpTx_Init
00146 */
00147 // ------------------------------------------------------------------------------------------------------------
00148 void UdpTx_Init ( void )
00149 {
00150     // Creating the socket once and then re-using it is quicker than creating it everytime
00151     // but it does tie up a 1 of the 4 sockets
00152     UDP_TransmitSocket.init();   
00153 }
00154 
00155 // ------------------------------------------------------------------------------------------------------------
00156 /*!
00157     @brief UdpTx
00158 */
00159 // ------------------------------------------------------------------------------------------------------------
00160 void UdpTx ( void )
00161 {
00162 Endpoint target;
00163 int returnVal;
00164  
00165  
00166     target.set_address(UDP_TARGET_IP, UDP_TARGET_PORT);
00167     
00168     pc.printf("Sending UDP Message to port (%i)..\r\n", UDP_TARGET_PORT);
00169     
00170     returnVal = UDP_TransmitSocket.sendTo(target, (char *)UDP_TX_Buffer, sizeof(UDP_TX_Buffer));
00171         
00172     if ( returnVal < 0 )
00173     {
00174         pc.printf("UdpTx : failed to send UDP message ReturnVal : %i\r\n", returnVal);
00175     }
00176     else
00177     {
00178          pc.printf("UDP Message Sent (%i)..\r\n", returnVal);
00179     }
00180 }
00181     
00182 // ------------------------------------------------------------------------------------------------------------
00183 /*!
00184     @brief UdpRxTx_Init - Set up a non blocking UDP port for incoming messages
00185 */
00186 // ------------------------------------------------------------------------------------------------------------
00187 void UdpRx_Init ( void )
00188 {
00189 long optvalue_block = 0;
00190 
00191     // Note : This seems wrong but .. we are using a socket option that stops the cc3000 blocking
00192     // 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
00193     UDP_RecvSocket.set_blocking(true, 0);
00194 
00195     if ( 0 == UDP_RecvSocket.bind(UDP_LISTEN_PORT) )
00196     {
00197         // Socket bound to the port
00198         // Configure the module to not block when checking for UDP data
00199         UDP_RecvSocket.set_option(SOL_SOCKET, SOCKOPT_RECV_NONBLOCK, &optvalue_block, 1);
00200         pc.printf("UDP Socket open and listening\r\n");
00201     }
00202     else
00203     {
00204         pc.printf("Failed to bind to UDP port\r\n");
00205     }
00206 }
00207 
00208 // ------------------------------------------------------------------------------------------------------------
00209 /*!
00210     @brief UdpRx
00211 */
00212 // ------------------------------------------------------------------------------------------------------------
00213 void UdpRx ( void )
00214 {
00215 Endpoint client;
00216 int returnVal = 0;
00217 
00218     do
00219     {
00220         returnVal = UDP_RecvSocket.receiveFrom(client, (char *)UDP_RecvBuffer, UDP_RECV_BUF_LEN);
00221         
00222         if ( returnVal > 0 )
00223         {
00224             pc.printf("UDP Message Recv'd %i bytes from : %s \r\n", returnVal, client.get_address());
00225         
00226             // TODO : Process your UDP message here  
00227             // NOTE : a message larger than your CC3000 SPI buffer and the UDP_RECV_BUF_LEN will be split up into multiple receiveFrom calls
00228             // NOTE : multiple messages on a UDP port seem to get merged.       
00229         }
00230         
00231     } while ( returnVal > 0 );
00232 }
00233 
00234 // ------------------------------------------------------------------------------------------------------------
00235 /*!
00236     @brief Init
00237 */
00238 // ------------------------------------------------------------------------------------------------------------
00239 void init() 
00240 {
00241     NVIC_SetPriority(SSP1_IRQn, 0x0); 
00242     NVIC_SetPriority(PIN_INT0_IRQn, 0x1);
00243     
00244     // SysTick set to lower priority than Wi-Fi SPI bus interrupt
00245     NVIC_SetPriority(SysTick_IRQn, 0x2); 
00246     
00247     // Enable RAM1
00248     LPC_SYSCON->SYSAHBCLKCTRL |= (0x1 << 26);
00249     
00250     uart.baud(SERIAL_BAUD_RATE);
00251     
00252     Button.mode(PullUp);
00253     
00254     wait(1);
00255 }
00256 
00257 // ------------------------------------------------------------------------------------------------------------
00258 /*!
00259     @brief SetupSockets - Sets up the UDP sockets and resolves localhost to work around internal CC3000 issues
00260 */
00261 // ------------------------------------------------------------------------------------------------------------
00262 void SetupSockets ( void )
00263 {
00264 uint32_t ip;
00265 
00266     // Connected, v1.28 firmware workaround, ask for localhost to be resolved
00267     wifi._socket.gethostbyname((uint8_t *)LOCALHOST,strlen((const char *)LOCALHOST), &ip);
00268     
00269     // Ignore the result, ask again
00270     wifi._socket.gethostbyname((uint8_t *)LOCALHOST,strlen((const char *)LOCALHOST), &ip);
00271     
00272     // Ignore the result
00273     
00274     // set up a lisening socket
00275     UdpRx_Init();
00276     UdpTx_Init();
00277 
00278 }
00279 
00280 // ------------------------------------------------------------------------------------------------------------
00281 /*!
00282     @brief main loop
00283 */
00284 // ------------------------------------------------------------------------------------------------------------
00285 int main( void ) 
00286 {  
00287 int tickCnt = 0;
00288 
00289     // Initalise the WiFi Module
00290     init(); 
00291     
00292     WaitForUser();
00293     
00294     pc.printf("Starting CC3000 module\r\n");
00295     
00296     wifi.start(0);
00297     
00298     WaitForConnection();
00299     
00300     SetupSockets();
00301     
00302     while (1)
00303     {        
00304     
00305         if ( wifi.is_connected() )
00306         {
00307             // Check for UDP coms, non blocking
00308             UdpRx();
00309                     
00310             if ( tickCnt > 100 )
00311             {
00312                 tickCnt = 0;
00313                 // And then send a UDP message
00314                 UdpTx();
00315             }
00316             
00317             tickCnt ++;
00318         }
00319         else
00320         {
00321             // We have lost connection, tell the objects to close the sockets
00322             // this clears down the socket handles
00323             UDP_RecvSocket.close();
00324             UDP_TransmitSocket.close();
00325             
00326             wifi.restart(0);
00327             
00328             wifi._wlan.ioctl_set_connection_policy(0, 1, 1);
00329             
00330             // Block and wait for re-connection
00331             WaitForConnection();
00332     
00333             // set up a lisening and transmit socket
00334             SetupSockets();
00335         }
00336         
00337         // TODO : Do other things, like service sensors etc..
00338         // For now lets simulate a task that lasts for 100ms
00339         wait(0.1);
00340         pc.printf(".");
00341         
00342         // If the user presses the button, send a message
00343         if (! Button )
00344         {
00345             UdpTx();
00346         }
00347     }
00348    
00349 }