rfcomm.c (2e98e94777c5c47163576922d6cfcab3956af8f5) rfcomm.c (a7a98a14513a32bb8a1b7d8f69d92f3c9f0b8988)
1/*
2 * Copyright (C) 2014 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright

--- 53 unchanged lines hidden (view full) ---

62#ifndef PRIxPTR
63#if defined(__MSP430X__) && defined(__MSP430X_LARGE__)
64#define PRIxPTR "lx"
65#else
66#define PRIxPTR "x"
67#endif
68#endif
69
1/*
2 * Copyright (C) 2014 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright

--- 53 unchanged lines hidden (view full) ---

62#ifndef PRIxPTR
63#if defined(__MSP430X__) && defined(__MSP430X_LARGE__)
64#define PRIxPTR "lx"
65#else
66#define PRIxPTR "x"
67#endif
68#endif
69
70// L2CAP ERTM requires ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE and ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE_FOR_RFCOMM
71#if defined(ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE) && defined(ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE_FOR_RFCOMM)
72#define RFCOMM_USE_OUTGOING_BUFFER
73#define RFCOMM_USE_ERTM
74#endif
75
70#define RFCOMM_MULIPLEXER_TIMEOUT_MS 60000
71
72#define RFCOMM_CREDITS 10
73
74// FCS calc
75#define BT_RFCOMM_CODE_WORD 0xE0 // pol = x8+x2+x1+1
76#define BT_RFCOMM_CRC_CHECK_LEN 3
77#define BT_RFCOMM_UIHCRC_CHECK_LEN 2

--- 51 unchanged lines hidden (view full) ---

129
130// linked lists for all
131static btstack_linked_list_t rfcomm_multiplexers = NULL;
132static btstack_linked_list_t rfcomm_channels = NULL;
133static btstack_linked_list_t rfcomm_services = NULL;
134
135static gap_security_level_t rfcomm_security_level;
136
76#define RFCOMM_MULIPLEXER_TIMEOUT_MS 60000
77
78#define RFCOMM_CREDITS 10
79
80// FCS calc
81#define BT_RFCOMM_CODE_WORD 0xE0 // pol = x8+x2+x1+1
82#define BT_RFCOMM_CRC_CHECK_LEN 3
83#define BT_RFCOMM_UIHCRC_CHECK_LEN 2

--- 51 unchanged lines hidden (view full) ---

135
136// linked lists for all
137static btstack_linked_list_t rfcomm_multiplexers = NULL;
138static btstack_linked_list_t rfcomm_channels = NULL;
139static btstack_linked_list_t rfcomm_services = NULL;
140
141static gap_security_level_t rfcomm_security_level;
142
137#if defined(ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE) && defined(ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE_FOR_RFCOMM)
138#define RFCOMM_USE_OUTGOING_BUFFER
143#ifdef RFCOMM_USE_ERTM
144static uint16_t ertm_id;
145void (*rfcomm_ertm_request_callback)(rfcomm_ertm_request_t * request);
146void (*rfcomm_ertm_released_callback)(uint16_t ertm_id);
139#endif
140
141#ifdef RFCOMM_USE_OUTGOING_BUFFER
142static uint8_t outgoing_buffer[1030];
143#endif
144
145static int rfcomm_channel_can_send(rfcomm_channel_t * channel);
146static int rfcomm_channel_ready_for_open(rfcomm_channel_t *channel);

--- 836 unchanged lines hidden (view full) ---

983 return 1;
984 }
985
986 multiplexer->con_handle = con_handle;
987 multiplexer->l2cap_cid = l2cap_cid;
988 //
989 multiplexer->state = RFCOMM_MULTIPLEXER_W4_SABM_0;
990 log_info("L2CAP_EVENT_INCOMING_CONNECTION (l2cap_cid 0x%02x) for BLUETOOTH_PROTOCOL_RFCOMM => accept", l2cap_cid);
147#endif
148
149#ifdef RFCOMM_USE_OUTGOING_BUFFER
150static uint8_t outgoing_buffer[1030];
151#endif
152
153static int rfcomm_channel_can_send(rfcomm_channel_t * channel);
154static int rfcomm_channel_ready_for_open(rfcomm_channel_t *channel);

--- 836 unchanged lines hidden (view full) ---

991 return 1;
992 }
993
994 multiplexer->con_handle = con_handle;
995 multiplexer->l2cap_cid = l2cap_cid;
996 //
997 multiplexer->state = RFCOMM_MULTIPLEXER_W4_SABM_0;
998 log_info("L2CAP_EVENT_INCOMING_CONNECTION (l2cap_cid 0x%02x) for BLUETOOTH_PROTOCOL_RFCOMM => accept", l2cap_cid);
999
1000#ifdef RFCOMM_USE_ERTM
1001 // request
1002 rfcomm_ertm_request_t request;
1003 memset(&request, 0, sizeof(rfcomm_ertm_request_t));
1004 memcpy(request.addr, event_addr, 6);
1005 request.ertm_id = ++ertm_id;
1006 if (rfcomm_ertm_request_callback){
1007 (*rfcomm_ertm_request_callback)(&request);
1008 }
1009 if (request.ertm_config && request.ertm_buffer && request.ertm_buffer_size){
1010 multiplexer->ertm_id = request.ertm_id;
1011 l2cap_accept_ertm_connection(l2cap_cid, request.ertm_config, request.ertm_buffer, request.ertm_buffer_size);
1012 }
1013 return 1;
1014#endif
1015
991 l2cap_accept_connection(l2cap_cid);
992 return 1;
993
994 // l2cap connection opened -> store l2cap_cid, remote_addr
995 case L2CAP_EVENT_CHANNEL_OPENED:
996
997 if (little_endian_read_16(packet, 11) != BLUETOOTH_PROTOCOL_RFCOMM) break;
998

--- 76 unchanged lines hidden (view full) ---

1075 multiplexer = rfcomm_multiplexer_for_l2cap_cid(l2cap_cid);
1076 log_info("L2CAP_EVENT_CHANNEL_CLOSED cid 0x%0x, mult %p", l2cap_cid, multiplexer);
1077 if (!multiplexer) break;
1078 log_info("L2CAP_EVENT_CHANNEL_CLOSED state %u", multiplexer->state);
1079 // no need to call l2cap_disconnect here, as it's already closed
1080 rfcomm_multiplexer_finalize(multiplexer);
1081 return 1;
1082
1016 l2cap_accept_connection(l2cap_cid);
1017 return 1;
1018
1019 // l2cap connection opened -> store l2cap_cid, remote_addr
1020 case L2CAP_EVENT_CHANNEL_OPENED:
1021
1022 if (little_endian_read_16(packet, 11) != BLUETOOTH_PROTOCOL_RFCOMM) break;
1023

--- 76 unchanged lines hidden (view full) ---

1100 multiplexer = rfcomm_multiplexer_for_l2cap_cid(l2cap_cid);
1101 log_info("L2CAP_EVENT_CHANNEL_CLOSED cid 0x%0x, mult %p", l2cap_cid, multiplexer);
1102 if (!multiplexer) break;
1103 log_info("L2CAP_EVENT_CHANNEL_CLOSED state %u", multiplexer->state);
1104 // no need to call l2cap_disconnect here, as it's already closed
1105 rfcomm_multiplexer_finalize(multiplexer);
1106 return 1;
1107
1108#ifdef RFCOMM_USE_ERTM
1109 case L2CAP_EVENT_ERTM_BUFFER_RELEASED:
1110 l2cap_cid = l2cap_event_ertm_buffer_released_get_local_cid(packet);
1111 multiplexer = rfcomm_multiplexer_for_l2cap_cid(l2cap_cid);
1112 if (multiplexer) {
1113 log_info("buffer for ertm id %u released", multiplexer->ertm_id);
1114 if (rfcomm_ertm_released_callback){
1115 (*rfcomm_ertm_released_callback)(multiplexer->ertm_id);
1116 }
1117 }
1118 break;
1119#endif
1120
1083 default:
1084 break;
1085 }
1086 return 0;
1087}
1088
1089static int rfcomm_multiplexer_l2cap_packet_handler(uint16_t channel, uint8_t *packet, uint16_t size){
1090 // get or create a multiplexer for a certain device

--- 1243 unchanged lines hidden (view full) ---

2334 if (out_rfcomm_cid){
2335 *out_rfcomm_cid = channel->rfcomm_cid;
2336 }
2337
2338 // start multiplexer setup
2339 if (multiplexer->state != RFCOMM_MULTIPLEXER_OPEN) {
2340 channel->state = RFCOMM_CHANNEL_W4_MULTIPLEXER;
2341 uint16_t l2cap_cid = 0;
1121 default:
1122 break;
1123 }
1124 return 0;
1125}
1126
1127static int rfcomm_multiplexer_l2cap_packet_handler(uint16_t channel, uint8_t *packet, uint16_t size){
1128 // get or create a multiplexer for a certain device

--- 1243 unchanged lines hidden (view full) ---

2372 if (out_rfcomm_cid){
2373 *out_rfcomm_cid = channel->rfcomm_cid;
2374 }
2375
2376 // start multiplexer setup
2377 if (multiplexer->state != RFCOMM_MULTIPLEXER_OPEN) {
2378 channel->state = RFCOMM_CHANNEL_W4_MULTIPLEXER;
2379 uint16_t l2cap_cid = 0;
2342 status = l2cap_create_channel(rfcomm_packet_handler, addr, BLUETOOTH_PROTOCOL_RFCOMM, l2cap_max_mtu(), &l2cap_cid);
2380#ifdef RFCOMM_USE_ERTM
2381 // request
2382 rfcomm_ertm_request_t request;
2383 memset(&request, 0, sizeof(rfcomm_ertm_request_t));
2384 memcpy(request.addr, addr, 6);
2385 request.ertm_id = ++ertm_id;
2386 if (rfcomm_ertm_request_callback){
2387 (*rfcomm_ertm_request_callback)(&request);
2388 }
2389 if (request.ertm_config && request.ertm_buffer && request.ertm_buffer_size){
2390 multiplexer->ertm_id = request.ertm_id;
2391 status = l2cap_create_ertm_channel(rfcomm_packet_handler, addr, BLUETOOTH_PROTOCOL_RFCOMM,
2392 request.ertm_config, request.ertm_buffer, request.ertm_buffer_size, &l2cap_cid);
2393 }
2394 else
2395#endif
2396 {
2397 status = l2cap_create_channel(rfcomm_packet_handler, addr, BLUETOOTH_PROTOCOL_RFCOMM, l2cap_max_mtu(), &l2cap_cid);
2398 }
2343 if (status) goto fail;
2344 multiplexer->l2cap_cid = l2cap_cid;
2345 return 0;
2346 }
2347
2348 channel->state = RFCOMM_CHANNEL_SEND_UIH_PN;
2349
2350 // start connecting, if multiplexer is already up and running

--- 129 unchanged lines hidden (view full) ---

2480 if (!channel) return;
2481 if (!channel->incoming_flow_control) return;
2482 channel->new_credits_incoming += credits;
2483
2484 // process
2485 l2cap_request_can_send_now_event(channel->multiplexer->l2cap_cid);
2486}
2487
2399 if (status) goto fail;
2400 multiplexer->l2cap_cid = l2cap_cid;
2401 return 0;
2402 }
2403
2404 channel->state = RFCOMM_CHANNEL_SEND_UIH_PN;
2405
2406 // start connecting, if multiplexer is already up and running

--- 129 unchanged lines hidden (view full) ---

2536 if (!channel) return;
2537 if (!channel->incoming_flow_control) return;
2538 channel->new_credits_incoming += credits;
2539
2540 // process
2541 l2cap_request_can_send_now_event(channel->multiplexer->l2cap_cid);
2542}
2543
2544#ifdef RFCOMM_USE_ERTM
2545void rfcomm_enable_l2cap_ertm(void request_callback(rfcomm_ertm_request_t * request), void released_callback(uint16_t ertm_id)){
2546 rfcomm_ertm_request_callback = request_callback;
2547 rfcomm_ertm_released_callback = released_callback;
2548}
2549#endif