handle HCI_POWER_ON and HCI_POWER_OFF in existing 4 states

This commit is contained in:
matthias.ringwald 2011-01-07 19:36:05 +00:00
parent c7e0c5f6bb
commit 8d213e1a0d
2 changed files with 136 additions and 37 deletions

View File

@ -17,8 +17,11 @@ NEXT:
- power handling - power handling
- DONE: figure out how to receive iPhone System Power IONotifications (in BTdaemon) to detect, when phone gets locked and wakes up - DONE: figure out how to receive iPhone System Power IONotifications (in BTdaemon) to detect, when phone gets locked and wakes up
- DONE: introduce HCI states SLEEPING and FALLING_ASLEEP - DONE: introduce HCI states SLEEPING and FALLING_ASLEEP
- DONE: introduce HCI power mode command SLEEP - DONE: introduce HCI power mode command SLEEPING
- stop all baseband connections on HCI_POWER_OFF and HCI_POWER_SLEEP - DONE: stop all baseband connections on HCI_POWER_OFF
- DONE: handle HCI_POWER_ON and HCI_POWER_OFF in existing 4 states
- stop all baseband connections on HCI_POWER_SLEEP
- handle power-off and power-on for states SLEEPING and FALLING_ASLEEP
- for now, treat sleep/wake the same as power off/on - for now, treat sleep/wake the same as power off/on
- decide on configure flags - decide on configure flags
- clean up components - clean up components

166
src/hci.c
View File

@ -547,8 +547,42 @@ void hci_close(){
} }
} }
// State-Module-Driver overview
// state module low-level
// HCI_STATE_OFF off close
// HCI_STATE_INITIALIZING, on open
// HCI_STATE_WORKING, on open
// HCI_STATE_HALTING, on open
// HCI_STATE_SLEEPING, ?? ??
// HCI_STATE_FALLING_ASLEEP ?? ??
static int hci_power_control_on(){
// power on
int err = 0;
if (hci_stack.control && hci_stack.control->on){
err = (*hci_stack.control->on)(hci_stack.config);
}
if (err){
log_err( "POWER_ON failed\n");
hci_emit_hci_open_failed();
return err;
}
// open low-level device
err = hci_stack.hci_transport->open(hci_stack.config);
if (err){
log_err( "HCI_INIT failed, turning Bluetooth off again\n");
if (hci_stack.control && hci_stack.control->off){
(*hci_stack.control->off)(hci_stack.config);
}
hci_emit_hci_open_failed();
return err;
}
return 0;
}
static void hci_power_control_off(){ static void hci_power_control_off(){
// close all open connections
// close low-level device // close low-level device
hci_stack.hci_transport->close(hci_stack.config); hci_stack.hci_transport->close(hci_stack.config);
@ -560,42 +594,104 @@ static void hci_power_control_off(){
} }
int hci_power_control(HCI_POWER_MODE power_mode){ int hci_power_control(HCI_POWER_MODE power_mode){
if (power_mode == HCI_POWER_ON && hci_stack.state == HCI_STATE_OFF) { int err = 0;
switch (hci_stack.state){
// power on
int err = 0; case HCI_STATE_OFF:
if (hci_stack.control && hci_stack.control->on){ switch (power_mode){
err = (*hci_stack.control->on)(hci_stack.config); case HCI_POWER_ON:
} err = hci_power_control_on();
if (err){ if (err) return err;
log_err( "POWER_ON failed\n"); // set up state machine
hci_emit_hci_open_failed(); hci_stack.num_cmd_packets = 1; // assume that one cmd can be sent
return err; hci_stack.state = HCI_STATE_INITIALIZING;
} hci_stack.substate = 0;
break;
// open low-level device case HCI_POWER_OFF:
err = hci_stack.hci_transport->open(hci_stack.config); // do nothing
if (err){ break;
log_err( "HCI_INIT failed, turning Bluetooth off again\n"); case HCI_POWER_SLEEP:
if (hci_stack.control && hci_stack.control->off){ // TODO ...
(*hci_stack.control->off)(hci_stack.config); break;
} }
hci_emit_hci_open_failed(); break;
return err;
} case HCI_STATE_INITIALIZING:
switch (power_mode){
// set up state machine case HCI_POWER_ON:
hci_stack.num_cmd_packets = 1; // assume that one cmd can be sent // do nothing
hci_stack.state = HCI_STATE_INITIALIZING; break;
hci_stack.substate = 0; case HCI_POWER_OFF:
// no connections yet, just turn it off
} else if (power_mode == HCI_POWER_OFF && hci_stack.state == HCI_STATE_WORKING){ hci_power_control_off();
hci_stack.state = HCI_STATE_OFF;
// see hci_run break;
hci_stack.state = HCI_STATE_HALTING; case HCI_POWER_SLEEP:
// TODO ...
break;
}
break;
case HCI_STATE_WORKING:
switch (power_mode){
case HCI_POWER_ON:
// do nothing
break;
case HCI_POWER_OFF:
// see hci_run
hci_stack.state = HCI_STATE_HALTING;
break;
case HCI_POWER_SLEEP:
// TODO ...
break;
}
break;
case HCI_STATE_HALTING:
switch (power_mode){
case HCI_POWER_ON:
// set up state machine
hci_stack.state = HCI_STATE_INITIALIZING;
hci_stack.substate = 0;
break;
case HCI_POWER_OFF:
// do nothing
break;
case HCI_POWER_SLEEP:
// TODO ...
break;
}
break;
case HCI_STATE_FALLING_ASLEEP:
switch (power_mode){
case HCI_POWER_ON:
// TODO ...
break;
case HCI_POWER_OFF:
// TODO ...
break;
case HCI_POWER_SLEEP:
// TODO ...
break;
}
break;
case HCI_STATE_SLEEPING:
switch (power_mode){
case HCI_POWER_ON:
// TODO ...
break;
case HCI_POWER_OFF:
// TODO ...
break;
case HCI_POWER_SLEEP:
// TODO ...
break;
}
break;
} }
// create internal event // create internal event
hci_emit_state(); hci_emit_state();