mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-04-15 23:42:52 +00:00
manage RFCOMM channel services by name for iOS platform, rework RFCOMM service registration
This commit is contained in:
parent
84aa122ee4
commit
933d8a8084
@ -97,12 +97,12 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint
|
||||
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)
|
||||
// data: event(8), len(8), status (8), address (48), handle(16), 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);
|
||||
rfcomm_channel_id = READ_BT_16(packet, 12);
|
||||
mtu = READ_BT_16(packet, 14);
|
||||
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));
|
||||
|
@ -125,8 +125,8 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint
|
||||
bd_addr_t event_addr;
|
||||
uint16_t mtu;
|
||||
uint16_t psm;
|
||||
uint8_t rfcomm_channel_nr;
|
||||
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"
|
||||
@ -151,21 +151,31 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint
|
||||
case BTSTACK_EVENT_STATE:
|
||||
// bt stack activated, get started
|
||||
if (packet[2] == HCI_STATE_WORKING) {
|
||||
// register RFCOMM channel
|
||||
bt_send_cmd(&rfcomm_register_service, 0x4711, 100); // random registration ID
|
||||
}
|
||||
// get persistent RFCOMM channel
|
||||
printf("HCI_STATE_WORKING\n");
|
||||
bt_send_cmd(&rfcomm_persistent_channel_for_service, "ch.ringwald.btstack.rfcomm-echo2");
|
||||
}
|
||||
break;
|
||||
|
||||
case RFCOMM_EVENT_SERVICE_REGISTERED:
|
||||
rfcomm_channel_nr = packet[5];
|
||||
case RFCOMM_EVENT_PERSISTENT_CHANNEL:
|
||||
rfcomm_channel_nr = packet[3];
|
||||
printf("RFCOMM channel %u was assigned by BTdaemon\n", rfcomm_channel_nr);
|
||||
bt_send_cmd(&rfcomm_register_service, rfcomm_channel_nr, 100); // reserved channel, mtu=100
|
||||
break;
|
||||
|
||||
case RFCOMM_EVENT_SERVICE_REGISTERED:
|
||||
printf("RFCOMM_EVENT_SERVICE_REGISTERED\n");
|
||||
rfcomm_channel_nr = packet[3];
|
||||
// register SDP for our SPP
|
||||
create_spp_service(service_buffer, rfcomm_channel_nr);
|
||||
bt_send_cmd(&sdp_register_service_record, service_buffer);
|
||||
bt_send_cmd(&btstack_set_discoverable, 1);
|
||||
break;
|
||||
|
||||
case SDP_SERVICE_REGISTERED:
|
||||
bt_send_cmd(&btstack_set_discoverable, 1);
|
||||
// event not sent yet
|
||||
// printf("SDP_SERVICE_REGISTERED\n");
|
||||
// bt_send_cmd(&btstack_set_discoverable, 1);
|
||||
break;
|
||||
|
||||
case HCI_EVENT_PIN_CODE_REQUEST:
|
||||
|
@ -168,9 +168,11 @@ extern "C" {
|
||||
// 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)
|
||||
// data: event(8), len(8), status (8), rfcomm server channel id (8)
|
||||
#define RFCOMM_EVENT_SERVICE_REGISTERED 0x85
|
||||
|
||||
// data: event(8), len(8), status (8), rfcomm server channel id (8)
|
||||
#define RFCOMM_EVENT_PERSISTENT_CHANNEL 0x86
|
||||
|
||||
// data: event(8), len(8), service_record_handle(32)
|
||||
#define SDP_SERVICE_REGISTERED 0x90
|
||||
@ -203,6 +205,7 @@ extern "C" {
|
||||
#define L2CAP_CONFIG_RESPONSE_RESULT_UNKNOWN_OPTIONS 0x69
|
||||
|
||||
#define RFCOMM_MULTIPLEXER_STOPPED 0x70
|
||||
#define RFCOMM_CHANNEL_ALREADY_REGISTERED 0x71
|
||||
|
||||
/**
|
||||
* Default INQ Mode
|
||||
@ -296,13 +299,21 @@ extern const hci_cmd_t l2cap_unregister_service;
|
||||
extern const hci_cmd_t sdp_register_service_record;
|
||||
extern const hci_cmd_t sdp_unregister_service_record;
|
||||
|
||||
// accept connection @param bd_addr(48), rfcomm_cid (16)
|
||||
extern const hci_cmd_t rfcomm_accept_connection;
|
||||
// create rfcomm channel: @param bd_addr(48), channel (8)
|
||||
extern const hci_cmd_t rfcomm_create_channel;
|
||||
// decline rfcomm disconnect,@param bd_addr(48), rfcomm cid (16), reason(8)
|
||||
extern const hci_cmd_t rfcomm_decline_connection;
|
||||
// disconnect rfcomm disconnect, @param rfcomm_cid(8), reason(8)
|
||||
extern const hci_cmd_t rfcomm_disconnect;
|
||||
// register rfcomm service: @param channel(8), mtu (16)
|
||||
extern const hci_cmd_t rfcomm_register_service;
|
||||
// unregister rfcomm service, @param service_channel(16)
|
||||
extern const hci_cmd_t rfcomm_unregister_service;
|
||||
|
||||
// request persisten rfcomm channel for service name: serive name (char*)
|
||||
extern const hci_cmd_t rfcomm_persistent_channel_for_service;
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
28
src/daemon.c
28
src/daemon.c
@ -111,6 +111,9 @@ static void (*bluetooth_status_handler)(BLUETOOTH_STATE state) = dummy_bluetooth
|
||||
|
||||
static int global_enable = 0;
|
||||
|
||||
static remote_device_db_t * remote_device_db = NULL;
|
||||
static rfcomm_channel_generator = 1;
|
||||
|
||||
static void dummy_bluetooth_status_handler(BLUETOOTH_STATE state){
|
||||
printf("Bluetooth status: %u\n", state);
|
||||
};
|
||||
@ -239,9 +242,9 @@ static int btstack_command_handler(connection_t *connection, uint8_t *packet, ui
|
||||
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);
|
||||
rfcomm_channel = packet[3];
|
||||
mtu = READ_BT_16(packet, 4);
|
||||
rfcomm_register_service_internal(connection, rfcomm_channel, mtu);
|
||||
break;
|
||||
case RFCOMM_UNREGISTER_SERVICE:
|
||||
service_channel = READ_BT_16(packet, 3);
|
||||
@ -256,6 +259,24 @@ static int btstack_command_handler(connection_t *connection, uint8_t *packet, ui
|
||||
reason = packet[7];
|
||||
rfcomm_decline_connection_internal(cid);
|
||||
break;
|
||||
case RFCOMM_PERSISTENT_CHANNEL: {
|
||||
if (remote_device_db) {
|
||||
// enforce \0
|
||||
packet[3+248] = 0;
|
||||
rfcomm_channel = remote_device_db->persistent_rfcomm_channel(&packet[3]);
|
||||
} else {
|
||||
// NOTE: hack for non-iOS platforms
|
||||
rfcomm_channel = rfcomm_channel_generator++;
|
||||
}
|
||||
uint8_t event[4];
|
||||
event[0] = RFCOMM_EVENT_PERSISTENT_CHANNEL;
|
||||
event[1] = sizeof(event) - 2;
|
||||
event[2] = 0;
|
||||
event[3] = rfcomm_channel;
|
||||
hci_dump_packet(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
socket_connection_send_packet(connection, HCI_EVENT_PACKET, 0, (uint8_t *) event, sizeof(event));
|
||||
break;
|
||||
}
|
||||
|
||||
case SDP_REGISTER_SERVICE_RECORD:
|
||||
printf("SDP_REGISTER_SERVICE_RECORD size %u\n", size);
|
||||
@ -493,7 +514,6 @@ int main (int argc, char * const * argv){
|
||||
|
||||
|
||||
bt_control_t * control = NULL;
|
||||
remote_device_db_t * remote_device_db = NULL;
|
||||
|
||||
#ifdef HAVE_TRANSPORT_H4
|
||||
transport = hci_transport_h4_instance();
|
||||
|
@ -129,7 +129,8 @@ extern "C" {
|
||||
#define RFCOMM_UNREGISTER_SERVICE 0x43
|
||||
#define RFCOMM_ACCEPT_CONNECTION 0x44
|
||||
#define RFCOMM_DECLINE_CONNECTION 0x45
|
||||
|
||||
#define RFCOMM_PERSISTENT_CHANNEL 0x46
|
||||
|
||||
//
|
||||
#define IS_COMMAND(packet, command) (READ_BT_16(packet,0) == command.opcode)
|
||||
|
||||
|
@ -404,21 +404,24 @@ const hci_cmd_t rfcomm_create_channel = {
|
||||
const hci_cmd_t rfcomm_disconnect = {
|
||||
OPCODE(OGF_BTSTACK, RFCOMM_DISCONNECT), "21"
|
||||
};
|
||||
// register rfcomm service: @param registration id(16), mtu (16)
|
||||
|
||||
// register rfcomm service: @param channel(8), mtu (16)
|
||||
const hci_cmd_t rfcomm_register_service = {
|
||||
OPCODE(OGF_BTSTACK, RFCOMM_REGISTER_SERVICE), "22"
|
||||
OPCODE(OGF_BTSTACK, RFCOMM_REGISTER_SERVICE), "12"
|
||||
};
|
||||
// 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)
|
||||
// accept connection @param source 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)
|
||||
// decline connection @param source cid (16)
|
||||
const hci_cmd_t rfcomm_decline_connection = {
|
||||
OPCODE(OGF_BTSTACK, RFCOMM_DECLINE_CONNECTION), "21"
|
||||
// @param source cid (16), reason(8)
|
||||
};
|
||||
// request persisten rfcomm channel number for named service
|
||||
const hci_cmd_t rfcomm_persistent_channel_for_service = {
|
||||
OPCODE(OGF_BTSTACK, RFCOMM_PERSISTENT_CHANNEL), "N"
|
||||
};
|
||||
|
@ -46,10 +46,14 @@ typedef struct {
|
||||
void (*put_link_key)(bd_addr_t *bd_addr, link_key_t *key);
|
||||
void (*delete_link_key)(bd_addr_t *bd_addr);
|
||||
|
||||
// remove name
|
||||
// remote name
|
||||
int (*get_name)(bd_addr_t *bd_addr, device_name_t *device_name);
|
||||
void (*put_name)(bd_addr_t *bd_addr, device_name_t *device_name);
|
||||
void (*delete_name)(bd_addr_t *bd_addr);
|
||||
|
||||
// persistent rfcomm channel
|
||||
uint8_t (*persistent_rfcomm_channel)(char *servicename);
|
||||
|
||||
} remote_device_db_t;
|
||||
|
||||
extern remote_device_db_t remote_device_db_iphone;
|
||||
|
@ -35,13 +35,21 @@
|
||||
|
||||
#define BTdaemonID "ch.ringwald.btdaemon"
|
||||
#define BTDaemonPrefsPath "Library/Preferences/ch.ringwald.btdaemon.plist"
|
||||
|
||||
#define DEVICES_KEY "devices"
|
||||
#define PREFS_REMOTE_NAME @"RemoteName"
|
||||
#define PREFS_LINK_KEY @"LinkKey"
|
||||
|
||||
#define MAX_RFCOMM_CHANNEL_NR 30
|
||||
|
||||
#define RFCOMM_SERVICES_KEY "rfcommServices"
|
||||
#define PREFS_CHANNEL @"channel"
|
||||
#define PREFS_LAST_USED @"lastUsed"
|
||||
|
||||
static void put_name(bd_addr_t *bd_addr, device_name_t *device_name);
|
||||
|
||||
static NSMutableDictionary *remote_devices = nil;
|
||||
static NSMutableDictionary *remote_devices = nil;
|
||||
static NSMutableDictionary *rfcomm_services = nil;
|
||||
|
||||
// Device info
|
||||
static void db_open(){
|
||||
@ -53,7 +61,8 @@ static void db_open(){
|
||||
// NSDictionary * dict = [defaults persistentDomainForName:BTdaemonID];
|
||||
|
||||
// NSDictionary * dict = (NSDictionary*) CFPreferencesCopyAppValue(CFSTR(DEVICES_KEY), CFSTR(BTdaemonID));
|
||||
NSDictionary * dict = (NSDictionary*) CFPreferencesCopyAppValue(CFSTR(DEVICES_KEY), CFSTR(BTdaemonID));
|
||||
NSDictionary * dict;
|
||||
dict = (NSDictionary*) CFPreferencesCopyAppValue(CFSTR(DEVICES_KEY), CFSTR(BTdaemonID));
|
||||
remote_devices = [[NSMutableDictionary alloc] initWithCapacity:([dict count]+5)];
|
||||
|
||||
// copy entries
|
||||
@ -64,6 +73,17 @@ static void db_open(){
|
||||
[remote_devices setObject:deviceEntry forKey:key];
|
||||
}
|
||||
|
||||
dict = (NSDictionary*) CFPreferencesCopyAppValue(CFSTR(RFCOMM_SERVICES_KEY), CFSTR(BTdaemonID));
|
||||
rfcomm_services = [[NSMutableDictionary alloc] initWithCapacity:([dict count]+5)];
|
||||
|
||||
// copy entries
|
||||
for (id key in dict) {
|
||||
NSDictionary *value = [dict objectForKey:key];
|
||||
NSMutableDictionary *serviceEntry = [NSMutableDictionary dictionaryWithCapacity:[value count]];
|
||||
[serviceEntry addEntriesFromDictionary:value];
|
||||
[rfcomm_services setObject:serviceEntry forKey:key];
|
||||
}
|
||||
|
||||
log_dbg("read prefs for %u devices\n", [dict count]);
|
||||
|
||||
[pool release];
|
||||
@ -76,6 +96,7 @@ static void db_synchronize(){
|
||||
|
||||
// Core Foundation
|
||||
CFPreferencesSetValue(CFSTR(DEVICES_KEY), (CFPropertyListRef) remote_devices, CFSTR(BTdaemonID), kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
|
||||
CFPreferencesSetValue(CFSTR(RFCOMM_SERVICES_KEY), (CFPropertyListRef) rfcomm_services, CFSTR(BTdaemonID), kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
|
||||
CFPreferencesSynchronize(CFSTR(BTdaemonID), kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
|
||||
|
||||
// NSUserDefaults didn't work
|
||||
@ -174,6 +195,76 @@ static int get_name(bd_addr_t *bd_addr, device_name_t *device_name) {
|
||||
return (remoteName != nil);
|
||||
}
|
||||
|
||||
#pragma mark PERSISTENT RFCOMM CHANNEL ALLOCATION
|
||||
|
||||
static int firstFreeChannelNr(){
|
||||
BOOL channelUsed[MAX_RFCOMM_CHANNEL_NR+1];
|
||||
int i;
|
||||
for (i=0; i<=MAX_RFCOMM_CHANNEL_NR ; i++) channelUsed[i] = NO;
|
||||
channelUsed[0] = YES;
|
||||
channelUsed[1] = YES; // preserve channel #1 for testing
|
||||
for (NSDictionary * serviceEntry in [rfcomm_services allValues]){
|
||||
int channel = [(NSNumber *) [serviceEntry objectForKey:PREFS_CHANNEL] intValue];
|
||||
channelUsed[channel] = YES;
|
||||
}
|
||||
for (i=0;i<=MAX_RFCOMM_CHANNEL_NR;i++) {
|
||||
if (channelUsed[i] == NO) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void deleteLeastUsed(){
|
||||
NSString * leastUsedName = nil;
|
||||
NSDate * leastUsedDate = nil;
|
||||
for (NSString * serviceName in [rfcomm_services allKeys]){
|
||||
NSDictionary *service = [rfcomm_services objectForKey:serviceName];
|
||||
NSDate *serviceDate = [service objectForKey:PREFS_LAST_USED];
|
||||
if (leastUsedName == nil || [leastUsedDate compare:serviceDate] == NSOrderedDescending) {
|
||||
leastUsedName = serviceName;
|
||||
leastUsedDate = serviceDate;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (leastUsedName){
|
||||
// NSLog(@"removing %@", leastUsedName);
|
||||
[rfcomm_services removeObjectForKey:leastUsedName];
|
||||
}
|
||||
}
|
||||
|
||||
static void addService(NSString * serviceName, int channel){
|
||||
NSMutableDictionary * serviceEntry = [NSMutableDictionary dictionaryWithCapacity:2];
|
||||
[serviceEntry setObject:[NSNumber numberWithInt:channel] forKey:PREFS_CHANNEL];
|
||||
[serviceEntry setObject:[NSDate date] forKey:PREFS_LAST_USED];
|
||||
[rfcomm_services setObject:serviceEntry forKey:serviceName];
|
||||
}
|
||||
|
||||
static uint8_t persistent_rfcomm_channel(char *serviceName){
|
||||
// find existing entry
|
||||
NSString *serviceString = [NSString stringWithUTF8String:serviceName];
|
||||
NSMutableDictionary *serviceEntry = [rfcomm_services objectForKey:serviceString];
|
||||
if (serviceEntry){
|
||||
// update timestamp
|
||||
[serviceEntry setObject:[NSDate date] forKey:PREFS_LAST_USED];
|
||||
|
||||
db_synchronize();
|
||||
|
||||
return [(NSNumber *) [serviceEntry objectForKey:PREFS_CHANNEL] intValue];
|
||||
}
|
||||
// free channel exist?
|
||||
int channel = firstFreeChannelNr();
|
||||
if (channel < 0){
|
||||
// free channel
|
||||
deleteLeastUsed();
|
||||
channel = firstFreeChannelNr();
|
||||
}
|
||||
addService(serviceString, channel);
|
||||
|
||||
db_synchronize();
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
|
||||
remote_device_db_t remote_device_db_iphone = {
|
||||
db_open,
|
||||
db_close,
|
||||
@ -182,6 +273,7 @@ remote_device_db_t remote_device_db_iphone = {
|
||||
delete_link_key,
|
||||
get_name,
|
||||
put_name,
|
||||
delete_name
|
||||
delete_name,
|
||||
persistent_rfcomm_channel
|
||||
};
|
||||
|
||||
|
36
src/rfcomm.c
36
src/rfcomm.c
@ -119,7 +119,7 @@ typedef struct {
|
||||
linked_item_t item;
|
||||
|
||||
// server channel
|
||||
uint16_t server_channel;
|
||||
uint8_t server_channel;
|
||||
|
||||
// incoming max frame size
|
||||
uint16_t max_frame_size;
|
||||
@ -195,7 +195,6 @@ typedef struct {
|
||||
|
||||
// global rfcomm data
|
||||
static uint16_t rfcomm_client_cid_generator; // used for client channel IDs
|
||||
static uint8_t rfcomm_server_cid_generator; // used for service registration
|
||||
|
||||
// linked lists for all
|
||||
static linked_list_t rfcomm_multiplexers = NULL;
|
||||
@ -274,7 +273,7 @@ static void rfcomm_dump_channels(){
|
||||
}
|
||||
|
||||
static void rfcomm_channel_initialize(rfcomm_channel_t *channel, rfcomm_multiplexer_t *multiplexer,
|
||||
rfcomm_service_t *service, uint16_t server_channel){
|
||||
rfcomm_service_t *service, uint8_t server_channel){
|
||||
|
||||
// don't use 0 as channel id
|
||||
if (rfcomm_client_cid_generator == 0) ++rfcomm_client_cid_generator;
|
||||
@ -301,7 +300,7 @@ static void rfcomm_channel_initialize(rfcomm_channel_t *channel, rfcomm_multiple
|
||||
|
||||
// service == NULL -> outgoing channel
|
||||
static rfcomm_channel_t * rfcomm_channel_create(rfcomm_multiplexer_t * multiplexer,
|
||||
rfcomm_service_t * service, uint16_t server_channel){
|
||||
rfcomm_service_t * service, uint8_t server_channel){
|
||||
|
||||
log_dbg("rfcomm_channel_create for service %p, channel %u --- begin\n", service, server_channel);
|
||||
rfcomm_dump_channels();
|
||||
@ -341,7 +340,7 @@ static rfcomm_channel_t * rfcomm_channel_for_multiplexer_and_dlci(rfcomm_multipl
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static rfcomm_service_t * rfcomm_service_for_channel(uint16_t server_channel){
|
||||
static rfcomm_service_t * rfcomm_service_for_channel(uint8_t server_channel){
|
||||
linked_item_t *it;
|
||||
for (it = (linked_item_t *) rfcomm_services; it ; it = it->next){
|
||||
rfcomm_service_t * service = ((rfcomm_service_t *) it);
|
||||
@ -507,7 +506,7 @@ static void rfcomm_emit_channel_opened(rfcomm_channel_t *channel, uint8_t status
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = status;
|
||||
bt_flip_addr(&event[pos], channel->multiplexer->remote_addr); pos += 6;
|
||||
// bt_store_16(event, pos, channel->multiplexer->con_handle); pos += 2;
|
||||
bt_store_16(event, pos, channel->multiplexer->con_handle); pos += 2;
|
||||
event[pos++] = channel->dlci >> 1;
|
||||
bt_store_16(event, pos, channel->rfcomm_cid); pos += 2; // channel ID
|
||||
bt_store_16(event, pos, channel->max_frame_size); pos += 2; // max frame size
|
||||
@ -537,13 +536,12 @@ static void rfcomm_emit_credits(rfcomm_channel_t * channel, uint8_t credits) {
|
||||
(*app_packet_handler)(channel->connection, HCI_EVENT_PACKET, 0, (uint8_t *) event, sizeof(event));
|
||||
}
|
||||
|
||||
static void rfcomm_emit_service_registered(void *connection, uint8_t status, uint16_t registration_id, uint16_t rfcomm_channel_id){
|
||||
uint8_t event[6];
|
||||
static void rfcomm_emit_service_registered(void *connection, uint8_t status, uint8_t channel){
|
||||
uint8_t event[4];
|
||||
event[0] = RFCOMM_EVENT_SERVICE_REGISTERED;
|
||||
event[1] = sizeof(event) - 2;
|
||||
event[2] = status;
|
||||
bt_store_16(event, 3, registration_id);
|
||||
event[5] = rfcomm_channel_id;
|
||||
event[3] = channel;
|
||||
hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
(*app_packet_handler)(connection, HCI_EVENT_PACKET, 0, (uint8_t *) event, sizeof(event));
|
||||
}
|
||||
@ -1217,7 +1215,6 @@ void rfcomm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
|
||||
void rfcomm_init(){
|
||||
rfcomm_client_cid_generator = 0;
|
||||
rfcomm_server_cid_generator = 0;
|
||||
rfcomm_multiplexers = NULL;
|
||||
rfcomm_services = NULL;
|
||||
rfcomm_channels = NULL;
|
||||
@ -1320,12 +1317,19 @@ void rfcomm_disconnect_internal(uint16_t rfcomm_cid){
|
||||
}
|
||||
}
|
||||
|
||||
void rfcomm_register_service_internal(void * connection, uint16_t registration_id, uint16_t max_frame_size){
|
||||
void rfcomm_register_service_internal(void * connection, uint8_t channel, uint16_t max_frame_size){
|
||||
|
||||
// check if already registered
|
||||
rfcomm_service_t * service = rfcomm_service_for_channel(channel);
|
||||
if (service){
|
||||
rfcomm_emit_service_registered(service->connection, RFCOMM_CHANNEL_ALREADY_REGISTERED, channel);
|
||||
return;
|
||||
}
|
||||
|
||||
// alloc structure
|
||||
rfcomm_service_t * service = malloc(sizeof(rfcomm_service_t));
|
||||
service = malloc(sizeof(rfcomm_service_t));
|
||||
if (!service) {
|
||||
rfcomm_emit_service_registered(service->connection, BTSTACK_MEMORY_ALLOC_FAILED, registration_id, 0);
|
||||
rfcomm_emit_service_registered(service->connection, BTSTACK_MEMORY_ALLOC_FAILED, channel);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1336,14 +1340,14 @@ void rfcomm_register_service_internal(void * connection, uint16_t registration_i
|
||||
|
||||
// fill in
|
||||
service->connection = connection;
|
||||
service->server_channel = ++rfcomm_server_cid_generator;
|
||||
service->server_channel = channel;
|
||||
service->max_frame_size = max_frame_size;
|
||||
|
||||
// add to services list
|
||||
linked_list_add(&rfcomm_services, (linked_item_t *) service);
|
||||
|
||||
// done
|
||||
rfcomm_emit_service_registered(service->connection, 0, registration_id, service->server_channel);
|
||||
rfcomm_emit_service_registered(service->connection, 0, channel);
|
||||
}
|
||||
|
||||
void rfcomm_unregister_service_internal(uint8_t service_channel){
|
||||
|
@ -48,7 +48,7 @@ void rfcomm_register_packet_handler(void (*handler)(void * connection, uint8_t p
|
||||
// BTstack Internal RFCOMM API
|
||||
void rfcomm_create_channel_internal(void * connectio, bd_addr_t *addr, uint8_t channel);
|
||||
void rfcomm_disconnect_internal(uint16_t rfcomm_cid);
|
||||
void rfcomm_register_service_internal(void * connection, uint16_t registration_id, uint16_t max_frame_size);
|
||||
void rfcomm_register_service_internal(void * connection, uint8_t channel, uint16_t max_frame_size);
|
||||
void rfcomm_unregister_service_internal(uint8_t service_channel);
|
||||
void rfcomm_accept_connection_internal(uint16_t rfcomm_cid);
|
||||
void rfcomm_decline_connection_internal(uint16_t rfcomm_cid);
|
||||
|
Loading…
x
Reference in New Issue
Block a user