12439e4bfSJean-Christophe PLAGNIOL-VILLARD /* 22439e4bfSJean-Christophe PLAGNIOL-VILLARD * (C) Copyright 2004 32439e4bfSJean-Christophe PLAGNIOL-VILLARD * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 42439e4bfSJean-Christophe PLAGNIOL-VILLARD * 52439e4bfSJean-Christophe PLAGNIOL-VILLARD * See file CREDITS for list of people who contributed to this 62439e4bfSJean-Christophe PLAGNIOL-VILLARD * project. 72439e4bfSJean-Christophe PLAGNIOL-VILLARD * 82439e4bfSJean-Christophe PLAGNIOL-VILLARD * This program is free software; you can redistribute it and/or 92439e4bfSJean-Christophe PLAGNIOL-VILLARD * modify it under the terms of the GNU General Public License as 102439e4bfSJean-Christophe PLAGNIOL-VILLARD * published by the Free Software Foundation; either version 2 of 112439e4bfSJean-Christophe PLAGNIOL-VILLARD * the License, or (at your option) any later version. 122439e4bfSJean-Christophe PLAGNIOL-VILLARD * 132439e4bfSJean-Christophe PLAGNIOL-VILLARD * This program is distributed in the hope that it will be useful, 142439e4bfSJean-Christophe PLAGNIOL-VILLARD * but WITHOUT ANY WARRANTY; without even the implied warranty of 152439e4bfSJean-Christophe PLAGNIOL-VILLARD * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 162439e4bfSJean-Christophe PLAGNIOL-VILLARD * GNU General Public License for more details. 172439e4bfSJean-Christophe PLAGNIOL-VILLARD * 182439e4bfSJean-Christophe PLAGNIOL-VILLARD * You should have received a copy of the GNU General Public License 192439e4bfSJean-Christophe PLAGNIOL-VILLARD * along with this program; if not, write to the Free Software 202439e4bfSJean-Christophe PLAGNIOL-VILLARD * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 212439e4bfSJean-Christophe PLAGNIOL-VILLARD * MA 02111-1307 USA 222439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 232439e4bfSJean-Christophe PLAGNIOL-VILLARD 242439e4bfSJean-Christophe PLAGNIOL-VILLARD #include <common.h> 252439e4bfSJean-Christophe PLAGNIOL-VILLARD #include <command.h> 2652cb4d4fSJean-Christophe PLAGNIOL-VILLARD #include <stdio_dev.h> 272439e4bfSJean-Christophe PLAGNIOL-VILLARD #include <net.h> 282439e4bfSJean-Christophe PLAGNIOL-VILLARD 292439e4bfSJean-Christophe PLAGNIOL-VILLARD DECLARE_GLOBAL_DATA_PTR; 302439e4bfSJean-Christophe PLAGNIOL-VILLARD 312c8fe512SJoe Hershberger #ifndef CONFIG_NETCONSOLE_BUFFER_SIZE 322c8fe512SJoe Hershberger #define CONFIG_NETCONSOLE_BUFFER_SIZE 512 332c8fe512SJoe Hershberger #endif 342c8fe512SJoe Hershberger 352c8fe512SJoe Hershberger static char input_buffer[CONFIG_NETCONSOLE_BUFFER_SIZE]; 36e1902ac6SJoe Hershberger static int input_size; /* char count in input buffer */ 37e1902ac6SJoe Hershberger static int input_offset; /* offset to valid chars in input buffer */ 38e1902ac6SJoe Hershberger static int input_recursion; 39e1902ac6SJoe Hershberger static int output_recursion; 402439e4bfSJean-Christophe PLAGNIOL-VILLARD static int net_timeout; 412439e4bfSJean-Christophe PLAGNIOL-VILLARD static uchar nc_ether[6]; /* server enet address */ 422439e4bfSJean-Christophe PLAGNIOL-VILLARD static IPaddr_t nc_ip; /* server ip */ 437f51898cSJoe Hershberger static short nc_out_port; /* target output port */ 447f51898cSJoe Hershberger static short nc_in_port; /* source input port */ 452439e4bfSJean-Christophe PLAGNIOL-VILLARD static const char *output_packet; /* used by first send udp */ 46e1902ac6SJoe Hershberger static int output_packet_len; 47f8be7d65SJoe Hershberger /* 48f8be7d65SJoe Hershberger * Start with a default last protocol. 49f8be7d65SJoe Hershberger * We are only interested in NETCONS or not. 50f8be7d65SJoe Hershberger */ 51f8be7d65SJoe Hershberger enum proto_t net_loop_last_protocol = BOOTP; 522439e4bfSJean-Christophe PLAGNIOL-VILLARD 5303eb129fSLuca Ceresoli static void nc_wait_arp_handler(uchar *pkt, unsigned dest, 5403eb129fSLuca Ceresoli IPaddr_t sip, unsigned src, 552439e4bfSJean-Christophe PLAGNIOL-VILLARD unsigned len) 562439e4bfSJean-Christophe PLAGNIOL-VILLARD { 5722f6e99dSJoe Hershberger net_set_state(NETLOOP_SUCCESS); /* got arp reply - quit net loop */ 582439e4bfSJean-Christophe PLAGNIOL-VILLARD } 592439e4bfSJean-Christophe PLAGNIOL-VILLARD 6003eb129fSLuca Ceresoli static void nc_handler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, 612439e4bfSJean-Christophe PLAGNIOL-VILLARD unsigned len) 622439e4bfSJean-Christophe PLAGNIOL-VILLARD { 632439e4bfSJean-Christophe PLAGNIOL-VILLARD if (input_size) 6422f6e99dSJoe Hershberger net_set_state(NETLOOP_SUCCESS); /* got input - quit net loop */ 652439e4bfSJean-Christophe PLAGNIOL-VILLARD } 662439e4bfSJean-Christophe PLAGNIOL-VILLARD 672439e4bfSJean-Christophe PLAGNIOL-VILLARD static void nc_timeout(void) 682439e4bfSJean-Christophe PLAGNIOL-VILLARD { 6922f6e99dSJoe Hershberger net_set_state(NETLOOP_SUCCESS); 702439e4bfSJean-Christophe PLAGNIOL-VILLARD } 712439e4bfSJean-Christophe PLAGNIOL-VILLARD 72e827fec2SJoe Hershberger static int is_broadcast(IPaddr_t ip) 73e827fec2SJoe Hershberger { 74e827fec2SJoe Hershberger static IPaddr_t netmask; 75e827fec2SJoe Hershberger static IPaddr_t our_ip; 76e827fec2SJoe Hershberger static int env_changed_id; 77e827fec2SJoe Hershberger int env_id = get_env_id(); 78e827fec2SJoe Hershberger 79e827fec2SJoe Hershberger /* update only when the environment has changed */ 80e827fec2SJoe Hershberger if (env_changed_id != env_id) { 81e827fec2SJoe Hershberger netmask = getenv_IPaddr("netmask"); 82e827fec2SJoe Hershberger our_ip = getenv_IPaddr("ipaddr"); 83e827fec2SJoe Hershberger 84e827fec2SJoe Hershberger env_changed_id = env_id; 85e827fec2SJoe Hershberger } 86e827fec2SJoe Hershberger 87e827fec2SJoe Hershberger return (ip == ~0 || /* 255.255.255.255 */ 88e827fec2SJoe Hershberger ((netmask & our_ip) == (netmask & ip) && /* on the same net */ 89e827fec2SJoe Hershberger (netmask | ip) == ~0)); /* broadcast to our net */ 90e827fec2SJoe Hershberger } 91e827fec2SJoe Hershberger 92e827fec2SJoe Hershberger static int refresh_settings_from_env(void) 93e827fec2SJoe Hershberger { 94e827fec2SJoe Hershberger const char *p; 95e827fec2SJoe Hershberger static int env_changed_id; 96e827fec2SJoe Hershberger int env_id = get_env_id(); 97e827fec2SJoe Hershberger 98e827fec2SJoe Hershberger /* update only when the environment has changed */ 99e827fec2SJoe Hershberger if (env_changed_id != env_id) { 100e827fec2SJoe Hershberger if (getenv("ncip")) { 101e827fec2SJoe Hershberger nc_ip = getenv_IPaddr("ncip"); 102e827fec2SJoe Hershberger if (!nc_ip) 103e827fec2SJoe Hershberger return -1; /* ncip is 0.0.0.0 */ 104e827fec2SJoe Hershberger p = strchr(getenv("ncip"), ':'); 105e827fec2SJoe Hershberger if (p != NULL) { 106e827fec2SJoe Hershberger nc_out_port = simple_strtoul(p + 1, NULL, 10); 107e827fec2SJoe Hershberger nc_in_port = nc_out_port; 108e827fec2SJoe Hershberger } 109e827fec2SJoe Hershberger } else 110e827fec2SJoe Hershberger nc_ip = ~0; /* ncip is not set, so broadcast */ 111e827fec2SJoe Hershberger 112e827fec2SJoe Hershberger p = getenv("ncoutport"); 113e827fec2SJoe Hershberger if (p != NULL) 114e827fec2SJoe Hershberger nc_out_port = simple_strtoul(p, NULL, 10); 115e827fec2SJoe Hershberger p = getenv("ncinport"); 116e827fec2SJoe Hershberger if (p != NULL) 117e827fec2SJoe Hershberger nc_in_port = simple_strtoul(p, NULL, 10); 118e827fec2SJoe Hershberger 119e827fec2SJoe Hershberger if (is_broadcast(nc_ip)) 120e827fec2SJoe Hershberger /* broadcast MAC address */ 121e827fec2SJoe Hershberger memset(nc_ether, 0xff, sizeof(nc_ether)); 122e827fec2SJoe Hershberger else 123e827fec2SJoe Hershberger /* force arp request */ 124e827fec2SJoe Hershberger memset(nc_ether, 0, sizeof(nc_ether)); 125e827fec2SJoe Hershberger } 126e827fec2SJoe Hershberger return 0; 127e827fec2SJoe Hershberger } 128e827fec2SJoe Hershberger 129e827fec2SJoe Hershberger /** 130e827fec2SJoe Hershberger * Called from NetLoop in net/net.c before each packet 131e827fec2SJoe Hershberger */ 1322439e4bfSJean-Christophe PLAGNIOL-VILLARD void NcStart(void) 1332439e4bfSJean-Christophe PLAGNIOL-VILLARD { 134e827fec2SJoe Hershberger refresh_settings_from_env(); 1352439e4bfSJean-Christophe PLAGNIOL-VILLARD if (!output_packet_len || memcmp(nc_ether, NetEtherNullAddr, 6)) { 1362439e4bfSJean-Christophe PLAGNIOL-VILLARD /* going to check for input packet */ 137ece223b5SJoe Hershberger net_set_udp_handler(nc_handler); 1382439e4bfSJean-Christophe PLAGNIOL-VILLARD NetSetTimeout(net_timeout, nc_timeout); 1392439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 1402439e4bfSJean-Christophe PLAGNIOL-VILLARD /* send arp request */ 1412439e4bfSJean-Christophe PLAGNIOL-VILLARD uchar *pkt; 142ece223b5SJoe Hershberger net_set_arp_handler(nc_wait_arp_handler); 143594c26f8SJoe Hershberger pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE; 1442439e4bfSJean-Christophe PLAGNIOL-VILLARD memcpy(pkt, output_packet, output_packet_len); 1457f51898cSJoe Hershberger NetSendUDPPacket(nc_ether, nc_ip, nc_out_port, nc_in_port, 146e1902ac6SJoe Hershberger output_packet_len); 1472439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1482439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1492439e4bfSJean-Christophe PLAGNIOL-VILLARD 150*8a0eccb1SJoe Hershberger int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port, 151*8a0eccb1SJoe Hershberger unsigned src_port, unsigned len) 1522439e4bfSJean-Christophe PLAGNIOL-VILLARD { 1532439e4bfSJean-Christophe PLAGNIOL-VILLARD int end, chunk; 1542439e4bfSJean-Christophe PLAGNIOL-VILLARD 155*8a0eccb1SJoe Hershberger if (dest_port != nc_in_port || !len) 1562439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; /* not for us */ 1572439e4bfSJean-Christophe PLAGNIOL-VILLARD 158*8a0eccb1SJoe Hershberger if (src_ip != nc_ip && !is_broadcast(nc_ip)) 159*8a0eccb1SJoe Hershberger return 0; /* not from our client */ 160*8a0eccb1SJoe Hershberger 1614ef8d53cSJoe Hershberger debug_cond(DEBUG_DEV_PKT, "input: \"%*.*s\"\n", len, len, pkt); 1624ef8d53cSJoe Hershberger 163e1902ac6SJoe Hershberger if (input_size == sizeof(input_buffer)) 1642439e4bfSJean-Christophe PLAGNIOL-VILLARD return 1; /* no space */ 165e1902ac6SJoe Hershberger if (len > sizeof(input_buffer) - input_size) 166e1902ac6SJoe Hershberger len = sizeof(input_buffer) - input_size; 1672439e4bfSJean-Christophe PLAGNIOL-VILLARD 1682439e4bfSJean-Christophe PLAGNIOL-VILLARD end = input_offset + input_size; 169e1902ac6SJoe Hershberger if (end > sizeof(input_buffer)) 170e1902ac6SJoe Hershberger end -= sizeof(input_buffer); 1712439e4bfSJean-Christophe PLAGNIOL-VILLARD 1722439e4bfSJean-Christophe PLAGNIOL-VILLARD chunk = len; 173e1902ac6SJoe Hershberger if (end + len > sizeof(input_buffer)) { 174e1902ac6SJoe Hershberger chunk = sizeof(input_buffer) - end; 1752439e4bfSJean-Christophe PLAGNIOL-VILLARD memcpy(input_buffer, pkt + chunk, len - chunk); 1762439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1772439e4bfSJean-Christophe PLAGNIOL-VILLARD memcpy(input_buffer + end, pkt, chunk); 1782439e4bfSJean-Christophe PLAGNIOL-VILLARD 1792439e4bfSJean-Christophe PLAGNIOL-VILLARD input_size += len; 1802439e4bfSJean-Christophe PLAGNIOL-VILLARD 1812439e4bfSJean-Christophe PLAGNIOL-VILLARD return 1; 1822439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1832439e4bfSJean-Christophe PLAGNIOL-VILLARD 1842439e4bfSJean-Christophe PLAGNIOL-VILLARD static void nc_send_packet(const char *buf, int len) 1852439e4bfSJean-Christophe PLAGNIOL-VILLARD { 1862439e4bfSJean-Christophe PLAGNIOL-VILLARD struct eth_device *eth; 1872439e4bfSJean-Christophe PLAGNIOL-VILLARD int inited = 0; 1882439e4bfSJean-Christophe PLAGNIOL-VILLARD uchar *pkt; 1892439e4bfSJean-Christophe PLAGNIOL-VILLARD uchar *ether; 1902439e4bfSJean-Christophe PLAGNIOL-VILLARD IPaddr_t ip; 1912439e4bfSJean-Christophe PLAGNIOL-VILLARD 1924ef8d53cSJoe Hershberger debug_cond(DEBUG_DEV_PKT, "output: \"%*.*s\"\n", len, len, buf); 1934ef8d53cSJoe Hershberger 194e1902ac6SJoe Hershberger eth = eth_get_dev(); 195e1902ac6SJoe Hershberger if (eth == NULL) 1962439e4bfSJean-Christophe PLAGNIOL-VILLARD return; 1972439e4bfSJean-Christophe PLAGNIOL-VILLARD 1982439e4bfSJean-Christophe PLAGNIOL-VILLARD if (!memcmp(nc_ether, NetEtherNullAddr, 6)) { 1992439e4bfSJean-Christophe PLAGNIOL-VILLARD if (eth->state == ETH_STATE_ACTIVE) 2002439e4bfSJean-Christophe PLAGNIOL-VILLARD return; /* inside net loop */ 2012439e4bfSJean-Christophe PLAGNIOL-VILLARD output_packet = buf; 2022439e4bfSJean-Christophe PLAGNIOL-VILLARD output_packet_len = len; 2032439e4bfSJean-Christophe PLAGNIOL-VILLARD NetLoop(NETCONS); /* wait for arp reply and send packet */ 2042439e4bfSJean-Christophe PLAGNIOL-VILLARD output_packet_len = 0; 2052439e4bfSJean-Christophe PLAGNIOL-VILLARD return; 2062439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2072439e4bfSJean-Christophe PLAGNIOL-VILLARD 2082439e4bfSJean-Christophe PLAGNIOL-VILLARD if (eth->state != ETH_STATE_ACTIVE) { 209f8be7d65SJoe Hershberger if (eth_is_on_demand_init()) { 2102439e4bfSJean-Christophe PLAGNIOL-VILLARD if (eth_init(gd->bd) < 0) 2112439e4bfSJean-Christophe PLAGNIOL-VILLARD return; 212f8be7d65SJoe Hershberger eth_set_last_protocol(NETCONS); 213f8be7d65SJoe Hershberger } else 214f8be7d65SJoe Hershberger eth_init_state_only(gd->bd); 215f8be7d65SJoe Hershberger 2162439e4bfSJean-Christophe PLAGNIOL-VILLARD inited = 1; 2172439e4bfSJean-Christophe PLAGNIOL-VILLARD } 218594c26f8SJoe Hershberger pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE; 2192439e4bfSJean-Christophe PLAGNIOL-VILLARD memcpy(pkt, buf, len); 2202439e4bfSJean-Christophe PLAGNIOL-VILLARD ether = nc_ether; 2212439e4bfSJean-Christophe PLAGNIOL-VILLARD ip = nc_ip; 2227f51898cSJoe Hershberger NetSendUDPPacket(ether, ip, nc_out_port, nc_in_port, len); 2232439e4bfSJean-Christophe PLAGNIOL-VILLARD 224f8be7d65SJoe Hershberger if (inited) { 225f8be7d65SJoe Hershberger if (eth_is_on_demand_init()) 2262439e4bfSJean-Christophe PLAGNIOL-VILLARD eth_halt(); 227f8be7d65SJoe Hershberger else 228f8be7d65SJoe Hershberger eth_halt_state_only(); 229f8be7d65SJoe Hershberger } 2302439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2312439e4bfSJean-Christophe PLAGNIOL-VILLARD 232fa2744deSMike Frysinger static int nc_start(void) 2332439e4bfSJean-Christophe PLAGNIOL-VILLARD { 234e827fec2SJoe Hershberger int retval; 2352439e4bfSJean-Christophe PLAGNIOL-VILLARD 2367f51898cSJoe Hershberger nc_out_port = 6666; /* default port */ 2377f51898cSJoe Hershberger nc_in_port = nc_out_port; 2382439e4bfSJean-Christophe PLAGNIOL-VILLARD 239e827fec2SJoe Hershberger retval = refresh_settings_from_env(); 240e827fec2SJoe Hershberger if (retval != 0) 241e827fec2SJoe Hershberger return retval; 2422439e4bfSJean-Christophe PLAGNIOL-VILLARD 243d7310c7eSJoe Hershberger /* 244d7310c7eSJoe Hershberger * Initialize the static IP settings and buffer pointers 245d7310c7eSJoe Hershberger * incase we call NetSendUDPPacket before NetLoop 246d7310c7eSJoe Hershberger */ 247d7310c7eSJoe Hershberger net_init(); 248d7310c7eSJoe Hershberger 2492439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 2502439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2512439e4bfSJean-Christophe PLAGNIOL-VILLARD 252fa2744deSMike Frysinger static void nc_putc(char c) 2532439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2542439e4bfSJean-Christophe PLAGNIOL-VILLARD if (output_recursion) 2552439e4bfSJean-Christophe PLAGNIOL-VILLARD return; 2562439e4bfSJean-Christophe PLAGNIOL-VILLARD output_recursion = 1; 2572439e4bfSJean-Christophe PLAGNIOL-VILLARD 2582439e4bfSJean-Christophe PLAGNIOL-VILLARD nc_send_packet(&c, 1); 2592439e4bfSJean-Christophe PLAGNIOL-VILLARD 2602439e4bfSJean-Christophe PLAGNIOL-VILLARD output_recursion = 0; 2612439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2622439e4bfSJean-Christophe PLAGNIOL-VILLARD 263fa2744deSMike Frysinger static void nc_puts(const char *s) 2642439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2652439e4bfSJean-Christophe PLAGNIOL-VILLARD int len; 2662439e4bfSJean-Christophe PLAGNIOL-VILLARD 2672439e4bfSJean-Christophe PLAGNIOL-VILLARD if (output_recursion) 2682439e4bfSJean-Christophe PLAGNIOL-VILLARD return; 2692439e4bfSJean-Christophe PLAGNIOL-VILLARD output_recursion = 1; 2702439e4bfSJean-Christophe PLAGNIOL-VILLARD 2711a9845b4SMichael Walle len = strlen(s); 2721a9845b4SMichael Walle while (len) { 2732c8fe512SJoe Hershberger int send_len = min(len, sizeof(input_buffer)); 2741a9845b4SMichael Walle nc_send_packet(s, send_len); 2751a9845b4SMichael Walle len -= send_len; 2761a9845b4SMichael Walle s += send_len; 2771a9845b4SMichael Walle } 2782439e4bfSJean-Christophe PLAGNIOL-VILLARD 2792439e4bfSJean-Christophe PLAGNIOL-VILLARD output_recursion = 0; 2802439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2812439e4bfSJean-Christophe PLAGNIOL-VILLARD 282fa2744deSMike Frysinger static int nc_getc(void) 2832439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2842439e4bfSJean-Christophe PLAGNIOL-VILLARD uchar c; 2852439e4bfSJean-Christophe PLAGNIOL-VILLARD 2862439e4bfSJean-Christophe PLAGNIOL-VILLARD input_recursion = 1; 2872439e4bfSJean-Christophe PLAGNIOL-VILLARD 2882439e4bfSJean-Christophe PLAGNIOL-VILLARD net_timeout = 0; /* no timeout */ 2892439e4bfSJean-Christophe PLAGNIOL-VILLARD while (!input_size) 2902439e4bfSJean-Christophe PLAGNIOL-VILLARD NetLoop(NETCONS); 2912439e4bfSJean-Christophe PLAGNIOL-VILLARD 2922439e4bfSJean-Christophe PLAGNIOL-VILLARD input_recursion = 0; 2932439e4bfSJean-Christophe PLAGNIOL-VILLARD 2942439e4bfSJean-Christophe PLAGNIOL-VILLARD c = input_buffer[input_offset++]; 2952439e4bfSJean-Christophe PLAGNIOL-VILLARD 296e1902ac6SJoe Hershberger if (input_offset >= sizeof(input_buffer)) 297e1902ac6SJoe Hershberger input_offset -= sizeof(input_buffer); 2982439e4bfSJean-Christophe PLAGNIOL-VILLARD input_size--; 2992439e4bfSJean-Christophe PLAGNIOL-VILLARD 3002439e4bfSJean-Christophe PLAGNIOL-VILLARD return c; 3012439e4bfSJean-Christophe PLAGNIOL-VILLARD } 3022439e4bfSJean-Christophe PLAGNIOL-VILLARD 303fa2744deSMike Frysinger static int nc_tstc(void) 3042439e4bfSJean-Christophe PLAGNIOL-VILLARD { 3052439e4bfSJean-Christophe PLAGNIOL-VILLARD struct eth_device *eth; 3062439e4bfSJean-Christophe PLAGNIOL-VILLARD 3072439e4bfSJean-Christophe PLAGNIOL-VILLARD if (input_recursion) 3082439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 3092439e4bfSJean-Christophe PLAGNIOL-VILLARD 3102439e4bfSJean-Christophe PLAGNIOL-VILLARD if (input_size) 3112439e4bfSJean-Christophe PLAGNIOL-VILLARD return 1; 3122439e4bfSJean-Christophe PLAGNIOL-VILLARD 3132439e4bfSJean-Christophe PLAGNIOL-VILLARD eth = eth_get_dev(); 3142439e4bfSJean-Christophe PLAGNIOL-VILLARD if (eth && eth->state == ETH_STATE_ACTIVE) 3152439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; /* inside net loop */ 3162439e4bfSJean-Christophe PLAGNIOL-VILLARD 3172439e4bfSJean-Christophe PLAGNIOL-VILLARD input_recursion = 1; 3182439e4bfSJean-Christophe PLAGNIOL-VILLARD 3192439e4bfSJean-Christophe PLAGNIOL-VILLARD net_timeout = 1; 3202439e4bfSJean-Christophe PLAGNIOL-VILLARD NetLoop(NETCONS); /* kind of poll */ 3212439e4bfSJean-Christophe PLAGNIOL-VILLARD 3222439e4bfSJean-Christophe PLAGNIOL-VILLARD input_recursion = 0; 3232439e4bfSJean-Christophe PLAGNIOL-VILLARD 3242439e4bfSJean-Christophe PLAGNIOL-VILLARD return input_size != 0; 3252439e4bfSJean-Christophe PLAGNIOL-VILLARD } 3262439e4bfSJean-Christophe PLAGNIOL-VILLARD 3272439e4bfSJean-Christophe PLAGNIOL-VILLARD int drv_nc_init(void) 3282439e4bfSJean-Christophe PLAGNIOL-VILLARD { 32952cb4d4fSJean-Christophe PLAGNIOL-VILLARD struct stdio_dev dev; 3302439e4bfSJean-Christophe PLAGNIOL-VILLARD int rc; 3312439e4bfSJean-Christophe PLAGNIOL-VILLARD 3322439e4bfSJean-Christophe PLAGNIOL-VILLARD memset(&dev, 0, sizeof(dev)); 3332439e4bfSJean-Christophe PLAGNIOL-VILLARD 3342439e4bfSJean-Christophe PLAGNIOL-VILLARD strcpy(dev.name, "nc"); 3352439e4bfSJean-Christophe PLAGNIOL-VILLARD dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; 3362439e4bfSJean-Christophe PLAGNIOL-VILLARD dev.start = nc_start; 3372439e4bfSJean-Christophe PLAGNIOL-VILLARD dev.putc = nc_putc; 3382439e4bfSJean-Christophe PLAGNIOL-VILLARD dev.puts = nc_puts; 3392439e4bfSJean-Christophe PLAGNIOL-VILLARD dev.getc = nc_getc; 3402439e4bfSJean-Christophe PLAGNIOL-VILLARD dev.tstc = nc_tstc; 3412439e4bfSJean-Christophe PLAGNIOL-VILLARD 34252cb4d4fSJean-Christophe PLAGNIOL-VILLARD rc = stdio_register(&dev); 3432439e4bfSJean-Christophe PLAGNIOL-VILLARD 3442439e4bfSJean-Christophe PLAGNIOL-VILLARD return (rc == 0) ? 1 : rc; 3452439e4bfSJean-Christophe PLAGNIOL-VILLARD } 346