+
+unsigned char set_next_alarm ( unsigned int secs, unsigned int usecs ) {
+
+ // assume that SIGALRM is already being caught, we just set the itimer here
+
+ struct itimerval itv;
+
+ // if no timer at all, set the 'current' one so it does something; otherwise
+ // let it continue..
+ getitimer ( ITIMER_REAL, &itv );
+
+ if ( itv.it_value.tv_sec == 0 && itv.it_value.tv_sec == 0 ) {
+ itv.it_value.tv_sec = secs;
+ itv.it_value.tv_usec = usecs;
+ }
+
+ // set the next timer
+ //bzero ( &itv, sizeof(struct itimerval) );
+
+ itv.it_interval.tv_sec = secs;
+ itv.it_interval.tv_usec = usecs;
+
+ // if next-timer is less than current, set current too
+ if ( itv.it_value.tv_sec > itv.it_interval.tv_sec ) {
+ itv.it_value.tv_sec = secs;
+ itv.it_value.tv_usec = usecs;
+ }
+
+ if ( setitimer ( ITIMER_REAL, &itv, NULL /* old value returned here */ ) < 0 ) {
+ // sucks
+ return ( 0 );
+ }
+
+ return ( 1 );
+}
+
+void sigalrm_handler ( int n ) {
+
+ pnd_log ( pndn_debug, "---[ SIGALRM ]---\n" );
+
+ int batlevel = pnd_device_get_battery_gauge_perc();
+
+ if ( batlevel < 0 ) {
+ // couldn't read the battery level, so just assume low and make blinks?
+ batlevel = 4; // low, but not cause a shutdown
+ }
+
+ // is battery warning already active?
+ if ( b_active ) {
+ // warning is on!
+
+ // is user charging up? if so, stop blinking.
+ // perhaps we shoudl check if charger is connected, and not blink at all in that case..
+ if ( batlevel > b_threshold + 1 /* allow for error in read */ ) {
+ pnd_log ( pndn_debug, "Battery is high again, flipping to non-blinker mode\n" );
+ b_active = 0;
+ set_next_alarm ( b_frequency, 0 );
+ pnd_device_set_led_power_brightness ( 250 );
+ return;
+ }
+
+ if ( b_active == 1 ) {
+ // turn LED on
+ pnd_log ( pndn_debug, "Blink on\n" );
+ pnd_device_set_led_power_brightness ( 200 );
+ // set timer to short duration
+ b_active = 2;
+ set_next_alarm ( 0, b_blinkdur );
+ } else if ( b_active == 2 ) {
+ // turn LED off
+ pnd_log ( pndn_debug, "Blink off\n" );
+ pnd_device_set_led_power_brightness ( 10 );
+ // back to longer duration
+ b_active = 1;
+ set_next_alarm ( b_blinkfreq, 0 );
+ }
+
+ return;
+ }
+
+ // warning is off..
+ if ( batlevel <= b_threshold ) {
+ // battery seems low, go to active mode
+ pnd_log ( pndn_debug, "Battery is low, flipping to blinker mode\n" );
+ b_active = 1;
+ set_next_alarm ( b_blinkfreq, 0 );
+ } // battery level
+
+ return;
+}