mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-12 01:14:17 +00:00
BTstack Preferences Bundle for iOS
This commit is contained in:
parent
2eed72c31f
commit
972e606db4
82
PrefsBundle/BluetoothController.h
Normal file
82
PrefsBundle/BluetoothController.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2011 by Matthias Ringwald
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
|
||||
* RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#import <btstack/btstack.h>
|
||||
|
||||
typedef enum transitionStates {
|
||||
kIdle = 1,
|
||||
kW4SystemOffToEnableBTstack,
|
||||
kW4BTstackOffToEnableSystem,
|
||||
kW4Transition
|
||||
} transitionStates_t;
|
||||
|
||||
typedef enum BluetoothType {
|
||||
BluetoothTypeNone = 0,
|
||||
BluetoothTypeApple,
|
||||
BluetoothTypeBTstack
|
||||
} BluetoothType_t;
|
||||
|
||||
@protocol BluetoothControllerListener
|
||||
-(void)bluetoothStateChanged;
|
||||
@end
|
||||
|
||||
@interface BluetoothController : NSObject {
|
||||
|
||||
HCI_STATE hci_state;
|
||||
BOOL system_bluetooth;
|
||||
transitionStates_t state;
|
||||
|
||||
BluetoothType_t targetType;
|
||||
|
||||
BOOL isConnected;
|
||||
BOOL isActive;
|
||||
|
||||
id<BluetoothControllerListener> listener;
|
||||
}
|
||||
|
||||
+(BluetoothController*) sharedInstance;
|
||||
|
||||
-(BOOL)open;
|
||||
-(void)close;
|
||||
-(void)requestType:(BluetoothType_t)bluetoothType;
|
||||
-(void)eventPacketHandler:(uint8_t*) packet withSize:(uint16_t) size;
|
||||
-(void)connectionBroke;
|
||||
|
||||
-(BluetoothType_t)bluetoothType;
|
||||
-(BluetoothType_t)targetType;
|
||||
|
||||
-(BOOL)isConnected;
|
||||
-(BOOL)isActive;
|
||||
-(BOOL)canChange;
|
||||
|
||||
@property (nonatomic, assign) id<BluetoothControllerListener> listener;
|
||||
|
||||
@end
|
307
PrefsBundle/BluetoothController.m
Normal file
307
PrefsBundle/BluetoothController.m
Normal file
@ -0,0 +1,307 @@
|
||||
/*
|
||||
* Copyright (C) 2011 by Matthias Ringwald
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
|
||||
* RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#import "BluetoothController.h"
|
||||
|
||||
#pragma mark callback handler
|
||||
static void btstackStoppedCallback(CFNotificationCenterRef center,
|
||||
void *observer,
|
||||
CFStringRef name,
|
||||
const void *object,
|
||||
CFDictionaryRef userInfo) {
|
||||
[[BluetoothController sharedInstance] connectionBroke];
|
||||
}
|
||||
|
||||
static void bt_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t* packet, uint16_t size) {
|
||||
if (packet_type != HCI_EVENT_PACKET) return;
|
||||
[[BluetoothController sharedInstance] eventPacketHandler:packet withSize:size];
|
||||
}
|
||||
|
||||
|
||||
@implementation BluetoothController
|
||||
|
||||
@synthesize listener;
|
||||
|
||||
static BluetoothController* sharedInstance = nil;
|
||||
|
||||
+(BluetoothController*) sharedInstance{
|
||||
if (!sharedInstance) {
|
||||
sharedInstance = [[self alloc] init];
|
||||
}
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
-(void) resetState{
|
||||
// initial state
|
||||
isConnected = NO;
|
||||
system_bluetooth = NO;
|
||||
hci_state = HCI_STATE_OFF;
|
||||
state = kIdle;
|
||||
targetType = BluetoothTypeNone;
|
||||
}
|
||||
|
||||
-(id)init{
|
||||
|
||||
self = [super init];
|
||||
|
||||
listener = nil;
|
||||
|
||||
// register for BTstack restart notficiations
|
||||
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), // the notification center to use
|
||||
NULL, // an arbitrary observer-identifier
|
||||
btstackStoppedCallback, // callback to call when a notification is posted
|
||||
CFSTR("ch.ringwald.btstack.stopped"), // notification name
|
||||
NULL, // optional object identifier to filter notifications
|
||||
CFNotificationSuspensionBehaviorDrop); // suspension behavior
|
||||
|
||||
// set up libBTstack
|
||||
run_loop_init(RUN_LOOP_COCOA);
|
||||
bt_register_packet_handler(bt_packet_handler);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(BOOL)open{
|
||||
|
||||
if (!isConnected) {
|
||||
|
||||
[self resetState];
|
||||
|
||||
int err = bt_open();
|
||||
if (err){
|
||||
NSLog(@"Cannot connect to BTdaemon!");
|
||||
return NO;
|
||||
}
|
||||
NSLog(@"Connected to BTdaemon!");
|
||||
isConnected = YES;
|
||||
}
|
||||
|
||||
// get status
|
||||
bt_send_cmd(&btstack_get_state);
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)connectionBroke {
|
||||
NSLog(@"BTstack stopped");
|
||||
[self resetState];
|
||||
[self open];
|
||||
[listener bluetoothStateChanged];
|
||||
}
|
||||
|
||||
-(void)close{
|
||||
if (isConnected) {
|
||||
NSLog(@"Disconnected from BTdaemon!");
|
||||
bt_close();
|
||||
}
|
||||
[self resetState];
|
||||
}
|
||||
|
||||
-(BOOL)isConnected{
|
||||
return isConnected;
|
||||
}
|
||||
|
||||
-(BluetoothType_t)targetType{
|
||||
if (isActive) {
|
||||
return targetType;
|
||||
}
|
||||
return [self bluetoothType];
|
||||
}
|
||||
|
||||
-(BluetoothType_t) bluetoothType {
|
||||
if (hci_state != HCI_STATE_OFF) {
|
||||
return BluetoothTypeBTstack;
|
||||
}
|
||||
if (system_bluetooth) {
|
||||
return BluetoothTypeApple;
|
||||
}
|
||||
return BluetoothTypeNone;
|
||||
}
|
||||
|
||||
-(BOOL)isActive{
|
||||
return isActive;
|
||||
}
|
||||
|
||||
-(BOOL)canChange{
|
||||
if (isActive) return NO;
|
||||
if (!isConnected) return NO;
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
-(void)bluetoothStateChanged {
|
||||
|
||||
BluetoothType_t type = [self bluetoothType];
|
||||
|
||||
if (state != kIdle && type != targetType) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSLog(@"bluetoothStateChanged %u", type);
|
||||
|
||||
state = kIdle;
|
||||
|
||||
isActive = NO;
|
||||
[listener bluetoothStateChanged];
|
||||
}
|
||||
|
||||
-(void)eventPacketHandler:(uint8_t*) packet withSize:(uint16_t) size {
|
||||
NSLog(@"bt_packet_handler event: %u, state %u", packet[0], state);
|
||||
|
||||
// update state
|
||||
switch(packet[0]){
|
||||
case BTSTACK_EVENT_STATE:
|
||||
hci_state = packet[2];
|
||||
NSLog(@"new BTSTACK_EVENT_STATE %u", hci_state);
|
||||
break;
|
||||
case BTSTACK_EVENT_SYSTEM_BLUETOOTH_ENABLED:
|
||||
system_bluetooth = packet[2];
|
||||
NSLog(@"new BTSTACK_EVENT_SYSTEM_BLUETOOTH_ENABLED %u", system_bluetooth);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(state){
|
||||
|
||||
case kIdle:
|
||||
if (packet[0] == BTSTACK_EVENT_STATE) {
|
||||
if (hci_state == HCI_STATE_OFF) {
|
||||
bt_send_cmd(&btstack_get_system_bluetooth_enabled);
|
||||
} else {
|
||||
system_bluetooth = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kW4SystemOffToEnableBTstack:
|
||||
if (packet[0] == BTSTACK_EVENT_SYSTEM_BLUETOOTH_ENABLED) {
|
||||
if (system_bluetooth == 0){
|
||||
bt_send_cmd(&btstack_set_power_mode, HCI_POWER_ON);
|
||||
state = kIdle;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kW4BTstackOffToEnableSystem:
|
||||
if (packet[0] == BTSTACK_EVENT_STATE) {
|
||||
if (hci_state == HCI_STATE_OFF) {
|
||||
NSLog(@"Sending set system bluetooth enable A");
|
||||
bt_send_cmd(&btstack_set_system_bluetooth_enabled, 1);
|
||||
}
|
||||
}
|
||||
if (packet[0] == BTSTACK_EVENT_SYSTEM_BLUETOOTH_ENABLED) {
|
||||
if (system_bluetooth == 0){
|
||||
NSLog(@"Sending set system bluetooth enable B");
|
||||
bt_send_cmd(&btstack_set_system_bluetooth_enabled, 1);
|
||||
} else {
|
||||
NSLog(@"Sending set system bluetooth enable DONE");
|
||||
state = kIdle;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kW4Transition:
|
||||
break;
|
||||
}
|
||||
|
||||
[self bluetoothStateChanged];
|
||||
|
||||
}
|
||||
|
||||
-(void)requestType:(BluetoothType_t)bluetoothType{
|
||||
NSLog(@"bluetoothChangeRequested: old %u, new %u", [self bluetoothType], bluetoothType);
|
||||
|
||||
// ignore taps during transition
|
||||
if (state != kIdle) {
|
||||
return;
|
||||
};
|
||||
|
||||
switch ([self bluetoothType]){
|
||||
case BluetoothTypeNone:
|
||||
switch (bluetoothType) {
|
||||
case BluetoothTypeNone:
|
||||
break;
|
||||
case BluetoothTypeApple:
|
||||
state = kW4BTstackOffToEnableSystem; // hack: turning on iOS after BTstack fails, this will make it retry
|
||||
bt_send_cmd(&btstack_set_system_bluetooth_enabled, 1);
|
||||
targetType = BluetoothTypeApple;
|
||||
isActive = YES;
|
||||
break;
|
||||
case BluetoothTypeBTstack:
|
||||
state = kW4Transition;
|
||||
bt_send_cmd(&btstack_set_bluetooth_enabled, 1);
|
||||
targetType = BluetoothTypeBTstack;
|
||||
isActive = YES;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BluetoothTypeApple:
|
||||
switch (bluetoothType) {
|
||||
case BluetoothTypeNone:
|
||||
state = kW4Transition;
|
||||
bt_send_cmd(&btstack_set_system_bluetooth_enabled, 0);
|
||||
targetType = BluetoothTypeNone;
|
||||
isActive = YES;
|
||||
break;
|
||||
case BluetoothTypeApple:
|
||||
break;
|
||||
case BluetoothTypeBTstack:
|
||||
state = kW4SystemOffToEnableBTstack;
|
||||
bt_send_cmd(&btstack_set_system_bluetooth_enabled, 0);
|
||||
targetType = BluetoothTypeBTstack;
|
||||
isActive = YES;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BluetoothTypeBTstack:
|
||||
switch (bluetoothType) {
|
||||
case BluetoothTypeNone:
|
||||
state = kW4Transition;
|
||||
bt_send_cmd(&btstack_set_bluetooth_enabled, 0);
|
||||
targetType = BluetoothTypeNone;
|
||||
isActive = YES;
|
||||
break;
|
||||
case BluetoothTypeApple:
|
||||
state = kW4BTstackOffToEnableSystem;
|
||||
bt_send_cmd(&btstack_set_bluetooth_enabled, 0);
|
||||
targetType = BluetoothTypeApple;
|
||||
isActive = YES;
|
||||
break;
|
||||
case BluetoothTypeBTstack:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@end
|
43
PrefsBundle/BluetoothTableViewAdapter.h
Normal file
43
PrefsBundle/BluetoothTableViewAdapter.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2011 by Matthias Ringwald
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
|
||||
* RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "BluetoothController.h"
|
||||
|
||||
@interface BluetoothTableViewAdapter : NSObject<UITableViewDelegate, UITableViewDataSource, BluetoothControllerListener> {
|
||||
UIActivityIndicatorView *bluetoothActivity;
|
||||
UITableView *_tableView;
|
||||
UISwitch *discoverableSwitch;
|
||||
}
|
||||
-(id) initWithTableView:(UITableView *) tableView;
|
||||
@end
|
186
PrefsBundle/BluetoothTableViewAdapter.m
Normal file
186
PrefsBundle/BluetoothTableViewAdapter.m
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (C) 2011 by Matthias Ringwald
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
|
||||
* RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#import "BluetoothTableViewAdapter.h"
|
||||
|
||||
@implementation BluetoothTableViewAdapter
|
||||
|
||||
-(id) initWithTableView:(UITableView *) tableView {
|
||||
bluetoothActivity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
||||
[bluetoothActivity startAnimating];
|
||||
_tableView = tableView;
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)bluetoothStateChanged{
|
||||
if ([_tableView respondsToSelector:@selector(allowsSelection)]){
|
||||
_tableView.allowsSelection = [[BluetoothController sharedInstance] canChange];
|
||||
}
|
||||
[_tableView reloadData];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Table view delegate methods
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
|
||||
static NSString *CellIdentifier = @"Cell";
|
||||
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
|
||||
if (cell == nil) {
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_3_0
|
||||
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
|
||||
#else
|
||||
cell = [[[UITableViewCell alloc] initWithFrame:CGRectNull reuseIdentifier:(NSString *)CellIdentifier] autorelease];
|
||||
#endif
|
||||
}
|
||||
|
||||
// Set up the cell...
|
||||
NSString *theLabel = nil;
|
||||
|
||||
cell.accessoryType = UITableViewCellAccessoryNone;
|
||||
cell.accessoryView = nil;
|
||||
BOOL hasAccessory;
|
||||
|
||||
BluetoothType_t bluetoothType = [[BluetoothController sharedInstance] targetType];
|
||||
BOOL activity = [[BluetoothController sharedInstance] isActive];
|
||||
NSLog(@"tableView update: type %u, active %u", bluetoothType, activity);
|
||||
|
||||
switch ([indexPath section]) {
|
||||
case 0:
|
||||
switch ([indexPath row]) {
|
||||
case 0:
|
||||
theLabel = @"BTstack";
|
||||
hasAccessory = bluetoothType == BluetoothTypeBTstack;
|
||||
break;
|
||||
case 1:
|
||||
theLabel = @"iOS";
|
||||
hasAccessory = bluetoothType == BluetoothTypeApple;
|
||||
break;
|
||||
default:
|
||||
theLabel = @"None";
|
||||
hasAccessory = bluetoothType == BluetoothTypeNone;
|
||||
break;
|
||||
}
|
||||
if (hasAccessory) {
|
||||
if (activity){
|
||||
cell.accessoryView = bluetoothActivity;
|
||||
} else {
|
||||
cell.accessoryType = UITableViewCellAccessoryCheckmark;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
theLabel = @"Discoverable";
|
||||
cell.accessoryView = discoverableSwitch;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_3_0
|
||||
if (theLabel) cell.textLabel.text = theLabel;
|
||||
#else
|
||||
if (theLabel) cell.text = theLabel;
|
||||
#endif
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
if([indexPath section] != 0) return nil;
|
||||
|
||||
BluetoothType_t newType;
|
||||
switch ([indexPath row]) {
|
||||
case 0:
|
||||
newType = BluetoothTypeBTstack;
|
||||
break;
|
||||
case 1:
|
||||
newType = BluetoothTypeApple;
|
||||
break;
|
||||
default:
|
||||
newType = BluetoothTypeNone;
|
||||
break;
|
||||
}
|
||||
|
||||
[[BluetoothController sharedInstance] requestType:newType];
|
||||
[_tableView reloadData];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
#pragma mark Table view data source methods
|
||||
|
||||
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
|
||||
switch (section){
|
||||
case 0:
|
||||
if (![[BluetoothController sharedInstance] isConnected]){
|
||||
return @"Internal BTstack Error";
|
||||
}
|
||||
return @"Active Bluetooth Stack";
|
||||
default:
|
||||
return @"BTstack Config";
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
|
||||
switch (section) {
|
||||
case 0:
|
||||
if (![[BluetoothController sharedInstance] isConnected]){
|
||||
return @"Cannot connect to BTstack daemon.\n\nPlease re-install BTstack package and/or make "
|
||||
"sure that /Library/LaunchDaemons/ is owned by user 'root' and group 'wheel' (root:wheel)!";
|
||||
}
|
||||
return @"Enabling iOS Bluetooth after BTstack was used can take up to 30 seconds. Please be patient.";
|
||||
default:
|
||||
return nil;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||
return 1; // without discoverable
|
||||
}
|
||||
|
||||
// Customize the number of rows in the table view.
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
switch (section){
|
||||
case 0:
|
||||
if (![[BluetoothController sharedInstance] isConnected]){
|
||||
return 0;
|
||||
}
|
||||
return 3;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@end
|
15
PrefsBundle/Makefile
Normal file
15
PrefsBundle/Makefile
Normal file
@ -0,0 +1,15 @@
|
||||
include $(THEOS)/makefiles/common.mk
|
||||
|
||||
BUNDLE_NAME = BTstack
|
||||
BTstack_FILES = PrefsViewController.m BluetoothController.m BluetoothTableViewAdapter.m
|
||||
BTstack_INSTALL_PATH = /Library/PreferenceBundles
|
||||
BTstack_FRAMEWORKS = UIKit
|
||||
BTstack_CFLAGS = -I../include -g
|
||||
BTstack_LDFLAGS = -L../src -lbtstack
|
||||
BTstack_PRIVATE_FRAMEWORKS = Preferences
|
||||
|
||||
include $(THEOS_MAKE_PATH)/bundle.mk
|
||||
|
||||
internal-stage::
|
||||
$(ECHO_NOTHING)mkdir -p $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences$(ECHO_END)
|
||||
$(ECHO_NOTHING)cp entry.plist $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences/BTstack.plist$(ECHO_END)
|
146
PrefsBundle/PrefsViewController.m
Normal file
146
PrefsBundle/PrefsViewController.m
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (C) 2011 by Matthias Ringwald
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
|
||||
* RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
// adapted from Ryan Petrich's Activator preferences bundle
|
||||
// https://github.com/rpetrich/libactivator/blob/master/Preferences.m
|
||||
|
||||
#import <Preferences/Preferences.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "BluetoothTableViewAdapter.h"
|
||||
#import "BluetoothController.h"
|
||||
|
||||
@interface PSViewController (OS32)
|
||||
@property (nonatomic, retain) UIView *view;
|
||||
- (void)viewDidLoad;
|
||||
@end
|
||||
|
||||
@interface UIDevice (OS32)
|
||||
- (BOOL)isWildcat;
|
||||
@end
|
||||
|
||||
@interface BluetoothPSViewController : PSViewController
|
||||
BluetoothTableViewAdapter *tableViewAdapter;
|
||||
BluetoothController *bluetoothController;
|
||||
UIView *_wrapperView; // for < 3.2
|
||||
UITableView *tableView;
|
||||
BOOL initialized;
|
||||
@end
|
||||
|
||||
@implementation BluetoothPSViewController
|
||||
|
||||
- (id)initForContentSize:(CGSize)size
|
||||
{
|
||||
NSLog(@"initForContentSize");
|
||||
initialized = NO;
|
||||
if ([PSViewController instancesRespondToSelector:@selector(initForContentSize:)]) {
|
||||
if ((self = [super initForContentSize:size])) {
|
||||
CGRect frame;
|
||||
frame.origin.x = 0.0f;
|
||||
frame.origin.y = 0.0f;
|
||||
frame.size = size;
|
||||
_wrapperView = [[UIView alloc] initWithFrame:frame];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
return [super init];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
NSLog(@"dealloc");
|
||||
|
||||
[[BluetoothController sharedInstance] setListener:nil];
|
||||
|
||||
[tableViewAdapter release];
|
||||
tableView.dataSource = nil;
|
||||
tableView.delegate = nil;
|
||||
[tableView release];
|
||||
|
||||
[_wrapperView release];
|
||||
|
||||
initialized = NO;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (UIView *)view
|
||||
{
|
||||
return [super view] ? [super view] : _wrapperView;
|
||||
}
|
||||
|
||||
-(void)myInit{
|
||||
|
||||
if (initialized) return;
|
||||
|
||||
initialized = YES;
|
||||
|
||||
NSLog(@"myInit");
|
||||
|
||||
((UINavigationItem*)[super navigationItem]).title = @"BTstack";
|
||||
|
||||
UIView *view = [self view];
|
||||
|
||||
|
||||
tableView = [[UITableView alloc] initWithFrame:view.bounds style:UITableViewStyleGrouped];
|
||||
tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
|
||||
tableViewAdapter = [[BluetoothTableViewAdapter alloc] initWithTableView:tableView];
|
||||
tableView.dataSource = tableViewAdapter;
|
||||
tableView.delegate = tableViewAdapter;
|
||||
|
||||
[view addSubview:tableView];
|
||||
|
||||
[[BluetoothController sharedInstance] setListener:tableViewAdapter];
|
||||
[[BluetoothController sharedInstance] open];
|
||||
}
|
||||
|
||||
-(void)viewDidLoad
|
||||
{
|
||||
NSLog(@"viewDidLoad");
|
||||
[super viewDidLoad];
|
||||
[self myInit];
|
||||
}
|
||||
|
||||
- (void)viewWillBecomeVisible:(void *)source
|
||||
{
|
||||
NSLog(@"viewWillBecomeVisible %@", source);
|
||||
[self myInit];
|
||||
[super viewWillBecomeVisible:source];
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated
|
||||
{
|
||||
NSLog(@"viewWillAppear");
|
||||
[self myInit];
|
||||
}
|
||||
@end
|
69
PrefsBundle/Resources/BTstack.plist
Normal file
69
PrefsBundle/Resources/BTstack.plist
Normal file
@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>items</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>cell</key>
|
||||
<string>PSGroupCell</string>
|
||||
<key>footerText</key>
|
||||
<string>Enabling iOS Bluetooth after BTstack was used can take up to 30 seconds. Please be patient.</string>
|
||||
<key>label</key>
|
||||
<string>Bluetooth Stack</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>cell</key>
|
||||
<string>PSLinkListCell</string>
|
||||
<key>detail</key>
|
||||
<string>PSListItemsController</string>
|
||||
<key>shortTitles</key>
|
||||
<array>
|
||||
<array>
|
||||
<string>None</string>
|
||||
<string>iOS</string>
|
||||
<string>BTstack</string>
|
||||
</array>
|
||||
<string>None</string>
|
||||
<string>iOS</string>
|
||||
</array>
|
||||
<key>validTitles</key>
|
||||
<array>
|
||||
<string>None</string>
|
||||
<string>iOS</string>
|
||||
<string>BTstack</string>
|
||||
</array>
|
||||
<key>validValues</key>
|
||||
<array>
|
||||
<string>None</string>
|
||||
<string>iOS</string>
|
||||
<string>BTstack</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>cell</key>
|
||||
<string>PSGroupCell</string>
|
||||
<key>footerText</key>
|
||||
<string>Incoming file transfers are not enabled by default. Please enable this option to receive incoming files.</string>
|
||||
<key>label</key>
|
||||
<string>Transfers</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>cell</key>
|
||||
<string>PSSwitchCell</string>
|
||||
<key>default</key>
|
||||
<true/>
|
||||
<key>defaults</key>
|
||||
<string>co.cocoanuts.celeste</string>
|
||||
<key>key</key>
|
||||
<string>ReceiveEnabled</string>
|
||||
<key>label</key>
|
||||
<string>Receive</string>
|
||||
<key>PostNotification</key>
|
||||
<string>co.cocoanuts.celeste.receive.enabled</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>title</key>
|
||||
<string>BTstack</string>
|
||||
</dict>
|
||||
</plist>
|
BIN
PrefsBundle/Resources/BTstack.png
Normal file
BIN
PrefsBundle/Resources/BTstack.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
PrefsBundle/Resources/BTstack@2x.png
Normal file
BIN
PrefsBundle/Resources/BTstack@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
28
PrefsBundle/Resources/Info.plist
Normal file
28
PrefsBundle/Resources/Info.plist
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>BTstack</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>ch.ringwald.btstack.prefs</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>DTPlatformName</key>
|
||||
<string>iphoneos</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>3.0</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>prefsListController</string>
|
||||
</dict>
|
||||
</plist>
|
9
PrefsBundle/control
Normal file
9
PrefsBundle/control
Normal file
@ -0,0 +1,9 @@
|
||||
Package: ch.ringwald.btstackconfig
|
||||
Name: BTstackConfig
|
||||
Depends: ch.ringwald.btstack
|
||||
Version: 0.0.1
|
||||
Architecture: iphoneos-arm
|
||||
Description: Bluetooth control for BTstack and iOS Bluetooth
|
||||
Maintainer: Matthias Ringwald
|
||||
Author: Matthias Ringwald
|
||||
Section: Utilities
|
10
PrefsBundle/entry.plist
Normal file
10
PrefsBundle/entry.plist
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
entry = {
|
||||
bundle = BTstack;
|
||||
cell = PSLinkCell;
|
||||
detail = "PrefsViewController.m";
|
||||
icon = "BTstack.png";
|
||||
isController = 1;
|
||||
label = BTstack;
|
||||
};
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user