This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

redboot load method with netcat


Hi
this lets redboot connect to any specified port on the host for downloading.
example:
#nc -l -p 578 < image.elf on the host

load -m nc -h IP -p 578 in redboot;
if no -p is specified 8000 is used for the port.
The advantages of this method is that no server setup or root privileges are required on the host
and images need not be copied to specific directories.OTOH it is not easily automated since
one needs to manually break host nc or call it with -w timeout.


diff -Nur redboot.orig/current/ChangeLog redboot/current/ChangeLog
--- redboot.orig/current/ChangeLog	Tue Sep  3 16:07:13 2002
+++ redboot/current/ChangeLog	Wed Sep  4 15:20:26 2002
@@ -1,3 +1,13 @@
+2002-09-04  Jani Monoses  <jani@iv.ro>
+
+	* src/net/nc_client.c: New file based on http_client.c. 
+	* src/load.c:
+	* cdl/redboot.cdl: Support new raw transfer with netcat
+	on the host side.
+	* src/net/tcp.c: Cancel retransmission timer when SYN is acked
+	otherwise an open active connection which doesn't send data
+	eventually resends the SYN resulting in reset from the peer.
+	
 2002-09-03  Yoshinori Sato <qzb04471@nifty.ne.jp>
 2002-09-03  Mark Salter  <msalter@redhat.com>
 
diff -Nur redboot.orig/current/cdl/redboot.cdl redboot/current/cdl/redboot.cdl
--- redboot.orig/current/cdl/redboot.cdl	Wed Sep  4 13:08:09 2002
+++ redboot/current/cdl/redboot.cdl	Tue Aug 27 15:38:21 2002
@@ -230,6 +230,16 @@
                 This option enables the use of the HTTP protocol for download"
         }
 
+	cdl_option CYGSEM_REDBOOT_NET_NC_DOWNLOAD {
+            display          "Support netcat raw transfer for download"
+            flavor           bool
+            default_value    1
+            compile          -library=libextras.a net/nc_client.c
+            description      "
+                This option enables the use of netcat at the host for download"
+        }
+
+
         cdl_component CYGDAT_REDBOOT_DEFAULT_IP_ADDR {
             display          "Default IP address"
             flavor           booldata
diff -Nur redboot.orig/current/src/load.c redboot/current/src/load.c
--- redboot.orig/current/src/load.c	Wed Sep  4 13:08:20 2002
+++ redboot/current/src/load.c	Tue Sep  3 17:52:48 2002
@@ -574,7 +574,7 @@
     char *mode_str;
 #ifdef CYGPKG_REDBOOT_NETWORKING
     struct sockaddr_in host;
-    bool hostname_set;
+    bool hostname_set,port_set;
     char *hostname;
 #endif
     bool decompress = false;
@@ -590,7 +590,7 @@
     connection_info_t info;
     getc_io_funcs_t *io;
     struct load_io_entry *io_tab;
-
+    unsigned long port;	
 #ifdef CYGPKG_REDBOOT_NETWORKING
     memset((char *)&host, 0, sizeof(host));
     host.sin_len = sizeof(host);
@@ -617,6 +617,9 @@
     init_opts(&opts[num_options], 'h', true, OPTION_ARG_TYPE_STR, 
               (void **)&hostname, (bool *)&hostname_set, "host name or IP address");
     num_options++;
+    init_opts(&opts[num_options], 'p', true, OPTION_ARG_TYPE_NUM, 
+              (void **)&port, (bool *)&port_set, "TCP port");
+    num_options++;
 #endif
 #ifdef CYGPKG_COMPRESS_ZLIB
     init_opts(&opts[num_options], 'd', false, OPTION_ARG_TYPE_FLG, 
@@ -642,6 +645,8 @@
             return;
         }
     }
+    if (port_set) 
+	    host.sin_port = port;
 #endif
     if (chan >= CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS) {
         diag_printf("Invalid I/O channel: %d\n", chan);
diff -Nur redboot.orig/current/src/net/nc_client.c redboot/current/src/net/nc_client.c
--- redboot.orig/current/src/net/nc_client.c	Thu Jan  1 00:00:00 1970
+++ redboot/current/src/net/nc_client.c	Wed Sep  4 15:17:28 2002
@@ -0,0 +1,184 @@
+//==========================================================================
+//
+//      net/nc_client.c
+//
+//      Netcat client support for RedBoot
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2002 Gary Thomas
+//
+// eCos 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 2 or (at your option) any later version.
+//
+// eCos 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 License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at nc://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    jani@iv.ro
+// Contributors: 
+// Date:         2002-08-09
+// Purpose:      
+// Description:  netcat client support
+//              
+// This code is part of RedBoot (tm).
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <redboot.h>     // have_net
+#include <net/net.h>
+
+#define NC_OPEN		1
+#define NC_IO		2
+
+// So we remember which ports have been used
+static int get_port = 7800;
+
+static struct _stream{
+    bool open;
+    int  avail, actual_len, pos, filelen;
+    char data[4096];
+    char *bufp;
+    tcp_socket_t sock;
+} nc_stream;
+
+static __inline__ int
+min(int a, int b)
+{
+    if (a < b) 
+        return a;
+    else
+        return b;
+}
+
+int
+nc_stream_open(connection_info_t *info, int *err)
+{
+    int res;
+    struct _stream *s = &nc_stream;
+    if(!info->server->sin_port)	
+	    info->server->sin_port = 8000;  
+    if ((res = __tcp_open(&s->sock, info->server, get_port++, 5000, err)) < 0) {
+        *err = NC_OPEN;
+        return -1;
+    }
+    s->avail = 0;
+    s->open = true;
+    s->pos = 0;
+    return 0;
+}
+
+void
+nc_stream_close(int *err)
+{    
+    struct _stream *s = &nc_stream;
+
+    if (s->open) {
+        __tcp_close(&s->sock);
+        s->open = false;    
+    }
+}
+
+int
+nc_stream_read(char *buf,
+                 int len,
+                 int *err)
+{    
+    struct _stream *s = &nc_stream;
+    int total = 0;
+    int cnt;
+
+    if (!s->open) {
+        return -1;  // Shouldn't happen, but...
+    }
+    while (len) {
+        while (s->avail == 0) {
+            // Need to wait for some data to arrive
+            __tcp_poll();
+            if (s->sock.state != _ESTABLISHED) {
+                if (s->sock.state == _CLOSE_WAIT) {
+                    // This connection is breaking
+                    if (s->sock.data_bytes == 0 && s->sock.rxcnt == 0) {
+                        __tcp_close(&s->sock);
+                        return total;
+                    }
+                } else
+                if (s->sock.state == _CLOSED) {
+                    // The connection is gone
+                    s->open = false;
+                    return -1;
+                } else {
+	            *err = NC_IO;
+        	    return -1;
+		}	
+            }
+            s->actual_len = __tcp_read(&s->sock, s->data, sizeof(s->data));
+            if (s->actual_len > 0) {
+                s->bufp = s->data;
+                s->avail = s->actual_len;
+    
+            } else if (s->actual_len < 0) {
+                *err = NC_IO;
+                return -1;
+            }
+        }
+        cnt = min(len, s->avail);
+        memcpy(buf, s->bufp, cnt);
+        s->avail -= cnt;
+        s->bufp += cnt;
+        buf += cnt;
+        total += cnt;
+        len -= cnt;
+    }
+    return total;
+}
+
+char *
+nc_error(int err)
+{
+    char *errmsg = "Unknown error";
+
+    switch (err) {
+    case NC_OPEN:
+        return "Can't connect to host";
+    case NC_IO:
+        return "I/O error";
+    }
+    return errmsg;
+}
+
+//
+// RedBoot interface
+//
+GETC_IO_FUNCS(nc_io, nc_stream_open, nc_stream_close,
+              0, nc_stream_read, nc_error);
+RedBoot_load(nc, nc_io, true, false, 0);
diff -Nur redboot.orig/current/src/net/tcp.c redboot/current/src/net/tcp.c
--- redboot.orig/current/src/net/tcp.c	Wed Sep  4 13:09:20 2002
+++ redboot/current/src/net/tcp.c	Mon Aug 19 13:03:51 2002
@@ -474,6 +474,7 @@
                   s->state = _ESTABLISHED;
                   s->ack = ntohl(tcp->seqnum) + 1;
                   s->seq = ntohl(tcp->acknum);
+		  __timer_cancel(&s->timer);
                   send_ack(s);
 		break;
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]