1 /******************************************************************************
2  *
3  *  Copyright 2018 The Android Open Source Project
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 #pragma once
19 
20 #include <vector>
21 
22 #include <gmock/gmock.h>
23 
24 namespace bluetooth {
25 namespace rfcomm {
26 
27 class RfcommCallback {
28  public:
29   virtual void PortManagementCallback(uint32_t code, uint16_t port_handle,
30                                       uint16_t callback_index) = 0;
31   virtual void PortEventCallback(uint32_t code, uint16_t port_handle,
32                                  uint16_t callback_index) = 0;
33   virtual ~RfcommCallback() = default;
34 };
35 
36 class MockRfcommCallback : public RfcommCallback {
37  public:
38   MOCK_METHOD3(PortManagementCallback, void(uint32_t code, uint16_t port_handle,
39                                             uint16_t callback_index));
40   MOCK_METHOD3(PortEventCallback, void(uint32_t code, uint16_t port_handle,
41                                        uint16_t callback_index));
42 };
43 
44 /**
45  * Create DLCI using direction of service channel number
46  *
47  * @param on_originator_side is this a channel on initiator side
48  * @param scn service channel number
49  * @return DLCI
50  */
51 uint8_t GetDlci(bool on_originator_side, uint8_t scn);
52 
53 /**
54  * Create address field in RFCOMM packet
55  *
56  * @param ea end of field byte, true if field only has 1 byte, false otherwise
57  * @param cr command and response bit, true if packet is from initiator,
58  *           false otherwise, not actual "command" and "response"
59  * @param dlci DLCI of this pcaket, RFCOMM_MX_DLCI for multiplexer control
60  * @return address field
61  */
62 uint8_t GetAddressField(bool ea, bool cr, uint8_t dlci);
63 
64 /**
65  * Create control field in RFCOMM packet
66  *
67  * @param pf Poll/Finish bit, normally 1 for multiplexer control channel
68  * @param frame_type frame type
69  * @return control field
70  */
71 uint8_t GetControlField(bool pf, uint8_t frame_type);
72 
73 /**
74  * Create Multiplexer control channel parameter negotiation frame
75  *
76  * @param dlci DLCI to be configured
77  * @param i_bits i bits
78  * @param cl_bits cl bits
79  * @param priority priority
80  * @param timer_value timer value
81  * @param rfcomm_mtu rfcomm mtu
82  * @param max_num_retransmission maximum number of retransmission
83  * @param err_recovery_window_k error recovery window k
84  * @return vector of bytes of this frame
85  */
86 std::vector<uint8_t> CreateMccPnFrame(uint8_t dlci, uint8_t i_bits,
87                                       uint8_t cl_bits, uint8_t priority,
88                                       uint8_t timer_value, uint16_t rfcomm_mtu,
89                                       uint8_t max_num_retransmission,
90                                       uint8_t err_recovery_window_k);
91 /**
92  * Create Multiplexer Control Modem Status Configuration Frame
93  *
94  * @param dlci DLCI to be configured
95  * @param fc flow control
96  * @param rtc ready to communicate
97  * @param rtr ready to receive
98  * @param ic incoming call indicator
99  * @param dv is data valid
100  * @return vector of bytes
101  */
102 std::vector<uint8_t> CreateMccMscFrame(uint8_t dlci, bool fc, bool rtc,
103                                        bool rtr, bool ic, bool dv);
104 
105 /**
106  * Create Multiplexer Control Frame
107  *
108  * @param command_type type of command
109  * @param cr command or response flag, true when this is a command, false when
110  *           this is a response, regardless of connection direction
111  * @param data frame data
112  * @return vector of bytes
113  */
114 std::vector<uint8_t> CreateMultiplexerControlFrame(
115     uint8_t command_type, bool cr, const std::vector<uint8_t>& data);
116 
117 /**
118  * Create a general RFCOMM packet
119  *
120  * @param address address byte
121  * @param control control byte
122  * @param credits number of credits, <= 0 will cause this to be ignored
123  * @param data frame data
124  * @return vector of bytes
125  */
126 std::vector<uint8_t> CreateRfcommPacket(uint8_t address, uint8_t control,
127                                         int credits,
128                                         const std::vector<uint8_t>& data);
129 /*
130  * Various shortcut for getting frequently used packets
131  */
132 
133 /**
134  * Create SABM packet that is used to connect to a service channel number in a
135  * multiplexer
136  *
137  * @param dlci DLCI to be connected
138  * @param l2cap_lcid L2CAP channel ID
139  * @param acl_handle ACL handle
140  * @return vector of bytes of unwrapped ACL packet
141  */
142 std::vector<uint8_t> CreateQuickSabmPacket(uint8_t dlci, uint16_t l2cap_lcid,
143                                            uint16_t acl_handle);
144 
145 /**
146  * Create UA packet that is used to acknowledge service channel connection
147  *
148  * @param dlci DLCI to be connected
149  * @param l2cap_lcid L2CAP channel ID
150  * @param acl_handle ACL handle
151  * @return vector of bytes of unwrapped ACL packet
152  */
153 std::vector<uint8_t> CreateQuickUaPacket(uint8_t dlci, uint16_t l2cap_lcid,
154                                          uint16_t acl_handle);
155 
156 /**
157  * Create parameter negotiation packet used to setup parameters for a DLCI
158  *
159  * @param rfc_cr RFCOMM command/response bit, true of initiator
160  * @param target_dlci DLCI to be configured
161  * @param mx_cr multiplexer command or reponse, regardless of initiator
162  * @param rfc_mtu RFCOMM mtu to be used for DLCI
163  * @param cl CL bit
164  * @param priority prirority
165  * @param k error recovery window k
166  * @param l2cap_lcid L2CAP channel ID
167  * @param acl_handle ACL handle
168  * @return vector of bytes of unwrapped ACL packet
169  */
170 std::vector<uint8_t> CreateQuickPnPacket(bool rfc_cr, uint8_t target_dlci,
171                                          bool mx_cr, uint16_t rfc_mtu,
172                                          uint8_t cl, uint8_t priority,
173                                          uint8_t k, uint16_t l2cap_lcid,
174                                          uint16_t acl_handle);
175 
176 /**
177  * Create modem signal control packet
178  *
179  * @param rfc_cr RFCOMM command/response bit, true of initiator
180  * @param dlci DLCI to be configured
181  * @param l2cap_lcid L2CAP channel ID
182  * @param acl_handle ACL handle
183  * @param mx_cr multiplexer command or reponse, regardless of initiator
184  * @param fc flow control
185  * @param rtc ready to communicate
186  * @param rtr ready to receive
187  * @param ic incoming call indicator
188  * @param dv data valid
189  * @return vector of bytes of unwrapped ACL packet
190  */
191 std::vector<uint8_t> CreateQuickMscPacket(bool rfc_cr, uint8_t dlci,
192                                           uint16_t l2cap_lcid,
193                                           uint16_t acl_handle, bool mx_cr,
194                                           bool fc, bool rtc, bool rtr, bool ic,
195                                           bool dv);
196 
197 /**
198  * Create a quick RFCOMM data packet
199  *
200  * @param dlci DLCI of this packet
201  * @param cr command or control, true for initiator
202  * @param l2cap_lcid L2CAP channel ID
203  * @param acl_handle ACL handle
204  * @param credits number of credits
205  * @param data data bytes
206  * @return vector of bytes of unwrapped ACL packet
207  */
208 std::vector<uint8_t> CreateQuickDataPacket(uint8_t dlci, bool cr,
209                                            uint16_t l2cap_lcid,
210                                            uint16_t acl_handle, int credits,
211                                            const std::vector<uint8_t>& data);
212 
213 /**
214  * Create a quick RFCOMM data packet
215  *
216  * @param dlci DLCI of this packet
217  * @param cr command or control, true for initiator
218  * @param l2cap_lcid L2CAP channel ID
219  * @param acl_handle ACL handle
220  * @param credits number of credits
221  * @param str message in string format
222  * @return vector of bytes of unwrapped ACL packet
223  */
224 std::vector<uint8_t> CreateQuickDataPacket(uint8_t dlci, bool cr,
225                                            uint16_t l2cap_lcid,
226                                            uint16_t acl_handle, int credits,
227                                            const std::string& str);
228 
229 }  // namespace rfcomm
230 }  // namespace bluetooth
231