Example #1
0
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;
}
Example #2
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");
}
Example #3
0
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;
}
Example #4
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;
}
Example #5
0
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;
}
Example #6
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;
}
Example #7
0
File: core.c Project: Learath2/sBNC
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;
}
Example #8
0
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;
}
Example #9
0
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;
}
Example #10
0
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;
}
Example #11
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;
}
Example #12
0
/* 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;
    }
  }
Example #14
0
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);
}
Example #15
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;
}
Example #16
0
File: main.c Project: kmeaw/bootos
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;
      }
    }
  }
Example #18
0
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;
}
Example #19
0
// 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;
	}
}
Example #20
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;
}
Example #21
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 ),
};
Example #22
0
/*
 * 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;
}
Example #23
0
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;
}