move all inquiry related code from BTstackCocoaAppDelegate into BTInquiryViewController

This commit is contained in:
matthias.ringwald 2009-10-22 21:05:00 +00:00
parent c0557808b3
commit 5edccd66e5
5 changed files with 205 additions and 209 deletions

View File

@ -17,7 +17,8 @@ typedef enum {
kInquiryRemoteName
} InquiryState;
@interface BTInquiryViewController : UITableViewController {
@interface BTInquiryViewController : UITableViewController
{
NSMutableArray *devices;
HCI_STATE bluetoothState;
InquiryState inquiryState;
@ -27,14 +28,11 @@ typedef enum {
UIFont * macAddressFont;
id<BTInquiryDelegate> delegate;
}
- (void) setBluetoothState:(HCI_STATE)state;
- (void) setInquiryState:(InquiryState)state;
- (InquiryState) inquiryState;
- (HCI_STATE) bluetoothState;
- (void) startInquiry;
@property (nonatomic, retain) NSMutableArray *devices;
@property (nonatomic, retain) id<BTInquiryDelegate> delegate;
@end
@protocol BTInquiryDelegate
-(void) deviceChoosen:(BTInquiryViewController *) inqView device:(BTDevice*) device;
- (void) deviceChoosen:(BTInquiryViewController *) inqView device:(BTDevice*) device;
@end

View File

@ -7,12 +7,176 @@
#import "BTInquiryViewController.h"
#import "BTDevice.h"
#include <btstack/btstack.h>
static BTInquiryViewController *inqView;
static btstack_packet_handler_t clientHandler;
static uint8_t remoteNameIndex;
@interface BTInquiryViewController (private)
- (void) handlePacket:(uint8_t) packet_type channel:(uint16_t) channel packet:(uint8_t*) packet size:(uint16_t) size;
- (BTDevice *) getDeviceForAddress:(bd_addr_t *)addr;
- (bool) getNextRemoteName;
- (void) startInquiry;
@end
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
if (inqView) {
[inqView handlePacket:packet_type channel:channel packet:packet size:size];
}
}
@implementation BTInquiryViewController
@synthesize devices;
@synthesize delegate;
int mock_state = 0;
- (void) handlePacket:(uint8_t) packet_type channel:(uint16_t) channel packet:(uint8_t*) packet size:(uint16_t) size {
static bool inquiryDone = 0;
bd_addr_t event_addr;
switch (packet_type) {
case HCI_EVENT_PACKET:
switch (packet[0]){
case BTSTACK_EVENT_STATE:
// bt stack activated
bluetoothState = packet[2];
[[self tableView] reloadData];
// set BT state
if (!inquiryDone && packet[2] == HCI_STATE_WORKING) {
inquiryDone = true;
if (inquiryState != kInquiryInactive) {
NSLog(@"Inquiry already active");
return;
}
NSLog(@"Inquiry started");
inquiryState = kInquiryActive;
[[self tableView] reloadData];
bt_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, 15, 0);
}
break;
case BTSTACK_EVENT_POWERON_FAILED:
bluetoothState = HCI_STATE_OFF;
[[self tableView] reloadData];
UIAlertView* alertView = [[UIAlertView alloc] init];
alertView.title = @"Bluetooth not accessible!";
alertView.message = @"Hardware initialization failed!\n"
"Make sure you have turned off Bluetooth in the System Settings.";
NSLog(@"Alert: %@ - %@", alertView.title, alertView.message);
[alertView addButtonWithTitle:@"Dismiss"];
[alertView show];
break;
case HCI_EVENT_INQUIRY_RESULT:
case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI:
{
int numResponses = packet[2];
int i;
for (i=0; i<numResponses;i++){
bd_addr_t addr;
bt_flip_addr(addr, &packet[3+i*6]);
if ([inqView getDeviceForAddress:&addr]) {
NSLog(@"Device %@ already in list", [BTDevice stringForAddress:&addr]);
continue;
}
BTDevice *dev = [[BTDevice alloc] init];
[dev setAddress:&addr];
[dev setPageScanRepetitionMode:packet[3 + numResponses*6 + i]];
[dev setClassOfDevice:READ_BT_24(packet, 3 + numResponses*(6+1+1+1) + i*3)];
[dev setClockOffset:(READ_BT_16(packet, 3 + numResponses*(6+1+1+1+3) + i*2) & 0x7fff)];
hexdump(packet, size);
NSLog(@"adding %@", [dev toString] );
[devices addObject:dev];
}
}
[[inqView tableView] reloadData];
break;
case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE:
bt_flip_addr(event_addr, &packet[3]);
BTDevice *dev = [inqView getDeviceForAddress:&event_addr];
if (!dev) break;
[dev setConnectionState:kBluetoothConnectionNotConnected];
if (packet[2] == 0) {
[dev setName:[NSString stringWithUTF8String:(const char *) &packet[9]]];
}
[[self tableView] reloadData];
remoteNameIndex++;
[self getNextRemoteName];
break;
case L2CAP_EVENT_CHANNEL_OPENED:
// inform about new l2cap connection
bt_flip_addr(event_addr, &packet[2]);
uint16_t psm = READ_BT_16(packet, 10);
uint16_t source_cid = READ_BT_16(packet, 12);
printf("Channel successfully opened: ");
print_bd_addr(event_addr);
printf(", handle 0x%02x, psm 0x%02x, source cid 0x%02x, dest cid 0x%02x\n",
READ_BT_16(packet, 8), psm, source_cid, READ_BT_16(packet, 14));
break;
case HCI_EVENT_COMMAND_COMPLETE:
break;
default:
// Inquiry done
if (packet[0] == HCI_EVENT_INQUIRY_COMPLETE || COMMAND_COMPLETE_EVENT(packet, hci_inquiry_cancel)){
NSLog(@"Inquiry stopped");
if (inquiryState == kInquiryActive){
remoteNameIndex = 0;
[self getNextRemoteName];
}
break;
}
hexdump(packet, size);
break;
}
default:
break;
}
// forward to client app
(*clientHandler)(packet_type, channel, packet, size);
}
- (BTDevice *) getDeviceForAddress:(bd_addr_t *)addr {
uint8_t j;
for (j=0; j<[devices count]; j++){
BTDevice *dev = [devices objectAtIndex:j];
if (BD_ADDR_CMP(addr, [dev address]) == 0){
return dev;
}
}
return nil;
}
- (bool) getNextRemoteName{
BTDevice *remoteDev = nil;
for (remoteNameIndex = 0; remoteNameIndex < [devices count] ; remoteNameIndex++){
BTDevice *dev = [devices objectAtIndex:remoteNameIndex];
if (![dev name]){
remoteDev = dev;
break;
}
}
if (remoteDev) {
inquiryState = kInquiryRemoteName;
[remoteDev setConnectionState:kBluetoothConnectionRemoteName];
bt_send_cmd(&hci_remote_name_request, [remoteDev address], [remoteDev pageScanRepetitionMode], 0, [remoteDev clockOffset] | 0x8000);
} else {
inquiryState = kInquiryInactive;
[[self tableView] reloadData];
// inquiry done.
}
return remoteDev;
}
- (id) init {
self = [super initWithStyle:UITableViewStyleGrouped];
@ -26,9 +190,22 @@ int mock_state = 0;
[deviceActivity startAnimating];
bluetoothActivity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[bluetoothActivity startAnimating];
devices = [[NSMutableArray alloc] init];
inqView = self;
return self;
}
- (void) startInquiry {
// put into loop
clientHandler = bt_register_packet_handler(packet_handler);
bt_send_cmd(&btstack_set_power_mode, HCI_POWER_ON );
bluetoothState = HCI_STATE_INITIALIZING;
[[self tableView] reloadData];
}
/*
- (void)viewDidLoad {
[super viewDidLoad];
@ -76,6 +253,13 @@ int mock_state = 0;
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
// unregister self
bt_register_packet_handler(clientHandler);
// done
[super dealloc];
}
#pragma mark Table view methods
@ -173,8 +357,7 @@ int mock_state = 0;
// valid selection?
int idx = [indexPath indexAtPosition:1];
if (bluetoothState == HCI_STATE_WORKING && inquiryState == kInquiryInactive && idx < [devices count]){
if (delegate && [delegate respondsToSelector:@selector(deviceChoosen:device:)]){
NSLog(@"delegate would respond");
if (delegate && [delegate respondsTo:@selector(deviceChoosen:device:)]){
[delegate deviceChoosen:self device:[devices objectAtIndex:idx]];
}
} else {
@ -183,27 +366,5 @@ int mock_state = 0;
}
- (void) setBluetoothState:(HCI_STATE)state {
bluetoothState = state;
[[self tableView] reloadData];
}
- (void) setInquiryState:(InquiryState)state {
inquiryState = state;
[[self tableView] reloadData];
}
- (InquiryState) inquiryState {
return inquiryState;
}
- (HCI_STATE) bluetoothState {
return bluetoothState;
}
- (void)dealloc {
[super dealloc];
}
@end

View File

@ -11,14 +11,7 @@
@interface BTstackCocoaAppDelegate : NSObject <UIApplicationDelegate,BTInquiryDelegate> {
UIWindow *window;
BTInquiryViewController *inqView;
bool inqActive;
NSMutableArray *devices;
uint8_t remoteNameIndex;
}
- (void) handlePacketWithType:(uint8_t) packetType data:(uint8_t*)data len:(uint16_t)len;
- (void) startInquiry;
@property (nonatomic, retain) UIWindow *window;
@end

View File

@ -17,167 +17,13 @@
#include <btstack/run_loop.h>
#include <btstack/hci_cmds.h>
// forward packet to Objective C method
void packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){
[ ((BTstackCocoaAppDelegate *)[[UIApplication sharedApplication] delegate]) handlePacketWithType:packet_type data:packet len:size];
}
void showAlert(NSString *title, NSString *message){
NSLog(@"Alert: %@ - %@", title, message);
UIAlertView* alertView = [[UIAlertView alloc] init];
alertView.title = title;
alertView.message = message;
[alertView addButtonWithTitle:@"Dismiss"];
[alertView show];
void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
}
@implementation BTstackCocoaAppDelegate
@synthesize window;
- (BTDevice *) getDeviceForAddress:(bd_addr_t *)addr {
uint8_t j;
for (j=0; j<[devices count]; j++){
BTDevice *dev = [devices objectAtIndex:j];
if (BD_ADDR_CMP(addr, [dev address]) == 0){
return dev;
}
}
return nil;
}
- (bool) getNextRemoteName{
BTDevice *remoteDev = nil;
for (remoteNameIndex = 0; remoteNameIndex < [devices count] ; remoteNameIndex++){
BTDevice *dev = [devices objectAtIndex:remoteNameIndex];
if (![dev name]){
remoteDev = dev;
break;
}
}
if (remoteDev) {
[inqView setInquiryState:kInquiryRemoteName];
[remoteDev setConnectionState:kBluetoothConnectionRemoteName];
bt_send_cmd(&hci_remote_name_request, [remoteDev address], [remoteDev pageScanRepetitionMode], 0, [remoteDev clockOffset] | 0x8000);
} else {
[inqView setInquiryState:kInquiryInactive];
// inquiry done.
}
return remoteDev;
}
- (void) startInquiry {
if ([inqView inquiryState] != kInquiryInactive) {
NSLog(@"Inquiry already active");
return;
}
NSLog(@"Inquiry started");
[inqView setInquiryState:kInquiryActive];
bt_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, 15, 0);
}
- (void) handlePacketWithType:(uint8_t) packetType data:(uint8_t*) data len:(uint16_t) len {
static bool inquiryDone = 0;
bd_addr_t event_addr;
switch (packetType) {
case HCI_EVENT_PACKET:
switch (data[0]){
case BTSTACK_EVENT_STATE:
// bt stack activated
[inqView setBluetoothState:data[2] ];
// set BT state
if (!inquiryDone && data[2] == HCI_STATE_WORKING) {
inquiryDone = true;
[self startInquiry];
}
break;
case BTSTACK_EVENT_POWERON_FAILED:
[inqView setBluetoothState:HCI_STATE_OFF];
showAlert(@"Bluetooth not accessible!",
@"Hardware initialization failed!\n"
"Make sure you have turned off Bluetooth in the System Settings.");
break;
case HCI_EVENT_INQUIRY_RESULT:
case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI:
{
int numResponses = data[2];
int i;
for (i=0; i<numResponses;i++){
bd_addr_t addr;
bt_flip_addr(addr, &data[3+i*6]);
if ([self getDeviceForAddress:&addr]) {
NSLog(@"Device %@ already in list", [BTDevice stringForAddress:&addr]);
continue;
}
BTDevice *dev = [[BTDevice alloc] init];
[dev setAddress:&addr];
[dev setPageScanRepetitionMode:data[3 + numResponses*6 + i]];
[dev setClassOfDevice:READ_BT_24(data, 3 + numResponses*(6+1+1+1) + i*3)];
[dev setClockOffset:(READ_BT_16(data, 3 + numResponses*(6+1+1+1+3) + i*2) & 0x7fff)];
hexdump(data, len);
NSLog(@"adding %@", [dev toString] );
[devices addObject:dev];
}
}
[[inqView tableView] reloadData];
break;
case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE:
bt_flip_addr(event_addr, &data[3]);
BTDevice *dev = [self getDeviceForAddress:&event_addr];
if (!dev) break;
[dev setConnectionState:kBluetoothConnectionNotConnected];
if (data[2] == 0) {
[dev setName:[NSString stringWithUTF8String:(const char *) &data[9]]];
}
[[inqView tableView] reloadData];
remoteNameIndex++;
[self getNextRemoteName];
break;
case L2CAP_EVENT_CHANNEL_OPENED:
// inform about new l2cap connection
bt_flip_addr(event_addr, &data[2]);
uint16_t psm = READ_BT_16(data, 10);
uint16_t source_cid = READ_BT_16(data, 12);
printf("Channel successfully opened: ");
print_bd_addr(event_addr);
printf(", handle 0x%02x, psm 0x%02x, source cid 0x%02x, dest cid 0x%02x\n",
READ_BT_16(data, 8), psm, source_cid, READ_BT_16(data, 14));
break;
case HCI_EVENT_COMMAND_COMPLETE:
break;
default:
// Inquiry done
if (data[0] == HCI_EVENT_INQUIRY_COMPLETE || COMMAND_COMPLETE_EVENT(data, hci_inquiry_cancel)){
NSLog(@"Inquiry stopped");
if ([inqView inquiryState] == kInquiryActive){
remoteNameIndex = 0;
[self getNextRemoteName];
}
break;
}
hexdump(data, len);
break;
}
default:
break;
}
}
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after application launch
@ -185,8 +31,6 @@ void showAlert(NSString *title, NSString *message){
// create BTInquiryView
inqView = [[BTInquiryViewController alloc] init];
devices = [[NSMutableArray alloc] init];
[inqView setDevices:devices];
[inqView setDelegate:self];
[window addSubview:[inqView view]];
@ -195,30 +39,31 @@ void showAlert(NSString *title, NSString *message){
[window makeKeyAndVisible];
// start Bluetooth
[inqView setBluetoothState:HCI_STATE_INITIALIZING];
run_loop_init(RUN_LOOP_COCOA);
int res = bt_open();
if (res){
[inqView setBluetoothState:HCI_STATE_OFF];
showAlert(@"Bluetooth not accessible!",
@"Connection to BTstack failed!\n"
"Please make sure that BTstack is installed correctly.");
UIAlertView* alertView = [[UIAlertView alloc] init];
alertView.title = @"Bluetooth not accessible!";
alertView.message = @"Connection to BTstack failed!\n"
"Please make sure that BTstack is installed correctly.";
NSLog(@"Alert: %@ - %@", alertView.title, alertView.message);
[alertView addButtonWithTitle:@"Dismiss"];
[alertView show];
} else {
bt_register_packet_handler(packet_handler);
bt_send_cmd(&btstack_set_power_mode, HCI_POWER_ON );
[inqView startInquiry];
}
}
/** BTInquiryDelegate */
-(void) deviceChoosen:(BTInquiryViewController *) inqView device:(BTDevice*) device{
NSLog(@"deviceChoosen %@", [device toString]);
}
- (void)dealloc {
[window release];
[super dealloc];
}
/** BTInquiryDelegate */
-(void) deviceChoosen:(BTInquiryViewController *) inqView device:(BTDevice*) device{
NSLog(@"deviceChoosen %@", [device toString]);
}
@end

View File

@ -1,11 +1,10 @@
/* new todo file for BTstack */
NEXT:
- CocoaTouch User Interface Components
- move all inquiry related code from BTstackCocoaAppDelegate into BTInquiryViewController
- figure out why stack doesn't shut Bluetooth off when in sleep for a while/after wakeup
- prepare WiiMoteDemo for release
- integrate new inquiry code
- use navigation controller to switch views
- figure out why stack doesn't shut Bluetooth off when in sleep for a while/after wakeup
- provide test version by setting up APT repository within BTstack SVN
- instructions: http://www.saurik.com/id/7
- prepend all source files with 'new BSD' copyright header