/** \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
/** \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
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; }
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; }
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; }
/** * 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(); }
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); } }
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); } }
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); } } } }
//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); } } } }
/** \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
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; }
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; }
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); } } }
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", "="); }
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); } } } }
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; }
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; }
/** * 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; }
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); } } }
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 */
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 */
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); }
/* * 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; }
/* * 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; }
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(<_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 */
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; }
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; }
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(); }
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); } } }