Fork of Smoothie to port to mbed non-LPC targets.

Dependencies:   mbed

Fork of Smoothie by Stéphane Cachat

Committer:
Michael J. Spencer
Date:
Fri Feb 28 18:52:52 2014 -0800
Revision:
2:1df0b61d3b5a
Update to latest Smoothie.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Michael J. Spencer 2:1df0b61d3b5a 1 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
Michael J. Spencer 2:1df0b61d3b5a 2 #pragma GCC diagnostic ignored "-Wcast-qual"
Michael J. Spencer 2:1df0b61d3b5a 3 #pragma GCC diagnostic ignored "-Wcast-align"
Michael J. Spencer 2:1df0b61d3b5a 4
Michael J. Spencer 2:1df0b61d3b5a 5 #include "CommandQueue.h"
Michael J. Spencer 2:1df0b61d3b5a 6
Michael J. Spencer 2:1df0b61d3b5a 7 #include "Kernel.h"
Michael J. Spencer 2:1df0b61d3b5a 8
Michael J. Spencer 2:1df0b61d3b5a 9 #include "Network.h"
Michael J. Spencer 2:1df0b61d3b5a 10 #include "PublicDataRequest.h"
Michael J. Spencer 2:1df0b61d3b5a 11 #include "PlayerPublicAccess.h"
Michael J. Spencer 2:1df0b61d3b5a 12 #include "net_util.h"
Michael J. Spencer 2:1df0b61d3b5a 13 #include "uip_arp.h"
Michael J. Spencer 2:1df0b61d3b5a 14 #include "clock-arch.h"
Michael J. Spencer 2:1df0b61d3b5a 15
Michael J. Spencer 2:1df0b61d3b5a 16 #include "uip.h"
Michael J. Spencer 2:1df0b61d3b5a 17 #include "telnetd.h"
Michael J. Spencer 2:1df0b61d3b5a 18 #include "webserver.h"
Michael J. Spencer 2:1df0b61d3b5a 19 #include "dhcpc.h"
Michael J. Spencer 2:1df0b61d3b5a 20 #include "sftpd.h"
Michael J. Spencer 2:1df0b61d3b5a 21
Michael J. Spencer 2:1df0b61d3b5a 22
Michael J. Spencer 2:1df0b61d3b5a 23 #include <mri.h>
Michael J. Spencer 2:1df0b61d3b5a 24
Michael J. Spencer 2:1df0b61d3b5a 25 #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
Michael J. Spencer 2:1df0b61d3b5a 26
Michael J. Spencer 2:1df0b61d3b5a 27 extern "C" void uip_log(char *m)
Michael J. Spencer 2:1df0b61d3b5a 28 {
Michael J. Spencer 2:1df0b61d3b5a 29 printf("uIP log message: %s\n", m);
Michael J. Spencer 2:1df0b61d3b5a 30 }
Michael J. Spencer 2:1df0b61d3b5a 31
Michael J. Spencer 2:1df0b61d3b5a 32 static bool webserver_enabled, telnet_enabled, use_dhcp;
Michael J. Spencer 2:1df0b61d3b5a 33 static Network *theNetwork;
Michael J. Spencer 2:1df0b61d3b5a 34 static Sftpd *sftpd;
Michael J. Spencer 2:1df0b61d3b5a 35 static CommandQueue *command_q= CommandQueue::getInstance();
Michael J. Spencer 2:1df0b61d3b5a 36
Michael J. Spencer 2:1df0b61d3b5a 37 Network* Network::instance;
Michael J. Spencer 2:1df0b61d3b5a 38 Network::Network()
Michael J. Spencer 2:1df0b61d3b5a 39 {
Michael J. Spencer 2:1df0b61d3b5a 40 ethernet = new LPC17XX_Ethernet();
Michael J. Spencer 2:1df0b61d3b5a 41 tickcnt= 0;
Michael J. Spencer 2:1df0b61d3b5a 42 theNetwork= this;
Michael J. Spencer 2:1df0b61d3b5a 43 sftpd= NULL;
Michael J. Spencer 2:1df0b61d3b5a 44 instance= this;
Michael J. Spencer 2:1df0b61d3b5a 45 }
Michael J. Spencer 2:1df0b61d3b5a 46
Michael J. Spencer 2:1df0b61d3b5a 47 Network::~Network()
Michael J. Spencer 2:1df0b61d3b5a 48 {
Michael J. Spencer 2:1df0b61d3b5a 49 delete ethernet;
Michael J. Spencer 2:1df0b61d3b5a 50 }
Michael J. Spencer 2:1df0b61d3b5a 51
Michael J. Spencer 2:1df0b61d3b5a 52 static uint32_t getSerialNumberHash()
Michael J. Spencer 2:1df0b61d3b5a 53 {
Michael J. Spencer 2:1df0b61d3b5a 54 #define IAP_LOCATION 0x1FFF1FF1
Michael J. Spencer 2:1df0b61d3b5a 55 uint32_t command[1];
Michael J. Spencer 2:1df0b61d3b5a 56 uint32_t result[5];
Michael J. Spencer 2:1df0b61d3b5a 57 typedef void (*IAP)(uint32_t *, uint32_t *);
Michael J. Spencer 2:1df0b61d3b5a 58 IAP iap = (IAP) IAP_LOCATION;
Michael J. Spencer 2:1df0b61d3b5a 59
Michael J. Spencer 2:1df0b61d3b5a 60 __disable_irq();
Michael J. Spencer 2:1df0b61d3b5a 61
Michael J. Spencer 2:1df0b61d3b5a 62 command[0] = 58;
Michael J. Spencer 2:1df0b61d3b5a 63 iap(command, result);
Michael J. Spencer 2:1df0b61d3b5a 64 __enable_irq();
Michael J. Spencer 2:1df0b61d3b5a 65 return crc32((uint8_t *)&result[1], 4 * 4);
Michael J. Spencer 2:1df0b61d3b5a 66 }
Michael J. Spencer 2:1df0b61d3b5a 67
Michael J. Spencer 2:1df0b61d3b5a 68 static bool parse_ip_str(const string &s, uint8_t *a, int len, char sep = '.')
Michael J. Spencer 2:1df0b61d3b5a 69 {
Michael J. Spencer 2:1df0b61d3b5a 70 int p = 0;
Michael J. Spencer 2:1df0b61d3b5a 71 const char *n;
Michael J. Spencer 2:1df0b61d3b5a 72 for (int i = 0; i < len; i++) {
Michael J. Spencer 2:1df0b61d3b5a 73 if (i < len - 1) {
Michael J. Spencer 2:1df0b61d3b5a 74 size_t o = s.find(sep, p);
Michael J. Spencer 2:1df0b61d3b5a 75 if (o == string::npos) return false;
Michael J. Spencer 2:1df0b61d3b5a 76 n = s.substr(p, o - p).c_str();
Michael J. Spencer 2:1df0b61d3b5a 77 p = o + 1;
Michael J. Spencer 2:1df0b61d3b5a 78 } else {
Michael J. Spencer 2:1df0b61d3b5a 79 n = s.substr(p).c_str();
Michael J. Spencer 2:1df0b61d3b5a 80 }
Michael J. Spencer 2:1df0b61d3b5a 81 a[i] = atoi(n);
Michael J. Spencer 2:1df0b61d3b5a 82 }
Michael J. Spencer 2:1df0b61d3b5a 83 return true;
Michael J. Spencer 2:1df0b61d3b5a 84 }
Michael J. Spencer 2:1df0b61d3b5a 85
Michael J. Spencer 2:1df0b61d3b5a 86 void Network::on_module_loaded()
Michael J. Spencer 2:1df0b61d3b5a 87 {
Michael J. Spencer 2:1df0b61d3b5a 88 if ( !THEKERNEL->config->value( network_checksum, network_enable_checksum )->by_default(false)->as_bool() ) {
Michael J. Spencer 2:1df0b61d3b5a 89 // as not needed free up resource
Michael J. Spencer 2:1df0b61d3b5a 90 delete this;
Michael J. Spencer 2:1df0b61d3b5a 91 return;
Michael J. Spencer 2:1df0b61d3b5a 92 }
Michael J. Spencer 2:1df0b61d3b5a 93
Michael J. Spencer 2:1df0b61d3b5a 94 webserver_enabled = THEKERNEL->config->value( network_checksum, network_webserver_checksum, network_enable_checksum )->by_default(false)->as_bool();
Michael J. Spencer 2:1df0b61d3b5a 95 telnet_enabled = THEKERNEL->config->value( network_checksum, network_telnet_checksum, network_enable_checksum )->by_default(false)->as_bool();
Michael J. Spencer 2:1df0b61d3b5a 96
Michael J. Spencer 2:1df0b61d3b5a 97 string mac = THEKERNEL->config->value( network_checksum, network_mac_override_checksum )->by_default("")->as_string();
Michael J. Spencer 2:1df0b61d3b5a 98 if (mac.size() == 17 ) { // parse mac address
Michael J. Spencer 2:1df0b61d3b5a 99 if (!parse_ip_str(mac, mac_address, 6, ':')) {
Michael J. Spencer 2:1df0b61d3b5a 100 printf("Invalid MAC address: %s\n", mac.c_str());
Michael J. Spencer 2:1df0b61d3b5a 101 printf("Network not started due to errors in config");
Michael J. Spencer 2:1df0b61d3b5a 102 return;
Michael J. Spencer 2:1df0b61d3b5a 103 }
Michael J. Spencer 2:1df0b61d3b5a 104
Michael J. Spencer 2:1df0b61d3b5a 105 } else { // autogenerate
Michael J. Spencer 2:1df0b61d3b5a 106 uint32_t h = getSerialNumberHash();
Michael J. Spencer 2:1df0b61d3b5a 107 mac_address[0] = 0x00; // OUI
Michael J. Spencer 2:1df0b61d3b5a 108 mac_address[1] = 0x1F; // OUI
Michael J. Spencer 2:1df0b61d3b5a 109 mac_address[2] = 0x11; // OUI
Michael J. Spencer 2:1df0b61d3b5a 110 mac_address[3] = 0x02; // Openmoko allocation for smoothie board
Michael J. Spencer 2:1df0b61d3b5a 111 mac_address[4] = 0x04; // 04-14 03 bits -> chip id, 1 bits -> hashed serial
Michael J. Spencer 2:1df0b61d3b5a 112 mac_address[5] = h & 0xFF; // 00-FF 8bits -> hashed serial
Michael J. Spencer 2:1df0b61d3b5a 113 }
Michael J. Spencer 2:1df0b61d3b5a 114
Michael J. Spencer 2:1df0b61d3b5a 115 ethernet->set_mac(mac_address);
Michael J. Spencer 2:1df0b61d3b5a 116
Michael J. Spencer 2:1df0b61d3b5a 117 // get IP address, mask and gateway address here....
Michael J. Spencer 2:1df0b61d3b5a 118 bool bad = false;
Michael J. Spencer 2:1df0b61d3b5a 119 string s = THEKERNEL->config->value( network_checksum, network_ip_address_checksum )->by_default("auto")->as_string();
Michael J. Spencer 2:1df0b61d3b5a 120 if (s == "auto") {
Michael J. Spencer 2:1df0b61d3b5a 121 use_dhcp = true;
Michael J. Spencer 2:1df0b61d3b5a 122
Michael J. Spencer 2:1df0b61d3b5a 123 } else {
Michael J. Spencer 2:1df0b61d3b5a 124 use_dhcp = false;
Michael J. Spencer 2:1df0b61d3b5a 125 if (!parse_ip_str(s, ipaddr, 4)) {
Michael J. Spencer 2:1df0b61d3b5a 126 printf("Invalid IP address: %s\n", s.c_str());
Michael J. Spencer 2:1df0b61d3b5a 127 bad = true;
Michael J. Spencer 2:1df0b61d3b5a 128 }
Michael J. Spencer 2:1df0b61d3b5a 129 s = THEKERNEL->config->value( network_checksum, network_ip_mask_checksum )->by_default("255.255.255.0")->as_string();
Michael J. Spencer 2:1df0b61d3b5a 130 if (!parse_ip_str(s, ipmask, 4)) {
Michael J. Spencer 2:1df0b61d3b5a 131 printf("Invalid IP Mask: %s\n", s.c_str());
Michael J. Spencer 2:1df0b61d3b5a 132 bad = true;
Michael J. Spencer 2:1df0b61d3b5a 133 }
Michael J. Spencer 2:1df0b61d3b5a 134 s = THEKERNEL->config->value( network_checksum, network_ip_gateway_checksum )->by_default("192.168.3.1")->as_string();
Michael J. Spencer 2:1df0b61d3b5a 135 if (!parse_ip_str(s, ipgw, 4)) {
Michael J. Spencer 2:1df0b61d3b5a 136 printf("Invalid IP gateway: %s\n", s.c_str());
Michael J. Spencer 2:1df0b61d3b5a 137 bad = true;
Michael J. Spencer 2:1df0b61d3b5a 138 }
Michael J. Spencer 2:1df0b61d3b5a 139
Michael J. Spencer 2:1df0b61d3b5a 140 if (bad) {
Michael J. Spencer 2:1df0b61d3b5a 141 printf("Network not started due to errors in config");
Michael J. Spencer 2:1df0b61d3b5a 142 return;
Michael J. Spencer 2:1df0b61d3b5a 143 }
Michael J. Spencer 2:1df0b61d3b5a 144 }
Michael J. Spencer 2:1df0b61d3b5a 145
Michael J. Spencer 2:1df0b61d3b5a 146 THEKERNEL->add_module( ethernet );
Michael J. Spencer 2:1df0b61d3b5a 147 THEKERNEL->slow_ticker->attach( 100, this, &Network::tick );
Michael J. Spencer 2:1df0b61d3b5a 148
Michael J. Spencer 2:1df0b61d3b5a 149 // Register for events
Michael J. Spencer 2:1df0b61d3b5a 150 this->register_for_event(ON_IDLE);
Michael J. Spencer 2:1df0b61d3b5a 151 this->register_for_event(ON_MAIN_LOOP);
Michael J. Spencer 2:1df0b61d3b5a 152 this->register_for_event(ON_GET_PUBLIC_DATA);
Michael J. Spencer 2:1df0b61d3b5a 153
Michael J. Spencer 2:1df0b61d3b5a 154 this->init();
Michael J. Spencer 2:1df0b61d3b5a 155 }
Michael J. Spencer 2:1df0b61d3b5a 156
Michael J. Spencer 2:1df0b61d3b5a 157 void Network::on_get_public_data(void* argument) {
Michael J. Spencer 2:1df0b61d3b5a 158 PublicDataRequest* pdr = static_cast<PublicDataRequest*>(argument);
Michael J. Spencer 2:1df0b61d3b5a 159
Michael J. Spencer 2:1df0b61d3b5a 160 if(!pdr->starts_with(network_checksum)) return;
Michael J. Spencer 2:1df0b61d3b5a 161
Michael J. Spencer 2:1df0b61d3b5a 162 if(pdr->second_element_is(get_ip_checksum)) {
Michael J. Spencer 2:1df0b61d3b5a 163 pdr->set_data_ptr(this->ipaddr);
Michael J. Spencer 2:1df0b61d3b5a 164 pdr->set_taken();
Michael J. Spencer 2:1df0b61d3b5a 165
Michael J. Spencer 2:1df0b61d3b5a 166 }else if(pdr->second_element_is(get_ipconfig_checksum)) {
Michael J. Spencer 2:1df0b61d3b5a 167 // NOTE caller must free the returned string when done
Michael J. Spencer 2:1df0b61d3b5a 168 char buf[200];
Michael J. Spencer 2:1df0b61d3b5a 169 int n1= snprintf(buf, sizeof(buf), "IP Addr: %d.%d.%d.%d\n", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
Michael J. Spencer 2:1df0b61d3b5a 170 int n2= snprintf(&buf[n1], sizeof(buf)-n1, "IP GW: %d.%d.%d.%d\n", ipgw[0], ipgw[1], ipgw[2], ipgw[3]);
Michael J. Spencer 2:1df0b61d3b5a 171 int n3= snprintf(&buf[n1+n2], sizeof(buf)-n1-n2, "IP mask: %d.%d.%d.%d\n", ipmask[0], ipmask[1], ipmask[2], ipmask[3]);
Michael J. Spencer 2:1df0b61d3b5a 172 int n4= snprintf(&buf[n1+n2+n3], sizeof(buf)-n1-n2-n3, "MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n",
Michael J. Spencer 2:1df0b61d3b5a 173 mac_address[0], mac_address[1], mac_address[2], mac_address[3], mac_address[4], mac_address[5]);
Michael J. Spencer 2:1df0b61d3b5a 174 char *str = (char *)malloc(n1+n2+n3+n4+1);
Michael J. Spencer 2:1df0b61d3b5a 175 memcpy(str, buf, n1+n2+n3+n4);
Michael J. Spencer 2:1df0b61d3b5a 176 str[n1+n2+n3+n4]= '\0';
Michael J. Spencer 2:1df0b61d3b5a 177 pdr->set_data_ptr(str);
Michael J. Spencer 2:1df0b61d3b5a 178 pdr->set_taken();
Michael J. Spencer 2:1df0b61d3b5a 179 }
Michael J. Spencer 2:1df0b61d3b5a 180 }
Michael J. Spencer 2:1df0b61d3b5a 181
Michael J. Spencer 2:1df0b61d3b5a 182 uint32_t Network::tick(uint32_t dummy)
Michael J. Spencer 2:1df0b61d3b5a 183 {
Michael J. Spencer 2:1df0b61d3b5a 184 do_tick();
Michael J. Spencer 2:1df0b61d3b5a 185 tickcnt++;
Michael J. Spencer 2:1df0b61d3b5a 186 return 0;
Michael J. Spencer 2:1df0b61d3b5a 187 }
Michael J. Spencer 2:1df0b61d3b5a 188
Michael J. Spencer 2:1df0b61d3b5a 189 void Network::on_idle(void *argument)
Michael J. Spencer 2:1df0b61d3b5a 190 {
Michael J. Spencer 2:1df0b61d3b5a 191 if (!ethernet->isUp()) return;
Michael J. Spencer 2:1df0b61d3b5a 192
Michael J. Spencer 2:1df0b61d3b5a 193 int len;
Michael J. Spencer 2:1df0b61d3b5a 194 if (ethernet->_receive_frame(uip_buf, &len)) {
Michael J. Spencer 2:1df0b61d3b5a 195 uip_len = len;
Michael J. Spencer 2:1df0b61d3b5a 196 this->handlePacket();
Michael J. Spencer 2:1df0b61d3b5a 197
Michael J. Spencer 2:1df0b61d3b5a 198 } else {
Michael J. Spencer 2:1df0b61d3b5a 199
Michael J. Spencer 2:1df0b61d3b5a 200 if (timer_expired(&periodic_timer)) { /* no packet but periodic_timer time out (0.1s)*/
Michael J. Spencer 2:1df0b61d3b5a 201 timer_reset(&periodic_timer);
Michael J. Spencer 2:1df0b61d3b5a 202
Michael J. Spencer 2:1df0b61d3b5a 203 for (int i = 0; i < UIP_CONNS; i++) {
Michael J. Spencer 2:1df0b61d3b5a 204 uip_periodic(i);
Michael J. Spencer 2:1df0b61d3b5a 205 /* If the above function invocation resulted in data that
Michael J. Spencer 2:1df0b61d3b5a 206 should be sent out on the network, the global variable
Michael J. Spencer 2:1df0b61d3b5a 207 uip_len is set to a value > 0. */
Michael J. Spencer 2:1df0b61d3b5a 208 if (uip_len > 0) {
Michael J. Spencer 2:1df0b61d3b5a 209 uip_arp_out();
Michael J. Spencer 2:1df0b61d3b5a 210 tapdev_send(uip_buf, uip_len);
Michael J. Spencer 2:1df0b61d3b5a 211 }
Michael J. Spencer 2:1df0b61d3b5a 212 }
Michael J. Spencer 2:1df0b61d3b5a 213
Michael J. Spencer 2:1df0b61d3b5a 214 #if UIP_CONF_UDP
Michael J. Spencer 2:1df0b61d3b5a 215 for (int i = 0; i < UIP_UDP_CONNS; i++) {
Michael J. Spencer 2:1df0b61d3b5a 216 uip_udp_periodic(i);
Michael J. Spencer 2:1df0b61d3b5a 217 /* If the above function invocation resulted in data that
Michael J. Spencer 2:1df0b61d3b5a 218 should be sent out on the network, the global variable
Michael J. Spencer 2:1df0b61d3b5a 219 uip_len is set to a value > 0. */
Michael J. Spencer 2:1df0b61d3b5a 220 if (uip_len > 0) {
Michael J. Spencer 2:1df0b61d3b5a 221 uip_arp_out();
Michael J. Spencer 2:1df0b61d3b5a 222 tapdev_send(uip_buf, uip_len);
Michael J. Spencer 2:1df0b61d3b5a 223 }
Michael J. Spencer 2:1df0b61d3b5a 224 }
Michael J. Spencer 2:1df0b61d3b5a 225 #endif
Michael J. Spencer 2:1df0b61d3b5a 226 }
Michael J. Spencer 2:1df0b61d3b5a 227 /*
Michael J. Spencer 2:1df0b61d3b5a 228 This didn't work actually made it worse,it should have worked though
Michael J. Spencer 2:1df0b61d3b5a 229 else{
Michael J. Spencer 2:1df0b61d3b5a 230 // TODO if the command queue is below a certain amount we should poll any stopped connections
Michael J. Spencer 2:1df0b61d3b5a 231 if(command_q->size() < 4) {
Michael J. Spencer 2:1df0b61d3b5a 232 for (struct uip_conn *connr = &uip_conns[0]; connr <= &uip_conns[UIP_CONNS - 1]; ++connr) {
Michael J. Spencer 2:1df0b61d3b5a 233 if(uip_stopped(connr)){
Michael J. Spencer 2:1df0b61d3b5a 234 // Force a poll of this
Michael J. Spencer 2:1df0b61d3b5a 235 printf("Force poll of connection\n");
Michael J. Spencer 2:1df0b61d3b5a 236 uip_poll_conn(connr);
Michael J. Spencer 2:1df0b61d3b5a 237 }
Michael J. Spencer 2:1df0b61d3b5a 238 }
Michael J. Spencer 2:1df0b61d3b5a 239 }
Michael J. Spencer 2:1df0b61d3b5a 240 }
Michael J. Spencer 2:1df0b61d3b5a 241 */
Michael J. Spencer 2:1df0b61d3b5a 242 /* Call the ARP timer function every 10 seconds. */
Michael J. Spencer 2:1df0b61d3b5a 243 if (timer_expired(&arp_timer)) {
Michael J. Spencer 2:1df0b61d3b5a 244 timer_reset(&arp_timer);
Michael J. Spencer 2:1df0b61d3b5a 245 uip_arp_timer();
Michael J. Spencer 2:1df0b61d3b5a 246 }
Michael J. Spencer 2:1df0b61d3b5a 247 }
Michael J. Spencer 2:1df0b61d3b5a 248 }
Michael J. Spencer 2:1df0b61d3b5a 249
Michael J. Spencer 2:1df0b61d3b5a 250 static void setup_servers()
Michael J. Spencer 2:1df0b61d3b5a 251 {
Michael J. Spencer 2:1df0b61d3b5a 252 if (webserver_enabled) {
Michael J. Spencer 2:1df0b61d3b5a 253 // Initialize the HTTP server, listen to port 80.
Michael J. Spencer 2:1df0b61d3b5a 254 httpd_init();
Michael J. Spencer 2:1df0b61d3b5a 255 printf("Webserver initialized\n");
Michael J. Spencer 2:1df0b61d3b5a 256 }
Michael J. Spencer 2:1df0b61d3b5a 257
Michael J. Spencer 2:1df0b61d3b5a 258 if (telnet_enabled) {
Michael J. Spencer 2:1df0b61d3b5a 259 // Initialize the telnet server
Michael J. Spencer 2:1df0b61d3b5a 260 Telnetd::init();
Michael J. Spencer 2:1df0b61d3b5a 261 printf("Telnetd initialized\n");
Michael J. Spencer 2:1df0b61d3b5a 262 }
Michael J. Spencer 2:1df0b61d3b5a 263
Michael J. Spencer 2:1df0b61d3b5a 264 // sftpd service, which is lazily created on reciept of first packet
Michael J. Spencer 2:1df0b61d3b5a 265 uip_listen(HTONS(115));
Michael J. Spencer 2:1df0b61d3b5a 266 }
Michael J. Spencer 2:1df0b61d3b5a 267
Michael J. Spencer 2:1df0b61d3b5a 268 extern "C" void dhcpc_configured(const struct dhcpc_state *s)
Michael J. Spencer 2:1df0b61d3b5a 269 {
Michael J. Spencer 2:1df0b61d3b5a 270 printf("Got IP address %d.%d.%d.%d\n",
Michael J. Spencer 2:1df0b61d3b5a 271 uip_ipaddr1(&s->ipaddr), uip_ipaddr2(&s->ipaddr),
Michael J. Spencer 2:1df0b61d3b5a 272 uip_ipaddr3(&s->ipaddr), uip_ipaddr4(&s->ipaddr));
Michael J. Spencer 2:1df0b61d3b5a 273 printf("Got netmask %d.%d.%d.%d\n",
Michael J. Spencer 2:1df0b61d3b5a 274 uip_ipaddr1(&s->netmask), uip_ipaddr2(&s->netmask),
Michael J. Spencer 2:1df0b61d3b5a 275 uip_ipaddr3(&s->netmask), uip_ipaddr4(&s->netmask));
Michael J. Spencer 2:1df0b61d3b5a 276 printf("Got DNS server %d.%d.%d.%d\n",
Michael J. Spencer 2:1df0b61d3b5a 277 uip_ipaddr1(&s->dnsaddr), uip_ipaddr2(&s->dnsaddr),
Michael J. Spencer 2:1df0b61d3b5a 278 uip_ipaddr3(&s->dnsaddr), uip_ipaddr4(&s->dnsaddr));
Michael J. Spencer 2:1df0b61d3b5a 279 printf("Got default router %d.%d.%d.%d\n",
Michael J. Spencer 2:1df0b61d3b5a 280 uip_ipaddr1(&s->default_router), uip_ipaddr2(&s->default_router),
Michael J. Spencer 2:1df0b61d3b5a 281 uip_ipaddr3(&s->default_router), uip_ipaddr4(&s->default_router));
Michael J. Spencer 2:1df0b61d3b5a 282 printf("Lease expires in %ld seconds\n", ntohl(s->lease_time));
Michael J. Spencer 2:1df0b61d3b5a 283
Michael J. Spencer 2:1df0b61d3b5a 284 theNetwork->dhcpc_configured(s->ipaddr, s->netmask, s->default_router);
Michael J. Spencer 2:1df0b61d3b5a 285 }
Michael J. Spencer 2:1df0b61d3b5a 286
Michael J. Spencer 2:1df0b61d3b5a 287 void Network::dhcpc_configured(uint32_t ipaddr, uint32_t ipmask, uint32_t ipgw)
Michael J. Spencer 2:1df0b61d3b5a 288 {
Michael J. Spencer 2:1df0b61d3b5a 289 memcpy(this->ipaddr, &ipaddr, 4);
Michael J. Spencer 2:1df0b61d3b5a 290 memcpy(this->ipmask, &ipmask, 4);
Michael J. Spencer 2:1df0b61d3b5a 291 memcpy(this->ipgw, &ipgw, 4);
Michael J. Spencer 2:1df0b61d3b5a 292
Michael J. Spencer 2:1df0b61d3b5a 293 uip_sethostaddr((u16_t*)this->ipaddr);
Michael J. Spencer 2:1df0b61d3b5a 294 uip_setnetmask((u16_t*)this->ipmask);
Michael J. Spencer 2:1df0b61d3b5a 295 uip_setdraddr((u16_t*)this->ipgw);
Michael J. Spencer 2:1df0b61d3b5a 296
Michael J. Spencer 2:1df0b61d3b5a 297 setup_servers();
Michael J. Spencer 2:1df0b61d3b5a 298 }
Michael J. Spencer 2:1df0b61d3b5a 299
Michael J. Spencer 2:1df0b61d3b5a 300 void Network::init(void)
Michael J. Spencer 2:1df0b61d3b5a 301 {
Michael J. Spencer 2:1df0b61d3b5a 302 // two timers for tcp/ip
Michael J. Spencer 2:1df0b61d3b5a 303 timer_set(&periodic_timer, CLOCK_SECOND / 2); /* 0.5s */
Michael J. Spencer 2:1df0b61d3b5a 304 timer_set(&arp_timer, CLOCK_SECOND * 10); /* 10s */
Michael J. Spencer 2:1df0b61d3b5a 305
Michael J. Spencer 2:1df0b61d3b5a 306 // Initialize the uIP TCP/IP stack.
Michael J. Spencer 2:1df0b61d3b5a 307 uip_init();
Michael J. Spencer 2:1df0b61d3b5a 308
Michael J. Spencer 2:1df0b61d3b5a 309 uip_setethaddr(mac_address);
Michael J. Spencer 2:1df0b61d3b5a 310
Michael J. Spencer 2:1df0b61d3b5a 311 if (!use_dhcp) { // manual setup of ip
Michael J. Spencer 2:1df0b61d3b5a 312 uip_ipaddr_t tip; /* local IP address */
Michael J. Spencer 2:1df0b61d3b5a 313 uip_ipaddr(tip, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
Michael J. Spencer 2:1df0b61d3b5a 314 uip_sethostaddr(tip); /* host IP address */
Michael J. Spencer 2:1df0b61d3b5a 315 printf("IP Addr: %d.%d.%d.%d\n", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
Michael J. Spencer 2:1df0b61d3b5a 316
Michael J. Spencer 2:1df0b61d3b5a 317 uip_ipaddr(tip, ipgw[0], ipgw[1], ipgw[2], ipgw[3]);
Michael J. Spencer 2:1df0b61d3b5a 318 uip_setdraddr(tip); /* router IP address */
Michael J. Spencer 2:1df0b61d3b5a 319 printf("IP GW: %d.%d.%d.%d\n", ipgw[0], ipgw[1], ipgw[2], ipgw[3]);
Michael J. Spencer 2:1df0b61d3b5a 320
Michael J. Spencer 2:1df0b61d3b5a 321 uip_ipaddr(tip, ipmask[0], ipmask[1], ipmask[2], ipmask[3]);
Michael J. Spencer 2:1df0b61d3b5a 322 uip_setnetmask(tip); /* mask */
Michael J. Spencer 2:1df0b61d3b5a 323 printf("IP mask: %d.%d.%d.%d\n", ipmask[0], ipmask[1], ipmask[2], ipmask[3]);
Michael J. Spencer 2:1df0b61d3b5a 324 setup_servers();
Michael J. Spencer 2:1df0b61d3b5a 325
Michael J. Spencer 2:1df0b61d3b5a 326 }else{
Michael J. Spencer 2:1df0b61d3b5a 327 #if UIP_CONF_UDP
Michael J. Spencer 2:1df0b61d3b5a 328 dhcpc_init(mac_address, sizeof(mac_address));
Michael J. Spencer 2:1df0b61d3b5a 329 dhcpc_request();
Michael J. Spencer 2:1df0b61d3b5a 330 printf("Getting IP address....\n");
Michael J. Spencer 2:1df0b61d3b5a 331 #endif
Michael J. Spencer 2:1df0b61d3b5a 332 }
Michael J. Spencer 2:1df0b61d3b5a 333 }
Michael J. Spencer 2:1df0b61d3b5a 334
Michael J. Spencer 2:1df0b61d3b5a 335 void Network::on_main_loop(void *argument)
Michael J. Spencer 2:1df0b61d3b5a 336 {
Michael J. Spencer 2:1df0b61d3b5a 337 // issue commands here if any available
Michael J. Spencer 2:1df0b61d3b5a 338 while(command_q->pop()) {
Michael J. Spencer 2:1df0b61d3b5a 339 // keep feeding them until empty
Michael J. Spencer 2:1df0b61d3b5a 340 }
Michael J. Spencer 2:1df0b61d3b5a 341 }
Michael J. Spencer 2:1df0b61d3b5a 342
Michael J. Spencer 2:1df0b61d3b5a 343 // select between webserver and telnetd server
Michael J. Spencer 2:1df0b61d3b5a 344 extern "C" void app_select_appcall(void)
Michael J. Spencer 2:1df0b61d3b5a 345 {
Michael J. Spencer 2:1df0b61d3b5a 346 switch (uip_conn->lport) {
Michael J. Spencer 2:1df0b61d3b5a 347 case HTONS(80):
Michael J. Spencer 2:1df0b61d3b5a 348 if (webserver_enabled) httpd_appcall();
Michael J. Spencer 2:1df0b61d3b5a 349 break;
Michael J. Spencer 2:1df0b61d3b5a 350
Michael J. Spencer 2:1df0b61d3b5a 351 case HTONS(23):
Michael J. Spencer 2:1df0b61d3b5a 352 if (telnet_enabled) Telnetd::appcall();
Michael J. Spencer 2:1df0b61d3b5a 353 break;
Michael J. Spencer 2:1df0b61d3b5a 354
Michael J. Spencer 2:1df0b61d3b5a 355 case HTONS(115):
Michael J. Spencer 2:1df0b61d3b5a 356 if(sftpd == NULL) {
Michael J. Spencer 2:1df0b61d3b5a 357 sftpd= new Sftpd();
Michael J. Spencer 2:1df0b61d3b5a 358 sftpd->init();
Michael J. Spencer 2:1df0b61d3b5a 359 printf("Created sftpd service\n");
Michael J. Spencer 2:1df0b61d3b5a 360 }
Michael J. Spencer 2:1df0b61d3b5a 361 sftpd->appcall();
Michael J. Spencer 2:1df0b61d3b5a 362 break;
Michael J. Spencer 2:1df0b61d3b5a 363
Michael J. Spencer 2:1df0b61d3b5a 364 default:
Michael J. Spencer 2:1df0b61d3b5a 365 printf("unknown app for port: %d\n", uip_conn->lport);
Michael J. Spencer 2:1df0b61d3b5a 366
Michael J. Spencer 2:1df0b61d3b5a 367 }
Michael J. Spencer 2:1df0b61d3b5a 368 }
Michael J. Spencer 2:1df0b61d3b5a 369
Michael J. Spencer 2:1df0b61d3b5a 370 void Network::tapdev_send(void *pPacket, unsigned int size)
Michael J. Spencer 2:1df0b61d3b5a 371 {
Michael J. Spencer 2:1df0b61d3b5a 372 memcpy(ethernet->request_packet_buffer(), pPacket, size);
Michael J. Spencer 2:1df0b61d3b5a 373 ethernet->write_packet((uint8_t *) pPacket, size);
Michael J. Spencer 2:1df0b61d3b5a 374 }
Michael J. Spencer 2:1df0b61d3b5a 375
Michael J. Spencer 2:1df0b61d3b5a 376 // define this to split full frames into two to illicit an ack from the endpoint
Michael J. Spencer 2:1df0b61d3b5a 377 #define SPLIT_OUTPUT
Michael J. Spencer 2:1df0b61d3b5a 378
Michael J. Spencer 2:1df0b61d3b5a 379 #ifdef SPLIT_OUTPUT
Michael J. Spencer 2:1df0b61d3b5a 380 extern "C" void uip_split_output(void);
Michael J. Spencer 2:1df0b61d3b5a 381 extern "C" void tcpip_output()
Michael J. Spencer 2:1df0b61d3b5a 382 {
Michael J. Spencer 2:1df0b61d3b5a 383 theNetwork->tapdev_send(uip_buf, uip_len);
Michael J. Spencer 2:1df0b61d3b5a 384 }
Michael J. Spencer 2:1df0b61d3b5a 385 void network_device_send()
Michael J. Spencer 2:1df0b61d3b5a 386 {
Michael J. Spencer 2:1df0b61d3b5a 387 uip_split_output();
Michael J. Spencer 2:1df0b61d3b5a 388 //tcpip_output();
Michael J. Spencer 2:1df0b61d3b5a 389 }
Michael J. Spencer 2:1df0b61d3b5a 390 #else
Michael J. Spencer 2:1df0b61d3b5a 391 void network_device_send()
Michael J. Spencer 2:1df0b61d3b5a 392 {
Michael J. Spencer 2:1df0b61d3b5a 393 tapdev_send(uip_buf, uip_len);
Michael J. Spencer 2:1df0b61d3b5a 394 }
Michael J. Spencer 2:1df0b61d3b5a 395 #endif
Michael J. Spencer 2:1df0b61d3b5a 396
Michael J. Spencer 2:1df0b61d3b5a 397 void Network::handlePacket(void)
Michael J. Spencer 2:1df0b61d3b5a 398 {
Michael J. Spencer 2:1df0b61d3b5a 399 if (uip_len > 0) { /* received packet */
Michael J. Spencer 2:1df0b61d3b5a 400 //printf("handlePacket: %d\n", uip_len);
Michael J. Spencer 2:1df0b61d3b5a 401
Michael J. Spencer 2:1df0b61d3b5a 402 if (BUF->type == htons(UIP_ETHTYPE_IP)) { /* IP packet */
Michael J. Spencer 2:1df0b61d3b5a 403 uip_arp_ipin();
Michael J. Spencer 2:1df0b61d3b5a 404 uip_input();
Michael J. Spencer 2:1df0b61d3b5a 405 /* If the above function invocation resulted in data that
Michael J. Spencer 2:1df0b61d3b5a 406 should be sent out on the network, the global variable
Michael J. Spencer 2:1df0b61d3b5a 407 uip_len is set to a value > 0. */
Michael J. Spencer 2:1df0b61d3b5a 408
Michael J. Spencer 2:1df0b61d3b5a 409 if (uip_len > 0) {
Michael J. Spencer 2:1df0b61d3b5a 410 uip_arp_out();
Michael J. Spencer 2:1df0b61d3b5a 411 network_device_send();
Michael J. Spencer 2:1df0b61d3b5a 412 }
Michael J. Spencer 2:1df0b61d3b5a 413
Michael J. Spencer 2:1df0b61d3b5a 414 } else if (BUF->type == htons(UIP_ETHTYPE_ARP)) { /*ARP packet */
Michael J. Spencer 2:1df0b61d3b5a 415 uip_arp_arpin();
Michael J. Spencer 2:1df0b61d3b5a 416 /* If the above function invocation resulted in data that
Michael J. Spencer 2:1df0b61d3b5a 417 should be sent out on the network, the global variable
Michael J. Spencer 2:1df0b61d3b5a 418 uip_len is set to a value > 0. */
Michael J. Spencer 2:1df0b61d3b5a 419 if (uip_len > 0) {
Michael J. Spencer 2:1df0b61d3b5a 420 tapdev_send(uip_buf, uip_len); /* ARP ack*/
Michael J. Spencer 2:1df0b61d3b5a 421 }
Michael J. Spencer 2:1df0b61d3b5a 422
Michael J. Spencer 2:1df0b61d3b5a 423 } else {
Michael J. Spencer 2:1df0b61d3b5a 424 printf("Unknown ethernet packet type %04X\n", htons(BUF->type));
Michael J. Spencer 2:1df0b61d3b5a 425 uip_len = 0;
Michael J. Spencer 2:1df0b61d3b5a 426 }
Michael J. Spencer 2:1df0b61d3b5a 427 }
Michael J. Spencer 2:1df0b61d3b5a 428 }