Пример #1
0
/**
  \fn uint8_t i2c_request(uint8_t slaveAddr, uint8_t numRx, uint8_t *bufRx)
   
  \brief request data via I2C as master

  \param[in]  slaveAddr   7b address [6:0] of I2C slave
  \param[in]  numRx       number of bytes to receive
  \param[out] bufRx       receive buffer

  \return operation successful?

  request data from I2C slave with a 5ms frame timeout. Note that no start or stop condition is generated.
  
*/
uint8_t i2c_request(uint8_t slaveAddr, uint8_t numRx, uint8_t *bufRx) {

  uint8_t      i;
  
  // init receive buffer
  for (i=0; i<numRx; i++)
    bufRx[i] = 0;
    
  // start overall timeout
  start_timeout_ms(5);                                        

  // send 7b slave adress [7:1] + read flag (LSB=1)
  I2C.DR.byte = (uint8_t) ((slaveAddr << 1) | 0x01);        // shift left and set LSB (write=0, read=1)
  while ((!I2C.SR1.reg.ADDR) && (!check_timeout()));     // wait until adress sent or timeout
  while ((!I2C.SR3.reg.BUSY) && (!check_timeout()));     // seems to be required...???

  // receive data from slave
  for (i=0; i<numRx; i++) {
    while ((!I2C.SR1.reg.RXNE) && (!check_timeout()));   // wait until DR buffer not empty or timeout
    bufRx[i] = I2C.DR.byte;
  }
 
  // on I2C timeout set error flag
  if (check_timeout()) {
    stop_timeout_ms();
    return(ERROR_TIMOUT);
  }

  // reset timeout timer
  stop_timeout_ms(); 

  return(SUCCESS);
 
} // i2c_request
Пример #2
0
/**
  \fn uint8_t i2c_send(uint8_t addr, uint8_t numTx, uint8_t *bufTx)
   
  \brief write data via I2C

  \param[in]  addr        7b address [6:0] of I2C slave
  \param[in]  numTx       number of bytes to send
  \param[in]  bufTx       send buffer

  \return operation successful?

  write data via I2C with 5ms frame timeout. Note that no start or 
  stop condition is generated.
  
*/
uint8_t i2c_send(uint8_t addr, uint8_t numTx, uint8_t *bufTx) {

  uint8_t    i;
  
  // start overall timeout
  start_timeout_ms(5);                                        

  // send 7b slave adress [7:1] + write flag (LSB=0)
  I2C.DR.byte = (uint8_t) ((addr << 1) & ~0x01);                 // shift left and set LSB (write=0, read=1)
  while ((!I2C.SR1.reg.ADDR) && (!check_timeout()));     // wait until address sent or timeout
  while ((!I2C.SR3.reg.BUSY) && (!check_timeout()));     // seems to be required...???
  
  // send data
  if (!check_timeout()) {
    
    for (i=0; i<numTx; i++) {
      I2C.DR.byte = bufTx[i];
      while ((!I2C.SR1.reg.TXE) && (!check_timeout()));    // wait until DR buffer empty or timeout
    }
    
  }
 
  // on I2C timeout set error flag
  if (check_timeout()) {
    stop_timeout_ms();
    return(ERROR_TIMOUT);
  }

  // reset timeout timer
  stop_timeout_ms(); 

  return(SUCCESS);

} // i2c_send
Пример #3
0
int check_battery_li()/*1 ÊÇ﮵ç³Ø 0ÊÇÊÊÅäÆ÷*/
{
	 I2C_GenerateSTART(I2C2, ENABLE);

	 if(!check_timeout(I2C_EVENT_MASTER_MODE_SELECT)) return 0;  

	 I2C_Send7bitAddress(I2C2, 0x0B<<1, I2C_Direction_Transmitter);
	 if(!check_timeout(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) return 0;  

	 I2C_GenerateSTOP(I2C2, ENABLE);
	 return 1;
}
Пример #4
0
zchar os_read_key (int timeout, bool show_cursor)
{
  char c;
  int timed_out;

  /* Discard any keys read for line input.  */
  read_line_buffer[0] = '\0';

  if (read_key_buffer[0] == '\0') {
    timed_out = dumb_read_line(read_key_buffer, NULL, show_cursor, timeout,
			       INPUT_CHAR, NULL);
    /* An empty input line is reported as a single CR.
     * If there's anything else in the line, we report only the line's
     * contents and not the terminating CR.  */
    if (strlen(read_key_buffer) > 1)
      read_key_buffer[strlen(read_key_buffer) - 1] = '\0';
  } else
    timed_out = check_timeout(timeout);
    
  if (timed_out)
    return ZC_TIME_OUT;

  c = read_key_buffer[0];
  memmove(read_key_buffer, read_key_buffer + 1, strlen(read_key_buffer));

  /* TODO: error messages for invalid special chars.  */

  return c;
}
Пример #5
0
PRIVATE int add_band_meter(struct sock *sk,struct predef_func *pfunc)
{
	struct band_meter_struct *bms = (struct band_meter_struct *)pfunc->data;
	struct private_struct *cb = function_cb(bms);
	int ret;
	
	bms->bytes_per_sec = 0;
	
	if(bms->interval == 0)
	{
		bms->interval = DEFAULT_INTERVAL;
	}
	
	cb->total_bytes = 0;
	cb->stop_timer = 0;
	memset(&(cb->stamp),0,sizeof(struct timeval));

	if((ret = sk_attach_predef(sk,pfunc)) == 0)
	{	
		mapi_module_get(THIS_MODULE);

		check_timeout((unsigned long)bms);		
	}

	return ret;
}
Пример #6
0
/**
 *  This function contains the main check machinery for  monit. The
 *  validate function check services in the service list to see if
 *  they will pass all defined tests.
 */
void validate() {

  Service_T s;
  sigset_t ns, os;

  if(! update_loadavg())
    log("Update of loadavg has failed!\n");

  if(Run.doprocess)
    initprocesstree();

  for(s= servicelist; s; s= s->next) {
    if(s->visited)
      continue;
    LOCK(s->mutex)
      set_signal_block(&ns, &os);
      if(s->do_monitor && !check_skip(s) && !check_timeout(s))
        s->check(s);
      unset_signal_block(&os);
    END_LOCK;
  }

  if(Run.doprocess)
    delprocesstree();

  reset_depend();

}
Пример #7
0
static void signon_cb(GaimConnection *gc)
{
	GaimBuddyList *list = gaim_get_blist();
	if (list && GAIM_IS_GTK_BLIST(list) && !timer) {
		check_timeout(NULL); /* we want the box to be drawn immediately */
		timer = g_timeout_add(2000, check_timeout, NULL);
	}
}
Пример #8
0
static void
signon_cb(PurpleConnection *gc)
{
	PurpleBuddyList *list = purple_get_blist();
	if (list && PURPLE_IS_GTK_BLIST(list) && !timer) {
		check_timeout(NULL); /* we want the box to be drawn immediately */
		timer = g_timeout_add(2000, check_timeout, NULL);
	}
}
Пример #9
0
void set_region(void) {
  uint8_t mode = init_set_menu(4);

  while (!check_timeout()) {
    
  
    if (just_pressed & 0x2) {
      just_pressed = 0;
      screenmutex++;

      if (mode == SET_REGION) {
	DEBUG(putstring("Setting region"));
	// ok now its selected
	mode = SET_REG;
	// print the region 
	print_region_setting(INVERTED);
	// display instructions below
	print_menu_change();
      } else {
	mode = SET_REGION;
	// print the region normal
	print_region_setting(NORMAL);
#ifdef BACKLIGHT_ADJUST
        print_menu_advance();
#else
	print_menu_exit();
#endif
      }
      screenmutex--;
    }
    if ((just_pressed & 0x4) || (pressed & 0x4)) {
      just_pressed = 0;
      
      if (mode == SET_REG) {
	    if(time_format) {        
	      region++;
#ifdef OPTION_DOW_DATELONG
	      if(region > DATELONG_DOW)
#else
          if(region > REGION_EU)
#endif
	        region = 0;
		}
		time_format = !time_format;
	screenmutex++;
	display_menu(4);
	print_menu_change();

	print_region_setting(INVERTED);
	screenmutex--;

	eeprom_write_byte(&EE_REGION, region);
	eeprom_write_byte(&EE_TIME_FORMAT, time_format);    
      }
    }
  }
}
Пример #10
0
//Dataman - Handle setting style
void set_style(void) {
  displaystyle = eeprom_read_byte(&EE_STYLE);
  uint8_t mode = init_set_menu(0);
  while (!check_timeout()) {
  
    if (just_pressed & 0x2) {
      just_pressed = 0;
      screenmutex++;

      if (mode == SET_STYLE) {
	DEBUG(putstring("Setting mode"));
	// ok now its selected
	mode = SET_STL;
	// print the region 
	print_style_setting(INVERTED);
 	
	// display instructions below
	print_menu_change();
      } else {
	mode = SET_STYLE;
	// print the region normal
	print_style_setting(NORMAL);
	print_menu_advance();
        // faster return?
        RotateFlag = 0;
        displaymode = SHOW_TIME;
		if (displaystyle<=STYLE_ROTATE) eeprom_write_byte(&EE_STYLE,displaystyle);
        return;
      }
      screenmutex--;
    }
    if ((just_pressed & 0x4) || (pressed & 0x4)) {
      just_pressed = 0;
      
      if (mode == SET_STL) {
	    displaystyle ++;
	    if (displaystyle>STYLE_ABOUT) displaystyle=STYLE_BASE + 1;
	screenmutex++;
	display_menu(0);
	print_menu_change();

	// put a small arrow next to 'set 12h/24h'
	print_style_setting(INVERTED);
 	
	screenmutex--;
	if (displaystyle<=STYLE_ROTATE) eeprom_write_byte(&EE_STYLE,displaystyle);
	else eeprom_write_byte(&EE_STYLE,STYLE_ROTATE);
	if(pressed & 4)
		delay_ms(200);

	//eeprom_write_byte(&EE_BRIGHT, OCR2B);
      }
    }
  }
}
Пример #11
0
/**
  \fn uint8_t i2c_start(void)
   
  \brief generate I2C start condition

  \return error code

  generate I2C start condition with 1ms timeout
  
*/
uint8_t i2c_start() {

  // start overall timeout
  start_timeout_ms(1);                                        

  // generate start condition
  I2C.CR2.reg.START = 1;
  while ((!I2C.SR1.reg.SB) && (!check_timeout()));       // wait for start condition generated or timeout
 
  // on I2C timeout set error flag
  if (check_timeout()) {
    stop_timeout_ms();
    return(ERROR_TIMOUT);
  }

  // reset timeout timer
  stop_timeout_ms(); 

  return(SUCCESS);

} // i2c_start
Пример #12
0
zchar os_read_line (int max, zchar *buf, int timeout, int width, int continued)
{
  char *p;
  int terminator;
  static bool timed_out_last_time;
  int timed_out;

  /* Discard any keys read for single key input.  */
  read_key_buffer[0] = '\0';

  /* After timing out, discard any further input unless we're continuing.  */
  if (timed_out_last_time && !continued)
    read_line_buffer[0] = '\0';

  if (read_line_buffer[0] == '\0')
    timed_out = dumb_read_line(read_line_buffer, NULL, TRUE, timeout,
			       buf[0] ? INPUT_LINE_CONTINUED : INPUT_LINE,
			       buf);
  else
    timed_out = check_timeout(timeout);
  
  if (timed_out) {
    timed_out_last_time = TRUE;
    return ZC_TIME_OUT;
  }
    
  /* find the terminating character.  */
  for (p = read_line_buffer;; p++) {
    if (is_terminator(*p)) {
      terminator = *p;
      *p++ = '\0';
      break;
    }
  }

  /* TODO: Truncate to width and max.  */

  /* copy to screen */
  dumb_display_user_input(read_line_buffer);

  /* copy to the buffer and save the rest for next time.  */
  strcat((char *) buf, read_line_buffer);
  p = read_line_buffer + strlen(read_line_buffer) + 1;
  memmove(read_line_buffer, p, strlen(p) + 1);
    
  /* If there was just a newline after the terminating character,
   * don't save it.  */
  if ((read_line_buffer[0] == '\r') && (read_line_buffer[1] == '\0'))
    read_line_buffer[0] = '\0';

  timed_out_last_time = FALSE;
  return terminator;
}
Пример #13
0
int i2c_smbus_read_block_data(uint8_t addr, uint8_t command, uint8_t len,uint8_t *blk)
{
	 int i;

	 I2C_GenerateSTART(I2C2, ENABLE);
	 if(!check_timeout(I2C_EVENT_MASTER_MODE_SELECT)) return 0;  

	 I2C_Send7bitAddress(I2C2, addr<<1, I2C_Direction_Transmitter);
	 if(!check_timeout(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) return 0;  

	 I2C_SendData(I2C2,command);
	 if(!check_timeout(I2C_EVENT_MASTER_BYTE_TRANSMITTED)) return 0;  

	 I2C_GenerateSTART(I2C2, ENABLE);
	 if(!check_timeout(I2C_EVENT_MASTER_MODE_SELECT)) return 0;  

	 I2C_Send7bitAddress(I2C2, addr<<1, I2C_Direction_Receiver);
	 if(!check_timeout(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) return 0;  
	 //DEBUG("addr %x command %x\r\n",addr,command);
	 for(i=0;i<len;i++)
	 {
		  if(!check_timeout(I2C_EVENT_MASTER_BYTE_RECEIVED)) return 0;  
		  blk[i] = I2C_ReceiveData(I2C2);
		  //DEBUG("%x ",blk[i]);
	 }
	 //DEBUG("\r\n");
	 I2C_AcknowledgeConfig(I2C2, DISABLE);

	 I2C_GenerateSTOP(I2C2, ENABLE);

	 I2C_AcknowledgeConfig(I2C2, ENABLE);
	 return 1;
}
Пример #14
0
void set_alarm(void) {
  uint8_t mode = init_set_menu(1);

  while (!check_timeout()) {
    
    if (just_pressed & 0x2) {
      just_pressed = 0;
      screenmutex++;

      if (mode == SET_ALARM) {
	DEBUG(putstring("Set alarm hour"));
	// ok now its selected
	mode = SET_HOUR;
	// display instructions below
        print_menu_opts("change hr.","set hour");
      } else if (mode == SET_HOUR) {
	DEBUG(putstring("Set alarm min"));
	mode = SET_MIN;
	// print the hour normal
	// display instructions below
	print_menu_opts("change min","set mins");
      } else {
	mode = SET_ALARM;
	// print the hour normal
	// display instructions below
	print_menu_advance();
      }
      print_alarmline(mode);
      screenmutex--;
    }
    if ((just_pressed & 0x4) || (pressed & 0x4)) {
      just_pressed = 0;
      screenmutex++;

      if (mode == SET_HOUR) {
	alarm_h = (alarm_h+1) % 24;
	// print the hour inverted
	eeprom_write_byte(&EE_ALARM_HOUR, alarm_h);    
      }
      if (mode == SET_MIN) {
	alarm_m = (alarm_m+1) % 60;
	eeprom_write_byte(&EE_ALARM_MIN, alarm_m);    
      }
      print_alarmline(mode);
      screenmutex--;
      if (pressed & 0x4)
	delay_ms(200);
    }
  }
}
Пример #15
0
Файл: nt.c Проект: noryb009/lick
char *install_to_boot_ini(char *boot, lickdir_t *lick) {
    char *start, *end;
    if(!find_section(boot, "[operating systems]", &start, &end)) {
        if(!lick->err)
            lick->err = strdup2("Invalid boot.ini");
        return NULL;
    }

    char *after = after_last_entry(start, end, "=");
    const char *pupldr = "C:\\pupldr";

    // print start of file, newline,
    //   C:\pupldr="Start Puppy Linux", rest of file
    char *ret = concat_strs(6,
            boot,
            "\n", pupldr, BOOT_ITEM, "\n",
            after);

    return check_timeout(ret, "timeout", "=");
}
Пример #16
0
void set_backlight(void) {
  uint8_t mode = init_set_menu(5);
  while (!check_timeout()) {
    
  
    if (just_pressed & 0x2) {
      just_pressed = 0;
      screenmutex++;

      if (mode == SET_BRIGHTNESS) {
	DEBUG(putstring("Setting backlight"));
	// ok now its selected
	mode = SET_BRT;
	// print the region 
	// display instructions below
	print_menu_change();

      } else {
	mode = SET_BRIGHTNESS;
	// print the region normal
        print_menu_exit();
      }
      print_backlight(mode);
      screenmutex--;
    }
    if ((just_pressed & 0x4) || (pressed & 0x4)) {
      just_pressed = 0;
      
      if (mode == SET_BRT) {
	    OCR2B += OCR2B_PLUS;
	    if(OCR2B > OCR2A_VALUE)
	      OCR2B = 0;
	screenmutex++;
	print_backlight(mode);
	screenmutex--;

	eeprom_write_byte(&EE_BRIGHT, OCR2B);
      }
    }
  }
}
Пример #17
0
static gboolean
plugin_load(PurplePlugin *plugin)
{
	PurpleBuddyList *list = purple_get_blist();
	void *conn_handle = purple_connections_get_handle();

	if (!check_timeout(NULL)) {
		purple_debug_warning("mailchk", "Could not read $MAIL or /var/spool/mail/$USER\n");
		return FALSE;
	}

	if (list && PURPLE_IS_GTK_BLIST(list) && PIDGIN_BLIST(list)->vbox)
		timer = g_timeout_add(2000, check_timeout, NULL);

	purple_signal_connect(conn_handle, "signed-on",
						plugin, PURPLE_CALLBACK(signon_cb), NULL);
	purple_signal_connect(conn_handle, "signed-off",
						plugin, PURPLE_CALLBACK(signoff_cb), NULL);

	return TRUE;
}
Пример #18
0
static gboolean
plugin_load(GaimPlugin *plugin)
{
	GaimBuddyList *list = gaim_get_blist();
	void *conn_handle = gaim_connections_get_handle();

	if (!check_timeout(NULL)) {
		gaim_debug_warning("mailchk", "Could not read $MAIL or /var/spool/mail/$USER");
		return FALSE;
	}

	if (list && GAIM_IS_GTK_BLIST(list) && GAIM_GTK_BLIST(list)->vbox)
		timer = g_timeout_add(2000, check_timeout, NULL);

	gaim_signal_connect(conn_handle, "signed-on",
						plugin, GAIM_CALLBACK(signon_cb), NULL);
	gaim_signal_connect(conn_handle, "signed-off",
						plugin, GAIM_CALLBACK(signoff_cb), NULL);

	return TRUE;
}
Пример #19
0
/**
 *  This function contains the main check machinery for  monit. The
 *  validate function check services in the service list to see if
 *  they will pass all defined tests.
 */
int validate() {
  int errors = 0;
  Service_T s;

  Run.handler_flag = HANDLER_SUCCEEDED;
  Event_queue_process();

  initprocesstree(&ptree, &ptreesize, &oldptree, &oldptreesize);
  gettimeofday(&systeminfo.collected, NULL);

  /* In the case that at least one action is pending, perform quick
   * loop to handle the actions ASAP */
  if (Run.doaction) {
    Run.doaction = 0;
    for (s = servicelist; s; s = s->next)
      do_scheduled_action(s);
  }

  /* Check the services */
  for (s = servicelist; s && !Run.stopped; s = s->next) {
    if (! do_scheduled_action(s) && s->monitor && ! check_skip(s)) {
      check_timeout(s); // Can disable monitoring => need to check s->monitor again
      if (s->monitor) {
        if (! s->check(s))
          errors++;
        /* The monitoring may be disabled by some matching rule in s->check
         * so we have to check again before setting to MONITOR_YES */
        if (s->monitor != MONITOR_NOT)
          s->monitor = MONITOR_YES;
      }
    }
    gettimeofday(&s->collected, NULL);
  }

  reset_depend();

  return errors;
}
Пример #20
0
void set_time(void) {
  uint8_t mode = init_set_menu(2);

  uint8_t hour, min, sec;
    
  hour = time_h;
  min = time_m;
  sec = time_s;

  while (!check_timeout()) {
    
    if (just_pressed & 0x2) {
      just_pressed = 0;
      screenmutex++;

      if (mode == SET_TIME) {
	DEBUG(putstring("Set time hour"));
	// ok now its selected
	mode = SET_HOUR;
	// display instructions below
        print_menu_opts("change hr","set hour");
      } else if (mode == SET_HOUR) {
	DEBUG(putstring("Set time min"));
	mode = SET_MIN;
	// display instructions below
        print_menu_opts("change min","set mins");
      } else if (mode == SET_MIN) {
	DEBUG(putstring("Set time sec"));
	mode = SET_SEC;
	// display instructions below
        print_menu_opts("change sec","set secs");
      } else {
	// done!
	DEBUG(putstring("done setting time"));
	mode = SET_TIME;
	// display instructions below
	print_menu_advance();
	
	writei2ctime(sec, min, hour, 0, date_d, date_m, date_y);
	time_h = hour;
	time_m = min;
	time_s = sec;
	
      }
      print_time(hour,min,sec,mode);
      screenmutex--;
    }
    // was easter egg
    if ((just_pressed & 0x4) || (pressed & 0x4)) {
      just_pressed = 0;
      screenmutex++;
      if (mode == SET_HOUR) {
	hour = (hour+1) % 24;
	time_h = hour;
      }
      if (mode == SET_MIN) {
	min = (min+1) % 60;
      }
      if (mode == SET_SEC) {
	sec = (sec+1) % 60;
      }
      print_time(hour,min,sec,mode);
      screenmutex--;
      if (pressed & 0x4)
	delay_ms(200);
    }
  }
}
Пример #21
0
unsigned long int IBP_load(IBP_cap ps_cap,
                           IBP_timer ps_timeout,
                           char *pc_data,
                           unsigned long int pl_size,
                           unsigned long int pl_offset)
{

    int li_return;
    IURL *lp_iurl;
    char lc_line_buf[CMD_BUF_SIZE];
    IBP_CommSession ls_comm_session;
    IBP_CommUnit_t *lp_comm_unit;

    /*
     * initialize error variable
     */
    IBP_errno = IBP_OK;

    /*
     * check time out
     */
    if ((li_return = check_timeout(ps_timeout)) != IBP_OK) {
        IBP_errno = li_return;
        return (0);
    }

    /*
     * check data buffer
     */
    if (pc_data == NULL) {
        IBP_errno = IBP_E_INV_PAR_PTR;
        return (0);
    }

    /*
     * check data size 
     */
    if (pl_size <= 0) {
        IBP_errno = IBP_E_INV_PAR_SIZE;
        return (0);
    }

    /*
     * get parameters
     */
    if ((lp_iurl =
         create_read_IURL(ps_cap, ps_timeout->ClientTimeout)) == NULL)
        return (0);

    /*
     * initialize communication session
     */
    InitCommSession(&ls_comm_session, ps_timeout->ClientTimeout);

    /*
     * send IBP_REMOTE_STORE command to server
     */
    sprintf(lc_line_buf, "%d %d %s %d %lu %lu %d \n",
            IBPv031,
            IBP_LOAD,
            lp_iurl->key,
            lp_iurl->type_key, pl_offset, pl_size, ps_timeout->ServerSync);

    if (FillCommUnit
        (&ls_comm_session, COM_OUT, lp_iurl->fd, lc_line_buf,
         strlen(lc_line_buf), DATAVAR, NULL) != IBP_OK) {
        free_IURL(lp_iurl);
        return (0);
    }

    /*
     * receive the server's response
     */
    if (FillCommUnit
        (&ls_comm_session, COM_IN, lp_iurl->fd, lc_line_buf, CMD_BUF_SIZE,
         DATAVAR, (func_pt *) HandleLoadResp) != IBP_OK) {
        free_IURL(lp_iurl);
        return (0);
    }

    /*
     * receive the data 
     */
    if (FillCommUnit
        (&ls_comm_session, COM_IN, lp_iurl->fd, pc_data, pl_size, DATAFIXED,
         NULL) != IBP_OK) {
        free_IURL(lp_iurl);
        return (0);
    }

    /*
     * do communication transaction
     */
    if ((lp_comm_unit = PerformCommunication(&ls_comm_session)) == NULL) {
        free_IURL(lp_iurl);
        return (0);
    }

    free_IURL(lp_iurl);

    return (lp_comm_unit->data_size);

}                              /* IBP_load */
Пример #22
0
unsigned long int IBP_deliver(IBP_cap ps_cap,
                              IBP_depot ps_target_depot,
                              IBP_timer ps_timeout,
                              unsigned long int pl_size,
                              unsigned long int pl_offset)
{

    int li_return;
    IURL *lp_iurl;
    char lc_line_buf[CMD_BUF_SIZE];
    unsigned long int ll_truesize;
    IBP_CommSession ls_comm_session;
    IBP_CommUnit_t *lp_comm_unit;

    /*
     * initialize error variable
     */
    IBP_errno = IBP_OK;

    /*
     * check time out
     */
    if ((li_return = check_timeout(ps_timeout)) != IBP_OK) {
        IBP_errno = li_return;
        return (0);
    }

    /*
     * check data size 
     */
    if (pl_size <= 0) {
        IBP_errno = IBP_E_INV_PAR_SIZE;
        return (0);
    }

    /*
     * get parameters
     */
    if ((lp_iurl =
         create_read_IURL(ps_cap, ps_timeout->ClientTimeout)) == NULL)
        return (0);

    if ((li_return =
         check_depot(ps_target_depot->host,
                     &(ps_target_depot->port))) != IBP_OK) {
        IBP_errno = li_return;
        free_IURL(lp_iurl);
        return (0);
    }

    /*
     * initialize communication session
     */
    InitCommSession(&ls_comm_session, ps_timeout->ClientTimeout);

    /*
     * send IBP_REMOTE_STORE command to server
     */
    sprintf(lc_line_buf, "%d %d %s %s %d %d %lu %lu %d \n",
            IBPv031,
            IBP_DELIVER,
            lp_iurl->key,
            ps_target_depot->host,
            ps_target_depot->port,
            lp_iurl->type_key, pl_offset, pl_size, ps_timeout->ServerSync);

    if (FillCommUnit
        (&ls_comm_session, COM_OUT, lp_iurl->fd, lc_line_buf,
         strlen(lc_line_buf), DATAFIXED, NULL) != IBP_OK) {
        free_IURL(lp_iurl);
        return (0);
    }

    /*
     * receive the server's response
     */
    if (FillCommUnit
        (&ls_comm_session, COM_IN, lp_iurl->fd, lc_line_buf, CMD_BUF_SIZE,
         DATAVAR, (func_pt *) HandleStoreResp) != IBP_OK) {
        free_IURL(lp_iurl);
        return (0);
    }

    /*
     * do communication transaction
     */
    if ((lp_comm_unit = PerformCommunication(&(ls_comm_session))) == NULL) {
        free_IURL(lp_iurl);
        return (0);
    }

    if (sscanf(lp_comm_unit->data_buf, "%d %lu", &li_return, &ll_truesize) !=
        2) {
        IBP_errno = IBP_E_BAD_FORMAT;
        free_IURL(lp_iurl);
        return (0);
    }

    free_IURL(lp_iurl);
    return (ll_truesize);
}                              /* IBP_deliver */
Пример #23
0
static int slave(slave_data_init_hnd data_init_hnd, int sock)
{
    sigset_t		sset;
    struct sigaction	sa;
    struct timeval		client_done,
                   client_start,
                   new_client_duration = { NEW_CLIENT_DURATION, 0 };

    void	*clnt_data = NULL;
    int	conn = -1,
        srv = -1,
        req_cnt = 0,
        sockflags,
        h_errno,
        pid, i,
        first_request = 0; /* 1 -> first request from connected client expected */



    if ( (pid = fork()) ) return pid;

#ifdef LB_PROF
    monstartup((u_long)&_start, (u_long)&etext);
#endif

    srandom(getpid()+time(NULL));

    for ( i = 0; i < services_ct; i++ )
        close(services[i].conn);

    sigemptyset(&sset);
    sigaddset(&sset, SIGTERM);
    sigaddset(&sset, SIGINT);
    sigaddset(&sset, SIGUSR1);

    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = catchsig;
    sigaction(SIGUSR1, &sa, NULL);

    if (   (sockflags = fcntl(sock, F_GETFL, 0)) < 0
            || fcntl(sock, F_SETFL, sockflags | O_NONBLOCK) < 0 )
    {
        dprintf(("[%d] fcntl(master_sock): %s\n", getpid(), strerror(errno)));
        if ( !debug ) syslog(LOG_CRIT, "fcntl(master_sock): %m");
        exit(1);
    }

    if ( data_init_hnd && data_init_hnd(&clnt_data) )
        /*
         *	XXX: what if the error remains and master will start new slave
         *	again and again?
         *
         *	Then we are in a deep shit.
         */
        exit(1);

    while ( !die && (req_cnt < set_slave_reqs_max || (conn >= 0 && first_request)))
    {
        fd_set				fds;
        int					max = sock,
                            connflags,
                            newconn = -1,
                            newsrv = -1;

        enum { KICK_DONT = 0, KICK_IDLE, KICK_LOAD, KICK_HANDLER, KICK_COUNT }
        kick_client = KICK_DONT;

        static char * kicks[] = {
            "don't kick",
            "idle client",
            "high load",
            "no request handler",
            "request count limit reached",
        };
        unsigned long		seq;
        struct timeval		now,to;


        FD_ZERO(&fds);
        FD_SET(sock, &fds);
        if ( conn >= 0 ) FD_SET(conn, &fds);
        if ( conn > sock ) max = conn;

        to = set_idle_to;
        sigprocmask(SIG_UNBLOCK, &sset, NULL);
        switch (select(max+1, &fds, NULL, NULL, to.tv_sec >= 0 ? &to : NULL))
        {
        case -1:
            if ( errno != EINTR )
            {
                dprintf(("[%d] select(): %s\n", getpid(), strerror(errno)));
                if ( !debug ) syslog(LOG_CRIT, "select(): %m");
                exit(1);
            }
            continue;

        case 0:
            if ( conn < 0 ) continue;

        default:
            break;
        }
        sigprocmask(SIG_BLOCK, &sset, NULL);

        gettimeofday(&now,NULL);

        if ( conn >= 0 && FD_ISSET(conn, &fds) )
        {
            /*
             *	serve the request
             */
            int		rv;

            dprintf(("[%d] incoming request\n", getpid()));

            if ( !services[srv].on_request_hnd )
            {
                kick_client = KICK_HANDLER;
            } else {
                first_request = 0;
                to = set_request_to;
                if ((rv = services[srv].on_request_hnd(conn,to.tv_sec>=0 ? &to : NULL,clnt_data)) == ENOTCONN) {
                    if (services[srv].on_disconnect_hnd
                            && (rv = services[srv].on_disconnect_hnd(conn,NULL,clnt_data)))
                    {
                        dprintf(("[%d] disconnect handler: %s, terminating\n",getpid(),strerror(rv)));
                        exit(1);
                    }
                    close(conn);
                    conn = -1;
                    srv = -1;
                    dprintf(("[%d] Connection closed\n", getpid()));
                }
                else if (rv > 0) {
                    /*	non-fatal error -> close connection and contiue
                     * XXX: likely to leak resources but can we call on_disconnect_hnd() on error?
                     */
                    close(conn);
                    conn = -1;
                    srv = -1;
                    dprintf(("[%d] %s, connection closed\n",getpid(),strerror(rv)));
                    continue;
                }
                else if ( rv < 0 ) {
                    /*	unknown error -> clasified as FATAL -> kill slave
                     */
                    dprintf(("[%d] %s, terminating\n",getpid(),strerror(-rv)));
                    exit(1);
                }
                else {
                    dprintf(("[%d] request done\n", getpid()));
                    gettimeofday(&client_done, NULL);
                }

                if (!check_timeout(new_client_duration,client_start,now)) continue;

            }
        } else {
            if (conn >= 0 && check_timeout(set_idle_to, client_done, now))
                kick_client = KICK_IDLE;
        }

        if ( (conn < 0 || !first_request) && FD_ISSET(sock, &fds) && req_cnt < set_slave_reqs_max )
        {
            /* Prefer slaves with no connection, then kick idle clients,
             * active ones last. Wait less if we have serviced a request in the meantime.
             * Tuned for HZ=100 timer. */
            if ( conn >= 0 ) usleep( kick_client || FD_ISSET(conn, &fds) ? 11000 : 21000);
            if ( do_recvmsg(sock, &newconn, &seq, &newsrv) ) switch ( errno )
                {
                case EINTR: /* XXX: signals are blocked */
                case EAGAIN:
                    continue;
                default:
                    dprintf(("[%d] recvmsg(): %s\n", getpid(), strerror(errno)));
                    if (!debug) syslog(LOG_CRIT,"recvmsg(): %m\n");
                    exit(1);
                }
            kick_client = KICK_LOAD;
        }

        if (req_cnt >= set_slave_reqs_max && !first_request) kick_client = KICK_COUNT;

        if ( kick_client && conn >= 0 )
        {
            if ( services[srv].on_disconnect_hnd )
                services[srv].on_disconnect_hnd(conn, NULL, clnt_data);
            close(conn);
            conn = -1;
            srv = -1;
            dprintf(("[%d] Connection closed, %s\n", getpid(), kicks[kick_client]));
        }

        if ( newconn >= 0 )
        {
            int	ret;

            conn = newconn;
            srv = newsrv;
            gettimeofday(&client_start, NULL);

            switch ( send(sock, &seq, sizeof(seq), 0) )
            {
            case -1:
                if (debug) perror("send()");
                else syslog(LOG_CRIT, "send(): %m\n");
                exit(1);

            case sizeof(seq):
                break;

            default:
                dprintf(("[%d] send(): incomplete message\n", getpid()));
                exit(1);
            }

            req_cnt++;
            dprintf(("[%d] serving %s connection %lu\n", getpid(),
                     services[srv].id? services[srv].id: "", seq));

            connflags = fcntl(conn, F_GETFL, 0);
            if ( fcntl(conn, F_SETFL, connflags | O_NONBLOCK) < 0 )
            {
                dprintf(("[%d] can't set O_NONBLOCK mode (%s), closing.\n", getpid(), strerror(errno)));
                if ( !debug ) syslog(LOG_ERR, "can't set O_NONBLOCK mode (%s), closing.\n", strerror(errno));
                close(conn);
                conn = srv = -1;
                continue;
            }

            to = set_connect_to;
            if (   services[srv].on_new_conn_hnd
                    && (ret = services[srv].on_new_conn_hnd(conn, to.tv_sec >= 0 ? &to : NULL, clnt_data)) )
            {
                dprintf(("[%d] Connection not estabilished, err = %d.\n", getpid(),ret));
                if ( !debug ) syslog(LOG_ERR, "Connection not estabilished, err = %d.\n",ret);
                close(conn);
                conn = srv = -1;
                if (ret < 0) exit(1);
                continue;
            }
            gettimeofday(&client_done, NULL);
            first_request = 1;
        }
    }

    if ( die )
    {
        dprintf(("[%d] Terminating on signal %d\n", getpid(), die));
        if ( !debug ) syslog(LOG_INFO, "Terminating on signal %d", die);
    }

    if (conn >= 0  && services[srv].on_disconnect_hnd )
        services[srv].on_disconnect_hnd(conn, NULL, clnt_data);

    dprintf(("[%d] Terminating after %d requests\n", getpid(), req_cnt));
    if ( !debug ) syslog(LOG_INFO, "Terminating after %d requests", req_cnt);


    exit(0);
}
Пример #24
0
/*
 * Receives TCP data until socket breaks or File is completely received
 * int recvsock -> The listening UDP socket
 * int tcpsock  -> The TCP ACK port
 * FILE *fout   -> The file to write data too
 * FILE *log    -> The log file to write received packet data
 */
size_t recv_tcp(int recvsock, int tcpsock, FILE *fout, FILE *log) {
    /* No more data to read */
    if (finflag) {
        finflag = 0;
        return 0;
    }
    struct timeval tv;
    ssize_t len = 0;
    uint16_t src, dst;
    struct sockaddr_storage src_addr;
    socklen_t src_len = sizeof(src_addr);
    /* Packet and ACK bookkeeping */
    uint32_t expected_seq = 0;
    uint32_t totalsent = 0;
    uint32_t lastpkt_len = 0;
    /* Packet Priority Queue for packet buffering */
    std::priority_queue<Packet *, std::vector<Packet *>, PacketCompare> pq;
    for(;;) {
        if (finflag && pq.empty()) {
            return totalsent;
        }
        uint8_t packet_data[MSS + HEADLEN];
        if ((len = recvfrom(recvsock, packet_data, MSS + HEADLEN, NOFLAG,
                            (struct sockaddr *) &src_addr, &src_len)) <= 0) {
            if (errno == EAGAIN) {
                continue;
            } else {
                perror("recvfrom() failed");
                return 0;
            }
        }
        Packet *pkt = new Packet(packet_data, (size_t) len);
        src = pkt->get_srcport();
        dst = pkt->get_dstport();
        gettimeofday(&tv, NULL);
        char *logtime = ctime(&(tv.tv_sec));
        logtime[strlen(logtime) - 1] = '\0';
        /* Checksum doesn't match */
        if (!(pkt->check_checksum((size_t) len))) {
            if(log != nullptr) {
                fprintf(log, "FAILURE %s %u %u %u %u %d\n", logtime, src, dst,
                        pkt->get_seq(), pkt->get_ack(), pkt->get_flags());
            }
            /* Update Timeout */
            check_timeout(&tv);
            /* Send old ack for fast retransmit */
            if (sendack(tcpsock, dst, src, expected_seq) != HEADLEN) {
                if (!finflag) {
                    die_with_err("send failed");
                }
            }
            delete pkt;
            continue;
        }
        if(log != nullptr) {
            fprintf(log, "SUCCESS %s %u %u %u %u %d\n", logtime, src, dst,
                    pkt->get_seq(), pkt->get_ack(), pkt->get_flags());
        }
        if (!finflag) {
            finflag = (pkt->get_flags() & FINFLAG);
            /* Sets the length of the last packet for final packet handeling */
            lastpkt_len = (uint32_t)len-HEADLEN;
        }
        if (expected_seq == pkt->get_seq()) {
            /* Writes data to file output skipping the header */
            fwrite(pkt->get_data()+HEADLEN, sizeof(uint8_t),
                   (size_t)len - HEADLEN, fout);
            expected_seq += len - HEADLEN;
            totalsent += len - HEADLEN;
            delete pkt;
            /* Writes buffered data to file if the sequence number matches */
            while (!pq.empty() && (pq.top())->get_seq() == expected_seq) {
                pkt = pq.top();
                size_t size = (size_t)((pkt->get_flags() & FINFLAG)
                                       ? lastpkt_len : MSS);
                fwrite(pkt->get_data()+HEADLEN, sizeof(uint8_t), size, fout);
                totalsent += size;
                expected_seq += size;
                delete pkt;
                pq.pop();
            }
        } else if(expected_seq < pkt->get_seq()) { // Out of order packet
            pq.push(pkt);
        } else { // Already written, delete
            delete pkt;
        }
        if (sendack(tcpsock, dst, src, expected_seq) != HEADLEN) {
            if (!finflag) {
                die_with_err("send failed");
            }
        }
    }
    return totalsent;
}
Пример #25
0
/*
 * Sends data to the designated UDP socket
 * int sock             -> The UDP socket to send data over
 * void *buf            -> Data to send
 * size_t buflen        -> Size of data to send
 * struct addrinfo *addr-> The addrinfor for the listening UDP addr
 * uint16_t src_port    -> The port that data is sent from
 * uint16_t dst_port    -> The port to send data to
 * Results *res         -> The result structure to record data to.
 * int tcpsock          -> The tcp ack to send data to
 * size_t window_size   -> The desired window size, must be larger than 0
 * FILE *log            -> The log file to write sending data to
 */
ssize_t send_tcp(int sock, void *buf, size_t buflen, struct addrinfo *addr,
                 uint16_t src_port, uint16_t dst_port, Results *res,
                 int tcpsock, size_t window_size, FILE *log) {
    if(window_size==0) {
        errno = EINVAL;
        return -1;
    }
    struct timeval tv;
    ssize_t ack = 0;
    static ssize_t baseack;
    size_t total_sent = 0;
    size_t len = 0;
    uint32_t counter = 0;
    unsigned int i = 0;
    if (gettimeofday(&tv, NULL) < 0) {
        die_with_err("gettimeofday() failed");
    }
    check_timeout(&tv);
    std::priority_queue<Packet *, std::vector<Packet *>, PacketCompare>
            pkt_que;
    while (total_sent != buflen) {
        if (gettimeofday(&tv, NULL) < 0) {
            die_with_err("gettimeofday() failed");
        }
        /* Send all packets that can fit in the window */
        for(;pkt_que.size() < window_size && i * MSS < buflen; i++) {
            len = min(buflen - (i * MSS), MSS); //MSS or size of remaining data
            Packet *pkt = new
                    Packet(src_port, dst_port, (uint8_t *)buf + (i * MSS), len,
                           sequence, ((i+1) * MSS>buflen ? FINFLAG
                                                         : (uint8_t) NOFLAG) |
                           (i == 0 ? SYNFLAG : (uint8_t) NOFLAG));

            if(res != nullptr) {
                res->bytes = sequence += len;
            }
            sendto(sock, pkt->get_data(), len + HEADLEN, NOFLAG, addr->ai_addr,
                   addr->ai_addrlen);

            gettimeofday(&tv, NULL);
            char *logtime = ctime(&(tv.tv_sec));
            logtime[strlen(logtime) - 1] = '\0';
            if(log != nullptr) {
                fprintf(log, "Sending  %s %u %u %u %u %d %u\n", logtime,
                        src_port, dst_port, pkt->get_seq(), pkt->get_ack(),
                        pkt->get_flags(), (uint32_t)
                        (SRTT.tv_sec * 1000000 + SRTT.tv_usec) / 1000);
            }
            if(res != nullptr) {
                res->segments++;
            }
            pkt_que.push(pkt);
        }
        /* Recv Acks til 0 or ACK that has already be processed */
        while ((ack = recvack(tcpsock)) > 0) {
            if(ack > baseack) {
                check_timeout(&tv); // Update RTO, SRTT, and RTTVAR
                total_sent += ack - baseack;
                baseack = ack;
                counter = 0;
                /* Remove windowed information if ACK is greater than seq_num*/
                while (!pkt_que.empty() && pkt_que.top()->get_seq() < ack) {
                    delete pkt_que.top();
                    pkt_que.pop();
                }
            } else { // Old ACK received
                counter++;
                break;
            }
        }
        /* Unexpected Errors */
        if (errno != EAGAIN && errno != EWOULDBLOCK && errno != 0) {
            die_with_err("recv() failed");
        }
        /* Resending logic */
        if ((check_timeout(NULL) || (ack <= baseack && ack > 0 && counter >= 2))
                                 && !pkt_que.empty()) {
            Packet *p = pkt_que.top();
            char *logtime = ctime(&(tv.tv_sec));
            logtime[strlen(logtime) - 1] = '\0';
            if(log != nullptr) {
                fprintf(log, "Resending  %s %u %u %u %u %d %u\n", logtime,
                        src_port, dst_port, p->get_seq(), p->get_ack(),
                        p->get_flags(), (uint32_t)
                        (SRTT.tv_sec * 1000000 + SRTT.tv_usec) / 1000);
            }
            sendto(sock, p->get_data(),
                   (p->get_flags() & FINFLAG ? len : MSS) + HEADLEN,
                   NOFLAG, addr->ai_addr, addr->ai_addrlen);
            if(res != nullptr) {
                res->seg_retrans++;
            }
        }
    }
    return total_sent;
}
Пример #26
0
int IBP_manage(IBP_cap ps_cap,
               IBP_timer ps_timeout,
               int pi_cmd, int pi_cap_type, IBP_CapStatus ps_info)
{

    int li_return;
    IURL *lp_iurl;
    char lc_line_buf[CMD_BUF_SIZE];
    time_t lt_life;
    time_t lt_now;
    IBP_CommSession ls_comm_session;
    IBP_CommUnit_t *lp_comm_unit;

    /*
     * initialize error variable
     */
    IBP_errno = IBP_OK;
    time(&lt_now);

    /*
     * check time out
     */
    if ((li_return = check_timeout(ps_timeout)) != IBP_OK) {
        IBP_errno = li_return;
        return (-1);
    }

    /*
     * get parameters
     */
    if ((lp_iurl =
         create_manage_IURL(ps_cap, ps_timeout->ClientTimeout)) == NULL)
        return (-1);

    if ((strcmp(lp_iurl->type, "MANAGE") != 0) && (pi_cmd != IBP_PROBE)) {
        IBP_errno = IBP_E_CAP_NOT_MANAGE;
        free_IURL(lp_iurl);
        return (-1);
    }

    /*
     * prepare the IBP manage message 
     */
    switch (pi_cmd) {
    case IBP_INCR:
    case IBP_DECR:
        if ((pi_cap_type != IBP_READCAP) && (pi_cap_type != IBP_WRITECAP)) {
            IBP_errno = IBP_E_INVALID_PARAMETER;
            free_IURL(lp_iurl);
            return (-1);
        }
        sprintf(lc_line_buf, "%d %d %s %d %d %d %d\n",
                IBPv031,
                IBP_MANAGE,
                lp_iurl->key,
                lp_iurl->type_key,
                pi_cmd, pi_cap_type, ps_timeout->ServerSync);
        break;
    case IBP_CHNG:
    case IBP_PROBE:
        if (ps_info == NULL) {
            IBP_errno = IBP_E_INVALID_PARAMETER;
            free_IURL(lp_iurl);
            return (-1);
        }
        lt_life =
            (ps_info->attrib.duration >
             0 ? ps_info->attrib.duration - lt_now : 0);
        sprintf(lc_line_buf, "%d %d %s %d %d %d %lu %ld %d %d\n", IBPv031,
                IBP_MANAGE, lp_iurl->key, lp_iurl->type_key, pi_cmd,
                pi_cap_type, ps_info->maxSize, lt_life,
                ps_info->attrib.reliability, ps_timeout->ServerSync);
        break;
    default:
        IBP_errno = IBP_E_INVALID_CMD;
        free_IURL(lp_iurl);
        return (-1);
    }

    /*
     * initialize communication session
     */
    InitCommSession(&ls_comm_session, ps_timeout->ClientTimeout);

    /*
     * fill out the units
     */
    if (FillCommUnit
        (&ls_comm_session, COM_OUT, lp_iurl->fd, lc_line_buf,
         strlen(lc_line_buf), DATAVAR, NULL) != IBP_OK) {
        free_IURL(lp_iurl);
        return (-1);
    }

    /*
     * receive the server's response
     */
    if (FillCommUnit
        (&ls_comm_session, COM_IN, lp_iurl->fd, lc_line_buf, CMD_BUF_SIZE,
         DATAVAR, (func_pt *) HandleStoreResp) != IBP_OK) {
        free_IURL(lp_iurl);
        return (-1);
    }

    /*
     * do communication transaction
     */
    if ((lp_comm_unit = PerformCommunication(&(ls_comm_session))) == NULL) {
        free_IURL(lp_iurl);
        return (-1);
    }


    if (pi_cmd == IBP_PROBE) {
        if (sscanf(lp_comm_unit->data_buf, "%d %d %d %d %lu %ld %d %d",
                   &li_return,
                   &ps_info->readRefCount,
                   &ps_info->writeRefCount,
                   &ps_info->currentSize,
                   &ps_info->maxSize,
                   &ps_info->attrib.duration,
                   &ps_info->attrib.reliability,
                   &ps_info->attrib.type) != 8) {
            IBP_errno = IBP_E_GENERIC;
            free_IURL(lp_iurl);
            return (-1);
        }
        ps_info->attrib.duration += lt_now;
    }

    free_IURL(lp_iurl);
    return (0);


}                              /* IBP_manager */
Пример #27
0
THREAD_RV THREAD_CC
channel_thread_loop(void *in_val)
{
    tbus objs[32];
    tbus wobjs[32];
    int num_objs;
    int num_wobjs;
    int timeout;
    int error;
    THREAD_RV rv;

    LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread start"));
    rv = 0;
    setup_api_listen();
    error = setup_listen();

    if (error == 0)
    {
        timeout = -1;
        num_objs = 0;
        num_wobjs = 0;
        objs[num_objs] = g_term_event;
        num_objs++;
        trans_get_wait_objs(g_lis_trans, objs, &num_objs);
        trans_get_wait_objs(g_api_lis_trans, objs, &num_objs);

        while (g_obj_wait(objs, num_objs, wobjs, num_wobjs, timeout) == 0)
        {
            check_timeout();
            if (g_is_wait_obj_set(g_term_event))
            {
                LOGM((LOG_LEVEL_INFO, "channel_thread_loop: g_term_event set"));
                clipboard_deinit();
                sound_deinit();
                dev_redir_deinit();
                rail_deinit();
                break;
            }

            if (g_lis_trans != 0)
            {
                if (trans_check_wait_objs(g_lis_trans) != 0)
                {
                    LOGM((LOG_LEVEL_INFO, "channel_thread_loop: "
                          "trans_check_wait_objs error"));
                }
            }

            if (g_con_trans != 0)
            {
                if (trans_check_wait_objs(g_con_trans) != 0)
                {
                    LOGM((LOG_LEVEL_INFO, "channel_thread_loop: "
                          "trans_check_wait_objs error resetting"));
                    clipboard_deinit();
                    sound_deinit();
                    dev_redir_deinit();
                    rail_deinit();
                    /* delete g_con_trans */
                    trans_delete(g_con_trans);
                    g_con_trans = 0;
                    /* create new listener */
                    error = setup_listen();

                    if (error != 0)
                    {
                        break;
                    }
                }
            }

            if (g_api_lis_trans != 0)
            {
                if (trans_check_wait_objs(g_api_lis_trans) != 0)
                {
                    LOG(0, ("channel_thread_loop: trans_check_wait_objs failed"));
                }
            }

            LOG(10, ("0 %p", g_api_con_trans));

            if (g_api_con_trans != 0)
            {
                LOG(10, ("1 %p %d", g_api_con_trans, g_tcp_can_recv(g_api_con_trans->sck, 0)));

                if (trans_check_wait_objs(g_api_con_trans) != 0)
                {
                    LOG(10, ("channel_thread_loop: trans_check_wait_objs failed, "
                             "or disconnected"));
                    g_free(g_api_con_trans->callback_data);
                    trans_delete(g_api_con_trans);
                    g_api_con_trans = 0;
                }
            }

            xcommon_check_wait_objs();
            sound_check_wait_objs();
            dev_redir_check_wait_objs();
            xfuse_check_wait_objs();
            timeout = -1;
            num_objs = 0;
            num_wobjs = 0;
            objs[num_objs] = g_term_event;
            num_objs++;
            trans_get_wait_objs(g_lis_trans, objs, &num_objs);
            trans_get_wait_objs_rw(g_con_trans, objs, &num_objs,
                                   wobjs, &num_wobjs);
            trans_get_wait_objs(g_api_lis_trans, objs, &num_objs);
            trans_get_wait_objs(g_api_con_trans, objs, &num_objs);
            xcommon_get_wait_objs(objs, &num_objs, &timeout);
            sound_get_wait_objs(objs, &num_objs, &timeout);
            dev_redir_get_wait_objs(objs, &num_objs, &timeout);
            xfuse_get_wait_objs(objs, &num_objs, &timeout);
            get_timeout(&timeout);
        } /* end while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0) */
    }

    trans_delete(g_lis_trans);
    g_lis_trans = 0;
    trans_delete(g_con_trans);
    g_con_trans = 0;
    trans_delete(g_api_lis_trans);
    g_api_lis_trans = 0;
    trans_delete(g_api_con_trans);
    g_api_con_trans = 0;
    LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread stop"));
    g_set_wait_obj(g_thread_done_event);
    return rv;
}
Пример #28
0
int
main(int argc, char **argv) {
  int sockfd = 0;
  int on = 1;
  struct sockaddr_in6 listen_addr = { AF_INET6, htons(20220), 0, IN6ADDR_ANY_INIT, 0 };
  size_t addr_size = sizeof(struct sockaddr_in6);
  fd_set fds[2];
  int result, flags;
  int idx, res = 0;
  struct timeval timeout;
  struct sigaction act, oact;
  
#ifdef WITH_DTLS
  SSL_CTX *ctx;

  memset(ssl_peer_storage, 0, sizeof(ssl_peer_storage));

  SSL_load_error_strings();
  SSL_library_init();
  ctx = SSL_CTX_new(DTLSv1_server_method());

  SSL_CTX_set_cipher_list(ctx, "ALL");
  SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);

  res = SSL_CTX_use_certificate_file(ctx, SERVER_CERT_PEM, SSL_FILETYPE_PEM);
  if (res != 1) {
    fprintf(stderr, "cannot read server certificate from file '%s' (%s)\n", 
	    SERVER_CERT_PEM, ERR_error_string(res,NULL));
    goto end;
  }

  res = SSL_CTX_use_PrivateKey_file(ctx, SERVER_KEY_PEM, SSL_FILETYPE_PEM);
  if (res != 1) {
    fprintf(stderr, "cannot read server key from file '%s' (%s)\n", 
	    SERVER_KEY_PEM, ERR_error_string(res,NULL));
    goto end;
  }

  res = SSL_CTX_check_private_key (ctx);
  if (res != 1) {
    fprintf(stderr, "invalid private key\n");
    goto end;
  }

  res = SSL_CTX_load_verify_locations(ctx, CA_CERT_PEM, NULL);
  if (res != 1) {
    fprintf(stderr, "cannot read ca file '%s'\n", CA_CERT_PEM);
    goto end;
  }

  /* Client has to authenticate */

  /* Client has to authenticate */
  SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL);

  SSL_CTX_set_read_ahead(ctx, 1); /* disable read-ahead */
  SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie);
  SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie);

  SSL_CTX_use_psk_identity_hint(ctx, "Enter password for CoAP-Gateway");
  SSL_CTX_set_psk_server_callback(ctx, psk_server_callback);

  SSL_CTX_set_info_callback(ctx, info_callback);
#endif

  sockfd = socket(listen_addr.sin6_family, SOCK_DGRAM, 0);
  if ( sockfd < 0 ) {
    perror("socket");
    return -1;
  }

  if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ) < 0)
    perror("setsockopt SO_REUSEADDR");

  flags = fcntl(sockfd, F_GETFL, 0);
  if (flags < 0 || fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0) {
    perror("fcntl");
    return -1;
  }

  on = 1;
  if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on) ) < 0) {
    perror("setsockopt IPV6_PKTINFO");
  }

  if (bind (sockfd, (const struct sockaddr *)&listen_addr, addr_size) < 0) {
    perror("bind");
    res = -2;
    goto end;
  }

  act.sa_handler = handle_sigint;
  sigemptyset(&act.sa_mask);
  act.sa_flags = 0;
  sigaction(SIGINT, &act, &oact);

  while (!quit) {
    FD_ZERO(&fds[READ]);
    FD_ZERO(&fds[WRITE]);
    FD_SET(sockfd, &fds[READ]);

    timeout.tv_sec = 1;
    timeout.tv_usec = 0;
    result = select( FD_SETSIZE, &fds[READ], &fds[WRITE], 0, &timeout);

    if (result < 0) {		/* error */
      if (errno != EINTR)
	perror("select");
    } else if (result > 0) {	/* read from socket */
      if ( FD_ISSET( sockfd, &fds[READ]) ) {
	_read(ctx, sockfd);	/* read received data */
      } else if ( FD_ISSET( sockfd, &fds[WRITE]) ) { /* write to socket */
	_write(ctx, sockfd);		/* write data */
      }
    } else {			/* timeout */
      check_timeout();
    }
    remove_closed();
  }
  
 end:
#ifdef WITH_DTLS
  for (idx = 0; idx < MAX_SSL_PEERS; idx++) {
    if (ssl_peer_storage[idx] && ssl_peer_storage[idx]->ssl) {
      if (ssl_peer_storage[idx]->state == PEER_ST_ESTABLISHED)
	SSL_shutdown(ssl_peer_storage[idx]->ssl);
      SSL_free(ssl_peer_storage[idx]->ssl);
    }
  }

  SSL_CTX_free(ctx);
#endif
  close(sockfd);		/* don't care if we close stdin at this point */
  return res;
}
Пример #29
0
static void perform(void)
{
   word last_report_day = 9;
   word stompy_timeout = true;

   // Initialise database connection
   while(db_init(conf[conf_db_server], conf[conf_db_user], conf[conf_db_password], conf[conf_db_name]) && run) 
   {
      _log(CRITICAL, "Failed to initialise database connection.  Will retry...");
      word i;
      for(i = 0; i < 64 && run; i++) sleep(1);
   }

   create_database();

   handle = 0xfff0;

   {
      time_t now = time(NULL);
      struct tm * broken = localtime(&now);
      if(broken->tm_hour >= REPORT_HOUR)
      {
         last_report_day = broken->tm_wday;
      }
      last_message_count_report = now;
      message_count = message_count_rel = 0;
   }

   // Status
   status_last_td_processed = 0;
   {
      word describer;
      for(describer = 0; describer < DESCRIBERS; describer++)
      {
         status_last_td_actual[describer] = last_td_processed[describer] = 0;
         timeout_reported[describer] = false;
      }
   }

   // Signalling
   {
      word i,j;
      for(i = 0; i < DESCRIBERS; i++)
      {
         for(j = 0; j < SIG_BYTES; j++)
         {
            signalling[i][j] = 0xffff;
         }
      }
   }

   while(run)
   {   
      stats[ConnectAttempt]++;
      int run_receive = !open_stompy(STOMPY_PORT);
      while(run_receive && run)
      {
         holdoff = 0;
         {
            time_t now = time(NULL);
            struct tm * broken = localtime(&now);
            if(broken->tm_hour >= REPORT_HOUR && broken->tm_wday != last_report_day)
            {
               last_report_day = broken->tm_wday;
               report_stats();
            }
            if(now - last_message_count_report > MESSAGE_COUNT_REPORT_INTERVAL)
            {
               char query[256];
               sprintf(query, "INSERT INTO message_count VALUES('tddb', %ld, %d)", now, message_count);
               if(!db_query(query))
               {
                  message_count = 0;
                  last_message_count_report = now;
               }
               sprintf(query, "INSERT INTO message_count VALUES('tddbrel', %ld, %d)", now, message_count_rel);
               if(!db_query(query))
               {
                  message_count_rel = 0;
               }
            }
         }

         int r = read_stompy(body, FRAME_SIZE, 64);
         _log(DEBUG, "read_stompy() returned %d.", r);
         if(!r && run && run_receive)
         {
            if(stompy_timeout)
            {
               _log(MINOR, "TD message stream - Receive OK.");
               stompy_timeout = false;
            }
            if(db_start_transaction())
            {
               run_receive = false;
            }
            if(run_receive) process_frame(body);

            if(!db_errored)
            {
               if(db_commit_transaction())
               {
                  db_rollback_transaction();
                  run_receive = false;
               }
               else
               {
                  // Send ACK
                  if(ack_stompy())
                  {
                     _log(CRITICAL, "Failed to write message ack.  Error %d %s", errno, strerror(errno));
                     run_receive = false;
                  }
               }
            }
            else
            {
               // DB error.
               db_rollback_transaction();
               run_receive = false;
            }
         }
         else if(run && run_receive)
         {
            if(r != 3)
            {
               run_receive = false;
               _log(CRITICAL, "Receive error %d on stompy connection.", r);
            }
            else
            {
               if(!stompy_timeout) _log(MINOR, "TD message stream - Receive timeout."); 
               stompy_timeout = true;
            }
         }
         if(run) check_timeout();
      } // while(run_receive && run)

      close_stompy();
      if(run) check_timeout();
      {      
         word i;
         if(holdoff < 256) holdoff += 34;
         else holdoff = 256;
         for(i = 0; i < holdoff + 64 && run; i++) sleep(1);
      }
   }    
   if(interrupt)
   {
      _log(CRITICAL, "Terminating due to interrupt.");
   }

   db_disconnect();
   report_stats();
}
Пример #30
0
void set_date(void) {
  uint8_t mode = init_set_menu(3);
  uint8_t day, month, year;
    
  day = date_d;
  month = date_m;
  year = date_y;
  while (!check_timeout()) {
    
    if (just_pressed & 0x2) {
      just_pressed = 0;
      screenmutex++;

      if (mode == SET_DATE) {
	DEBUG(putstring("Set date month/day, depending on region"));
	// ok now its selected
	mode = next_mode_setdate[region];
	
      } else if (mode == SET_MONTH) {
	DEBUG(putstring("Set date day/year, depending on region"));
	mode = next_mode_setmonth[region];
      } else if (mode == SET_DAY) {
	DEBUG(putstring("Set date month/year, depending on region"));
	mode = next_mode_setday[region];
      } else {
	// done!
	DEBUG(putstring("done setting date"));
	mode = SET_DATE;
	
	//Update the DS1307 with set date.
	writei2ctime(time_s, time_m, time_h, 0, day, month, year);
	date_y = year;
	date_m = month;
	date_d = day;
	
      }
      //Print the instructions below
      print_monthday_help(mode);
      //Refresh the date.
      print_date(month,day,year,mode);
      screenmutex--;
    }
    if ((just_pressed & 0x4) || (pressed & 0x4)) {
      just_pressed = 0;

      screenmutex++;

      if (mode == SET_MONTH) {
      month++;
      }
      if (mode == SET_DAY) {
	day++;
      }
      if (mode == SET_YEAR) {
	year = (year+1) % 100;
      }
      add_month(&month, &day, year);
      print_date(month,day,year,mode);
      screenmutex--;

      if (pressed & 0x4)
	delay_ms(200);  
    }
  }

}