mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-26 02:37:41 +00:00
moved l2cap_channel_t, l2cap_service_t, rfcomm_multiplexer_t, rfcomm_channel_t, rfcomm_service_t to header files
This commit is contained in:
parent
9574ad1db1
commit
73cf2b3d2a
117
src/l2cap.c
117
src/l2cap.c
@ -66,93 +66,6 @@
|
|||||||
#define L2CAP_SIGNALING_COMMAND_LENGTH_OFFSET 2
|
#define L2CAP_SIGNALING_COMMAND_LENGTH_OFFSET 2
|
||||||
#define L2CAP_SIGNALING_COMMAND_DATA_OFFSET 4
|
#define L2CAP_SIGNALING_COMMAND_DATA_OFFSET 4
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
L2CAP_STATE_CLOSED = 1, // no baseband
|
|
||||||
L2CAP_STATE_WILL_SEND_CREATE_CONNECTION,
|
|
||||||
L2CAP_STATE_WAIT_CONNECTION_COMPLETE,
|
|
||||||
L2CAP_STATE_WAIT_CLIENT_ACCEPT_OR_REJECT,
|
|
||||||
L2CAP_STATE_WAIT_CONNECT_RSP, // from peer
|
|
||||||
L2CAP_STATE_CONFIG,
|
|
||||||
L2CAP_STATE_OPEN,
|
|
||||||
L2CAP_STATE_WAIT_DISCONNECT, // from application
|
|
||||||
L2CAP_STATE_WILL_SEND_CONNECTION_REQUEST,
|
|
||||||
L2CAP_STATE_WILL_SEND_CONNECTION_RESPONSE_DECLINE,
|
|
||||||
L2CAP_STATE_WILL_SEND_CONNECTION_RESPONSE_ACCEPT,
|
|
||||||
L2CAP_STATE_WILL_SEND_DISCONNECT_REQUEST,
|
|
||||||
L2CAP_STATE_WILL_SEND_DISCONNECT_RESPONSE,
|
|
||||||
} L2CAP_STATE;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
STATE_VAR_NONE = 0,
|
|
||||||
STATE_VAR_RCVD_CONF_REQ = 1 << 0,
|
|
||||||
STATE_VAR_RCVD_CONF_RSP = 1 << 1,
|
|
||||||
STATE_VAR_SEND_CONF_REQ = 1 << 2,
|
|
||||||
STATE_VAR_SEND_CONF_RSP = 1 << 3,
|
|
||||||
STATE_VAR_SENT_CONF_REQ = 1 << 4,
|
|
||||||
STATE_VAR_SENT_CONF_RSP = 1 << 5,
|
|
||||||
} L2CAP_CHANNEL_STATE_VAR;
|
|
||||||
|
|
||||||
// info regarding an actual coneection
|
|
||||||
typedef struct {
|
|
||||||
// linked list - assert: first field
|
|
||||||
linked_item_t item;
|
|
||||||
|
|
||||||
L2CAP_STATE state;
|
|
||||||
L2CAP_CHANNEL_STATE_VAR state_var;
|
|
||||||
|
|
||||||
bd_addr_t address;
|
|
||||||
hci_con_handle_t handle;
|
|
||||||
|
|
||||||
uint8_t remote_sig_id; // used by other side, needed for delayed response
|
|
||||||
uint8_t local_sig_id; // own signaling identifier
|
|
||||||
|
|
||||||
uint16_t local_cid;
|
|
||||||
uint16_t remote_cid;
|
|
||||||
|
|
||||||
uint16_t local_mtu;
|
|
||||||
uint16_t remote_mtu;
|
|
||||||
|
|
||||||
uint16_t psm;
|
|
||||||
|
|
||||||
uint8_t packets_granted; // number of L2CAP/ACL packets client is allowed to send
|
|
||||||
|
|
||||||
uint8_t reason; // used in decline internal
|
|
||||||
|
|
||||||
// client connection
|
|
||||||
void * connection;
|
|
||||||
|
|
||||||
// internal connection
|
|
||||||
btstack_packet_handler_t packet_handler;
|
|
||||||
|
|
||||||
} 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;
|
|
||||||
|
|
||||||
// client connection
|
|
||||||
void *connection;
|
|
||||||
|
|
||||||
// internal connection
|
|
||||||
btstack_packet_handler_t packet_handler;
|
|
||||||
|
|
||||||
} l2cap_service_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct l2cap_signaling_response {
|
|
||||||
hci_con_handle_t handle;
|
|
||||||
uint8_t sig_id;
|
|
||||||
uint8_t code;
|
|
||||||
uint16_t infoType;
|
|
||||||
} l2cap_signaling_response_t;
|
|
||||||
|
|
||||||
static void null_packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
static void null_packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
||||||
static void l2cap_packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t size);
|
static void l2cap_packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t size);
|
||||||
|
|
||||||
@ -423,7 +336,7 @@ void l2cap_run(void){
|
|||||||
|
|
||||||
case L2CAP_STATE_WILL_SEND_CONNECTION_RESPONSE_ACCEPT:
|
case L2CAP_STATE_WILL_SEND_CONNECTION_RESPONSE_ACCEPT:
|
||||||
channel->state = L2CAP_STATE_CONFIG;
|
channel->state = L2CAP_STATE_CONFIG;
|
||||||
channel->state_var |= STATE_VAR_SEND_CONF_REQ;
|
channel->state_var |= L2CAP_CHANNEL_STATE_VAR_SEND_CONF_REQ;
|
||||||
l2cap_send_signaling_packet(channel->handle, CONNECTION_RESPONSE, channel->remote_sig_id, channel->local_cid, channel->remote_cid, 0, 0);
|
l2cap_send_signaling_packet(channel->handle, CONNECTION_RESPONSE, channel->remote_sig_id, channel->local_cid, channel->remote_cid, 0, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -435,14 +348,14 @@ void l2cap_run(void){
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_STATE_CONFIG:
|
case L2CAP_STATE_CONFIG:
|
||||||
if (channel->state_var & STATE_VAR_SEND_CONF_RSP){
|
if (channel->state_var & L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP){
|
||||||
channel->state_var &= ~STATE_VAR_SEND_CONF_RSP;
|
channel->state_var &= ~L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP;
|
||||||
channel->state_var |= STATE_VAR_SENT_CONF_RSP;
|
channel->state_var |= L2CAP_CHANNEL_STATE_VAR_SENT_CONF_RSP;
|
||||||
l2cap_send_signaling_packet(channel->handle, CONFIGURE_RESPONSE, channel->remote_sig_id, channel->remote_cid, 0, 0, 0, NULL);
|
l2cap_send_signaling_packet(channel->handle, CONFIGURE_RESPONSE, channel->remote_sig_id, channel->remote_cid, 0, 0, 0, NULL);
|
||||||
}
|
}
|
||||||
else if (channel->state_var & STATE_VAR_SEND_CONF_REQ){
|
else if (channel->state_var & L2CAP_CHANNEL_STATE_VAR_SEND_CONF_REQ){
|
||||||
channel->state_var &= ~STATE_VAR_SEND_CONF_REQ;
|
channel->state_var &= ~L2CAP_CHANNEL_STATE_VAR_SEND_CONF_REQ;
|
||||||
channel->state_var |= STATE_VAR_SENT_CONF_REQ;
|
channel->state_var |= L2CAP_CHANNEL_STATE_VAR_SENT_CONF_REQ;
|
||||||
channel->local_sig_id = l2cap_next_sig_id();
|
channel->local_sig_id = l2cap_next_sig_id();
|
||||||
config_options[0] = 1; // MTU
|
config_options[0] = 1; // MTU
|
||||||
config_options[1] = 2; // len param
|
config_options[1] = 2; // len param
|
||||||
@ -502,7 +415,7 @@ void l2cap_create_channel_internal(void * connection, btstack_packet_handler_t p
|
|||||||
|
|
||||||
// set initial state
|
// set initial state
|
||||||
chan->state = L2CAP_STATE_WILL_SEND_CREATE_CONNECTION;
|
chan->state = L2CAP_STATE_WILL_SEND_CREATE_CONNECTION;
|
||||||
chan->state_var = STATE_VAR_NONE;
|
chan->state_var = L2CAP_CHANNEL_STATE_VAR_NONE;
|
||||||
chan->remote_sig_id = L2CAP_SIG_ID_INVALID;
|
chan->remote_sig_id = L2CAP_SIG_ID_INVALID;
|
||||||
chan->local_sig_id = L2CAP_SIG_ID_INVALID;
|
chan->local_sig_id = L2CAP_SIG_ID_INVALID;
|
||||||
|
|
||||||
@ -699,7 +612,7 @@ static void l2cap_handle_connection_request(hci_con_handle_t handle, uint8_t sig
|
|||||||
|
|
||||||
// set initial state
|
// set initial state
|
||||||
channel->state = L2CAP_STATE_WAIT_CLIENT_ACCEPT_OR_REJECT;
|
channel->state = L2CAP_STATE_WAIT_CLIENT_ACCEPT_OR_REJECT;
|
||||||
channel->state_var = STATE_VAR_NONE;
|
channel->state_var = L2CAP_CHANNEL_STATE_VAR_NONE;
|
||||||
|
|
||||||
// add to connections list
|
// add to connections list
|
||||||
linked_list_add(&l2cap_channels, (linked_item_t *) channel);
|
linked_list_add(&l2cap_channels, (linked_item_t *) channel);
|
||||||
@ -753,8 +666,8 @@ void l2cap_signaling_handle_configure_request(l2cap_channel_t *channel, uint8_t
|
|||||||
|
|
||||||
static int l2cap_channel_ready_for_open(l2cap_channel_t *channel){
|
static int l2cap_channel_ready_for_open(l2cap_channel_t *channel){
|
||||||
// log_info("l2cap_channel_ready_for_open 0x%02x\n", channel->state_var);
|
// log_info("l2cap_channel_ready_for_open 0x%02x\n", channel->state_var);
|
||||||
if ((channel->state_var & STATE_VAR_RCVD_CONF_RSP) == 0) return 0;
|
if ((channel->state_var & L2CAP_CHANNEL_STATE_VAR_RCVD_CONF_RSP) == 0) return 0;
|
||||||
if ((channel->state_var & STATE_VAR_SENT_CONF_RSP) == 0) return 0;
|
if ((channel->state_var & L2CAP_CHANNEL_STATE_VAR_SENT_CONF_RSP) == 0) return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -795,7 +708,7 @@ void l2cap_signaling_handler_channel(l2cap_channel_t *channel, uint8_t *command)
|
|||||||
// successful connection
|
// successful connection
|
||||||
channel->remote_cid = READ_BT_16(command, L2CAP_SIGNALING_COMMAND_DATA_OFFSET);
|
channel->remote_cid = READ_BT_16(command, L2CAP_SIGNALING_COMMAND_DATA_OFFSET);
|
||||||
channel->state = L2CAP_STATE_CONFIG;
|
channel->state = L2CAP_STATE_CONFIG;
|
||||||
channel->state_var |= STATE_VAR_SEND_CONF_REQ;
|
channel->state_var |= L2CAP_CHANNEL_STATE_VAR_SEND_CONF_REQ;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// connection pending. get some coffee
|
// connection pending. get some coffee
|
||||||
@ -828,12 +741,12 @@ void l2cap_signaling_handler_channel(l2cap_channel_t *channel, uint8_t *command)
|
|||||||
case L2CAP_STATE_CONFIG:
|
case L2CAP_STATE_CONFIG:
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case CONFIGURE_REQUEST:
|
case CONFIGURE_REQUEST:
|
||||||
channel->state_var |= STATE_VAR_RCVD_CONF_REQ;
|
channel->state_var |= L2CAP_CHANNEL_STATE_VAR_RCVD_CONF_REQ;
|
||||||
channel->state_var |= STATE_VAR_SEND_CONF_RSP;
|
channel->state_var |= L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP;
|
||||||
l2cap_signaling_handle_configure_request(channel, command);
|
l2cap_signaling_handle_configure_request(channel, command);
|
||||||
break;
|
break;
|
||||||
case CONFIGURE_RESPONSE:
|
case CONFIGURE_RESPONSE:
|
||||||
channel->state_var |= STATE_VAR_RCVD_CONF_RSP;
|
channel->state_var |= L2CAP_CHANNEL_STATE_VAR_RCVD_CONF_RSP;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
90
src/l2cap.h
90
src/l2cap.h
@ -68,6 +68,96 @@ void l2cap_unregister_service_internal(void *connection, uint16_t psm);
|
|||||||
void l2cap_accept_connection_internal(uint16_t local_cid);
|
void l2cap_accept_connection_internal(uint16_t local_cid);
|
||||||
void l2cap_decline_connection_internal(uint16_t local_cid, uint8_t reason);
|
void l2cap_decline_connection_internal(uint16_t local_cid, uint8_t reason);
|
||||||
|
|
||||||
|
|
||||||
|
// private structs
|
||||||
|
typedef enum {
|
||||||
|
L2CAP_STATE_CLOSED = 1, // no baseband
|
||||||
|
L2CAP_STATE_WILL_SEND_CREATE_CONNECTION,
|
||||||
|
L2CAP_STATE_WAIT_CONNECTION_COMPLETE,
|
||||||
|
L2CAP_STATE_WAIT_CLIENT_ACCEPT_OR_REJECT,
|
||||||
|
L2CAP_STATE_WAIT_CONNECT_RSP, // from peer
|
||||||
|
L2CAP_STATE_CONFIG,
|
||||||
|
L2CAP_STATE_OPEN,
|
||||||
|
L2CAP_STATE_WAIT_DISCONNECT, // from application
|
||||||
|
L2CAP_STATE_WILL_SEND_CONNECTION_REQUEST,
|
||||||
|
L2CAP_STATE_WILL_SEND_CONNECTION_RESPONSE_DECLINE,
|
||||||
|
L2CAP_STATE_WILL_SEND_CONNECTION_RESPONSE_ACCEPT,
|
||||||
|
L2CAP_STATE_WILL_SEND_DISCONNECT_REQUEST,
|
||||||
|
L2CAP_STATE_WILL_SEND_DISCONNECT_RESPONSE,
|
||||||
|
} L2CAP_STATE;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
L2CAP_CHANNEL_STATE_VAR_NONE = 0,
|
||||||
|
L2CAP_CHANNEL_STATE_VAR_RCVD_CONF_REQ = 1 << 0,
|
||||||
|
L2CAP_CHANNEL_STATE_VAR_RCVD_CONF_RSP = 1 << 1,
|
||||||
|
L2CAP_CHANNEL_STATE_VAR_SEND_CONF_REQ = 1 << 2,
|
||||||
|
L2CAP_CHANNEL_STATE_VAR_SEND_CONF_RSP = 1 << 3,
|
||||||
|
L2CAP_CHANNEL_STATE_VAR_SENT_CONF_REQ = 1 << 4,
|
||||||
|
L2CAP_CHANNEL_STATE_VAR_SENT_CONF_RSP = 1 << 5,
|
||||||
|
} L2CAP_CHANNEL_STATE_VAR;
|
||||||
|
|
||||||
|
// info regarding an actual coneection
|
||||||
|
typedef struct {
|
||||||
|
// linked list - assert: first field
|
||||||
|
linked_item_t item;
|
||||||
|
|
||||||
|
L2CAP_STATE state;
|
||||||
|
L2CAP_CHANNEL_STATE_VAR state_var;
|
||||||
|
|
||||||
|
bd_addr_t address;
|
||||||
|
hci_con_handle_t handle;
|
||||||
|
|
||||||
|
uint8_t remote_sig_id; // used by other side, needed for delayed response
|
||||||
|
uint8_t local_sig_id; // own signaling identifier
|
||||||
|
|
||||||
|
uint16_t local_cid;
|
||||||
|
uint16_t remote_cid;
|
||||||
|
|
||||||
|
uint16_t local_mtu;
|
||||||
|
uint16_t remote_mtu;
|
||||||
|
|
||||||
|
uint16_t psm;
|
||||||
|
|
||||||
|
uint8_t packets_granted; // number of L2CAP/ACL packets client is allowed to send
|
||||||
|
|
||||||
|
uint8_t reason; // used in decline internal
|
||||||
|
|
||||||
|
// client connection
|
||||||
|
void * connection;
|
||||||
|
|
||||||
|
// internal connection
|
||||||
|
btstack_packet_handler_t packet_handler;
|
||||||
|
|
||||||
|
} 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;
|
||||||
|
|
||||||
|
// client connection
|
||||||
|
void *connection;
|
||||||
|
|
||||||
|
// internal connection
|
||||||
|
btstack_packet_handler_t packet_handler;
|
||||||
|
|
||||||
|
} l2cap_service_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct l2cap_signaling_response {
|
||||||
|
hci_con_handle_t handle;
|
||||||
|
uint8_t sig_id;
|
||||||
|
uint8_t code;
|
||||||
|
uint16_t infoType;
|
||||||
|
} l2cap_signaling_response_t;
|
||||||
|
|
||||||
|
|
||||||
#if defined __cplusplus
|
#if defined __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
281
src/rfcomm.c
281
src/rfcomm.c
@ -84,195 +84,6 @@
|
|||||||
|
|
||||||
#include "l2cap.h"
|
#include "l2cap.h"
|
||||||
|
|
||||||
// private structs
|
|
||||||
typedef enum {
|
|
||||||
RFCOMM_MULTIPLEXER_CLOSED = 1,
|
|
||||||
RFCOMM_MULTIPLEXER_W4_CONNECT, // outgoing
|
|
||||||
RFCOMM_MULTIPLEXER_SEND_SABM_0, // "
|
|
||||||
RFCOMM_MULTIPLEXER_W4_UA_0, // "
|
|
||||||
RFCOMM_MULTIPLEXER_W4_SABM_0, // incoming
|
|
||||||
RFCOMM_MULTIPLEXER_SEND_UA_0,
|
|
||||||
RFCOMM_MULTIPLEXER_OPEN,
|
|
||||||
RFCOMM_MULTIPLEXER_SEND_UA_0_AND_DISC
|
|
||||||
} RFCOMM_MULTIPLEXER_STATE;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
MULT_EV_READY_TO_SEND = 1,
|
|
||||||
|
|
||||||
} RFCOMM_MULTIPLEXER_EVENT;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
RFCOMM_CHANNEL_CLOSED = 1,
|
|
||||||
RFCOMM_CHANNEL_W4_MULTIPLEXER,
|
|
||||||
RFCOMM_CHANNEL_SEND_UIH_PN,
|
|
||||||
RFCOMM_CHANNEL_W4_PN_RSP,
|
|
||||||
RFCOMM_CHANNEL_SEND_SABM_W4_UA,
|
|
||||||
RFCOMM_CHANNEL_W4_UA,
|
|
||||||
RFCOMM_CHANNEL_INCOMING_SETUP,
|
|
||||||
RFCOMM_CHANNEL_DLC_SETUP,
|
|
||||||
RFCOMM_CHANNEL_OPEN,
|
|
||||||
RFCOMM_CHANNEL_SEND_UA_AFTER_DISC,
|
|
||||||
RFCOMM_CHANNEL_SEND_DISC,
|
|
||||||
RFCOMM_CHANNEL_SEND_DM,
|
|
||||||
|
|
||||||
} RFCOMM_CHANNEL_STATE;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
STATE_VAR_NONE = 0,
|
|
||||||
STATE_VAR_CLIENT_ACCEPTED = 1 << 0,
|
|
||||||
STATE_VAR_RCVD_PN = 1 << 1,
|
|
||||||
STATE_VAR_RCVD_RPN = 1 << 2,
|
|
||||||
STATE_VAR_RCVD_SABM = 1 << 3,
|
|
||||||
|
|
||||||
STATE_VAR_RCVD_MSC_CMD = 1 << 4,
|
|
||||||
STATE_VAR_RCVD_MSC_RSP = 1 << 5,
|
|
||||||
STATE_VAR_SEND_PN_RSP = 1 << 6,
|
|
||||||
STATE_VAR_SEND_RPN_INFO = 1 << 7,
|
|
||||||
|
|
||||||
STATE_VAR_SEND_RPN_RSP = 1 << 8,
|
|
||||||
STATE_VAR_SEND_UA = 1 << 9,
|
|
||||||
STATE_VAR_SEND_MSC_CMD = 1 << 10,
|
|
||||||
STATE_VAR_SEND_MSC_RSP = 1 << 11,
|
|
||||||
|
|
||||||
STATE_VAR_SEND_CREDITS = 1 << 12,
|
|
||||||
STATE_VAR_SENT_MSC_CMD = 1 << 13,
|
|
||||||
STATE_VAR_SENT_MSC_RSP = 1 << 14,
|
|
||||||
STATE_VAR_SENT_CREDITS = 1 << 15,
|
|
||||||
} RFCOMM_CHANNEL_STATE_VAR;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CH_EVT_RCVD_SABM = 1,
|
|
||||||
CH_EVT_RCVD_UA,
|
|
||||||
CH_EVT_RCVD_PN,
|
|
||||||
CH_EVT_RCVD_PN_RSP,
|
|
||||||
CH_EVT_RCVD_DISC,
|
|
||||||
CH_EVT_RCVD_DM,
|
|
||||||
CH_EVT_RCVD_MSC_CMD,
|
|
||||||
CH_EVT_RCVD_MSC_RSP,
|
|
||||||
CH_EVT_RCVD_RPN_CMD,
|
|
||||||
CH_EVT_RCVD_RPN_REQ,
|
|
||||||
CH_EVT_MULTIPLEXER_READY,
|
|
||||||
CH_EVT_READY_TO_SEND,
|
|
||||||
} RFCOMM_CHANNEL_EVENT;
|
|
||||||
|
|
||||||
typedef struct rfcomm_channel_event {
|
|
||||||
RFCOMM_CHANNEL_EVENT type;
|
|
||||||
} rfcomm_channel_event_t;
|
|
||||||
|
|
||||||
typedef struct rfcomm_channel_event_pn {
|
|
||||||
rfcomm_channel_event_t super;
|
|
||||||
uint16_t max_frame_size;
|
|
||||||
uint8_t priority;
|
|
||||||
uint8_t credits_outgoing;
|
|
||||||
} rfcomm_channel_event_pn_t;
|
|
||||||
|
|
||||||
typedef struct rfcomm_rpn_data {
|
|
||||||
uint8_t baud_rate;
|
|
||||||
uint8_t flags;
|
|
||||||
uint8_t flow_control;
|
|
||||||
uint8_t xon;
|
|
||||||
uint8_t xoff;
|
|
||||||
uint8_t parameter_mask_0; // first byte
|
|
||||||
uint8_t parameter_mask_1; // second byte
|
|
||||||
} rfcomm_rpn_data_t;
|
|
||||||
|
|
||||||
typedef struct rfcomm_channel_event_rpn {
|
|
||||||
rfcomm_channel_event_t super;
|
|
||||||
rfcomm_rpn_data_t data;
|
|
||||||
} rfcomm_channel_event_rpn_t;
|
|
||||||
|
|
||||||
// info regarding potential connections
|
|
||||||
typedef struct {
|
|
||||||
// linked list - assert: first field
|
|
||||||
linked_item_t item;
|
|
||||||
|
|
||||||
// server channel
|
|
||||||
uint8_t server_channel;
|
|
||||||
|
|
||||||
// incoming max frame size
|
|
||||||
uint16_t max_frame_size;
|
|
||||||
|
|
||||||
// client connection
|
|
||||||
void *connection;
|
|
||||||
|
|
||||||
// internal connection
|
|
||||||
btstack_packet_handler_t packet_handler;
|
|
||||||
|
|
||||||
} rfcomm_service_t;
|
|
||||||
|
|
||||||
// info regarding multiplexer
|
|
||||||
// note: spec mandates single multplexer per device combination
|
|
||||||
typedef struct {
|
|
||||||
// linked list - assert: first field
|
|
||||||
linked_item_t item;
|
|
||||||
|
|
||||||
timer_source_t timer;
|
|
||||||
int timer_active;
|
|
||||||
|
|
||||||
RFCOMM_MULTIPLEXER_STATE state;
|
|
||||||
|
|
||||||
uint16_t l2cap_cid;
|
|
||||||
uint8_t l2cap_credits;
|
|
||||||
|
|
||||||
bd_addr_t remote_addr;
|
|
||||||
hci_con_handle_t con_handle;
|
|
||||||
|
|
||||||
uint8_t outgoing;
|
|
||||||
|
|
||||||
// hack to deal with authentication failure only observed by remote side
|
|
||||||
uint8_t at_least_one_connection;
|
|
||||||
|
|
||||||
uint16_t max_frame_size;
|
|
||||||
|
|
||||||
// send DM for DLCI != 0
|
|
||||||
uint8_t send_dm_for_dlci;
|
|
||||||
|
|
||||||
} rfcomm_multiplexer_t;
|
|
||||||
|
|
||||||
// info regarding an actual coneection
|
|
||||||
typedef struct {
|
|
||||||
// linked list - assert: first field
|
|
||||||
linked_item_t item;
|
|
||||||
|
|
||||||
rfcomm_multiplexer_t *multiplexer;
|
|
||||||
uint16_t rfcomm_cid;
|
|
||||||
uint8_t outgoing;
|
|
||||||
uint8_t dlci;
|
|
||||||
|
|
||||||
// credits for outgoing traffic
|
|
||||||
uint8_t credits_outgoing;
|
|
||||||
|
|
||||||
// number of packets granted to client
|
|
||||||
uint8_t packets_granted;
|
|
||||||
|
|
||||||
// credits for incoming traffic
|
|
||||||
uint8_t credits_incoming;
|
|
||||||
|
|
||||||
// channel state
|
|
||||||
RFCOMM_CHANNEL_STATE state;
|
|
||||||
|
|
||||||
// state variables used in RFCOMM_CHANNEL_INCOMING
|
|
||||||
RFCOMM_CHANNEL_STATE_VAR state_var;
|
|
||||||
|
|
||||||
// priority set by incoming side in PN
|
|
||||||
uint8_t pn_priority;
|
|
||||||
|
|
||||||
// negotiated frame size
|
|
||||||
uint16_t max_frame_size;
|
|
||||||
|
|
||||||
// rpn data
|
|
||||||
rfcomm_rpn_data_t rpn_data;
|
|
||||||
|
|
||||||
// server channel (see rfcomm_service_t) - NULL => outgoing channel
|
|
||||||
rfcomm_service_t * service;
|
|
||||||
|
|
||||||
// internal connection
|
|
||||||
btstack_packet_handler_t packet_handler;
|
|
||||||
|
|
||||||
// client connection
|
|
||||||
void * connection;
|
|
||||||
|
|
||||||
} rfcomm_channel_t;
|
|
||||||
|
|
||||||
// global rfcomm data
|
// global rfcomm data
|
||||||
static uint16_t rfcomm_client_cid_generator; // used for client channel IDs
|
static uint16_t rfcomm_client_cid_generator; // used for client channel IDs
|
||||||
@ -444,7 +255,7 @@ static void rfcomm_channel_initialize(rfcomm_channel_t *channel, rfcomm_multiple
|
|||||||
bzero(channel, sizeof(rfcomm_channel_t));
|
bzero(channel, sizeof(rfcomm_channel_t));
|
||||||
|
|
||||||
channel->state = RFCOMM_CHANNEL_CLOSED;
|
channel->state = RFCOMM_CHANNEL_CLOSED;
|
||||||
channel->state_var = STATE_VAR_NONE;
|
channel->state_var = RFCOMM_CHANNEL_STATE_VAR_NONE;
|
||||||
|
|
||||||
channel->multiplexer = multiplexer;
|
channel->multiplexer = multiplexer;
|
||||||
channel->service = service;
|
channel->service = service;
|
||||||
@ -1361,10 +1172,10 @@ void rfcomm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int rfcomm_channel_ready_for_open(rfcomm_channel_t *channel){
|
static int rfcomm_channel_ready_for_open(rfcomm_channel_t *channel){
|
||||||
// log_info("rfcomm_channel_ready_for_open state %u, flags needed %04x, current %04x, rf credits %u, l2cap credits %u \n", channel->state, STATE_VAR_RCVD_MSC_RSP|STATE_VAR_SENT_MSC_RSP|STATE_VAR_SENT_CREDITS, channel->state_var, channel->credits_outgoing, channel->multiplexer->l2cap_credits);
|
// log_info("rfcomm_channel_ready_for_open state %u, flags needed %04x, current %04x, rf credits %u, l2cap credits %u \n", channel->state, RFCOMM_CHANNEL_STATE_VAR_RCVD_MSC_RSP|RFCOMM_CHANNEL_STATE_VAR_SENT_MSC_RSP|RFCOMM_CHANNEL_STATE_VAR_SENT_CREDITS, channel->state_var, channel->credits_outgoing, channel->multiplexer->l2cap_credits);
|
||||||
if ((channel->state_var & STATE_VAR_RCVD_MSC_RSP) == 0) return 0;
|
if ((channel->state_var & RFCOMM_CHANNEL_STATE_VAR_RCVD_MSC_RSP) == 0) return 0;
|
||||||
if ((channel->state_var & STATE_VAR_SENT_MSC_RSP) == 0) return 0;
|
if ((channel->state_var & RFCOMM_CHANNEL_STATE_VAR_SENT_MSC_RSP) == 0) return 0;
|
||||||
if ((channel->state_var & STATE_VAR_SENT_CREDITS) == 0) return 0;
|
if ((channel->state_var & RFCOMM_CHANNEL_STATE_VAR_SENT_CREDITS) == 0) return 0;
|
||||||
if (channel->credits_outgoing == 0) return 0;
|
if (channel->credits_outgoing == 0) return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -1404,7 +1215,7 @@ static void rfcomm_channel_state_machine(rfcomm_channel_t *channel, rfcomm_chann
|
|||||||
// control port parameters
|
// control port parameters
|
||||||
rfcomm_channel_event_rpn_t *event_rpn = (rfcomm_channel_event_rpn_t*) event;
|
rfcomm_channel_event_rpn_t *event_rpn = (rfcomm_channel_event_rpn_t*) event;
|
||||||
memcpy(&channel->rpn_data, &event_rpn->data, sizeof(rfcomm_rpn_data_t));
|
memcpy(&channel->rpn_data, &event_rpn->data, sizeof(rfcomm_rpn_data_t));
|
||||||
channel->state_var |= STATE_VAR_SEND_RPN_RSP;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_RPN_RSP;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1420,15 +1231,15 @@ static void rfcomm_channel_state_machine(rfcomm_channel_t *channel, rfcomm_chann
|
|||||||
rpn_data.parameter_mask_0 = 0x7f; /* parameter mask, all values set */
|
rpn_data.parameter_mask_0 = 0x7f; /* parameter mask, all values set */
|
||||||
rpn_data.parameter_mask_1 = 0x3f; /* parameter mask, all values set */
|
rpn_data.parameter_mask_1 = 0x3f; /* parameter mask, all values set */
|
||||||
memcpy(&channel->rpn_data, &rpn_data, sizeof(rfcomm_rpn_data_t));
|
memcpy(&channel->rpn_data, &rpn_data, sizeof(rfcomm_rpn_data_t));
|
||||||
channel->state_var |= STATE_VAR_SEND_RPN_RSP;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_RPN_RSP;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: integrate in common swich
|
// TODO: integrate in common swich
|
||||||
if (event->type == CH_EVT_READY_TO_SEND){
|
if (event->type == CH_EVT_READY_TO_SEND){
|
||||||
if (channel->state_var & STATE_VAR_SEND_RPN_RSP){
|
if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_SEND_RPN_RSP){
|
||||||
log_info("Sending Remote Port Negotiation RSP for #%u\n", channel->dlci);
|
log_info("Sending Remote Port Negotiation RSP for #%u\n", channel->dlci);
|
||||||
channel->state_var &= ~STATE_VAR_SEND_RPN_RSP;
|
channel->state_var &= ~RFCOMM_CHANNEL_STATE_VAR_SEND_RPN_RSP;
|
||||||
rfcomm_send_uih_rpn_rsp(multiplexer, channel->dlci, &channel->rpn_data);
|
rfcomm_send_uih_rpn_rsp(multiplexer, channel->dlci, &channel->rpn_data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1441,14 +1252,14 @@ static void rfcomm_channel_state_machine(rfcomm_channel_t *channel, rfcomm_chann
|
|||||||
switch (event->type){
|
switch (event->type){
|
||||||
case CH_EVT_RCVD_SABM:
|
case CH_EVT_RCVD_SABM:
|
||||||
log_info("-> Inform app\n");
|
log_info("-> Inform app\n");
|
||||||
channel->state_var |= STATE_VAR_RCVD_SABM;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_RCVD_SABM;
|
||||||
channel->state = RFCOMM_CHANNEL_INCOMING_SETUP;
|
channel->state = RFCOMM_CHANNEL_INCOMING_SETUP;
|
||||||
rfcomm_emit_connection_request(channel);
|
rfcomm_emit_connection_request(channel);
|
||||||
break;
|
break;
|
||||||
case CH_EVT_RCVD_PN:
|
case CH_EVT_RCVD_PN:
|
||||||
rfcomm_channel_accept_pn(channel, event_pn);
|
rfcomm_channel_accept_pn(channel, event_pn);
|
||||||
log_info("-> Inform app\n");
|
log_info("-> Inform app\n");
|
||||||
channel->state_var |= STATE_VAR_RCVD_PN;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_RCVD_PN;
|
||||||
channel->state = RFCOMM_CHANNEL_INCOMING_SETUP;
|
channel->state = RFCOMM_CHANNEL_INCOMING_SETUP;
|
||||||
rfcomm_emit_connection_request(channel);
|
rfcomm_emit_connection_request(channel);
|
||||||
break;
|
break;
|
||||||
@ -1460,32 +1271,32 @@ static void rfcomm_channel_state_machine(rfcomm_channel_t *channel, rfcomm_chann
|
|||||||
case RFCOMM_CHANNEL_INCOMING_SETUP:
|
case RFCOMM_CHANNEL_INCOMING_SETUP:
|
||||||
switch (event->type){
|
switch (event->type){
|
||||||
case CH_EVT_RCVD_SABM:
|
case CH_EVT_RCVD_SABM:
|
||||||
channel->state_var |= STATE_VAR_RCVD_SABM;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_RCVD_SABM;
|
||||||
if (channel->state_var & STATE_VAR_CLIENT_ACCEPTED) {
|
if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_CLIENT_ACCEPTED) {
|
||||||
channel->state_var |= STATE_VAR_SEND_UA;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_UA;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CH_EVT_RCVD_PN:
|
case CH_EVT_RCVD_PN:
|
||||||
rfcomm_channel_accept_pn(channel, event_pn);
|
rfcomm_channel_accept_pn(channel, event_pn);
|
||||||
channel->state_var |= STATE_VAR_RCVD_PN;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_RCVD_PN;
|
||||||
if (channel->state_var & STATE_VAR_CLIENT_ACCEPTED) {
|
if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_CLIENT_ACCEPTED) {
|
||||||
channel->state_var |= STATE_VAR_SEND_PN_RSP;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_PN_RSP;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CH_EVT_READY_TO_SEND:
|
case CH_EVT_READY_TO_SEND:
|
||||||
if (channel->state_var & STATE_VAR_SEND_PN_RSP){
|
if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_SEND_PN_RSP){
|
||||||
log_info("Sending UIH Parameter Negotiation Respond for #%u\n", channel->dlci);
|
log_info("Sending UIH Parameter Negotiation Respond for #%u\n", channel->dlci);
|
||||||
channel->state_var &= ~STATE_VAR_SEND_PN_RSP;
|
channel->state_var &= ~RFCOMM_CHANNEL_STATE_VAR_SEND_PN_RSP;
|
||||||
rfcomm_send_uih_pn_response(multiplexer, channel->dlci, channel->pn_priority, channel->max_frame_size);
|
rfcomm_send_uih_pn_response(multiplexer, channel->dlci, channel->pn_priority, channel->max_frame_size);
|
||||||
}
|
}
|
||||||
else if (channel->state_var & STATE_VAR_SEND_UA){
|
else if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_SEND_UA){
|
||||||
log_info("Sending UA #%u\n", channel->dlci);
|
log_info("Sending UA #%u\n", channel->dlci);
|
||||||
channel->state_var &= ~STATE_VAR_SEND_UA;
|
channel->state_var &= ~RFCOMM_CHANNEL_STATE_VAR_SEND_UA;
|
||||||
rfcomm_send_ua(multiplexer, channel->dlci);
|
rfcomm_send_ua(multiplexer, channel->dlci);
|
||||||
}
|
}
|
||||||
if ((channel->state_var & STATE_VAR_CLIENT_ACCEPTED) && (channel->state_var & STATE_VAR_RCVD_SABM)) {
|
if ((channel->state_var & RFCOMM_CHANNEL_STATE_VAR_CLIENT_ACCEPTED) && (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_RCVD_SABM)) {
|
||||||
channel->state_var |= STATE_VAR_SEND_MSC_CMD;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_CMD;
|
||||||
channel->state_var |= STATE_VAR_SEND_CREDITS;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_CREDITS;
|
||||||
channel->state = RFCOMM_CHANNEL_DLC_SETUP;
|
channel->state = RFCOMM_CHANNEL_DLC_SETUP;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1550,8 +1361,8 @@ static void rfcomm_channel_state_machine(rfcomm_channel_t *channel, rfcomm_chann
|
|||||||
switch (event->type){
|
switch (event->type){
|
||||||
case CH_EVT_RCVD_UA:
|
case CH_EVT_RCVD_UA:
|
||||||
channel->state = RFCOMM_CHANNEL_DLC_SETUP;
|
channel->state = RFCOMM_CHANNEL_DLC_SETUP;
|
||||||
channel->state_var |= STATE_VAR_SEND_MSC_CMD;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_CMD;
|
||||||
channel->state_var |= STATE_VAR_SEND_CREDITS;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_CREDITS;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1561,32 +1372,32 @@ static void rfcomm_channel_state_machine(rfcomm_channel_t *channel, rfcomm_chann
|
|||||||
case RFCOMM_CHANNEL_DLC_SETUP:
|
case RFCOMM_CHANNEL_DLC_SETUP:
|
||||||
switch (event->type){
|
switch (event->type){
|
||||||
case CH_EVT_RCVD_MSC_CMD:
|
case CH_EVT_RCVD_MSC_CMD:
|
||||||
channel->state_var |= STATE_VAR_RCVD_MSC_CMD;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_RCVD_MSC_CMD;
|
||||||
channel->state_var |= STATE_VAR_SEND_MSC_RSP;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_RSP;
|
||||||
break;
|
break;
|
||||||
case CH_EVT_RCVD_MSC_RSP:
|
case CH_EVT_RCVD_MSC_RSP:
|
||||||
channel->state_var |= STATE_VAR_RCVD_MSC_RSP;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_RCVD_MSC_RSP;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CH_EVT_READY_TO_SEND:
|
case CH_EVT_READY_TO_SEND:
|
||||||
if (channel->state_var & STATE_VAR_SEND_MSC_CMD){
|
if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_CMD){
|
||||||
log_info("Sending MSC CMD for #%u\n", channel->dlci);
|
log_info("Sending MSC CMD for #%u\n", channel->dlci);
|
||||||
channel->state_var &= ~STATE_VAR_SEND_MSC_CMD;
|
channel->state_var &= ~RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_CMD;
|
||||||
channel->state_var |= STATE_VAR_SENT_MSC_CMD;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SENT_MSC_CMD;
|
||||||
rfcomm_send_uih_msc_cmd(multiplexer, channel->dlci , 0x8d); // ea=1,fc=0,rtc=1,rtr=1,ic=0,dv=1
|
rfcomm_send_uih_msc_cmd(multiplexer, channel->dlci , 0x8d); // ea=1,fc=0,rtc=1,rtr=1,ic=0,dv=1
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (channel->state_var & STATE_VAR_SEND_MSC_RSP){
|
if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_RSP){
|
||||||
log_info("Sending MSC RSP for #%u\n", channel->dlci);
|
log_info("Sending MSC RSP for #%u\n", channel->dlci);
|
||||||
channel->state_var &= ~STATE_VAR_SEND_MSC_RSP;
|
channel->state_var &= ~RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_RSP;
|
||||||
channel->state_var |= STATE_VAR_SENT_MSC_RSP;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SENT_MSC_RSP;
|
||||||
rfcomm_send_uih_msc_rsp(multiplexer, channel->dlci, 0x8d); // ea=1,fc=0,rtc=1,rtr=1,ic=0,dv=1
|
rfcomm_send_uih_msc_rsp(multiplexer, channel->dlci, 0x8d); // ea=1,fc=0,rtc=1,rtr=1,ic=0,dv=1
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (channel->state_var & STATE_VAR_SEND_CREDITS){
|
if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_SEND_CREDITS){
|
||||||
log_info("Providing credits for #%u\n", channel->dlci);
|
log_info("Providing credits for #%u\n", channel->dlci);
|
||||||
channel->state_var &= ~STATE_VAR_SEND_CREDITS;
|
channel->state_var &= ~RFCOMM_CHANNEL_STATE_VAR_SEND_CREDITS;
|
||||||
channel->state_var |= STATE_VAR_SENT_CREDITS;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SENT_CREDITS;
|
||||||
rfcomm_channel_provide_credits(channel);
|
rfcomm_channel_provide_credits(channel);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1605,12 +1416,12 @@ static void rfcomm_channel_state_machine(rfcomm_channel_t *channel, rfcomm_chann
|
|||||||
case RFCOMM_CHANNEL_OPEN:
|
case RFCOMM_CHANNEL_OPEN:
|
||||||
switch (event->type){
|
switch (event->type){
|
||||||
case CH_EVT_RCVD_MSC_CMD:
|
case CH_EVT_RCVD_MSC_CMD:
|
||||||
channel->state_var |= STATE_VAR_SEND_MSC_RSP;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_RSP;
|
||||||
break;
|
break;
|
||||||
case CH_EVT_READY_TO_SEND:
|
case CH_EVT_READY_TO_SEND:
|
||||||
if (channel->state_var & STATE_VAR_SEND_MSC_RSP){
|
if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_RSP){
|
||||||
log_info("Sending MSC RSP for #%u\n", channel->dlci);
|
log_info("Sending MSC RSP for #%u\n", channel->dlci);
|
||||||
channel->state_var &= ~STATE_VAR_SEND_MSC_RSP;
|
channel->state_var &= ~RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_RSP;
|
||||||
rfcomm_send_uih_msc_rsp(multiplexer, channel->dlci, 0x8d); // ea=1,fc=0,rtc=1,rtr=1,ic=0,dv=1
|
rfcomm_send_uih_msc_rsp(multiplexer, channel->dlci, 0x8d); // ea=1,fc=0,rtc=1,rtr=1,ic=0,dv=1
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1860,12 +1671,12 @@ void rfcomm_accept_connection_internal(uint16_t rfcomm_cid){
|
|||||||
if (!channel) return;
|
if (!channel) return;
|
||||||
switch (channel->state) {
|
switch (channel->state) {
|
||||||
case RFCOMM_CHANNEL_INCOMING_SETUP:
|
case RFCOMM_CHANNEL_INCOMING_SETUP:
|
||||||
channel->state_var |= STATE_VAR_CLIENT_ACCEPTED;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_CLIENT_ACCEPTED;
|
||||||
if (channel->state_var & STATE_VAR_RCVD_PN){
|
if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_RCVD_PN){
|
||||||
channel->state_var |= STATE_VAR_SEND_PN_RSP;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_PN_RSP;
|
||||||
}
|
}
|
||||||
if (channel->state_var & STATE_VAR_RCVD_SABM){
|
if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_RCVD_SABM){
|
||||||
channel->state_var |= STATE_VAR_SEND_UA;
|
channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_UA;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
197
src/rfcomm.h
197
src/rfcomm.h
@ -38,6 +38,10 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#if defined __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
void rfcomm_init(void);
|
void rfcomm_init(void);
|
||||||
|
|
||||||
// register packet handler
|
// register packet handler
|
||||||
@ -56,4 +60,197 @@ int rfcomm_send_internal(uint8_t rfcomm_cid, uint8_t *data, uint16_t len);
|
|||||||
void rfcomm_close_connection(void *connection);
|
void rfcomm_close_connection(void *connection);
|
||||||
|
|
||||||
|
|
||||||
|
// private structs
|
||||||
|
typedef enum {
|
||||||
|
RFCOMM_MULTIPLEXER_CLOSED = 1,
|
||||||
|
RFCOMM_MULTIPLEXER_W4_CONNECT, // outgoing
|
||||||
|
RFCOMM_MULTIPLEXER_SEND_SABM_0, // "
|
||||||
|
RFCOMM_MULTIPLEXER_W4_UA_0, // "
|
||||||
|
RFCOMM_MULTIPLEXER_W4_SABM_0, // incoming
|
||||||
|
RFCOMM_MULTIPLEXER_SEND_UA_0,
|
||||||
|
RFCOMM_MULTIPLEXER_OPEN,
|
||||||
|
RFCOMM_MULTIPLEXER_SEND_UA_0_AND_DISC
|
||||||
|
} RFCOMM_MULTIPLEXER_STATE;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MULT_EV_READY_TO_SEND = 1,
|
||||||
|
|
||||||
|
} RFCOMM_MULTIPLEXER_EVENT;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
RFCOMM_CHANNEL_CLOSED = 1,
|
||||||
|
RFCOMM_CHANNEL_W4_MULTIPLEXER,
|
||||||
|
RFCOMM_CHANNEL_SEND_UIH_PN,
|
||||||
|
RFCOMM_CHANNEL_W4_PN_RSP,
|
||||||
|
RFCOMM_CHANNEL_SEND_SABM_W4_UA,
|
||||||
|
RFCOMM_CHANNEL_W4_UA,
|
||||||
|
RFCOMM_CHANNEL_INCOMING_SETUP,
|
||||||
|
RFCOMM_CHANNEL_DLC_SETUP,
|
||||||
|
RFCOMM_CHANNEL_OPEN,
|
||||||
|
RFCOMM_CHANNEL_SEND_UA_AFTER_DISC,
|
||||||
|
RFCOMM_CHANNEL_SEND_DISC,
|
||||||
|
RFCOMM_CHANNEL_SEND_DM,
|
||||||
|
|
||||||
|
} RFCOMM_CHANNEL_STATE;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
RFCOMM_CHANNEL_STATE_VAR_NONE = 0,
|
||||||
|
RFCOMM_CHANNEL_STATE_VAR_CLIENT_ACCEPTED = 1 << 0,
|
||||||
|
RFCOMM_CHANNEL_STATE_VAR_RCVD_PN = 1 << 1,
|
||||||
|
RFCOMM_CHANNEL_STATE_VAR_RCVD_RPN = 1 << 2,
|
||||||
|
RFCOMM_CHANNEL_STATE_VAR_RCVD_SABM = 1 << 3,
|
||||||
|
|
||||||
|
RFCOMM_CHANNEL_STATE_VAR_RCVD_MSC_CMD = 1 << 4,
|
||||||
|
RFCOMM_CHANNEL_STATE_VAR_RCVD_MSC_RSP = 1 << 5,
|
||||||
|
RFCOMM_CHANNEL_STATE_VAR_SEND_PN_RSP = 1 << 6,
|
||||||
|
RFCOMM_CHANNEL_STATE_VAR_SEND_RPN_INFO = 1 << 7,
|
||||||
|
|
||||||
|
RFCOMM_CHANNEL_STATE_VAR_SEND_RPN_RSP = 1 << 8,
|
||||||
|
RFCOMM_CHANNEL_STATE_VAR_SEND_UA = 1 << 9,
|
||||||
|
RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_CMD = 1 << 10,
|
||||||
|
RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_RSP = 1 << 11,
|
||||||
|
|
||||||
|
RFCOMM_CHANNEL_STATE_VAR_SEND_CREDITS = 1 << 12,
|
||||||
|
RFCOMM_CHANNEL_STATE_VAR_SENT_MSC_CMD = 1 << 13,
|
||||||
|
RFCOMM_CHANNEL_STATE_VAR_SENT_MSC_RSP = 1 << 14,
|
||||||
|
RFCOMM_CHANNEL_STATE_VAR_SENT_CREDITS = 1 << 15,
|
||||||
|
} RFCOMM_CHANNEL_STATE_VAR;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CH_EVT_RCVD_SABM = 1,
|
||||||
|
CH_EVT_RCVD_UA,
|
||||||
|
CH_EVT_RCVD_PN,
|
||||||
|
CH_EVT_RCVD_PN_RSP,
|
||||||
|
CH_EVT_RCVD_DISC,
|
||||||
|
CH_EVT_RCVD_DM,
|
||||||
|
CH_EVT_RCVD_MSC_CMD,
|
||||||
|
CH_EVT_RCVD_MSC_RSP,
|
||||||
|
CH_EVT_RCVD_RPN_CMD,
|
||||||
|
CH_EVT_RCVD_RPN_REQ,
|
||||||
|
CH_EVT_MULTIPLEXER_READY,
|
||||||
|
CH_EVT_READY_TO_SEND,
|
||||||
|
} RFCOMM_CHANNEL_EVENT;
|
||||||
|
|
||||||
|
typedef struct rfcomm_channel_event {
|
||||||
|
RFCOMM_CHANNEL_EVENT type;
|
||||||
|
} rfcomm_channel_event_t;
|
||||||
|
|
||||||
|
typedef struct rfcomm_channel_event_pn {
|
||||||
|
rfcomm_channel_event_t super;
|
||||||
|
uint16_t max_frame_size;
|
||||||
|
uint8_t priority;
|
||||||
|
uint8_t credits_outgoing;
|
||||||
|
} rfcomm_channel_event_pn_t;
|
||||||
|
|
||||||
|
typedef struct rfcomm_rpn_data {
|
||||||
|
uint8_t baud_rate;
|
||||||
|
uint8_t flags;
|
||||||
|
uint8_t flow_control;
|
||||||
|
uint8_t xon;
|
||||||
|
uint8_t xoff;
|
||||||
|
uint8_t parameter_mask_0; // first byte
|
||||||
|
uint8_t parameter_mask_1; // second byte
|
||||||
|
} rfcomm_rpn_data_t;
|
||||||
|
|
||||||
|
typedef struct rfcomm_channel_event_rpn {
|
||||||
|
rfcomm_channel_event_t super;
|
||||||
|
rfcomm_rpn_data_t data;
|
||||||
|
} rfcomm_channel_event_rpn_t;
|
||||||
|
|
||||||
|
// info regarding potential connections
|
||||||
|
typedef struct {
|
||||||
|
// linked list - assert: first field
|
||||||
|
linked_item_t item;
|
||||||
|
|
||||||
|
// server channel
|
||||||
|
uint8_t server_channel;
|
||||||
|
|
||||||
|
// incoming max frame size
|
||||||
|
uint16_t max_frame_size;
|
||||||
|
|
||||||
|
// client connection
|
||||||
|
void *connection;
|
||||||
|
|
||||||
|
// internal connection
|
||||||
|
btstack_packet_handler_t packet_handler;
|
||||||
|
|
||||||
|
} rfcomm_service_t;
|
||||||
|
|
||||||
|
// info regarding multiplexer
|
||||||
|
// note: spec mandates single multplexer per device combination
|
||||||
|
typedef struct {
|
||||||
|
// linked list - assert: first field
|
||||||
|
linked_item_t item;
|
||||||
|
|
||||||
|
timer_source_t timer;
|
||||||
|
int timer_active;
|
||||||
|
|
||||||
|
RFCOMM_MULTIPLEXER_STATE state;
|
||||||
|
|
||||||
|
uint16_t l2cap_cid;
|
||||||
|
uint8_t l2cap_credits;
|
||||||
|
|
||||||
|
bd_addr_t remote_addr;
|
||||||
|
hci_con_handle_t con_handle;
|
||||||
|
|
||||||
|
uint8_t outgoing;
|
||||||
|
|
||||||
|
// hack to deal with authentication failure only observed by remote side
|
||||||
|
uint8_t at_least_one_connection;
|
||||||
|
|
||||||
|
uint16_t max_frame_size;
|
||||||
|
|
||||||
|
// send DM for DLCI != 0
|
||||||
|
uint8_t send_dm_for_dlci;
|
||||||
|
|
||||||
|
} rfcomm_multiplexer_t;
|
||||||
|
|
||||||
|
// info regarding an actual coneection
|
||||||
|
typedef struct {
|
||||||
|
// linked list - assert: first field
|
||||||
|
linked_item_t item;
|
||||||
|
|
||||||
|
rfcomm_multiplexer_t *multiplexer;
|
||||||
|
uint16_t rfcomm_cid;
|
||||||
|
uint8_t outgoing;
|
||||||
|
uint8_t dlci;
|
||||||
|
|
||||||
|
// credits for outgoing traffic
|
||||||
|
uint8_t credits_outgoing;
|
||||||
|
|
||||||
|
// number of packets granted to client
|
||||||
|
uint8_t packets_granted;
|
||||||
|
|
||||||
|
// credits for incoming traffic
|
||||||
|
uint8_t credits_incoming;
|
||||||
|
|
||||||
|
// channel state
|
||||||
|
RFCOMM_CHANNEL_STATE state;
|
||||||
|
|
||||||
|
// state variables used in RFCOMM_CHANNEL_INCOMING
|
||||||
|
RFCOMM_CHANNEL_STATE_VAR state_var;
|
||||||
|
|
||||||
|
// priority set by incoming side in PN
|
||||||
|
uint8_t pn_priority;
|
||||||
|
|
||||||
|
// negotiated frame size
|
||||||
|
uint16_t max_frame_size;
|
||||||
|
|
||||||
|
// rpn data
|
||||||
|
rfcomm_rpn_data_t rpn_data;
|
||||||
|
|
||||||
|
// server channel (see rfcomm_service_t) - NULL => outgoing channel
|
||||||
|
rfcomm_service_t * service;
|
||||||
|
|
||||||
|
// internal connection
|
||||||
|
btstack_packet_handler_t packet_handler;
|
||||||
|
|
||||||
|
// client connection
|
||||||
|
void * connection;
|
||||||
|
|
||||||
|
} rfcomm_channel_t;
|
||||||
|
|
||||||
|
|
||||||
|
#if defined __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user