1*3deb3ec6SMatthias Ringwald /* 2*3deb3ec6SMatthias Ringwald * Copyright (C) 2014 BlueKitchen GmbH 3*3deb3ec6SMatthias Ringwald * 4*3deb3ec6SMatthias Ringwald * Redistribution and use in source and binary forms, with or without 5*3deb3ec6SMatthias Ringwald * modification, are permitted provided that the following conditions 6*3deb3ec6SMatthias Ringwald * are met: 7*3deb3ec6SMatthias Ringwald * 8*3deb3ec6SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 9*3deb3ec6SMatthias Ringwald * notice, this list of conditions and the following disclaimer. 10*3deb3ec6SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11*3deb3ec6SMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 12*3deb3ec6SMatthias Ringwald * documentation and/or other materials provided with the distribution. 13*3deb3ec6SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 14*3deb3ec6SMatthias Ringwald * contributors may be used to endorse or promote products derived 15*3deb3ec6SMatthias Ringwald * from this software without specific prior written permission. 16*3deb3ec6SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 17*3deb3ec6SMatthias Ringwald * personal benefit and not for any commercial purpose or for 18*3deb3ec6SMatthias Ringwald * monetary gain. 19*3deb3ec6SMatthias Ringwald * 20*3deb3ec6SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21*3deb3ec6SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22*3deb3ec6SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23*3deb3ec6SMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24*3deb3ec6SMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25*3deb3ec6SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26*3deb3ec6SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27*3deb3ec6SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28*3deb3ec6SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29*3deb3ec6SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30*3deb3ec6SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31*3deb3ec6SMatthias Ringwald * SUCH DAMAGE. 32*3deb3ec6SMatthias Ringwald * 33*3deb3ec6SMatthias Ringwald * Please inquire about commercial licensing options at 34*3deb3ec6SMatthias Ringwald * [email protected] 35*3deb3ec6SMatthias Ringwald * 36*3deb3ec6SMatthias Ringwald */ 37*3deb3ec6SMatthias Ringwald 38*3deb3ec6SMatthias Ringwald /* 39*3deb3ec6SMatthias Ringwald * RFCOMM.h 40*3deb3ec6SMatthias Ringwald */ 41*3deb3ec6SMatthias Ringwald 42*3deb3ec6SMatthias Ringwald #ifndef __RFCOMM_H 43*3deb3ec6SMatthias Ringwald #define __RFCOMM_H 44*3deb3ec6SMatthias Ringwald 45*3deb3ec6SMatthias Ringwald #include "utils.h" 46*3deb3ec6SMatthias Ringwald 47*3deb3ec6SMatthias Ringwald #include <stdint.h> 48*3deb3ec6SMatthias Ringwald 49*3deb3ec6SMatthias Ringwald #if defined __cplusplus 50*3deb3ec6SMatthias Ringwald extern "C" { 51*3deb3ec6SMatthias Ringwald #endif 52*3deb3ec6SMatthias Ringwald 53*3deb3ec6SMatthias Ringwald #define UNLIMITED_INCOMING_CREDITS 0xff 54*3deb3ec6SMatthias Ringwald 55*3deb3ec6SMatthias Ringwald #define RFCOMM_TEST_DATA_MAX_LEN 4 56*3deb3ec6SMatthias Ringwald 57*3deb3ec6SMatthias Ringwald #define RFCOMM_RLS_STATUS_INVALID 0xff 58*3deb3ec6SMatthias Ringwald 59*3deb3ec6SMatthias Ringwald // Line Status 60*3deb3ec6SMatthias Ringwald #define LINE_STATUS_NO_ERROR 0x00 61*3deb3ec6SMatthias Ringwald #define LINE_STATUS_OVERRUN_ERROR 0x03 62*3deb3ec6SMatthias Ringwald #define LINE_STATUS_PARITY_ERORR 0x05 63*3deb3ec6SMatthias Ringwald #define LINE_STATUS_FRAMING_ERROR 0x09 64*3deb3ec6SMatthias Ringwald 65*3deb3ec6SMatthias Ringwald // Modem Status Flags 66*3deb3ec6SMatthias Ringwald #define MODEM_STATUS_FC 0x02 67*3deb3ec6SMatthias Ringwald #define MODEM_STATUS_RTC 0x04 68*3deb3ec6SMatthias Ringwald #define MODEM_STATUS_RTR 0x08 69*3deb3ec6SMatthias Ringwald #define MODEM_STATUS_IC 0x40 70*3deb3ec6SMatthias Ringwald #define MODEM_STATUS_DV 0x80 71*3deb3ec6SMatthias Ringwald 72*3deb3ec6SMatthias Ringwald typedef enum rpn_baud { 73*3deb3ec6SMatthias Ringwald RPN_BAUD_2400 = 0, 74*3deb3ec6SMatthias Ringwald RPN_BAUD_4800, 75*3deb3ec6SMatthias Ringwald RPN_BAUD_7200, 76*3deb3ec6SMatthias Ringwald RPN_BAUD_9600, 77*3deb3ec6SMatthias Ringwald RPN_BAUD_19200, 78*3deb3ec6SMatthias Ringwald RPN_BAUD_38400, 79*3deb3ec6SMatthias Ringwald RPN_BAUD_57600, 80*3deb3ec6SMatthias Ringwald RPN_BAUD_115200, 81*3deb3ec6SMatthias Ringwald RPN_BAUD_230400 82*3deb3ec6SMatthias Ringwald } rpn_baud_t; 83*3deb3ec6SMatthias Ringwald 84*3deb3ec6SMatthias Ringwald typedef enum rpn_data_bits { 85*3deb3ec6SMatthias Ringwald RPN_DATA_BITS_5 = 0, 86*3deb3ec6SMatthias Ringwald RPN_DATA_BITS_6 = 0, 87*3deb3ec6SMatthias Ringwald RPN_DATA_BITS_7 = 0, 88*3deb3ec6SMatthias Ringwald RPN_DATA_BITS_8 = 0 89*3deb3ec6SMatthias Ringwald } rpn_data_bits_t; 90*3deb3ec6SMatthias Ringwald 91*3deb3ec6SMatthias Ringwald typedef enum rpn_stop_bits { 92*3deb3ec6SMatthias Ringwald RPN_STOP_BITS_1_0 = 0, 93*3deb3ec6SMatthias Ringwald RPN_STOP_BITS_1_5 94*3deb3ec6SMatthias Ringwald } rpn_stop_bits_t; 95*3deb3ec6SMatthias Ringwald 96*3deb3ec6SMatthias Ringwald typedef enum rpn_parity { 97*3deb3ec6SMatthias Ringwald RPN_PARITY_NONE = 0, 98*3deb3ec6SMatthias Ringwald RPN_PARITY_ODD = 1, 99*3deb3ec6SMatthias Ringwald RPN_PARITY_EVEN = 3, 100*3deb3ec6SMatthias Ringwald RPN_PARITY_MARK = 5, 101*3deb3ec6SMatthias Ringwald RPN_PARITY_SPACE = 7, 102*3deb3ec6SMatthias Ringwald } rpn_parity_t; 103*3deb3ec6SMatthias Ringwald 104*3deb3ec6SMatthias Ringwald typedef enum rpn_flow_control { 105*3deb3ec6SMatthias Ringwald RPN_FLOW_CONTROL_XONXOFF_ON_INPUT = 1 << 0, 106*3deb3ec6SMatthias Ringwald RPN_FLOW_CONTROL_XONXOFF_ON_OUTPUT = 1 << 1, 107*3deb3ec6SMatthias Ringwald RPN_FLOW_CONTROL_RTR_ON_INPUT = 1 << 2, 108*3deb3ec6SMatthias Ringwald RPN_FLOW_CONTROL_RTR_ON_OUTPUT = 1 << 3, 109*3deb3ec6SMatthias Ringwald RPN_FLOW_CONTROL_RTC_ON_INPUT = 1 << 4, 110*3deb3ec6SMatthias Ringwald RPN_FLOW_CONTROL_RTC_ON_OUTPUT = 1 << 5, 111*3deb3ec6SMatthias Ringwald } rpn_flow_control_t; 112*3deb3ec6SMatthias Ringwald 113*3deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_0_BAUD 0x01 114*3deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_0_DATA_BITS 0x02 115*3deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_0_STOP_BITS 0x04 116*3deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_0_PARITY 0x08 117*3deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_0_PARITY_TYPE 0x10 118*3deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_0_XON_CHAR 0x20 119*3deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_0_XOFF_CHAR 0x40 120*3deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_0_RESERVED 0x80 121*3deb3ec6SMatthias Ringwald 122*3deb3ec6SMatthias Ringwald // @note: values are identical to rpn_flow_control_t 123*3deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_1_XONOFF_ON_INPUT 0x01 124*3deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_1_XONOFF_ON_OUTPUT 0x02 125*3deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_1_RTR_ON_INPUT 0x04 126*3deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_1_RTR_ON_OUTPUT 0x08 127*3deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_1_RTC_ON_INPUT 0x10 128*3deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_1_RTC_ON_OUTPUT 0x20 129*3deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_1_RESERVED_0 0x40 130*3deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_1_RESERVED_1 0x80 131*3deb3ec6SMatthias Ringwald 132*3deb3ec6SMatthias Ringwald 133*3deb3ec6SMatthias Ringwald // private structs 134*3deb3ec6SMatthias Ringwald typedef enum { 135*3deb3ec6SMatthias Ringwald RFCOMM_MULTIPLEXER_CLOSED = 1, 136*3deb3ec6SMatthias Ringwald RFCOMM_MULTIPLEXER_W4_CONNECT, // outgoing 137*3deb3ec6SMatthias Ringwald RFCOMM_MULTIPLEXER_SEND_SABM_0, // " 138*3deb3ec6SMatthias Ringwald RFCOMM_MULTIPLEXER_W4_UA_0, // " 139*3deb3ec6SMatthias Ringwald RFCOMM_MULTIPLEXER_W4_SABM_0, // incoming 140*3deb3ec6SMatthias Ringwald RFCOMM_MULTIPLEXER_SEND_UA_0, 141*3deb3ec6SMatthias Ringwald RFCOMM_MULTIPLEXER_OPEN, 142*3deb3ec6SMatthias Ringwald RFCOMM_MULTIPLEXER_SEND_UA_0_AND_DISC 143*3deb3ec6SMatthias Ringwald } RFCOMM_MULTIPLEXER_STATE; 144*3deb3ec6SMatthias Ringwald 145*3deb3ec6SMatthias Ringwald typedef enum { 146*3deb3ec6SMatthias Ringwald MULT_EV_READY_TO_SEND = 1, 147*3deb3ec6SMatthias Ringwald 148*3deb3ec6SMatthias Ringwald } RFCOMM_MULTIPLEXER_EVENT; 149*3deb3ec6SMatthias Ringwald 150*3deb3ec6SMatthias Ringwald typedef enum { 151*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_CLOSED = 1, 152*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_W4_MULTIPLEXER, 153*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_SEND_UIH_PN, 154*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_W4_PN_RSP, 155*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_SEND_SABM_W4_UA, 156*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_W4_UA, 157*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_INCOMING_SETUP, 158*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_DLC_SETUP, 159*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_OPEN, 160*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_SEND_UA_AFTER_DISC, 161*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_SEND_DISC, 162*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_W4_UA_AFTER_UA, 163*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_SEND_DM, 164*3deb3ec6SMatthias Ringwald 165*3deb3ec6SMatthias Ringwald } RFCOMM_CHANNEL_STATE; 166*3deb3ec6SMatthias Ringwald 167*3deb3ec6SMatthias Ringwald typedef enum { 168*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_STATE_VAR_NONE = 0, 169*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_STATE_VAR_CLIENT_ACCEPTED = 1 << 0, 170*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_STATE_VAR_RCVD_PN = 1 << 1, 171*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_STATE_VAR_RCVD_RPN = 1 << 2, 172*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_STATE_VAR_RCVD_SABM = 1 << 3, 173*3deb3ec6SMatthias Ringwald 174*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_STATE_VAR_RCVD_MSC_CMD = 1 << 4, 175*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_STATE_VAR_RCVD_MSC_RSP = 1 << 5, 176*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_STATE_VAR_SEND_PN_RSP = 1 << 6, 177*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_STATE_VAR_SEND_RPN_INFO = 1 << 7, 178*3deb3ec6SMatthias Ringwald 179*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_STATE_VAR_SEND_RPN_RSP = 1 << 8, 180*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_STATE_VAR_SEND_UA = 1 << 9, 181*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_CMD = 1 << 10, 182*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_RSP = 1 << 11, 183*3deb3ec6SMatthias Ringwald 184*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_STATE_VAR_SEND_CREDITS = 1 << 12, 185*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_STATE_VAR_SENT_MSC_CMD = 1 << 13, 186*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_STATE_VAR_SENT_MSC_RSP = 1 << 14, 187*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_STATE_VAR_SENT_CREDITS = 1 << 15, 188*3deb3ec6SMatthias Ringwald } RFCOMM_CHANNEL_STATE_VAR; 189*3deb3ec6SMatthias Ringwald 190*3deb3ec6SMatthias Ringwald typedef enum { 191*3deb3ec6SMatthias Ringwald CH_EVT_RCVD_SABM = 1, 192*3deb3ec6SMatthias Ringwald CH_EVT_RCVD_UA, 193*3deb3ec6SMatthias Ringwald CH_EVT_RCVD_PN, 194*3deb3ec6SMatthias Ringwald CH_EVT_RCVD_PN_RSP, 195*3deb3ec6SMatthias Ringwald CH_EVT_RCVD_DISC, 196*3deb3ec6SMatthias Ringwald CH_EVT_RCVD_DM, 197*3deb3ec6SMatthias Ringwald CH_EVT_RCVD_MSC_CMD, 198*3deb3ec6SMatthias Ringwald CH_EVT_RCVD_MSC_RSP, 199*3deb3ec6SMatthias Ringwald CH_EVT_RCVD_NSC_RSP, 200*3deb3ec6SMatthias Ringwald CH_EVT_RCVD_RLS_CMD, 201*3deb3ec6SMatthias Ringwald CH_EVT_RCVD_RLS_RSP, 202*3deb3ec6SMatthias Ringwald CH_EVT_RCVD_RPN_CMD, 203*3deb3ec6SMatthias Ringwald CH_EVT_RCVD_RPN_REQ, 204*3deb3ec6SMatthias Ringwald CH_EVT_RCVD_CREDITS, 205*3deb3ec6SMatthias Ringwald CH_EVT_MULTIPLEXER_READY, 206*3deb3ec6SMatthias Ringwald CH_EVT_READY_TO_SEND, 207*3deb3ec6SMatthias Ringwald } RFCOMM_CHANNEL_EVENT; 208*3deb3ec6SMatthias Ringwald 209*3deb3ec6SMatthias Ringwald typedef struct rfcomm_channel_event { 210*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_EVENT type; 211*3deb3ec6SMatthias Ringwald uint16_t dummy; // force rfcomm_channel_event to be 2-byte aligned -> avoid -Wcast-align warning 212*3deb3ec6SMatthias Ringwald } rfcomm_channel_event_t; 213*3deb3ec6SMatthias Ringwald 214*3deb3ec6SMatthias Ringwald typedef struct rfcomm_channel_event_pn { 215*3deb3ec6SMatthias Ringwald rfcomm_channel_event_t super; 216*3deb3ec6SMatthias Ringwald uint16_t max_frame_size; 217*3deb3ec6SMatthias Ringwald uint8_t priority; 218*3deb3ec6SMatthias Ringwald uint8_t credits_outgoing; 219*3deb3ec6SMatthias Ringwald } rfcomm_channel_event_pn_t; 220*3deb3ec6SMatthias Ringwald 221*3deb3ec6SMatthias Ringwald typedef struct rfcomm_rpn_data { 222*3deb3ec6SMatthias Ringwald uint8_t baud_rate; 223*3deb3ec6SMatthias Ringwald uint8_t flags; 224*3deb3ec6SMatthias Ringwald uint8_t flow_control; 225*3deb3ec6SMatthias Ringwald uint8_t xon; 226*3deb3ec6SMatthias Ringwald uint8_t xoff; 227*3deb3ec6SMatthias Ringwald uint8_t parameter_mask_0; // first byte 228*3deb3ec6SMatthias Ringwald uint8_t parameter_mask_1; // second byte 229*3deb3ec6SMatthias Ringwald } rfcomm_rpn_data_t; 230*3deb3ec6SMatthias Ringwald 231*3deb3ec6SMatthias Ringwald typedef struct rfcomm_channel_event_rpn { 232*3deb3ec6SMatthias Ringwald rfcomm_channel_event_t super; 233*3deb3ec6SMatthias Ringwald rfcomm_rpn_data_t data; 234*3deb3ec6SMatthias Ringwald } rfcomm_channel_event_rpn_t; 235*3deb3ec6SMatthias Ringwald 236*3deb3ec6SMatthias Ringwald typedef struct rfcomm_channel_event_rls { 237*3deb3ec6SMatthias Ringwald rfcomm_channel_event_t super; 238*3deb3ec6SMatthias Ringwald uint8_t line_status; 239*3deb3ec6SMatthias Ringwald } rfcomm_channel_event_rls_t; 240*3deb3ec6SMatthias Ringwald 241*3deb3ec6SMatthias Ringwald typedef struct rfcomm_channel_event_msc { 242*3deb3ec6SMatthias Ringwald rfcomm_channel_event_t super; 243*3deb3ec6SMatthias Ringwald uint8_t modem_status; 244*3deb3ec6SMatthias Ringwald } rfcomm_channel_event_msc_t; 245*3deb3ec6SMatthias Ringwald 246*3deb3ec6SMatthias Ringwald // info regarding potential connections 247*3deb3ec6SMatthias Ringwald typedef struct { 248*3deb3ec6SMatthias Ringwald // linked list - assert: first field 249*3deb3ec6SMatthias Ringwald linked_item_t item; 250*3deb3ec6SMatthias Ringwald 251*3deb3ec6SMatthias Ringwald // server channel 252*3deb3ec6SMatthias Ringwald uint8_t server_channel; 253*3deb3ec6SMatthias Ringwald 254*3deb3ec6SMatthias Ringwald // incoming max frame size 255*3deb3ec6SMatthias Ringwald uint16_t max_frame_size; 256*3deb3ec6SMatthias Ringwald 257*3deb3ec6SMatthias Ringwald // use incoming flow control 258*3deb3ec6SMatthias Ringwald uint8_t incoming_flow_control; 259*3deb3ec6SMatthias Ringwald 260*3deb3ec6SMatthias Ringwald // initial incoming credits 261*3deb3ec6SMatthias Ringwald uint8_t incoming_initial_credits; 262*3deb3ec6SMatthias Ringwald 263*3deb3ec6SMatthias Ringwald // client connection 264*3deb3ec6SMatthias Ringwald void *connection; 265*3deb3ec6SMatthias Ringwald 266*3deb3ec6SMatthias Ringwald // internal connection 267*3deb3ec6SMatthias Ringwald btstack_packet_handler_t packet_handler; 268*3deb3ec6SMatthias Ringwald 269*3deb3ec6SMatthias Ringwald } rfcomm_service_t; 270*3deb3ec6SMatthias Ringwald 271*3deb3ec6SMatthias Ringwald // info regarding multiplexer 272*3deb3ec6SMatthias Ringwald // note: spec mandates single multiplexer per device combination 273*3deb3ec6SMatthias Ringwald typedef struct { 274*3deb3ec6SMatthias Ringwald // linked list - assert: first field 275*3deb3ec6SMatthias Ringwald linked_item_t item; 276*3deb3ec6SMatthias Ringwald 277*3deb3ec6SMatthias Ringwald timer_source_t timer; 278*3deb3ec6SMatthias Ringwald int timer_active; 279*3deb3ec6SMatthias Ringwald 280*3deb3ec6SMatthias Ringwald RFCOMM_MULTIPLEXER_STATE state; 281*3deb3ec6SMatthias Ringwald 282*3deb3ec6SMatthias Ringwald uint16_t l2cap_cid; 283*3deb3ec6SMatthias Ringwald uint8_t l2cap_credits; 284*3deb3ec6SMatthias Ringwald 285*3deb3ec6SMatthias Ringwald uint8_t fcon; // only send if fcon & 1, send rsp if fcon & 0x80 286*3deb3ec6SMatthias Ringwald 287*3deb3ec6SMatthias Ringwald bd_addr_t remote_addr; 288*3deb3ec6SMatthias Ringwald hci_con_handle_t con_handle; 289*3deb3ec6SMatthias Ringwald 290*3deb3ec6SMatthias Ringwald uint8_t outgoing; 291*3deb3ec6SMatthias Ringwald 292*3deb3ec6SMatthias Ringwald // hack to deal with authentication failure only observed by remote side 293*3deb3ec6SMatthias Ringwald uint8_t at_least_one_connection; 294*3deb3ec6SMatthias Ringwald 295*3deb3ec6SMatthias Ringwald uint16_t max_frame_size; 296*3deb3ec6SMatthias Ringwald 297*3deb3ec6SMatthias Ringwald // send DM for DLCI != 0 298*3deb3ec6SMatthias Ringwald uint8_t send_dm_for_dlci; 299*3deb3ec6SMatthias Ringwald 300*3deb3ec6SMatthias Ringwald // non supported command, 0 if not set 301*3deb3ec6SMatthias Ringwald uint8_t nsc_command; 302*3deb3ec6SMatthias Ringwald 303*3deb3ec6SMatthias Ringwald // test data - limited to RFCOMM_TEST_DATA_MAX_LEN 304*3deb3ec6SMatthias Ringwald uint8_t test_data_len; 305*3deb3ec6SMatthias Ringwald uint8_t test_data[RFCOMM_TEST_DATA_MAX_LEN]; 306*3deb3ec6SMatthias Ringwald 307*3deb3ec6SMatthias Ringwald } rfcomm_multiplexer_t; 308*3deb3ec6SMatthias Ringwald 309*3deb3ec6SMatthias Ringwald // info regarding an actual connection 310*3deb3ec6SMatthias Ringwald typedef struct { 311*3deb3ec6SMatthias Ringwald // linked list - assert: first field 312*3deb3ec6SMatthias Ringwald linked_item_t item; 313*3deb3ec6SMatthias Ringwald 314*3deb3ec6SMatthias Ringwald rfcomm_multiplexer_t *multiplexer; 315*3deb3ec6SMatthias Ringwald uint16_t rfcomm_cid; 316*3deb3ec6SMatthias Ringwald uint8_t outgoing; 317*3deb3ec6SMatthias Ringwald uint8_t dlci; 318*3deb3ec6SMatthias Ringwald 319*3deb3ec6SMatthias Ringwald // number of packets granted to client 320*3deb3ec6SMatthias Ringwald uint8_t packets_granted; 321*3deb3ec6SMatthias Ringwald 322*3deb3ec6SMatthias Ringwald // credits for outgoing traffic 323*3deb3ec6SMatthias Ringwald uint8_t credits_outgoing; 324*3deb3ec6SMatthias Ringwald 325*3deb3ec6SMatthias Ringwald // number of packets remote will be granted 326*3deb3ec6SMatthias Ringwald uint8_t new_credits_incoming; 327*3deb3ec6SMatthias Ringwald 328*3deb3ec6SMatthias Ringwald // credits for incoming traffic 329*3deb3ec6SMatthias Ringwald uint8_t credits_incoming; 330*3deb3ec6SMatthias Ringwald 331*3deb3ec6SMatthias Ringwald // use incoming flow control 332*3deb3ec6SMatthias Ringwald uint8_t incoming_flow_control; 333*3deb3ec6SMatthias Ringwald 334*3deb3ec6SMatthias Ringwald // channel state 335*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_STATE state; 336*3deb3ec6SMatthias Ringwald 337*3deb3ec6SMatthias Ringwald // state variables used in RFCOMM_CHANNEL_INCOMING 338*3deb3ec6SMatthias Ringwald RFCOMM_CHANNEL_STATE_VAR state_var; 339*3deb3ec6SMatthias Ringwald 340*3deb3ec6SMatthias Ringwald // priority set by incoming side in PN 341*3deb3ec6SMatthias Ringwald uint8_t pn_priority; 342*3deb3ec6SMatthias Ringwald 343*3deb3ec6SMatthias Ringwald // negotiated frame size 344*3deb3ec6SMatthias Ringwald uint16_t max_frame_size; 345*3deb3ec6SMatthias Ringwald 346*3deb3ec6SMatthias Ringwald // local rpn data 347*3deb3ec6SMatthias Ringwald rfcomm_rpn_data_t rpn_data; 348*3deb3ec6SMatthias Ringwald 349*3deb3ec6SMatthias Ringwald // rls line status. RFCOMM_RLS_STATUS_INVALID if not set 350*3deb3ec6SMatthias Ringwald uint8_t rls_line_status; 351*3deb3ec6SMatthias Ringwald 352*3deb3ec6SMatthias Ringwald // msc modem status. 353*3deb3ec6SMatthias Ringwald uint8_t msc_modem_status; 354*3deb3ec6SMatthias Ringwald 355*3deb3ec6SMatthias Ringwald // server channel (see rfcomm_service_t) - NULL => outgoing channel 356*3deb3ec6SMatthias Ringwald rfcomm_service_t * service; 357*3deb3ec6SMatthias Ringwald 358*3deb3ec6SMatthias Ringwald // internal connection 359*3deb3ec6SMatthias Ringwald btstack_packet_handler_t packet_handler; 360*3deb3ec6SMatthias Ringwald 361*3deb3ec6SMatthias Ringwald // client connection 362*3deb3ec6SMatthias Ringwald void * connection; 363*3deb3ec6SMatthias Ringwald 364*3deb3ec6SMatthias Ringwald } rfcomm_channel_t; 365*3deb3ec6SMatthias Ringwald 366*3deb3ec6SMatthias Ringwald void rfcomm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); 367*3deb3ec6SMatthias Ringwald 368*3deb3ec6SMatthias Ringwald /* API_START */ 369*3deb3ec6SMatthias Ringwald 370*3deb3ec6SMatthias Ringwald /** 371*3deb3ec6SMatthias Ringwald * @brief Set up RFCOMM. 372*3deb3ec6SMatthias Ringwald */ 373*3deb3ec6SMatthias Ringwald void rfcomm_init(void); 374*3deb3ec6SMatthias Ringwald 375*3deb3ec6SMatthias Ringwald /** 376*3deb3ec6SMatthias Ringwald * @brief Set security level required for incoming connections, need to be called before registering services. 377*3deb3ec6SMatthias Ringwald */ 378*3deb3ec6SMatthias Ringwald void rfcomm_set_required_security_level(gap_security_level_t security_level); 379*3deb3ec6SMatthias Ringwald 380*3deb3ec6SMatthias Ringwald /** 381*3deb3ec6SMatthias Ringwald * @brief Register packet handler. 382*3deb3ec6SMatthias Ringwald */ 383*3deb3ec6SMatthias Ringwald void rfcomm_register_packet_handler(void (*handler)(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)); 384*3deb3ec6SMatthias Ringwald 385*3deb3ec6SMatthias Ringwald /** 386*3deb3ec6SMatthias Ringwald * @brief Creates RFCOMM connection (channel) to a given server channel on a remote device with baseband address. A new baseband connection will be initiated if necessary. This channel will automatically provide enough credits to the remote side 387*3deb3ec6SMatthias Ringwald */ 388*3deb3ec6SMatthias Ringwald void rfcomm_create_channel_internal(void * connection, bd_addr_t addr, uint8_t channel); 389*3deb3ec6SMatthias Ringwald 390*3deb3ec6SMatthias Ringwald /** 391*3deb3ec6SMatthias Ringwald * @brief Creates RFCOMM connection (channel) to a given server channel on a remote device with baseband address. new baseband connection will be initiated if necessary. This channel will use explicit credit management. During channel establishment, an initial amount of credits is provided. 392*3deb3ec6SMatthias Ringwald */ 393*3deb3ec6SMatthias Ringwald void rfcomm_create_channel_with_initial_credits_internal(void * connection, bd_addr_t addr, uint8_t server_channel, uint8_t initial_credits); 394*3deb3ec6SMatthias Ringwald 395*3deb3ec6SMatthias Ringwald /** 396*3deb3ec6SMatthias Ringwald * @brief Disconnects RFCOMM channel with given identifier. 397*3deb3ec6SMatthias Ringwald */ 398*3deb3ec6SMatthias Ringwald void rfcomm_disconnect_internal(uint16_t rfcomm_cid); 399*3deb3ec6SMatthias Ringwald 400*3deb3ec6SMatthias Ringwald /** 401*3deb3ec6SMatthias Ringwald * @brief Registers RFCOMM service for a server channel and a maximum frame size, and assigns a packet handler. On embedded systems, use NULL for connection parameter. This channel provides automatically enough credits to the remote side. 402*3deb3ec6SMatthias Ringwald */ 403*3deb3ec6SMatthias Ringwald void rfcomm_register_service_internal(void * connection, uint8_t channel, uint16_t max_frame_size); 404*3deb3ec6SMatthias Ringwald 405*3deb3ec6SMatthias Ringwald /** 406*3deb3ec6SMatthias Ringwald * @brief Registers RFCOMM service for a server channel and a maximum frame size, and assigns a packet handler. On embedded systems, use NULL for connection parameter. This channel will use explicit credit management. During channel establishment, an initial amount of credits is provided. 407*3deb3ec6SMatthias Ringwald */ 408*3deb3ec6SMatthias Ringwald void rfcomm_register_service_with_initial_credits_internal(void * connection, uint8_t channel, uint16_t max_frame_size, uint8_t initial_credits); 409*3deb3ec6SMatthias Ringwald 410*3deb3ec6SMatthias Ringwald /** 411*3deb3ec6SMatthias Ringwald * @brief Unregister RFCOMM service. 412*3deb3ec6SMatthias Ringwald */ 413*3deb3ec6SMatthias Ringwald void rfcomm_unregister_service_internal(uint8_t service_channel); 414*3deb3ec6SMatthias Ringwald 415*3deb3ec6SMatthias Ringwald /** 416*3deb3ec6SMatthias Ringwald * @brief Accepts/Deny incoming RFCOMM connection. 417*3deb3ec6SMatthias Ringwald */ 418*3deb3ec6SMatthias Ringwald void rfcomm_accept_connection_internal(uint16_t rfcomm_cid); 419*3deb3ec6SMatthias Ringwald void rfcomm_decline_connection_internal(uint16_t rfcomm_cid); 420*3deb3ec6SMatthias Ringwald 421*3deb3ec6SMatthias Ringwald /** 422*3deb3ec6SMatthias Ringwald * @brief Grant more incoming credits to the remote side for the given RFCOMM channel identifier. 423*3deb3ec6SMatthias Ringwald */ 424*3deb3ec6SMatthias Ringwald void rfcomm_grant_credits(uint16_t rfcomm_cid, uint8_t credits); 425*3deb3ec6SMatthias Ringwald 426*3deb3ec6SMatthias Ringwald /** 427*3deb3ec6SMatthias Ringwald * @brief Checks if RFCOMM can send packet. Returns yes if packet can be sent. 428*3deb3ec6SMatthias Ringwald */ 429*3deb3ec6SMatthias Ringwald int rfcomm_can_send_packet_now(uint16_t rfcomm_cid); 430*3deb3ec6SMatthias Ringwald 431*3deb3ec6SMatthias Ringwald /** 432*3deb3ec6SMatthias Ringwald * @brief Sends RFCOMM data packet to the RFCOMM channel with given identifier. 433*3deb3ec6SMatthias Ringwald */ 434*3deb3ec6SMatthias Ringwald int rfcomm_send_internal(uint16_t rfcomm_cid, uint8_t *data, uint16_t len); 435*3deb3ec6SMatthias Ringwald 436*3deb3ec6SMatthias Ringwald /** 437*3deb3ec6SMatthias Ringwald * @brief Sends Local Line Status, see LINE_STATUS_.. 438*3deb3ec6SMatthias Ringwald */ 439*3deb3ec6SMatthias Ringwald int rfcomm_send_local_line_status(uint16_t rfcomm_cid, uint8_t line_status); 440*3deb3ec6SMatthias Ringwald 441*3deb3ec6SMatthias Ringwald /** 442*3deb3ec6SMatthias Ringwald * @brief Send local modem status. see MODEM_STAUS_.. 443*3deb3ec6SMatthias Ringwald */ 444*3deb3ec6SMatthias Ringwald int rfcomm_send_modem_status(uint16_t rfcomm_cid, uint8_t modem_status); 445*3deb3ec6SMatthias Ringwald 446*3deb3ec6SMatthias Ringwald /** 447*3deb3ec6SMatthias Ringwald * @brief Configure remote port 448*3deb3ec6SMatthias Ringwald */ 449*3deb3ec6SMatthias Ringwald int rfcomm_send_port_configuration(uint16_t rfcomm_cid, rpn_baud_t baud_rate, rpn_data_bits_t data_bits, rpn_stop_bits_t stop_bits, rpn_parity_t parity, rpn_flow_control_t flow_control); 450*3deb3ec6SMatthias Ringwald 451*3deb3ec6SMatthias Ringwald /** 452*3deb3ec6SMatthias Ringwald * @brief Query remote port 453*3deb3ec6SMatthias Ringwald */ 454*3deb3ec6SMatthias Ringwald int rfcomm_query_port_configuration(uint16_t rfcomm_cid); 455*3deb3ec6SMatthias Ringwald 456*3deb3ec6SMatthias Ringwald /** 457*3deb3ec6SMatthias Ringwald * @brief Allow to create RFCOMM packet in outgoing buffer. 458*3deb3ec6SMatthias Ringwald */ 459*3deb3ec6SMatthias Ringwald int rfcomm_reserve_packet_buffer(void); 460*3deb3ec6SMatthias Ringwald void rfcomm_release_packet_buffer(void); 461*3deb3ec6SMatthias Ringwald uint8_t * rfcomm_get_outgoing_buffer(void); 462*3deb3ec6SMatthias Ringwald uint16_t rfcomm_get_max_frame_size(uint16_t rfcomm_cid); 463*3deb3ec6SMatthias Ringwald int rfcomm_send_prepared(uint16_t rfcomm_cid, uint16_t len); 464*3deb3ec6SMatthias Ringwald /* API_END */ 465*3deb3ec6SMatthias Ringwald 466*3deb3ec6SMatthias Ringwald #if defined __cplusplus 467*3deb3ec6SMatthias Ringwald } 468*3deb3ec6SMatthias Ringwald #endif 469*3deb3ec6SMatthias Ringwald 470*3deb3ec6SMatthias Ringwald #endif // __RFCOMM_H 471