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