add advanced power management for iOS by Jens David (and bump version)

This commit is contained in:
matthias.ringwald 2011-08-04 21:25:43 +00:00
parent f7659c28b1
commit 0ff3056bc7
5 changed files with 125 additions and 15 deletions

View File

@ -9,6 +9,7 @@ AM_INIT_AUTOMAKE(BTstack,0.1)
AC_ARG_WITH(hci-transport, [AS_HELP_STRING([--with-hci-transport=transportType], [Specify BT type to use: h4, usb (not supported yet])], HCI_TRANSPORT=$withval, HCI_TRANSPORT="h4")
AC_ARG_WITH(uart-device, [AS_HELP_STRING([--with-uart-device=uartDevice], [Specify BT UART device to use])], UART_DEVICE=$withval, UART_DEVICE="DEFAULT")
AC_ARG_WITH(uart-speed, [AS_HELP_STRING([--with-uart-speed=uartSpeed], [Specify BT UART speed to use])], UART_SPEED=$withval, UART_SPEED="115200")
AC_ARG_ENABLE(powermanagement, [AS_HELP_STRING([--disable-powermanagement],[Disable powermanagement])], USE_POWERMANAGEMENT=$enableval, USE_POWERMANAGEMENT="yes")
AC_ARG_ENABLE(bluetool, [AS_HELP_STRING([--disable-bluetool],[Disable init of Bluetooth module by BlueTool])], USE_BLUETOOL=$enableval, USE_BLUETOOL="DEFAULT")
AC_ARG_ENABLE(springboard, [AS_HELP_STRING([--disable-springboard],[Disable display of BTstack status in SpringBoard])], USE_SPRINGBOARD=$enableval, USE_SPRINGBOARD="DEFAULT")
AC_ARG_ENABLE(launchd, [AS_HELP_STRING([--enable-launchd],[Compiles BTdaemon for use by launchd])], USE_LAUNCHD=$enableval, USE_LAUNCHD="no")
@ -155,7 +156,7 @@ if test "x$target" = xiphone; then
USE_BLUETOOL="yes"
echo "USE_BLUETOOL: $USE_BLUETOOL"
fi
if test "x$USE_SPRINGBOARD" = xDEFAULT ; then
USE_SPRINGBOARD="yes"
fi
@ -192,6 +193,7 @@ CPPFLAGS="$CPPFLAGS -Werror -Wall -Wpointer-arith"
AM_CONDITIONAL(USE_SPRINGBOARD, [test "x$USE_SPRINGBOARD" == "xyes"])
AM_CONDITIONAL(USE_BLUETOOL, [test "x$USE_BLUETOOL" == "xyes"])
AM_CONDITIONAL(USE_POWERMANAGEMENT, [test "x$USE_POWERMANAGEMENT" == "xyes"])
AM_CONDITIONAL(USE_PREFSBUNDLE, [test "x$USE_PREFSBUNDLE" == "xyes"])
# summary
@ -215,6 +217,7 @@ echo "PLATFORM_SOURCES: $PLATFORM_SOURCES"
echo "USE_LAUNCHD: $USE_LAUNCHD"
echo "USE_SPRINGBOARD: $USE_SPRINGBOARD"
echo "USE_PREFSBUNDLE: $USE_PREFSBUNDLE"
echo "USE_POWERMANAGEMENT: $USE_POWERMANAGEMENT"
echo "USE_COCOA_RUN_LOOP: $USE_COCOA_RUN_LOOP"
echo "REMOTE_DEVICE_DB: $REMOTE_DEVICE_DB"
echo "HAVE_SO_NOSIGPIPE: $HAVE_SO_NOSIGPIPE"
@ -235,6 +238,9 @@ else
if test "x$USE_BLUETOOL" = xyes; then
echo "#define USE_BLUETOOL" >> config.h
fi
if test "x$USE_POWERMANAGEMENT" = xyes; then
echo "#define USE_POWERMANAGEMENT" >> config.h
fi
fi
if test "x$USE_SPRINGBOARD" = xyes; then
SPRINGBOARD_ACCESS_SOURCES="../SpringBoardAccess/SpringBoardAccess.c"

View File

@ -4,7 +4,7 @@ PACKAGE=BTstack
svn update
VERSION=0.3
VERSION=0.4
REVISION=`svn info | grep Revision | cut -d " " -f 2`
ARCHIVE=$PACKAGE-$VERSION-$REVISION.deb

View File

@ -35,6 +35,7 @@
* control Bluetooth module using BlueTool
*
* Created by Matthias Ringwald on 5/19/09.
* PowerManagement implementation by Jens David, DG1KJD on 20110801.
*
* Bluetooth Toggle by BigBoss
*/
@ -126,7 +127,6 @@ static data_source_t power_notification_ds;
#endif
#endif
int iphone_system_bt_enabled(){
return SBA_getBluetoothEnabled();
}
@ -148,6 +148,10 @@ static char buffer[BUFF_LEN+1];
static bd_addr_t local_mac_address;
static uint32_t transport_speed;
static int power_management_active = 0;
static char *os3xBlueTool = "BlueTool";
static char *os4xBlueTool = "/usr/local/bin/BlueToolH4";
/**
* get machine name
*/
@ -373,6 +377,23 @@ static int iphone_write_initscript (int output, int baudrate){
}
// close input
close(input);
#ifdef USE_POWERMANAGEMENT
if (iphone_has_csr()) {
/* CSR BT module */
iphone_write_string(output, "msleep 50\n");
iphone_write_string(output, "csr -p 0x01ca=0x0031\n");
iphone_write_string(output, "msleep 50\n");
iphone_write_string(output, "csr -p 0x01c7=0x0001,0x01f4,0x0005,0x0020\n");
power_management_active = 1;
} else {
/* BCM BT module, deactivated since untested for now */
// iphone_write_string(output, "bcm -s 0x01,0x00,0x00,0x01,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x01\n");
// iphone_write_string(output, "msleep 50\n");
power_management_active = 0;
}
#endif
return 0;
}
@ -382,18 +403,27 @@ static void iphone_write_configscript(int fd, int baudrate){
iphone_csr_set_baud(fd, baudrate);
iphone_csr_set_bd_addr(fd);
iphone_write_string(fd, "csr -r\n");
#ifdef USE_POWERMANAGEMENT
iphone_write_string(fd, "msleep 50\n");
iphone_write_string(fd, "csr -p 0x01ca=0x0031\n");
iphone_write_string(fd, "msleep 50\n");
iphone_write_string(fd, "csr -p 0x01c7=0x0001,0x01f4,0x0005,0x0020\n");
power_management_active = 1;
#endif
} else {
iphone_bcm_set_baud(fd, baudrate);
iphone_write_string(fd, "msleep 200\n");
iphone_bcm_set_bd_addr(fd);
iphone_write_string(fd, "msleep 50\n");
#ifdef USE_POWERMANAGEMENT
iphone_write_string(fd, "bcm -s 0x01,0x00,0x00,0x01,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x01\n");
iphone_write_string(fd, "msleep 50\n");
power_management_active = 1;
#endif
}
iphone_write_string(fd, "quit\n");
}
static char *os3xBlueTool = "BlueTool";
static char *os4xBlueTool = "/usr/local/bin/BlueToolH4";
static int iphone_on (void *transport_config){
log_info("iphone_on: entered\n");
@ -558,12 +588,20 @@ static int iphone_off (void *config){
}
static int iphone_sleep(void *config){
// will sleep by itself
if (power_management_active) return 0;
// put Bluetooth into deep sleep
system ("echo \"wake off\nquit\" | BlueTool");
return 0;
}
static int iphone_wake(void *config){
// will wake by itself
if (power_management_active) return 0;
// wake up Bluetooth module
system ("echo \"wake on\nquit\" | BlueTool");
return 0;
@ -604,9 +642,11 @@ static void MySleepCallBack( void * refCon, io_service_t service, natural_t mess
data = POWER_WILL_SLEEP;
write(power_notification_pipe_fds[1], &data, 1);
// don't allow power change to get the 30 second delay
// IOAllowPowerChange( root_port, (long)messageArgument );
// only allow power change when power management active (and BT goes to sleep alone)
if (!power_management_active) break;
IOAllowPowerChange( root_port, (long)messageArgument );
break;
case kIOMessageSystemWillPowerOn:
@ -635,8 +675,10 @@ static int power_notification_process(struct data_source *ds) {
if (bytes_read != 1) return -1;
log_info("power_notification_process: %u\n", token);
if (power_management_active) return 0;
power_notification_callback( (POWER_NOTIFICATION_t) token );
power_notification_callback( (POWER_NOTIFICATION_t) token );
return 0;
}

View File

@ -2,7 +2,7 @@
FILE=../include/btstack/version.h
REVISION=`svnversion | sed "s/\([0-9]*\).*/\1/"`
MAJOR=0
MINOR=3
MINOR=4
DATE=`date "+%Y-%m-%d_%H:%M:%S"`
printf "// BTstack - version.h\n" > $FILE
printf "// - generated by %s\n" $0>> $FILE

View File

@ -36,6 +36,14 @@
*
* Created by Matthias Ringwald on 4/29/09.
*/
#include "../config.h"
#undef USE_NETGRAPH
#undef USE_HCI_READER_THREAD
// go back to sleep in 3s
#define HCI_WAKE_TIMER_MS 3000
#include <termios.h> /* POSIX terminal control definitions */
#include <fcntl.h> /* File control definitions */
#include <unistd.h> /* UNIX standard function definitions */
@ -48,7 +56,11 @@
#include "hci_transport.h"
#include "hci_dump.h"
// #define USE_HCI_READER_THREAD
#if defined (USE_BLUETOOL) && defined (USE_POWERMANAGEMENT)
/* iPhone power management support */
#define BT_WAKE_DEVICE "/dev/btwake"
static int fd_wake = 0;
#endif
typedef enum {
H4_W4_PACKET_TYPE,
@ -69,6 +81,9 @@ typedef struct hci_transport_h4 {
pthread_mutex_t mutex;
pthread_cond_t cond;
#endif
#if defined (USE_BLUETOOL) && defined (USE_POWERMANAGEMENT)
timer_source_t sleep_timer;
#endif
} hci_transport_h4_t;
// single instance
@ -82,7 +97,11 @@ static hci_uart_config_t *hci_uart_config;
static void *h4_reader(void *context);
static int h4_reader_process(struct data_source *ds);
#endif
#if defined (USE_BLUETOOL) && defined (USE_POWERMANAGEMENT)
static void h4_wake_on(void);
static void h4_wake_off(void);
static void h4_wake_timeout(struct timer *ts);
#endif
static void (*packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size) = dummy_handler;
@ -93,6 +112,38 @@ static int read_pos;
static uint8_t hci_packet[1+HCI_PACKET_BUFFER_SIZE]; // packet type + max(acl header + acl payload, event header + event data)
#if defined (USE_BLUETOOL) && defined (USE_POWERMANAGEMENT)
static void h4_wake_on(void)
{
if (!fd_wake) {
fd_wake = open(BT_WAKE_DEVICE, O_RDWR);
usleep(10000);
}
run_loop_remove_timer(&hci_transport_h4->sleep_timer);
run_loop_set_timer(&hci_transport_h4->sleep_timer, HCI_WAKE_TIMER_MS);
hci_transport_h4->sleep_timer.process = h4_wake_timeout;
run_loop_add_timer(&hci_transport_h4->sleep_timer);
return;
}
static void h4_wake_off(void)
{
run_loop_remove_timer(&hci_transport_h4->sleep_timer);
if (fd_wake) {
close(fd_wake);
fd_wake = 0;
}
return;
}
static void h4_wake_timeout(struct timer *ts)
{
h4_wake_off();
}
#endif /* defined (USE_BLUETOOL) && defined (USE_POWERMANAGEMENT) */
// prototypes
static int h4_open(void *transport_config){
hci_uart_config = (hci_uart_config_t*) transport_config;
@ -191,13 +242,18 @@ static int h4_open(void *transport_config){
return 0;
}
static int h4_close(void *transport_config){
static int h4_close(void *transport_config){
// first remove run loop handler
run_loop_remove_data_source(hci_transport_h4->ds);
// close device
close(hci_transport_h4->ds->fd);
#if defined (USE_BLUETOOL) && defined (USE_POWERMANAGEMENT)
// let module sleep
h4_wake_off();
#endif
// free struct
free(hci_transport_h4->ds);
hci_transport_h4->ds = NULL;
@ -207,6 +263,12 @@ static int h4_close(void *transport_config){
static int h4_send_packet(uint8_t packet_type, uint8_t * packet, int size){
if (hci_transport_h4->ds == NULL) return -1;
if (hci_transport_h4->uart_fd == 0) return -1;
#if defined (USE_BLUETOOL) && defined (USE_POWERMANAGEMENT)
// wake Bluetooth module
h4_wake_on();
#endif
hci_dump_packet( (uint8_t) packet_type, 0, packet, size);
char *data = (char*) packet;
int bytes_written = write(hci_transport_h4->uart_fd, &packet_type, 1);