Added RFCOMM

This commit is contained in:
matthias.ringwald 2011-04-30 20:30:05 +00:00
parent 3c4d4b9093
commit e115bf24db
19 changed files with 489 additions and 407 deletions

View File

@ -18,8 +18,11 @@
- removed link key and name caching from BTstackManager, honor BTSTACK_EVENT_REMOTE_NAME_CACHED
- Retina icons!
NEXT:
- create Retina status bar icons
2011-03-xx: Release 0.3 - RFCOMM for Celeste and others
- use posix run loop for daemon again - fixes issues with lost bytes on Bluetooth UART
- fixes for cocoa run loop implemenation
- move RFCOMM code into BTdaemon
- Darwin notification on BTdaemon start/stop
AFTER:
- fix broken host detection in configure.in (make it compile on linux)
@ -40,8 +43,6 @@ AFTER:
- decide on configure flags
- dynamic link BTdaemon against libBTstack.dylist
- move RFCOMM code into BTdaemon
- HCI CMD packet is limited to 1024 bytes payload. SDP records could be larger than that. Options:
- provide a way to transfer SDP records in segments
- ignore HCI command lenght on socket connection and directly stream data without buffer
@ -82,7 +83,7 @@ AFTER:
* use deleteRowsAtIndexPaths:withRowAnimation: to remove them-
== Refactor/Improve Architecture ==
- add linked_list_iterator that can remove elements (used by l2cap_close_connection and sdp_unregister_services_for_connection
- add linked_list_iterator that can remove elements (used by l2cap_close_connection and sdp_unregister_services_for_connection)
- clean up control flow
- l2cap directly sends data over socket: good/bad?
- split daemon into stack parts

View File

@ -238,6 +238,7 @@ if test "x$USE_COCOA_RUN_LOOP" = xyes; then
fi
echo "#define USE_POSIX_RUN_LOOP" >> config.h
echo "#define HAVE_SDP" >> config.h
echo "#define HAVE_RFCOMM" >> config.h
if test ! -z "$REMOTE_DEVICE_DB" ; then
echo "#define REMOTE_DEVICE_DB $REMOTE_DEVICE_DB" >> config.h
fi

View File

@ -2,8 +2,6 @@
# http://bit.ly/af0Evu
# http://hwtt.net/ths
export TARGET_STRIP_FLAGS=
include $(THEOS)/makefiles/common.mk
APPLICATION_NAME = WiiMoteOpenGLDemo
@ -13,6 +11,6 @@ WiiMoteOpenGLDemo_FILES += ../../CocoaTouch/src/BTstackManager.m ../../CocoaTouc
WiiMoteOpenGLDemo_CFLAGS = -I . -I Classes -I ../../include -I ../../CocoaTouch/include
WiiMoteOpenGLDemo_LDFLAGS = -L../../src -lbtstack
WiiMoteOpenGLDemo_FRAMEWORKS = Foundation UIKit CoreGraphics OpenGLES QuartzCore
WiiMoteOpenGLDemo_RESOURCE_FILES = wiimote_logo_55px.png wiimote_texture.png Info.plist
WiiMoteOpenGLDemo_RESOURCE_FILES = wiimote_logo_55px.png wiimote_texture.png
include $(FW_MAKEDIR)/application.mk

View File

@ -11,10 +11,11 @@
1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
9C0D06391091035200FC3BBA /* BTDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C0D06361091035200FC3BBA /* BTDevice.m */; };
9C0D070D1092316D00FC3BBA /* EAGLViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C0D070C1092316D00FC3BBA /* EAGLViewController.m */; };
9C5E121612DE55B80013EF2C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C5E121512DE55B80013EF2C /* Foundation.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
9C5E127112DE59E30013EF2C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C5E127012DE59E30013EF2C /* UIKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
9C5E127312DE59EB0013EF2C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C5E127212DE59EB0013EF2C /* CoreGraphics.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
9C5E127712DE59FA0013EF2C /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C5E127612DE59FA0013EF2C /* OpenGLES.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
9C5E139612DE6C7B0013EF2C /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C5E139512DE6C7B0013EF2C /* OpenGLES.framework */; };
9C5E139A12DE6C8A0013EF2C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C5E139912DE6C8A0013EF2C /* CoreGraphics.framework */; };
9C5E139E12DE6C960013EF2C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C5E139D12DE6C960013EF2C /* UIKit.framework */; };
9C5E13A212DE6CAA0013EF2C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C5E13A112DE6CAA0013EF2C /* CoreFoundation.framework */; };
9C5E13A812DE6CB30013EF2C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C5E13A712DE6CB30013EF2C /* Foundation.framework */; };
9C6BB62E1027911E00A0BCB0 /* wiimote_texture.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C6BB62D1027911E00A0BCB0 /* wiimote_texture.png */; };
9C8B71C712DBB9FE00E3FD8A /* BTstackManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C8B71C412DBB9FE00E3FD8A /* BTstackManager.m */; };
9C8B71C812DBB9FE00E3FD8A /* BTDiscoveryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C8B71C612DBB9FE00E3FD8A /* BTDiscoveryViewController.m */; };
@ -42,10 +43,11 @@
9C18001D108B94FB00824BE7 /* linked_list.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = linked_list.h; sourceTree = "<group>"; };
9C18001E108B94FB00824BE7 /* run_loop.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = run_loop.h; sourceTree = "<group>"; };
9C18001F108B94FB00824BE7 /* utils.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = utils.h; sourceTree = "<group>"; };
9C5E121512DE55B80013EF2C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
9C5E127012DE59E30013EF2C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
9C5E127212DE59EB0013EF2C /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
9C5E127612DE59FA0013EF2C /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
9C5E139512DE6C7B0013EF2C /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
9C5E139912DE6C8A0013EF2C /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
9C5E139D12DE6C960013EF2C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
9C5E13A112DE6CAA0013EF2C /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
9C5E13A712DE6CB30013EF2C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
9C6BB62D1027911E00A0BCB0 /* wiimote_texture.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = wiimote_texture.png; sourceTree = "<group>"; };
9C8B71C312DBB9FE00E3FD8A /* BTstackManager.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = BTstackManager.h; path = ../../CocoaTouch/include/BTstack/BTstackManager.h; sourceTree = SOURCE_ROOT; };
9C8B71C412DBB9FE00E3FD8A /* BTstackManager.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; name = BTstackManager.m; path = ../../CocoaTouch/src/BTstackManager.m; sourceTree = SOURCE_ROOT; };
@ -62,10 +64,11 @@
buildActionMask = 2147483647;
files = (
9CD1C867117E2F6900C7A4F4 /* libBTstack.dylib in Frameworks */,
9C5E121612DE55B80013EF2C /* Foundation.framework in Frameworks */,
9C5E127112DE59E30013EF2C /* UIKit.framework in Frameworks */,
9C5E127312DE59EB0013EF2C /* CoreGraphics.framework in Frameworks */,
9C5E127712DE59FA0013EF2C /* OpenGLES.framework in Frameworks */,
9C5E139612DE6C7B0013EF2C /* OpenGLES.framework in Frameworks */,
9C5E139A12DE6C8A0013EF2C /* CoreGraphics.framework in Frameworks */,
9C5E139E12DE6C960013EF2C /* UIKit.framework in Frameworks */,
9C5E13A212DE6CAA0013EF2C /* CoreFoundation.framework in Frameworks */,
9C5E13A812DE6CB30013EF2C /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -131,10 +134,11 @@
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
isa = PBXGroup;
children = (
9C5E121512DE55B80013EF2C /* Foundation.framework */,
9C5E127012DE59E30013EF2C /* UIKit.framework */,
9C5E127212DE59EB0013EF2C /* CoreGraphics.framework */,
9C5E127612DE59FA0013EF2C /* OpenGLES.framework */,
9C5E139512DE6C7B0013EF2C /* OpenGLES.framework */,
9C5E139912DE6C8A0013EF2C /* CoreGraphics.framework */,
9C5E139D12DE6C960013EF2C /* UIKit.framework */,
9C5E13A112DE6CAA0013EF2C /* CoreFoundation.framework */,
9C5E13A712DE6CB30013EF2C /* Foundation.framework */,
);
name = Frameworks;
sourceTree = "<group>";
@ -279,8 +283,9 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Milanka Ringwald (Y4MWH89GZ9)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Don't Code Sign";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_VERSION = 4.2;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
ONLY_ACTIVE_ARCH = YES;
@ -294,8 +299,7 @@
"-lbtstack",
);
PREBINDING = NO;
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "86D3FD5B-5B72-4D87-88B3-0737B204F98E";
SDKROOT = iphonesimulator3.0;
SDKROOT = iphoneos3.0;
USER_HEADER_SEARCH_PATHS = "";
};
name = Debug;
@ -304,8 +308,9 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Milanka Ringwald (Y4MWH89GZ9)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Don't Code Sign";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_VERSION = 4.2;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
ONLY_ACTIVE_ARCH = YES;
@ -319,8 +324,7 @@
"-lbtstack",
);
PREBINDING = NO;
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "86D3FD5B-5B72-4D87-88B3-0737B204F98E";
SDKROOT = iphonesimulator3.0;
SDKROOT = iphoneos3.0;
USER_HEADER_SEARCH_PATHS = "";
};
name = Release;

View File

@ -1,4 +1,5 @@
Package: ch.ringwald.wiimoteopengldemo
Package: ch.ringwald.wiimoteopengldemo
Version: 1.0
Name: WiiMote OpenGL-ES Demo
Description: BTstack Demo
This demo shows how a virtual WiiMote can mirror
@ -10,4 +11,3 @@ Homepage: http://code.google.com/p/btstack/
Depends: ch.ringwald.btstack
Maintainer: Matthias Ringwald <iphone@ringwald.ch>
Author: Matthias Ringwald <iphone@ringwald.ch>
Version: 1.0

View File

@ -120,7 +120,6 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint
// bt stack activated, get started - set local name
if (packet[2] == HCI_STATE_WORKING) {
bt_send_cmd(&hci_write_inquiry_mode, 0x01); // with RSSI
next();
}
break;

View File

@ -49,6 +49,83 @@ hci_con_handle_t con_handle;
uint16_t hid_control = 0;
uint16_t hid_interrupt = 0;
uint8_t sdp_response_0100[] = {
0x07, 0x00, 0x00, 0x00, 0x7B, 0x00, 0x76, 0x36, 0x01, 0xD7,
0x36, 0x01, 0x7F, 0x09, 0x00, 0x00, 0x0A, 0x00, 0x01, 0x00,
0x00, 0x09, 0x00, 0x01, 0x35, 0x03, 0x19, 0x11, 0x24, 0x09,
0x00, 0x04, 0x35, 0x0D, 0x35, 0x06, 0x19, 0x01, 0x00, 0x09,
0x00, 0x11, 0x35, 0x03, 0x19, 0x00, 0x11, 0x09, 0x00, 0x05,
0x35, 0x03, 0x19, 0x10, 0x02, 0x09, 0x00, 0x06, 0x35, 0x09,
0x09, 0x65, 0x6E, 0x09, 0x00, 0x6A, 0x09, 0x01, 0x00, 0x09,
0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, 0x11, 0x24, 0x09,
0x01, 0x00, 0x09, 0x00, 0x0D, 0x35, 0x0F, 0x35, 0x0D, 0x35,
0x06, 0x19, 0x01, 0x00, 0x09, 0x00, 0x13, 0x35, 0x03, 0x19,
0x00, 0x11, 0x09, 0x01, 0x00, 0x25, 0x20, 0x42, 0x72, 0x6F,
0x61, 0x64, 0x63, 0x6F, 0x6D, 0x20, 0x42, 0x6C, 0x75, 0x65,
0x74, 0x6F, 0x6F, 0x74, 0x68, 0x02, 0x00, 0x76
};
uint8_t sdp_response_0100_0076[] = {
0x07, 0x00, 0x01, 0x00, 0x7B, 0x00, 0x76, 0x20, 0x44, 0x65,
0x6D, 0x6F, 0x20, 0x4B, 0x65, 0x79, 0x62, 0x6F, 0x61, 0x72,
0x64, 0x09, 0x01, 0x01, 0x25, 0x08, 0x4B, 0x65, 0x79, 0x62,
0x6F, 0x61, 0x72, 0x64, 0x09, 0x01, 0x02, 0x25, 0x0E, 0x42,
0x72, 0x6F, 0x61, 0x64, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F,
0x72, 0x70, 0x2E, 0x09, 0x02, 0x00, 0x09, 0x01, 0x00, 0x09,
0x02, 0x01, 0x09, 0x01, 0x11, 0x09, 0x02, 0x02, 0x08, 0x40,
0x09, 0x02, 0x03, 0x08, 0x33, 0x09, 0x02, 0x04, 0x28, 0x01,
0x09, 0x02, 0x05, 0x28, 0x01, 0x09, 0x02, 0x06, 0x35, 0x9F,
0x35, 0x9D, 0x08, 0x22, 0x25, 0x99, 0x05, 0x01, 0x09, 0x06,
0xA1, 0x01, 0x85, 0x01, 0x05, 0x07, 0x19, 0xE0, 0x29, 0xE7,
0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02,
0x95, 0x01, 0x75, 0x08, 0x81, 0x02, 0x00, 0xEC
};
uint8_t sdp_response_0100_00EC[] = {
0x07, 0x00, 0x02, 0x00, 0x7B, 0x00, 0x76, 0x01, 0x95, 0x05,
0x75, 0x01, 0x05, 0x08, 0x19, 0x01, 0x29, 0x05, 0x91, 0x02,
0x95, 0x01, 0x75, 0x03, 0x91, 0x01, 0x95, 0x06, 0x75, 0x08,
0x15, 0x00, 0x25, 0x65, 0x05, 0x07, 0x19, 0x00, 0x29, 0x65,
0x81, 0x00, 0xC0, 0x05, 0x0C, 0x09, 0x01, 0xA1, 0x01, 0x85,
0x02, 0x19, 0x00, 0x29, 0xFF, 0x15, 0x00, 0x25, 0xFF, 0x75,
0x08, 0x95, 0x01, 0x81, 0x00, 0xC0, 0x05, 0x0C, 0x09, 0x01,
0xA1, 0x01, 0x85, 0x05, 0x05, 0x01, 0x09, 0x06, 0xA1, 0x02,
0x05, 0x06, 0x09, 0x20, 0x15, 0x00, 0x25, 0xFF, 0x75, 0x08,
0x95, 0x08, 0x81, 0x00, 0x09, 0x20, 0x15, 0x00, 0x25, 0xFF,
0x75, 0x08, 0x95, 0x08, 0xB1, 0x00, 0xC0, 0x05, 0x0C, 0x09,
0x01, 0xA1, 0x01, 0x85, 0x06, 0x19, 0x00, 0x29, 0xFE, 0x15,
0x00, 0x25, 0xFF, 0x75, 0x08, 0x02, 0x01, 0x62
};
uint8_t sdp_response_0100_0162[] = {
0x07, 0x00, 0x03, 0x00, 0x7B, 0x00, 0x76, 0x95, 0x02, 0x81,
0x00, 0xC0, 0xC0, 0x09, 0x02, 0x07, 0x35, 0x08, 0x35, 0x06,
0x09, 0x03, 0x09, 0x09, 0x01, 0x00, 0x09, 0x02, 0x0B, 0x09,
0x01, 0x00, 0x09, 0x02, 0x0D, 0x28, 0x00, 0x09, 0x02, 0x0E,
0x28, 0x01, 0x36, 0x00, 0x52, 0x09, 0x00, 0x00, 0x0A, 0x00,
0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x35, 0x03, 0x19, 0x12,
0x00, 0x09, 0x00, 0x04, 0x35, 0x0D, 0x35, 0x06, 0x19, 0x01,
0x00, 0x09, 0x00, 0x01, 0x35, 0x03, 0x19, 0x00, 0x01, 0x09,
0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, 0x12, 0x00, 0x09,
0x01, 0x00, 0x09, 0x02, 0x00, 0x09, 0x01, 0x00, 0x09, 0x02,
0x01, 0x09, 0x0A, 0x5C, 0x09, 0x02, 0x02, 0x09, 0x20, 0x01,
0x09, 0x02, 0x03, 0x09, 0x01, 0x07, 0x09, 0x02, 0x04, 0x28,
0x01, 0x09, 0x02, 0x05, 0x09, 0x02, 0x01, 0xD8
};
uint8_t sdp_response_0100_01D8[] = {
0x07, 0x00, 0x04, 0x00, 0x05, 0x00, 0x02, 0x00, 0x02, 0x00
};
uint8_t sdp_response_1200[] = {
0x07, 0x00, 0x01, 0x00, 0x5B, 0x00, 0x58, 0x36, 0x00, 0x55,
0x36, 0x00, 0x52, 0x09, 0x00, 0x00, 0x0A, 0x00, 0x01, 0x00,
0x01, 0x09, 0x00, 0x01, 0x35, 0x03, 0x19, 0x12, 0x00, 0x09,
0x00, 0x04, 0x35, 0x0D, 0x35, 0x06, 0x19, 0x01, 0x00, 0x09,
0x00, 0x01, 0x35, 0x03, 0x19, 0x00, 0x01, 0x09, 0x00, 0x09,
0x35, 0x08, 0x35, 0x06, 0x19, 0x12, 0x00, 0x09, 0x01, 0x00,
0x09, 0x02, 0x00, 0x09, 0x01, 0x00, 0x09, 0x02, 0x01, 0x09,
0x0A, 0x5C, 0x09, 0x02, 0x02, 0x09, 0x20, 0x01, 0x09, 0x02,
0x03, 0x09, 0x01, 0x07, 0x09, 0x02, 0x04, 0x28, 0x01, 0x09,
0x02, 0x05, 0x09, 0x00, 0x02, 0x00
};
void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
bd_addr_t event_addr;
@ -58,13 +135,53 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint
uint16_t remote_cid;
char pin[20];
int i;
uint16_t UUID;
uint16_t cont = 0;
uint8_t * response;
uint16_t len;
switch (packet_type) {
case L2CAP_DATA_PACKET:
// just dump data for now
printf("source cid %x -- ", channel);
hexdump( packet, size );
//
if (packet[0] != 0x06) return; // no sdp request
UUID = packet[8] << 8 | packet [9];
switch (UUID) {
case 0x0100:
if (packet[19]){
cont = packet[20] << 8 | packet [21];
}
switch (cont) {
case 0:
response = sdp_response_0100;
len = sizeof(sdp_response_0100);
break;
case 0x0076:
response = sdp_response_0100_0076;
len = sizeof(sdp_response_0100_0076);
break;
case 0x00EC:
response = sdp_response_0100_00EC;
len = sizeof(sdp_response_0100_00EC);
break;
case 0x0162:
response = sdp_response_0100_0162;
len = sizeof(sdp_response_0100_0162);
break;
case 0x01d8:
response = sdp_response_0100_01D8;
len = sizeof(sdp_response_0100_01D8);
break;
}
memcpy(response+1, &packet[1], 2);
bt_send_l2cap( channel, response, len);
printf("answering 0100 request, cont %u\n", cont);
break;
case 0x1200:
memcpy(sdp_response_1200+1, &packet[1], 2);
bt_send_l2cap( channel, sdp_response_1200, sizeof(sdp_response_1200));
printf("answering 1200 request\n");
break;
}
break;
case HCI_EVENT_PACKET:
@ -106,7 +223,7 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint
break;
case HCI_EVENT_PIN_CODE_REQUEST:
// inform about pin code request
/* // inform about pin code request
printf("Please enter PIN here: ");
fgets(pin, 20, stdin);
i = strlen(pin)-1;
@ -114,6 +231,8 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint
pin[i] = '\0';
}
printf("PIN = '%s'\n", pin);
*/
strcpy(pin, "0000");
bt_flip_addr(event_addr, &packet[2]);
bt_send_cmd(&hci_pin_code_request_reply, &event_addr, strlen(pin), pin);
break;
@ -129,16 +248,6 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint
print_bd_addr(event_addr);
printf(", handle 0x%02x, psm 0x%02x, local cid 0x%02x, remote cid 0x%02x\n",
handle, psm, local_cid, READ_BT_16(packet, 15));
if (psm == PSM_HID_CONTROL){
hid_control = local_cid;
}
if (psm == PSM_HID_INTERRUPT){
hid_interrupt = local_cid;
}
if (hid_control && hid_interrupt){
bt_send_cmd(&hci_switch_role_command, &event_addr, 0);
}
} else {
printf("L2CAP connection to device ");
print_bd_addr(event_addr);
@ -146,14 +255,7 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint
exit(1);
}
break;
case HCI_EVENT_ROLE_CHANGE: {
//HID Control: 0x06 bytes - SET_FEATURE_REPORT [ 53 F4 42 03 00 00 ]
uint8_t set_feature_report[] = { 0x53, 0xf4, 0x42, 0x03, 0x00, 0x00};
bt_send_l2cap(hid_control, (uint8_t*) &set_feature_report, sizeof(set_feature_report));
break;
}
case HCI_EVENT_DISCONNECTION_COMPLETE:
// connection closed -> quit tes app
printf("Basebank connection closed\n");
@ -185,6 +287,7 @@ int main (int argc, const char * argv[]){
return err;
}
bt_register_packet_handler(packet_handler);
bt_send_cmd(&l2cap_register_service, PSM_SDP, 250);
bt_send_cmd(&l2cap_register_service, PSM_HID_CONTROL, 250);
bt_send_cmd(&l2cap_register_service, PSM_HID_INTERRUPT, 250);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2009 by Matthias Ringwald
* Copyright (C) 2010 by Matthias Ringwald
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -30,7 +30,7 @@
*/
/*
* test.c
* rfcomm.c
*
* Command line parsing and debug option
* added by Vladimir Vyskocil <vladimir.vyskocil@gmail.com>
@ -48,264 +48,32 @@
#include <sys/stat.h>
#include <btstack/btstack.h>
#include <btstack/sdp_util.h>
// copy and paste from BTnut
// Control field values bit no. 1 2 3 4 5 6 7 8
#define BT_RFCOMM_SABM 0x3F // 1 1 1 1 P/F 1 0 0
#define BT_RFCOMM_UA 0x73 // 1 1 0 0 P/F 1 1 0
#define BT_RFCOMM_DM 0x0F // 1 1 1 1 P/F 0 0 0
#define BT_RFCOMM_DM_PF 0x1F
#define BT_RFCOMM_DISC 0x53 // 1 1 0 0 P/F 0 1 1
#define BT_RFCOMM_UIH 0xEF // 1 1 1 1 P/F 1 1 1
#define BT_RFCOMM_UIH_PF 0xFF
// Multiplexer message types
#define BT_RFCOMM_PN_CMD 0x83
#define BT_RFCOMM_PN_RSP 0x81
#define BT_RFCOMM_TEST_CMD 0x23
#define BT_RFCOMM_TEST_RSP 0x21
#define BT_RFCOMM_FCON_CMD 0xA3
#define BT_RFCOMM_FCON_RSP 0xA1
#define BT_RFCOMM_FCOFF_CMD 0x63
#define BT_RFCOMM_FCOFF_RSP 0x61
#define BT_RFCOMM_MSC_CMD 0xE3
#define BT_RFCOMM_MSC_RSP 0xE1
#define BT_RFCOMM_RPN_CMD 0x93
#define BT_RFCOMM_RPN_RSP 0x91
#define BT_RFCOMM_RLS_CMD 0x53
#define BT_RFCOMM_RLS_RSP 0x51
#define BT_RFCOMM_NSC_RSP 0x11
// FCS calc
#define BT_RFCOMM_CODE_WORD 0xE0 // pol = x8+x2+x1+1
#define BT_RFCOMM_CRC_CHECK_LEN 3
#define BT_RFCOMM_UIHCRC_CHECK_LEN 2
#define NR_CREDITS 0x30
bd_addr_t addr = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
int RFCOMM_CHANNEL_ID = 1;
char PIN[] = "0000";
int DEBUG = 0;
hci_con_handle_t con_handle;
uint16_t source_cid;
int fifo_fd;
// used to assemble rfcomm packets
uint8_t rfcomm_out_buffer[1000];
/**
* @param credits - only used for RFCOMM flow control in UIH wiht P/F = 1
*/
void rfcomm_send_packet(uint16_t source_cid, uint8_t address, uint8_t control, uint8_t credits, uint8_t *data, uint16_t len){
uint16_t pos = 0;
uint8_t crc_fields = 3;
rfcomm_out_buffer[pos++] = address;
rfcomm_out_buffer[pos++] = control;
// length field can be 1 or 2 octets
if (len < 128){
rfcomm_out_buffer[pos++] = (len << 1)| 1; // bits 0-6
} else {
rfcomm_out_buffer[pos++] = (len & 0x7f) << 1; // bits 0-6
rfcomm_out_buffer[pos++] = len >> 7; // bits 7-14
crc_fields++;
}
// add credits for UIH frames when PF bit is set
if (control == BT_RFCOMM_UIH_PF){
rfcomm_out_buffer[pos++] = credits;
}
// copy actual data
memcpy(&rfcomm_out_buffer[pos], data, len);
pos += len;
// UIH frames only calc FCS over address + control (5.1.1)
if ((control & 0xef) == BT_RFCOMM_UIH){
crc_fields = 2;
}
rfcomm_out_buffer[pos++] = crc8_calc(rfcomm_out_buffer, crc_fields); // calc fcs
bt_send_l2cap( source_cid, rfcomm_out_buffer, pos);
}
void _bt_rfcomm_send_sabm(uint16_t source_cid, uint8_t initiator, uint8_t channel)
{
uint8_t address = (1 << 0) | (initiator << 1) | (initiator << 1) | (channel << 3);
rfcomm_send_packet(source_cid, address, BT_RFCOMM_SABM, 0, NULL, 0);
}
void _bt_rfcomm_send_uih_data(uint16_t source_cid, uint8_t initiator, uint8_t channel, uint8_t *data, uint16_t len) {
uint8_t address = (1 << 0) | (initiator << 1) | (initiator << 1) | (channel << 3);
rfcomm_send_packet(source_cid, address, BT_RFCOMM_UIH, 0, data, len);
}
void _bt_rfcomm_send_uih_msc_cmd(uint16_t source_cid, uint8_t initiator, uint8_t channel, uint8_t signals)
{
uint8_t address = (1 << 0) | (initiator << 1); // EA and C/R bit set - always server channel 0
uint8_t payload[4];
uint8_t pos = 0;
payload[pos++] = BT_RFCOMM_MSC_CMD;
payload[pos++] = 2 << 1 | 1; // len
payload[pos++] = (1 << 0) | (1 << 1) | (0 << 2) | (channel << 3); // shouldn't D = initiator = 1 ?
payload[pos++] = signals;
rfcomm_send_packet(source_cid, address, BT_RFCOMM_UIH, 0, (uint8_t *) payload, pos);
}
void _bt_rfcomm_send_uih_pn_command(uint16_t source_cid, uint8_t initiator, uint8_t channel, uint16_t max_frame_size){
uint8_t payload[10];
uint8_t address = (1 << 0) | (initiator << 1); // EA and C/R bit set - always server channel 0
uint8_t pos = 0;
payload[pos++] = BT_RFCOMM_PN_CMD;
payload[pos++] = 8 << 1 | 1; // len
payload[pos++] = channel << 1;
payload[pos++] = 0xf0; // pre defined for Bluetooth, see 5.5.3 of TS 07.10 Adaption for RFCOMM
payload[pos++] = 0; // priority
payload[pos++] = 0; // max 60 seconds ack
payload[pos++] = max_frame_size & 0xff; // max framesize low
payload[pos++] = max_frame_size >> 8; // max framesize high
payload[pos++] = 0x00; // number of retransmissions
payload[pos++] = 0x00; // unused error recovery window
rfcomm_send_packet(source_cid, address, BT_RFCOMM_UIH, 0, (uint8_t *) payload, pos);
}
// input from command line arguments
bd_addr_t addr = { };
uint16_t con_handle;
int rfcomm_channel = 1;
char pin[17];
void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
bd_addr_t event_addr;
static uint8_t msc_resp_send = 0;
static uint8_t msc_resp_received = 0;
static uint8_t credits_used = 0;
static uint8_t credits_free = 0;
uint8_t packet_processed = 0;
uint16_t mtu;
uint16_t psm;
uint16_t rfcomm_channel_id;
uint16_t rfcomm_channel_nr;
uint8_t credits;
static uint32_t packet_counter = 0;
static char packet_info[30]; // "packets: 1234567890"
switch (packet_type) {
case L2CAP_DATA_PACKET:
// rfcomm: data[8] = addr
// rfcomm: data[9] = command
// received 1. message BT_RF_COMM_UA
if (size == 4 && packet[1] == BT_RFCOMM_UA && packet[0] == 0x03){
packet_processed++;
printf("Received RFCOMM unnumbered acknowledgement for channel 0 - multiplexer working\n");
printf("Sending UIH Parameter Negotiation Command\n");
_bt_rfcomm_send_uih_pn_command(source_cid, 1, RFCOMM_CHANNEL_ID, 100);
}
// received UIH Parameter Negotiation Response
if (size == 14 && packet[1] == BT_RFCOMM_UIH && packet[3] == BT_RFCOMM_PN_RSP){
packet_processed++;
printf("UIH Parameter Negotiation Response\n");
printf("Sending SABM #%u\n", RFCOMM_CHANNEL_ID);
_bt_rfcomm_send_sabm(source_cid, 1, RFCOMM_CHANNEL_ID);
}
// received 2. message BT_RF_COMM_UA
if (size == 4 && packet[1] == BT_RFCOMM_UA && packet[0] == ((RFCOMM_CHANNEL_ID << 3) | 3) ){
packet_processed++;
printf("Received RFCOMM unnumbered acknowledgement for channel %u - channel opened\n", RFCOMM_CHANNEL_ID);
printf("Sending MSC 'I'm ready'\n");
_bt_rfcomm_send_uih_msc_cmd(source_cid, 1, RFCOMM_CHANNEL_ID, 0x8d); // ea=1,fc=0,rtc=1,rtr=1,ic=0,dv=1
}
// received BT_RFCOMM_MSC_CMD
if (size == 8 && packet[1] == BT_RFCOMM_UIH && packet[3] == BT_RFCOMM_MSC_CMD){
packet_processed++;
printf("Received BT_RFCOMM_MSC_CMD\n");
printf("Responding to 'I'm ready'\n");
// fine with this
uint8_t address = packet[0] | 2; // set response
packet[3] = BT_RFCOMM_MSC_RSP; // " "
rfcomm_send_packet(source_cid, address, BT_RFCOMM_UIH, 0x30, (uint8_t*)&packet[3], 4);
msc_resp_send = 1;
}
// received BT_RFCOMM_MSC_RSP
if (size == 8 && packet[1] == BT_RFCOMM_UIH && packet[3] == BT_RFCOMM_MSC_RSP){
packet_processed++;
msc_resp_received = 1;
}
if (packet[1] == BT_RFCOMM_UIH && packet[0] == ((RFCOMM_CHANNEL_ID<<3)|1)){
packet_processed++;
credits_used++;
if(DEBUG){
printf("RX: address %02x, control %02x: ", packet[0], packet[1]);
hexdump( (uint8_t*) &packet[3], size-4);
}
int written = 0;
int length = size-4;
int start_of_data = 3;
//write data to fifo
while (length) {
if ((written = write(fifo_fd, &packet[start_of_data], length)) == -1) {
printf("Error writing to FIFO\n");
} else {
length -= written;
}
}
}
if (packet[1] == BT_RFCOMM_UIH_PF && packet[0] == ((RFCOMM_CHANNEL_ID<<3)|1)){
packet_processed++;
credits_used++;
if (!credits_free) {
printf("Got %u credits, can send!\n", packet[2]);
}
credits_free = packet[2];
if(DEBUG){
printf("RX: address %02x, control %02x: ", packet[0], packet[1]);
hexdump( (uint8_t *) &packet[4], size-5);
}
int written = 0;
int length = size-5;
int start_of_data = 4;
//write data to fifo
while (length) {
if ((written = write(fifo_fd, &packet[start_of_data], length)) == -1) {
printf("Error writing to FIFO\n");
} else {
length -= written;
}
}
}
uint8_t send_credits_packet = 0;
if (credits_used >= NR_CREDITS ) {
send_credits_packet = 1;
credits_used -= NR_CREDITS;
}
if (msc_resp_send && msc_resp_received) {
send_credits_packet = 1;
msc_resp_send = msc_resp_received = 0;
printf("RFCOMM up and running!\n");
}
if (send_credits_packet) {
// send 0x30 credits
uint8_t initiator = 1;
uint8_t address = (1 << 0) | (initiator << 1) | (initiator << 1) | (RFCOMM_CHANNEL_ID << 3);
rfcomm_send_packet(source_cid, address, BT_RFCOMM_UIH_PF, NR_CREDITS, NULL, 0);
}
if (!packet_processed){
// just dump data for now
printf("??: address %02x, control %02x: ", packet[0], packet[1]);
hexdump( packet, size );
}
case RFCOMM_DATA_PACKET:
printf("Received RFCOMM data on channel id %u, size %u\n", channel, size);
hexdump(packet, size);
break;
case HCI_EVENT_PACKET:
switch (packet[0]) {
case BTSTACK_EVENT_POWERON_FAILED:
@ -317,68 +85,75 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint
case BTSTACK_EVENT_STATE:
// bt stack activated, get started - use authentication yes/no
if (packet[2] == HCI_STATE_WORKING) {
bt_send_cmd(&hci_write_authentication_enable, 1);
bt_send_cmd(&hci_write_class_of_device, 0x1f00);
}
break;
case HCI_EVENT_LINK_KEY_REQUEST:
// link key request
bt_flip_addr(event_addr, &packet[2]);
bt_send_cmd(&hci_link_key_request_negative_reply, &event_addr);
break;
case HCI_EVENT_PIN_CODE_REQUEST:
// inform about pin code request
bt_flip_addr(event_addr, &packet[2]);
bt_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, PIN);
printf("Please enter PIN %s on remote device\n", PIN);
break;
case L2CAP_EVENT_CHANNEL_OPENED:
// inform about new l2cap connection
bt_flip_addr(event_addr, &packet[3]);
uint16_t psm = READ_BT_16(packet, 11);
source_cid = READ_BT_16(packet, 13);
con_handle = READ_BT_16(packet, 9);
if (packet[2] == 0) {
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",
con_handle, psm, source_cid, READ_BT_16(packet, 15));
// send SABM command on dlci 0
printf("Sending SABM #0\n");
_bt_rfcomm_send_sabm(source_cid, 1, 0);
} else {
printf("L2CAP connection to device ");
print_bd_addr(event_addr);
printf(" failed. status code %u\n", packet[2]);
exit(1);
}
break;
case HCI_EVENT_DISCONNECTION_COMPLETE:
// connection closed -> quit test app
printf("Basebank connection closed, exit.\n");
exit(0);
break;
case HCI_EVENT_COMMAND_COMPLETE:
// connect to RFCOMM device (PSM 0x03) at addr
if ( COMMAND_COMPLETE_EVENT(packet, hci_write_authentication_enable) ) {
bt_send_cmd(&l2cap_create_channel, addr, 0x03);
if ( COMMAND_COMPLETE_EVENT(packet, hci_write_class_of_device) ) {
// outgoing only:
bt_send_cmd(&rfcomm_create_channel, addr, rfcomm_channel);
}
if ( COMMAND_COMPLETE_EVENT(packet, hci_read_bd_addr) ) {
bt_flip_addr(event_addr, &packet[6]);
printf("Own BD_ADDR: ");
print_bd_addr(event_addr);
printf("\n");
}
break;
case HCI_EVENT_PIN_CODE_REQUEST:
// inform about pin code request
printf("Using PIN 0000\n");
bt_flip_addr(event_addr, &packet[2]);
bt_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000");
break;
case RFCOMM_EVENT_INCOMING_CONNECTION:
// data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
bt_flip_addr(event_addr, &packet[2]);
rfcomm_channel_nr = packet[8];
rfcomm_channel_id = READ_BT_16(packet, 9);
printf("RFCOMM channel %u requested for ", rfcomm_channel_nr);
print_bd_addr(event_addr);
printf("\n");
bt_send_cmd(&rfcomm_accept_connection, rfcomm_channel_id);
break;
case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE:
// data: event(8), len(8), status (8), address (48), server channel(8), rfcomm_cid(16), max frame size(16)
if (packet[2]) {
printf("RFCOMM channel open failed, status %u\n", packet[2]);
} else {
rfcomm_channel_id = READ_BT_16(packet, 10);
mtu = READ_BT_16(packet, 12);
printf("RFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u\n", rfcomm_channel_id, mtu);
uint8_t message[] = "Hello World from BTstack!\n";
// bt_send_rfcomm(rfcomm_channel_id, message, sizeof(message));
}
break;
case RFCOMM_EVENT_CREDITS:
// how many? for whom?
rfcomm_channel_id = READ_BT_16(packet, 2);
credits = packet[4];
//
packet_counter++;
sprintf(packet_info, "\rPacket counter: %09u", packet_counter);
bt_send_rfcomm(rfcomm_channel_id, packet_info, strlen(packet_info));
break;
case HCI_EVENT_DISCONNECTION_COMPLETE:
// connection closed -> quit test app
printf("Basebank connection closed\n");
break;
default:
// unhandled event
if(DEBUG) printf("unhandled event : %02x\n", packet[0]);
break;
}
break;
default:
// unhandled packet type
if(DEBUG) printf("unhandled packet type : %02x\n", packet_type);
break;
}
}
@ -387,9 +162,79 @@ void usage(const char *name){
fprintf(stderr, "Usage : %s [-a|--address aa:bb:cc:dd:ee:ff] [-c|--channel n] [-p|--pin nnnn]\n", name);
}
#define FIFO_NAME "/tmp/rfcomm0"
uint8_t service_buffer[100];
void create_spp_service(uint8_t *service){
uint8_t* attribute;
de_create_sequence(service);
// 0x0001 "Service Class ID List"
de_add_number(service, DE_UINT, DE_SIZE_16, 0x0001);
attribute = de_push_sequence(service);
{
de_add_number(attribute, DE_UUID, DE_SIZE_16, 0x1101 );
}
de_pop_sequence(service, attribute);
// 0x0004 "Protocol Descriptor List"
de_add_number(service, DE_UINT, DE_SIZE_16, 0x0004);
attribute = de_push_sequence(service);
{
uint8_t* l2cpProtocol = de_push_sequence(attribute);
{
de_add_number(l2cpProtocol, DE_UUID, DE_SIZE_16, 0x0100);
}
de_pop_sequence(attribute, l2cpProtocol);
uint8_t* rfcomm = de_push_sequence(attribute);
{
de_add_number(rfcomm, DE_UUID, DE_SIZE_16, 0x0003); // rfcomm_service
de_add_number(rfcomm, DE_UINT, DE_SIZE_8, 0x0001); // rfcomm channel
}
de_pop_sequence(attribute, rfcomm);
}
de_pop_sequence(service, attribute);
// 0x0005 "Public Browse Group"
de_add_number(service, DE_UINT, DE_SIZE_16, 0x0005); // public browse group
attribute = de_push_sequence(service);
{
de_add_number(attribute, DE_UUID, DE_SIZE_16, 0x1002 );
}
de_pop_sequence(service, attribute);
// 0x0006
de_add_number(service, DE_UINT, DE_SIZE_16, SDP_LanguageBaseAttributeIDList);
attribute = de_push_sequence(service);
{
de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x656e);
de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x006a);
de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x0100);
}
de_pop_sequence(service, attribute);
// 0x0009 "Bluetooth Profile Descriptor List"
de_add_number(service, DE_UINT, DE_SIZE_16, 0x0009);
attribute = de_push_sequence(service);
{
uint8_t *sppProfile = de_push_sequence(attribute);
{
de_add_number(sppProfile, DE_UUID, DE_SIZE_16, 0x1101);
de_add_number(sppProfile, DE_UINT, DE_SIZE_16, 0x0100);
}
de_pop_sequence(attribute, sppProfile);
}
de_pop_sequence(service, attribute);
// 0x0100 "ServiceName"
de_add_number(service, DE_UINT, DE_SIZE_16, 0x0100);
de_add_data(service, DE_STRING, 3, (uint8_t *) "CMD");
}
int main (int argc, const char * argv[]){
#if 1
int arg = 1;
if (argc == 1){
@ -405,45 +250,50 @@ int main (int argc, const char * argv[]){
}
} else if (!strcmp(argv[arg], "-c") || !strcmp(argv[arg], "--channel")) {
arg++;
if(arg >= argc || !sscanf(argv[arg], "%d", &RFCOMM_CHANNEL_ID)){
if(arg >= argc || !sscanf(argv[arg], "%d", &rfcomm_channel)){
usage(argv[0]);
return 1;
}
} else if (!strcmp(argv[arg], "-p") || !strcmp(argv[arg], "--pin")) {
arg++;
int pin1,pin2,pin3,pin4;
if(arg >= argc || sscanf(argv[arg], "%1d%1d%1d%1d", &pin1, &pin2, &pin3, &pin4) != 4){
if(arg >= argc) {
usage(argv[0]);
return 1;
}
snprintf(PIN, 5, "%01d%01d%01d%01d", pin1, pin2, pin3, pin4);
strncpy(pin, argv[arg], 16);
pin[16] = 0;
} else {
usage(argv[0]);
return 1;
}
arg++;
}
printf("Waiting for client to open %s...\n", FIFO_NAME);
int err = mknod(FIFO_NAME, S_IFIFO | 0666, 0);
if(err >= 0 || errno == EEXIST){
fifo_fd = open(FIFO_NAME, O_WRONLY);
run_loop_init(RUN_LOOP_POSIX);
err = bt_open();
if (err) {
fprintf(stderr,"Failed to open connection to BTdaemon, err %d\n",err);
return 1;
}
printf("Trying connection to ");
print_bd_addr(addr);
printf(" channel %d\n", RFCOMM_CHANNEL_ID);
bt_register_packet_handler(packet_handler);
bt_send_cmd(&btstack_set_power_mode, HCI_POWER_ON );
run_loop_execute();
bt_close();
} else {
fprintf(stderr, "Failed mknod %s, errno %d\n", FIFO_NAME, errno);
#endif
run_loop_init(RUN_LOOP_POSIX);
int err = bt_open();
if (err) {
fprintf(stderr,"Failed to open connection to BTdaemon, err %d\n",err);
return 1;
}
bt_register_packet_handler(packet_handler);
#if 1
printf("Trying connection to ");
print_bd_addr(addr);
printf(" channel %d\n", rfcomm_channel);
#endif
// register RFCOM channel
bt_send_cmd(&rfcomm_register_service, 1, 100);
// register SDP for our SPP
create_spp_service(service_buffer);
bt_send_cmd(&sdp_register_service_record, service_buffer);
bt_send_cmd(&btstack_set_power_mode, HCI_POWER_ON );
run_loop_execute();
bt_close();
return 0;
}

View File

@ -45,7 +45,8 @@
// bd_addr_t addr = {0x00, 0x03, 0xc9, 0x3d, 0x77, 0x43 }; // Think Outside Keyboard
// bd_addr_t addr = {0x00, 0x19, 0x1d, 0x90, 0x44, 0x68 }; // WiiMote
bd_addr_t addr = {0x76, 0x6d, 0x62, 0xdb, 0xca, 0x73 }; // iPad
// bd_addr_t addr = {0x76, 0x6d, 0x62, 0xdb, 0xca, 0x73 }; // iPad
bd_addr_t addr = {0x00, 0x06, 0x66, 0x42, 0x16, 0xf5 }; // iControlPad-16f5
hci_con_handle_t con_handle;
uint16_t source_cid_interrupt;
@ -61,16 +62,6 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint
// just dump data for now
printf("source cid %x -- ", channel);
hexdump( packet, size );
// HOME => disconnect
if (packet[0] == 0xA1) { // Status report
if (packet[1] == 0x30 || packet[1] == 0x31) { // type 0x30 or 0x31
if (packet[3] & 0x080) { // homne button pressed
printf("Disconnect baseband\n");
bt_send_cmd(&hci_disconnect, con_handle, 0x13); // remote closed connection
}
}
}
break;
case HCI_EVENT_PACKET:
@ -85,7 +76,7 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint
case BTSTACK_EVENT_STATE:
// bt stack activated, get started - disable pairing
if (packet[2] == HCI_STATE_WORKING) {
bt_send_cmd(&hci_write_authentication_enable, 0);
bt_send_cmd(&hci_write_authentication_enable, 1);
}
break;
@ -100,7 +91,7 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint
// inform about pin code request
printf("Please enter PIN 0000 on remote device\n");
bt_flip_addr(event_addr, &packet[2]);
bt_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000");
bt_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "1234");
break;
case L2CAP_EVENT_CHANNEL_OPENED:
@ -118,8 +109,6 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint
if (psm == 0x13) {
source_cid_interrupt = source_cid;
// interupt channel openedn succesfully, now open control channel, too.
bt_send_cmd(&l2cap_create_channel, event_addr, 0x11);
} else {
source_cid_control = source_cid;
// request acceleration data..
@ -128,6 +117,7 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint
// stop blinking
// uint8_t setLEDs[] = { 0x52, 0x11, 0x10 };
// bt_send_l2cap( source_cid, setLEDs, sizeof(setLEDs));
bt_send_cmd(&l2cap_create_channel, event_addr, 0x13);
}
} else {
printf("L2CAP connection to device ");
@ -146,7 +136,7 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint
case HCI_EVENT_COMMAND_COMPLETE:
// connect to HID device (PSM 0x13) at addr
if ( COMMAND_COMPLETE_EVENT(packet, hci_write_authentication_enable) ) {
bt_send_cmd(&l2cap_create_channel, addr, 0x13);
bt_send_cmd(&l2cap_create_channel, addr, 0x11);
printf("Press 1+2 on WiiMote to make it discoverable - Press HOME to disconnect later :)\n");
}
break;

View File

@ -79,6 +79,7 @@ btstack_packet_handler_t bt_register_packet_handler(btstack_packet_handler_t han
void bt_send_acl(uint8_t * data, uint16_t len);
void bt_send_l2cap(uint16_t local_cid, uint8_t *data, uint16_t len);
void bt_send_rfcomm(uint16_t rfcom_cid, uint8_t *data, uint16_t len);
#if defined __cplusplus
}

View File

@ -143,6 +143,30 @@ extern "C" {
// data: event(8), len(8), local_cid(16), credits(8)
#define L2CAP_EVENT_CREDITS 0x74
// RFCOMM EVENTS
// data: event(8), len(8), status (8), address (48), server channel(8), rfcomm_cid(16), max frame size(16)
// status: 0 = OK
#define RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE 0x80
// data: event(8), len(8), channelID(8)
// status: 0 = OK
#define RFCOMM_EVENT_CHANNEL_CLOSED 0x81
// data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
#define RFCOMM_EVENT_INCOMING_CONNECTION 0x82
// data: event (8), len(8), rfcommid (16), ...
#define RFCOMM_EVENT_REMOTE_LINE_STATUS 0x83
// data: event(8), len(8), local_cid(16), credits(8)
#define RFCOMM_EVENT_CREDITS 0x84
// data: event(8), len(8), status (8), registration id(16), rfcomm server channel id (8)
#define RFCOMM_EVENT_SERVICE_REGISTERED 0x85
// data: event(8), len(8), service_record_handle(32)
#define SDP_SERVICE_REGISTERED 0x90
@ -173,6 +197,8 @@ extern "C" {
#define L2CAP_CONFIG_RESPONSE_RESULT_REJECTED 0x68
#define L2CAP_CONFIG_RESPONSE_RESULT_UNKNOWN_OPTIONS 0x69
#define RFCOMM_MULTIPLEXER_STOPPED 0x70
/**
* Default INQ Mode
*/

View File

@ -4,7 +4,7 @@ PACKAGE=BTstack
svn update
VERSION=0.2
VERSION=0.3
REVISION=`svn info | grep Revision | cut -d " " -f 2`
ARCHIVE=$PACKAGE-$VERSION-$REVISION.deb
@ -34,6 +34,10 @@ cp resources/Silver*.png $PACKAGE/System/Library/Frameworks/UIKit.framework/
mkdir -p $PACKAGE/Library/LaunchDaemons/
cp resources/ch.ringwald.BTstack.plist $PACKAGE/Library/LaunchDaemons/
# PrefsBundle
pushd PrefsBundle ; make package ; popd
cp -r PrefsBundle/_/* $PACKAGE
# prerm: called on remove and upgrade - stop daemon and get rid of BlueToolH4
echo "#!/bin/sh" > $PACKAGE/DEBIAN/prerm
echo "/bin/launchctl unload /Library/LaunchDaemons/ch.ringwald.BTstack.plist 2&> /dev/null" >> $PACKAGE/DEBIAN/prerm
@ -56,7 +60,6 @@ echo "#!/bin/sh" > $PACKAGE/DEBIAN/postinst
echo "/bin/launchctl load /Library/LaunchDaemons/ch.ringwald.BTstack.plist 2&> /dev/null" >> $PACKAGE/DEBIAN/postinst
chmod +x $PACKAGE/DEBIAN/postinst
# set ownership to root:root
sudo chown -R 0:0 $PACKAGE

View File

@ -17,17 +17,18 @@
9C04B876107D2B7C002A63D0 /* run_loop_cocoa.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CEB4DAA10753B4B00DD5720 /* run_loop_cocoa.m */; };
9C04B87A107D2BA7002A63D0 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C04B879107D2BA7002A63D0 /* CoreFoundation.framework */; };
9C05FC971020D3F300255261 /* socket_connection.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C00F7301017ACC3008DAB17 /* socket_connection.c */; };
9C18015C108BAA7200824BE7 /* libusb-1.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C18015B108BAA7200824BE7 /* libusb-1.0.dylib */; };
9C2169D212F9FB7000072B00 /* platform_iphone.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C2169D112F9FB7000072B00 /* platform_iphone.m */; };
9C255D4A11E0C59900CDD689 /* run_loop_embedded.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C255D4911E0C59900CDD689 /* run_loop_embedded.c */; };
9C3AED88122C201C008046F4 /* remote_device_db_iphone.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C3AED87122C201C008046F4 /* remote_device_db_iphone.m */; };
9C46FC3A0FA906F700ABEF05 /* hci_transport_h4.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C46FC360FA906F700ABEF05 /* hci_transport_h4.c */; };
9C77E79210667F0600F39DCF /* platform_iphone.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C77E79110667F0600F39DCF /* platform_iphone.c */; };
9C5E0F0E12DE39250013EF2C /* hci_transport_usb.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C2071F210014D3200A07EA4 /* hci_transport_usb.c */; };
9C7B5AC0100BD3340065D87E /* linked_list.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C7B5ABF100BD3340065D87E /* linked_list.c */; };
9C7B5D01100FC9AE0065D87E /* btstack.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CC813A10FFC0774002816F9 /* btstack.c */; };
9C7B5D03100FC9BB0065D87E /* test.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C7B5B7E100D04450065D87E /* test.c */; };
9C7B5D0D100FC9CE0065D87E /* linked_list.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C7B5ABF100BD3340065D87E /* linked_list.c */; };
9C7ECBB50FCC95DD0085DAC5 /* hci_dump.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C7ECBB40FCC95DD0085DAC5 /* hci_dump.c */; };
9C88500E0FBF6702004980E4 /* l2cap.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C88500C0FBF6702004980E4 /* l2cap.c */; };
9C9F1A3D122F02DD004E21AC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C9F1A3C122F02DD004E21AC /* Foundation.framework */; };
9CB9846B11BC32A800A2F346 /* sdp_util.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CB9846A11BC32A800A2F346 /* sdp_util.c */; };
9CC813A50FFC0A51002816F9 /* daemon.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CC813A40FFC0A51002816F9 /* daemon.c */; };
9CCE6CEA1025BD0000FCE9F4 /* hci.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C46FC340FA906F700ABEF05 /* hci.c */; };
@ -68,9 +69,9 @@
9C13C9FC10ECED6300B04243 /* BTDevice.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; name = BTDevice.m; path = CocoaTouch/src/BTDevice.m; sourceTree = "<group>"; };
9C13C9FD10ECED6300B04243 /* BTInquiryViewController.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = BTInquiryViewController.h; path = CocoaTouch/include/BTstack/BTInquiryViewController.h; sourceTree = "<group>"; };
9C13C9FE10ECED6300B04243 /* BTInquiryViewController.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; name = BTInquiryViewController.m; path = CocoaTouch/src/BTInquiryViewController.m; sourceTree = "<group>"; };
9C18015B108BAA7200824BE7 /* libusb-1.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libusb-1.0.dylib"; path = "/usr/local/lib/libusb-1.0.dylib"; sourceTree = "<absolute>"; };
9C1813F71042FCCA00C68F09 /* mitm.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = mitm.c; path = example/mitm.c; sourceTree = "<group>"; };
9C2071F210014D3200A07EA4 /* hci_transport_usb.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = hci_transport_usb.c; path = src/hci_transport_usb.c; sourceTree = "<group>"; };
9C2169D112F9FB7000072B00 /* platform_iphone.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; name = platform_iphone.m; path = src/platform_iphone.m; sourceTree = "<group>"; };
9C255D4911E0C59900CDD689 /* run_loop_embedded.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = run_loop_embedded.c; path = src/run_loop_embedded.c; sourceTree = "<group>"; };
9C255D7611E0DD2C00CDD689 /* hci_transport_h4_stellaris.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = hci_transport_h4_stellaris.c; path = "../../TI/Stellarware/boards/dk-lm3s9b96/bt_init/hci_transport_h4_stellaris.c"; sourceTree = SOURCE_ROOT; };
9C255DB511E10AEB00CDD689 /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = debug.h; path = src/debug.h; sourceTree = "<group>"; };
@ -95,7 +96,6 @@
9C77E7501066680800F39DCF /* SpringBoardAccessExtension.mm */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.cpp.objcpp; name = SpringBoardAccessExtension.mm; path = SpringBoardAccess/SpringBoardAccessExtension.mm; sourceTree = "<group>"; };
9C77E75310666B5D00F39DCF /* SpringBoardAccess.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = SpringBoardAccess.c; path = SpringBoardAccess/SpringBoardAccess.c; sourceTree = "<group>"; };
9C77E75410666B5D00F39DCF /* SpringBoardAccess.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = SpringBoardAccess.h; path = SpringBoardAccess/SpringBoardAccess.h; sourceTree = "<group>"; };
9C77E79110667F0600F39DCF /* platform_iphone.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = platform_iphone.c; path = src/platform_iphone.c; sourceTree = "<group>"; };
9C77E7BC1066AC4100F39DCF /* control */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = control; path = SpringBoardAccess/control; sourceTree = "<group>"; };
9C78A04A103C6734003B2950 /* Default_BTstack.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default_BTstack.png; path = resources/Default_BTstack.png; sourceTree = "<group>"; };
9C78A04B103C6734003B2950 /* Default_BTstackActive.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default_BTstackActive.png; path = resources/Default_BTstackActive.png; sourceTree = "<group>"; };
@ -114,6 +114,7 @@
9C9485C41211D58300B66EF1 /* l2cap-throughput.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = "l2cap-throughput.c"; path = "example/l2cap-throughput.c"; sourceTree = "<group>"; };
9C978672113DC04900380B3E /* ch.ringwald.BTstackTCP.plist */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.plist.xml; name = ch.ringwald.BTstackTCP.plist; path = resources/ch.ringwald.BTstackTCP.plist; sourceTree = "<group>"; };
9C994B8E106BEEB700C70311 /* rfcomm.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = rfcomm.c; path = example/rfcomm.c; sourceTree = "<group>"; };
9C9F1A3C122F02DD004E21AC /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
9CA3C0900FB8B3C4005F48DE /* TODO.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = TODO.txt; sourceTree = "<group>"; };
9CAA573610A5D87400D0E1A9 /* inquiry.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = inquiry.c; path = example/inquiry.c; sourceTree = "<group>"; };
9CB9846A11BC32A800A2F346 /* sdp_util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sdp_util.c; path = src/sdp_util.c; sourceTree = "<group>"; };
@ -149,7 +150,7 @@
buildActionMask = 2147483647;
files = (
9C04B87A107D2BA7002A63D0 /* CoreFoundation.framework in Frameworks */,
9C18015C108BAA7200824BE7 /* libusb-1.0.dylib in Frameworks */,
9C9F1A3D122F02DD004E21AC /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -175,6 +176,7 @@
isa = PBXGroup;
children = (
9CBE154810A354FF00597802 /* package.sh */,
9CA3C0900FB8B3C4005F48DE /* TODO.txt */,
9CEB4B7510715DC200DD5720 /* include */,
9C77E4AD10634E3100F39DCF /* 3rdparty */,
9C78A049103C671D003B2950 /* Resources */,
@ -185,8 +187,8 @@
C6A0FF2B0290797F04C91782 /* Documentation */,
1AB674ADFE9D54B511CA2CBB /* Products */,
9CC152C61009052100223347 /* config.h */,
9CA3C0900FB8B3C4005F48DE /* TODO.txt */,
9C04B879107D2BA7002A63D0 /* CoreFoundation.framework */,
9C9F1A3C122F02DD004E21AC /* Foundation.framework */,
);
name = project;
sourceTree = "<group>";
@ -224,8 +226,8 @@
9C00F7301017ACC3008DAB17 /* socket_connection.c */,
9C00F7311017ACC3008DAB17 /* socket_connection.h */,
9C00F86210191097008DAB17 /* utils.c */,
9C77E79110667F0600F39DCF /* platform_iphone.c */,
9C6459DE1037554B0081A00B /* platform_iphone.h */,
9C2169D112F9FB7000072B00 /* platform_iphone.m */,
9CB9846A11BC32A800A2F346 /* sdp_util.c */,
9CE7CDD711BFF5470096F5B1 /* sdp.c */,
9CFFD48C11C4CD0100A37038 /* sdp.h */,
@ -283,7 +285,6 @@
9C77E4AD10634E3100F39DCF /* 3rdparty */ = {
isa = PBXGroup;
children = (
9C18015B108BAA7200824BE7 /* libusb-1.0.dylib */,
9C77E4AE10634E3100F39DCF /* launch.h */,
9C77E4AF10634E3100F39DCF /* libsubstrate.dylib */,
9C77E4B010634E3100F39DCF /* README */,
@ -400,7 +401,14 @@
isa = PBXProject;
buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "project" */;
compatibilityVersion = "Xcode 3.1";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
Japanese,
French,
German,
);
mainGroup = 08FB7794FE84155DC02AAC07 /* project */;
projectDirPath = "";
projectRoot = "";
@ -437,7 +445,6 @@
9C00F86510191097008DAB17 /* utils.c in Sources */,
9C00F87410191130008DAB17 /* l2cap_signaling.c in Sources */,
9CCE6CEA1025BD0000FCE9F4 /* hci.c in Sources */,
9C77E79210667F0600F39DCF /* platform_iphone.c in Sources */,
9CEB4F17107AAAEF00DD5720 /* run_loop_posix.c in Sources */,
9C04B826107D1CED002A63D0 /* run_loop.c in Sources */,
9C04B876107D2B7C002A63D0 /* run_loop_cocoa.m in Sources */,
@ -445,6 +452,8 @@
9CE7CDD811BFF5470096F5B1 /* sdp.c in Sources */,
9C255D4A11E0C59900CDD689 /* run_loop_embedded.c in Sources */,
9C3AED88122C201C008046F4 /* remote_device_db_iphone.m in Sources */,
9C5E0F0E12DE39250013EF2C /* hci_transport_usb.c in Sources */,
9C2169D212F9FB7000072B00 /* platform_iphone.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -521,6 +530,11 @@
/sw/include,
);
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "-I/usr/local/include";
OTHER_LDFLAGS = (
"-L/usr/local/lib",
"-lusb-1.0",
);
PREBINDING = NO;
SDKROOT = macosx10.5;
};
@ -533,6 +547,11 @@
GCC_C_LANGUAGE_STANDARD = c99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OTHER_CFLAGS = "-I/usr/local/include";
OTHER_LDFLAGS = (
"-L/usr/local/lib",
"-lusb-1.0",
);
PREBINDING = NO;
SDKROOT = macosx10.5;
};
@ -589,6 +608,11 @@
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "-I/usr/local/include";
OTHER_LDFLAGS = (
"-L/usr/local/lib",
"-lusb-1.0",
);
PREBINDING = NO;
SDKROOT = iphoneos2.0;
};

View File

@ -24,6 +24,7 @@ BTdaemon_SOURCES = $(libBTstack_SOURCES) \
l2cap_signaling.c \
$(remote_device_db_sources) \
platform_iphone.m \
rfcomm.c \
sdp.c \
$(springboard_access_sources)

View File

@ -119,6 +119,11 @@ void bt_send_l2cap(uint16_t source_cid, uint8_t *data, uint16_t len){
socket_connection_send_packet(btstack_connection, L2CAP_DATA_PACKET, source_cid, data, len);
}
void bt_send_rfcomm(uint16_t rfcomm_cid, uint8_t *data, uint16_t len){
// send
socket_connection_send_packet(btstack_connection, RFCOMM_DATA_PACKET, rfcomm_cid, data, len);
}
void bt_send_acl(uint8_t * data, uint16_t len){
// send
socket_connection_send_packet(btstack_connection, HCI_ACL_DATA_PACKET, 0, data, len);

View File

@ -51,6 +51,7 @@
#include <btstack/btstack.h>
#include <btstack/linked_list.h>
#include <btstack/run_loop.h>
#include <btstack/rfcomm.h>
#include "hci.h"
#include "hci_dump.h"
@ -127,8 +128,11 @@ static int btstack_command_handler(connection_t *connection, uint8_t *packet, ui
bd_addr_t addr;
uint16_t cid;
uint16_t psm;
uint16_t service_channel;
uint16_t registration_id;
uint16_t mtu;
uint8_t reason;
uint8_t rfcomm_channel;
uint32_t service_record_handle;
client_state_t *client;
@ -223,6 +227,36 @@ static int btstack_command_handler(connection_t *connection, uint8_t *packet, ui
reason = packet[7];
l2cap_decline_connection_internal(cid, reason);
break;
case RFCOMM_CREATE_CHANNEL:
bt_flip_addr(addr, &packet[3]);
rfcomm_channel = packet[9];
rfcomm_create_channel_internal( connection, &addr, rfcomm_channel );
break;
case RFCOMM_DISCONNECT:
cid = READ_BT_16(packet, 3);
reason = packet[5];
rfcomm_disconnect_internal(cid);
break;
case RFCOMM_REGISTER_SERVICE:
registration_id = READ_BT_16(packet, 3);
mtu = READ_BT_16(packet, 5);
rfcomm_register_service_internal(connection, registration_id, mtu);
break;
case RFCOMM_UNREGISTER_SERVICE:
service_channel = READ_BT_16(packet, 3);
rfcomm_unregister_service_internal(service_channel);
break;
case RFCOMM_ACCEPT_CONNECTION:
cid = READ_BT_16(packet, 3);
rfcomm_accept_connection_internal(cid);
break;
case RFCOMM_DECLINE_CONNECTION:
cid = READ_BT_16(packet, 3);
reason = packet[7];
rfcomm_decline_connection_internal(cid);
break;
case SDP_REGISTER_SERVICE_RECORD:
printf("SDP_REGISTER_SERVICE_RECORD size %u\n", size);
sdp_register_service_internal(connection, &packet[3]);
@ -261,6 +295,10 @@ static int daemon_client_handler(connection_t *connection, uint16_t packet_type,
// process l2cap packet...
err = l2cap_send_internal(channel, data, length);
break;
case RFCOMM_DATA_PACKET:
// process l2cap packet...
err = rfcomm_send_internal(channel, data, length);
break;
case DAEMON_EVENT_PACKET:
switch (data[0]) {
case DAEMON_EVENT_CONNECTION_OPENED:
@ -501,8 +539,13 @@ int main (int argc, char * const * argv){
l2cap_register_packet_handler(daemon_packet_handler);
timeout.process = daemon_no_connections_timeout;
#ifdef HAVE_RFCOMM
printf("config.h: HAVE_RFCOMM\n");
rfcomm_init();
rfcomm_register_packet_handler(daemon_packet_handler);
#endif
#ifdef HAVE_SDP
// init SDP
sdp_init();
// sdp_test();
#endif

View File

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

View File

@ -122,6 +122,13 @@ extern "C" {
// unregister SDP Service Record
#define SDP_UNREGISTER_SERVICE_RECORD 0x31
// RFCOMM "HCI" Commands
#define RFCOMM_CREATE_CHANNEL 0x40
#define RFCOMM_DISCONNECT 0x41
#define RFCOMM_REGISTER_SERVICE 0x42
#define RFCOMM_UNREGISTER_SERVICE 0x43
#define RFCOMM_ACCEPT_CONNECTION 0x44
#define RFCOMM_DECLINE_CONNECTION 0x45
//
#define IS_COMMAND(packet, command) (READ_BT_16(packet,0) == command.opcode)

View File

@ -396,3 +396,29 @@ OPCODE(OGF_BTSTACK, SDP_UNREGISTER_SERVICE_RECORD), "4"
// @param service record handle (32)
};
// create rfcomm channel: @param bd_addr(48), channel (8)
const hci_cmd_t rfcomm_create_channel = {
OPCODE(OGF_BTSTACK, RFCOMM_CREATE_CHANNEL), "B1"
};
// disconnect rfcomm disconnect, @param rfcomm_cid(8), reason(8)
const hci_cmd_t rfcomm_disconnect = {
OPCODE(OGF_BTSTACK, RFCOMM_DISCONNECT), "21"
};
// register rfcomm service: @param registration id(16), mtu (16)
const hci_cmd_t rfcomm_register_service = {
OPCODE(OGF_BTSTACK, RFCOMM_REGISTER_SERVICE), "22"
};
// unregister rfcomm service, @param service_channel(16)
const hci_cmd_t rfcomm_unregister_service = {
OPCODE(OGF_BTSTACK, RFCOMM_UNREGISTER_SERVICE), "2"
};
// accept connection @param bd_addr(48), rfcomm_cid (16)
const hci_cmd_t rfcomm_accept_connection = {
OPCODE(OGF_BTSTACK, RFCOMM_ACCEPT_CONNECTION), "2"
// @param source cid (16)
};
// decline rfcomm disconnect,@param bd_addr(48), rfcomm cid (16), reason(8)
const hci_cmd_t rfcomm_decline_connection = {
OPCODE(OGF_BTSTACK, RFCOMM_DECLINE_CONNECTION), "21"
// @param source cid (16), reason(8)
};