xref: /btstack/src/classic/rfcomm.h (revision 5d1e858f3a5ea7e2387b1312b6c1e259b1e20e52)
13deb3ec6SMatthias Ringwald /*
23deb3ec6SMatthias Ringwald  * Copyright (C) 2014 BlueKitchen GmbH
33deb3ec6SMatthias Ringwald  *
43deb3ec6SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
53deb3ec6SMatthias Ringwald  * modification, are permitted provided that the following conditions
63deb3ec6SMatthias Ringwald  * are met:
73deb3ec6SMatthias Ringwald  *
83deb3ec6SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
93deb3ec6SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
103deb3ec6SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
113deb3ec6SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
123deb3ec6SMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
133deb3ec6SMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
143deb3ec6SMatthias Ringwald  *    contributors may be used to endorse or promote products derived
153deb3ec6SMatthias Ringwald  *    from this software without specific prior written permission.
163deb3ec6SMatthias Ringwald  * 4. Any redistribution, use, or modification is done solely for
173deb3ec6SMatthias Ringwald  *    personal benefit and not for any commercial purpose or for
183deb3ec6SMatthias Ringwald  *    monetary gain.
193deb3ec6SMatthias Ringwald  *
203deb3ec6SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
213deb3ec6SMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
223deb3ec6SMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
233deb3ec6SMatthias Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
243deb3ec6SMatthias Ringwald  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
253deb3ec6SMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
263deb3ec6SMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
273deb3ec6SMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
283deb3ec6SMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
293deb3ec6SMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
303deb3ec6SMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
313deb3ec6SMatthias Ringwald  * SUCH DAMAGE.
323deb3ec6SMatthias Ringwald  *
333deb3ec6SMatthias Ringwald  * Please inquire about commercial licensing options at
343deb3ec6SMatthias Ringwald  * [email protected]
353deb3ec6SMatthias Ringwald  *
363deb3ec6SMatthias Ringwald  */
373deb3ec6SMatthias Ringwald 
383deb3ec6SMatthias Ringwald /*
393deb3ec6SMatthias Ringwald  *  RFCOMM.h
403deb3ec6SMatthias Ringwald  */
413deb3ec6SMatthias Ringwald 
423deb3ec6SMatthias Ringwald #ifndef __RFCOMM_H
433deb3ec6SMatthias Ringwald #define __RFCOMM_H
443deb3ec6SMatthias Ringwald 
453deb3ec6SMatthias Ringwald #include "utils.h"
463deb3ec6SMatthias Ringwald 
473deb3ec6SMatthias Ringwald #include <stdint.h>
483deb3ec6SMatthias Ringwald 
493deb3ec6SMatthias Ringwald #if defined __cplusplus
503deb3ec6SMatthias Ringwald extern "C" {
513deb3ec6SMatthias Ringwald #endif
523deb3ec6SMatthias Ringwald 
533deb3ec6SMatthias Ringwald #define UNLIMITED_INCOMING_CREDITS 0xff
543deb3ec6SMatthias Ringwald 
553deb3ec6SMatthias Ringwald #define RFCOMM_TEST_DATA_MAX_LEN 4
563deb3ec6SMatthias Ringwald 
573deb3ec6SMatthias Ringwald #define RFCOMM_RLS_STATUS_INVALID 0xff
583deb3ec6SMatthias Ringwald 
593deb3ec6SMatthias Ringwald // Line Status
603deb3ec6SMatthias Ringwald #define LINE_STATUS_NO_ERROR       0x00
613deb3ec6SMatthias Ringwald #define LINE_STATUS_OVERRUN_ERROR  0x03
623deb3ec6SMatthias Ringwald #define LINE_STATUS_PARITY_ERORR   0x05
633deb3ec6SMatthias Ringwald #define LINE_STATUS_FRAMING_ERROR  0x09
643deb3ec6SMatthias Ringwald 
653deb3ec6SMatthias Ringwald // Modem Status Flags
663deb3ec6SMatthias Ringwald #define MODEM_STATUS_FC   0x02
673deb3ec6SMatthias Ringwald #define MODEM_STATUS_RTC  0x04
683deb3ec6SMatthias Ringwald #define MODEM_STATUS_RTR  0x08
693deb3ec6SMatthias Ringwald #define MODEM_STATUS_IC   0x40
703deb3ec6SMatthias Ringwald #define MODEM_STATUS_DV   0x80
713deb3ec6SMatthias Ringwald 
723deb3ec6SMatthias Ringwald typedef enum rpn_baud {
733deb3ec6SMatthias Ringwald     RPN_BAUD_2400 = 0,
743deb3ec6SMatthias Ringwald     RPN_BAUD_4800,
753deb3ec6SMatthias Ringwald     RPN_BAUD_7200,
763deb3ec6SMatthias Ringwald     RPN_BAUD_9600,
773deb3ec6SMatthias Ringwald     RPN_BAUD_19200,
783deb3ec6SMatthias Ringwald     RPN_BAUD_38400,
793deb3ec6SMatthias Ringwald     RPN_BAUD_57600,
803deb3ec6SMatthias Ringwald     RPN_BAUD_115200,
813deb3ec6SMatthias Ringwald     RPN_BAUD_230400
823deb3ec6SMatthias Ringwald } rpn_baud_t;
833deb3ec6SMatthias Ringwald 
843deb3ec6SMatthias Ringwald typedef enum rpn_data_bits {
853deb3ec6SMatthias Ringwald     RPN_DATA_BITS_5 = 0,
863deb3ec6SMatthias Ringwald     RPN_DATA_BITS_6 = 0,
873deb3ec6SMatthias Ringwald     RPN_DATA_BITS_7 = 0,
883deb3ec6SMatthias Ringwald     RPN_DATA_BITS_8 = 0
893deb3ec6SMatthias Ringwald } rpn_data_bits_t;
903deb3ec6SMatthias Ringwald 
913deb3ec6SMatthias Ringwald typedef enum rpn_stop_bits {
923deb3ec6SMatthias Ringwald     RPN_STOP_BITS_1_0 = 0,
933deb3ec6SMatthias Ringwald     RPN_STOP_BITS_1_5
943deb3ec6SMatthias Ringwald } rpn_stop_bits_t;
953deb3ec6SMatthias Ringwald 
963deb3ec6SMatthias Ringwald typedef enum rpn_parity {
973deb3ec6SMatthias Ringwald     RPN_PARITY_NONE  = 0,
983deb3ec6SMatthias Ringwald     RPN_PARITY_ODD   = 1,
993deb3ec6SMatthias Ringwald     RPN_PARITY_EVEN  = 3,
1003deb3ec6SMatthias Ringwald     RPN_PARITY_MARK  = 5,
1013deb3ec6SMatthias Ringwald     RPN_PARITY_SPACE = 7,
1023deb3ec6SMatthias Ringwald } rpn_parity_t;
1033deb3ec6SMatthias Ringwald 
1043deb3ec6SMatthias Ringwald typedef enum rpn_flow_control {
1053deb3ec6SMatthias Ringwald     RPN_FLOW_CONTROL_XONXOFF_ON_INPUT  = 1 << 0,
1063deb3ec6SMatthias Ringwald     RPN_FLOW_CONTROL_XONXOFF_ON_OUTPUT = 1 << 1,
1073deb3ec6SMatthias Ringwald     RPN_FLOW_CONTROL_RTR_ON_INPUT  = 1 << 2,
1083deb3ec6SMatthias Ringwald     RPN_FLOW_CONTROL_RTR_ON_OUTPUT = 1 << 3,
1093deb3ec6SMatthias Ringwald     RPN_FLOW_CONTROL_RTC_ON_INPUT  = 1 << 4,
1103deb3ec6SMatthias Ringwald     RPN_FLOW_CONTROL_RTC_ON_OUTPUT = 1 << 5,
1113deb3ec6SMatthias Ringwald } rpn_flow_control_t;
1123deb3ec6SMatthias Ringwald 
1133deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_0_BAUD             0x01
1143deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_0_DATA_BITS        0x02
1153deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_0_STOP_BITS        0x04
1163deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_0_PARITY           0x08
1173deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_0_PARITY_TYPE      0x10
1183deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_0_XON_CHAR         0x20
1193deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_0_XOFF_CHAR        0x40
1203deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_0_RESERVED         0x80
1213deb3ec6SMatthias Ringwald 
1223deb3ec6SMatthias Ringwald // @note: values are identical to rpn_flow_control_t
1233deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_1_XONOFF_ON_INPUT  0x01
1243deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_1_XONOFF_ON_OUTPUT 0x02
1253deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_1_RTR_ON_INPUT     0x04
1263deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_1_RTR_ON_OUTPUT    0x08
1273deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_1_RTC_ON_INPUT     0x10
1283deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_1_RTC_ON_OUTPUT    0x20
1293deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_1_RESERVED_0       0x40
1303deb3ec6SMatthias Ringwald #define RPN_PARAM_MASK_1_RESERVED_1       0x80
1313deb3ec6SMatthias Ringwald 
1323deb3ec6SMatthias Ringwald 
1333deb3ec6SMatthias Ringwald // private structs
1343deb3ec6SMatthias Ringwald typedef enum {
1353deb3ec6SMatthias Ringwald 	RFCOMM_MULTIPLEXER_CLOSED = 1,
1363deb3ec6SMatthias Ringwald 	RFCOMM_MULTIPLEXER_W4_CONNECT,  // outgoing
1373deb3ec6SMatthias Ringwald 	RFCOMM_MULTIPLEXER_SEND_SABM_0,     //    "
1383deb3ec6SMatthias Ringwald 	RFCOMM_MULTIPLEXER_W4_UA_0,     //    "
1393deb3ec6SMatthias Ringwald 	RFCOMM_MULTIPLEXER_W4_SABM_0,   // incoming
1403deb3ec6SMatthias Ringwald     RFCOMM_MULTIPLEXER_SEND_UA_0,
1413deb3ec6SMatthias Ringwald 	RFCOMM_MULTIPLEXER_OPEN,
1423deb3ec6SMatthias Ringwald     RFCOMM_MULTIPLEXER_SEND_UA_0_AND_DISC
1433deb3ec6SMatthias Ringwald } RFCOMM_MULTIPLEXER_STATE;
1443deb3ec6SMatthias Ringwald 
1453deb3ec6SMatthias Ringwald typedef enum {
1463deb3ec6SMatthias Ringwald     MULT_EV_READY_TO_SEND = 1,
1473deb3ec6SMatthias Ringwald 
1483deb3ec6SMatthias Ringwald } RFCOMM_MULTIPLEXER_EVENT;
1493deb3ec6SMatthias Ringwald 
1503deb3ec6SMatthias Ringwald typedef enum {
1513deb3ec6SMatthias Ringwald 	RFCOMM_CHANNEL_CLOSED = 1,
1523deb3ec6SMatthias Ringwald 	RFCOMM_CHANNEL_W4_MULTIPLEXER,
1533deb3ec6SMatthias Ringwald 	RFCOMM_CHANNEL_SEND_UIH_PN,
1543deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_W4_PN_RSP,
1553deb3ec6SMatthias Ringwald 	RFCOMM_CHANNEL_SEND_SABM_W4_UA,
1563deb3ec6SMatthias Ringwald 	RFCOMM_CHANNEL_W4_UA,
1573deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_INCOMING_SETUP,
1583deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_DLC_SETUP,
1593deb3ec6SMatthias Ringwald 	RFCOMM_CHANNEL_OPEN,
1603deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_SEND_UA_AFTER_DISC,
1613deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_SEND_DISC,
1623deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_W4_UA_AFTER_UA,
1633deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_SEND_DM,
1643deb3ec6SMatthias Ringwald 
1653deb3ec6SMatthias Ringwald } RFCOMM_CHANNEL_STATE;
1663deb3ec6SMatthias Ringwald 
1673deb3ec6SMatthias Ringwald typedef enum {
1683deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_STATE_VAR_NONE            = 0,
1693deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_STATE_VAR_CLIENT_ACCEPTED = 1 << 0,
1703deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_STATE_VAR_RCVD_PN         = 1 << 1,
1713deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_STATE_VAR_RCVD_RPN        = 1 << 2,
1723deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_STATE_VAR_RCVD_SABM       = 1 << 3,
1733deb3ec6SMatthias Ringwald 
1743deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_STATE_VAR_RCVD_MSC_CMD    = 1 << 4,
1753deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_STATE_VAR_RCVD_MSC_RSP    = 1 << 5,
1763deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_STATE_VAR_SEND_PN_RSP     = 1 << 6,
1773deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_STATE_VAR_SEND_RPN_INFO   = 1 << 7,
1783deb3ec6SMatthias Ringwald 
1793deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_STATE_VAR_SEND_RPN_RSP    = 1 << 8,
1803deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_STATE_VAR_SEND_UA         = 1 << 9,
1813deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_CMD    = 1 << 10,
1823deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_RSP    = 1 << 11,
1833deb3ec6SMatthias Ringwald 
1843deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_STATE_VAR_SEND_CREDITS    = 1 << 12,
1853deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_STATE_VAR_SENT_MSC_CMD    = 1 << 13,
1863deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_STATE_VAR_SENT_MSC_RSP    = 1 << 14,
1873deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_STATE_VAR_SENT_CREDITS    = 1 << 15,
1883deb3ec6SMatthias Ringwald } RFCOMM_CHANNEL_STATE_VAR;
1893deb3ec6SMatthias Ringwald 
1903deb3ec6SMatthias Ringwald typedef enum {
1913deb3ec6SMatthias Ringwald     CH_EVT_RCVD_SABM = 1,
1923deb3ec6SMatthias Ringwald     CH_EVT_RCVD_UA,
1933deb3ec6SMatthias Ringwald     CH_EVT_RCVD_PN,
1943deb3ec6SMatthias Ringwald     CH_EVT_RCVD_PN_RSP,
1953deb3ec6SMatthias Ringwald     CH_EVT_RCVD_DISC,
1963deb3ec6SMatthias Ringwald     CH_EVT_RCVD_DM,
1973deb3ec6SMatthias Ringwald     CH_EVT_RCVD_MSC_CMD,
1983deb3ec6SMatthias Ringwald     CH_EVT_RCVD_MSC_RSP,
1993deb3ec6SMatthias Ringwald     CH_EVT_RCVD_NSC_RSP,
2003deb3ec6SMatthias Ringwald     CH_EVT_RCVD_RLS_CMD,
2013deb3ec6SMatthias Ringwald     CH_EVT_RCVD_RLS_RSP,
2023deb3ec6SMatthias Ringwald     CH_EVT_RCVD_RPN_CMD,
2033deb3ec6SMatthias Ringwald     CH_EVT_RCVD_RPN_REQ,
2043deb3ec6SMatthias Ringwald     CH_EVT_RCVD_CREDITS,
2053deb3ec6SMatthias Ringwald     CH_EVT_MULTIPLEXER_READY,
2063deb3ec6SMatthias Ringwald     CH_EVT_READY_TO_SEND,
2073deb3ec6SMatthias Ringwald } RFCOMM_CHANNEL_EVENT;
2083deb3ec6SMatthias Ringwald 
2093deb3ec6SMatthias Ringwald typedef struct rfcomm_channel_event {
2103deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_EVENT type;
2113deb3ec6SMatthias Ringwald     uint16_t dummy; // force rfcomm_channel_event to be 2-byte aligned -> avoid -Wcast-align warning
2123deb3ec6SMatthias Ringwald } rfcomm_channel_event_t;
2133deb3ec6SMatthias Ringwald 
2143deb3ec6SMatthias Ringwald typedef struct rfcomm_channel_event_pn {
2153deb3ec6SMatthias Ringwald     rfcomm_channel_event_t super;
2163deb3ec6SMatthias Ringwald     uint16_t max_frame_size;
2173deb3ec6SMatthias Ringwald     uint8_t  priority;
2183deb3ec6SMatthias Ringwald     uint8_t  credits_outgoing;
2193deb3ec6SMatthias Ringwald } rfcomm_channel_event_pn_t;
2203deb3ec6SMatthias Ringwald 
2213deb3ec6SMatthias Ringwald typedef struct rfcomm_rpn_data {
2223deb3ec6SMatthias Ringwald     uint8_t baud_rate;
2233deb3ec6SMatthias Ringwald     uint8_t flags;
2243deb3ec6SMatthias Ringwald     uint8_t flow_control;
2253deb3ec6SMatthias Ringwald     uint8_t xon;
2263deb3ec6SMatthias Ringwald     uint8_t xoff;
2273deb3ec6SMatthias Ringwald     uint8_t parameter_mask_0;   // first byte
2283deb3ec6SMatthias Ringwald     uint8_t parameter_mask_1;   // second byte
2293deb3ec6SMatthias Ringwald } rfcomm_rpn_data_t;
2303deb3ec6SMatthias Ringwald 
2313deb3ec6SMatthias Ringwald typedef struct rfcomm_channel_event_rpn {
2323deb3ec6SMatthias Ringwald     rfcomm_channel_event_t super;
2333deb3ec6SMatthias Ringwald     rfcomm_rpn_data_t data;
2343deb3ec6SMatthias Ringwald } rfcomm_channel_event_rpn_t;
2353deb3ec6SMatthias Ringwald 
2363deb3ec6SMatthias Ringwald typedef struct rfcomm_channel_event_rls {
2373deb3ec6SMatthias Ringwald     rfcomm_channel_event_t super;
2383deb3ec6SMatthias Ringwald     uint8_t line_status;
2393deb3ec6SMatthias Ringwald } rfcomm_channel_event_rls_t;
2403deb3ec6SMatthias Ringwald 
2413deb3ec6SMatthias Ringwald typedef struct rfcomm_channel_event_msc {
2423deb3ec6SMatthias Ringwald     rfcomm_channel_event_t super;
2433deb3ec6SMatthias Ringwald     uint8_t modem_status;
2443deb3ec6SMatthias Ringwald } rfcomm_channel_event_msc_t;
2453deb3ec6SMatthias Ringwald 
2463deb3ec6SMatthias Ringwald // info regarding potential connections
2473deb3ec6SMatthias Ringwald typedef struct {
2483deb3ec6SMatthias Ringwald     // linked list - assert: first field
2493deb3ec6SMatthias Ringwald     linked_item_t    item;
2503deb3ec6SMatthias Ringwald 
2513deb3ec6SMatthias Ringwald     // server channel
2523deb3ec6SMatthias Ringwald     uint8_t server_channel;
2533deb3ec6SMatthias Ringwald 
2543deb3ec6SMatthias Ringwald     // incoming max frame size
2553deb3ec6SMatthias Ringwald     uint16_t max_frame_size;
2563deb3ec6SMatthias Ringwald 
2573deb3ec6SMatthias Ringwald     // use incoming flow control
2583deb3ec6SMatthias Ringwald     uint8_t incoming_flow_control;
2593deb3ec6SMatthias Ringwald 
2603deb3ec6SMatthias Ringwald     // initial incoming credits
2613deb3ec6SMatthias Ringwald     uint8_t incoming_initial_credits;
2623deb3ec6SMatthias Ringwald 
2633deb3ec6SMatthias Ringwald     // client connection
2643deb3ec6SMatthias Ringwald     void *connection;
2653deb3ec6SMatthias Ringwald 
2663deb3ec6SMatthias Ringwald     // internal connection
2673deb3ec6SMatthias Ringwald     btstack_packet_handler_t packet_handler;
2683deb3ec6SMatthias Ringwald 
2693deb3ec6SMatthias Ringwald } rfcomm_service_t;
2703deb3ec6SMatthias Ringwald 
2713deb3ec6SMatthias Ringwald // info regarding multiplexer
2723deb3ec6SMatthias Ringwald // note: spec mandates single multiplexer per device combination
2733deb3ec6SMatthias Ringwald typedef struct {
2743deb3ec6SMatthias Ringwald     // linked list - assert: first field
2753deb3ec6SMatthias Ringwald     linked_item_t    item;
2763deb3ec6SMatthias Ringwald 
2773deb3ec6SMatthias Ringwald     timer_source_t   timer;
2783deb3ec6SMatthias Ringwald     int              timer_active;
2793deb3ec6SMatthias Ringwald 
2803deb3ec6SMatthias Ringwald 	RFCOMM_MULTIPLEXER_STATE state;
2813deb3ec6SMatthias Ringwald 
2823deb3ec6SMatthias Ringwald     uint16_t  l2cap_cid;
2833deb3ec6SMatthias Ringwald     uint8_t   l2cap_credits;
2843deb3ec6SMatthias Ringwald 
2853deb3ec6SMatthias Ringwald     uint8_t   fcon; // only send if fcon & 1, send rsp if fcon & 0x80
2863deb3ec6SMatthias Ringwald 
2873deb3ec6SMatthias Ringwald 	bd_addr_t remote_addr;
2883deb3ec6SMatthias Ringwald     hci_con_handle_t con_handle;
2893deb3ec6SMatthias Ringwald 
2903deb3ec6SMatthias Ringwald 	uint8_t   outgoing;
2913deb3ec6SMatthias Ringwald 
2923deb3ec6SMatthias Ringwald     // hack to deal with authentication failure only observed by remote side
2933deb3ec6SMatthias Ringwald     uint8_t at_least_one_connection;
2943deb3ec6SMatthias Ringwald 
2953deb3ec6SMatthias Ringwald     uint16_t max_frame_size;
2963deb3ec6SMatthias Ringwald 
2973deb3ec6SMatthias Ringwald     // send DM for DLCI != 0
2983deb3ec6SMatthias Ringwald     uint8_t send_dm_for_dlci;
2993deb3ec6SMatthias Ringwald 
3003deb3ec6SMatthias Ringwald     // non supported command, 0 if not set
3013deb3ec6SMatthias Ringwald     uint8_t nsc_command;
3023deb3ec6SMatthias Ringwald 
3033deb3ec6SMatthias Ringwald     // test data - limited to RFCOMM_TEST_DATA_MAX_LEN
3043deb3ec6SMatthias Ringwald     uint8_t test_data_len;
3053deb3ec6SMatthias Ringwald     uint8_t test_data[RFCOMM_TEST_DATA_MAX_LEN];
3063deb3ec6SMatthias Ringwald 
3073deb3ec6SMatthias Ringwald } rfcomm_multiplexer_t;
3083deb3ec6SMatthias Ringwald 
3093deb3ec6SMatthias Ringwald // info regarding an actual connection
3103deb3ec6SMatthias Ringwald typedef struct {
3113deb3ec6SMatthias Ringwald     // linked list - assert: first field
3123deb3ec6SMatthias Ringwald     linked_item_t    item;
3133deb3ec6SMatthias Ringwald 
3143deb3ec6SMatthias Ringwald 	rfcomm_multiplexer_t *multiplexer;
3153deb3ec6SMatthias Ringwald 	uint16_t rfcomm_cid;
3163deb3ec6SMatthias Ringwald     uint8_t  outgoing;
3173deb3ec6SMatthias Ringwald     uint8_t  dlci;
3183deb3ec6SMatthias Ringwald 
3193deb3ec6SMatthias Ringwald     // number of packets granted to client
3203deb3ec6SMatthias Ringwald     uint8_t packets_granted;
3213deb3ec6SMatthias Ringwald 
3223deb3ec6SMatthias Ringwald     // credits for outgoing traffic
3233deb3ec6SMatthias Ringwald     uint8_t credits_outgoing;
3243deb3ec6SMatthias Ringwald 
3253deb3ec6SMatthias Ringwald     // number of packets remote will be granted
3263deb3ec6SMatthias Ringwald     uint8_t new_credits_incoming;
3273deb3ec6SMatthias Ringwald 
3283deb3ec6SMatthias Ringwald     // credits for incoming traffic
3293deb3ec6SMatthias Ringwald     uint8_t credits_incoming;
3303deb3ec6SMatthias Ringwald 
3313deb3ec6SMatthias Ringwald     // use incoming flow control
3323deb3ec6SMatthias Ringwald     uint8_t incoming_flow_control;
3333deb3ec6SMatthias Ringwald 
3343deb3ec6SMatthias Ringwald     // channel state
3353deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_STATE state;
3363deb3ec6SMatthias Ringwald 
3373deb3ec6SMatthias Ringwald     // state variables used in RFCOMM_CHANNEL_INCOMING
3383deb3ec6SMatthias Ringwald     RFCOMM_CHANNEL_STATE_VAR state_var;
3393deb3ec6SMatthias Ringwald 
3403deb3ec6SMatthias Ringwald     // priority set by incoming side in PN
3413deb3ec6SMatthias Ringwald     uint8_t pn_priority;
3423deb3ec6SMatthias Ringwald 
3433deb3ec6SMatthias Ringwald 	// negotiated frame size
3443deb3ec6SMatthias Ringwald     uint16_t max_frame_size;
3453deb3ec6SMatthias Ringwald 
3463deb3ec6SMatthias Ringwald     // local rpn data
3473deb3ec6SMatthias Ringwald     rfcomm_rpn_data_t rpn_data;
3483deb3ec6SMatthias Ringwald 
3493deb3ec6SMatthias Ringwald     // rls line status. RFCOMM_RLS_STATUS_INVALID if not set
3503deb3ec6SMatthias Ringwald     uint8_t rls_line_status;
3513deb3ec6SMatthias Ringwald 
3523deb3ec6SMatthias Ringwald     // msc modem status.
3533deb3ec6SMatthias Ringwald     uint8_t msc_modem_status;
3543deb3ec6SMatthias Ringwald 
3553deb3ec6SMatthias Ringwald 	// server channel (see rfcomm_service_t) - NULL => outgoing channel
3563deb3ec6SMatthias Ringwald 	rfcomm_service_t * service;
3573deb3ec6SMatthias Ringwald 
3583deb3ec6SMatthias Ringwald     // internal connection
3593deb3ec6SMatthias Ringwald     btstack_packet_handler_t packet_handler;
3603deb3ec6SMatthias Ringwald 
3613deb3ec6SMatthias Ringwald     // client connection
3623deb3ec6SMatthias Ringwald     void * connection;
3633deb3ec6SMatthias Ringwald 
3643deb3ec6SMatthias Ringwald } rfcomm_channel_t;
3653deb3ec6SMatthias Ringwald 
3663deb3ec6SMatthias Ringwald void rfcomm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
3673deb3ec6SMatthias Ringwald 
3683deb3ec6SMatthias Ringwald /* API_START */
3693deb3ec6SMatthias Ringwald 
3703deb3ec6SMatthias Ringwald /**
3713deb3ec6SMatthias Ringwald  * @brief Set up RFCOMM.
3723deb3ec6SMatthias Ringwald  */
3733deb3ec6SMatthias Ringwald void rfcomm_init(void);
3743deb3ec6SMatthias Ringwald 
3753deb3ec6SMatthias Ringwald /**
3763deb3ec6SMatthias Ringwald  * @brief Set security level required for incoming connections, need to be called before registering services.
3773deb3ec6SMatthias Ringwald  */
3783deb3ec6SMatthias Ringwald void rfcomm_set_required_security_level(gap_security_level_t security_level);
3793deb3ec6SMatthias Ringwald 
3803deb3ec6SMatthias Ringwald /**
3813deb3ec6SMatthias Ringwald  * @brief Register packet handler.
3823deb3ec6SMatthias Ringwald  */
3833deb3ec6SMatthias Ringwald void rfcomm_register_packet_handler(void (*handler)(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size));
3843deb3ec6SMatthias Ringwald 
385*5d1e858fSMatthias Ringwald /*
386*5d1e858fSMatthias Ringwald  * @brief Create RFCOMM connection to a given server channel on a remote deivce.
387*5d1e858fSMatthias Ringwald  * This channel will automatically provide enough credits to the remote side.
388*5d1e858fSMatthias Ringwald  * @param addr
389*5d1e858fSMatthias Ringwald  * @param server_channel
390*5d1e858fSMatthias Ringwald  * @param out_cid
391*5d1e858fSMatthias Ringwald  * @result status
3923deb3ec6SMatthias Ringwald  */
393*5d1e858fSMatthias Ringwald uint8_t rfcomm_create_channel(bd_addr_t addr, uint8_t server_channel, uint16_t * out_cid);
3943deb3ec6SMatthias Ringwald 
395*5d1e858fSMatthias Ringwald /*
396*5d1e858fSMatthias Ringwald  * @brief Create RFCOMM connection to a given server channel on a remote deivce.
397*5d1e858fSMatthias Ringwald  * This channel will use explicit credit management. During channel establishment, an initial  amount of credits is provided.
398*5d1e858fSMatthias Ringwald  * @param addr
399*5d1e858fSMatthias Ringwald  * @param server_channel
400*5d1e858fSMatthias Ringwald  * @param initial_credits
401*5d1e858fSMatthias Ringwald  * @param out_cid
402*5d1e858fSMatthias Ringwald  * @result status
4033deb3ec6SMatthias Ringwald  */
404*5d1e858fSMatthias Ringwald uint8_t rfcomm_create_channel_with_initial_credits(bd_addr_t addr, uint8_t server_channel, uint8_t initial_credits, uint16_t * out_cid);
4053deb3ec6SMatthias Ringwald 
4063deb3ec6SMatthias Ringwald /**
4073deb3ec6SMatthias Ringwald  * @brief Disconnects RFCOMM channel with given identifier.
4083deb3ec6SMatthias Ringwald  */
4093deb3ec6SMatthias Ringwald void rfcomm_disconnect_internal(uint16_t rfcomm_cid);
4103deb3ec6SMatthias Ringwald 
4113deb3ec6SMatthias Ringwald /**
4123deb3ec6SMatthias 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.
4133deb3ec6SMatthias Ringwald  */
4143deb3ec6SMatthias Ringwald void rfcomm_register_service_internal(void * connection, uint8_t channel, uint16_t max_frame_size);
4153deb3ec6SMatthias Ringwald 
4163deb3ec6SMatthias Ringwald /**
4173deb3ec6SMatthias 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.
4183deb3ec6SMatthias Ringwald  */
4193deb3ec6SMatthias Ringwald void rfcomm_register_service_with_initial_credits_internal(void * connection, uint8_t channel, uint16_t max_frame_size, uint8_t initial_credits);
4203deb3ec6SMatthias Ringwald 
4213deb3ec6SMatthias Ringwald /**
4223deb3ec6SMatthias Ringwald  * @brief Unregister RFCOMM service.
4233deb3ec6SMatthias Ringwald  */
4243deb3ec6SMatthias Ringwald void rfcomm_unregister_service_internal(uint8_t service_channel);
4253deb3ec6SMatthias Ringwald 
4263deb3ec6SMatthias Ringwald /**
4273deb3ec6SMatthias Ringwald  * @brief Accepts/Deny incoming RFCOMM connection.
4283deb3ec6SMatthias Ringwald  */
4293deb3ec6SMatthias Ringwald void rfcomm_accept_connection_internal(uint16_t rfcomm_cid);
4303deb3ec6SMatthias Ringwald void rfcomm_decline_connection_internal(uint16_t rfcomm_cid);
4313deb3ec6SMatthias Ringwald 
4323deb3ec6SMatthias Ringwald /**
4333deb3ec6SMatthias Ringwald  * @brief Grant more incoming credits to the remote side for the given RFCOMM channel identifier.
4343deb3ec6SMatthias Ringwald  */
4353deb3ec6SMatthias Ringwald void rfcomm_grant_credits(uint16_t rfcomm_cid, uint8_t credits);
4363deb3ec6SMatthias Ringwald 
4373deb3ec6SMatthias Ringwald /**
4383deb3ec6SMatthias Ringwald  * @brief Checks if RFCOMM can send packet. Returns yes if packet can be sent.
4393deb3ec6SMatthias Ringwald  */
4403deb3ec6SMatthias Ringwald int rfcomm_can_send_packet_now(uint16_t rfcomm_cid);
4413deb3ec6SMatthias Ringwald 
4423deb3ec6SMatthias Ringwald /**
4433deb3ec6SMatthias Ringwald  * @brief Sends RFCOMM data packet to the RFCOMM channel with given identifier.
4443deb3ec6SMatthias Ringwald  */
4453deb3ec6SMatthias Ringwald int  rfcomm_send_internal(uint16_t rfcomm_cid, uint8_t *data, uint16_t len);
4463deb3ec6SMatthias Ringwald 
4473deb3ec6SMatthias Ringwald /**
4483deb3ec6SMatthias Ringwald  * @brief Sends Local Line Status, see LINE_STATUS_..
4493deb3ec6SMatthias Ringwald  */
4503deb3ec6SMatthias Ringwald int rfcomm_send_local_line_status(uint16_t rfcomm_cid, uint8_t line_status);
4513deb3ec6SMatthias Ringwald 
4523deb3ec6SMatthias Ringwald /**
4533deb3ec6SMatthias Ringwald  * @brief Send local modem status. see MODEM_STAUS_..
4543deb3ec6SMatthias Ringwald  */
4553deb3ec6SMatthias Ringwald int rfcomm_send_modem_status(uint16_t rfcomm_cid, uint8_t modem_status);
4563deb3ec6SMatthias Ringwald 
4573deb3ec6SMatthias Ringwald /**
4583deb3ec6SMatthias Ringwald  * @brief Configure remote port
4593deb3ec6SMatthias Ringwald  */
4603deb3ec6SMatthias 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);
4613deb3ec6SMatthias Ringwald 
4623deb3ec6SMatthias Ringwald /**
4633deb3ec6SMatthias Ringwald  * @brief Query remote port
4643deb3ec6SMatthias Ringwald  */
4653deb3ec6SMatthias Ringwald int rfcomm_query_port_configuration(uint16_t rfcomm_cid);
4663deb3ec6SMatthias Ringwald 
4673deb3ec6SMatthias Ringwald /**
4683deb3ec6SMatthias Ringwald  * @brief Allow to create RFCOMM packet in outgoing buffer.
4693deb3ec6SMatthias Ringwald  */
4703deb3ec6SMatthias Ringwald int       rfcomm_reserve_packet_buffer(void);
4713deb3ec6SMatthias Ringwald void      rfcomm_release_packet_buffer(void);
4723deb3ec6SMatthias Ringwald uint8_t * rfcomm_get_outgoing_buffer(void);
4733deb3ec6SMatthias Ringwald uint16_t  rfcomm_get_max_frame_size(uint16_t rfcomm_cid);
4743deb3ec6SMatthias Ringwald int       rfcomm_send_prepared(uint16_t rfcomm_cid, uint16_t len);
4753deb3ec6SMatthias Ringwald /* API_END */
4763deb3ec6SMatthias Ringwald 
477*5d1e858fSMatthias Ringwald // depreccated
478*5d1e858fSMatthias Ringwald 
479*5d1e858fSMatthias Ringwald /**
480*5d1e858fSMatthias 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
481*5d1e858fSMatthias Ringwald  */
482*5d1e858fSMatthias Ringwald void rfcomm_create_channel_internal(void * connection, bd_addr_t addr, uint8_t channel);
483*5d1e858fSMatthias Ringwald 
484*5d1e858fSMatthias Ringwald /**
485*5d1e858fSMatthias 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.
486*5d1e858fSMatthias Ringwald  */
487*5d1e858fSMatthias Ringwald void rfcomm_create_channel_with_initial_credits_internal(void * connection, bd_addr_t addr, uint8_t server_channel, uint8_t initial_credits);
488*5d1e858fSMatthias Ringwald 
4893deb3ec6SMatthias Ringwald #if defined __cplusplus
4903deb3ec6SMatthias Ringwald }
4913deb3ec6SMatthias Ringwald #endif
4923deb3ec6SMatthias Ringwald 
4933deb3ec6SMatthias Ringwald #endif // __RFCOMM_H
494