xref: /btstack/src/classic/rfcomm.h (revision 3deb3ec68039c68a16974dffc53343233662f909)
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