int mainloop(sp_session *session, int listen_fd) { int event, timeout; int loops; event = 0; do { syslog(LOG_DEBUG, "EVENTLOOP [id %d]: Processing Spotify events", event); loops = 0; do { sp_session_process_events(session, &timeout); loops++; } while(timeout == 0); syslog(LOG_DEBUG, "EVENTLOOP [id %d]: Done processing %d Spotify events, next timeout %dms", event, loops, timeout); if(app_process_events() < 0) { syslog(LOG_INFO, "EVENTLOOP [id %d]: app_process_events() failed", event); break; } if(net_poll(listen_fd, timeout) < 0) { syslog(LOG_INFO, "EVENTLOOP [id %d]: net_poll() failed", event); break; } event++; } while(1); return 0; }
static void dhcp_send_packet(struct uip_udp_conn *conn, const char *name, DhcpPacket *out, DhcpPacket *in) { // Send the outbound packet. printf("Sending %s... ", name); uip_udp_packet_send(conn, out, sizeof(*out)); printf("done.\n"); // Prepare for the reply. printf("Waiting for reply... "); dhcp_in = in; dhcp_out = out; dhcp_in_ready = 0; // Poll network driver until we get a reply. Resend periodically. net_set_callback(&dhcp_callback); for (;;) { uint64_t start = timer_us(0); do { net_poll(); } while (!dhcp_in_ready && timer_us(start) < DhcpRespTimeoutUs); if (dhcp_in_ready) break; // No response, try again. uip_udp_packet_send(conn, out, sizeof(*out)); } net_set_callback(NULL); printf("done.\n"); }
static int tftp_poll(struct file_priv *priv) { if (ctrlc()) { priv->state = STATE_DONE; priv->err = -EINTR; return -EINTR; } if (is_timeout(priv->resend_timeout, TFTP_RESEND_TIMEOUT)) { printf("T "); priv->resend_timeout = get_time_ns(); priv->block_requested = -1; return TFTP_ERR_RESEND; } if (is_timeout(priv->progress_timeout, TFTP_TIMEOUT)) { priv->state = STATE_DONE; priv->err = -ETIMEDOUT; return -ETIMEDOUT; } net_poll(); return 0; }
static int do_nfs(int argc, char *argv[]) { char *localfile; char *remotefile; if (argc < 2) return COMMAND_ERROR_USAGE; remotefile = argv[1]; if (argc == 2) localfile = basename(remotefile); else localfile = argv[2]; net_store_fd = open(localfile, O_WRONLY | O_CREAT); if (net_store_fd < 0) { perror("open"); return 1; } nfs_con = net_udp_new(net_get_serverip(), 0, nfs_handler, NULL); if (IS_ERR(nfs_con)) { nfs_err = PTR_ERR(nfs_con); goto err_udp; } net_udp_bind(nfs_con, 1000); nfs_err = 0; nfs_start(remotefile); while (nfs_state != STATE_DONE) { if (ctrlc()) { nfs_err = -EINTR; break; } net_poll(); if (is_timeout(nfs_timer_start, NFS_TIMEOUT * SECOND)) { show_progress(-1); nfs_send(); } } net_unregister(nfs_con); err_udp: close(net_store_fd); if (nfs_err) { printf("NFS failed: %s\n", strerror(-nfs_err)); unlink(localfile); } printf("\n"); return nfs_err == 0 ? 0 : 1; }
static int nc_tstc(struct console_device *cdev) { struct nc_priv *priv = container_of(cdev, struct nc_priv, cdev); if (priv->busy) return kfifo_len(priv->fifo) ? 1 : 0; net_poll(); return kfifo_len(priv->fifo) ? 1 : 0; }
static int nc_getc(struct console_device *cdev) { struct nc_priv *priv = container_of(cdev, struct nc_priv, cdev); unsigned char c; while (!kfifo_len(priv->fifo)) net_poll(); kfifo_getc(priv->fifo, &c); return c; }
int core_run(void) { int s_server = 0, s_listener = 0; bool running = true; struct pollfd fds[MAX_SOCKETS]; store_init(); net_init(); state_init(); if((s_server = srv_init()) < 0) return EXIT_FAILURE; if(srv_connect() == -1){ ERR("srv_connect() failed. Exiting..."); return EXIT_FAILURE; } if((s_listener = clt_init()) == -1){ ERR("clt_init() failed. Exiting..."); return EXIT_FAILURE; } memset(fds, 0 , sizeof(fds)); net_poll_add(s_server, POLLIN); net_poll_add_listener(s_listener, POLLIN); while(running){ net_poll(POLLTIMEOUT); proc_tick(); for(int i = 0; i < net_nfds(); i++){ while(net_socket_avail(i)){ char msg[513] = ""; net_socket_msg(i, msg, sizeof msg); proc_proc(i, msg); } } while(proc_wqueue_length()){ wqueue_entry_t ent = proc_wqueue_head(); net_socket_write(ENT_GET(ent, target), ENT_GET(ent, data), ENT_GET(ent, datasz)); proc_wqueue_next(); } } return EXIT_SUCCESS; }
static int poll_fdsetup(int fd, FAR struct pollfd *fds, bool setup) { FAR struct filelist *list; FAR struct file *this_file; FAR struct inode *inode; int ret = -ENOSYS; /* Check for a valid file descriptor */ if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS) { /* Perform the socket ioctl */ #if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 if ((unsigned int)fd < (CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS)) { return net_poll(fd, fds, setup); } else #endif { return -EBADF; } } /* Get the thread-specific file list */ list = sched_getfiles(); if (!list) { return -EMFILE; } /* Is a driver registered? Does it support the poll method? * If not, return -ENOSYS */ this_file = &list->fl_files[fd]; inode = this_file->f_inode; if (inode && inode->u.i_ops && inode->u.i_ops->poll) { /* Yes, then setup the poll */ ret = (int)inode->u.i_ops->poll(this_file, fds, setup); } return ret; }
IPaddr_t resolv(char *host) { IPaddr_t ip; const char *ns; if (!string_to_ip(host, &ip)) return ip; dns_ip = 0; dns_state = STATE_INIT; ns = getenv("net.nameserver"); if (!ns || !*ns) { printk("%s: no nameserver specified in $net.nameserver\n", __func__); return 0; } if (string_to_ip(ns, &ip)) return 0; debug("resolving host %s via nameserver %s\n", host, ip_to_string(ip)); dns_con = net_udp_new(ip, DNS_PORT, dns_handler, NULL); if (IS_ERR(dns_con)) return PTR_ERR(dns_con); dns_timer_start = get_time_ns(); dns_send(host); while (dns_state != STATE_DONE) { if (ctrlc()) { break; } net_poll(); if (is_timeout(dns_timer_start, SECOND)) { dns_timer_start = get_time_ns(); printf("T "); dns_send(host); } } net_unregister(dns_con); return dns_ip; }
static int do_dhcp(struct command *cmdtp, int argc, char *argv[]) { int ret; dhcp_con = net_udp_new(0xffffffff, PORT_BOOTPS, dhcp_handler, NULL); if (IS_ERR(dhcp_con)) { ret = PTR_ERR(dhcp_con); goto out; } ret = net_udp_bind(dhcp_con, PORT_BOOTPC); if (ret) goto out1; net_set_ip(0); ret = bootp_request(); /* Basically same as BOOTP */ if (ret) goto out1; while (dhcp_state != BOUND) { if (ctrlc()) break; net_poll(); if (is_timeout(dhcp_start, 3 * SECOND)) { dhcp_start = get_time_ns(); printf("T "); ret = bootp_request(); if (ret) goto out1; } } out1: net_unregister(dhcp_con); out: if (ret) printf("dhcp failed: %s\n", strerror(-ret)); return ret ? 1 : 0; }
/* * sana_poll() * This routine polls SanaPort and processes replied * requests appropriately */ BOOL sana_poll(void) { struct IOIPReq * io; spl_t s = splnet(); while (io = (struct IOIPReq *)GetMsg(SanaPort)) { /* touch the network interface */ GetSysTime(&io->ioip_if->ss_if.if_lastchange); if (io->ioip_dispatch) { (*io->ioip_dispatch)(io->ioip_if, io); } else { __log(LOG_ERR, "No dispatch function in request for %s\n", io->ioip_if->ss_name); } } net_poll(); splx(s); return FALSE; }
/* We need this */ int main(int argc, char *argv[]) { int optc, show_help, show_version, show_usage; char *local_file, *cmd_listen_port, *cmd_pid_file; int inetd_mode, no_daemon; /* Set up some globals */ progname = argv[0]; listen_port = x_strdup(DEFAULT_LISTEN_PORT); pid_file = (DEFAULT_PID_FILE ? x_strdup(DEFAULT_PID_FILE) : 0); #ifndef DEBUG no_daemon = 0; #else /* DEBUG */ no_daemon = 1; #endif /* DEBUG */ local_file = cmd_listen_port = cmd_pid_file = 0; show_help = show_version = show_usage = inetd_mode = 0; while ((optc = getopt_long(argc, argv, GETOPTIONS, long_opts, NULL)) != -1) { switch (optc) { case 'h': show_help = 1; break; case 'v': show_version = 1; break; case 'D': #ifndef DEBUG no_daemon = 1; #else /* DEBUG */ no_daemon = 0; #endif /* DEBUG */ break; case 'I': inetd_mode = 1; break; case 'P': free(cmd_listen_port); cmd_listen_port = x_strdup(optarg); break; case 'p': free(cmd_pid_file); cmd_pid_file = x_strdup(optarg); break; case 'f': free(local_file); local_file = x_strdup(optarg); break; default: show_usage = 1; break; } } if (show_usage || (optind < argc)) { _print_usage(); return 1; } if (show_version) { _print_version(); if (!show_help) return 0; } if (show_help) { _print_help(); return 0; } /* If no -f was specified use the home directory */ if (!local_file && !inetd_mode) { struct stat statinfo; struct passwd *pw; pw = getpwuid(geteuid()); if (pw && pw->pw_dir) { local_file = x_sprintf("%s/%s", pw->pw_dir, USER_CONFIG_FILENAME); debug("Local config file: %s", local_file); if (!stat(local_file, &statinfo) && (statinfo.st_mode & 0077)) { fprintf(stderr, "%s: Permissions of %s must be 0700 or " "more restrictive\n", progname, local_file); free(local_file); return 2; } if (cfg_read(local_file, &listen_port, &pid_file, &g)) { /* If the local one didn't exist, set to 0 so we open global one */ free(local_file); local_file = 0; } else { config_file = x_strdup(local_file); } } } else if (local_file) { if (cfg_read(local_file, &listen_port, &pid_file, &g)) { /* This is fatal! */ fprintf(stderr, "%s: Couldn't read configuration from %s: %s\n", progname, local_file, strerror(errno)); free(local_file); return 2; } else { config_file = x_strdup(local_file); } } /* Read global config file if local one not found */ if (!local_file) { char *global_file; /* Not fatal if it doesn't exist */ global_file = x_sprintf("%s/%s", SYSCONFDIR, GLOBAL_CONFIG_FILENAME); debug("Global config file: %s", global_file); cfg_read(global_file, &listen_port, &pid_file, &g); config_file = x_strdup(global_file); free(global_file); } else { free(local_file); } /* Check we got some connection classes */ if (!connclasses) { fprintf(stderr, "%s: No connection classes have been defined.\n", progname); return 2; } /* -P overrides config file */ if (cmd_listen_port) { free(listen_port); listen_port = cmd_listen_port; } /* -p overrides pid file */ if (cmd_pid_file) { free(pid_file); pid_file = cmd_pid_file; } /* Set signal handlers */ signal(SIGTERM, _sig_term); signal(SIGINT, _sig_term); signal(SIGHUP, _sig_hup); signal(SIGCHLD, _sig_child); #ifdef DEBUG_MEMORY signal(SIGUSR1, _sig_usr); signal(SIGUSR2, _sig_usr); #endif /* DEBUG_MEMORY */ /* Broken Pipe? This means that someone disconnected while we were sending stuff. Naughty! */ signal(SIGPIPE, SIG_IGN); if (!inetd_mode) { debug("Ordinary console dodge-monkey mode"); /* Make listening socket before we fork */ if (ircnet_listen(listen_port)) { fprintf(stderr, "%s: Unable to establish listen port\n", progname); return 3; } /* go daemon here */ if (!no_daemon) { switch (go_daemon()) { case -1: return -1; case 0: break; default: return 0; } } } else { /* running under inetd means we are backgrounded right *now* */ in_background = 1; debug("Inetd SuperTed mode!"); /* Hook STDIN into a new proxy */ ircnet_hooksocket(STDIN_FILENO); } /* Open a connection to syslog if we're in the background */ if (in_background) openlog(PACKAGE, LOG_PID, LOG_USER); if (pid_file) { FILE *pidfile; pidfile = fopen(pid_file, "w"); if (pidfile) { fchmod(fileno(pidfile), 0600); fprintf(pidfile, "%d\n", getpid()); fclose(pidfile); } else { syscall_fail("fopen", pid_file, 0); } } /* Main loop! */ while (!stop_poll) { int ns, nt, status; pid_t pid; ircnet_expunge_proxies(); dccnet_expunge_proxies(); ns = net_poll(); nt = timer_poll(); /* Reap any children */ while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { debug("Reaped process %d, exit status %d", pid, status); /* Handle any DNS children */ dns_endrequest(pid, status); } /* Reload the configuration file? */ if (reload_config) { _reload_config(); reload_config = 0; } if (!ns && !nt) break; } if (pid_file) { unlink(pid_file); } /* Free up stuff */ ircnet_flush(); dccnet_flush(); dns_flush(); timer_flush(); /* Do a lingering close on all sockets */ net_closeall(); net_flush(); /* Close down and free up memory */ if (!inetd_mode && !no_daemon) closelog(); free(listen_port); free(pid_file); free(config_file); #ifdef DEBUG_MEMORY mem_report("termination"); #endif /* DEBUG_MEMORY */ return 0; }
void main(void) { unsigned char x, y; // DEBUG / QA stats: get last reset reason: x = (~RCON) & 0x1f; if (STKPTRbits.STKFUL) x += 32; if (STKPTRbits.STKUNF) x += 64; // ...clear RCON: RCONbits.NOT_BOR = 1; // b0 = 1 = Brown Out Reset RCONbits.NOT_POR = 1; // b1 = 2 = Power On Reset //RCONbits.NOT_PD = 1; // b2 = 4 = Power Down detection //RCONbits.NOT_TO = 1; // b3 = 8 = watchdog TimeOut occured RCONbits.NOT_RI = 1; // b4 = 16 = Reset Instruction if (x == 3) // 3 = normal Power On { debug_crashreason = 0; debug_crashcnt = 0; #ifdef OVMS_LOGGINGMODULE logging_initialise(); #endif } else { debug_crashreason = x | 0x80; // 0x80 = keep checkpoint until sent to server debug_crashcnt++; } CHECKPOINT(0x20) for (x = 0; x < FEATURES_MAP_PARAM; x++) sys_features[x] = 0; // Turn off the features // The top N features are persistent for (x = FEATURES_MAP_PARAM; x < FEATURES_MAX; x++) { sys_features[x] = atoi(par_get(PARAM_FEATURE_S + (x - FEATURES_MAP_PARAM))); } // Make sure cooldown is off car_coolingdown = -1; // Port configuration inputs_initialise(); TRISB = 0xFE; // Timer 0 enabled, Fosc/4, 16 bit mode, prescaler 1:256 // This gives us one tick every 51.2uS before prescale (13.1ms after) T0CON = 0b10000111; // @ 5Mhz => 51.2uS // Initialisation... led_initialise(); par_initialise(); vehicle_initialise(); net_initialise(); CHECKPOINT(0x21) // Startup sequence... // Holding the RED led on, pulse out the firmware version on the GREEN led delay100(10); // Delay 1 second led_set(OVMS_LED_RED, OVMS_LED_ON); led_set(OVMS_LED_GRN, OVMS_LED_OFF); led_start(); delay100(10); // Delay 1.0 seconds led_set(OVMS_LED_GRN, ovms_firmware[0]); led_start(); delay100(35); // Delay 3.5 seconds ClrWdt(); // Clear Watchdog Timer led_set(OVMS_LED_GRN, ovms_firmware[1]); led_start(); delay100(35); // Delay 3.5 seconds ClrWdt(); // Clear Watchdog Timer led_set(OVMS_LED_GRN, ovms_firmware[2]); led_start(); delay100(35); // Delay 3.5 seconds ClrWdt(); // Clear Watchdog Timer led_set(OVMS_LED_GRN, OVMS_LED_OFF); led_set(OVMS_LED_RED, OVMS_LED_OFF); led_start(); delay100(10); // Delay 1 second ClrWdt(); // Clear Watchdog Timer // Setup ready for the main loop led_set(OVMS_LED_GRN, OVMS_LED_OFF); led_start(); #ifdef OVMS_HW_V2 car_12vline = inputs_voltage()*10; car_12vline_ref = 0; #endif #ifdef OVMS_ACCMODULE acc_initialise(); #endif // Proceed to main loop y = 0; // Last TMR0H while (1) // Main Loop { CHECKPOINT(0x22) if ((vUARTIntStatus.UARTIntRxError) || (vUARTIntStatus.UARTIntRxOverFlow)) net_reset_async(); while (!vUARTIntStatus.UARTIntRxBufferEmpty) { CHECKPOINT(0x23) net_poll(); } CHECKPOINT(0x24) vehicle_idlepoll(); ClrWdt(); // Clear Watchdog Timer x = TMR0L; if (TMR0H >= 0x4c) // Timout ~1sec (actually 996ms) { TMR0H = 0; TMR0L = 0; // Reset timer CHECKPOINT(0x25) net_ticker(); CHECKPOINT(0x26) vehicle_ticker(); #ifdef OVMS_LOGGINGMODULE CHECKPOINT(0x27) logging_ticker(); #endif #ifdef OVMS_ACCMODULE CHECKPOINT(0x28) acc_ticker(); #endif } else if (TMR0H != y) { if ((TMR0H % 0x04) == 0) { CHECKPOINT(0x29) net_ticker10th(); CHECKPOINT(0x2A) vehicle_ticker10th(); CHECKPOINT(0x2B) } y = TMR0H; } }
void CheckForNetworkEvents(int server_socket, int client_socket, std::vector<FifoFrameData>& frames, std::vector<AnalyzedFrameInfo>& analyzed_frames) { #if 0 fd_set readset; FD_ZERO(&readset); // FD_SET(server_socket, &readset); // if (client_socket != -1) FD_SET(client_socket, &readset); // int maxfd = std::max(client_socket, server_socket); int maxfd = client_socket; struct timeval timeout; timeout.tv_sec = 1; timeout.tv_usec = 0; char data[12]; int ret = net_select(maxfd+1, &readset, NULL, NULL, &timeout); // TODO: Is this compatible with winsocks? if (ret <= 0) { if (ret < 0) printf("select returned %d\n", ret); return; } /* if (FD_ISSET(server_socket, &readset)) { int new_socket = net_accept(server_socket, NULL, NULL); if (new_socket < 0) { qDebug() << "accept failed"; } else client_socket = new_socket; }*/ #endif struct pollsd fds[2]; memset(fds, 0, sizeof(fds)); // fds[0].socket = server_socket; fds[0].socket = client_socket; fds[0].events = POLLIN; int nfds = 1; int timeout = 1; // TODO: Set to zero int ret; do { ret = net_poll(fds, nfds, timeout); if (ret < 0) { printf("poll returned error %d\n", ret); return; } if (ret == 0) { printf("timeout :(\n"); // timeout return; } char cmd; ssize_t numread = net_recv(client_socket, &cmd, 1, 0); printf("Peeked command %d\n", cmd); switch (cmd) { case CMD_HANDSHAKE: if (RET_SUCCESS == ReadHandshake(client_socket)) printf("Successfully exchanged handshake token!\n"); else printf("Failed to exchange handshake token!\n"); // TODO: should probably write a handshake in return, but ... I'm lazy break; case CMD_STREAM_DFF: //ReadStreamedDff(client_socket); break; case CMD_ENABLE_COMMAND: case CMD_DISABLE_COMMAND: ReadCommandEnable(client_socket, analyzed_frames, (cmd == CMD_ENABLE_COMMAND) ? true : false); break; case CMD_PATCH_COMMAND: ReadCommandPatch(client_socket, frames); break; default: printf("Received unknown command: %d\n", cmd); break; } printf("Looping again\n"); timeout = 100; } while (ret > 0); }
static int do_dhcp(int argc, char *argv[]) { int ret, opt; int retries = DHCP_DEFAULT_RETRY; dhcp_reset_env(); getenv_uint("global.dhcp.retries", &retries); while((opt = getopt(argc, argv, "H:v:c:u:U:r:")) > 0) { switch(opt) { case 'H': dhcp_set_param_data(DHCP_HOSTNAME, optarg); break; case 'v': dhcp_set_param_data(DHCP_VENDOR_ID, optarg); break; case 'c': dhcp_set_param_data(DHCP_CLIENT_ID, optarg); break; case 'u': dhcp_set_param_data(DHCP_CLIENT_UUID, optarg); break; case 'U': dhcp_set_param_data(DHCP_USER_CLASS, optarg); break; case 'r': retries = simple_strtoul(optarg, NULL, 10); break; } } if (!retries) { printf("retries is set to zero, set it to %d\n", DHCP_DEFAULT_RETRY); retries = DHCP_DEFAULT_RETRY; } dhcp_con = net_udp_new(0xffffffff, PORT_BOOTPS, dhcp_handler, NULL); if (IS_ERR(dhcp_con)) { ret = PTR_ERR(dhcp_con); goto out; } ret = net_udp_bind(dhcp_con, PORT_BOOTPC); if (ret) goto out1; net_set_ip(0); dhcp_start = get_time_ns(); ret = bootp_request(); /* Basically same as BOOTP */ if (ret) goto out1; while (dhcp_state != BOUND) { if (ctrlc()) { ret = -EINTR; goto out1; } if (!retries) { ret = -ETIMEDOUT; goto out1; } net_poll(); if (is_timeout(dhcp_start, 3 * SECOND)) { dhcp_start = get_time_ns(); printf("T "); ret = bootp_request(); /* no need to check if retries > 0 as we check if != 0 */ retries--; if (ret) goto out1; } } if (dhcp_tftpname[0] != 0) { IPaddr_t tftpserver = resolv(dhcp_tftpname); if (tftpserver) net_set_serverip(tftpserver); } out1: net_unregister(dhcp_con); out: if (ret) printf("dhcp failed: %s\n", strerror(-ret)); return ret; }
int main(void) { int res; udelay(2000000); debug_init(); printf("\n\nBootOS Stage 2 starting.\n"); printf("Waiting for thread 1...\n"); while(!_thread1_active); printf("Thread 1 is alive, all systems go.\n"); exceptions_init(); lv2_cleanup(); mm_init(); #ifdef USE_NETWORK net_init(); gstate = STATE_START; while(1) { net_poll(); if(sequence()) break; } #endif #ifdef AUTO_HDD static FATFS fatfs; DSTATUS stat; stat = disk_initialize(0); if (stat & ~STA_PROTECT) fatal("disk_initialize() failed"); printf("Mounting filesystem...\n"); res = f_mount(0, &fatfs); if (res != FR_OK) fatal("f_mount() failed"); printf("Reading kboot.conf...\n"); res = readfile("/kboot.conf", conf_buf, MAX_KBOOTCONF_SIZE-1); if (res <= 0) { printf("Could not read kboot.conf (%d), panicking\n", res); lv1_panic(0); } conf_buf[res] = 0; kbootconf_parse(); if (conf.num_kernels == 0) { printf("No kernels found in configuration file. Panicing...\n"); lv1_panic(0); } boot_entry = conf.default_idx; printf("Starting to boot '%s'\n", conf.kernels[boot_entry].label); printf("Loading kernel (%s)...\n", conf.kernels[boot_entry].kernel); kernel_buf = mm_highmem_freestart(); res = readfile(conf.kernels[boot_entry].kernel, kernel_buf, mm_highmem_freesize()); if (res <= 0) { printf("Could not read kernel (%d), panicking\n", res); lv1_panic(0); } printf("Kernel size: %d\n", res); if (kernel_load(kernel_buf, res) != 0) { printf("Failed to load kernel. Rebooting...\n"); lv1_panic(1); } if (conf.kernels[boot_entry].initrd && conf.kernels[boot_entry].initrd[0]) { initrd_buf = mm_highmem_freestart(); res = readfile(conf.kernels[boot_entry].initrd, initrd_buf, mm_highmem_freesize()); if (res <= 0) { printf("Could not read initrd (%d), panicking\n", res); lv1_panic(0); } printf("Initrd size: %d\n", res); mm_highmem_reserve(res); kernel_set_initrd(initrd_buf, res); } kernel_build_cmdline(conf.kernels[boot_entry].parameters, conf.kernels[boot_entry].root); f_mount(0, NULL); disk_shutdown(0); mm_shutdown(); kernel_launch(); #endif printf("Loading embedded kernel...\n"); kernel_buf = mm_highmem_freestart(); printf("Decompressing kernel to %lX...\n", (u64) kernel_buf); res = unzpipe (kernel_buf, __vmlinux, &kernel_sz); if (res) { printf("Cannot decompress kernel, error %d.\n", res); lv1_panic(1); } printf("Kernel size: %ld\n", kernel_sz); if (kernel_load(kernel_buf, kernel_sz) != 0) { printf("Failed to load embedded kernel. Rebooting...\n"); lv1_panic(1); } kernel_build_cmdline("video=ps3fb:mode:0 panic=5", "/dev/sda1"); shutdown_and_launch(); printf("End of main() reached! Rebooting...\n"); lv1_panic(1); return 0; }
void main(void) { unsigned char x,y; char *p; for (x=0;x<FEATURES_MAP_PARAM;x++) sys_features[x]=0; // Turn off the features // The top N features are persistent for (x=FEATURES_MAP_PARAM;x<FEATURES_MAX;x++) { sys_features[x] = atoi(par_get(PARAM_FEATURE_S+(x-FEATURES_MAP_PARAM))); } PORTA = 0x00; // Initialise port A ADCON1 = 0x0F; // Switch off A/D converter TRISA = 0xFF; TRISB = 0xFE; // Timer 0 enabled, Fosc/4, 16 bit mode, prescaler 1:256 // This gives us one tick every 51.2uS before prescale (13.1ms after) T0CON = 0b10000111; // @ 5Mhz => 51.2uS // Initialisation... led_initialise(); par_initialise(); can_initialise(); net_initialise(); // Startup sequence... // Holding the RED led on, pulse out the firmware version on the GREEN led delay100(10); // Delay 1 second led_set(OVMS_LED_RED,OVMS_LED_ON); led_set(OVMS_LED_GRN,OVMS_LED_OFF); led_start(); delay100(10); // Delay 1.0 seconds led_set(OVMS_LED_GRN, ovms_firmware[0]); led_start(); delay100(35); // Delay 3.5 seconds ClrWdt(); // Clear Watchdog Timer led_set(OVMS_LED_GRN, ovms_firmware[1]); led_start(); delay100(35); // Delay 3.5 seconds ClrWdt(); // Clear Watchdog Timer led_set(OVMS_LED_GRN, ovms_firmware[2]); led_start(); delay100(35); // Delay 3.5 seconds ClrWdt(); // Clear Watchdog Timer led_set(OVMS_LED_GRN, OVMS_LED_OFF); led_set(OVMS_LED_RED, OVMS_LED_OFF); led_start(); delay100(10); // Delay 1 second ClrWdt(); // Clear Watchdog Timer // Setup ready for the main loop led_set(OVMS_LED_GRN,NET_LED_WAKEUP); led_start(); // Proceed to main loop y = 0; // Last TMR0H while (1) // Main Loop { if((vUARTIntStatus.UARTIntRxError) || (vUARTIntStatus.UARTIntRxOverFlow)) net_reset_async(); if (! vUARTIntStatus.UARTIntRxBufferEmpty) net_poll(); can_idlepoll(); ClrWdt(); // Clear Watchdog Timer x = TMR0L; if (TMR0H >= 0x4c) // Timout ~1sec (actually 996ms) { TMR0H = 0; TMR0L = 0; // Reset timer net_ticker(); can_ticker(); } else if (TMR0H != y) { if ((TMR0H % 0x04)==0) { net_ticker10th(); can_ticker10th(); } y = TMR0H; } } }
int dhcp(int retries, struct dhcp_req_param *param) { int ret = 0; dhcp_reset_env(); dhcp_set_param_data(DHCP_HOSTNAME, param->hostname); dhcp_set_param_data(DHCP_VENDOR_ID, param->vendor_id); dhcp_set_param_data(DHCP_CLIENT_ID, param->client_id); dhcp_set_param_data(DHCP_USER_CLASS, param->user_class); dhcp_set_param_data(DHCP_CLIENT_UUID, param->client_uuid); if (!retries) retries = DHCP_DEFAULT_RETRY; dhcp_con = net_udp_new(0xffffffff, PORT_BOOTPS, dhcp_handler, NULL); if (IS_ERR(dhcp_con)) { ret = PTR_ERR(dhcp_con); goto out; } ret = net_udp_bind(dhcp_con, PORT_BOOTPC); if (ret) goto out1; net_set_ip(0); dhcp_start = get_time_ns(); ret = bootp_request(); /* Basically same as BOOTP */ if (ret) goto out1; while (dhcp_state != BOUND) { if (ctrlc()) { ret = -EINTR; goto out1; } if (!retries) { ret = -ETIMEDOUT; goto out1; } net_poll(); if (is_timeout(dhcp_start, 3 * SECOND)) { dhcp_start = get_time_ns(); printf("T "); ret = bootp_request(); /* no need to check if retries > 0 as we check if != 0 */ retries--; if (ret) goto out1; } } if (dhcp_tftpname[0] != 0) { IPaddr_t tftpserver = resolv(dhcp_tftpname); if (tftpserver) net_set_serverip(tftpserver); } out1: net_unregister(dhcp_con); out: if (ret) debug("dhcp failed: %s\n", strerror(-ret)); return ret; }
// return zero if command processed locally char *sim_input() { int i, n=0, k, key; char *cp = ibuf; char key_name[16]; if (!boot_time) boot_time = timer_ms(); // check for 5370 power loss (we may still be running via USB power) if (!(bus_read(RREG_LDACSR) & DSR_VOK)) { lprintf("5370 power loss\n"); usleep(1000000); while (!(bus_read(RREG_LDACSR) & DSR_VOK)) { sched_yield(); usleep(250000); } lprintf("5370 power on\n"); usleep(1000000); sys_reset = TRUE; return 0; } // can't recall any keys until self-test is finished if (self_test && boot_time && (time_diff(timer_ms(), boot_time) > SELF_TEST_DELAY)) { self_test = FALSE; } if (!self_test && !need_recall_file && !recall_active) { config_file_update(); } if (!self_test && need_recall_file) { sprintf(dbuf, "%s/.5370.%s.keys", ROOT_DIR, conf_profile); if ((kfp = fopen(dbuf, "r")) != NULL) { key_epoch = timer_ms(); key_threshold = rcl_key = 0; recall_active = TRUE; } else { printf("no key profile named \"%s\", will create one\n", conf_profile); } need_recall_file = FALSE; } if (recall_active && kfp && !self_test && kdelay(rcl_key * 256)) { if (fgets(dbuf, N_DBUF, kfp)) { if (sscanf(dbuf, "rcl key 0x%02x %16s", &key, key_name) == 2) { cp = "k-\n"; n=3; // virtual command to get key press thru code below rcl_key++; } } else { fclose(kfp); kfp = 0; recall_active = FALSE; } } #ifdef DEBUG #ifdef HPIB_SIM if (bug_stdev) { if (kdelay(0)) hpib_input("tr\n", 0); if (kdelay(500)) hpib_input("ta+0.05\n", 0); if (kdelay(1000)) find_bug(); } #endif if (bug_freq) { if (kdelay(0)) { cp = "k fn3\n"; n=6; } if (kdelay(500) && gate1) { cp = "k gt1\n"; n=6; } if (kdelay(500) && gate2) { cp = "k gt2\n"; n=6; } if (kdelay(500) && gate3) { cp = "k gt3\n"; n=6; } if (kdelay(500) && gate4) { cp = "k gt4\n"; n=6; } //if (kdelay(1000)) { cp = "t\n"; n=2; } //if (kdelay(1500)) { cp = "z\n"; n=2; } } #endif #ifdef HPIB_SIM // handle HPIB data over the network char *nb; i = net_poll(NET_HPIB, &nb); if (i) { if (strncmp(nb, "GET ", 4) == 0) { nb = dbuf; sprintf(nb, "attempted web connection on port %d, you want port %s instead\n", HPIB_TCP_PORT, WEBSERVER_PORT); printf("%s", nb); // nothing we tried could get message to show up in browser, unlike below //net_send(NET_HPIB, nb, strlen(nb), NO_COPY(TRUE), FLUSH(TRUE)); net_disconnect(NET_HPIB); } else { hpib_input(nb, i); } } #endif // handle keyboard commands over the network if (!n) { n = net_poll(NET_TELNET, &cp); if (n) { cp[n] = 0; if (strncmp(cp, "GET ", 4) == 0) { // this message will show up in browser due to net_send(NET_TELNET, ...) in lprintf() lprintf("attempted web connection on port %d, you want port %s instead\n", TELNET_TCP_PORT, WEBSERVER_PORT); net_disconnect(NET_TELNET); n = 0; } } } if (!n) { n = webserver_to_app(cp, N_IBUF-2); // N_IBUF-2: leave room for \n\0 if (n) { cp[n] = 0; if (cp[n-1] != '\n') { strcat(cp, "\n"); // make sure there is a trailing \n n++; } } } if (!n) { if (background_mode) return 0; n = read(tty, cp, N_IBUF); if (n >= 1) cp[n] = 0; } if (n >= 1) { if ((n == 1) || (*cp == '?') || (strcmp(cp, "help\n") == 0) || ((*cp == 'h') && (n == 2))) { printf("commands:\n" "d\t\tshow instrument display including unit and key LEDs\n" "h <HPIB cmd>\temulate HPIB command input, e.g. \"h md2\"\n" "h?\t\tprints reminder list of HPIB commands\n" "k <fn1 .. fn4>\temulate function key 1-4 press, e.g. \"k fn1\" is TI key\n" "k <gt1 .. gt4>\temulate gate time key 1-4 press\n" "k <st1 .. st8>\temulate statistics key 1-8 press\n" "k <ss1 .. ss5>\temulate sample size key 1-5 press\n" "k <m1 .. m6>\temulate \"misc\" key 1-6 press\n" "\t\t1 TI only, 2 +/- TI, 3 ext h.off, 4 per compl, 5 ext arm, 6 man rate\n" "m\t\trun measurement extension example code\n" "s\t\tshow measurement statistics\n" "rc\t\tshow values of count-chain registers (one sample)\n" "rcl|recall [name] load key settings from current or named profile\n" "sto|store name save key settings to named profile\n" "r\t\treset instrument\n" "q\t\tquit\n" "\n"); return 0; } if ((*cp == 'r') && (n == 2)) { dsp_7seg_str(DSP_LEFT, "reset", DSP_CLEAR); sys_reset = TRUE; return 0; } if (*cp == 'q') { printf("quit\n"); delay(1000); // let webserver show message exit(0); } // process command starting with '-' as args if (*cp == '-') { #define NARGS 16 int argc; char *argv[NARGS]; argc = 1 + split(cp, &argc, &argv[1], NARGS); sim_args(FALSE, argc, argv); hpib_args(FALSE, argc, argv); return 0; } if (*cp == 'm') { meas_extend_example(0); return 0; } // show what's on the 7 segment display, units display and key LEDs if (*cp == 'd') { dsp_7seg_translate(dbuf, 0); printf("display: %s\n", dbuf); dsp_key_leds_translate(dbuf); // which keys have their LEDs lit printf("keys: %s\n", dbuf); return 0; } // emulate a key press by causing an interrupt and returning the correct // scan code for the subsequent read of the RREG_KEY_SCAN register if (*cp == 'k') { k = 0; if (*(cp+1) == '-') { // key press from recall above k = -1; } else if (sscanf(cp, "k fn%d", &n) == 1) { // function keys 1..4 if (n >= 1 && n <= 4) k = skey_func[n-1]; } else if (sscanf(cp, "k gt%d", &n) == 1) { // gate time keys 1..4 if (n >= 1 && n <= 4) k = skey_gate[n-1]; } else if (sscanf(cp, "k st%d", &n) == 1) { // statistics keys 1..8 if (n >= 1 && n <= 8) k = skey_stat[n-1]; } else if (sscanf(cp, "k ss%d", &n) == 1) { // sample size keys 1..5 if (n >= 1 && n <= 5) k = skey_samp[n-1]; } else if (sscanf(cp, "k m%d", &n) == 1) { // misc keys 1..6 if (n >= 1 && n <= 6) k = skey_misc[n-1]; } else #if defined(DEBUG) || defined(NET_PRINTF) // for remote debugging of menu mode if (strcmp(cp, "k r\n") == 0) { k = RESET; } else if (strcmp(cp, "k rd\n") == 0) { k = RESET; reset_key_down = timer_ms(); } else if (strcmp(cp, "k d\n") == 0) { k = TI; } else if (strcmp(cp, "k u\n") == 0) { k = FREQ; } else #endif ; if (k > 0) { sim_key = KEY(k); sim_key_intr = 1; printf("key press: %s (%d 0x%02x)\n", front_pnl_led[k].name, n, sim_key); } else if (k == -1) { sim_key = key; sim_key_intr = 1; printf("recall: key 0x%02x %s\n", key, key_name); } else { cp[strlen(cp)-1] = 0; printf("bad key command: \"%s\"\n", cp); } num_meas = 0; return 0; } if (strcmp(cp, "rcl\n")==0 || strcmp(cp, "recall\n")==0) { printf("recall key settings from current profile \"%s\"\n", conf_profile); need_recall_file = TRUE; return 0; } if (sscanf(cp, "rcl %16s", conf_profile)==1 || sscanf(cp, "recall %16s", conf_profile)==1) { printf("recall key settings from profile \"%s\"\n", conf_profile); need_recall_file = TRUE; return 0; } if (strcmp(cp, "sto\n")==0 || strcmp(cp, "store\n")==0) { printf("usage: sto|store name\n"); return 0; } if (sscanf(cp, "store %16s", conf_profile)==1 || sscanf(cp, "sto %16s", conf_profile)==1) { printf("store key settings to profile \"%s\"\n", conf_profile); return 0; } // measure number of measurements-per-second if (*cp == 's' && n==2) { if (num_meas) { printf("%.1f meas/s\n", (float)num_meas / ((float)(timer_ms()-meas_time)/1000.0)); num_meas = meas_time = 0; } return 0; } #ifdef DEBUG if (*cp == 'r' && cp[1] == 'c' && n==3) { dump_regs = BIT_AREG(N0ST) | BIT_AREG(N1N2H) | BIT_AREG(N1N2L) | BIT_AREG(N0H) | BIT_AREG(N0L); return 0; } if (*cp == 'z') { //trace_regs ^= 1; //trace_iDump(1); hps ^= 1; return 0; } #endif #ifdef HPIB_SIM // emulate input of an HPIB command // e.g. "h md2" "h mr" "h md1" "h tb1" "h tb0" if (*cp == 'h' && cp[1] == ' ') { hpib_input(cp+2, 0); // presumes that hpib input is processed before another sim input num_meas = 0; return 0; } #endif if (*cp == 'h' && cp[1] == '?') { printf("HPIB command reminder list: (shown uppercase but may be typed as lowercase)\n" "function: FN1 TI, FN2 trig lvl, FN3 freq, FN4 period\n" "gate: GT1 single period, GT2 0.01s, GT3 0.1s, GT4 1s\n" "statistics: ST1 mean, ST2 std dev, ST3 min, ST4 max, ST5 dsp ref, ST6 clr ref, ST7 dsp evts, ST8 set ref, ST9 dsp all\n" "sample sizes: SS1 1, SS2 100, SS3 1k, SS4 10k, SS5 100k, SB <4 bytes> (set size for binary xfer)\n" "mode: MD1 front pnl, MD2 hold until \"MR\" cmd, MD3 fast (only if addressed), MD4 fast (wait until addressed)\n" "input: IN1 start+stop, IN2 stop only, IN3 start only, IN4 start+stop swap\n" "slope: SA1 start+, SA2 start-, S01 stop+, S02 stop-, SL slope local, SR slope remote\n" "arm select: AR1 +TI only, AR2 +/-TI\n" "ext arming: EA0 dis, EA1 ena, SE1 slope+, SE2 slope-, EH0 hold-off dis, EH1 hold-off ena\n" "int arming: IA1 auto, IA2 start ch arm, IA3 stop ch arm\n" "trigger: TL trig local, TR trig remote, TA <volts> start lvl, TO <volts> stop lvl\n" "binary mode: TB0 disable, TB1 enable, TB2 fast-mode enable (virtual cmd)\n" "other: MR man rate, MI man input, PC period compl, TE teach (store), LN learn (recall)\n" "\n"); return 0; } return cp; // pass to caller } else { return 0; } }
static int do_dhcp(int argc, char *argv[]) { int ret, opt; dhcp_reset_env(); while((opt = getopt(argc, argv, "H:v:c:u:U:")) > 0) { switch(opt) { case 'H': dhcp_set_param_data(DHCP_HOSTNAME, optarg); break; case 'v': dhcp_set_param_data(DHCP_VENDOR_ID, optarg); break; case 'c': dhcp_set_param_data(DHCP_CLIENT_ID, optarg); break; case 'u': dhcp_set_param_data(DHCP_CLIENT_UUID, optarg); break; case 'U': dhcp_set_param_data(DHCP_USER_CLASS, optarg); break; } } dhcp_con = net_udp_new(0xffffffff, PORT_BOOTPS, dhcp_handler, NULL); if (IS_ERR(dhcp_con)) { ret = PTR_ERR(dhcp_con); goto out; } ret = net_udp_bind(dhcp_con, PORT_BOOTPC); if (ret) goto out1; net_set_ip(0); dhcp_start = get_time_ns(); ret = bootp_request(); /* Basically same as BOOTP */ if (ret) goto out1; while (dhcp_state != BOUND) { if (ctrlc()) break; net_poll(); if (is_timeout(dhcp_start, 3 * SECOND)) { dhcp_start = get_time_ns(); printf("T "); ret = bootp_request(); if (ret) goto out1; } } out1: net_unregister(dhcp_con); out: if (ret) printf("dhcp failed: %s\n", strerror(-ret)); return ret ? 1 : 0; }
/* PXENV_UNDI_GET_MCAST_ADDRESS * * Status: working */ static PXENV_EXIT_t pxenv_undi_get_mcast_address ( struct s_PXENV_UNDI_GET_MCAST_ADDRESS *undi_get_mcast_address ) { struct ll_protocol *ll_protocol; struct in_addr ip = { .s_addr = undi_get_mcast_address->InetAddr }; int rc; /* Sanity check */ if ( ! pxe_netdev ) { DBGC ( &pxe_netdev, "PXENV_UNDI_GET_MCAST_ADDRESS called with " "no network device\n" ); undi_get_mcast_address->Status = PXENV_STATUS_UNDI_INVALID_STATE; return PXENV_EXIT_FAILURE; } DBGC ( &pxe_netdev, "PXENV_UNDI_GET_MCAST_ADDRESS %s", inet_ntoa ( ip ) ); /* Hash address using the network device's link-layer protocol */ ll_protocol = pxe_netdev->ll_protocol; if ( ( rc = ll_protocol->mc_hash ( AF_INET, &ip, undi_get_mcast_address->MediaAddr ))!=0){ DBGC ( &pxe_netdev, " failed: %s\n", strerror ( rc ) ); undi_get_mcast_address->Status = PXENV_STATUS ( rc ); return PXENV_EXIT_FAILURE; } DBGC ( &pxe_netdev, "=>%s\n", ll_protocol->ntoa ( undi_get_mcast_address->MediaAddr ) ); undi_get_mcast_address->Status = PXENV_STATUS_SUCCESS; return PXENV_EXIT_SUCCESS; } /* PXENV_UNDI_GET_NIC_TYPE * * Status: working */ static PXENV_EXIT_t pxenv_undi_get_nic_type ( struct s_PXENV_UNDI_GET_NIC_TYPE *undi_get_nic_type ) { struct device *dev; /* Sanity check */ if ( ! pxe_netdev ) { DBGC ( &pxe_netdev, "PXENV_UNDI_GET_NIC_TYPE called with " "no network device\n" ); undi_get_nic_type->Status = PXENV_STATUS_UNDI_INVALID_STATE; return PXENV_EXIT_FAILURE; } DBGC ( &pxe_netdev, "PXENV_UNDI_GET_NIC_TYPE" ); /* Fill in information */ memset ( &undi_get_nic_type->info, 0, sizeof ( undi_get_nic_type->info ) ); dev = pxe_netdev->dev; switch ( dev->desc.bus_type ) { case BUS_TYPE_PCI: { struct pci_nic_info *info = &undi_get_nic_type->info.pci; undi_get_nic_type->NicType = PCI_NIC; info->Vendor_ID = dev->desc.vendor; info->Dev_ID = dev->desc.device; info->Base_Class = PCI_BASE_CLASS ( dev->desc.class ); info->Sub_Class = PCI_SUB_CLASS ( dev->desc.class ); info->Prog_Intf = PCI_PROG_INTF ( dev->desc.class ); info->BusDevFunc = dev->desc.location; /* Earlier versions of the PXE specification do not * have the SubVendor_ID and SubDevice_ID fields. It * is possible that some NBPs will not provide space * for them, and so we must not fill them in. */ DBGC ( &pxe_netdev, " PCI %02x:%02x.%x %04x:%04x " "('%04x:%04x') %02x%02x%02x rev %02x\n", PCI_BUS ( info->BusDevFunc ), PCI_SLOT ( info->BusDevFunc ), PCI_FUNC ( info->BusDevFunc ), info->Vendor_ID, info->Dev_ID, info->SubVendor_ID, info->SubDevice_ID, info->Base_Class, info->Sub_Class, info->Prog_Intf, info->Rev ); break; } case BUS_TYPE_ISAPNP: { struct pnp_nic_info *info = &undi_get_nic_type->info.pnp; undi_get_nic_type->NicType = PnP_NIC; info->EISA_Dev_ID = ( ( dev->desc.vendor << 16 ) | dev->desc.device ); info->CardSelNum = dev->desc.location; /* Cheat: remaining fields are probably unnecessary, * and would require adding extra code to isapnp.c. */ DBGC ( &pxe_netdev, " ISAPnP CSN %04x %08x %02x%02x%02x\n", info->CardSelNum, info->EISA_Dev_ID, info->Base_Class, info->Sub_Class, info->Prog_Intf ); break; } default: DBGC ( &pxe_netdev, " failed: unknown bus type\n" ); undi_get_nic_type->Status = PXENV_STATUS_FAILURE; return PXENV_EXIT_FAILURE; } undi_get_nic_type->Status = PXENV_STATUS_SUCCESS; return PXENV_EXIT_SUCCESS; } /* PXENV_UNDI_GET_IFACE_INFO * * Status: working */ static PXENV_EXIT_t pxenv_undi_get_iface_info ( struct s_PXENV_UNDI_GET_IFACE_INFO *undi_get_iface_info ) { /* Sanity check */ if ( ! pxe_netdev ) { DBGC ( &pxe_netdev, "PXENV_UNDI_GET_IFACE_INFO called with " "no network device\n" ); undi_get_iface_info->Status = PXENV_STATUS_UNDI_INVALID_STATE; return PXENV_EXIT_FAILURE; } DBGC ( &pxe_netdev, "PXENV_UNDI_GET_IFACE_INFO" ); /* Just hand back some info, doesn't really matter what it is. * Most PXE stacks seem to take this approach. */ snprintf ( ( char * ) undi_get_iface_info->IfaceType, sizeof ( undi_get_iface_info->IfaceType ), "DIX+802.3" ); undi_get_iface_info->LinkSpeed = 10000000; /* 10 Mbps */ undi_get_iface_info->ServiceFlags = ( SUPPORTED_BROADCAST | SUPPORTED_MULTICAST | SUPPORTED_SET_STATION_ADDRESS | SUPPORTED_RESET | SUPPORTED_OPEN_CLOSE ); if ( netdev_irq_supported ( pxe_netdev ) ) undi_get_iface_info->ServiceFlags |= SUPPORTED_IRQ; memset ( undi_get_iface_info->Reserved, 0, sizeof(undi_get_iface_info->Reserved) ); DBGC ( &pxe_netdev, " %s %dbps flags %08x\n", undi_get_iface_info->IfaceType, undi_get_iface_info->LinkSpeed, undi_get_iface_info->ServiceFlags ); undi_get_iface_info->Status = PXENV_STATUS_SUCCESS; return PXENV_EXIT_SUCCESS; } /* PXENV_UNDI_GET_STATE * * Status: impossible due to opcode collision */ /* PXENV_UNDI_ISR * * Status: working */ static PXENV_EXIT_t pxenv_undi_isr ( struct s_PXENV_UNDI_ISR *undi_isr ) { struct io_buffer *iobuf; size_t len; struct ll_protocol *ll_protocol; const void *ll_dest; const void *ll_source; uint16_t net_proto; unsigned int flags; size_t ll_hlen; struct net_protocol *net_protocol; unsigned int prottype; int rc; /* Use a different debug colour, since UNDI ISR messages are * likely to be interspersed amongst other UNDI messages. */ /* Sanity check */ if ( ! pxe_netdev ) { DBGC ( &pxenv_undi_isr, "PXENV_UNDI_ISR called with " "no network device\n" ); undi_isr->Status = PXENV_STATUS_UNDI_INVALID_STATE; return PXENV_EXIT_FAILURE; } DBGC2 ( &pxenv_undi_isr, "PXENV_UNDI_ISR" ); /* Just in case some idiot actually looks at these fields when * we weren't meant to fill them in... */ undi_isr->BufferLength = 0; undi_isr->FrameLength = 0; undi_isr->FrameHeaderLength = 0; undi_isr->ProtType = 0; undi_isr->PktType = 0; switch ( undi_isr->FuncFlag ) { case PXENV_UNDI_ISR_IN_START : DBGC2 ( &pxenv_undi_isr, " START" ); /* Call poll(). This should acknowledge the device * interrupt and queue up any received packet. */ net_poll(); /* A 100% accurate determination of "OURS" vs "NOT * OURS" is difficult to achieve without invasive and * unpleasant changes to the driver model. We settle * for always returning "OURS" if interrupts are * currently enabled. * * Returning "NOT OURS" when interrupts are disabled * allows us to avoid a potential interrupt storm when * we are on a shared interrupt line; if we were to * always return "OURS" then the other device's ISR * may never be called. */ if ( netdev_irq_enabled ( pxe_netdev ) ) { DBGC2 ( &pxenv_undi_isr, " OURS" ); undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_OURS; } else { DBGC2 ( &pxenv_undi_isr, " NOT OURS" ); undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_NOT_OURS; } /* Disable interrupts */ netdev_irq ( pxe_netdev, 0 ); break; case PXENV_UNDI_ISR_IN_PROCESS : case PXENV_UNDI_ISR_IN_GET_NEXT : DBGC2 ( &pxenv_undi_isr, " %s", ( ( undi_isr->FuncFlag == PXENV_UNDI_ISR_IN_PROCESS ) ? "PROCESS" : "GET_NEXT" ) ); /* Some dumb NBPs (e.g. emBoot's winBoot/i) never call * PXENV_UNDI_ISR with FuncFlag=PXENV_UNDI_ISR_START; * they just sit in a tight polling loop merrily * violating the PXE spec with repeated calls to * PXENV_UNDI_ISR_IN_PROCESS. Force extra polls to * cope with these out-of-spec clients. */ net_poll(); /* If we have not yet marked a TX as complete, and the * netdev TX queue is empty, report the TX completion. */ if ( undi_tx_count && list_empty ( &pxe_netdev->tx_queue ) ) { DBGC2 ( &pxenv_undi_isr, " TXC" ); undi_tx_count--; undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_TRANSMIT; break; } /* Remove first packet from netdev RX queue */ iobuf = netdev_rx_dequeue ( pxe_netdev ); if ( ! iobuf ) { DBGC2 ( &pxenv_undi_isr, " DONE" ); /* No more packets remaining */ undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_DONE; /* Re-enable interrupts */ netdev_irq ( pxe_netdev, 1 ); break; } /* Copy packet to base memory buffer */ len = iob_len ( iobuf ); DBGC2 ( &pxenv_undi_isr, " RX" ); if ( len > sizeof ( basemem_packet ) ) { /* Should never happen */ DBGC2 ( &pxenv_undi_isr, " overlength (%zx)", len ); len = sizeof ( basemem_packet ); } memcpy ( basemem_packet, iobuf->data, len ); /* Strip link-layer header */ ll_protocol = pxe_netdev->ll_protocol; if ( ( rc = ll_protocol->pull ( pxe_netdev, iobuf, &ll_dest, &ll_source, &net_proto, &flags ) ) != 0 ) { /* Assume unknown net_proto and no ll_source */ net_proto = 0; ll_source = NULL; } ll_hlen = ( len - iob_len ( iobuf ) ); /* Determine network-layer protocol */ switch ( net_proto ) { case htons ( ETH_P_IP ): net_protocol = &ipv4_protocol; prottype = P_IP; break; case htons ( ETH_P_ARP ): net_protocol = &arp_protocol; prottype = P_ARP; break; case htons ( ETH_P_RARP ): net_protocol = &rarp_protocol; prottype = P_RARP; break; default: net_protocol = NULL; prottype = P_UNKNOWN; break; } /* Fill in UNDI_ISR structure */ undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_RECEIVE; undi_isr->BufferLength = len; undi_isr->FrameLength = len; undi_isr->FrameHeaderLength = ll_hlen; undi_isr->Frame.segment = rm_ds; undi_isr->Frame.offset = __from_data16 ( basemem_packet ); undi_isr->ProtType = prottype; if ( flags & LL_BROADCAST ) { undi_isr->PktType = P_BROADCAST; } else if ( flags & LL_MULTICAST ) { undi_isr->PktType = P_MULTICAST; } else { undi_isr->PktType = P_DIRECTED; } DBGC2 ( &pxenv_undi_isr, " %04x:%04x+%x(%x) %s hlen %d", undi_isr->Frame.segment, undi_isr->Frame.offset, undi_isr->BufferLength, undi_isr->FrameLength, ( net_protocol ? net_protocol->name : "RAW" ), undi_isr->FrameHeaderLength ); /* Free packet */ free_iob ( iobuf ); break; default : DBGC2 ( &pxenv_undi_isr, " INVALID(%04x)\n", undi_isr->FuncFlag ); /* Should never happen */ undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_DONE; undi_isr->Status = PXENV_STATUS_UNDI_INVALID_PARAMETER; return PXENV_EXIT_FAILURE; } DBGC2 ( &pxenv_undi_isr, "\n" ); undi_isr->Status = PXENV_STATUS_SUCCESS; return PXENV_EXIT_SUCCESS; } /** PXE UNDI API */ struct pxe_api_call pxe_undi_api[] __pxe_api_call = { PXE_API_CALL ( PXENV_UNDI_STARTUP, pxenv_undi_startup, struct s_PXENV_UNDI_STARTUP ), PXE_API_CALL ( PXENV_UNDI_CLEANUP, pxenv_undi_cleanup, struct s_PXENV_UNDI_CLEANUP ), PXE_API_CALL ( PXENV_UNDI_INITIALIZE, pxenv_undi_initialize, struct s_PXENV_UNDI_INITIALIZE ), PXE_API_CALL ( PXENV_UNDI_RESET_ADAPTER, pxenv_undi_reset_adapter, struct s_PXENV_UNDI_RESET ), PXE_API_CALL ( PXENV_UNDI_SHUTDOWN, pxenv_undi_shutdown, struct s_PXENV_UNDI_SHUTDOWN ), PXE_API_CALL ( PXENV_UNDI_OPEN, pxenv_undi_open, struct s_PXENV_UNDI_OPEN ), PXE_API_CALL ( PXENV_UNDI_CLOSE, pxenv_undi_close, struct s_PXENV_UNDI_CLOSE ), PXE_API_CALL ( PXENV_UNDI_TRANSMIT, pxenv_undi_transmit, struct s_PXENV_UNDI_TRANSMIT ), PXE_API_CALL ( PXENV_UNDI_SET_MCAST_ADDRESS, pxenv_undi_set_mcast_address, struct s_PXENV_UNDI_SET_MCAST_ADDRESS ), PXE_API_CALL ( PXENV_UNDI_SET_STATION_ADDRESS, pxenv_undi_set_station_address, struct s_PXENV_UNDI_SET_STATION_ADDRESS ), PXE_API_CALL ( PXENV_UNDI_SET_PACKET_FILTER, pxenv_undi_set_packet_filter, struct s_PXENV_UNDI_SET_PACKET_FILTER ), PXE_API_CALL ( PXENV_UNDI_GET_INFORMATION, pxenv_undi_get_information, struct s_PXENV_UNDI_GET_INFORMATION ), PXE_API_CALL ( PXENV_UNDI_GET_STATISTICS, pxenv_undi_get_statistics, struct s_PXENV_UNDI_GET_STATISTICS ), PXE_API_CALL ( PXENV_UNDI_CLEAR_STATISTICS, pxenv_undi_clear_statistics, struct s_PXENV_UNDI_CLEAR_STATISTICS ), PXE_API_CALL ( PXENV_UNDI_INITIATE_DIAGS, pxenv_undi_initiate_diags, struct s_PXENV_UNDI_INITIATE_DIAGS ), PXE_API_CALL ( PXENV_UNDI_FORCE_INTERRUPT, pxenv_undi_force_interrupt, struct s_PXENV_UNDI_FORCE_INTERRUPT ), PXE_API_CALL ( PXENV_UNDI_GET_MCAST_ADDRESS, pxenv_undi_get_mcast_address, struct s_PXENV_UNDI_GET_MCAST_ADDRESS ), PXE_API_CALL ( PXENV_UNDI_GET_NIC_TYPE, pxenv_undi_get_nic_type, struct s_PXENV_UNDI_GET_NIC_TYPE ), PXE_API_CALL ( PXENV_UNDI_GET_IFACE_INFO, pxenv_undi_get_iface_info, struct s_PXENV_UNDI_GET_IFACE_INFO ), PXE_API_CALL ( PXENV_UNDI_ISR, pxenv_undi_isr, struct s_PXENV_UNDI_ISR ), };
/* * rpc_req - synchronous RPC request */ static int rpc_req(struct nfs_priv *npriv, int rpc_prog, int rpc_proc, uint32_t *data, int datalen) { struct rpc_call pkt; unsigned long id; int dport; int ret; unsigned char *payload = net_udp_get_payload(npriv->con); int nfserr; int tries = 0; npriv->rpc_id++; id = npriv->rpc_id; pkt.id = htonl(id); pkt.type = htonl(MSG_CALL); pkt.rpcvers = htonl(2); /* use RPC version 2 */ pkt.prog = htonl(rpc_prog); pkt.vers = htonl(2); /* portmapper is version 2 */ pkt.proc = htonl(rpc_proc); memcpy(payload, &pkt, sizeof(pkt)); memcpy(payload + sizeof(pkt), data, datalen * sizeof(uint32_t)); if (rpc_prog == PROG_PORTMAP) dport = SUNRPC_PORT; else if (rpc_prog == PROG_MOUNT) dport = npriv->mount_port; else dport = npriv->nfs_port; npriv->con->udp->uh_dport = htons(dport); again: ret = net_udp_send(npriv->con, sizeof(pkt) + datalen * sizeof(uint32_t)); nfs_timer_start = get_time_ns(); nfs_state = STATE_START; nfs_packet = NULL; while (nfs_state != STATE_DONE) { if (ctrlc()) { ret = -EINTR; break; } net_poll(); if (is_timeout(nfs_timer_start, NFS_TIMEOUT)) { tries++; if (tries == NFS_MAX_RESEND) return -ETIMEDOUT; goto again; } ret = rpc_check_reply(nfs_packet, rpc_prog, npriv->rpc_id, &nfserr); if (!ret) { ret = nfserr; break; } } return ret; }
static int do_ping(int argc, char *argv[]) { int ret; uint64_t ping_start; unsigned retries = 0; if (argc < 2) return COMMAND_ERROR_USAGE; net_ping_ip = resolv(argv[1]); if (!net_ping_ip) { printf("unknown host %s\n", argv[1]); return 1; } ping_con = net_icmp_new(net_ping_ip, ping_handler, NULL); if (IS_ERR(ping_con)) { ret = PTR_ERR(ping_con); goto out; } ping_start = get_time_ns(); ret = ping_send(); if (ret) goto out_unreg; ping_state = PING_STATE_INIT; ping_sequence_number = 0; while (ping_state == PING_STATE_INIT) { if (ctrlc()) { ret = -EINTR; break; } net_poll(); if (is_timeout(ping_start, SECOND)) { /* No answer, send another packet */ ping_start = get_time_ns(); ret = ping_send(); if (ret) goto out_unreg; retries++; } if (retries > PKT_NUM_RETRIES) { ret = -ETIMEDOUT; goto out_unreg; } } if (!ret) printf("host %s is alive\n", argv[1]); out_unreg: net_unregister(ping_con); out: if (ret) printf("ping failed: %s\n", strerror(-ret)); return ping_state == PING_STATE_SUCCESS ? 0 : 1; }