/** Try to get the ticket for the local site. * */ int do_grant_ticket(struct ticket_config *tk, int options) { int rv; tk_log_info("granting ticket"); if (tk->leader == local) return RLT_SUCCESS; if (is_owned(tk)) return RLT_OVERGRANT; set_future_time(&tk->delay_commit, tk->term_duration + tk->acquire_after); if (options & OPT_IMMEDIATE) { tk_log_warn("granting ticket immediately! If there are " "unreachable sites, _hope_ you are sure that they don't " "have the ticket!"); time_reset(&tk->delay_commit); } rv = acquire_ticket(tk, OR_ADMIN); if (rv) { time_reset(&tk->delay_commit); return rv; } else { return RLT_MORE; } }
int main(int argc, char **argv) { pcap_t *fh; char errbuf[PCAP_ERRBUF_SIZE]; u_char* args = NULL; struct timeval time; struct in_addr peer_ip; if (argc < 4) { printf("Usage: %s <input pcap file> <netflow ip> <netflow port>\n", argv[0]); return -1; } inet_aton(argv[2], &peer_ip); nf_init_peer(&nf_peer, &peer_ip, atoi(argv[3])); fh = pcap_open_offline(argv[1], errbuf); if (fh == NULL) { printf("Failed to open %s: %s\n", argv[1], errbuf); return -1; } memset(ftable, 0, sizeof(ftable)); time_reset(); pcap_loop(fh, -1, handle_packet, args); /* Dump reamining flow record */ flow_expire(&nf_peer, &flowcache, ftable, time_sysuptime() + FLOW_TIMER); return 0; }
/* is it safe to commit the grant? * if we didn't hear from all sites on the initial grant, we may * need to delay the commit * * TODO: investigate possibility to devise from history whether a * missing site could be holding a ticket or not */ static int ticket_dangerous(struct ticket_config *tk) { int tdiff; /* we may be invoked often, don't spam the log unnecessarily */ static int no_log_delay_msg; if (!is_time_set(&tk->delay_commit)) return 0; if (is_past(&tk->delay_commit) || all_sites_replied(tk)) { if (tk->leader == local) { tk_log_info("%s, committing to CIB", is_past(&tk->delay_commit) ? "ticket delay expired" : "all sites replied"); } time_reset(&tk->delay_commit); no_log_delay_msg = 0; return 0; } tdiff = time_left(&tk->delay_commit); tk_log_debug("delay ticket commit for another " intfmt(tdiff)); if (!no_log_delay_msg) { tk_log_info("delaying ticket commit to CIB for " intfmt(tdiff)); tk_log_info("(or all sites are reached)"); no_log_delay_msg = 1; } return 1; }
static void won_elections(struct ticket_config *tk) { set_leader(tk, local); set_state(tk, ST_LEADER); set_ticket_expiry(tk, tk->term_duration); time_reset(&tk->election_end); tk->voted_for = NULL; if (is_time_set(&tk->delay_commit) && all_sites_replied(tk)) { time_reset(&tk->delay_commit); tk_log_debug("reset delay commit as all sites replied"); } save_committed_tkt(tk); ticket_broadcast(tk, OP_HEARTBEAT, OP_ACK, RLT_SUCCESS, 0); tk->ticket_updated = 0; }
/** Try to get the ticket for the local site. * */ int do_grant_ticket(struct ticket_config *tk, int options) { int rv; tk_log_info("granting ticket"); if (tk->leader == local) return RLT_SUCCESS; if (is_owned(tk)) { if (is_manual(tk) && (options & OPT_IMMEDIATE)) { /* -F flag has been used while granting a manual ticket. * The ticket will be granted and may end up being granted * on multiple sites */ tk_log_warn("manual ticket forced to be granted! be aware that " "you may end up having two sites holding the same manual " "ticket! revoke the ticket from the unnecessary site!"); } else { return RLT_OVERGRANT; } } set_future_time(&tk->delay_commit, tk->term_duration + tk->acquire_after); if (options & OPT_IMMEDIATE) { tk_log_warn("granting ticket immediately! If there are " "unreachable sites, _hope_ you are sure that they don't " "have the ticket!"); time_reset(&tk->delay_commit); } rv = acquire_ticket(tk, OR_ADMIN); if (rv) { time_reset(&tk->delay_commit); return rv; } else { return RLT_MORE; } }
static void become_follower(struct ticket_config *tk, struct boothc_ticket_msg *msg) { copy_ticket_from_msg(tk, msg); set_state(tk, ST_FOLLOWER); time_reset(&tk->delay_commit); tk->in_election = 0; /* if we're following and the ticket was granted here * then commit to CIB right away (we're probably restarting) */ if (tk->is_granted) { disown_ticket(tk); ticket_write(tk); } }
// Runs through an automatic calibration sequence void auto_calibrate() { time_reset(); set_motors(60, -60); while(get_ms() < 250) calibrate_line_sensors(IR_EMITTERS_ON); set_motors(-60, 60); while(get_ms() < 750) calibrate_line_sensors(IR_EMITTERS_ON); set_motors(60, -60); while(get_ms() < 1000) calibrate_line_sensors(IR_EMITTERS_ON); set_motors(0, 0); serial_send_blocking("c",1); }
void auto_test_sensor_range() { clear(); print("AutoTest"); lcd_goto_xy(0,1); print("B"); while(!button_is_pressed(BUTTON_B)); while(button_is_pressed(ALL_BUTTONS)); delay_ms(300); clear(); // Auto calibrate with IR on time_reset(); set_motors(20, -20); while(get_ms() < 650) calibrate_line_sensors(IR_EMITTERS_ON); set_motors(-20, 20); while(get_ms() < 1950) calibrate_line_sensors(IR_EMITTERS_ON); set_motors(20, -20); while(get_ms() < 2600) calibrate_line_sensors(IR_EMITTERS_ON); set_motors(0, 0); unsigned int * maximum_calibration_values = get_line_sensors_calibrated_maximum_on(); unsigned int * minimum_calibration_values = get_line_sensors_calibrated_minimum_on(); unsigned char k; unsigned char readings_ok = 1; unsigned char ok_array[5] = {'G','G','G','G','G'}; for (k=0;k<5;k++) { if ((maximum_calibration_values[k] - minimum_calibration_values[k]) > 1000) { if ((minimum_calibration_values[k] * 2) < maximum_calibration_values[k]) { if (minimum_calibration_values[k] < 1600) { continue; } else { ok_array[k] = 'H'; } } else { ok_array[k] = 'M'; } } else { ok_array[k] = 'R'; } readings_ok = 0; } if (!readings_ok) { clear(); print("QTR FAIL"); lcd_goto_xy(0,1); for (k=0;k<5;k++) { print_character(ok_array[k]); } print(" C "); while(!button_is_pressed(BUTTON_C)); while(button_is_pressed(ALL_BUTTONS)); } }
// *** triggered by middle button *** // This function tests the eight user I/O pins and the trimmer potentiometer. // At any given time, one pin is being driven low while the rest are weakly // pulled high (to 5 V). At the same time, the LCD is displaying the input // values on the eight user I/O pins. If you short a pin to *GROUND* (note: // do not short the pin to power, only short it to one of the ground pads // along the top edge of the board), you will see the corresponding bit on // the LCD go to zero. The PD1 bit will always read zero as it is being // pulled down through the red user LED. unsigned char IOTest() { // the bits of the "outputs" byte will correspond to the pin states of // the user I/O lines as follows: // outputs: b7 b6 b5 b4 b3 b2 b1 b0 // user I/O: PC5 PC4 PC3 PC2 PC1 PC0 PD1 PD0 // Only one bit of "outputs" will ever be set (1) at a time; the rest will // be cleared (0). The user I/O pin that corresponds to the set bit will // be an output that is driven low while all of the other user I/O pins // will be inputs with internal pull-ups enabled (i.e. they will be weakly // pulled to 5V and will read as high). unsigned char outputs = 0x80; // binary: 10000000 unsigned char direction = 0; unsigned char button; red_led(0); // turn red and green LEDs off green_led(0); clear(); // clear the LCD print("User I/O"); set_analog_mode(MODE_8_BIT); // configure ADC for 8-bit readings while (1) // loop here until we detect a button press and return { time_reset(); // reset millisecond timer count to zero DDRC = 0; // make PC0 - PC5 inputs PORTC = 0; // PC0 - PC5 -> high impedance inputs DDRD &= ~0x03; // clear PD0 & PD1 bits (make them inputs) PORTD &= ~0x03; // PD0 & PD1 -> high impedance inputs PORTC |= ~outputs >> 2; // set the outputs states of PC0 - PC5 DDRC |= outputs >> 2; // make low pin an output (inputs for rest) PORTD |= ~outputs & 0x03; // set the output states of PD0 and PD1 DDRD |= outputs & 0x03; // make low pin an output (inputs for rest) // The following loop will execute for an amount of time determined // by the position of the user trimmer potentiometer (trimpot). // When the trimpot is at one extreme, the loop will take 256*2 = 512 // milliseconds. When the trimpot is at the other extreme, the // loop will only execute once, which takes slightly more than 20 ms. // In this way, the trimpot controls the speed at which the output // byte changes. do { // The bits of the "inputs" byte reflect the input values of pins // PD0, PD1, and PC0 - PC5. Bit 0 corresponds to PD0, bit 1 to // PD1, and bits 2 - 7 to PC0 - PC5, respectively. unsigned char inputs = PIND & 0x03; // store PD0 and PD1 input vals inputs |= PINC << 2; // store PC0 - PC5 input values lcd_goto_xy(0, 1); // go to the start of the second LCD line print_binary(inputs); // print the "input" byte in binary delay_ms(20); // delay here for 20 milliseconds // check if top or bottom buttons have been pressed button = button_is_pressed(TOP_BUTTON | BOTTOM_BUTTON); if (button != 0) // if so, reset I/O states, return button ID { DDRC = 0; // make PC0 - PC5 inputs PORTC = 0; // disable pull-ups on PC0 - PC5 DDRD &= ~0x03; // make PD0 and PD1 inputs PORTD &= ~0x03; // disable pull-ups on PD0 and PD1 return button; } } while (get_ms() < read_trimpot() * 2); if (direction) outputs <<= 1; // bit-shift our output byte left by one bit else outputs >>= 1; // bit-shift our output byte right by one bit if (outputs == 1) // if we have reached the right edge direction = 1; // switch direction to "left" if (outputs == 0x80) // if we have reached the left edge direction = 0; // switch direction to "right" } }
// *** triggered by top button *** // This function plays a melody from flash in the background while the two // user LEDs alternately fade in and out. unsigned char melodyTest() { unsigned char button; int i = 0; // the following function does not block execution play_from_program_space(fugue); // play music from flash in the background red_led(0); // turn red and green LEDs off green_led(0); clear(); // clear the LCD, go to the start of the first LCD line print("melody:"); // print to the LCD lcd_goto_xy(0, 1); // go to the start of the second LCD line print("fugue"); // print to the LCD time_reset(); // reset the internal millisecond timer count to zero while (1) // loop here until we detect a button press and return { if (get_ms() >= 5) // if 5 or more milliseconds have elapsed { time_reset(); // reset timer count to zero // check if middle or bottom buttons have been pressed button = button_is_pressed(MIDDLE_BUTTON | BOTTOM_BUTTON); if (button != 0) // if so, stop melody and return the button ID { stop_playing(); // stop playing music return button; } i += 5; // increase our state variable based on the time if (i >= 1000) // once a second has elapsed, reset the state var i = 0; } // the following code alternately flashes the red and green LEDs, // fading them in and out over time as the music plays in the // background. This is accomplished by using high-frequency PWM // signals on the LED lines. Essentially, each LED is flickering // on and off very quickly, which gives it the apperance of variable // brightness depending on the percentage of the cycle the LED is on. // Each LED flicker cycle takes a total approximately 251 us. if (i < 250) // phase 1: ramp up the red LED brightness { // as i increases over time red_led(1); // turn the red LED on delay_us(i + 1); // microsecond delay red_led(0); // turn the red LED off delay_us(250 - i); // microsecond delay } else if (i < 500) // phase 2: ramp down the red LED brightness { red_led(1); // turn the red LED on delay_us(500 - i); // microsecond delay red_led(0); // turn the red LED off delay_us(i - 249); // microsecond delay } else if (i < 750) // phase 3: ramp up the green LED brightness { green_led(1); // turn the green LED on delay_us(i - 499); // microsecond delay green_led(0); // turn the green LED off delay_us(750 - i); // microsecond delay } else // phase 4: ramp down the green LED brightness { green_led(1); // turn the green LED on delay_us(1000 - i); // microsecond delay green_led(0); // turn the green LED off delay_us(i - 749); // microsecond delay } } }
int main() { char buffer[20]; // load the bar graph load_custom_characters(); // configure serial clock for 115.2 kbaud serial_set_baud_rate(115200); // wait for the device to show up while(1) { clear(); print("Master"); delay_ms(100); serial_send("\x81",1); if(serial_receive_blocking(buffer, 6, 50)) continue; clear(); print("Connect"); lcd_goto_xy(0,1); buffer[6] = 0; print(buffer); // clear the slave's LCD and display "Connect" and "OK" on two lines // Put OK in the center to test x-y positioning slave_clear(); slave_print("Connect"); slave_lcd_goto_xy(3,1); slave_print("OK"); // play a tune char tune[] = "\xB3 l16o6gab>c"; tune[1] = sizeof(tune)-3; serial_send_blocking(tune,sizeof(tune)-1); // wait wait_for_button(ANY_BUTTON); // reset calibration slave_reset_calibration(); time_reset(); slave_auto_calibrate(); unsigned char speed1 = 0, speed2 = 0; // read sensors in a loop while(1) { serial_send("\x87",1); // returns calibrated sensor values // read 10 characters if(serial_receive_blocking(buffer, 10, 100)) break; // get the line position serial_send("\xB6", 1); int line_position[1]; if(serial_receive_blocking((char *)line_position, 2, 100)) break; // get the battery voltage serial_send("\xB1",1); // read 2 bytes int battery_millivolts[1]; if(serial_receive_blocking((char *)battery_millivolts, 2, 100)) break; // display readings display_levels((unsigned int*)buffer); lcd_goto_xy(5,0); line_position[0] /= 4; // to get it into the range of 0-1000 if(line_position[0] == 1000) line_position[0] = 999; // to keep it to a maximum of 3 characters print_long(line_position[0]); print(" "); lcd_goto_xy(0,1); print_long(battery_millivolts[0]); print(" mV "); delay_ms(10); // if button A is pressed, increase motor1 speed if(button_is_pressed(BUTTON_A) && speed1 < 127) speed1 ++; else if(speed1 > 1) speed1 -= 2; else if(speed1 > 0) speed1 = 0; // if button C is pressed, control motor2 if(button_is_pressed(BUTTON_C) && speed2 < 127) speed2 ++; else if(speed2 > 1) speed2 -= 2; else if(speed2 > 0) speed2 = 0; // if button B is pressed, do PID control if(button_is_pressed(BUTTON_B)) slave_set_pid(40, 1, 20, 3, 2); else { slave_stop_pid(); slave_set_motors(speed1, speed2); } } } while(1); }
// *** triggered by middle button *** // This function tests the eight user I/O pins and the trimmer potentiometer. // At any given time, one pin is being driven low while the rest are weakly // pulled high (to 5 V). At the same time, the LCD is displaying the input // values on the eight user I/O pins. If you short a pin to *GROUND* (note: // do not short the pin to power, only short it to one of the ground pads // along the top edge of the board), you will see the corresponding bit on // the LCD go to zero. The PD1 bit will always read zero as it is being // pulled down through the red user LED. unsigned char IOTest() { // the bits of the "outputs" byte will correspond to the pin states of // the user I/O lines as follows: // outputs: b7 b6 b5 b4 b3 b2 b1 b0 // user I/O: PC5 PC4 PC3 PC2 PC1 PC0 PD1 PD0 // Only one bit of "outputs" will ever be set (1) at a time; the rest will // be cleared (0). The user I/O pin that corresponds to the set bit will // be an output that is driven low while all of the other user I/O pins // will be inputs with internal pull-ups enabled (i.e. they will be weakly // pulled to 5V and will read as high). unsigned int outputs = 0x8000; // binary: 10000000 00000000 unsigned char *outputsA = (unsigned char *)&outputs; // pointer to low byte of outputs unsigned char *outputsD = outputsA + 1; // pointer to high byte of outputs unsigned char direction = 0; unsigned char button; red_led(1); green_led(1); clear(); // clear the LCD print("User I/O"); lcd_goto_xy(0, 1); print("DDDDDDDD AAAAAAAA"); lcd_goto_xy(0, 2); print("76543210 76543210"); set_analog_mode(MODE_8_BIT); // configure ADC for 8-bit readings while (1) // loop here until we detect a button press and return { time_reset(); // reset millisecond timer count to zero DDRA = 0; // make PA0 - PA7 inputs PORTA = 0; // PA0 - PA7 -> high impedance inputs DDRD = 0; // make PD0 - PD7 inputs PORTD = 0; // PD0 - PD7 -> high impedance inputs PORTD |= ~(*outputsD); DDRD |= *outputsD; PORTA |= (~(*outputsA)) & 0x3F; DDRA |= *outputsA & 0x3F; // never make PA6 and PA7 outputs // The following loop will execute for an amount of time determined // by the position of the user trimmer potentiometer (trimpot). // When the trimpot is at one extreme, the loop will take 256*2 = 512 // milliseconds. When the trimpot is at the other extreme, the // loop will only execute once, which takes slightly more than 20 ms. // In this way, the trimpot controls the speed at which the output // byte changes. do { // The bits of the "inputs" byte reflect the input values of pins // PD0, PD1, and PC0 - PC5. Bit 0 corresponds to PD0, bit 1 to // PD1, and bits 2 - 7 to PC0 - PC5, respectively. unsigned char inputsA = PINA; unsigned char inputsD = PIND; lcd_goto_xy(0, 3); // go to the start of the fourth LCD line print_binary(inputsD); // print the "input" byte in binary print(" "); print_binary(inputsA); delay_ms(20); // delay here for 20 milliseconds // check if top or bottom buttons have been pressed button = button_is_pressed(TOP_BUTTON | BOTTOM_BUTTON); if (button != 0) // if so, reset I/O states, return button ID { DDRA = 0; // make PA0 - PA7 inputs PORTA = 0; // PA0 - PA7 -> high impedance inputs DDRD = 0; // make PD0 - PD7 inputs PORTD = 0; // PD0 - PD7 -> high impedance inputs return button; } } while (get_ms() < read_trimpot() * 2); if (direction) outputs <<= 1; // bit-shift our output byte left by one bit else outputs >>= 1; // bit-shift our output byte right by one bit if (outputs == 1) // if we have reached the right edge direction = 1; // switch direction to "left" if (outputs == 0x8000) // if we have reached the left edge direction = 0; // switch direction to "right" } }