Test of C++ Sockets API with Ethernet

Dependencies:   mbed EthernetInterface

Files at this revision

API Documentation at this revision

Comitter:
donatien
Date:
Fri Jun 15 16:38:40 2012 +0000
Child:
1:74160c87c7ce
Commit message:
Initial commit

Changed in this revision

EthernetInterface.lib Show annotated file Show diff for this revision Revisions of this file
RTX_Conf_CM.c Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
rtos.lib Show annotated file Show diff for this revision Revisions of this file
rtx.lib Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EthernetInterface.lib	Fri Jun 15 16:38:40 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/donatien/code/EthernetInterface/#b01299fd0ce3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RTX_Conf_CM.c	Fri Jun 15 16:38:40 2012 +0000
@@ -0,0 +1,266 @@
+/*----------------------------------------------------------------------------
+ *      RL-ARM - RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RTX_Conf_CM.C
+ *      Purpose: Configuration of CMSIS RTX Kernel for Cortex-M
+ *      Rev.:    V4.20
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used 
+ *    to endorse or promote products derived from this software without 
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "cmsis_os.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*----------------------------------------------------------------------------
+ *      RTX User configuration part BEGIN
+ *---------------------------------------------------------------------------*/
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
+//
+// <h>Thread Configuration
+// =======================
+//   <o>Number of concurrent running threads <0-250>
+//   <i> Defines max. number of threads that will run at the same time.
+//       counting "main", but not counting "osTimerThread"
+//   <i> Default: 6
+#ifndef OS_TASKCNT
+#  if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
+#    define OS_TASKCNT         7
+#  elif defined(TARGET_LPC11U24)
+#    define OS_TASKCNT         3
+#  endif
+#endif
+
+//   <o>Number of threads with user-provided stack size <0-250>
+//   The stack of "main" and "osTimerThread" are calculated separately
+//   <i> Defines the number of threads with user-provided stack size.
+//   <i> Default: 0
+#ifndef OS_PRIVCNT
+ #define OS_PRIVCNT         (OS_TASKCNT - 1)
+#endif
+
+//   <o>Default Thread stack size [bytes] <64-4096:8><#/4>
+//   <i> Defines default stack size for threads.
+//   <i> Default: 200
+#ifndef OS_STKSIZE
+ #define OS_STKSIZE         WORDS_STACK_SIZE
+#endif
+
+//   <o>Main Thread stack size [bytes] <64-4096:8><#/4>
+//   <i> Defines stack size for main thread.
+//   <i> Default: 200
+#ifndef OS_MAINSTKSIZE
+//Donatien: default allocated stack size is a bit too low
+ #define OS_MAINSTKSIZE     512
+#endif
+
+//   <o>Total stack size [bytes] for threads with user-provided stack size <0-4096:8><#/4>
+//   <i> Defines the combined stack size for threads with user-provided stack size.
+//   <i> Default: 0
+#ifndef OS_PRIVSTKSIZE
+//Donatien: default allocated stack size is a bit too low
+#  if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
+#    define OS_PRIVSTKSIZE     3000
+#  elif defined(TARGET_LPC11U24)
+#    define OS_PRIVSTKSIZE     512
+#  endif
+#endif
+
+// <q>Check for stack overflow
+// ===========================
+// <i> Includes the stack checking code for stack overflow.
+// <i> Note that additional code reduces the Kernel performance.
+#ifndef OS_STKCHECK
+ #define OS_STKCHECK    1
+#endif
+
+// <q>Run in privileged mode
+// =========================
+// <i> Runs all Threads in privileged mode.
+// <i> Default: Unprivileged
+#ifndef OS_RUNPRIV
+ #define OS_RUNPRIV     1
+#endif
+
+// </h>
+// <h>SysTick Timer Configuration
+// ==============================
+//
+//   <o>Timer clock value [Hz] <1-1000000000>
+//   <i> Defines the timer clock value.
+//   <i> Default: 6000000  (6MHz)
+#ifndef OS_CLOCK
+#  if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
+#    define OS_CLOCK       96000000
+#  elif defined(TARGET_LPC11U24)
+#    define OS_CLOCK       48000000
+#  endif
+#endif
+
+//   <o>Timer tick value [us] <1-1000000>
+//   <i> Defines the timer tick value.
+//   <i> Default: 1000  (1ms)
+#ifndef OS_TICK
+ #define OS_TICK        1000
+#endif
+
+// </h>
+
+// <h>System Configuration
+// =======================
+//
+// <e>Round-Robin Thread switching
+// ===============================
+//
+// <i> Enables Round-Robin Thread switching.
+#ifndef OS_ROBIN
+ #define OS_ROBIN       1
+#endif
+
+//   <o>Round-Robin Timeout [ticks] <1-1000>
+//   <i> Defines how long a thread will execute before a thread switch.
+//   <i> Default: 5
+#ifndef OS_ROBINTOUT
+ #define OS_ROBINTOUT   5
+#endif
+
+// </e>
+
+// <e>User Timers
+// ==============
+//   <i> Enables user Timers
+#ifndef OS_TIMERS
+ #define OS_TIMERS      1
+#endif
+
+//   <o>Timer Thread Priority
+//                        <1=> Low
+//     <2=> Below Normal  <3=> Normal
+//                        <4=> Above Normal
+//                        <5=> High
+//                        <6=> Realtime
+//   <i> Defines priority for Timer Thread
+//   <i> Default: High
+#ifndef OS_TIMERPRIO
+ #define OS_TIMERPRIO   5
+#endif
+
+//   <o>Timer Thread stack size [bytes] <64-4096:8><#/4>
+//   <i> Defines stack size for Timer thread.
+//   <i> Default: 200
+#ifndef OS_TIMERSTKSZ
+ #define OS_TIMERSTKSZ  WORDS_STACK_SIZE
+#endif
+
+//   <o>Timer Callback Queue size <1-32>
+//   <i> Defines number of concurrent callbacks that will be queued.
+//   <i> Default: 4
+#ifndef OS_TIMERCBQSZ
+ #define OS_TIMERCBQS   4
+#endif
+
+// </e>
+
+//   <o>ISR FIFO Queue size<4=>   4 entries  <8=>   8 entries
+//                         <12=> 12 entries  <16=> 16 entries
+//                         <24=> 24 entries  <32=> 32 entries
+//                         <48=> 48 entries  <64=> 64 entries
+//                         <96=> 96 entries
+//   <i> ISR functions store requests to this buffer,
+//   <i> when they are called from the iterrupt handler.
+//   <i> Default: 16 entries
+#ifndef OS_FIFOSZ
+ #define OS_FIFOSZ      16
+#endif
+
+// </h>
+
+//------------- <<< end of configuration section >>> -----------------------
+
+// Standard library system mutexes
+// ===============================
+//  Define max. number system mutexes that are used to protect 
+//  the arm standard runtime library. For microlib they are not used.
+#ifndef OS_MUTEXCNT
+ #define OS_MUTEXCNT    8
+#endif
+
+/*----------------------------------------------------------------------------
+ *      RTX User configuration part END
+ *---------------------------------------------------------------------------*/
+#define OS_TRV          ((uint32_t)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1)
+
+
+/*----------------------------------------------------------------------------
+ *      OS Idle daemon
+ *---------------------------------------------------------------------------*/
+void os_idle_demon (void) {
+  /* The idle demon is a system thread, running when no other thread is      */
+  /* ready to run.                                                           */
+  
+  /* Sleep: ideally, we should put the chip to sleep.
+     Unfortunately, this usually requires disconnecting the interface chip (debugger).
+     This can be done, but it would break the local file system.
+  */
+  for (;;) {
+      // sleep();
+  }
+}
+
+/*----------------------------------------------------------------------------
+ *      RTX Errors
+ *---------------------------------------------------------------------------*/
+extern void mbed_die(void);
+
+void os_error (uint32_t err_code) {
+    /* This function is called when a runtime error is detected. Parameter     */
+    /* 'err_code' holds the runtime error code (defined in RTX_Config.h).      */
+    mbed_die();
+}
+
+void sysThreadError(osStatus status) {
+    if (status != osOK) {
+        mbed_die();
+    }
+}
+
+/*----------------------------------------------------------------------------
+ *      RTX Configuration Functions
+ *---------------------------------------------------------------------------*/

+
+#include "RTX_CM_lib.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Jun 15 16:38:40 2012 +0000
@@ -0,0 +1,223 @@
+/* cpp_sockets_test.cpp */
+/*
+Copyright (C) 2012 ARM Limited.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#define __DEBUG__ 4 //Maximum verbosity
+#ifndef __MODULE__
+#define __MODULE__ "cpp_sockets_test.cpp"
+#endif
+
+#include "core/fwk.h"
+#include "mbed.h"
+
+#include "rtos.h"
+
+#include "EthernetInterface.h"
+#include "TCPSocket.h"
+#include "UDPSocket.h"
+
+#define CHECK_ERR(ret) if(ret < 0) break;
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+void notify(bool a, bool b, bool c)
+{
+  led1 = a;
+  led2 = b;
+  led3 = c;
+}
+
+extern "C" void HardFault_Handler()
+{
+  error("Hard Fault!\n");
+}
+
+void test(void const*)
+{
+  EthernetInterface eth;
+  DBG("Hello!");
+  
+  int count = 0;
+  eth.init(); //Use DHCP
+
+  count++;
+  DBG("iteration #%d", count);
+  
+  char in_buf[256];
+
+  notify(0, 1, 1);
+  int ret = eth.connect();
+  notify(0, 1, 0);
+  if (ret == OK)
+  {
+    //TCP Socket test
+    do
+    {
+      DBG("TCP Client test");
+      TCPSocket sock;
+      //http://mbed.org/media/uploads/donatien/hello.txt
+      ret = sock.connect("mbed.org", 80);
+      CHECK_ERR(ret);
+      const char http_cmd[] = "GET /media/uploads/donatien/hello.txt HTTP/1.1\r\nHost: %s\r\n\r\n";
+      ret = sock.send((std::uint8_t*)http_cmd, sizeof(http_cmd) - 1, 3000);
+      CHECK_ERR(ret);
+      
+      bool firstIt = true;
+      do
+      {
+        ret = sock.receive((std::uint8_t*)in_buf, 255, firstIt?3000:0);
+        CHECK_ERR(ret);
+        in_buf[ret] = '\0';
+        DBG("Received %d chars from server: %s", ret, in_buf);
+        firstIt = false;
+      } while( ret > 0 );
+      CHECK_ERR(ret);
+      ret = sock.close();  
+      CHECK_ERR(ret);
+    } while(0);
+    if(ret < 0)
+    {
+      WARN("TCP Client test failed");
+    }
+    else
+    {
+      DBG("TCP Client test succeeded");
+    }
+    
+    do
+    {
+      DBG("TCP Server test");
+      TCPSocket sock;
+      ret = sock.bind(80); //Listen on all interfaces
+      CHECK_ERR(ret);
+      
+      TCPSocket hdlrSock;
+      ret = sock.listen(1);
+      CHECK_ERR(ret);
+      DBG("Now listening on port 80, open a browser and try to fetch the page");
+      
+      char* inHost;
+      int inPort;
+      ret = sock.accept(hdlrSock, &inHost, &inPort, 150000);
+      CHECK_ERR(ret);
+      DBG("Connection from %s on port %d", inHost, inPort);
+      bool firstIt = true;
+      do
+      {
+        ret = hdlrSock.receive((std::uint8_t*)in_buf, 255, firstIt?3000:0);
+        CHECK_ERR(ret);
+        in_buf[ret] = '\0';
+        DBG("Received %d chars from client: %s", ret, in_buf);
+        firstIt = false;
+      } while( ret > 0 );
+      CHECK_ERR(ret);
+      
+      const char http_resp[] = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 12\r\n\r\nHello world!";
+      ret = hdlrSock.send((std::uint8_t*)http_resp, sizeof(http_resp) - 1, 3000);
+      CHECK_ERR(ret); 
+      
+      ret = hdlrSock.close();
+      CHECK_ERR(ret);
+      
+      ret = sock.close();  
+      CHECK_ERR(ret);
+    } while(0);
+    if(ret < 0)
+    {
+      WARN("TCP Server test failed");
+    }
+    else
+    {
+      DBG("TCP Server test succeeded");
+    }
+    
+    //UDP Socket test
+    do
+    {
+      DBG("UDP Client test");
+      UDPSocket sock;
+      sock.bind(0); //Use a random port
+      const char daytime_cmd[] = "plop"; //Does not matter
+      ret = sock.sendTo((std::uint8_t*)daytime_cmd, sizeof(daytime_cmd) - 1, "utcnist.colorado.edu", 37, 3000);
+      CHECK_ERR(ret);
+
+      char* inHost;
+      int inPort;
+      ret = sock.receiveFrom((std::uint8_t*)in_buf, 4, &inHost, &inPort, 3000);
+      CHECK_ERR(ret);
+      
+      std::uint32_t timeRes = ntohl( *((std::uint32_t*)in_buf));
+      
+      DBG("Received %d bytes from server %s on port %d: %u seconds since 1/01/1900 00:00 GMT", ret, inHost, inPort, timeRes);
+        
+      ret = sock.close();  
+      CHECK_ERR(ret);
+    } while(0);
+    if(ret < 0)
+    {
+      WARN("UDP Client test failed");
+    }
+    else
+    {
+      DBG("UDP Client test succeeded");
+    }
+    
+  }
+  eth.disconnect();
+  DBG("Disconnected");
+
+  notify(1, 1, 1);
+
+  while (1)
+  {
+    Thread::wait(100);
+  }
+}
+
+void keepAlive(void const*)
+{
+  while (1)
+  {
+    led1 = !led1;
+    Thread::wait(500);
+  }
+}
+
+void tick()
+{
+  led4 = !led4;
+}
+
+int main()
+{
+  Ticker t;
+  t.attach(tick, 1);
+  DBG_INIT();
+  notify(1, 0, 0);
+
+  Thread testTask(test, NULL, osPriorityNormal, 1024 * 4);
+  keepAlive(NULL);
+
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Fri Jun 15 16:38:40 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/976df7c37ad5
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rtos.lib	Fri Jun 15 16:38:40 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/emilmont/code/rtos/#d042ad0c4507
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rtx.lib	Fri Jun 15 16:38:40 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/emilmont/code/rtx/#985806751475