implemented PSM management

This commit is contained in:
matthias.ringwald 2010-01-25 18:29:06 +00:00
parent 22cc1a0ca7
commit 9d9bbc01f5
4 changed files with 77 additions and 7 deletions

View File

@ -5,8 +5,15 @@
NEXT:
- implement rest of L2CAP state machine
- incoming connections
- list of supported PSM
- commands and events-- Add improved RFCOMM user-client
- manage list of supported PSM
- new commands
- l2cap_register_service(psm, mtu)
- l2cap_unregister_service(psm)
- l2cap_accept_connection( bd_addr_t, dest cid )
- l2cap_deny_connection( bd_addr_t, dest cid, reason )
- events
- l2cap_incoming_connection(psm, handle, dest cid)
- Add improved RFCOMM user-client
- use switch on RFCOMM control field in rfcomm.c packet handler
- add configure option for uart flowcontrol
- create <btstack/errors.h>

View File

@ -170,7 +170,7 @@ static int daemon_client_handler(connection_t *connection, uint16_t packet_type,
case DAEMON_EVENT_PACKET:
switch (data[0]) {
case DAEMON_EVENT_CONNECTION_CLOSED:
l2cap_close_channels_for_connection(connection);
l2cap_close_connection(connection);
break;
case DAEMON_NR_CONNECTIONS_CHANGED:
printf("Nr Connections changed, new %u\n", data[1]);

View File

@ -52,6 +52,7 @@ static void null_data_handler(uint16_t source_cid, uint8_t *packet, uint16_t siz
static uint8_t * sig_buffer = NULL;
static linked_list_t l2cap_channels = NULL;
static linked_list_t l2cap_services = NULL;
static uint8_t * acl_buffer = NULL;
static void (*event_packet_handler) (uint8_t *packet, uint16_t size) = null_event_handler;
static void (*data_packet_handler) (uint16_t source_cid, uint8_t *packet, uint16_t size) = null_data_handler;
@ -378,9 +379,49 @@ void l2cap_finialize_channel_close(l2cap_channel_t *channel){
free (channel);
}
//
void l2cap_close_channels_for_connection(connection_t *connection){
l2cap_service_t * l2cap_get_service(uint16_t psm){
linked_item_t *it;
// close open channels
for (it = (linked_item_t *) l2cap_services; it ; it = it->next){
l2cap_service_t * service = ((l2cap_service_t *) it);
if ( service->psm == psm){
return service;
};
}
return NULL;
}
void l2cap_register_service(connection_t *connection, uint16_t psm, uint16_t mtu){
// check for alread registered psm // TODO: emit error event
l2cap_service_t *service = l2cap_get_service(psm);
if (service) return;
// alloc structure // TODO: emit error event
service = malloc(sizeof(l2cap_service_t));
if (!service) return;
// fill in
service->psm = psm;
service->mtu = mtu;
service->connection = connection;
// add to services list
linked_list_add(&l2cap_services, (linked_item_t *) service);
}
void l2cap_unregister_service(connection_t *connection, uint16_t psm){
l2cap_service_t *service = l2cap_get_service(psm);
if (service) return;
linked_list_remove(&l2cap_services, (linked_item_t *) service);
free( service );
}
//
void l2cap_close_connection(connection_t *connection){
linked_item_t *it;
// close open channels
l2cap_channel_t * channel;
for (it = (linked_item_t *) l2cap_channels; it ; it = it->next){
channel = (l2cap_channel_t *) it;
@ -389,7 +430,10 @@ void l2cap_close_channels_for_connection(connection_t *connection){
l2cap_send_signaling_packet( channel->handle, DISCONNECTION_REQUEST, channel->sig_id, channel->dest_cid, channel->source_cid);
channel->state = L2CAP_STATE_WAIT_DISCONNECT;
}
}
}
// TODO: INCOMING unregister services
}
// notify client

View File

@ -56,6 +56,7 @@ typedef enum {
L2CAP_STATE_WAIT_DISCONNECT, // from application
} L2CAP_STATE;
// info regarding an actual coneection
typedef struct {
// linked list - assert: first field
linked_item_t item;
@ -74,8 +75,19 @@ typedef struct {
// uint16_t flush_timeout_outgoing;
} l2cap_channel_t;
// info regarding potential connections
typedef struct {
// linked list - assert: first field
linked_item_t item;
// service id
uint16_t psm;
// incoming MTU
uint16_t mtu;
// provider for this server
connection_t *connection;
} l2cap_service_t;
void l2cap_init();
@ -89,7 +101,14 @@ void l2cap_event_handler( uint8_t *packet, uint16_t size );
void l2cap_set_capture_connection(connection_t * connection);
void l2cap_finialize_channel_close(l2cap_channel_t *channel);
void l2cap_close_channels_for_connection(connection_t *connection);
void l2cap_close_connection(connection_t *connection);
l2cap_service_t * l2cap_get_service(uint16_t psm);
void l2cap_register_service(connection_t *connection, uint16_t psm, uint16_t);
void l2cap_unregister_service(connection_t *connection, uint16_t psm);
void l2cap_accept_connection(bd_addr_t address, uint16_t dest_cid);
void l2cap_decline_connection(bd_addr_t address, uint16_t dest_cid, uint8_t reason);
void l2cap_emit_channel_opened(l2cap_channel_t *channel, uint8_t status);
void l2cap_emit_channel_closed(l2cap_channel_t *channel);