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 |
|