BTstack Bluetooth stack

Dependencies:   mbed USBHost

USBホストライブラリを変更しました。

  • Bluetoothマウス(VGP-BMS33)での動作を確認しました。mouse_demo.cpp
Committer:
va009039
Date:
Fri Mar 22 22:35:57 2013 +0000
Revision:
2:871b41f4789e
Parent:
0:1ed23ab1345f
change to single thread

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:1ed23ab1345f 1 /*
va009039 0:1ed23ab1345f 2 * Copyright (C) 2009-2012 by Matthias Ringwald
va009039 0:1ed23ab1345f 3 *
va009039 0:1ed23ab1345f 4 * Redistribution and use in source and binary forms, with or without
va009039 0:1ed23ab1345f 5 * modification, are permitted provided that the following conditions
va009039 0:1ed23ab1345f 6 * are met:
va009039 0:1ed23ab1345f 7 *
va009039 0:1ed23ab1345f 8 * 1. Redistributions of source code must retain the above copyright
va009039 0:1ed23ab1345f 9 * notice, this list of conditions and the following disclaimer.
va009039 0:1ed23ab1345f 10 * 2. Redistributions in binary form must reproduce the above copyright
va009039 0:1ed23ab1345f 11 * notice, this list of conditions and the following disclaimer in the
va009039 0:1ed23ab1345f 12 * documentation and/or other materials provided with the distribution.
va009039 0:1ed23ab1345f 13 * 3. Neither the name of the copyright holders nor the names of
va009039 0:1ed23ab1345f 14 * contributors may be used to endorse or promote products derived
va009039 0:1ed23ab1345f 15 * from this software without specific prior written permission.
va009039 0:1ed23ab1345f 16 * 4. Any redistribution, use, or modification is done solely for
va009039 0:1ed23ab1345f 17 * personal benefit and not for any commercial purpose or for
va009039 0:1ed23ab1345f 18 * monetary gain.
va009039 0:1ed23ab1345f 19 *
va009039 0:1ed23ab1345f 20 * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
va009039 0:1ed23ab1345f 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
va009039 0:1ed23ab1345f 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
va009039 0:1ed23ab1345f 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
va009039 0:1ed23ab1345f 24 * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
va009039 0:1ed23ab1345f 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
va009039 0:1ed23ab1345f 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
va009039 0:1ed23ab1345f 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
va009039 0:1ed23ab1345f 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
va009039 0:1ed23ab1345f 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
va009039 0:1ed23ab1345f 30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
va009039 0:1ed23ab1345f 31 * SUCH DAMAGE.
va009039 0:1ed23ab1345f 32 *
va009039 0:1ed23ab1345f 33 * Please inquire about commercial licensing options at btstack@ringwald.ch
va009039 0:1ed23ab1345f 34 *
va009039 0:1ed23ab1345f 35 */
va009039 0:1ed23ab1345f 36
va009039 0:1ed23ab1345f 37 /*
va009039 0:1ed23ab1345f 38 * rfcomm.c
va009039 0:1ed23ab1345f 39 */
va009039 0:1ed23ab1345f 40
va009039 0:1ed23ab1345f 41 #include <stdio.h>
va009039 0:1ed23ab1345f 42 #include <stdlib.h>
va009039 0:1ed23ab1345f 43 #include <string.h> // memcpy
va009039 0:1ed23ab1345f 44 #include <stdint.h>
va009039 0:1ed23ab1345f 45
va009039 0:1ed23ab1345f 46 #include <btstack/btstack.h>
va009039 0:1ed23ab1345f 47 #include <btstack/hci_cmds.h>
va009039 0:1ed23ab1345f 48 #include <btstack/utils.h>
va009039 0:1ed23ab1345f 49
va009039 0:1ed23ab1345f 50 #include <btstack/utils.h>
va009039 0:1ed23ab1345f 51 #include "btstack_memory.h"
va009039 0:1ed23ab1345f 52 #include "hci.h"
va009039 0:1ed23ab1345f 53 #include "hci_dump.h"
va009039 0:1ed23ab1345f 54 #include "debug.h"
va009039 0:1ed23ab1345f 55 #include "rfcomm.h"
va009039 0:1ed23ab1345f 56
va009039 0:1ed23ab1345f 57 // workaround for missing PRIxPTR on mspgcc (16/20-bit MCU)
va009039 0:1ed23ab1345f 58 #ifndef PRIxPTR
va009039 0:1ed23ab1345f 59 #if defined(__MSP430X__) && defined(__MSP430X_LARGE__)
va009039 0:1ed23ab1345f 60 #define PRIxPTR "lx"
va009039 0:1ed23ab1345f 61 #else
va009039 0:1ed23ab1345f 62 #define PRIxPTR "x"
va009039 0:1ed23ab1345f 63 #endif
va009039 0:1ed23ab1345f 64 #endif
va009039 0:1ed23ab1345f 65
va009039 0:1ed23ab1345f 66
va009039 0:1ed23ab1345f 67 // Control field values bit no. 1 2 3 4 PF 6 7 8
va009039 0:1ed23ab1345f 68 #define BT_RFCOMM_SABM 0x3F // 1 1 1 1 1 1 0 0
va009039 0:1ed23ab1345f 69 #define BT_RFCOMM_UA 0x73 // 1 1 0 0 1 1 1 0
va009039 0:1ed23ab1345f 70 #define BT_RFCOMM_DM 0x0F // 1 1 1 1 0 0 0 0
va009039 0:1ed23ab1345f 71 #define BT_RFCOMM_DM_PF 0x1F // 1 1 1 1 1 0 0 0
va009039 0:1ed23ab1345f 72 #define BT_RFCOMM_DISC 0x53 // 1 1 0 0 1 0 1 0
va009039 0:1ed23ab1345f 73 #define BT_RFCOMM_UIH 0xEF // 1 1 1 1 0 1 1 1
va009039 0:1ed23ab1345f 74 #define BT_RFCOMM_UIH_PF 0xFF // 1 1 1 1 0 1 1 1
va009039 0:1ed23ab1345f 75
va009039 0:1ed23ab1345f 76 // Multiplexer message types
va009039 0:1ed23ab1345f 77 #define BT_RFCOMM_CLD_CMD 0xC3
va009039 0:1ed23ab1345f 78 #define BT_RFCOMM_FCON_CMD 0xA3
va009039 0:1ed23ab1345f 79 #define BT_RFCOMM_FCON_RSP 0xA1
va009039 0:1ed23ab1345f 80 #define BT_RFCOMM_FCOFF_CMD 0x63
va009039 0:1ed23ab1345f 81 #define BT_RFCOMM_FCOFF_RSP 0x61
va009039 0:1ed23ab1345f 82 #define BT_RFCOMM_MSC_CMD 0xE3
va009039 0:1ed23ab1345f 83 #define BT_RFCOMM_MSC_RSP 0xE1
va009039 0:1ed23ab1345f 84 #define BT_RFCOMM_NSC_RSP 0x11
va009039 0:1ed23ab1345f 85 #define BT_RFCOMM_PN_CMD 0x83
va009039 0:1ed23ab1345f 86 #define BT_RFCOMM_PN_RSP 0x81
va009039 0:1ed23ab1345f 87 #define BT_RFCOMM_RLS_CMD 0x53
va009039 0:1ed23ab1345f 88 #define BT_RFCOMM_RLS_RSP 0x51
va009039 0:1ed23ab1345f 89 #define BT_RFCOMM_RPN_CMD 0x93
va009039 0:1ed23ab1345f 90 #define BT_RFCOMM_RPN_RSP 0x91
va009039 0:1ed23ab1345f 91 #define BT_RFCOMM_TEST_CMD 0x23
va009039 0:1ed23ab1345f 92 #define BT_RFCOMM_TEST_RSP 0x21
va009039 0:1ed23ab1345f 93
va009039 0:1ed23ab1345f 94 #define RFCOMM_MULIPLEXER_TIMEOUT_MS 60000
va009039 0:1ed23ab1345f 95
va009039 0:1ed23ab1345f 96 // FCS calc
va009039 0:1ed23ab1345f 97 #define BT_RFCOMM_CODE_WORD 0xE0 // pol = x8+x2+x1+1
va009039 0:1ed23ab1345f 98 #define BT_RFCOMM_CRC_CHECK_LEN 3
va009039 0:1ed23ab1345f 99 #define BT_RFCOMM_UIHCRC_CHECK_LEN 2
va009039 0:1ed23ab1345f 100
va009039 0:1ed23ab1345f 101 #include "l2cap.h"
va009039 0:1ed23ab1345f 102
va009039 0:1ed23ab1345f 103 // used for debugging
va009039 0:1ed23ab1345f 104 // #define RFCOMM_LOG_CREDITS
va009039 0:1ed23ab1345f 105
va009039 0:1ed23ab1345f 106 // global rfcomm data
va009039 0:1ed23ab1345f 107 static uint16_t rfcomm_client_cid_generator; // used for client channel IDs
va009039 0:1ed23ab1345f 108
va009039 0:1ed23ab1345f 109 // linked lists for all
va009039 0:1ed23ab1345f 110 static linked_list_t rfcomm_multiplexers = NULL;
va009039 0:1ed23ab1345f 111 static linked_list_t rfcomm_channels = NULL;
va009039 0:1ed23ab1345f 112 static linked_list_t rfcomm_services = NULL;
va009039 0:1ed23ab1345f 113
va009039 0:1ed23ab1345f 114 static void (*app_packet_handler)(void * connection, uint8_t packet_type,
va009039 0:1ed23ab1345f 115 uint16_t channel, uint8_t *packet, uint16_t size);
va009039 0:1ed23ab1345f 116
va009039 0:1ed23ab1345f 117 static void rfcomm_run(void);
va009039 0:1ed23ab1345f 118 static void rfcomm_hand_out_credits(void);
va009039 0:1ed23ab1345f 119 static void rfcomm_channel_state_machine(rfcomm_channel_t *channel, rfcomm_channel_event_t *event);
va009039 0:1ed23ab1345f 120 static void rfcomm_channel_state_machine_2(rfcomm_multiplexer_t * multiplexer, uint8_t dlci, rfcomm_channel_event_t *event);
va009039 0:1ed23ab1345f 121 static int rfcomm_channel_ready_for_open(rfcomm_channel_t *channel);
va009039 0:1ed23ab1345f 122 static void rfcomm_multiplexer_state_machine(rfcomm_multiplexer_t * multiplexer, RFCOMM_MULTIPLEXER_EVENT event);
va009039 0:1ed23ab1345f 123
va009039 0:1ed23ab1345f 124
va009039 0:1ed23ab1345f 125 // MARK: RFCOMM CLIENT EVENTS
va009039 0:1ed23ab1345f 126
va009039 0:1ed23ab1345f 127 // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
va009039 0:1ed23ab1345f 128 static void rfcomm_emit_connection_request(rfcomm_channel_t *channel) {
va009039 0:1ed23ab1345f 129 uint8_t event[11];
va009039 0:1ed23ab1345f 130 event[0] = RFCOMM_EVENT_INCOMING_CONNECTION;
va009039 0:1ed23ab1345f 131 event[1] = sizeof(event) - 2;
va009039 0:1ed23ab1345f 132 bt_flip_addr(&event[2], channel->multiplexer->remote_addr);
va009039 0:1ed23ab1345f 133 event[8] = channel->dlci >> 1;
va009039 0:1ed23ab1345f 134 bt_store_16(event, 9, channel->rfcomm_cid);
va009039 0:1ed23ab1345f 135 hci_dump_packet(HCI_EVENT_PACKET, 0, event, sizeof(event));
va009039 0:1ed23ab1345f 136 (*app_packet_handler)(channel->connection, HCI_EVENT_PACKET, 0, (uint8_t *) event, sizeof(event));
va009039 0:1ed23ab1345f 137 }
va009039 0:1ed23ab1345f 138
va009039 0:1ed23ab1345f 139 // API Change: BTstack-0.3.50x uses
va009039 0:1ed23ab1345f 140 // data: event(8), len(8), status (8), address (48), server channel(8), rfcomm_cid(16), max frame size(16)
va009039 0:1ed23ab1345f 141 // next Cydia release will use SVN version of this
va009039 0:1ed23ab1345f 142 // data: event(8), len(8), status (8), address (48), handle (16), server channel(8), rfcomm_cid(16), max frame size(16)
va009039 0:1ed23ab1345f 143 static void rfcomm_emit_channel_opened(rfcomm_channel_t *channel, uint8_t status) {
va009039 0:1ed23ab1345f 144 uint8_t event[16];
va009039 0:1ed23ab1345f 145 uint8_t pos = 0;
va009039 0:1ed23ab1345f 146 event[pos++] = RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE;
va009039 0:1ed23ab1345f 147 event[pos++] = sizeof(event) - 2;
va009039 0:1ed23ab1345f 148 event[pos++] = status;
va009039 0:1ed23ab1345f 149 bt_flip_addr(&event[pos], channel->multiplexer->remote_addr); pos += 6;
va009039 0:1ed23ab1345f 150 bt_store_16(event, pos, channel->multiplexer->con_handle); pos += 2;
va009039 0:1ed23ab1345f 151 event[pos++] = channel->dlci >> 1;
va009039 0:1ed23ab1345f 152 bt_store_16(event, pos, channel->rfcomm_cid); pos += 2; // channel ID
va009039 0:1ed23ab1345f 153 bt_store_16(event, pos, channel->max_frame_size); pos += 2; // max frame size
va009039 0:1ed23ab1345f 154 hci_dump_packet(HCI_EVENT_PACKET, 0, event, sizeof(event));
va009039 0:1ed23ab1345f 155 (*app_packet_handler)(channel->connection, HCI_EVENT_PACKET, 0, (uint8_t *) event, pos);
va009039 0:1ed23ab1345f 156 }
va009039 0:1ed23ab1345f 157
va009039 0:1ed23ab1345f 158 static void rfcomm_emit_channel_open_failed_outgoing_memory(void * connection, bd_addr_t *addr, uint8_t server_channel){
va009039 0:1ed23ab1345f 159 uint8_t event[16];
va009039 0:1ed23ab1345f 160 uint8_t pos = 0;
va009039 0:1ed23ab1345f 161 event[pos++] = RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE;
va009039 0:1ed23ab1345f 162 event[pos++] = sizeof(event) - 2;
va009039 0:1ed23ab1345f 163 event[pos++] = BTSTACK_MEMORY_ALLOC_FAILED;
va009039 0:1ed23ab1345f 164 bt_flip_addr(&event[pos], *addr); pos += 6;
va009039 0:1ed23ab1345f 165 bt_store_16(event, pos, 0); pos += 2;
va009039 0:1ed23ab1345f 166 event[pos++] = server_channel;
va009039 0:1ed23ab1345f 167 bt_store_16(event, pos, 0); pos += 2; // channel ID
va009039 0:1ed23ab1345f 168 bt_store_16(event, pos, 0); pos += 2; // max frame size
va009039 0:1ed23ab1345f 169 hci_dump_packet(HCI_EVENT_PACKET, 0, event, sizeof(event));
va009039 0:1ed23ab1345f 170 (*app_packet_handler)(connection, HCI_EVENT_PACKET, 0, (uint8_t *) event, pos);
va009039 0:1ed23ab1345f 171 }
va009039 0:1ed23ab1345f 172
va009039 0:1ed23ab1345f 173 // data: event(8), len(8), creidts incoming(8), new credits incoming(8), credits outgoing(8)
va009039 0:1ed23ab1345f 174 static inline void rfcomm_emit_credit_status(rfcomm_channel_t * channel) {
va009039 0:1ed23ab1345f 175 #ifdef RFCOMM_LOG_CREDITS
va009039 0:1ed23ab1345f 176 uint8_t event[5];
va009039 0:1ed23ab1345f 177 event[0] = 0x88;
va009039 0:1ed23ab1345f 178 event[1] = sizeof(event) - 2;
va009039 0:1ed23ab1345f 179 event[2] = channel->credits_incoming;
va009039 0:1ed23ab1345f 180 event[3] = channel->new_credits_incoming;
va009039 0:1ed23ab1345f 181 event[4] = channel->credits_outgoing;
va009039 0:1ed23ab1345f 182 hci_dump_packet(HCI_EVENT_PACKET, 0, event, sizeof(event));
va009039 0:1ed23ab1345f 183 #endif
va009039 0:1ed23ab1345f 184 }
va009039 0:1ed23ab1345f 185
va009039 0:1ed23ab1345f 186 // data: event(8), len(8), rfcomm_cid(16)
va009039 0:1ed23ab1345f 187 static void rfcomm_emit_channel_closed(rfcomm_channel_t * channel) {
va009039 0:1ed23ab1345f 188 uint8_t event[4];
va009039 0:1ed23ab1345f 189 event[0] = RFCOMM_EVENT_CHANNEL_CLOSED;
va009039 0:1ed23ab1345f 190 event[1] = sizeof(event) - 2;
va009039 0:1ed23ab1345f 191 bt_store_16(event, 2, channel->rfcomm_cid);
va009039 0:1ed23ab1345f 192 hci_dump_packet(HCI_EVENT_PACKET, 0, event, sizeof(event));
va009039 0:1ed23ab1345f 193 (*app_packet_handler)(channel->connection, HCI_EVENT_PACKET, 0, (uint8_t *) event, sizeof(event));
va009039 0:1ed23ab1345f 194 }
va009039 0:1ed23ab1345f 195
va009039 0:1ed23ab1345f 196 static void rfcomm_emit_credits(rfcomm_channel_t * channel, uint8_t credits) {
va009039 0:1ed23ab1345f 197 uint8_t event[5];
va009039 0:1ed23ab1345f 198 event[0] = RFCOMM_EVENT_CREDITS;
va009039 0:1ed23ab1345f 199 event[1] = sizeof(event) - 2;
va009039 0:1ed23ab1345f 200 bt_store_16(event, 2, channel->rfcomm_cid);
va009039 0:1ed23ab1345f 201 event[4] = credits;
va009039 0:1ed23ab1345f 202 hci_dump_packet(HCI_EVENT_PACKET, 0, event, sizeof(event));
va009039 0:1ed23ab1345f 203 (*app_packet_handler)(channel->connection, HCI_EVENT_PACKET, 0, (uint8_t *) event, sizeof(event));
va009039 0:1ed23ab1345f 204 }
va009039 0:1ed23ab1345f 205
va009039 0:1ed23ab1345f 206 static void rfcomm_emit_service_registered(void *connection, uint8_t status, uint8_t channel){
va009039 0:1ed23ab1345f 207 uint8_t event[4];
va009039 0:1ed23ab1345f 208 event[0] = RFCOMM_EVENT_SERVICE_REGISTERED;
va009039 0:1ed23ab1345f 209 event[1] = sizeof(event) - 2;
va009039 0:1ed23ab1345f 210 event[2] = status;
va009039 0:1ed23ab1345f 211 event[3] = channel;
va009039 0:1ed23ab1345f 212 hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
va009039 0:1ed23ab1345f 213 (*app_packet_handler)(connection, HCI_EVENT_PACKET, 0, (uint8_t *) event, sizeof(event));
va009039 0:1ed23ab1345f 214 }
va009039 0:1ed23ab1345f 215
va009039 0:1ed23ab1345f 216 // MARK: RFCOMM MULTIPLEXER HELPER
va009039 0:1ed23ab1345f 217
va009039 0:1ed23ab1345f 218 static uint16_t rfcomm_max_frame_size_for_l2cap_mtu(uint16_t l2cap_mtu){
va009039 0:1ed23ab1345f 219
va009039 0:1ed23ab1345f 220 // Assume RFCOMM header with credits and single byte length field
va009039 0:1ed23ab1345f 221 uint16_t max_frame_size = l2cap_mtu - 5;
va009039 0:1ed23ab1345f 222
va009039 0:1ed23ab1345f 223 // single byte can denote len up to 127
va009039 0:1ed23ab1345f 224 if (max_frame_size > 127) {
va009039 0:1ed23ab1345f 225 max_frame_size--;
va009039 0:1ed23ab1345f 226 }
va009039 0:1ed23ab1345f 227
va009039 0:1ed23ab1345f 228 log_info("rfcomm_max_frame_size_for_l2cap_mtu: %u -> %u\n", l2cap_mtu, max_frame_size);
va009039 0:1ed23ab1345f 229 return max_frame_size;
va009039 0:1ed23ab1345f 230 }
va009039 0:1ed23ab1345f 231
va009039 0:1ed23ab1345f 232 static void rfcomm_multiplexer_initialize(rfcomm_multiplexer_t *multiplexer){
va009039 0:1ed23ab1345f 233
va009039 0:1ed23ab1345f 234 memset(multiplexer, 0, sizeof(rfcomm_multiplexer_t));
va009039 0:1ed23ab1345f 235
va009039 0:1ed23ab1345f 236 multiplexer->state = RFCOMM_MULTIPLEXER_CLOSED;
va009039 0:1ed23ab1345f 237 multiplexer->l2cap_credits = 0;
va009039 0:1ed23ab1345f 238 multiplexer->send_dm_for_dlci = 0;
va009039 0:1ed23ab1345f 239 multiplexer->max_frame_size = rfcomm_max_frame_size_for_l2cap_mtu(l2cap_max_mtu());
va009039 0:1ed23ab1345f 240 }
va009039 0:1ed23ab1345f 241
va009039 0:1ed23ab1345f 242 static rfcomm_multiplexer_t * rfcomm_multiplexer_create_for_addr(bd_addr_t *addr){
va009039 0:1ed23ab1345f 243
va009039 0:1ed23ab1345f 244 // alloc structure
va009039 0:1ed23ab1345f 245 rfcomm_multiplexer_t * multiplexer = (rfcomm_multiplexer_t*)btstack_memory_rfcomm_multiplexer_get();
va009039 0:1ed23ab1345f 246 if (!multiplexer) return NULL;
va009039 0:1ed23ab1345f 247
va009039 0:1ed23ab1345f 248 // fill in
va009039 0:1ed23ab1345f 249 rfcomm_multiplexer_initialize(multiplexer);
va009039 0:1ed23ab1345f 250 BD_ADDR_COPY(&multiplexer->remote_addr, addr);
va009039 0:1ed23ab1345f 251
va009039 0:1ed23ab1345f 252 // add to services list
va009039 0:1ed23ab1345f 253 linked_list_add(&rfcomm_multiplexers, (linked_item_t *) multiplexer);
va009039 0:1ed23ab1345f 254
va009039 0:1ed23ab1345f 255 return multiplexer;
va009039 0:1ed23ab1345f 256 }
va009039 0:1ed23ab1345f 257
va009039 0:1ed23ab1345f 258 static rfcomm_multiplexer_t * rfcomm_multiplexer_for_addr(bd_addr_t *addr){
va009039 0:1ed23ab1345f 259 linked_item_t *it;
va009039 0:1ed23ab1345f 260 for (it = (linked_item_t *) rfcomm_multiplexers; it ; it = it->next){
va009039 0:1ed23ab1345f 261 rfcomm_multiplexer_t * multiplexer = ((rfcomm_multiplexer_t *) it);
va009039 0:1ed23ab1345f 262 if (BD_ADDR_CMP(addr, multiplexer->remote_addr) == 0) {
va009039 0:1ed23ab1345f 263 return multiplexer;
va009039 0:1ed23ab1345f 264 };
va009039 0:1ed23ab1345f 265 }
va009039 0:1ed23ab1345f 266 return NULL;
va009039 0:1ed23ab1345f 267 }
va009039 0:1ed23ab1345f 268
va009039 0:1ed23ab1345f 269 static rfcomm_multiplexer_t * rfcomm_multiplexer_for_l2cap_cid(uint16_t l2cap_cid) {
va009039 0:1ed23ab1345f 270 linked_item_t *it;
va009039 0:1ed23ab1345f 271 for (it = (linked_item_t *) rfcomm_multiplexers; it ; it = it->next){
va009039 0:1ed23ab1345f 272 rfcomm_multiplexer_t * multiplexer = ((rfcomm_multiplexer_t *) it);
va009039 0:1ed23ab1345f 273 if (multiplexer->l2cap_cid == l2cap_cid) {
va009039 0:1ed23ab1345f 274 return multiplexer;
va009039 0:1ed23ab1345f 275 };
va009039 0:1ed23ab1345f 276 }
va009039 0:1ed23ab1345f 277 return NULL;
va009039 0:1ed23ab1345f 278 }
va009039 0:1ed23ab1345f 279
va009039 0:1ed23ab1345f 280 static int rfcomm_multiplexer_has_channels(rfcomm_multiplexer_t * multiplexer){
va009039 0:1ed23ab1345f 281 linked_item_t *it;
va009039 0:1ed23ab1345f 282 for (it = (linked_item_t *) rfcomm_channels; it ; it = it->next){
va009039 0:1ed23ab1345f 283 rfcomm_channel_t * channel = ((rfcomm_channel_t *) it);
va009039 0:1ed23ab1345f 284 if (channel->multiplexer == multiplexer) {
va009039 0:1ed23ab1345f 285 return 1;
va009039 0:1ed23ab1345f 286 }
va009039 0:1ed23ab1345f 287 }
va009039 0:1ed23ab1345f 288 return 0;
va009039 0:1ed23ab1345f 289 }
va009039 0:1ed23ab1345f 290
va009039 0:1ed23ab1345f 291 // MARK: RFCOMM CHANNEL HELPER
va009039 0:1ed23ab1345f 292
va009039 0:1ed23ab1345f 293 static void rfcomm_dump_channels(void){
va009039 0:1ed23ab1345f 294 #ifndef EMBEDDED
va009039 0:1ed23ab1345f 295 linked_item_t * it;
va009039 0:1ed23ab1345f 296 int channels = 0;
va009039 0:1ed23ab1345f 297 for (it = (linked_item_t *) rfcomm_channels; it ; it = it->next){
va009039 0:1ed23ab1345f 298 rfcomm_channel_t * channel = (rfcomm_channel_t *) it;
va009039 0:1ed23ab1345f 299 log_info("Channel #%u: addr %p, state %u\n", channels, channel, channel->state);
va009039 0:1ed23ab1345f 300 channels++;
va009039 0:1ed23ab1345f 301 }
va009039 0:1ed23ab1345f 302 #endif
va009039 0:1ed23ab1345f 303 }
va009039 0:1ed23ab1345f 304
va009039 0:1ed23ab1345f 305 static void rfcomm_channel_initialize(rfcomm_channel_t *channel, rfcomm_multiplexer_t *multiplexer,
va009039 0:1ed23ab1345f 306 rfcomm_service_t *service, uint8_t server_channel){
va009039 0:1ed23ab1345f 307
va009039 0:1ed23ab1345f 308 // don't use 0 as channel id
va009039 0:1ed23ab1345f 309 if (rfcomm_client_cid_generator == 0) ++rfcomm_client_cid_generator;
va009039 0:1ed23ab1345f 310
va009039 0:1ed23ab1345f 311 // setup channel
va009039 0:1ed23ab1345f 312 memset(channel, 0, sizeof(rfcomm_channel_t));
va009039 0:1ed23ab1345f 313
va009039 0:1ed23ab1345f 314 channel->state = RFCOMM_CHANNEL_CLOSED;
va009039 0:1ed23ab1345f 315 channel->state_var = RFCOMM_CHANNEL_STATE_VAR_NONE;
va009039 0:1ed23ab1345f 316
va009039 0:1ed23ab1345f 317 channel->multiplexer = multiplexer;
va009039 0:1ed23ab1345f 318 channel->service = service;
va009039 0:1ed23ab1345f 319 channel->rfcomm_cid = rfcomm_client_cid_generator++;
va009039 0:1ed23ab1345f 320 channel->max_frame_size = multiplexer->max_frame_size;
va009039 0:1ed23ab1345f 321
va009039 0:1ed23ab1345f 322 channel->credits_incoming = 0;
va009039 0:1ed23ab1345f 323 channel->credits_outgoing = 0;
va009039 0:1ed23ab1345f 324 channel->packets_granted = 0;
va009039 0:1ed23ab1345f 325
va009039 0:1ed23ab1345f 326 // incoming flow control not active
va009039 0:1ed23ab1345f 327 channel->new_credits_incoming = 0x30;
va009039 0:1ed23ab1345f 328 channel->incoming_flow_control = 0;
va009039 0:1ed23ab1345f 329
va009039 0:1ed23ab1345f 330 if (service) {
va009039 0:1ed23ab1345f 331 // incoming connection
va009039 0:1ed23ab1345f 332 channel->outgoing = 0;
va009039 0:1ed23ab1345f 333 channel->dlci = (server_channel << 1) | multiplexer->outgoing;
va009039 0:1ed23ab1345f 334 if (channel->max_frame_size > service->max_frame_size) {
va009039 0:1ed23ab1345f 335 channel->max_frame_size = service->max_frame_size;
va009039 0:1ed23ab1345f 336 }
va009039 0:1ed23ab1345f 337 channel->incoming_flow_control = service->incoming_flow_control;
va009039 0:1ed23ab1345f 338 channel->new_credits_incoming = service->incoming_initial_credits;
va009039 0:1ed23ab1345f 339 } else {
va009039 0:1ed23ab1345f 340 // outgoing connection
va009039 0:1ed23ab1345f 341 channel->outgoing = 1;
va009039 0:1ed23ab1345f 342 channel->dlci = (server_channel << 1) | (multiplexer->outgoing ^ 1);
va009039 0:1ed23ab1345f 343 }
va009039 0:1ed23ab1345f 344 }
va009039 0:1ed23ab1345f 345
va009039 0:1ed23ab1345f 346 // service == NULL -> outgoing channel
va009039 0:1ed23ab1345f 347 static rfcomm_channel_t * rfcomm_channel_create(rfcomm_multiplexer_t * multiplexer,
va009039 0:1ed23ab1345f 348 rfcomm_service_t * service, uint8_t server_channel){
va009039 0:1ed23ab1345f 349
va009039 0:1ed23ab1345f 350 log_info("rfcomm_channel_create for service %p, channel %u --- begin\n", service, server_channel);
va009039 0:1ed23ab1345f 351 rfcomm_dump_channels();
va009039 0:1ed23ab1345f 352
va009039 0:1ed23ab1345f 353 // alloc structure
va009039 0:1ed23ab1345f 354 rfcomm_channel_t * channel = (rfcomm_channel_t*)btstack_memory_rfcomm_channel_get();
va009039 0:1ed23ab1345f 355 if (!channel) return NULL;
va009039 0:1ed23ab1345f 356
va009039 0:1ed23ab1345f 357 // fill in
va009039 0:1ed23ab1345f 358 rfcomm_channel_initialize(channel, multiplexer, service, server_channel);
va009039 0:1ed23ab1345f 359
va009039 0:1ed23ab1345f 360 // add to services list
va009039 0:1ed23ab1345f 361 linked_list_add(&rfcomm_channels, (linked_item_t *) channel);
va009039 0:1ed23ab1345f 362
va009039 0:1ed23ab1345f 363 return channel;
va009039 0:1ed23ab1345f 364 }
va009039 0:1ed23ab1345f 365
va009039 0:1ed23ab1345f 366 static rfcomm_channel_t * rfcomm_channel_for_rfcomm_cid(uint16_t rfcomm_cid){
va009039 0:1ed23ab1345f 367 linked_item_t *it;
va009039 0:1ed23ab1345f 368 for (it = (linked_item_t *) rfcomm_channels; it ; it = it->next){
va009039 0:1ed23ab1345f 369 rfcomm_channel_t * channel = ((rfcomm_channel_t *) it);
va009039 0:1ed23ab1345f 370 if (channel->rfcomm_cid == rfcomm_cid) {
va009039 0:1ed23ab1345f 371 return channel;
va009039 0:1ed23ab1345f 372 };
va009039 0:1ed23ab1345f 373 }
va009039 0:1ed23ab1345f 374 return NULL;
va009039 0:1ed23ab1345f 375 }
va009039 0:1ed23ab1345f 376
va009039 0:1ed23ab1345f 377 static rfcomm_channel_t * rfcomm_channel_for_multiplexer_and_dlci(rfcomm_multiplexer_t * multiplexer, uint8_t dlci){
va009039 0:1ed23ab1345f 378 linked_item_t *it;
va009039 0:1ed23ab1345f 379 for (it = (linked_item_t *) rfcomm_channels; it ; it = it->next){
va009039 0:1ed23ab1345f 380 rfcomm_channel_t * channel = ((rfcomm_channel_t *) it);
va009039 0:1ed23ab1345f 381 if (channel->dlci == dlci && channel->multiplexer == multiplexer) {
va009039 0:1ed23ab1345f 382 return channel;
va009039 0:1ed23ab1345f 383 };
va009039 0:1ed23ab1345f 384 }
va009039 0:1ed23ab1345f 385 return NULL;
va009039 0:1ed23ab1345f 386 }
va009039 0:1ed23ab1345f 387
va009039 0:1ed23ab1345f 388 static rfcomm_service_t * rfcomm_service_for_channel(uint8_t server_channel){
va009039 0:1ed23ab1345f 389 linked_item_t *it;
va009039 0:1ed23ab1345f 390 for (it = (linked_item_t *) rfcomm_services; it ; it = it->next){
va009039 0:1ed23ab1345f 391 rfcomm_service_t * service = ((rfcomm_service_t *) it);
va009039 0:1ed23ab1345f 392 if ( service->server_channel == server_channel){
va009039 0:1ed23ab1345f 393 return service;
va009039 0:1ed23ab1345f 394 };
va009039 0:1ed23ab1345f 395 }
va009039 0:1ed23ab1345f 396 return NULL;
va009039 0:1ed23ab1345f 397 }
va009039 0:1ed23ab1345f 398
va009039 0:1ed23ab1345f 399 // MARK: RFCOMM SEND
va009039 0:1ed23ab1345f 400
va009039 0:1ed23ab1345f 401 /**
va009039 0:1ed23ab1345f 402 * @param credits - only used for RFCOMM flow control in UIH wiht P/F = 1
va009039 0:1ed23ab1345f 403 */
va009039 0:1ed23ab1345f 404 static int rfcomm_send_packet_for_multiplexer(rfcomm_multiplexer_t *multiplexer, uint8_t address, uint8_t control, uint8_t credits, uint8_t *data, uint16_t len){
va009039 0:1ed23ab1345f 405
va009039 0:1ed23ab1345f 406 if (!l2cap_can_send_packet_now(multiplexer->l2cap_cid)) return BTSTACK_ACL_BUFFERS_FULL;
va009039 0:1ed23ab1345f 407
va009039 0:1ed23ab1345f 408 uint8_t * rfcomm_out_buffer = l2cap_get_outgoing_buffer();
va009039 0:1ed23ab1345f 409
va009039 0:1ed23ab1345f 410 uint16_t pos = 0;
va009039 0:1ed23ab1345f 411 uint8_t crc_fields = 3;
va009039 0:1ed23ab1345f 412
va009039 0:1ed23ab1345f 413 rfcomm_out_buffer[pos++] = address;
va009039 0:1ed23ab1345f 414 rfcomm_out_buffer[pos++] = control;
va009039 0:1ed23ab1345f 415
va009039 0:1ed23ab1345f 416 // length field can be 1 or 2 octets
va009039 0:1ed23ab1345f 417 if (len < 128){
va009039 0:1ed23ab1345f 418 rfcomm_out_buffer[pos++] = (len << 1)| 1; // bits 0-6
va009039 0:1ed23ab1345f 419 } else {
va009039 0:1ed23ab1345f 420 rfcomm_out_buffer[pos++] = (len & 0x7f) << 1; // bits 0-6
va009039 0:1ed23ab1345f 421 rfcomm_out_buffer[pos++] = len >> 7; // bits 7-14
va009039 0:1ed23ab1345f 422 crc_fields++;
va009039 0:1ed23ab1345f 423 }
va009039 0:1ed23ab1345f 424
va009039 0:1ed23ab1345f 425 // add credits for UIH frames when PF bit is set
va009039 0:1ed23ab1345f 426 if (control == BT_RFCOMM_UIH_PF){
va009039 0:1ed23ab1345f 427 rfcomm_out_buffer[pos++] = credits;
va009039 0:1ed23ab1345f 428 }
va009039 0:1ed23ab1345f 429
va009039 0:1ed23ab1345f 430 // copy actual data
va009039 0:1ed23ab1345f 431 if (len) {
va009039 0:1ed23ab1345f 432 memcpy(&rfcomm_out_buffer[pos], data, len);
va009039 0:1ed23ab1345f 433 pos += len;
va009039 0:1ed23ab1345f 434 }
va009039 0:1ed23ab1345f 435
va009039 0:1ed23ab1345f 436 // UIH frames only calc FCS over address + control (5.1.1)
va009039 0:1ed23ab1345f 437 if ((control & 0xef) == BT_RFCOMM_UIH){
va009039 0:1ed23ab1345f 438 crc_fields = 2;
va009039 0:1ed23ab1345f 439 }
va009039 0:1ed23ab1345f 440 rfcomm_out_buffer[pos++] = crc8_calc(rfcomm_out_buffer, crc_fields); // calc fcs
va009039 0:1ed23ab1345f 441
va009039 0:1ed23ab1345f 442 int credits_taken = 0;
va009039 0:1ed23ab1345f 443 if (multiplexer->l2cap_credits){
va009039 0:1ed23ab1345f 444 credits_taken++;
va009039 0:1ed23ab1345f 445 multiplexer->l2cap_credits--;
va009039 0:1ed23ab1345f 446 } else {
va009039 0:1ed23ab1345f 447 log_info( "rfcomm_send_packet addr %02x, ctrl %02x size %u without l2cap credits\n", address, control, pos);
va009039 0:1ed23ab1345f 448 }
va009039 0:1ed23ab1345f 449
va009039 0:1ed23ab1345f 450 int err = l2cap_send_prepared(multiplexer->l2cap_cid, pos);
va009039 0:1ed23ab1345f 451
va009039 0:1ed23ab1345f 452 if (err) {
va009039 0:1ed23ab1345f 453 // undo credit counting
va009039 0:1ed23ab1345f 454 multiplexer->l2cap_credits += credits_taken;
va009039 0:1ed23ab1345f 455 }
va009039 0:1ed23ab1345f 456 return err;
va009039 0:1ed23ab1345f 457 }
va009039 0:1ed23ab1345f 458
va009039 0:1ed23ab1345f 459 // C/R Flag in Address
va009039 0:1ed23ab1345f 460 // - terms: initiator = station that creates multiplexer with SABM
va009039 0:1ed23ab1345f 461 // - terms: responder = station that responds to multiplexer setup with UA
va009039 0:1ed23ab1345f 462 // "For SABM, UA, DM and DISC frames C/R bit is set according to Table 1 in GSM 07.10, section 5.2.1.2"
va009039 0:1ed23ab1345f 463 // - command initiator = 1 /response responder = 1
va009039 0:1ed23ab1345f 464 // - command responder = 0 /response initiator = 0
va009039 0:1ed23ab1345f 465 // "For UIH frames, the C/R bit is always set according to section 5.4.3.1 in GSM 07.10.
va009039 0:1ed23ab1345f 466 // This applies independently of what is contained wthin the UIH frames, either data or control messages."
va009039 0:1ed23ab1345f 467 // - c/r = 1 for frames by initiating station, 0 = for frames by responding station
va009039 0:1ed23ab1345f 468
va009039 0:1ed23ab1345f 469 // C/R Flag in Message
va009039 0:1ed23ab1345f 470 // "In the message level, the C/R bit in the command type field is set as stated in section 5.4.6.2 in GSM 07.10."
va009039 0:1ed23ab1345f 471 // - If the C/R bit is set to 1 the message is a command
va009039 0:1ed23ab1345f 472 // - if it is set to 0 the message is a response.
va009039 0:1ed23ab1345f 473
va009039 0:1ed23ab1345f 474 // temp/old messge construction
va009039 0:1ed23ab1345f 475
va009039 0:1ed23ab1345f 476 // new object oriented version
va009039 0:1ed23ab1345f 477 static int rfcomm_send_sabm(rfcomm_multiplexer_t *multiplexer, uint8_t dlci){
va009039 0:1ed23ab1345f 478 uint8_t address = (1 << 0) | (multiplexer->outgoing << 1) | (dlci << 2); // command
va009039 0:1ed23ab1345f 479 return rfcomm_send_packet_for_multiplexer(multiplexer, address, BT_RFCOMM_SABM, 0, NULL, 0);
va009039 0:1ed23ab1345f 480 }
va009039 0:1ed23ab1345f 481
va009039 0:1ed23ab1345f 482 static int rfcomm_send_disc(rfcomm_multiplexer_t *multiplexer, uint8_t dlci){
va009039 0:1ed23ab1345f 483 uint8_t address = (1 << 0) | (multiplexer->outgoing << 1) | (dlci << 2); // command
va009039 0:1ed23ab1345f 484 return rfcomm_send_packet_for_multiplexer(multiplexer, address, BT_RFCOMM_DISC, 0, NULL, 0);
va009039 0:1ed23ab1345f 485 }
va009039 0:1ed23ab1345f 486
va009039 0:1ed23ab1345f 487 static int rfcomm_send_ua(rfcomm_multiplexer_t *multiplexer, uint8_t dlci){
va009039 0:1ed23ab1345f 488 uint8_t address = (1 << 0) | ((multiplexer->outgoing ^ 1) << 1) | (dlci << 2); // response
va009039 0:1ed23ab1345f 489 return rfcomm_send_packet_for_multiplexer(multiplexer, address, BT_RFCOMM_UA, 0, NULL, 0);
va009039 0:1ed23ab1345f 490 }
va009039 0:1ed23ab1345f 491
va009039 0:1ed23ab1345f 492 static int rfcomm_send_dm_pf(rfcomm_multiplexer_t *multiplexer, uint8_t dlci){
va009039 0:1ed23ab1345f 493 uint8_t address = (1 << 0) | ((multiplexer->outgoing ^ 1) << 1) | (dlci << 2); // response
va009039 0:1ed23ab1345f 494 return rfcomm_send_packet_for_multiplexer(multiplexer, address, BT_RFCOMM_DM_PF, 0, NULL, 0);
va009039 0:1ed23ab1345f 495 }
va009039 0:1ed23ab1345f 496
va009039 0:1ed23ab1345f 497 static int rfcomm_send_uih_msc_cmd(rfcomm_multiplexer_t *multiplexer, uint8_t dlci, uint8_t signals) {
va009039 0:1ed23ab1345f 498 uint8_t address = (1 << 0) | (multiplexer->outgoing << 1);
va009039 0:1ed23ab1345f 499 uint8_t payload[4];
va009039 0:1ed23ab1345f 500 uint8_t pos = 0;
va009039 0:1ed23ab1345f 501 payload[pos++] = BT_RFCOMM_MSC_CMD;
va009039 0:1ed23ab1345f 502 payload[pos++] = 2 << 1 | 1; // len
va009039 0:1ed23ab1345f 503 payload[pos++] = (1 << 0) | (1 << 1) | (dlci << 2); // CMD => C/R = 1
va009039 0:1ed23ab1345f 504 payload[pos++] = signals;
va009039 0:1ed23ab1345f 505 return rfcomm_send_packet_for_multiplexer(multiplexer, address, BT_RFCOMM_UIH, 0, (uint8_t *) payload, pos);
va009039 0:1ed23ab1345f 506 }
va009039 0:1ed23ab1345f 507
va009039 0:1ed23ab1345f 508 static int rfcomm_send_uih_msc_rsp(rfcomm_multiplexer_t *multiplexer, uint8_t dlci, uint8_t signals) {
va009039 0:1ed23ab1345f 509 uint8_t address = (1 << 0) | (multiplexer->outgoing<< 1);
va009039 0:1ed23ab1345f 510 uint8_t payload[4];
va009039 0:1ed23ab1345f 511 uint8_t pos = 0;
va009039 0:1ed23ab1345f 512 payload[pos++] = BT_RFCOMM_MSC_RSP;
va009039 0:1ed23ab1345f 513 payload[pos++] = 2 << 1 | 1; // len
va009039 0:1ed23ab1345f 514 payload[pos++] = (1 << 0) | (1 << 1) | (dlci << 2); // CMD => C/R = 1
va009039 0:1ed23ab1345f 515 payload[pos++] = signals;
va009039 0:1ed23ab1345f 516 return rfcomm_send_packet_for_multiplexer(multiplexer, address, BT_RFCOMM_UIH, 0, (uint8_t *) payload, pos);
va009039 0:1ed23ab1345f 517 }
va009039 0:1ed23ab1345f 518
va009039 0:1ed23ab1345f 519 static int rfcomm_send_uih_pn_command(rfcomm_multiplexer_t *multiplexer, uint8_t dlci, uint16_t max_frame_size){
va009039 0:1ed23ab1345f 520 uint8_t payload[10];
va009039 0:1ed23ab1345f 521 uint8_t address = (1 << 0) | (multiplexer->outgoing << 1);
va009039 0:1ed23ab1345f 522 uint8_t pos = 0;
va009039 0:1ed23ab1345f 523 payload[pos++] = BT_RFCOMM_PN_CMD;
va009039 0:1ed23ab1345f 524 payload[pos++] = 8 << 1 | 1; // len
va009039 0:1ed23ab1345f 525 payload[pos++] = dlci;
va009039 0:1ed23ab1345f 526 payload[pos++] = 0xf0; // pre-defined for Bluetooth, see 5.5.3 of TS 07.10 Adaption for RFCOMM
va009039 0:1ed23ab1345f 527 payload[pos++] = 0; // priority
va009039 0:1ed23ab1345f 528 payload[pos++] = 0; // max 60 seconds ack
va009039 0:1ed23ab1345f 529 payload[pos++] = max_frame_size & 0xff; // max framesize low
va009039 0:1ed23ab1345f 530 payload[pos++] = max_frame_size >> 8; // max framesize high
va009039 0:1ed23ab1345f 531 payload[pos++] = 0x00; // number of retransmissions
va009039 0:1ed23ab1345f 532 payload[pos++] = 0x00; // (unused error recovery window) initial number of credits
va009039 0:1ed23ab1345f 533 return rfcomm_send_packet_for_multiplexer(multiplexer, address, BT_RFCOMM_UIH, 0, (uint8_t *) payload, pos);
va009039 0:1ed23ab1345f 534 }
va009039 0:1ed23ab1345f 535
va009039 0:1ed23ab1345f 536 // "The response may not change the DLCI, the priority, the convergence layer, or the timer value." RFCOMM-tutorial.pdf
va009039 0:1ed23ab1345f 537 static int rfcomm_send_uih_pn_response(rfcomm_multiplexer_t *multiplexer, uint8_t dlci,
va009039 0:1ed23ab1345f 538 uint8_t priority, uint16_t max_frame_size){
va009039 0:1ed23ab1345f 539 uint8_t payload[10];
va009039 0:1ed23ab1345f 540 uint8_t address = (1 << 0) | (multiplexer->outgoing << 1);
va009039 0:1ed23ab1345f 541 uint8_t pos = 0;
va009039 0:1ed23ab1345f 542 payload[pos++] = BT_RFCOMM_PN_RSP;
va009039 0:1ed23ab1345f 543 payload[pos++] = 8 << 1 | 1; // len
va009039 0:1ed23ab1345f 544 payload[pos++] = dlci;
va009039 0:1ed23ab1345f 545 payload[pos++] = 0xe0; // pre defined for Bluetooth, see 5.5.3 of TS 07.10 Adaption for RFCOMM
va009039 0:1ed23ab1345f 546 payload[pos++] = priority; // priority
va009039 0:1ed23ab1345f 547 payload[pos++] = 0; // max 60 seconds ack
va009039 0:1ed23ab1345f 548 payload[pos++] = max_frame_size & 0xff; // max framesize low
va009039 0:1ed23ab1345f 549 payload[pos++] = max_frame_size >> 8; // max framesize high
va009039 0:1ed23ab1345f 550 payload[pos++] = 0x00; // number of retransmissions
va009039 0:1ed23ab1345f 551 payload[pos++] = 0x00; // (unused error recovery window) initial number of credits
va009039 0:1ed23ab1345f 552 return rfcomm_send_packet_for_multiplexer(multiplexer, address, BT_RFCOMM_UIH, 0, (uint8_t *) payload, pos);
va009039 0:1ed23ab1345f 553 }
va009039 0:1ed23ab1345f 554
va009039 0:1ed23ab1345f 555 static int rfcomm_send_uih_rpn_rsp(rfcomm_multiplexer_t *multiplexer, uint8_t dlci, rfcomm_rpn_data_t *rpn_data) {
va009039 0:1ed23ab1345f 556 uint8_t payload[10];
va009039 0:1ed23ab1345f 557 uint8_t address = (1 << 0) | (multiplexer->outgoing << 1);
va009039 0:1ed23ab1345f 558 uint8_t pos = 0;
va009039 0:1ed23ab1345f 559 payload[pos++] = BT_RFCOMM_RPN_RSP;
va009039 0:1ed23ab1345f 560 payload[pos++] = 8 << 1 | 1; // len
va009039 0:1ed23ab1345f 561 payload[pos++] = (1 << 0) | (1 << 1) | (dlci << 2); // CMD => C/R = 1
va009039 0:1ed23ab1345f 562 payload[pos++] = rpn_data->baud_rate;
va009039 0:1ed23ab1345f 563 payload[pos++] = rpn_data->flags;
va009039 0:1ed23ab1345f 564 payload[pos++] = rpn_data->flow_control;
va009039 0:1ed23ab1345f 565 payload[pos++] = rpn_data->xon;
va009039 0:1ed23ab1345f 566 payload[pos++] = rpn_data->xoff;
va009039 0:1ed23ab1345f 567 payload[pos++] = rpn_data->parameter_mask_0;
va009039 0:1ed23ab1345f 568 payload[pos++] = rpn_data->parameter_mask_1;
va009039 0:1ed23ab1345f 569 return rfcomm_send_packet_for_multiplexer(multiplexer, address, BT_RFCOMM_UIH, 0, (uint8_t *) payload, pos);
va009039 0:1ed23ab1345f 570 }
va009039 0:1ed23ab1345f 571
va009039 0:1ed23ab1345f 572 static int rfcomm_send_uih_data(rfcomm_multiplexer_t *multiplexer, uint8_t dlci, uint8_t *data, uint16_t len){
va009039 0:1ed23ab1345f 573 uint8_t address = (1 << 0) | (multiplexer->outgoing << 1) | (dlci << 2);
va009039 0:1ed23ab1345f 574 return rfcomm_send_packet_for_multiplexer(multiplexer, address, BT_RFCOMM_UIH, 0, data, len);
va009039 0:1ed23ab1345f 575 }
va009039 0:1ed23ab1345f 576
va009039 0:1ed23ab1345f 577 static void rfcomm_send_uih_credits(rfcomm_multiplexer_t *multiplexer, uint8_t dlci, uint8_t credits){
va009039 0:1ed23ab1345f 578 uint8_t address = (1 << 0) | (multiplexer->outgoing << 1) | (dlci << 2);
va009039 0:1ed23ab1345f 579 rfcomm_send_packet_for_multiplexer(multiplexer, address, BT_RFCOMM_UIH_PF, credits, NULL, 0);
va009039 0:1ed23ab1345f 580 }
va009039 0:1ed23ab1345f 581
va009039 0:1ed23ab1345f 582 // MARK: RFCOMM MULTIPLEXER
va009039 0:1ed23ab1345f 583
va009039 0:1ed23ab1345f 584 static void rfcomm_multiplexer_finalize(rfcomm_multiplexer_t * multiplexer){
va009039 0:1ed23ab1345f 585
va009039 0:1ed23ab1345f 586 // remove (potential) timer
va009039 0:1ed23ab1345f 587 if (multiplexer->timer_active) {
va009039 0:1ed23ab1345f 588 run_loop_remove_timer(&multiplexer->timer);
va009039 0:1ed23ab1345f 589 multiplexer->timer_active = 0;
va009039 0:1ed23ab1345f 590 }
va009039 0:1ed23ab1345f 591
va009039 0:1ed23ab1345f 592 // close and remove all channels
va009039 0:1ed23ab1345f 593 linked_item_t *it = (linked_item_t *) &rfcomm_channels;
va009039 0:1ed23ab1345f 594 while (it->next){
va009039 0:1ed23ab1345f 595 rfcomm_channel_t * channel = (rfcomm_channel_t *) it->next;
va009039 0:1ed23ab1345f 596 if (channel->multiplexer == multiplexer) {
va009039 0:1ed23ab1345f 597 // emit appropriate events
va009039 0:1ed23ab1345f 598 if (channel->state == RFCOMM_CHANNEL_OPEN) {
va009039 0:1ed23ab1345f 599 rfcomm_emit_channel_closed(channel);
va009039 0:1ed23ab1345f 600 } else {
va009039 0:1ed23ab1345f 601 rfcomm_emit_channel_opened(channel, RFCOMM_MULTIPLEXER_STOPPED);
va009039 0:1ed23ab1345f 602 }
va009039 0:1ed23ab1345f 603 // remove from list
va009039 0:1ed23ab1345f 604 it->next = it->next->next;
va009039 0:1ed23ab1345f 605 // free channel struct
va009039 0:1ed23ab1345f 606 btstack_memory_rfcomm_channel_free(channel);
va009039 0:1ed23ab1345f 607 } else {
va009039 0:1ed23ab1345f 608 it = it->next;
va009039 0:1ed23ab1345f 609 }
va009039 0:1ed23ab1345f 610 }
va009039 0:1ed23ab1345f 611
va009039 0:1ed23ab1345f 612 // keep reference to l2cap channel
va009039 0:1ed23ab1345f 613 uint16_t l2cap_cid = multiplexer->l2cap_cid;
va009039 0:1ed23ab1345f 614
va009039 0:1ed23ab1345f 615 // remove mutliplexer
va009039 0:1ed23ab1345f 616 linked_list_remove( &rfcomm_multiplexers, (linked_item_t *) multiplexer);
va009039 0:1ed23ab1345f 617 btstack_memory_rfcomm_multiplexer_free(multiplexer);
va009039 0:1ed23ab1345f 618
va009039 0:1ed23ab1345f 619 // close l2cap multiplexer channel, too
va009039 0:1ed23ab1345f 620 l2cap_disconnect_internal(l2cap_cid, 0x13);
va009039 0:1ed23ab1345f 621 }
va009039 0:1ed23ab1345f 622
va009039 0:1ed23ab1345f 623 static void rfcomm_multiplexer_timer_handler(timer_source_t *timer){
va009039 0:1ed23ab1345f 624 rfcomm_multiplexer_t * multiplexer = (rfcomm_multiplexer_t *) linked_item_get_user( (linked_item_t *) timer);
va009039 0:1ed23ab1345f 625 if (!rfcomm_multiplexer_has_channels(multiplexer)){
va009039 0:1ed23ab1345f 626 log_info( "rfcomm_multiplexer_timer_handler timeout: shutting down multiplexer!\n");
va009039 0:1ed23ab1345f 627 rfcomm_multiplexer_finalize(multiplexer);
va009039 0:1ed23ab1345f 628 }
va009039 0:1ed23ab1345f 629 }
va009039 0:1ed23ab1345f 630
va009039 0:1ed23ab1345f 631 static void rfcomm_multiplexer_prepare_idle_timer(rfcomm_multiplexer_t * multiplexer){
va009039 0:1ed23ab1345f 632 if (multiplexer->timer_active) {
va009039 0:1ed23ab1345f 633 run_loop_remove_timer(&multiplexer->timer);
va009039 0:1ed23ab1345f 634 multiplexer->timer_active = 0;
va009039 0:1ed23ab1345f 635 }
va009039 0:1ed23ab1345f 636 if (!rfcomm_multiplexer_has_channels(multiplexer)){
va009039 0:1ed23ab1345f 637 // start timer for multiplexer timeout check
va009039 0:1ed23ab1345f 638 run_loop_set_timer(&multiplexer->timer, RFCOMM_MULIPLEXER_TIMEOUT_MS);
va009039 0:1ed23ab1345f 639 multiplexer->timer.process = rfcomm_multiplexer_timer_handler;
va009039 0:1ed23ab1345f 640 linked_item_set_user((linked_item_t*) &multiplexer->timer, multiplexer);
va009039 0:1ed23ab1345f 641 run_loop_add_timer(&multiplexer->timer);
va009039 0:1ed23ab1345f 642 multiplexer->timer_active = 1;
va009039 0:1ed23ab1345f 643 }
va009039 0:1ed23ab1345f 644 }
va009039 0:1ed23ab1345f 645
va009039 0:1ed23ab1345f 646 static void rfcomm_multiplexer_opened(rfcomm_multiplexer_t *multiplexer){
va009039 0:1ed23ab1345f 647 log_info("Multiplexer up and running\n");
va009039 0:1ed23ab1345f 648 multiplexer->state = RFCOMM_MULTIPLEXER_OPEN;
va009039 0:1ed23ab1345f 649
va009039 0:1ed23ab1345f 650 rfcomm_channel_event_t event = { CH_EVT_MULTIPLEXER_READY };
va009039 0:1ed23ab1345f 651
va009039 0:1ed23ab1345f 652 // transition of channels that wait for multiplexer
va009039 0:1ed23ab1345f 653 linked_item_t *it;
va009039 0:1ed23ab1345f 654 for (it = (linked_item_t *) rfcomm_channels; it ; it = it->next){
va009039 0:1ed23ab1345f 655 rfcomm_channel_t * channel = ((rfcomm_channel_t *) it);
va009039 0:1ed23ab1345f 656 if (channel->multiplexer != multiplexer) continue;
va009039 0:1ed23ab1345f 657 rfcomm_channel_state_machine(channel, &event);
va009039 0:1ed23ab1345f 658 }
va009039 0:1ed23ab1345f 659
va009039 0:1ed23ab1345f 660 rfcomm_run();
va009039 0:1ed23ab1345f 661 rfcomm_multiplexer_prepare_idle_timer(multiplexer);
va009039 0:1ed23ab1345f 662 }
va009039 0:1ed23ab1345f 663
va009039 0:1ed23ab1345f 664
va009039 0:1ed23ab1345f 665 /**
va009039 0:1ed23ab1345f 666 * @return handled packet
va009039 0:1ed23ab1345f 667 */
va009039 0:1ed23ab1345f 668 static int rfcomm_multiplexer_hci_event_handler(uint8_t *packet, uint16_t size){
va009039 0:1ed23ab1345f 669 bd_addr_t event_addr;
va009039 0:1ed23ab1345f 670 uint16_t psm;
va009039 0:1ed23ab1345f 671 uint16_t l2cap_cid;
va009039 0:1ed23ab1345f 672 hci_con_handle_t con_handle;
va009039 0:1ed23ab1345f 673 rfcomm_multiplexer_t *multiplexer = NULL;
va009039 0:1ed23ab1345f 674 switch (packet[0]) {
va009039 0:1ed23ab1345f 675
va009039 0:1ed23ab1345f 676 // accept incoming PSM_RFCOMM connection if no multiplexer exists yet
va009039 0:1ed23ab1345f 677 case L2CAP_EVENT_INCOMING_CONNECTION:
va009039 0:1ed23ab1345f 678 // data: event(8), len(8), address(48), handle (16), psm (16), source cid(16) dest cid(16)
va009039 0:1ed23ab1345f 679 bt_flip_addr(event_addr, &packet[2]);
va009039 0:1ed23ab1345f 680 con_handle = READ_BT_16(packet, 8);
va009039 0:1ed23ab1345f 681 psm = READ_BT_16(packet, 10);
va009039 0:1ed23ab1345f 682 l2cap_cid = READ_BT_16(packet, 12);
va009039 0:1ed23ab1345f 683
va009039 0:1ed23ab1345f 684 if (psm != PSM_RFCOMM) break;
va009039 0:1ed23ab1345f 685
va009039 0:1ed23ab1345f 686 multiplexer = rfcomm_multiplexer_for_addr(&event_addr);
va009039 0:1ed23ab1345f 687
va009039 0:1ed23ab1345f 688 if (multiplexer) {
va009039 0:1ed23ab1345f 689 log_info("INCOMING_CONNECTION (l2cap_cid 0x%02x) for PSM_RFCOMM => decline - multiplexer already exists", l2cap_cid);
va009039 0:1ed23ab1345f 690 l2cap_decline_connection_internal(l2cap_cid, 0x04); // no resources available
va009039 0:1ed23ab1345f 691 return 1;
va009039 0:1ed23ab1345f 692 }
va009039 0:1ed23ab1345f 693
va009039 0:1ed23ab1345f 694 // create and inititialize new multiplexer instance (incoming)
va009039 0:1ed23ab1345f 695 multiplexer = rfcomm_multiplexer_create_for_addr(&event_addr);
va009039 0:1ed23ab1345f 696 if (!multiplexer){
va009039 0:1ed23ab1345f 697 log_info("INCOMING_CONNECTION (l2cap_cid 0x%02x) for PSM_RFCOMM => decline - no memory left", l2cap_cid);
va009039 0:1ed23ab1345f 698 l2cap_decline_connection_internal(l2cap_cid, 0x04); // no resources available
va009039 0:1ed23ab1345f 699 return 1;
va009039 0:1ed23ab1345f 700 }
va009039 0:1ed23ab1345f 701
va009039 0:1ed23ab1345f 702 multiplexer->con_handle = con_handle;
va009039 0:1ed23ab1345f 703 multiplexer->l2cap_cid = l2cap_cid;
va009039 0:1ed23ab1345f 704 multiplexer->state = RFCOMM_MULTIPLEXER_W4_SABM_0;
va009039 0:1ed23ab1345f 705
va009039 0:1ed23ab1345f 706 log_info("L2CAP_EVENT_INCOMING_CONNECTION (l2cap_cid 0x%02x) for PSM_RFCOMM => accept", l2cap_cid);
va009039 0:1ed23ab1345f 707 l2cap_accept_connection_internal(l2cap_cid);
va009039 0:1ed23ab1345f 708 return 1;
va009039 0:1ed23ab1345f 709
va009039 0:1ed23ab1345f 710 // l2cap connection opened -> store l2cap_cid, remote_addr
va009039 0:1ed23ab1345f 711 case L2CAP_EVENT_CHANNEL_OPENED:
va009039 0:1ed23ab1345f 712 if (READ_BT_16(packet, 11) != PSM_RFCOMM) break;
va009039 0:1ed23ab1345f 713 log_info("L2CAP_EVENT_CHANNEL_OPENED for PSM_RFCOMM\n");
va009039 0:1ed23ab1345f 714 // get multiplexer for remote addr
va009039 0:1ed23ab1345f 715 con_handle = READ_BT_16(packet, 9);
va009039 0:1ed23ab1345f 716 l2cap_cid = READ_BT_16(packet, 13);
va009039 0:1ed23ab1345f 717 bt_flip_addr(event_addr, &packet[3]);
va009039 0:1ed23ab1345f 718 multiplexer = rfcomm_multiplexer_for_addr(&event_addr);
va009039 0:1ed23ab1345f 719 if (!multiplexer) {
va009039 0:1ed23ab1345f 720 log_error("L2CAP_EVENT_CHANNEL_OPENED but no multiplexer prepared\n");
va009039 0:1ed23ab1345f 721 return 1;
va009039 0:1ed23ab1345f 722 }
va009039 0:1ed23ab1345f 723 if (multiplexer->state == RFCOMM_MULTIPLEXER_W4_CONNECT) {
va009039 0:1ed23ab1345f 724 log_info("L2CAP_EVENT_CHANNEL_OPENED: outgoing connection\n");
va009039 0:1ed23ab1345f 725 // wrong remote addr
va009039 0:1ed23ab1345f 726 if (BD_ADDR_CMP(event_addr, multiplexer->remote_addr)) break;
va009039 0:1ed23ab1345f 727 multiplexer->l2cap_cid = l2cap_cid;
va009039 0:1ed23ab1345f 728 multiplexer->con_handle = con_handle;
va009039 0:1ed23ab1345f 729 // send SABM #0
va009039 0:1ed23ab1345f 730 multiplexer->state = RFCOMM_MULTIPLEXER_SEND_SABM_0;
va009039 0:1ed23ab1345f 731 } else { // multiplexer->state == RFCOMM_MULTIPLEXER_W4_SABM_0
va009039 0:1ed23ab1345f 732
va009039 0:1ed23ab1345f 733 // set max frame size based on l2cap MTU
va009039 0:1ed23ab1345f 734 multiplexer->max_frame_size = rfcomm_max_frame_size_for_l2cap_mtu(READ_BT_16(packet, 17));
va009039 0:1ed23ab1345f 735 }
va009039 0:1ed23ab1345f 736 return 1;
va009039 0:1ed23ab1345f 737
va009039 0:1ed23ab1345f 738 // l2cap disconnect -> state = RFCOMM_MULTIPLEXER_CLOSED;
va009039 0:1ed23ab1345f 739
va009039 0:1ed23ab1345f 740 case L2CAP_EVENT_CREDITS:
va009039 0:1ed23ab1345f 741 // data: event(8), len(8), local_cid(16), credits(8)
va009039 0:1ed23ab1345f 742 l2cap_cid = READ_BT_16(packet, 2);
va009039 0:1ed23ab1345f 743 multiplexer = rfcomm_multiplexer_for_l2cap_cid(l2cap_cid);
va009039 0:1ed23ab1345f 744 if (!multiplexer) break;
va009039 0:1ed23ab1345f 745 multiplexer->l2cap_credits += packet[4];
va009039 0:1ed23ab1345f 746
va009039 0:1ed23ab1345f 747 // log_info("L2CAP_EVENT_CREDITS: %u (now %u)\n", packet[4], multiplexer->l2cap_credits);
va009039 0:1ed23ab1345f 748
va009039 0:1ed23ab1345f 749 // new credits, continue with signaling
va009039 0:1ed23ab1345f 750 rfcomm_run();
va009039 0:1ed23ab1345f 751
va009039 0:1ed23ab1345f 752 if (multiplexer->state != RFCOMM_MULTIPLEXER_OPEN) break;
va009039 0:1ed23ab1345f 753 rfcomm_hand_out_credits();
va009039 0:1ed23ab1345f 754 return 1;
va009039 0:1ed23ab1345f 755
va009039 0:1ed23ab1345f 756 case DAEMON_EVENT_HCI_PACKET_SENT:
va009039 0:1ed23ab1345f 757 // testing DMA done code
va009039 0:1ed23ab1345f 758 rfcomm_run();
va009039 0:1ed23ab1345f 759 break;
va009039 0:1ed23ab1345f 760
va009039 0:1ed23ab1345f 761 case L2CAP_EVENT_CHANNEL_CLOSED:
va009039 0:1ed23ab1345f 762 // data: event (8), len(8), channel (16)
va009039 0:1ed23ab1345f 763 l2cap_cid = READ_BT_16(packet, 2);
va009039 0:1ed23ab1345f 764 multiplexer = rfcomm_multiplexer_for_l2cap_cid(l2cap_cid);
va009039 0:1ed23ab1345f 765 if (!multiplexer) break;
va009039 0:1ed23ab1345f 766 switch (multiplexer->state) {
va009039 0:1ed23ab1345f 767 case RFCOMM_MULTIPLEXER_W4_SABM_0:
va009039 0:1ed23ab1345f 768 case RFCOMM_MULTIPLEXER_W4_UA_0:
va009039 0:1ed23ab1345f 769 case RFCOMM_MULTIPLEXER_OPEN:
va009039 0:1ed23ab1345f 770 rfcomm_multiplexer_finalize(multiplexer);
va009039 0:1ed23ab1345f 771 return 1;
va009039 0:1ed23ab1345f 772 default:
va009039 0:1ed23ab1345f 773 break;
va009039 0:1ed23ab1345f 774 }
va009039 0:1ed23ab1345f 775 break;
va009039 0:1ed23ab1345f 776 default:
va009039 0:1ed23ab1345f 777 break;
va009039 0:1ed23ab1345f 778 }
va009039 0:1ed23ab1345f 779 return 0;
va009039 0:1ed23ab1345f 780 }
va009039 0:1ed23ab1345f 781
va009039 0:1ed23ab1345f 782 static int rfcomm_multiplexer_l2cap_packet_handler(uint16_t channel, uint8_t *packet, uint16_t size){
va009039 0:1ed23ab1345f 783
va009039 0:1ed23ab1345f 784 // get or create a multiplexer for a certain device
va009039 0:1ed23ab1345f 785 rfcomm_multiplexer_t *multiplexer = rfcomm_multiplexer_for_l2cap_cid(channel);
va009039 0:1ed23ab1345f 786 if (!multiplexer) return 0;
va009039 0:1ed23ab1345f 787
va009039 0:1ed23ab1345f 788 // but only care for multiplexer control channel
va009039 0:1ed23ab1345f 789 uint8_t frame_dlci = packet[0] >> 2;
va009039 0:1ed23ab1345f 790 if (frame_dlci) return 0;
va009039 0:1ed23ab1345f 791 const uint8_t length_offset = (packet[2] & 1) ^ 1; // to be used for pos >= 3
va009039 0:1ed23ab1345f 792 const uint8_t credit_offset = ((packet[1] & BT_RFCOMM_UIH_PF) == BT_RFCOMM_UIH_PF) ? 1 : 0; // credits for uih_pf frames
va009039 0:1ed23ab1345f 793 const uint8_t payload_offset = 3 + length_offset + credit_offset;
va009039 0:1ed23ab1345f 794 switch (packet[1]){
va009039 0:1ed23ab1345f 795
va009039 0:1ed23ab1345f 796 case BT_RFCOMM_SABM:
va009039 0:1ed23ab1345f 797 if (multiplexer->state == RFCOMM_MULTIPLEXER_W4_SABM_0){
va009039 0:1ed23ab1345f 798 log_info("Received SABM #0\n");
va009039 0:1ed23ab1345f 799 multiplexer->outgoing = 0;
va009039 0:1ed23ab1345f 800 multiplexer->state = RFCOMM_MULTIPLEXER_SEND_UA_0;
va009039 0:1ed23ab1345f 801 return 1;
va009039 0:1ed23ab1345f 802 }
va009039 0:1ed23ab1345f 803 break;
va009039 0:1ed23ab1345f 804
va009039 0:1ed23ab1345f 805 case BT_RFCOMM_UA:
va009039 0:1ed23ab1345f 806 if (multiplexer->state == RFCOMM_MULTIPLEXER_W4_UA_0) {
va009039 0:1ed23ab1345f 807 // UA #0 -> send UA #0, state = RFCOMM_MULTIPLEXER_OPEN
va009039 0:1ed23ab1345f 808 log_info("Received UA #0 \n");
va009039 0:1ed23ab1345f 809 rfcomm_multiplexer_opened(multiplexer);
va009039 0:1ed23ab1345f 810 return 1;
va009039 0:1ed23ab1345f 811 }
va009039 0:1ed23ab1345f 812 break;
va009039 0:1ed23ab1345f 813
va009039 0:1ed23ab1345f 814 case BT_RFCOMM_DISC:
va009039 0:1ed23ab1345f 815 // DISC #0 -> send UA #0, close multiplexer
va009039 0:1ed23ab1345f 816 log_info("Received DISC #0, (ougoing = %u)\n", multiplexer->outgoing);
va009039 0:1ed23ab1345f 817 multiplexer->state = RFCOMM_MULTIPLEXER_SEND_UA_0_AND_DISC;
va009039 0:1ed23ab1345f 818 return 1;
va009039 0:1ed23ab1345f 819
va009039 0:1ed23ab1345f 820 case BT_RFCOMM_DM:
va009039 0:1ed23ab1345f 821 // DM #0 - we shouldn't get this, just give up
va009039 0:1ed23ab1345f 822 log_info("Received DM #0\n");
va009039 0:1ed23ab1345f 823 log_info("-> Closing down multiplexer\n");
va009039 0:1ed23ab1345f 824 rfcomm_multiplexer_finalize(multiplexer);
va009039 0:1ed23ab1345f 825 return 1;
va009039 0:1ed23ab1345f 826
va009039 0:1ed23ab1345f 827 case BT_RFCOMM_UIH:
va009039 0:1ed23ab1345f 828 if (packet[payload_offset] == BT_RFCOMM_CLD_CMD){
va009039 0:1ed23ab1345f 829 // Multiplexer close down (CLD) -> close mutliplexer
va009039 0:1ed23ab1345f 830 log_info("Received Multiplexer close down command\n");
va009039 0:1ed23ab1345f 831 log_info("-> Closing down multiplexer\n");
va009039 0:1ed23ab1345f 832 rfcomm_multiplexer_finalize(multiplexer);
va009039 0:1ed23ab1345f 833 return 1;
va009039 0:1ed23ab1345f 834 }
va009039 0:1ed23ab1345f 835 break;
va009039 0:1ed23ab1345f 836
va009039 0:1ed23ab1345f 837 default:
va009039 0:1ed23ab1345f 838 break;
va009039 0:1ed23ab1345f 839
va009039 0:1ed23ab1345f 840 }
va009039 0:1ed23ab1345f 841 return 0;
va009039 0:1ed23ab1345f 842 }
va009039 0:1ed23ab1345f 843
va009039 0:1ed23ab1345f 844 static void rfcomm_multiplexer_state_machine(rfcomm_multiplexer_t * multiplexer, RFCOMM_MULTIPLEXER_EVENT event){
va009039 0:1ed23ab1345f 845
va009039 0:1ed23ab1345f 846 // process stored DM responses
va009039 0:1ed23ab1345f 847 if (multiplexer->send_dm_for_dlci){
va009039 0:1ed23ab1345f 848 rfcomm_send_dm_pf(multiplexer, multiplexer->send_dm_for_dlci);
va009039 0:1ed23ab1345f 849 multiplexer->send_dm_for_dlci = 0;
va009039 0:1ed23ab1345f 850 }
va009039 0:1ed23ab1345f 851
va009039 0:1ed23ab1345f 852 switch (multiplexer->state) {
va009039 0:1ed23ab1345f 853 case RFCOMM_MULTIPLEXER_SEND_SABM_0:
va009039 0:1ed23ab1345f 854 switch (event) {
va009039 0:1ed23ab1345f 855 case MULT_EV_READY_TO_SEND:
va009039 0:1ed23ab1345f 856 log_info("Sending SABM #0 - (multi 0x%p)\n", multiplexer);
va009039 0:1ed23ab1345f 857 multiplexer->state = RFCOMM_MULTIPLEXER_W4_UA_0;
va009039 0:1ed23ab1345f 858 rfcomm_send_sabm(multiplexer, 0);
va009039 0:1ed23ab1345f 859 break;
va009039 0:1ed23ab1345f 860 default:
va009039 0:1ed23ab1345f 861 break;
va009039 0:1ed23ab1345f 862 }
va009039 0:1ed23ab1345f 863 break;
va009039 0:1ed23ab1345f 864 case RFCOMM_MULTIPLEXER_SEND_UA_0:
va009039 0:1ed23ab1345f 865 switch (event) {
va009039 0:1ed23ab1345f 866 case MULT_EV_READY_TO_SEND:
va009039 0:1ed23ab1345f 867 log_info("Sending UA #0\n");
va009039 0:1ed23ab1345f 868 multiplexer->state = RFCOMM_MULTIPLEXER_OPEN;
va009039 0:1ed23ab1345f 869 rfcomm_send_ua(multiplexer, 0);
va009039 0:1ed23ab1345f 870 rfcomm_multiplexer_opened(multiplexer);
va009039 0:1ed23ab1345f 871 break;
va009039 0:1ed23ab1345f 872 default:
va009039 0:1ed23ab1345f 873 break;
va009039 0:1ed23ab1345f 874 }
va009039 0:1ed23ab1345f 875 break;
va009039 0:1ed23ab1345f 876 case RFCOMM_MULTIPLEXER_SEND_UA_0_AND_DISC:
va009039 0:1ed23ab1345f 877 switch (event) {
va009039 0:1ed23ab1345f 878 case MULT_EV_READY_TO_SEND:
va009039 0:1ed23ab1345f 879 log_info("Sending UA #0\n");
va009039 0:1ed23ab1345f 880 log_info("Closing down multiplexer\n");
va009039 0:1ed23ab1345f 881 multiplexer->state = RFCOMM_MULTIPLEXER_CLOSED;
va009039 0:1ed23ab1345f 882 rfcomm_send_ua(multiplexer, 0);
va009039 0:1ed23ab1345f 883 rfcomm_multiplexer_finalize(multiplexer);
va009039 0:1ed23ab1345f 884 // try to detect authentication errors: drop link key if multiplexer closed before first channel got opened
va009039 0:1ed23ab1345f 885 if (!multiplexer->at_least_one_connection){
va009039 0:1ed23ab1345f 886 log_info("TODO: no connections established - delete link key prophylactically\n");
va009039 0:1ed23ab1345f 887 // hci_send_cmd(&hci_delete_stored_link_key, multiplexer->remote_addr);
va009039 0:1ed23ab1345f 888 }
va009039 0:1ed23ab1345f 889 default:
va009039 0:1ed23ab1345f 890 break;
va009039 0:1ed23ab1345f 891 }
va009039 0:1ed23ab1345f 892 break;
va009039 0:1ed23ab1345f 893 default:
va009039 0:1ed23ab1345f 894 break;
va009039 0:1ed23ab1345f 895 }
va009039 0:1ed23ab1345f 896 }
va009039 0:1ed23ab1345f 897
va009039 0:1ed23ab1345f 898 // MARK: RFCOMM CHANNEL
va009039 0:1ed23ab1345f 899
va009039 0:1ed23ab1345f 900 static void rfcomm_hand_out_credits(void){
va009039 0:1ed23ab1345f 901 linked_item_t * it;
va009039 0:1ed23ab1345f 902 for (it = (linked_item_t *) rfcomm_channels; it ; it = it->next){
va009039 0:1ed23ab1345f 903 rfcomm_channel_t * channel = (rfcomm_channel_t *) it;
va009039 0:1ed23ab1345f 904 if (channel->state != RFCOMM_CHANNEL_OPEN) {
va009039 0:1ed23ab1345f 905 // log_info("RFCOMM_EVENT_CREDITS: multiplexer not open\n");
va009039 0:1ed23ab1345f 906 continue;
va009039 0:1ed23ab1345f 907 }
va009039 0:1ed23ab1345f 908 if (channel->packets_granted) {
va009039 0:1ed23ab1345f 909 // log_info("RFCOMM_EVENT_CREDITS: already packets granted\n");
va009039 0:1ed23ab1345f 910 continue;
va009039 0:1ed23ab1345f 911 }
va009039 0:1ed23ab1345f 912 if (!channel->credits_outgoing) {
va009039 0:1ed23ab1345f 913 // log_info("RFCOMM_EVENT_CREDITS: no outgoing credits\n");
va009039 0:1ed23ab1345f 914 continue;
va009039 0:1ed23ab1345f 915 }
va009039 0:1ed23ab1345f 916 if (!channel->multiplexer->l2cap_credits){
va009039 0:1ed23ab1345f 917 // log_info("RFCOMM_EVENT_CREDITS: no l2cap credits\n");
va009039 0:1ed23ab1345f 918 continue;
va009039 0:1ed23ab1345f 919 }
va009039 0:1ed23ab1345f 920 // channel open, multiplexer has l2cap credits and we didn't hand out credit before -> go!
va009039 0:1ed23ab1345f 921 // log_info("RFCOMM_EVENT_CREDITS: 1\n");
va009039 0:1ed23ab1345f 922 channel->packets_granted += 1;
va009039 0:1ed23ab1345f 923 rfcomm_emit_credits(channel, 1);
va009039 0:1ed23ab1345f 924 }
va009039 0:1ed23ab1345f 925 }
va009039 0:1ed23ab1345f 926
va009039 0:1ed23ab1345f 927 static void rfcomm_channel_send_credits(rfcomm_channel_t *channel, uint8_t credits){
va009039 0:1ed23ab1345f 928 rfcomm_send_uih_credits(channel->multiplexer, channel->dlci, credits);
va009039 0:1ed23ab1345f 929 channel->credits_incoming += credits;
va009039 0:1ed23ab1345f 930
va009039 0:1ed23ab1345f 931 rfcomm_emit_credit_status(channel);
va009039 0:1ed23ab1345f 932 }
va009039 0:1ed23ab1345f 933
va009039 0:1ed23ab1345f 934 static void rfcomm_channel_opened(rfcomm_channel_t *rfChannel){
va009039 0:1ed23ab1345f 935
va009039 0:1ed23ab1345f 936 log_info("rfcomm_channel_opened!\n");
va009039 0:1ed23ab1345f 937
va009039 0:1ed23ab1345f 938 rfChannel->state = RFCOMM_CHANNEL_OPEN;
va009039 0:1ed23ab1345f 939 rfcomm_emit_channel_opened(rfChannel, 0);
va009039 0:1ed23ab1345f 940 rfcomm_hand_out_credits();
va009039 0:1ed23ab1345f 941
va009039 0:1ed23ab1345f 942 // remove (potential) timer
va009039 0:1ed23ab1345f 943 rfcomm_multiplexer_t *multiplexer = rfChannel->multiplexer;
va009039 0:1ed23ab1345f 944 if (multiplexer->timer_active) {
va009039 0:1ed23ab1345f 945 run_loop_remove_timer(&multiplexer->timer);
va009039 0:1ed23ab1345f 946 multiplexer->timer_active = 0;
va009039 0:1ed23ab1345f 947 }
va009039 0:1ed23ab1345f 948 // hack for problem detecting authentication failure
va009039 0:1ed23ab1345f 949 multiplexer->at_least_one_connection = 1;
va009039 0:1ed23ab1345f 950
va009039 0:1ed23ab1345f 951 // start next connection request if pending
va009039 0:1ed23ab1345f 952 rfcomm_run();
va009039 0:1ed23ab1345f 953 }
va009039 0:1ed23ab1345f 954
va009039 0:1ed23ab1345f 955 static void rfcomm_channel_packet_handler_uih(rfcomm_multiplexer_t *multiplexer, uint8_t * packet, uint16_t size){
va009039 0:1ed23ab1345f 956 const uint8_t frame_dlci = packet[0] >> 2;
va009039 0:1ed23ab1345f 957 const uint8_t length_offset = (packet[2] & 1) ^ 1; // to be used for pos >= 3
va009039 0:1ed23ab1345f 958 const uint8_t credit_offset = ((packet[1] & BT_RFCOMM_UIH_PF) == BT_RFCOMM_UIH_PF) ? 1 : 0; // credits for uih_pf frames
va009039 0:1ed23ab1345f 959 const uint8_t payload_offset = 3 + length_offset + credit_offset;
va009039 0:1ed23ab1345f 960
va009039 0:1ed23ab1345f 961 rfcomm_channel_t * channel = rfcomm_channel_for_multiplexer_and_dlci(multiplexer, frame_dlci);
va009039 0:1ed23ab1345f 962 if (!channel) return;
va009039 0:1ed23ab1345f 963
va009039 0:1ed23ab1345f 964 // handle new outgoing credits
va009039 0:1ed23ab1345f 965 if (packet[1] == BT_RFCOMM_UIH_PF) {
va009039 0:1ed23ab1345f 966
va009039 0:1ed23ab1345f 967 // add them
va009039 0:1ed23ab1345f 968 uint16_t new_credits = packet[3+length_offset];
va009039 0:1ed23ab1345f 969 channel->credits_outgoing += new_credits;
va009039 0:1ed23ab1345f 970 log_info( "RFCOMM data UIH_PF, new credits: %u, now %u\n", new_credits, channel->credits_outgoing);
va009039 0:1ed23ab1345f 971
va009039 0:1ed23ab1345f 972 // notify channel statemachine
va009039 0:1ed23ab1345f 973 rfcomm_channel_event_t channel_event = { CH_EVT_RCVD_CREDITS };
va009039 0:1ed23ab1345f 974 rfcomm_channel_state_machine(channel, &channel_event);
va009039 0:1ed23ab1345f 975 }
va009039 0:1ed23ab1345f 976
va009039 0:1ed23ab1345f 977 // contains payload?
va009039 0:1ed23ab1345f 978 if (size - 1 > payload_offset){
va009039 0:1ed23ab1345f 979
va009039 0:1ed23ab1345f 980 // log_info( "RFCOMM data UIH_PF, size %u, channel %p\n", size-payload_offset-1, rfChannel->connection);
va009039 0:1ed23ab1345f 981
va009039 0:1ed23ab1345f 982 // decrease incoming credit counter
va009039 0:1ed23ab1345f 983 if (channel->credits_incoming > 0){
va009039 0:1ed23ab1345f 984 channel->credits_incoming--;
va009039 0:1ed23ab1345f 985 }
va009039 0:1ed23ab1345f 986
va009039 0:1ed23ab1345f 987 // deliver payload
va009039 0:1ed23ab1345f 988 (*app_packet_handler)(channel->connection, RFCOMM_DATA_PACKET, channel->rfcomm_cid,
va009039 0:1ed23ab1345f 989 &packet[payload_offset], size-payload_offset-1);
va009039 0:1ed23ab1345f 990 }
va009039 0:1ed23ab1345f 991
va009039 0:1ed23ab1345f 992 // automatically provide new credits to remote device, if no incoming flow control
va009039 0:1ed23ab1345f 993 if (!channel->incoming_flow_control && channel->credits_incoming < 5){
va009039 0:1ed23ab1345f 994 channel->new_credits_incoming = 0x30;
va009039 0:1ed23ab1345f 995 }
va009039 0:1ed23ab1345f 996
va009039 0:1ed23ab1345f 997 rfcomm_emit_credit_status(channel);
va009039 0:1ed23ab1345f 998
va009039 0:1ed23ab1345f 999 // we received new RFCOMM credits, hand them out if possible
va009039 0:1ed23ab1345f 1000 rfcomm_hand_out_credits();
va009039 0:1ed23ab1345f 1001 }
va009039 0:1ed23ab1345f 1002
va009039 0:1ed23ab1345f 1003 static void rfcomm_channel_accept_pn(rfcomm_channel_t *channel, rfcomm_channel_event_pn_t *event){
va009039 0:1ed23ab1345f 1004 // priority of client request
va009039 0:1ed23ab1345f 1005 channel->pn_priority = event->priority;
va009039 0:1ed23ab1345f 1006
va009039 0:1ed23ab1345f 1007 // new credits
va009039 0:1ed23ab1345f 1008 channel->credits_outgoing = event->credits_outgoing;
va009039 0:1ed23ab1345f 1009
va009039 0:1ed23ab1345f 1010 // negotiate max frame size
va009039 0:1ed23ab1345f 1011 if (channel->max_frame_size > channel->multiplexer->max_frame_size) {
va009039 0:1ed23ab1345f 1012 channel->max_frame_size = channel->multiplexer->max_frame_size;
va009039 0:1ed23ab1345f 1013 }
va009039 0:1ed23ab1345f 1014 if (channel->max_frame_size > event->max_frame_size) {
va009039 0:1ed23ab1345f 1015 channel->max_frame_size = event->max_frame_size;
va009039 0:1ed23ab1345f 1016 }
va009039 0:1ed23ab1345f 1017
va009039 0:1ed23ab1345f 1018 }
va009039 0:1ed23ab1345f 1019
va009039 0:1ed23ab1345f 1020 static void rfcomm_channel_finalize(rfcomm_channel_t *channel){
va009039 0:1ed23ab1345f 1021
va009039 0:1ed23ab1345f 1022 rfcomm_multiplexer_t *multiplexer = channel->multiplexer;
va009039 0:1ed23ab1345f 1023
va009039 0:1ed23ab1345f 1024 // remove from list
va009039 0:1ed23ab1345f 1025 linked_list_remove( &rfcomm_channels, (linked_item_t *) channel);
va009039 0:1ed23ab1345f 1026
va009039 0:1ed23ab1345f 1027 // free channel
va009039 0:1ed23ab1345f 1028 btstack_memory_rfcomm_channel_free(channel);
va009039 0:1ed23ab1345f 1029
va009039 0:1ed23ab1345f 1030 // update multiplexer timeout after channel was removed from list
va009039 0:1ed23ab1345f 1031 rfcomm_multiplexer_prepare_idle_timer(multiplexer);
va009039 0:1ed23ab1345f 1032 }
va009039 0:1ed23ab1345f 1033
va009039 0:1ed23ab1345f 1034 static void rfcomm_channel_state_machine_2(rfcomm_multiplexer_t * multiplexer, uint8_t dlci, rfcomm_channel_event_t *event){
va009039 0:1ed23ab1345f 1035
va009039 0:1ed23ab1345f 1036 // TODO: if client max frame size is smaller than RFCOMM_DEFAULT_SIZE, send PN
va009039 0:1ed23ab1345f 1037
va009039 0:1ed23ab1345f 1038
va009039 0:1ed23ab1345f 1039 // lookup existing channel
va009039 0:1ed23ab1345f 1040 rfcomm_channel_t * channel = rfcomm_channel_for_multiplexer_and_dlci(multiplexer, dlci);
va009039 0:1ed23ab1345f 1041
va009039 0:1ed23ab1345f 1042 // log_info("rfcomm_channel_state_machine_2 lookup dlci #%u = 0x%08x - event %u\n", dlci, (int) channel, event->type);
va009039 0:1ed23ab1345f 1043
va009039 0:1ed23ab1345f 1044 if (channel) {
va009039 0:1ed23ab1345f 1045 rfcomm_channel_state_machine(channel, event);
va009039 0:1ed23ab1345f 1046 return;
va009039 0:1ed23ab1345f 1047 }
va009039 0:1ed23ab1345f 1048
va009039 0:1ed23ab1345f 1049 // service registered?
va009039 0:1ed23ab1345f 1050 rfcomm_service_t * service = rfcomm_service_for_channel(dlci >> 1);
va009039 0:1ed23ab1345f 1051 // log_info("rfcomm_channel_state_machine_2 service dlci #%u = 0x%08x\n", dlci, (int) service);
va009039 0:1ed23ab1345f 1052 if (!service) {
va009039 0:1ed23ab1345f 1053 // discard request by sending disconnected mode
va009039 0:1ed23ab1345f 1054 multiplexer->send_dm_for_dlci = dlci;
va009039 0:1ed23ab1345f 1055 return;
va009039 0:1ed23ab1345f 1056 }
va009039 0:1ed23ab1345f 1057
va009039 0:1ed23ab1345f 1058 // create channel for some events
va009039 0:1ed23ab1345f 1059 switch (event->type) {
va009039 0:1ed23ab1345f 1060 case CH_EVT_RCVD_SABM:
va009039 0:1ed23ab1345f 1061 case CH_EVT_RCVD_PN:
va009039 0:1ed23ab1345f 1062 case CH_EVT_RCVD_RPN_REQ:
va009039 0:1ed23ab1345f 1063 case CH_EVT_RCVD_RPN_CMD:
va009039 0:1ed23ab1345f 1064 // setup incoming channel
va009039 0:1ed23ab1345f 1065 channel = rfcomm_channel_create(multiplexer, service, dlci >> 1);
va009039 0:1ed23ab1345f 1066 if (!channel){
va009039 0:1ed23ab1345f 1067 // discard request by sending disconnected mode
va009039 0:1ed23ab1345f 1068 multiplexer->send_dm_for_dlci = dlci;
va009039 0:1ed23ab1345f 1069 }
va009039 0:1ed23ab1345f 1070 break;
va009039 0:1ed23ab1345f 1071 default:
va009039 0:1ed23ab1345f 1072 break;
va009039 0:1ed23ab1345f 1073 }
va009039 0:1ed23ab1345f 1074
va009039 0:1ed23ab1345f 1075 if (!channel) {
va009039 0:1ed23ab1345f 1076 // discard request by sending disconnected mode
va009039 0:1ed23ab1345f 1077 multiplexer->send_dm_for_dlci = dlci;
va009039 0:1ed23ab1345f 1078 return;
va009039 0:1ed23ab1345f 1079 }
va009039 0:1ed23ab1345f 1080 channel->connection = service->connection;
va009039 0:1ed23ab1345f 1081 rfcomm_channel_state_machine(channel, event);
va009039 0:1ed23ab1345f 1082 }
va009039 0:1ed23ab1345f 1083
va009039 0:1ed23ab1345f 1084 void rfcomm_channel_packet_handler(rfcomm_multiplexer_t * multiplexer, uint8_t *packet, uint16_t size){
va009039 0:1ed23ab1345f 1085
va009039 0:1ed23ab1345f 1086 // rfcomm: (0) addr [76543 server channel] [2 direction: initiator uses 1] [1 C/R: CMD by initiator = 1] [0 EA=1]
va009039 0:1ed23ab1345f 1087 const uint8_t frame_dlci = packet[0] >> 2;
va009039 0:1ed23ab1345f 1088 uint8_t message_dlci; // used by commands in UIH(_PF) packets
va009039 0:1ed23ab1345f 1089 uint8_t message_len; // "
va009039 0:1ed23ab1345f 1090
va009039 0:1ed23ab1345f 1091 // rfcomm: (1) command/control
va009039 0:1ed23ab1345f 1092 // -- credits_offset = 1 if command == BT_RFCOMM_UIH_PF
va009039 0:1ed23ab1345f 1093 const uint8_t credit_offset = ((packet[1] & BT_RFCOMM_UIH_PF) == BT_RFCOMM_UIH_PF) ? 1 : 0; // credits for uih_pf frames
va009039 0:1ed23ab1345f 1094 // rfcomm: (2) length. if bit 0 is cleared, 2 byte length is used. (little endian)
va009039 0:1ed23ab1345f 1095 const uint8_t length_offset = (packet[2] & 1) ^ 1; // to be used for pos >= 3
va009039 0:1ed23ab1345f 1096 // rfcomm: (3+length_offset) credits if credits_offset == 1
va009039 0:1ed23ab1345f 1097 // rfcomm: (3+length_offest+credits_offset)
va009039 0:1ed23ab1345f 1098 const uint8_t payload_offset = 3 + length_offset + credit_offset;
va009039 0:1ed23ab1345f 1099
va009039 0:1ed23ab1345f 1100 rfcomm_channel_event_t event;
va009039 0:1ed23ab1345f 1101 rfcomm_channel_event_pn_t event_pn;
va009039 0:1ed23ab1345f 1102 rfcomm_channel_event_rpn_t event_rpn;
va009039 0:1ed23ab1345f 1103
va009039 0:1ed23ab1345f 1104 // switch by rfcomm message type
va009039 0:1ed23ab1345f 1105 switch(packet[1]) {
va009039 0:1ed23ab1345f 1106
va009039 0:1ed23ab1345f 1107 case BT_RFCOMM_SABM:
va009039 0:1ed23ab1345f 1108 event.type = CH_EVT_RCVD_SABM;
va009039 0:1ed23ab1345f 1109 log_info("Received SABM #%u\n", frame_dlci);
va009039 0:1ed23ab1345f 1110 rfcomm_channel_state_machine_2(multiplexer, frame_dlci, &event);
va009039 0:1ed23ab1345f 1111 break;
va009039 0:1ed23ab1345f 1112
va009039 0:1ed23ab1345f 1113 case BT_RFCOMM_UA:
va009039 0:1ed23ab1345f 1114 event.type = CH_EVT_RCVD_UA;
va009039 0:1ed23ab1345f 1115 log_info("Received UA #%u - channel opened\n",frame_dlci);
va009039 0:1ed23ab1345f 1116 rfcomm_channel_state_machine_2(multiplexer, frame_dlci, &event);
va009039 0:1ed23ab1345f 1117 break;
va009039 0:1ed23ab1345f 1118
va009039 0:1ed23ab1345f 1119 case BT_RFCOMM_DISC:
va009039 0:1ed23ab1345f 1120 event.type = CH_EVT_RCVD_DISC;
va009039 0:1ed23ab1345f 1121 rfcomm_channel_state_machine_2(multiplexer, frame_dlci, &event);
va009039 0:1ed23ab1345f 1122 break;
va009039 0:1ed23ab1345f 1123
va009039 0:1ed23ab1345f 1124 case BT_RFCOMM_DM:
va009039 0:1ed23ab1345f 1125 case BT_RFCOMM_DM_PF:
va009039 0:1ed23ab1345f 1126 event.type = CH_EVT_RCVD_DM;
va009039 0:1ed23ab1345f 1127 rfcomm_channel_state_machine_2(multiplexer, frame_dlci, &event);
va009039 0:1ed23ab1345f 1128 break;
va009039 0:1ed23ab1345f 1129
va009039 0:1ed23ab1345f 1130 case BT_RFCOMM_UIH_PF:
va009039 0:1ed23ab1345f 1131 case BT_RFCOMM_UIH:
va009039 0:1ed23ab1345f 1132
va009039 0:1ed23ab1345f 1133 message_len = packet[payload_offset+1] >> 1;
va009039 0:1ed23ab1345f 1134
va009039 0:1ed23ab1345f 1135 switch (packet[payload_offset]) {
va009039 0:1ed23ab1345f 1136 case BT_RFCOMM_PN_CMD:
va009039 0:1ed23ab1345f 1137 message_dlci = packet[payload_offset+2];
va009039 0:1ed23ab1345f 1138 event_pn.super.type = CH_EVT_RCVD_PN;
va009039 0:1ed23ab1345f 1139 event_pn.priority = packet[payload_offset+4];
va009039 0:1ed23ab1345f 1140 event_pn.max_frame_size = READ_BT_16(packet, payload_offset+6);
va009039 0:1ed23ab1345f 1141 event_pn.credits_outgoing = packet[payload_offset+9];
va009039 0:1ed23ab1345f 1142 log_info("Received UIH Parameter Negotiation Command for #%u\n", message_dlci);
va009039 0:1ed23ab1345f 1143 rfcomm_channel_state_machine_2(multiplexer, message_dlci, (rfcomm_channel_event_t*) &event_pn);
va009039 0:1ed23ab1345f 1144 break;
va009039 0:1ed23ab1345f 1145
va009039 0:1ed23ab1345f 1146 case BT_RFCOMM_PN_RSP:
va009039 0:1ed23ab1345f 1147 message_dlci = packet[payload_offset+2];
va009039 0:1ed23ab1345f 1148 event_pn.super.type = CH_EVT_RCVD_PN_RSP;
va009039 0:1ed23ab1345f 1149 event_pn.priority = packet[payload_offset+4];
va009039 0:1ed23ab1345f 1150 event_pn.max_frame_size = READ_BT_16(packet, payload_offset+6);
va009039 0:1ed23ab1345f 1151 event_pn.credits_outgoing = packet[payload_offset+9];
va009039 0:1ed23ab1345f 1152 log_info("UIH Parameter Negotiation Response max frame %u, credits %u\n",
va009039 0:1ed23ab1345f 1153 event_pn.max_frame_size, event_pn.credits_outgoing);
va009039 0:1ed23ab1345f 1154 rfcomm_channel_state_machine_2(multiplexer, message_dlci, (rfcomm_channel_event_t*) &event_pn);
va009039 0:1ed23ab1345f 1155 break;
va009039 0:1ed23ab1345f 1156
va009039 0:1ed23ab1345f 1157 case BT_RFCOMM_MSC_CMD:
va009039 0:1ed23ab1345f 1158 message_dlci = packet[payload_offset+2] >> 2;
va009039 0:1ed23ab1345f 1159 event.type = CH_EVT_RCVD_MSC_CMD;
va009039 0:1ed23ab1345f 1160 log_info("Received MSC CMD for #%u, \n", message_dlci);
va009039 0:1ed23ab1345f 1161 rfcomm_channel_state_machine_2(multiplexer, message_dlci, &event);
va009039 0:1ed23ab1345f 1162 break;
va009039 0:1ed23ab1345f 1163
va009039 0:1ed23ab1345f 1164 case BT_RFCOMM_MSC_RSP:
va009039 0:1ed23ab1345f 1165 message_dlci = packet[payload_offset+2] >> 2;
va009039 0:1ed23ab1345f 1166 event.type = CH_EVT_RCVD_MSC_RSP;
va009039 0:1ed23ab1345f 1167 log_info("Received MSC RSP for #%u\n", message_dlci);
va009039 0:1ed23ab1345f 1168 rfcomm_channel_state_machine_2(multiplexer, message_dlci, &event);
va009039 0:1ed23ab1345f 1169 break;
va009039 0:1ed23ab1345f 1170
va009039 0:1ed23ab1345f 1171 case BT_RFCOMM_RPN_CMD:
va009039 0:1ed23ab1345f 1172 message_dlci = packet[payload_offset+2] >> 2;
va009039 0:1ed23ab1345f 1173 switch (message_len){
va009039 0:1ed23ab1345f 1174 case 1:
va009039 0:1ed23ab1345f 1175 log_info("Received Remote Port Negotiation for #%u\n", message_dlci);
va009039 0:1ed23ab1345f 1176 event.type = CH_EVT_RCVD_RPN_REQ;
va009039 0:1ed23ab1345f 1177 rfcomm_channel_state_machine_2(multiplexer, message_dlci, &event);
va009039 0:1ed23ab1345f 1178 break;
va009039 0:1ed23ab1345f 1179 case 8:
va009039 0:1ed23ab1345f 1180 log_info("Received Remote Port Negotiation (Info) for #%u\n", message_dlci);
va009039 0:1ed23ab1345f 1181 event_rpn.super.type = CH_EVT_RCVD_RPN_CMD;
va009039 0:1ed23ab1345f 1182 event_rpn.data.baud_rate = packet[payload_offset+3];
va009039 0:1ed23ab1345f 1183 event_rpn.data.flags = packet[payload_offset+4];
va009039 0:1ed23ab1345f 1184 event_rpn.data.flow_control = packet[payload_offset+5];
va009039 0:1ed23ab1345f 1185 event_rpn.data.xon = packet[payload_offset+6];
va009039 0:1ed23ab1345f 1186 event_rpn.data.xoff = packet[payload_offset+7];
va009039 0:1ed23ab1345f 1187 event_rpn.data.parameter_mask_0 = packet[payload_offset+8];
va009039 0:1ed23ab1345f 1188 event_rpn.data.parameter_mask_1 = packet[payload_offset+9];
va009039 0:1ed23ab1345f 1189 rfcomm_channel_state_machine_2(multiplexer, message_dlci, (rfcomm_channel_event_t*) &event_rpn);
va009039 0:1ed23ab1345f 1190 break;
va009039 0:1ed23ab1345f 1191 default:
va009039 0:1ed23ab1345f 1192 break;
va009039 0:1ed23ab1345f 1193 }
va009039 0:1ed23ab1345f 1194 break;
va009039 0:1ed23ab1345f 1195
va009039 0:1ed23ab1345f 1196 default:
va009039 0:1ed23ab1345f 1197 log_error("Received unknown UIH packet - 0x%02x\n", packet[payload_offset]);
va009039 0:1ed23ab1345f 1198 break;
va009039 0:1ed23ab1345f 1199 }
va009039 0:1ed23ab1345f 1200 break;
va009039 0:1ed23ab1345f 1201
va009039 0:1ed23ab1345f 1202 default:
va009039 0:1ed23ab1345f 1203 log_error("Received unknown RFCOMM message type %x\n", packet[1]);
va009039 0:1ed23ab1345f 1204 break;
va009039 0:1ed23ab1345f 1205 }
va009039 0:1ed23ab1345f 1206
va009039 0:1ed23ab1345f 1207 // trigger next action - example W4_PN_RSP: transition to SEND_SABM which only depends on "can send"
va009039 0:1ed23ab1345f 1208 rfcomm_run();
va009039 0:1ed23ab1345f 1209 }
va009039 0:1ed23ab1345f 1210
va009039 0:1ed23ab1345f 1211 void rfcomm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
va009039 0:1ed23ab1345f 1212
va009039 0:1ed23ab1345f 1213 // multiplexer handler
va009039 0:1ed23ab1345f 1214 int handled = 0;
va009039 0:1ed23ab1345f 1215 switch (packet_type) {
va009039 0:1ed23ab1345f 1216 case HCI_EVENT_PACKET:
va009039 0:1ed23ab1345f 1217 handled = rfcomm_multiplexer_hci_event_handler(packet, size);
va009039 0:1ed23ab1345f 1218 break;
va009039 0:1ed23ab1345f 1219 case L2CAP_DATA_PACKET:
va009039 0:1ed23ab1345f 1220 handled = rfcomm_multiplexer_l2cap_packet_handler(channel, packet, size);
va009039 0:1ed23ab1345f 1221 break;
va009039 0:1ed23ab1345f 1222 default:
va009039 0:1ed23ab1345f 1223 break;
va009039 0:1ed23ab1345f 1224 }
va009039 0:1ed23ab1345f 1225
va009039 0:1ed23ab1345f 1226 if (handled) {
va009039 0:1ed23ab1345f 1227 rfcomm_run();
va009039 0:1ed23ab1345f 1228 return;
va009039 0:1ed23ab1345f 1229 }
va009039 0:1ed23ab1345f 1230
va009039 0:1ed23ab1345f 1231 // we only handle l2cap packet over open multiplexer channel now
va009039 0:1ed23ab1345f 1232 if (packet_type != L2CAP_DATA_PACKET) {
va009039 0:1ed23ab1345f 1233 (*app_packet_handler)(NULL, packet_type, channel, packet, size);
va009039 0:1ed23ab1345f 1234 return;
va009039 0:1ed23ab1345f 1235 }
va009039 0:1ed23ab1345f 1236 rfcomm_multiplexer_t * multiplexer = rfcomm_multiplexer_for_l2cap_cid(channel);
va009039 0:1ed23ab1345f 1237 if (!multiplexer || multiplexer->state != RFCOMM_MULTIPLEXER_OPEN) {
va009039 0:1ed23ab1345f 1238 (*app_packet_handler)(NULL, packet_type, channel, packet, size);
va009039 0:1ed23ab1345f 1239 return;
va009039 0:1ed23ab1345f 1240 }
va009039 0:1ed23ab1345f 1241
va009039 0:1ed23ab1345f 1242 // channel data ?
va009039 0:1ed23ab1345f 1243 // rfcomm: (0) addr [76543 server channel] [2 direction: initiator uses 1] [1 C/R: CMD by initiator = 1] [0 EA=1]
va009039 0:1ed23ab1345f 1244 const uint8_t frame_dlci = packet[0] >> 2;
va009039 0:1ed23ab1345f 1245
va009039 0:1ed23ab1345f 1246 if (frame_dlci && (packet[1] == BT_RFCOMM_UIH || packet[1] == BT_RFCOMM_UIH_PF)) {
va009039 0:1ed23ab1345f 1247 rfcomm_channel_packet_handler_uih(multiplexer, packet, size);
va009039 0:1ed23ab1345f 1248 rfcomm_run();
va009039 0:1ed23ab1345f 1249 return;
va009039 0:1ed23ab1345f 1250 }
va009039 0:1ed23ab1345f 1251
va009039 0:1ed23ab1345f 1252 rfcomm_channel_packet_handler(multiplexer, packet, size);
va009039 0:1ed23ab1345f 1253 }
va009039 0:1ed23ab1345f 1254
va009039 0:1ed23ab1345f 1255 static int rfcomm_channel_ready_for_open(rfcomm_channel_t *channel){
va009039 0:1ed23ab1345f 1256 // 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);
va009039 0:1ed23ab1345f 1257 if ((channel->state_var & RFCOMM_CHANNEL_STATE_VAR_RCVD_MSC_RSP) == 0) return 0;
va009039 0:1ed23ab1345f 1258 if ((channel->state_var & RFCOMM_CHANNEL_STATE_VAR_SENT_MSC_RSP) == 0) return 0;
va009039 0:1ed23ab1345f 1259 if ((channel->state_var & RFCOMM_CHANNEL_STATE_VAR_SENT_CREDITS) == 0) return 0;
va009039 0:1ed23ab1345f 1260 if (channel->credits_outgoing == 0) return 0;
va009039 0:1ed23ab1345f 1261
va009039 0:1ed23ab1345f 1262 return 1;
va009039 0:1ed23ab1345f 1263 }
va009039 0:1ed23ab1345f 1264
va009039 0:1ed23ab1345f 1265 static void rfcomm_channel_state_machine(rfcomm_channel_t *channel, rfcomm_channel_event_t *event){
va009039 0:1ed23ab1345f 1266
va009039 0:1ed23ab1345f 1267 // log_info("rfcomm_channel_state_machine: state %u, state_var %04x, event %u\n", channel->state, channel->state_var ,event->type);
va009039 0:1ed23ab1345f 1268
va009039 0:1ed23ab1345f 1269 rfcomm_multiplexer_t *multiplexer = channel->multiplexer;
va009039 0:1ed23ab1345f 1270
va009039 0:1ed23ab1345f 1271 // TODO: integrate in common switch
va009039 0:1ed23ab1345f 1272 if (event->type == CH_EVT_RCVD_DISC){
va009039 0:1ed23ab1345f 1273 rfcomm_emit_channel_closed(channel);
va009039 0:1ed23ab1345f 1274 channel->state = RFCOMM_CHANNEL_SEND_UA_AFTER_DISC;
va009039 0:1ed23ab1345f 1275 return;
va009039 0:1ed23ab1345f 1276 }
va009039 0:1ed23ab1345f 1277
va009039 0:1ed23ab1345f 1278 // TODO: integrate in common switch
va009039 0:1ed23ab1345f 1279 if (event->type == CH_EVT_RCVD_DM){
va009039 0:1ed23ab1345f 1280 log_info("Received DM message for #%u\n", channel->dlci);
va009039 0:1ed23ab1345f 1281 log_info("-> Closing channel locally for #%u\n", channel->dlci);
va009039 0:1ed23ab1345f 1282 rfcomm_emit_channel_closed(channel);
va009039 0:1ed23ab1345f 1283 rfcomm_channel_finalize(channel);
va009039 0:1ed23ab1345f 1284 return;
va009039 0:1ed23ab1345f 1285 }
va009039 0:1ed23ab1345f 1286
va009039 0:1ed23ab1345f 1287 // remote port negotiation command - just accept everything for now
va009039 0:1ed23ab1345f 1288 //
va009039 0:1ed23ab1345f 1289 // "The RPN command can be used before a new DLC is opened and should be used whenever the port settings change."
va009039 0:1ed23ab1345f 1290 // "The RPN command is specified as optional in TS 07.10, but it is mandatory to recognize and respond to it in RFCOMM.
va009039 0:1ed23ab1345f 1291 // (Although the handling of individual settings are implementation-dependent.)"
va009039 0:1ed23ab1345f 1292 //
va009039 0:1ed23ab1345f 1293
va009039 0:1ed23ab1345f 1294 // TODO: integrate in common switch
va009039 0:1ed23ab1345f 1295 if (event->type == CH_EVT_RCVD_RPN_CMD){
va009039 0:1ed23ab1345f 1296 // control port parameters
va009039 0:1ed23ab1345f 1297 rfcomm_channel_event_rpn_t *event_rpn = (rfcomm_channel_event_rpn_t*) event;
va009039 0:1ed23ab1345f 1298 memcpy(&channel->rpn_data, &event_rpn->data, sizeof(rfcomm_rpn_data_t));
va009039 0:1ed23ab1345f 1299 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_RPN_RSP;
va009039 0:1ed23ab1345f 1300 return;
va009039 0:1ed23ab1345f 1301 }
va009039 0:1ed23ab1345f 1302
va009039 0:1ed23ab1345f 1303 // TODO: integrate in common switch
va009039 0:1ed23ab1345f 1304 if (event->type == CH_EVT_RCVD_RPN_REQ){
va009039 0:1ed23ab1345f 1305 // default rpn rsp
va009039 0:1ed23ab1345f 1306 rfcomm_rpn_data_t rpn_data;
va009039 0:1ed23ab1345f 1307 rpn_data.baud_rate = 0xa0; /* 9600 bps */
va009039 0:1ed23ab1345f 1308 rpn_data.flags = 0x03; /* 8-n-1 */
va009039 0:1ed23ab1345f 1309 rpn_data.flow_control = 0; /* no flow control */
va009039 0:1ed23ab1345f 1310 rpn_data.xon = 0xd1; /* XON */
va009039 0:1ed23ab1345f 1311 rpn_data.xoff = 0xd3; /* XOFF */
va009039 0:1ed23ab1345f 1312 rpn_data.parameter_mask_0 = 0x7f; /* parameter mask, all values set */
va009039 0:1ed23ab1345f 1313 rpn_data.parameter_mask_1 = 0x3f; /* parameter mask, all values set */
va009039 0:1ed23ab1345f 1314 memcpy(&channel->rpn_data, &rpn_data, sizeof(rfcomm_rpn_data_t));
va009039 0:1ed23ab1345f 1315 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_RPN_RSP;
va009039 0:1ed23ab1345f 1316 return;
va009039 0:1ed23ab1345f 1317 }
va009039 0:1ed23ab1345f 1318
va009039 0:1ed23ab1345f 1319 // TODO: integrate in common swich
va009039 0:1ed23ab1345f 1320 if (event->type == CH_EVT_READY_TO_SEND){
va009039 0:1ed23ab1345f 1321 if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_SEND_RPN_RSP){
va009039 0:1ed23ab1345f 1322 log_info("Sending Remote Port Negotiation RSP for #%u\n", channel->dlci);
va009039 0:1ed23ab1345f 1323 channel->state_var &= ~RFCOMM_CHANNEL_STATE_VAR_SEND_RPN_RSP;
va009039 0:1ed23ab1345f 1324 rfcomm_send_uih_rpn_rsp(multiplexer, channel->dlci, &channel->rpn_data);
va009039 0:1ed23ab1345f 1325 return;
va009039 0:1ed23ab1345f 1326 }
va009039 0:1ed23ab1345f 1327 }
va009039 0:1ed23ab1345f 1328
va009039 0:1ed23ab1345f 1329 rfcomm_channel_event_pn_t * event_pn = (rfcomm_channel_event_pn_t*) event;
va009039 0:1ed23ab1345f 1330
va009039 0:1ed23ab1345f 1331 switch (channel->state) {
va009039 0:1ed23ab1345f 1332 case RFCOMM_CHANNEL_CLOSED:
va009039 0:1ed23ab1345f 1333 switch (event->type){
va009039 0:1ed23ab1345f 1334 case CH_EVT_RCVD_SABM:
va009039 0:1ed23ab1345f 1335 log_info("-> Inform app\n");
va009039 0:1ed23ab1345f 1336 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_RCVD_SABM;
va009039 0:1ed23ab1345f 1337 channel->state = RFCOMM_CHANNEL_INCOMING_SETUP;
va009039 0:1ed23ab1345f 1338 rfcomm_emit_connection_request(channel);
va009039 0:1ed23ab1345f 1339 break;
va009039 0:1ed23ab1345f 1340 case CH_EVT_RCVD_PN:
va009039 0:1ed23ab1345f 1341 rfcomm_channel_accept_pn(channel, event_pn);
va009039 0:1ed23ab1345f 1342 log_info("-> Inform app\n");
va009039 0:1ed23ab1345f 1343 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_RCVD_PN;
va009039 0:1ed23ab1345f 1344 channel->state = RFCOMM_CHANNEL_INCOMING_SETUP;
va009039 0:1ed23ab1345f 1345 rfcomm_emit_connection_request(channel);
va009039 0:1ed23ab1345f 1346 break;
va009039 0:1ed23ab1345f 1347 default:
va009039 0:1ed23ab1345f 1348 break;
va009039 0:1ed23ab1345f 1349 }
va009039 0:1ed23ab1345f 1350 break;
va009039 0:1ed23ab1345f 1351
va009039 0:1ed23ab1345f 1352 case RFCOMM_CHANNEL_INCOMING_SETUP:
va009039 0:1ed23ab1345f 1353 switch (event->type){
va009039 0:1ed23ab1345f 1354 case CH_EVT_RCVD_SABM:
va009039 0:1ed23ab1345f 1355 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_RCVD_SABM;
va009039 0:1ed23ab1345f 1356 if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_CLIENT_ACCEPTED) {
va009039 0:1ed23ab1345f 1357 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_UA;
va009039 0:1ed23ab1345f 1358 }
va009039 0:1ed23ab1345f 1359 break;
va009039 0:1ed23ab1345f 1360 case CH_EVT_RCVD_PN:
va009039 0:1ed23ab1345f 1361 rfcomm_channel_accept_pn(channel, event_pn);
va009039 0:1ed23ab1345f 1362 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_RCVD_PN;
va009039 0:1ed23ab1345f 1363 if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_CLIENT_ACCEPTED) {
va009039 0:1ed23ab1345f 1364 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_PN_RSP;
va009039 0:1ed23ab1345f 1365 }
va009039 0:1ed23ab1345f 1366 break;
va009039 0:1ed23ab1345f 1367 case CH_EVT_READY_TO_SEND:
va009039 0:1ed23ab1345f 1368 if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_SEND_PN_RSP){
va009039 0:1ed23ab1345f 1369 log_info("Sending UIH Parameter Negotiation Respond for #%u\n", channel->dlci);
va009039 0:1ed23ab1345f 1370 channel->state_var &= ~RFCOMM_CHANNEL_STATE_VAR_SEND_PN_RSP;
va009039 0:1ed23ab1345f 1371 rfcomm_send_uih_pn_response(multiplexer, channel->dlci, channel->pn_priority, channel->max_frame_size);
va009039 0:1ed23ab1345f 1372 }
va009039 0:1ed23ab1345f 1373 else if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_SEND_UA){
va009039 0:1ed23ab1345f 1374 log_info("Sending UA #%u\n", channel->dlci);
va009039 0:1ed23ab1345f 1375 channel->state_var &= ~RFCOMM_CHANNEL_STATE_VAR_SEND_UA;
va009039 0:1ed23ab1345f 1376 rfcomm_send_ua(multiplexer, channel->dlci);
va009039 0:1ed23ab1345f 1377 }
va009039 0:1ed23ab1345f 1378 if ((channel->state_var & RFCOMM_CHANNEL_STATE_VAR_CLIENT_ACCEPTED) && (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_RCVD_SABM)) {
va009039 0:1ed23ab1345f 1379 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_CMD;
va009039 0:1ed23ab1345f 1380 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_CREDITS;
va009039 0:1ed23ab1345f 1381 channel->state = RFCOMM_CHANNEL_DLC_SETUP;
va009039 0:1ed23ab1345f 1382 }
va009039 0:1ed23ab1345f 1383 break;
va009039 0:1ed23ab1345f 1384
va009039 0:1ed23ab1345f 1385 default:
va009039 0:1ed23ab1345f 1386 break;
va009039 0:1ed23ab1345f 1387 }
va009039 0:1ed23ab1345f 1388 break;
va009039 0:1ed23ab1345f 1389
va009039 0:1ed23ab1345f 1390 case RFCOMM_CHANNEL_W4_MULTIPLEXER:
va009039 0:1ed23ab1345f 1391 switch (event->type) {
va009039 0:1ed23ab1345f 1392 case CH_EVT_MULTIPLEXER_READY:
va009039 0:1ed23ab1345f 1393 log_info("Muliplexer opened, sending UIH PN next\n");
va009039 0:1ed23ab1345f 1394 channel->state = RFCOMM_CHANNEL_SEND_UIH_PN;
va009039 0:1ed23ab1345f 1395 break;
va009039 0:1ed23ab1345f 1396 default:
va009039 0:1ed23ab1345f 1397 break;
va009039 0:1ed23ab1345f 1398 }
va009039 0:1ed23ab1345f 1399 break;
va009039 0:1ed23ab1345f 1400
va009039 0:1ed23ab1345f 1401 case RFCOMM_CHANNEL_SEND_UIH_PN:
va009039 0:1ed23ab1345f 1402 switch (event->type) {
va009039 0:1ed23ab1345f 1403 case CH_EVT_READY_TO_SEND:
va009039 0:1ed23ab1345f 1404 log_info("Sending UIH Parameter Negotiation Command for #%u (channel 0x%p)\n", channel->dlci, channel );
va009039 0:1ed23ab1345f 1405 channel->state = RFCOMM_CHANNEL_W4_PN_RSP;
va009039 0:1ed23ab1345f 1406 rfcomm_send_uih_pn_command(multiplexer, channel->dlci, channel->max_frame_size);
va009039 0:1ed23ab1345f 1407 break;
va009039 0:1ed23ab1345f 1408 default:
va009039 0:1ed23ab1345f 1409 break;
va009039 0:1ed23ab1345f 1410 }
va009039 0:1ed23ab1345f 1411 break;
va009039 0:1ed23ab1345f 1412
va009039 0:1ed23ab1345f 1413 case RFCOMM_CHANNEL_W4_PN_RSP:
va009039 0:1ed23ab1345f 1414 switch (event->type){
va009039 0:1ed23ab1345f 1415 case CH_EVT_RCVD_PN_RSP:
va009039 0:1ed23ab1345f 1416 // update max frame size
va009039 0:1ed23ab1345f 1417 if (channel->max_frame_size > event_pn->max_frame_size) {
va009039 0:1ed23ab1345f 1418 channel->max_frame_size = event_pn->max_frame_size;
va009039 0:1ed23ab1345f 1419 }
va009039 0:1ed23ab1345f 1420 // new credits
va009039 0:1ed23ab1345f 1421 channel->credits_outgoing = event_pn->credits_outgoing;
va009039 0:1ed23ab1345f 1422 channel->state = RFCOMM_CHANNEL_SEND_SABM_W4_UA;
va009039 0:1ed23ab1345f 1423 break;
va009039 0:1ed23ab1345f 1424 default:
va009039 0:1ed23ab1345f 1425 break;
va009039 0:1ed23ab1345f 1426 }
va009039 0:1ed23ab1345f 1427 break;
va009039 0:1ed23ab1345f 1428
va009039 0:1ed23ab1345f 1429 case RFCOMM_CHANNEL_SEND_SABM_W4_UA:
va009039 0:1ed23ab1345f 1430 switch (event->type) {
va009039 0:1ed23ab1345f 1431 case CH_EVT_READY_TO_SEND:
va009039 0:1ed23ab1345f 1432 log_info("Sending SABM #%u\n", channel->dlci);
va009039 0:1ed23ab1345f 1433 channel->state = RFCOMM_CHANNEL_W4_UA;
va009039 0:1ed23ab1345f 1434 rfcomm_send_sabm(multiplexer, channel->dlci);
va009039 0:1ed23ab1345f 1435 break;
va009039 0:1ed23ab1345f 1436 default:
va009039 0:1ed23ab1345f 1437 break;
va009039 0:1ed23ab1345f 1438 }
va009039 0:1ed23ab1345f 1439 break;
va009039 0:1ed23ab1345f 1440
va009039 0:1ed23ab1345f 1441 case RFCOMM_CHANNEL_W4_UA:
va009039 0:1ed23ab1345f 1442 switch (event->type){
va009039 0:1ed23ab1345f 1443 case CH_EVT_RCVD_UA:
va009039 0:1ed23ab1345f 1444 channel->state = RFCOMM_CHANNEL_DLC_SETUP;
va009039 0:1ed23ab1345f 1445 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_CMD;
va009039 0:1ed23ab1345f 1446 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_CREDITS;
va009039 0:1ed23ab1345f 1447 break;
va009039 0:1ed23ab1345f 1448 default:
va009039 0:1ed23ab1345f 1449 break;
va009039 0:1ed23ab1345f 1450 }
va009039 0:1ed23ab1345f 1451 break;
va009039 0:1ed23ab1345f 1452
va009039 0:1ed23ab1345f 1453 case RFCOMM_CHANNEL_DLC_SETUP:
va009039 0:1ed23ab1345f 1454 switch (event->type){
va009039 0:1ed23ab1345f 1455 case CH_EVT_RCVD_MSC_CMD:
va009039 0:1ed23ab1345f 1456 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_RCVD_MSC_CMD;
va009039 0:1ed23ab1345f 1457 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_RSP;
va009039 0:1ed23ab1345f 1458 break;
va009039 0:1ed23ab1345f 1459 case CH_EVT_RCVD_MSC_RSP:
va009039 0:1ed23ab1345f 1460 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_RCVD_MSC_RSP;
va009039 0:1ed23ab1345f 1461 break;
va009039 0:1ed23ab1345f 1462
va009039 0:1ed23ab1345f 1463 case CH_EVT_READY_TO_SEND:
va009039 0:1ed23ab1345f 1464 if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_CMD){
va009039 0:1ed23ab1345f 1465 log_info("Sending MSC CMD for #%u\n", channel->dlci);
va009039 0:1ed23ab1345f 1466 channel->state_var &= ~RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_CMD;
va009039 0:1ed23ab1345f 1467 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SENT_MSC_CMD;
va009039 0:1ed23ab1345f 1468 rfcomm_send_uih_msc_cmd(multiplexer, channel->dlci , 0x8d); // ea=1,fc=0,rtc=1,rtr=1,ic=0,dv=1
va009039 0:1ed23ab1345f 1469 break;
va009039 0:1ed23ab1345f 1470 }
va009039 0:1ed23ab1345f 1471 if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_RSP){
va009039 0:1ed23ab1345f 1472 log_info("Sending MSC RSP for #%u\n", channel->dlci);
va009039 0:1ed23ab1345f 1473 channel->state_var &= ~RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_RSP;
va009039 0:1ed23ab1345f 1474 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SENT_MSC_RSP;
va009039 0:1ed23ab1345f 1475 rfcomm_send_uih_msc_rsp(multiplexer, channel->dlci, 0x8d); // ea=1,fc=0,rtc=1,rtr=1,ic=0,dv=1
va009039 0:1ed23ab1345f 1476 break;
va009039 0:1ed23ab1345f 1477 }
va009039 0:1ed23ab1345f 1478 if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_SEND_CREDITS){
va009039 0:1ed23ab1345f 1479 log_info("Providing credits for #%u\n", channel->dlci);
va009039 0:1ed23ab1345f 1480 channel->state_var &= ~RFCOMM_CHANNEL_STATE_VAR_SEND_CREDITS;
va009039 0:1ed23ab1345f 1481 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SENT_CREDITS;
va009039 0:1ed23ab1345f 1482 if (channel->new_credits_incoming) {
va009039 0:1ed23ab1345f 1483 uint8_t new_credits = channel->new_credits_incoming;
va009039 0:1ed23ab1345f 1484 channel->new_credits_incoming = 0;
va009039 0:1ed23ab1345f 1485 rfcomm_channel_send_credits(channel, new_credits);
va009039 0:1ed23ab1345f 1486 }
va009039 0:1ed23ab1345f 1487 break;
va009039 0:1ed23ab1345f 1488
va009039 0:1ed23ab1345f 1489 }
va009039 0:1ed23ab1345f 1490 break;
va009039 0:1ed23ab1345f 1491 default:
va009039 0:1ed23ab1345f 1492 break;
va009039 0:1ed23ab1345f 1493 }
va009039 0:1ed23ab1345f 1494 // finally done?
va009039 0:1ed23ab1345f 1495 if (rfcomm_channel_ready_for_open(channel)){
va009039 0:1ed23ab1345f 1496 channel->state = RFCOMM_CHANNEL_OPEN;
va009039 0:1ed23ab1345f 1497 rfcomm_channel_opened(channel);
va009039 0:1ed23ab1345f 1498 }
va009039 0:1ed23ab1345f 1499 break;
va009039 0:1ed23ab1345f 1500
va009039 0:1ed23ab1345f 1501 case RFCOMM_CHANNEL_OPEN:
va009039 0:1ed23ab1345f 1502 switch (event->type){
va009039 0:1ed23ab1345f 1503 case CH_EVT_RCVD_MSC_CMD:
va009039 0:1ed23ab1345f 1504 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_RSP;
va009039 0:1ed23ab1345f 1505 break;
va009039 0:1ed23ab1345f 1506 case CH_EVT_READY_TO_SEND:
va009039 0:1ed23ab1345f 1507 if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_RSP){
va009039 0:1ed23ab1345f 1508 log_info("Sending MSC RSP for #%u\n", channel->dlci);
va009039 0:1ed23ab1345f 1509 channel->state_var &= ~RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_RSP;
va009039 0:1ed23ab1345f 1510 rfcomm_send_uih_msc_rsp(multiplexer, channel->dlci, 0x8d); // ea=1,fc=0,rtc=1,rtr=1,ic=0,dv=1
va009039 0:1ed23ab1345f 1511 break;
va009039 0:1ed23ab1345f 1512 }
va009039 0:1ed23ab1345f 1513 if (channel->new_credits_incoming) {
va009039 0:1ed23ab1345f 1514 uint8_t new_credits = channel->new_credits_incoming;
va009039 0:1ed23ab1345f 1515 channel->new_credits_incoming = 0;
va009039 0:1ed23ab1345f 1516 rfcomm_channel_send_credits(channel, new_credits);
va009039 0:1ed23ab1345f 1517 break;
va009039 0:1ed23ab1345f 1518 }
va009039 0:1ed23ab1345f 1519 break;
va009039 0:1ed23ab1345f 1520 case CH_EVT_RCVD_CREDITS: {
va009039 0:1ed23ab1345f 1521 // notify daemon -> might trigger re-try of parked connections
va009039 0:1ed23ab1345f 1522 uint8_t event[1] = { DAEMON_EVENT_NEW_RFCOMM_CREDITS };
va009039 0:1ed23ab1345f 1523 (*app_packet_handler)(channel->connection, DAEMON_EVENT_PACKET, channel->rfcomm_cid, event, sizeof(event));
va009039 0:1ed23ab1345f 1524 break;
va009039 0:1ed23ab1345f 1525 }
va009039 0:1ed23ab1345f 1526 default:
va009039 0:1ed23ab1345f 1527 break;
va009039 0:1ed23ab1345f 1528 }
va009039 0:1ed23ab1345f 1529 break;
va009039 0:1ed23ab1345f 1530
va009039 0:1ed23ab1345f 1531 case RFCOMM_CHANNEL_SEND_DM:
va009039 0:1ed23ab1345f 1532 switch (event->type) {
va009039 0:1ed23ab1345f 1533 case CH_EVT_READY_TO_SEND:
va009039 0:1ed23ab1345f 1534 log_info("Sending DM_PF for #%u\n", channel->dlci);
va009039 0:1ed23ab1345f 1535 // don't emit channel closed - channel was never open
va009039 0:1ed23ab1345f 1536 channel->state = RFCOMM_CHANNEL_CLOSED;
va009039 0:1ed23ab1345f 1537 rfcomm_send_dm_pf(multiplexer, channel->dlci);
va009039 0:1ed23ab1345f 1538 rfcomm_channel_finalize(channel);
va009039 0:1ed23ab1345f 1539 break;
va009039 0:1ed23ab1345f 1540 default:
va009039 0:1ed23ab1345f 1541 break;
va009039 0:1ed23ab1345f 1542 }
va009039 0:1ed23ab1345f 1543 break;
va009039 0:1ed23ab1345f 1544
va009039 0:1ed23ab1345f 1545 case RFCOMM_CHANNEL_SEND_DISC:
va009039 0:1ed23ab1345f 1546 switch (event->type) {
va009039 0:1ed23ab1345f 1547 case CH_EVT_READY_TO_SEND:
va009039 0:1ed23ab1345f 1548 channel->state = RFCOMM_CHANNEL_CLOSED;
va009039 0:1ed23ab1345f 1549 rfcomm_send_disc(multiplexer, channel->dlci);
va009039 0:1ed23ab1345f 1550 rfcomm_emit_channel_closed(channel);
va009039 0:1ed23ab1345f 1551 rfcomm_channel_finalize(channel);
va009039 0:1ed23ab1345f 1552 break;
va009039 0:1ed23ab1345f 1553 default:
va009039 0:1ed23ab1345f 1554 break;
va009039 0:1ed23ab1345f 1555 }
va009039 0:1ed23ab1345f 1556 break;
va009039 0:1ed23ab1345f 1557
va009039 0:1ed23ab1345f 1558 case RFCOMM_CHANNEL_SEND_UA_AFTER_DISC:
va009039 0:1ed23ab1345f 1559 switch (event->type) {
va009039 0:1ed23ab1345f 1560 case CH_EVT_READY_TO_SEND:
va009039 0:1ed23ab1345f 1561 log_info("Sending UA after DISC for #%u\n", channel->dlci);
va009039 0:1ed23ab1345f 1562 channel->state = RFCOMM_CHANNEL_CLOSED;
va009039 0:1ed23ab1345f 1563 rfcomm_send_ua(multiplexer, channel->dlci);
va009039 0:1ed23ab1345f 1564 rfcomm_channel_finalize(channel);
va009039 0:1ed23ab1345f 1565 break;
va009039 0:1ed23ab1345f 1566 default:
va009039 0:1ed23ab1345f 1567 break;
va009039 0:1ed23ab1345f 1568 }
va009039 0:1ed23ab1345f 1569 break;
va009039 0:1ed23ab1345f 1570
va009039 0:1ed23ab1345f 1571 default:
va009039 0:1ed23ab1345f 1572 break;
va009039 0:1ed23ab1345f 1573 }
va009039 0:1ed23ab1345f 1574 }
va009039 0:1ed23ab1345f 1575
va009039 0:1ed23ab1345f 1576
va009039 0:1ed23ab1345f 1577 // MARK: RFCOMM RUN
va009039 0:1ed23ab1345f 1578 // process outstanding signaling tasks
va009039 0:1ed23ab1345f 1579 static void rfcomm_run(void){
va009039 0:1ed23ab1345f 1580
va009039 0:1ed23ab1345f 1581 linked_item_t *it;
va009039 0:1ed23ab1345f 1582 linked_item_t *next;
va009039 0:1ed23ab1345f 1583
va009039 0:1ed23ab1345f 1584 for (it = (linked_item_t *) rfcomm_multiplexers; it ; it = next){
va009039 0:1ed23ab1345f 1585
va009039 0:1ed23ab1345f 1586 next = it->next; // be prepared for removal of channel in state machine
va009039 0:1ed23ab1345f 1587
va009039 0:1ed23ab1345f 1588 rfcomm_multiplexer_t * multiplexer = ((rfcomm_multiplexer_t *) it);
va009039 0:1ed23ab1345f 1589
va009039 0:1ed23ab1345f 1590 if (!l2cap_can_send_packet_now(multiplexer->l2cap_cid)) {
va009039 0:1ed23ab1345f 1591 // log_info("rfcomm_run cannot send l2cap packet for #%u, credits %u\n", multiplexer->l2cap_cid, multiplexer->l2cap_credits);
va009039 0:1ed23ab1345f 1592 continue;
va009039 0:1ed23ab1345f 1593 }
va009039 0:1ed23ab1345f 1594 // log_info("rfcomm_run: multi 0x%08x, state %u\n", (int) multiplexer, multiplexer->state);
va009039 0:1ed23ab1345f 1595
va009039 0:1ed23ab1345f 1596 rfcomm_multiplexer_state_machine(multiplexer, MULT_EV_READY_TO_SEND);
va009039 0:1ed23ab1345f 1597 }
va009039 0:1ed23ab1345f 1598
va009039 0:1ed23ab1345f 1599 for (it = (linked_item_t *) rfcomm_channels; it ; it = next){
va009039 0:1ed23ab1345f 1600
va009039 0:1ed23ab1345f 1601 next = it->next; // be prepared for removal of channel in state machine
va009039 0:1ed23ab1345f 1602
va009039 0:1ed23ab1345f 1603 rfcomm_channel_t * channel = ((rfcomm_channel_t *) it);
va009039 0:1ed23ab1345f 1604 rfcomm_multiplexer_t * multiplexer = channel->multiplexer;
va009039 0:1ed23ab1345f 1605
va009039 0:1ed23ab1345f 1606 if (!l2cap_can_send_packet_now(multiplexer->l2cap_cid)) continue;
va009039 0:1ed23ab1345f 1607
va009039 0:1ed23ab1345f 1608 rfcomm_channel_event_t event = { CH_EVT_READY_TO_SEND };
va009039 0:1ed23ab1345f 1609 rfcomm_channel_state_machine(channel, &event);
va009039 0:1ed23ab1345f 1610 }
va009039 0:1ed23ab1345f 1611 }
va009039 0:1ed23ab1345f 1612
va009039 0:1ed23ab1345f 1613 // MARK: RFCOMM BTstack API
va009039 0:1ed23ab1345f 1614
va009039 0:1ed23ab1345f 1615 void rfcomm_init(void){
va009039 0:1ed23ab1345f 1616 rfcomm_client_cid_generator = 0;
va009039 0:1ed23ab1345f 1617 rfcomm_multiplexers = NULL;
va009039 0:1ed23ab1345f 1618 rfcomm_services = NULL;
va009039 0:1ed23ab1345f 1619 rfcomm_channels = NULL;
va009039 0:1ed23ab1345f 1620 }
va009039 0:1ed23ab1345f 1621
va009039 0:1ed23ab1345f 1622 // register packet handler
va009039 0:1ed23ab1345f 1623 void rfcomm_register_packet_handler(void (*handler)(void * connection, uint8_t packet_type,
va009039 0:1ed23ab1345f 1624 uint16_t channel, uint8_t *packet, uint16_t size)){
va009039 0:1ed23ab1345f 1625 app_packet_handler = handler;
va009039 0:1ed23ab1345f 1626 }
va009039 0:1ed23ab1345f 1627
va009039 0:1ed23ab1345f 1628 // send packet over specific channel
va009039 0:1ed23ab1345f 1629 int rfcomm_send_internal(uint16_t rfcomm_cid, uint8_t *data, uint16_t len){
va009039 0:1ed23ab1345f 1630
va009039 0:1ed23ab1345f 1631 rfcomm_channel_t * channel = rfcomm_channel_for_rfcomm_cid(rfcomm_cid);
va009039 0:1ed23ab1345f 1632 if (!channel){
va009039 0:1ed23ab1345f 1633 log_error("rfcomm_send_internal cid %u doesn't exist!\n", rfcomm_cid);
va009039 0:1ed23ab1345f 1634 return 0;
va009039 0:1ed23ab1345f 1635 }
va009039 0:1ed23ab1345f 1636
va009039 0:1ed23ab1345f 1637 if (!channel->credits_outgoing){
va009039 0:1ed23ab1345f 1638 log_info("rfcomm_send_internal cid %u, no rfcomm outgoing credits!\n", rfcomm_cid);
va009039 0:1ed23ab1345f 1639 return RFCOMM_NO_OUTGOING_CREDITS;
va009039 0:1ed23ab1345f 1640 }
va009039 0:1ed23ab1345f 1641
va009039 0:1ed23ab1345f 1642 if (!channel->packets_granted){
va009039 0:1ed23ab1345f 1643 log_info("rfcomm_send_internal cid %u, no rfcomm credits granted!\n", rfcomm_cid);
va009039 0:1ed23ab1345f 1644 return RFCOMM_NO_OUTGOING_CREDITS;
va009039 0:1ed23ab1345f 1645 }
va009039 0:1ed23ab1345f 1646
va009039 0:1ed23ab1345f 1647 // log_info("rfcomm_send_internal: len %u... outgoing credits %u, l2cap credit %us, granted %u\n",
va009039 0:1ed23ab1345f 1648 // len, channel->credits_outgoing, channel->multiplexer->l2cap_credits, channel->packets_granted);
va009039 0:1ed23ab1345f 1649
va009039 0:1ed23ab1345f 1650
va009039 0:1ed23ab1345f 1651 // send might cause l2cap to emit new credits, update counters first
va009039 0:1ed23ab1345f 1652 channel->credits_outgoing--;
va009039 0:1ed23ab1345f 1653 int packets_granted_decreased = 0;
va009039 0:1ed23ab1345f 1654 if (channel->packets_granted) {
va009039 0:1ed23ab1345f 1655 channel->packets_granted--;
va009039 0:1ed23ab1345f 1656 packets_granted_decreased++;
va009039 0:1ed23ab1345f 1657 }
va009039 0:1ed23ab1345f 1658
va009039 0:1ed23ab1345f 1659 int result = rfcomm_send_uih_data(channel->multiplexer, channel->dlci, data, len);
va009039 0:1ed23ab1345f 1660
va009039 0:1ed23ab1345f 1661 if (result != 0) {
va009039 0:1ed23ab1345f 1662 channel->credits_outgoing++;
va009039 0:1ed23ab1345f 1663 channel->packets_granted += packets_granted_decreased;
va009039 0:1ed23ab1345f 1664 log_info("rfcomm_send_internal: error %d\n", result);
va009039 0:1ed23ab1345f 1665 return result;
va009039 0:1ed23ab1345f 1666 }
va009039 0:1ed23ab1345f 1667
va009039 0:1ed23ab1345f 1668 // log_info("rfcomm_send_internal: now outgoing credits %u, l2cap credit %us, granted %u\n",
va009039 0:1ed23ab1345f 1669 // channel->credits_outgoing, channel->multiplexer->l2cap_credits, channel->packets_granted);
va009039 0:1ed23ab1345f 1670
va009039 0:1ed23ab1345f 1671 rfcomm_hand_out_credits();
va009039 0:1ed23ab1345f 1672
va009039 0:1ed23ab1345f 1673 return result;
va009039 0:1ed23ab1345f 1674 }
va009039 0:1ed23ab1345f 1675
va009039 0:1ed23ab1345f 1676 void rfcomm_create_channel2(void * connection, bd_addr_t *addr, uint8_t server_channel, uint8_t incoming_flow_control, uint8_t initial_credits){
va009039 0:1ed23ab1345f 1677 log_info("rfcomm_create_channel_internal to %s, at channel #%02x, flow control %u, init credits %u\n", bd_addr_to_str(*addr), server_channel,
va009039 0:1ed23ab1345f 1678 incoming_flow_control, initial_credits);
va009039 0:1ed23ab1345f 1679
va009039 0:1ed23ab1345f 1680 // create new multiplexer if necessary
va009039 0:1ed23ab1345f 1681 rfcomm_multiplexer_t * multiplexer = rfcomm_multiplexer_for_addr(addr);
va009039 0:1ed23ab1345f 1682 if (!multiplexer) {
va009039 0:1ed23ab1345f 1683 multiplexer = rfcomm_multiplexer_create_for_addr(addr);
va009039 0:1ed23ab1345f 1684 if (!multiplexer){
va009039 0:1ed23ab1345f 1685 rfcomm_emit_channel_open_failed_outgoing_memory(connection, addr, server_channel);
va009039 0:1ed23ab1345f 1686 return;
va009039 0:1ed23ab1345f 1687 }
va009039 0:1ed23ab1345f 1688 multiplexer->outgoing = 1;
va009039 0:1ed23ab1345f 1689 multiplexer->state = RFCOMM_MULTIPLEXER_W4_CONNECT;
va009039 0:1ed23ab1345f 1690 }
va009039 0:1ed23ab1345f 1691
va009039 0:1ed23ab1345f 1692 // prepare channel
va009039 0:1ed23ab1345f 1693 rfcomm_channel_t * channel = rfcomm_channel_create(multiplexer, NULL, server_channel);
va009039 0:1ed23ab1345f 1694 if (!channel){
va009039 0:1ed23ab1345f 1695 rfcomm_emit_channel_open_failed_outgoing_memory(connection, addr, server_channel);
va009039 0:1ed23ab1345f 1696 return;
va009039 0:1ed23ab1345f 1697 }
va009039 0:1ed23ab1345f 1698 channel->connection = connection;
va009039 0:1ed23ab1345f 1699 channel->incoming_flow_control = incoming_flow_control;
va009039 0:1ed23ab1345f 1700 channel->new_credits_incoming = initial_credits;
va009039 0:1ed23ab1345f 1701
va009039 0:1ed23ab1345f 1702 // start multiplexer setup
va009039 0:1ed23ab1345f 1703 if (multiplexer->state != RFCOMM_MULTIPLEXER_OPEN) {
va009039 0:1ed23ab1345f 1704
va009039 0:1ed23ab1345f 1705 channel->state = RFCOMM_CHANNEL_W4_MULTIPLEXER;
va009039 0:1ed23ab1345f 1706
va009039 0:1ed23ab1345f 1707 l2cap_create_channel_internal(connection, rfcomm_packet_handler, *addr, PSM_RFCOMM, l2cap_max_mtu());
va009039 0:1ed23ab1345f 1708
va009039 0:1ed23ab1345f 1709 return;
va009039 0:1ed23ab1345f 1710 }
va009039 0:1ed23ab1345f 1711
va009039 0:1ed23ab1345f 1712 channel->state = RFCOMM_CHANNEL_SEND_UIH_PN;
va009039 0:1ed23ab1345f 1713
va009039 0:1ed23ab1345f 1714 // start connecting, if multiplexer is already up and running
va009039 0:1ed23ab1345f 1715 rfcomm_run();
va009039 0:1ed23ab1345f 1716 }
va009039 0:1ed23ab1345f 1717
va009039 0:1ed23ab1345f 1718 void rfcomm_create_channel_with_initial_credits_internal(void * connection, bd_addr_t *addr, uint8_t server_channel, uint8_t initial_credits){
va009039 0:1ed23ab1345f 1719 rfcomm_create_channel2(connection, addr, server_channel, 1, initial_credits);
va009039 0:1ed23ab1345f 1720 }
va009039 0:1ed23ab1345f 1721
va009039 0:1ed23ab1345f 1722 void rfcomm_create_channel_internal(void * connection, bd_addr_t *addr, uint8_t server_channel){
va009039 0:1ed23ab1345f 1723 rfcomm_create_channel2(connection, addr, server_channel, 0, 0x30);
va009039 0:1ed23ab1345f 1724 }
va009039 0:1ed23ab1345f 1725
va009039 0:1ed23ab1345f 1726 void rfcomm_disconnect_internal(uint16_t rfcomm_cid){
va009039 0:1ed23ab1345f 1727 rfcomm_channel_t * channel = rfcomm_channel_for_rfcomm_cid(rfcomm_cid);
va009039 0:1ed23ab1345f 1728 if (channel) {
va009039 0:1ed23ab1345f 1729 channel->state = RFCOMM_CHANNEL_SEND_DISC;
va009039 0:1ed23ab1345f 1730 }
va009039 0:1ed23ab1345f 1731
va009039 0:1ed23ab1345f 1732 // process
va009039 0:1ed23ab1345f 1733 rfcomm_run();
va009039 0:1ed23ab1345f 1734 }
va009039 0:1ed23ab1345f 1735
va009039 0:1ed23ab1345f 1736
va009039 0:1ed23ab1345f 1737 void rfcomm_register_service2(void * connection, uint8_t channel, uint16_t max_frame_size, uint8_t incoming_flow_control, uint8_t initial_credits){
va009039 0:1ed23ab1345f 1738 // check if already registered
va009039 0:1ed23ab1345f 1739 rfcomm_service_t * service = rfcomm_service_for_channel(channel);
va009039 0:1ed23ab1345f 1740 if (service){
va009039 0:1ed23ab1345f 1741 rfcomm_emit_service_registered(connection, RFCOMM_CHANNEL_ALREADY_REGISTERED, channel);
va009039 0:1ed23ab1345f 1742 return;
va009039 0:1ed23ab1345f 1743 }
va009039 0:1ed23ab1345f 1744
va009039 0:1ed23ab1345f 1745 // alloc structure
va009039 0:1ed23ab1345f 1746 service = (rfcomm_service_t*)btstack_memory_rfcomm_service_get();
va009039 0:1ed23ab1345f 1747 if (!service) {
va009039 0:1ed23ab1345f 1748 rfcomm_emit_service_registered(connection, BTSTACK_MEMORY_ALLOC_FAILED, channel);
va009039 0:1ed23ab1345f 1749 return;
va009039 0:1ed23ab1345f 1750 }
va009039 0:1ed23ab1345f 1751
va009039 0:1ed23ab1345f 1752 // register with l2cap if not registered before, max MTU
va009039 0:1ed23ab1345f 1753 if (linked_list_empty(&rfcomm_services)){
va009039 0:1ed23ab1345f 1754 l2cap_register_service_internal(NULL, rfcomm_packet_handler, PSM_RFCOMM, 0xffff);
va009039 0:1ed23ab1345f 1755 }
va009039 0:1ed23ab1345f 1756
va009039 0:1ed23ab1345f 1757 // fill in
va009039 0:1ed23ab1345f 1758 service->connection = connection;
va009039 0:1ed23ab1345f 1759 service->server_channel = channel;
va009039 0:1ed23ab1345f 1760 service->max_frame_size = max_frame_size;
va009039 0:1ed23ab1345f 1761 service->incoming_flow_control = incoming_flow_control;
va009039 0:1ed23ab1345f 1762 service->incoming_initial_credits = initial_credits;
va009039 0:1ed23ab1345f 1763
va009039 0:1ed23ab1345f 1764 // add to services list
va009039 0:1ed23ab1345f 1765 linked_list_add(&rfcomm_services, (linked_item_t *) service);
va009039 0:1ed23ab1345f 1766
va009039 0:1ed23ab1345f 1767 // done
va009039 0:1ed23ab1345f 1768 rfcomm_emit_service_registered(connection, 0, channel);
va009039 0:1ed23ab1345f 1769 }
va009039 0:1ed23ab1345f 1770
va009039 0:1ed23ab1345f 1771 void rfcomm_register_service_with_initial_credits_internal(void * connection, uint8_t channel, uint16_t max_frame_size, uint8_t initial_credits){
va009039 0:1ed23ab1345f 1772 rfcomm_register_service2(connection, channel, max_frame_size, 1, initial_credits);
va009039 0:1ed23ab1345f 1773 }
va009039 0:1ed23ab1345f 1774
va009039 0:1ed23ab1345f 1775 void rfcomm_register_service_internal(void * connection, uint8_t channel, uint16_t max_frame_size){
va009039 0:1ed23ab1345f 1776 rfcomm_register_service2(connection, channel, max_frame_size, 0, 0x30);
va009039 0:1ed23ab1345f 1777 }
va009039 0:1ed23ab1345f 1778
va009039 0:1ed23ab1345f 1779 void rfcomm_unregister_service_internal(uint8_t service_channel){
va009039 0:1ed23ab1345f 1780 rfcomm_service_t *service = rfcomm_service_for_channel(service_channel);
va009039 0:1ed23ab1345f 1781 if (!service) return;
va009039 0:1ed23ab1345f 1782 linked_list_remove(&rfcomm_services, (linked_item_t *) service);
va009039 0:1ed23ab1345f 1783 btstack_memory_rfcomm_service_free(service);
va009039 0:1ed23ab1345f 1784
va009039 0:1ed23ab1345f 1785 // unregister if no services active
va009039 0:1ed23ab1345f 1786 if (linked_list_empty(&rfcomm_services)){
va009039 0:1ed23ab1345f 1787 // bt_send_cmd(&l2cap_unregister_service, PSM_RFCOMM);
va009039 0:1ed23ab1345f 1788 l2cap_unregister_service_internal(NULL, PSM_RFCOMM);
va009039 0:1ed23ab1345f 1789 }
va009039 0:1ed23ab1345f 1790 }
va009039 0:1ed23ab1345f 1791
va009039 0:1ed23ab1345f 1792 void rfcomm_accept_connection_internal(uint16_t rfcomm_cid){
va009039 0:1ed23ab1345f 1793 log_info("Received Accept Connction\n");
va009039 0:1ed23ab1345f 1794 rfcomm_channel_t * channel = rfcomm_channel_for_rfcomm_cid(rfcomm_cid);
va009039 0:1ed23ab1345f 1795 if (!channel) return;
va009039 0:1ed23ab1345f 1796 switch (channel->state) {
va009039 0:1ed23ab1345f 1797 case RFCOMM_CHANNEL_INCOMING_SETUP:
va009039 0:1ed23ab1345f 1798 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_CLIENT_ACCEPTED;
va009039 0:1ed23ab1345f 1799 if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_RCVD_PN){
va009039 0:1ed23ab1345f 1800 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_PN_RSP;
va009039 0:1ed23ab1345f 1801 }
va009039 0:1ed23ab1345f 1802 if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_RCVD_SABM){
va009039 0:1ed23ab1345f 1803 channel->state_var |= RFCOMM_CHANNEL_STATE_VAR_SEND_UA;
va009039 0:1ed23ab1345f 1804 }
va009039 0:1ed23ab1345f 1805 break;
va009039 0:1ed23ab1345f 1806 default:
va009039 0:1ed23ab1345f 1807 break;
va009039 0:1ed23ab1345f 1808 }
va009039 0:1ed23ab1345f 1809
va009039 0:1ed23ab1345f 1810 // process
va009039 0:1ed23ab1345f 1811 rfcomm_run();
va009039 0:1ed23ab1345f 1812 }
va009039 0:1ed23ab1345f 1813
va009039 0:1ed23ab1345f 1814 void rfcomm_decline_connection_internal(uint16_t rfcomm_cid){
va009039 0:1ed23ab1345f 1815 log_info("Received Decline Connction\n");
va009039 0:1ed23ab1345f 1816 rfcomm_channel_t * channel = rfcomm_channel_for_rfcomm_cid(rfcomm_cid);
va009039 0:1ed23ab1345f 1817 if (!channel) return;
va009039 0:1ed23ab1345f 1818 switch (channel->state) {
va009039 0:1ed23ab1345f 1819 case RFCOMM_CHANNEL_INCOMING_SETUP:
va009039 0:1ed23ab1345f 1820 channel->state = RFCOMM_CHANNEL_SEND_DM;
va009039 0:1ed23ab1345f 1821 break;
va009039 0:1ed23ab1345f 1822 default:
va009039 0:1ed23ab1345f 1823 break;
va009039 0:1ed23ab1345f 1824 }
va009039 0:1ed23ab1345f 1825
va009039 0:1ed23ab1345f 1826 // process
va009039 0:1ed23ab1345f 1827 rfcomm_run();
va009039 0:1ed23ab1345f 1828 }
va009039 0:1ed23ab1345f 1829
va009039 0:1ed23ab1345f 1830 void rfcomm_grant_credits(uint16_t rfcomm_cid, uint8_t credits){
va009039 0:1ed23ab1345f 1831 rfcomm_channel_t * channel = rfcomm_channel_for_rfcomm_cid(rfcomm_cid);
va009039 0:1ed23ab1345f 1832 if (!channel) return;
va009039 0:1ed23ab1345f 1833 if (!channel->incoming_flow_control) return;
va009039 0:1ed23ab1345f 1834 channel->new_credits_incoming += credits;
va009039 0:1ed23ab1345f 1835
va009039 0:1ed23ab1345f 1836 // process
va009039 0:1ed23ab1345f 1837 rfcomm_run();
va009039 0:1ed23ab1345f 1838 }
va009039 0:1ed23ab1345f 1839
va009039 0:1ed23ab1345f 1840 //
va009039 0:1ed23ab1345f 1841 void rfcomm_close_connection(void *connection){
va009039 0:1ed23ab1345f 1842 linked_item_t *it;
va009039 0:1ed23ab1345f 1843
va009039 0:1ed23ab1345f 1844 // close open channels
va009039 0:1ed23ab1345f 1845 for (it = (linked_item_t *) rfcomm_channels; it ; it = it->next){
va009039 0:1ed23ab1345f 1846 rfcomm_channel_t * channel = (rfcomm_channel_t *)it;
va009039 0:1ed23ab1345f 1847 if (channel->connection != connection) continue;
va009039 0:1ed23ab1345f 1848 channel->state = RFCOMM_CHANNEL_SEND_DISC;
va009039 0:1ed23ab1345f 1849 }
va009039 0:1ed23ab1345f 1850
va009039 0:1ed23ab1345f 1851 // unregister services
va009039 0:1ed23ab1345f 1852 it = (linked_item_t *) &rfcomm_services;
va009039 0:1ed23ab1345f 1853 while (it->next) {
va009039 0:1ed23ab1345f 1854 rfcomm_service_t * service = (rfcomm_service_t *) it->next;
va009039 0:1ed23ab1345f 1855 if (service->connection == connection){
va009039 0:1ed23ab1345f 1856 it->next = it->next->next;
va009039 0:1ed23ab1345f 1857 btstack_memory_rfcomm_service_free(service);
va009039 0:1ed23ab1345f 1858 } else {
va009039 0:1ed23ab1345f 1859 it = it->next;
va009039 0:1ed23ab1345f 1860 }
va009039 0:1ed23ab1345f 1861 }
va009039 0:1ed23ab1345f 1862
va009039 0:1ed23ab1345f 1863 // process
va009039 0:1ed23ab1345f 1864 rfcomm_run();
va009039 0:1ed23ab1345f 1865 }
va009039 0:1ed23ab1345f 1866
va009039 0:1ed23ab1345f 1867
va009039 0:1ed23ab1345f 1868
va009039 0:1ed23ab1345f 1869