Exemple #1
0
/**
 * \copydoc Detector::notify_action_command_pressed
 */
bool Chest::notify_action_command_pressed() {

  if (is_enabled() &&
      get_hero().is_free() &&
      get_keys_effect().get_action_key_effect() != KeysEffect::ACTION_KEY_NONE
  ) {

    if (can_open()) {
      Sound::play("chest_open");
      set_open(true);
      treasure_date = System::now() + 300;

      get_keys_effect().set_action_key_effect(KeysEffect::ACTION_KEY_NONE);
      get_hero().start_freezed();
    }
    else if (!get_cannot_open_dialog_id().empty()) {
      Sound::play("wrong");
      get_game().start_dialog(get_cannot_open_dialog_id(), ScopedLuaRef(), ScopedLuaRef());
    }

    return true;
  }

  return false;
}
Exemple #2
0
// somewhat over-elaborate constructor
// because errors related to image files can be such a pain to debug
Image::Image(Point xy, string s, Suffix::Encoding e)
    :w(0), h(0), fn(xy,"")
{
    add(xy);

    if (!can_open(s)) {    // can we open s?
        fn.set_label("cannot open \""+s+'\"');
        p = new Bad_image(30,20);    // the "error image"
        return;
    }

    if (e == Suffix::none) e = get_encoding(s);

    switch(e) {        // check if it is a known encoding
    case Suffix::jpg:
        p = new Fl_JPEG_Image(s.c_str());
        break;
    case Suffix::gif:
        p = new Fl_GIF_Image(s.c_str());
        break;
    default:    // Unsupported image encoding
        fn.set_label("unsupported file type \""+s+'\"');
        p = new Bad_image(30,20);    // the "error image"
    }
}
Exemple #3
0
/**
 * @brief Notifies this detector that the player is interacting with it by
 * pressing the action command.
 *
 * This function is called when the player presses the action command
 * while the hero is facing this detector, and the action command effect lets
 * him do this.
 * The hero opens the door if possible, otherwise a message is shown.
 */
void Door::notify_action_command_pressed() {

  if (get_hero().is_free() && is_closed()) {

    if (can_open()) {
      Sound::play("door_unlocked");
      Sound::play("door_open");

      if (is_saved()) {
        get_savegame().set_boolean(savegame_variable, true);
      }

      if (is_opening_condition_consumed()) {
        consume_opening_condition();
      }

      set_opening();

      get_hero().check_position();
    }
    else if (!cannot_open_dialog_id.empty()) {
      Sound::play("wrong");
      get_dialog_box().start_dialog(cannot_open_dialog_id);
    }
  }
}
Exemple #4
0
int main(int argc, char **argv)
{
	int fd;
        char *port = "/dev/can1";	// use "1" to "4" for steinhoff
        int opt;
	int status;
	db_id_t *pdb_id_list = NULL;
	db_clt_typ *pclt;              /* Database client pointer */
	char hostname[MAXHOSTNAMELEN+1];
	char *domain = DEFAULT_SERVICE; 
	int xport = COMM_OS_XPORT;	
	int count = 0;
	
        while ((opt = getopt(argc, argv, "p:")) != -1) {
                switch (opt) {
                case 'p':
                        port = strdup(optarg);
                        break;
                default:
                        printf("Usage: %s -p <port>\n", argv[0]);
                        exit(1);
                }
        }

	fd = can_open(port, O_RDONLY);

	if (fd == -1)
		exit(EXIT_FAILURE);	// error message printed by can_open 

	printf("program %s, device name %s, fd: %d\n", argv[0], port, fd);
	fflush(stdout);

	pdb_id_list = get_db_id_list();
	get_local_name(hostname, MAXHOSTNAMELEN);

	// Log in to the data server and create variables for all VAA messages
	if ((pclt = db_list_init( argv[0], hostname, domain, xport, 
			pdb_id_list, num_vaa_msg_ids, NULL, 0)) == NULL) {
		printf("Database initialization error in %s.\n", argv[0]);
		exit(EXIT_FAILURE);
	}
	
        if(setjmp(exit_env) != 0) {
		printf("Successfully wrote %d messages to data server\n",
				count);
		if (fd != -1)
			status = can_close(&fd);
		if (status != -1)			
			exit(EXIT_SUCCESS);
		else
			exit(EXIT_FAILURE);	// can_close prints error info
        } else
		sig_ign(sig_list, sig_hand);

	for(;;) {
		int retval;
		retval = rcv_g(pclt, fd, (void *) &vaa_msg[0]);
		count += retval;
	}
}
Exemple #5
0
int aversive_open(aversive_dev_t* dev)
{
#if CONFIG_USE_I2C

  if (i2c_open(&dev->i2c_dev, 0) == -1)
  {
    DEBUG_ERROR("i2c_open\n");
    return -1;
  }

#elif CONFIG_USE_CAN

  dev->can_dev = can_open();
  if (dev->can_dev == 0)
  {
    DEBUG_ERROR("can_open\n");
    return -1;
  }

#endif /* CONFIG_USE_XXX */

#if (CONFIG_DO_ADC == 0)
#if (CONFIG_DO_KEYVAL == 0)

  /* send the following to initialize aversive
   */

  aversive_sync_sequence(dev);
  aversive_stop(dev);
  aversive_set_asserv(dev, 0);
  aversive_set_power(dev, 0);
  aversive_set_pos(dev, 0, 0, 0);
  aversive_set_power(dev, 1);
  aversive_set_asserv(dev, 1);
  aversive_set_blocking_params(dev, 5, 300, 8000);
  aversive_set_blocking_params2(dev, 150, 150);

#endif /* CONFIG_DO_KEYVAL == 0 */
#endif /* CONFIG_DO_ADC == 0 */

  return 0;
}
Exemple #6
0
bool
AudioProcessor::open(Speakers new_spk)
{
  if (!can_open(new_spk)) 
  {
    close();
    return false;
  }

  in_spk = new_spk;
  if (!rebuild_chain())
  {
    close();
    return false;
  }

  rebuild = false;
  new_stream_state = no_new_stream;
  return true;
}
Exemple #7
0
/**
 * @brief Notifies this detector that a collision was just detected with another entity.
 *
 * This function is called by the engine when there is a collision with another entity.
 *
 * @param entity_overlapping the entity overlapping the detector
 * @param collision_mode the collision mode that detected the collision
 */
void Door::notify_collision(MapEntity& entity_overlapping, CollisionMode collision_mode) {

  if (is_closed() && entity_overlapping.is_hero()) {

    Hero& hero = static_cast<Hero&>(entity_overlapping);

    if (get_keys_effect().get_action_key_effect() == KeysEffect::ACTION_KEY_NONE
        && hero.is_free()) {

      if (can_open()) {
        // The action command opens the door.
        get_keys_effect().set_action_key_effect(KeysEffect::ACTION_KEY_OPEN);
      }
      else if (!get_cannot_open_dialog_id().empty()) {
        // The action command shows a dialog.
        get_keys_effect().set_action_key_effect(KeysEffect::ACTION_KEY_LOOK);
      }
    }
  }
}
Exemple #8
0
Speakers 
AudioProcessor::user2output(Speakers in_spk_, Speakers user_spk_) const
{
  if (!can_open(in_spk_) || !query_user(user_spk_))
    return spk_unknown;

  Speakers result = in_spk_;
  if (user_spk_.format != FORMAT_UNKNOWN)
  {
    result.format = user_spk_.format;
    result.level = user_spk_.level;
  }

  if (user_spk_.mask)
    result.mask = user_spk_.mask;

  if (user_spk_.sample_rate)
    result.sample_rate = user_spk_.sample_rate;

  result.relation = user_spk_.relation;

  return result;
}
Exemple #9
0
/////////////////////////////////////////////////////////////////////////////////////////
// Open a CAN data channel
bool OpenCAN()
{
	int ret;
	
#if defined(PeakCAN)
	CAN_Ch[0] = getPCANChannelIndex("PCAN_PCIBUS1");
	CAN_Ch[1] = getPCANChannelIndex("PCAN_PCIBUS2");
	CAN_Ch[2] = getPCANChannelIndex("PCAN_PCIBUS3");
	CAN_Ch[3] = getPCANChannelIndex("PCAN_PCIBUS4");
#elif defined(IXXATCAN) || defined(SOFTINGCAN)
	CAN_Ch[0] = 1;
	CAN_Ch[1] = 2;
	CAN_Ch[2] = 3;
	CAN_Ch[3] = 4;
#else defined(NICAN) || defined(ESDCAN)
	CAN_Ch[0] = 0;
	CAN_Ch[1] = 1;
	CAN_Ch[2] = 2;
	CAN_Ch[3] = 3;
#endif

	for (int ch = 0; ch < CAN_Ch_COUNT; ch++) {
		if (!CAN_Ch_Enabled[ch]) continue;
		printf(">CAN(%d): open\n", CAN_Ch[ch]);
		ret = can_open(CAN_Ch[ch]);
		if(ret < 0)
		{
			printf("ERROR command_canopen !!! \n");
			return false;
		}
	}

	//StartCANListenThread();

	return true;
}
int main(int argc, char* argv[])
{
    int i = 0;
    struct timespec timedelay;
    int fd = -1;
    char* port = "/dev/can1";
    uint8_t extended = 0;
    int nmax = 0;
    int opt = 0;
    int verbose = 0;

    /*
    db_clt_typ *pclt;
    char hostname[MAXHOSTNAMELEN+1];
    char *domain = DEFAULT_SERVICE;
    int xport = COMM_OS_XPORT;
    */

    msg_type messages[6]; // 6 types of messages to be sent
    int num_msg = sizeof(messages) / sizeof(messages[0]);

    // initialize the messages
    memset(messages, 0, sizeof(messages));
    messages[0].id = 0;
    messages[0].frequency = 1;
    messages[1].id = 1;
    messages[1].frequency = 40;
    messages[2].id = 2;
    messages[2].frequency = 40;
    messages[3].id = 3;
    messages[3].frequency = 40;
    messages[4].id = 4;
    messages[4].frequency = 500;
    messages[5].id = 5;
    messages[5].frequency = 20;

    for (i = 0; i < num_msg; i++)
    {
	messages[i].count = 1;  // have them all send only 1 for now
	messages[i].period = 1.0 / messages[i].frequency;
    }

    // parse the command-line args
    while ((opt = getopt(argc, argv, "e:n:p:v:z")) != -1)
    {
	printf ("opt = %d\n", opt);
	switch (opt)
	{
	case 'e':
	    extended = 1;
	    break;
	case 'n':
	    nmax = atoi(optarg);
	    break;
	case 'p':
	    port = strdup(optarg);
	    break;
	case 'v':
	    verbose = 1;
	    break;
	}
    }

    // initialize the timedelay structure
    timedelay.tv_sec = 0;
    timedelay.tv_nsec = 10000000;   /* 10 millsecs */

    // open can port
    printf("sensor_simulator: trying to open %s\n", port); 
    fflush(stdout);
    
    fd = can_open(port, O_WRONLY);
    if (fd == -1 || fd == 0)
    {
	fprintf (stderr, "error opening %s\n", port);
	exit(EXIT_FAILURE);
    }
    printf ("can port opened. fd = %d\n", fd);

    // open database
    /*
    get_local_name(hostname, MAXHOSTNAMELEN);
    if ((pclt = db_list_init(argv[0], hostname, domain, xport,
			     NULL, 0, NULL, 0)) == NULL)
    {
	printf("Database initialization error in %s.\n", argv[0]);
	exit(EXIT_FAILURE);
    }
    */

    // keep on sending data until someone decides to press ctrl+C
    for (;;) 
    {
	unsigned now_ms;
	struct timespec timeread;

	clock_gettime(CLOCK_REALTIME, &timeread);
	now_ms = timeread.tv_sec * 1000 + timeread.tv_nsec / 1000000;

	for (i = 0; i < num_msg; ++i)
	{
	    // see how long it has been since that message was last sent
	    unsigned long diff = now_ms - messages[i].last_sent;
	    int j = 0;

	    // if not longer than the period, move on
	    if (diff < messages[i].period)
		continue;

	    for (j = 0; j < messages[i].count; j++)
	    {
		can_write(fd, messages[i].id, 0, &messages[i].data, 8);

//		snd_g(pclt, fd, 0, (void*)&vaa_msg_funcs[messages[i].id+1]);
		  
		messages[i].data++;
	    }

	    messages[i].last_sent = now_ms;
	}

	// sleep for 10 ms to avoid using all the cpu
//	nanosleep(&timedelay, NULL);
    }
    
    return 0;
}
Exemple #11
0
int main(int argc, char **argv)
{
	int size;
	int fd;
	unsigned long id;  
	unsigned char data[8];
        char *port = "/dev/can1";	// use "1" to "4" for steinhoff
        int opt;
	int status;
	int read_err = 0;
	int verbose = 0;
	int msg_count = 0;

        while ((opt = getopt(argc, argv, "p:v")) != -1) {
                switch (opt) {
                  case 'p':
                        port = strdup(optarg);
                        break;
                  case 'v':
                        verbose = 1; 
                        break;

                  default:
                        printf("Usage: %s -p <port>\n", argv[0]);
                        exit(1);
                }
        }

	printf("can_rx: trying to open %s\n", port); 
	fflush(stdout);

	fd = can_open(port, O_RDONLY);

	if (fd == -1)
		exit(EXIT_FAILURE);	// error message printed by can_open 

	printf("program %s, device name %s, fd: %d\n", argv[0], port, fd);
	fflush(stdout);

        if(setjmp(exit_env) != 0) {
		printf("%d messages, %d read errors\n", msg_count, read_err);
		if (fd != -1)
			status = can_close(&fd);
		if (status != -1)			
			exit(EXIT_SUCCESS);
		else
			exit(EXIT_FAILURE);	// can_close prints error info
        } else
		sig_ign(sig_list, sig_hand);

	for(;;) {
		int i;
		id = 0;		
		size = can_read(fd,&id,(char *)NULL,data,8);
		if (size < 0) 
			read_err++;	
		else {
			msg_count++;
			if (verbose) {
				printf(" %5lu ", id);		
				printf(" %u ", size);		
				for (i = 0; i < size; i++)
					printf("%03hhu ",data[i]);
				printf("\n");
				fflush(stdout);
			}
		}
	}
}
Exemple #12
0
/*
 * save_copy() - Append a copy of the message contained in "filename" to
 * the file specified by "copy_file".  This routine simply gets all of
 * the filenames right, and then invokes "save_mssg()" to do
 * the dirty work.
 */
int save_copy(const char *fname_dest, const char *fname_mssg,
	      const SEND_HEADER *shdr, int form)
{
	char  buffer[SLEN],	/* read buffer 		       */
	      savename[SLEN],	/* name of file saving into    */
	      msg_buffer[SLEN];
	char *return_alias;
	int is_ordinary_file;
	int  err;

	/* presume fname_dest is okay as is for now */
	strcpy(savename, fname_dest);

	/* if save_by_name or save_by_alias wanted */
	if((strcmp(fname_dest, "=") == 0)  || (strcmp(fname_dest, "=?") == 0)) {
	    if ((save_by_alias &&
		   (return_alias = address_to_alias(shdr->expanded_to)) != NULL))
		strcpy(buffer, return_alias);
	    else
	        if (save_by_name)
	          get_return_name(shdr->expanded_to, buffer, TRUE);
	        else
	      	  get_return_name(shdr->to, buffer, TRUE);

	  if (strlen(buffer) == 0) {

	    /* can't get file name from 'to' -- use sent_mail instead */
	    dprint(3, (debugfile,
		"Warning: get_return_name couldn't break down %s\n", shdr->to));
	    show_error(catgets(elm_msg_cat, ElmSet, ElmCannotDetermineToName,
"Cannot determine `to' name to save by! Saving to \"sent\" folder %s instead."),
	      sent_mail);
	    strcpy(savename, "<");
	    if (sleepmsg > 0)
		sleep(sleepmsg);
	  } else
	    sprintf(savename, "=%s", buffer);		/* good! */
	}

	expand_filename(savename);

	/*
	 *  If saving conditionally by logname but folder doesn't
	 *  exist save to sent folder instead.
	 */
	if((strcmp(fname_dest, "=?") == 0)
	      && (access(savename, WRITE_ACCESS) != 0)) {
	  dprint(5, (debugfile,
	    "Conditional save by name: file %s doesn't exist - using \"<\".\n",
	    savename));
	  strcpy(savename, "<");
	  expand_filename(savename);
	}

	/*
	 *  Allow options
	 *  confirm_files, confirm_folders,
	 *  confirm_append and confirm_create
	 *  to control where the actual copy
	 *  should be saved.
	 */
	is_ordinary_file = strncmp (savename, folders, strlen(folders));

        if (elm_access(savename, ACCESS_EXISTS)== 0) {	/* already there!! */
	    if (confirm_append || (confirm_files && is_ordinary_file)) {
		/*
		 *  OK in batch mode it may be impossible
		 *  to ask the user to confirm. So we have
		 *  to use sent_mail anyway.
		 */
		if (!OPMODE_IS_INTERACTIVE(opmode)) {
		    strcpy(savename, sent_mail);
		}
		else {
		    if (is_ordinary_file)
		      sprintf(msg_buffer, catgets(elm_msg_cat, ElmSet,
			  ElmConfirmFilesAppend,
			  "Append to an existing file `%s'?"), savename);
		    else
		      sprintf(msg_buffer, catgets(elm_msg_cat, ElmSet,
			  ElmConfirmFolderAppend,
			  "Append to mail folder `%s'?"), savename);

		    /* FOO - does this really need to be "clear-and-center" ? */
		    if (!enter_yn(msg_buffer, FALSE, LINES-2, TRUE)) {
			strcpy(savename, sent_mail);
			PutLine(LINES-2, 0, catgets(elm_msg_cat, ElmSet,
				  ElmSavingToInstead,
				  "Alright - saving to `%s' instead"),
				  savename);
			FlushOutput();
			if (sleepmsg > 0)
				sleep(sleepmsg);
			ClearLine (LINES-2);
		    }
		}
	    }
	}
        else {
            if (confirm_create || (confirm_folders && !is_ordinary_file)) {
		/*
		 *  OK in batch mode it may be impossible
		 *  to ask the user to confirm. So we have
		 *  to use sent_mail anyway.
		 */
		if (!OPMODE_IS_INTERACTIVE(opmode)) {
		    strcpy(savename, sent_mail);
		}
		else {
		    if (is_ordinary_file)
		      sprintf(msg_buffer, catgets(elm_msg_cat, ElmSet,
			  ElmConfirmFilesCreate,
			  "Create a new file `%s'?"), savename);
		    else
		      sprintf(msg_buffer, catgets(elm_msg_cat, ElmSet,
			  ElmConfirmFolderCreate,
			  "Create a new mail folder `%s'?"), savename);

		    /* FOO - does this really need to be "clear-and-center" ? */
		    if (!enter_yn(msg_buffer, FALSE, LINES-2, TRUE)) {
			strcpy(savename, sent_mail);
			PutLine(LINES-2, 0, catgets(elm_msg_cat, ElmSet,
				  ElmSavingToInstead,
				  "Alright - saving to `%s' instead"),
				  savename);
			FlushOutput();
			if (sleepmsg > 0)
				sleep(sleepmsg);
			ClearLine (LINES-2);
		    }
		}
	    }
	}

	if ((err = can_open(savename, "a"))) {
	  dprint(2, (debugfile,
	  "Error: attempt to autosave to a file that can't be appended to!\n"));
	  dprint(2, (debugfile, "\tfilename = \"%s\"\n", savename));
	  dprint(2, (debugfile, "** %s **\n", strerror(err)));

	  /* Lets try sent_mail before giving up */
	  if(strcmp(sent_mail, savename) == 0) {
	    /* we are ALREADY using sent_mail! */
	    show_error(catgets(elm_msg_cat, ElmSet, ElmCannotSaveTo,
			"Cannot save to %s!"), savename);
	    return(FALSE);
	  }

	  if ((err = can_open(sent_mail, "a"))) {
	    dprint(2, (debugfile,
	  "Error: attempt to autosave to a file that can't be appended to!\n"));
	    dprint(2, (debugfile, "\tfilename = \"%s\"\n", sent_mail));
	    dprint(2, (debugfile, "** %s **\n", strerror(err)));
	    show_error(catgets(elm_msg_cat, ElmSet, ElmCannotSaveToNorSent,
		    "Cannot save to %s nor to \"sent\" folder %s!"),
		    savename, sent_mail);
	    return(FALSE);
	  }
	  show_error(catgets(elm_msg_cat, ElmSet, ElmCannotSaveToSavingInstead,
		"Cannot save to %s! Saving to \"sent\" folder %s instead."),
	        savename, sent_mail);
	  if (sleepmsg > 0)
		sleep(sleepmsg);
	  strcpy(savename, sent_mail);
	}

	return save_mssg(savename, fname_mssg, shdr, form);
}
int main(int argc, char **argv)
{
	int size;
	int fd;
	unsigned long id;  
	unsigned char data[8];
        char *port = "/dev/can1";	/// use "1" to "4" for steinhoff
        int opt;
	int status;
	int read_err = 0;
	int msg_count = 0;
	timestamp_t start_ts, end_ts, diff_ts; /// report start and end times
	can_err_count_t errs;

        while ((opt = getopt(argc, argv, "p:")) != -1) {
                switch (opt) {
                  case 'p':
                        port = strdup(optarg);
                        break;
                  default:
                        printf("Usage: %s -p <port>\n", argv[0]);
                        exit(1);
                }
        }

	fd = can_open(port, O_RDONLY);

	if (fd == -1)
		exit(EXIT_FAILURE);	// error message printed by can_open 

	// Save starting time
	get_current_timestamp(&start_ts);

        if(setjmp(exit_env) != 0) {
		unsigned int i;
		get_current_timestamp(&end_ts);
		print_timestamp(stdout, &start_ts);
		printf(" ");
		print_timestamp(stdout, &end_ts);
		printf(" ");
		decrement_timestamp(&end_ts, &start_ts, &diff_ts);
		print_timestamp(stdout, &diff_ts); 	
		printf("\n");

		errs = can_get_errs(fd);

		if (read_err > 0)
			printf(" %d client read errors\n", read_err);

		printf("Error counts  at finish:\n");
		printf("intr_in_handler_count %u\n", errs.intr_in_handler_count);
		printf("rx_interrupt_count %u\n", errs.rx_interrupt_count);
		printf("rx_message_lost_count %u\n", errs.rx_message_lost_count);
		printf("tx_interrupt_count %u\n", errs.tx_interrupt_count);
		printf("shadow_buffer_count %u\n", errs.shadow_buffer_count);

		if (fd != -1)
			status = can_close(&fd);

		for (i = 0; i < msg_count; i++) { 
			save_data_t *p = &saved_data[i];
			printf("%u ", i);
			printf("%hhu ", p->can_id); 
			printf("%hd ", p->longitudinal);
			printf("%hd ", p->vertical);
			printf("%hd ", p->lateral);
			printf("%hhu ", p->thread_counter); 
			printf("%hhu ",	p->sensor_group_counter); 
			printf("\n");
		}

		if (status != -1)			
			exit(EXIT_SUCCESS);
		else
			exit(EXIT_FAILURE);	// can_close prints error info
        } else
		sig_ign(sig_list, sig_hand);

	/// Clear error counts in driver
	errs =  can_clear_errs(fd);

	printf("Error counts at start:\n");
	printf("intr_in_handler_count %u\n", errs.intr_in_handler_count);
	printf("rx_interrupt_count %u\n", errs.rx_interrupt_count);
	printf("rx_message_lost_count %u\n", errs.rx_message_lost_count);
	printf("tx_interrupt_count %u\n", errs.tx_interrupt_count);
	printf("shadow_buffer_count %u\n", errs.shadow_buffer_count);

	for(;;) {
		id = 0;		
		size = can_read(fd,&id,(char *)NULL,data,8);

		if (size < 0) 
			read_err++;	
		else {
			saved_data[msg_count].can_id = id;
			saved_data[msg_count].longitudinal = 
				(*(short *) &data[2]);
			saved_data[msg_count].vertical = 
				(*(short *) &data[0]);
			saved_data[msg_count].lateral = 
				(*(short *) &data[6]);
			saved_data[msg_count].sensor_group_counter = 
				 data[4];
			saved_data[msg_count].thread_counter = 
				 data[5];
		}
		msg_count++;
		if (msg_count >= max_count)
			longjmp(exit_env, 1);
	}
}
int main(int argc, char* argv[])
{
    int i = 0;
    msg_type messages[4];
    unsigned num_msg = sizeof(messages) / sizeof(messages[0]);
    struct timespec timeread;
    struct timespec timedelay;
    int fd = -1;
    char* port = "/dev/can1";
    char line[1024];
    char* read = NULL;
    int linenum = 0;
    uint8_t extended = 0;
    int nmax = 0;
    int opt = 0;
    int verbose = 0;

    // parse the command-line args
    while ((opt = getopt(argc, argv, "e:n:p:v:z")) != -1)
    {
	printf ("opt = %d\n", opt);
	switch (opt)
	{
	case 'e':
	    extended = 1;
	    break;
	case 'n':
	    nmax = atoi(optarg);
	    break;
	case 'p':
	    port = strdup(optarg);
	    break;
	case 'v':
	    verbose = 1;
	    break;
	}
    }

    memset(messages, 0, sizeof(messages));
    for (i = 0; i < num_msg; ++i)
    {
	messages[i].frequency = i * 10 + 10; // 10Hz, 20Hz, 30Hz, etc...
	messages[i].period = 1000 / messages[i].frequency;
    }

    // read 10 lines of messages from stdin
    read = fgets(line, sizeof(line), stdin);
    while ((int)read != EOF && read != NULL)
    {
	char* token = strtok(line, " \t");
	int num_msg_incoming = atoi(token);
	int id;

	// check number of messages matches the number we can store
	if (num_msg_incoming != num_msg)
	{
	    fprintf(stderr, "number of messages don't match: %d, %d\n",
		    num_msg_incoming, num_msg);
	    continue;
	}

	
	for (i = 0; i < num_msg_incoming; i++)
	{
	    msg_descriptor_t* p = NULL;
	    uint64_t msg_raw = 0;
	    
	    token = strtok(NULL, " \t");
	    id = atoi(token);
	    p = &msg_descriptors[id / 100 - 1];

	    if (messages[i].id != p->identifier)
	    {
		if (messages[i].id == 0)
		    messages[i].id = p->identifier;
		else
		{
		    fprintf(stderr, "identifers don't match.");
		    continue;
		}
	    }

	    msg_raw = parse_msg_input(p, NULL, NULL);
	    messages[i].data[linenum] = msg_raw;

	    if (verbose)
	    {
		printf ("msg parsed: ");
		print_data(msg_raw);
		putchar('\n');
	    }
	}

	linenum++;
	read = fgets(line, sizeof(line), stdin);
    }

    puts("input data correctly parsed.");

    // initialize the timedelay structure
    timedelay.tv_sec = 0;
    timedelay.tv_nsec = 10000000;   /* 10 millsecs */

    // open can port
    fd = can_open(port, O_WRONLY);
    if (fd == -1)
    {
	fprintf (stderr, "error opening %s\n", port);
	exit(1);
    }
    printf ("can port opened. fd = %d\n", fd);

    // keep on sending data until someone decides to press ctrl+C
    for (;;) 
    {
	unsigned now_ms;

	clock_gettime(CLOCK_REALTIME, &timeread);
	now_ms = timeread.tv_sec * 1000 + timeread.tv_nsec / 1000000;

	for (i = 0; i < num_msg; ++i)
	{
	    // see how long it has been since that message was last sent
	    unsigned long diff = now_ms - messages[i].lastsent;

	    // if longer than period, send again
	    if (diff >= messages[i].period)
	    {
		int rand_msg = rand() % 10;
		can_write(fd, 
			  messages[i].id, 
			  0, 
			  &messages[i].data[rand_msg], // pick random
			  8);
		
		if (verbose)
		{
		    printf ("msg sent: i=%d, id=%d, msg_index=%d, data= ",
			    i, messages[i].id,
			    rand_msg);
		    print_data(messages[i].data[rand_msg]);
		    putchar('\n');
		}
		    

		messages[i].lastsent = now_ms;
	    }
	}

	// sleep for 10 ms to avoid using all the cpu
//	nanosleep(&timedelay, NULL);
    }
    
    return 0;
}