Mbed port of RMCIOS. www.rmcios.fi https://github.com/fkorhone/

Dependencies:   mbed mbed-rtos EthernetInterface

Files at this revision

API Documentation at this revision

Comitter:
ransu
Date:
Thu Dec 27 19:21:42 2018 +0000
Commit message:
Initial commit to public.

Changed in this revision

EthernetInterface.lib Show annotated file Show diff for this revision Revisions of this file
README.md Show annotated file Show diff for this revision Revisions of this file
RMCIOS-Mbed-module.lib Show annotated file Show diff for this revision Revisions of this file
RMCIOS-Mbed.cpp Show annotated file Show diff for this revision Revisions of this file
RMCIOS-base-module.lib Show annotated file Show diff for this revision Revisions of this file
RMCIOS-interface.lib Show annotated file Show diff for this revision Revisions of this file
RMCIOS-std-module.lib Show annotated file Show diff for this revision Revisions of this file
RMCIOS-system.lib Show annotated file Show diff for this revision Revisions of this file
context.c Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib 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
mbed_ethernet_channels.cpp Show annotated file Show diff for this revision Revisions of this file
string-conversion.c 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	Thu Dec 27 19:21:42 2018 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/EthernetInterface/#183490eb1b4a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.md	Thu Dec 27 19:21:42 2018 +0000
@@ -0,0 +1,3 @@
+# RMCIOS-MBED
+RMCIOS implementation for mbed
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RMCIOS-Mbed-module.lib	Thu Dec 27 19:21:42 2018 +0000
@@ -0,0 +1,1 @@
+https://github.com/fkorhone/RMCIOS-Mbed-module.git/#c79fbb492c8eb0e742f4a4acde1eac2bd99a2ce0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RMCIOS-Mbed.cpp	Thu Dec 27 19:21:42 2018 +0000
@@ -0,0 +1,84 @@
+/* 
+RMCIOS - Reactive Multipurpose Control Input Output System
+Copyright (c) 2018 Frans Korhonen
+
+RMCIOS was originally developed at Institute for Atmospheric 
+and Earth System Research / Physics, Faculty of Science, 
+University of Helsinki, Finland
+
+Assistance, experience and feedback from following persons have been 
+critical for development of RMCIOS: Erkki Siivola, Juha Kangasluoma, 
+Lauri Ahonen, Ella Häkkinen, Pasi Aalto, Joonas Enroth, Runlong Cai, 
+Markku Kulmala and Tuukka Petäjä.
+
+This file is part of RMCIOS. This notice was encoded using utf-8.
+
+RMCIOS is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+RMCIOS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public Licenses
+along with RMCIOS.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Changelog: (date,who,description)
+ */
+#define VERSION_STR "Mbed" 
+ 
+#include "mbed.h"
+#include "RMCIOS-system.h"
+#include "std_channels.h"
+#include "base_channels.h"
+#include "mbed_channels.h"
+
+#include <stdio.h>
+
+LocalFileSystem local("local") ;
+// data_handle_name,MAX_CLASSES,MAX_CHANNELS
+CREATE_STATIC_CHANNEL_SYSTEM_DATA (ch_sys_dat, 80, 180);  
+
+int main (void)
+{
+   printf ("\nRMCIOS - Reactive Multipurpose Control Input Output Systen\r\n["
+           "] \r\n");
+   printf ("Copyright (c) 2018 Frans Korhonen\n");
+   printf ("\nInitializing system:\r\n");
+   ////////////////////////////////////////////////////////////////////////
+   // Init channel system
+   ////////////////////////////////////////////////////////////////////////
+   const struct context_rmcios *context;
+   // init channel api system
+   set_channel_system_data ((struct ch_system_data *) &ch_sys_dat);     
+   context = get_rmios_context();
+
+   // Init channel modules:
+   init_base_channels(context) ;
+   init_std_channels(context) ;
+   init_mbed_channels(context) ;
+   init_mbed_platform_channels(context) ; 
+   
+   write_str(context, context->control, 
+             "read as control file /local/conf.ini\n", 0);
+   
+   ///////////////////////////////////////////////////////////////////////
+   // initial configuration 
+   ///////////////////////////////////////////////////////////////////////
+   printf ("\r\nSystem initialized!\r\n");
+
+   /////////////////////////////////////////////////////////////////////////
+   // reception loop
+   /////////////////////////////////////////////////////////////////////////
+   while (1)
+   {
+        wait(1) ;
+   }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RMCIOS-base-module.lib	Thu Dec 27 19:21:42 2018 +0000
@@ -0,0 +1,1 @@
+https://github.com/fkorhone/RMCIOS-base-module/#e60fe77be2f1b3f54616c08d4d85ed579ee444de
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RMCIOS-interface.lib	Thu Dec 27 19:21:42 2018 +0000
@@ -0,0 +1,1 @@
+https://github.com/fkorhone/RMCIOS-interface/#7a801428d84a5ee680957fc887934f01453e7268
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RMCIOS-std-module.lib	Thu Dec 27 19:21:42 2018 +0000
@@ -0,0 +1,1 @@
+https://github.com/fkorhone/RMCIOS-std-module.git/#eb3fb80ee018fa193d9fc29ad8540cc901d7602c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RMCIOS-system.lib	Thu Dec 27 19:21:42 2018 +0000
@@ -0,0 +1,1 @@
+https://github.com/fkorhone/RMCIOS-system/#95dcd41cdbc5eb4f1f67bd782bec5bd9abe02262
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/context.c	Thu Dec 27 19:21:42 2018 +0000
@@ -0,0 +1,109 @@
+/* 
+RMCIOS - Reactive Multipurpose Control Input Output System
+Copyright (c) 2018 Frans Korhonen
+
+RMCIOS was originally developed at Institute for Atmospheric 
+and Earth System Research / Physics, Faculty of Science, 
+University of Helsinki, Finland
+
+Assistance, experience and feedback from following persons have been 
+critical for development of RMCIOS: Erkki Siivola, Juha Kangasluoma, 
+Lauri Ahonen, Ella Häkkinen, Pasi Aalto, Joonas Enroth, Runlong Cai, 
+Markku Kulmala and Tuukka Petäjä.
+
+This file is part of RMCIOS. This notice was encoded using utf-8.
+
+RMCIOS is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+RMCIOS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public Licenses
+along with RMCIOS.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "RMCIOS-functions.h"
+
+// Channel function for allocating and freeing memory
+void stdout_func (void *data,
+               const struct context_rmcios *context, int id,
+               enum function_rmcios function,
+               enum type_rmcios paramtype,
+               union param_rmcios returnv,
+               int num_params, const union param_rmcios param)
+{
+    
+}
+
+// Channel function for allocating and freeing memory
+void mem_func (void *data,
+               const struct context_rmcios *context, int id,
+               enum function_rmcios function,
+               enum type_rmcios paramtype,
+               union param_rmcios returnv,
+               int num_params, const union param_rmcios param)
+{
+   switch (function)
+   {
+   case help_rmcios:
+      // MEMORY INTERFACE: 
+      return_string (context, paramtype, returnv,
+                     " read mem \r\n "
+                     "   -read ammount of free memory\r\n"
+                     " write mem \r\n "
+                     "   -read memory allocation block size\r\n"
+                     " write mem n_bytes \r\n "
+                     "   -Allocate n bytes of memory\r\n"
+                     "   -Returns address of the allocated memory\r\n"
+                     "   -On n_bytes < 0 allocates complete allocation blocks\r\n"
+                     "   -returns 0 length on failure\r\n"
+                     " write mem (empty) addr(buffer/id)\r\n"
+                     "   -free memory pointed by addr in buffer\r\n"
+                     );
+      break;
+
+   case write_rmcios:
+      if (num_params == 0)
+      {
+      } // Read memory allocation block size
+      if (num_params == 1)      // Allocate n bytes of memory
+      {
+         void *ptr = malloc (param_to_integer (context, paramtype,
+                                               (const union param_rmcios)
+                                               param, 0));
+         //printf("allocated %x\n",ptr) ;
+         return_binary (context, paramtype, returnv, (char *) &ptr,
+                        sizeof (ptr));
+      }
+      if (num_params > 1)
+      {
+      } // Write data to memory by access id
+      if (num_params > 2)
+      {
+      } // +max size in bytes
+      if (num_params > 3)
+      {
+      } // +starting at offset
+      if (num_params == 2)      // Free 
+      {
+         if (param_to_integer
+             (context, paramtype, (const union param_rmcios) param, 0) == 0)
+         {
+            char *ptr = 0;
+            param_to_binary (context, paramtype, param, 1,
+                             sizeof (ptr), (char *) &ptr);
+            //printf("freeing: %x\n",ptr) ;
+            if (ptr != 0)
+               free (ptr);
+         }
+      }
+      break;
+   }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos.lib	Thu Dec 27 19:21:42 2018 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-rtos/#5713cbbdb706
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Thu Dec 27 19:21:42 2018 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/mbed_official/code/mbed/builds/994bdf8177cb
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed_ethernet_channels.cpp	Thu Dec 27 19:21:42 2018 +0000
@@ -0,0 +1,474 @@
+/* 
+RMCIOS - Reactive Multipurpose Control Input Output System
+Copyright (c) 2018 Frans Korhonen
+
+RMCIOS was originally developed at Institute for Atmospheric 
+and Earth System Research / Physics, Faculty of Science, 
+University of Helsinki, Finland
+
+Assistance, experience and feedback from following persons have been 
+critical for development of RMCIOS: Erkki Siivola, Juha Kangasluoma, 
+Lauri Ahonen, Ella Häkkinen, Pasi Aalto, Joonas Enroth, Runlong Cai, 
+Markku Kulmala and Tuukka Petäjä.
+
+This file is part of RMCIOS. This notice was encoded using utf-8.
+
+RMCIOS is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+RMCIOS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public Licenses
+along with RMCIOS.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#if DEVICE_ETHERNET == 1
+
+#include "EthernetInterface.h"
+#include "RMCIOS-functions.h"
+
+extern const struct context_rmcios *module_context ; 
+
+//////////////////////////////////////////////////////////////////////
+// Ethernet interface channel
+//////////////////////////////////////////////////////////////////////
+EthernetInterface enet ;
+EthernetInterface *eth=&enet ;
+char eth_configured=0;
+
+void ethernet_class_func(const struct context_rmcios *context, 
+                         void *data, int id, int function,
+                         enum type_rmcios paramtype,
+                         union param_rmcios returnv, 
+                         int num_params,union param_rmcios param)
+{
+ int iplen ;
+ int masklen ;
+ int gwlen ;
+ switch(function) 
+ {
+    case help_rmcios:
+       return_string(context, paramtype,returnv,
+             "help for ethernet interface channel\r\n"
+             " setup eth # Configure ethernet with DHCP\r\n"
+             " setup eth ip_addr ipmask gateway # Manual configuration\r\n"
+             ) ;
+       break ;
+
+    case setup_rmcios :
+       // Allocate ethernet interface.
+       if(eth==NULL) eth = new EthernetInterface ;
+       if(eth==NULL) break ;
+       if(eth_configured==1) {
+          return_string(context, paramtype,returnv,
+                "Ethernet can only be configured once.") ;
+          break ;
+       }
+
+       if(num_params<3) {
+          return_string(context, paramtype,returnv,
+                "Configuring ethernet with DHCP:") ;
+          eth_configured=1;
+          eth->init() ; // dhcp config
+          eth->connect();
+
+          return_string(context, paramtype,returnv,
+                "Ethernet configuration:\r\n") ;
+          return_string(context, paramtype,returnv,"ip:");
+          return_string(context, paramtype,returnv,eth->getIPAddress());
+          return_string(context, paramtype,returnv,"\r\nipmask:");
+          return_string(context, paramtype,returnv,eth->getNetworkMask());
+          return_string(context, paramtype,returnv,"\r\ngateway:");
+          return_string(context, paramtype,returnv,eth->getGateway());
+          return_string(context, paramtype,returnv,"\r\n");
+          break ;
+       }
+
+       iplen = param_string_length(context, paramtype, param, 0)+1;
+       masklen = param_string_length(context, paramtype, param, 1)+1;
+       gwlen = param_string_length(context, paramtype, param, 2)+1;
+       {
+
+          char ip[iplen] ;
+          char ipmask[masklen] ;
+          char gateway[gwlen] ;
+          param_to_string(context, paramtype, param, 0, iplen, ip);
+          param_to_string(context, paramtype, param, 1, masklen, ipmask);
+          param_to_string(context, paramtype, param, 2, gwlen, gateway);
+
+          printf("setup manual ip: %s %s %s\r\n", ip, ipmask, gateway) ;
+          eth_configured=1;
+          eth->init(ip,ipmask,gateway) ; // manual ip config
+          eth->connect();
+
+          return_string(context, paramtype,returnv,
+                        "Ethernet configuration:\r\n") ;
+          return_string(context, paramtype, returnv, "ip:");
+          return_string(context, paramtype, returnv, eth->getIPAddress());
+          return_string(context, paramtype, returnv, "\r\nipmask:");
+          return_string(context, paramtype, returnv, eth->getNetworkMask());
+          return_string(context, paramtype, returnv, "\r\ngateway:");
+          return_string(context, paramtype, returnv, eth->getGateway());
+          return_string(context, paramtype, returnv, "\r\n");
+       }
+       break ;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// TCP Client channel:
+////////////////////////////////////////////////////////////////////////
+struct tcp_connection_data {
+    char host[50] ;
+    int port ;
+    TCPSocketConnection socket;
+    bool closed ;
+};
+
+void tcp_client_class_func(void* data,
+                           const struct context_rmcios *context,
+                           int id, 
+                           int function,
+                           enum type_rmcios paramtype,
+                           union param_rmcios returnv, 
+                           int num_params,
+                           union param_rmcios param)
+{
+    tcp_connection_data *p_data=(tcp_connection_data *)data ;
+    int plen ;
+    switch(function) {
+        case help_rmcios:
+           return_string(context, paramtype, returnv,
+           "help for tcp client channel\r\n"
+           " create tcp_client newname\r\n"
+           " setup newname ip port #Open connection\r\n"
+           " setup newname #Close connection\r\n"
+           " write newname #Flush all buffers\r\n"
+           " write newname data #Write data to the connection.\r\n"
+           "       Reconnect if needed\r\n"
+           " link newname channel # Link received data to channel\r\n"
+           ) ;
+            break ;
+        case create_rmcios :
+            if(num_params<1) break ;
+            if(eth==NULL) break ;
+            
+            // allocate new data
+            p_data= new struct tcp_connection_data; 
+
+            // default values
+            p_data->host[0]=0;
+            p_data->port=0;
+            p_data->closed=true ;
+
+            create_channel_param(context, paramtype, param, 0, 
+                                 (class_rmcios)tcp_client_class_func, p_data) ; 
+                                 
+            break ;
+        case setup_rmcios :
+            if(p_data==NULL) break ;
+            if(num_params<1) { // Close connection
+                Thread::wait(500);
+                if(p_data==NULL) break ;
+                if(p_data->socket.is_connected()) p_data->socket.close();
+                break ;
+            }
+            if(num_params<2) break ;
+            param_to_string(context, paramtype, param, 0, 
+                            sizeof(p_data->host),p_data->host) ;
+            p_data->port=param_to_int(context, paramtype,param,1) ;
+            p_data->closed=true ;
+            break ;
+
+        case write_rmcios :
+            if(p_data==NULL) break ;
+            if(num_params<1) { // Close connection
+                Thread::wait(500);
+                if(p_data==NULL) break ;
+                if(p_data->socket.is_connected()) p_data->socket.close();
+                break ;
+            }
+
+            /// If socket is not open. Try 3 times to open connection:
+            if(!p_data->socket.is_connected() || p_data->closed==true ) {
+                if(p_data->socket.connect(p_data->host,p_data->port)==0) {
+                   p_data->closed=false ;
+                }
+                else p_data->closed=false ;
+            }
+            if(!p_data->socket.is_connected() || p_data->closed==true ) {
+                Thread::wait(200);
+                if(p_data->socket.connect(p_data->host,p_data->port)==0) {
+                   p_data->closed=false ;
+                }
+                else p_data->closed=false ;
+            }
+            if(!p_data->socket.is_connected() || p_data->closed==true ) {
+                Thread::wait(200);
+                if(p_data->socket.connect(p_data->host,p_data->port)==0) {
+                   p_data->closed=false ;
+                }
+                else p_data->closed=false ;
+            }
+
+            plen=param_buffer_alloc_size(context, paramtype,param,0) ;
+            {
+                char buffer[plen] ;
+                int retry;
+                struct buffer_rmcios p ;
+                p=param_to_buffer(context, paramtype,param, 0, plen, buffer) ;
+                // retry 3 times
+                for(retry=0 ;
+                    retry<3 && p_data->socket.send(p.data, p.length )<0 ;
+                    retry++)
+                { 
+                    Thread::wait(200);
+                }
+                Thread::wait(100);
+            }
+            break ;
+    }
+}
+
+///////////////////////////////////////////////////////
+// TCP server channel
+////////////////////////////////////////////////////////
+struct tcpserver_data {
+    int port ;
+    TCPSocketServer socket ;
+    TCPSocketConnection connection;
+    int linked_channels ;
+    char buffer[512] ;
+    int id ;
+};
+
+//! Thread for handling udp reception.
+void tcpserver_thread(const void *param)
+{
+    printf("tcp server thread created!\r\n") ;
+    int n=0 ;
+    struct tcpserver_data *pthis=(struct tcpserver_data *) param ;
+    
+    while(pthis->port==0) ;
+    {
+        Thread::wait(200);
+    }
+    
+    pthis->socket.bind(pthis->port) ;
+    pthis->socket.listen();
+    
+    while(1) {
+        pthis->socket.accept( pthis->connection )  ;
+        printf("connection accepted!\r\n") ;
+        // receive command
+        while( pthis->connection.is_connected() ) {
+            n=pthis->connection.receive(pthis->buffer,sizeof( pthis->buffer)-1);
+            if(n>0) {
+                if( pthis->linked_channels!=0) {
+                   write_buffer(module_context, pthis->linked_channels,
+                                pthis->buffer,n,pthis->id) ;
+                } 
+           }
+        }
+    }
+}
+
+void tcp_server_class_func(struct tcpserver_data *pthis, 
+                           const struct context_rmcios *context,
+                           int id, 
+                           int function,
+                           enum type_rmcios paramtype,
+                           union param_rmcios returnv, 
+                           int num_params,
+                           union param_rmcios param)
+{
+    int plen;
+    switch(function) {
+        case help_rmcios:
+            return_string(context, paramtype, returnv, 
+                          "TCP server channel\r\n"
+                          "create tcpserver newname\r\n"
+                          "setup newname port\r\n"
+                          "write newname data\r\n"
+                          "link newname channel\r\n"
+                          );
+            break;
+
+        case create_rmcios :
+            if(num_params<1) break ;
+            pthis=  (struct tcpserver_data *) 
+                    malloc(sizeof( struct tcpserver_data)) ; 
+            
+            pthis->port=0 ;
+            pthis->buffer[0]=0;
+            pthis->socket=TCPSocketServer();
+            pthis->connection=TCPSocketConnection();
+            
+            pthis->id=create_channel_param(context, paramtype, param, 0,
+                                           (class_rmcios)tcp_server_class_func,
+                                           pthis); 
+            pthis->linked_channels=linked_channels(context, pthis->id) ;
+            break;
+
+        case setup_rmcios :
+            if(pthis==NULL) break ;
+            if(num_params<1) {
+                if( !pthis->connection.is_connected() ){
+                   pthis->connection.close() ;
+                }
+                break ;
+            }
+            pthis->port=param_to_integer(context, paramtype, param,0);
+            
+            // Start reception thread
+            new Thread(tcpserver_thread, pthis);
+            break;
+
+        case write_rmcios :
+            if(pthis==NULL) break ;
+            if(num_params<1) break ;
+            plen=param_buffer_alloc_size(context, paramtype, param, 0) ; 
+            {
+                char buffer[plen] ; 
+                struct buffer_rmcios pbuffer ; 
+                pbuffer = param_to_buffer(context, paramtype,param, 0, 
+                                          plen , buffer) ;
+                if(pthis->connection.send(pbuffer.data, pbuffer.length)<0){
+                    return_int(context, paramtype, returnv, -1) ;
+                    pthis->connection.close() ;
+                }
+            }
+            break;
+    }
+}
+
+///////////////////////////////////////////////////////
+// UDP server channel
+////////////////////////////////////////////////////////
+struct udp_server_data {
+    int id ;
+    int port ;
+    UDPSocket socket ;
+    Endpoint client ;
+    char txbuffer[100] ;
+    char buffer[100] ;
+    int linked_channel ;
+} ;
+
+//! Thread for handling udp reception.
+void udp_server_thread(const void *param)
+{
+    //printf("udp thread created!\r\n") ;
+    int n=0 ;
+    struct udp_server_data *p_data=(struct udp_server_data *) param ;
+    //printf("waiting for configuration:\r\n") ;
+    while(p_data->port==0) ;
+    {
+        p_data->socket.bind(p_data->port) ;
+        Thread::wait(200);
+    }
+    while(1) {
+        // receive command
+        n=p_data->socket.receiveFrom(p_data->client, p_data->buffer, 
+                                     sizeof(p_data->buffer)-1 ) ;
+        if(n>0) {
+            if(p_data->linked_channel!=0){
+               write_buffer(module_context, p_data->linked_channel, 
+                            p_data->buffer, n, p_data->id) ;
+            }
+        }
+    }
+}
+
+void udp_server_class_func(udp_server_data *p_data,  
+                           const struct context_rmcios *context,
+                           int id, 
+                           int function,
+                           enum type_rmcios paramtype,
+                           union param_rmcios returnv, 
+                           int num_params,union param_rmcios param)
+{
+ switch(function) 
+ {
+    case help_rmcios :
+       return_string(context, paramtype, returnv,
+             "help for udp server channel\r\n"
+             " create udp_server newname\r\n"
+             " setup newname port \r\n"
+             " write newname \r\n"
+             "        # flush tansmit buffer)\r\n"
+             " write newname data \r\n"
+             "        # write data to tansmit buffer.\r\n"
+             "        Flush buffer to ethernet when \\r encountered. \r\n"
+             " link newname channel \r\n"
+             "        # Link received data to channel\r\n"
+             ) ;
+
+       break ;
+    case create_rmcios :
+       if(num_params<1) break ;
+       if(eth==NULL) break ;
+       p_data= new struct udp_server_data ;
+       if(p_data==NULL) break ;
+
+       // Default values:
+       p_data->port=0;
+       p_data->buffer[0]=0;
+       p_data->txbuffer[0]=0 ;
+
+       // Create the channel
+       p_data->id=create_channel_param(context, paramtype, param, 0, 
+                                       (class_rmcios)udp_server_class_func, 
+                                       p_data) ;
+
+       p_data->linked_channel=linked_channels(context,p_data->id);
+       break ;
+    case setup_rmcios :
+
+       if(p_data==NULL) break ;
+       if(num_params<1) break ;
+       else {
+          p_data->port=param_to_int(context, paramtype, param, 0);
+          new Thread(udp_server_thread, p_data);
+       }
+       break ;
+
+    case write_rmcios :
+       if(p_data==NULL) break ;
+       if(num_params<1) { // flush buffer
+          p_data->socket.sendTo(p_data->client, p_data->txbuffer, 
+                                strlen(p_data->txbuffer));
+          p_data->txbuffer[0]=0 ;
+          break ;
+       }
+
+       // collect data to buffer
+       param_to_string(context, paramtype, param, 0, 
+                       sizeof(p_data->txbuffer)-strlen(p_data->txbuffer), 
+                       p_data->txbuffer+strlen(p_data->txbuffer)) ;
+       break ;
+ }
+}
+
+void init_mbed_ethernet_channels(const struct context_rmcios *context)
+{
+    module_context=context ;
+    create_channel_str(context, "eth",(class_rmcios)ethernet_class_func, NULL);
+    create_channel_str(context, "udp_server",
+                       (class_rmcios)udp_server_class_func, NULL ) ;
+
+    // TCP Not usable. (Memory consumption issues.)
+    // create_channel_str("tcp_client",(channel_func) tcp_client_class_func, 
+    //                    NULL ) ;
+    // create_channel_str("tcp_server",(channel_func) tcp_server_class_func, 
+    //                    NULL ) ;
+}
+
+#endif //if DEVICE_ETHERNET == 1
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/string-conversion.c	Thu Dec 27 19:21:42 2018 +0000
@@ -0,0 +1,43 @@
+#include "string-conversion.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/* String to float converter 
+ * @param str String to convert from
+ * returns the converted value. Returns 0 on failure. */
+int string_to_integer (const char *str)
+{
+   return strtol (str, NULL, 0);
+}
+
+/* String to float converter 
+ * @param str String to convert from
+ * returns the converted value. Returns 0 on failure. */
+double string_to_float (const char *str)
+{
+   return strtof (str, NULL);
+}
+
+/* Integer to string converter 
+ * @param buffer buffer to write to
+ * @param len size of buffer
+ * @param value number to convert
+ * @return number of characters the full string representation needs. */
+int integer_to_string (char *buffer, int len, int value)
+{
+   return snprintf (buffer, len, "%d", value);
+}
+
+/* Float to string converter 
+ * @param buffer buffer to write to
+ * @param len size of buffer
+ * @param value Number to convert
+ * @return number of characters the full string representation needs.*/
+int float_to_string (char *buffer, int len, double value)
+{
+   return snprintf (buffer, len, "%g", value);
+}
+
+
+