1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 * BlueZ - Bluetooth protocol stack for Linux
6 * Copyright (C) 2011-2014 Intel Corporation
7 * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
29 void l2cap_frame_init(struct l2cap_frame *frame, uint16_t index, bool in,
30 uint16_t handle, uint8_t ident,
31 uint16_t cid, uint16_t psm,
32 const void *data, uint16_t size);
34 static inline void l2cap_frame_clone_size(struct l2cap_frame *frame,
35 const struct l2cap_frame *source,
38 if (frame != source) {
39 frame->index = source->index;
40 frame->in = source->in;
41 frame->handle = source->handle;
42 frame->ident = source->ident;
43 frame->cid = source->cid;
44 frame->psm = source->psm;
45 frame->chan = source->chan;
46 frame->mode = source->mode;
47 frame->data = source->data;
52 static inline void l2cap_frame_clone(struct l2cap_frame *frame,
53 const struct l2cap_frame *source)
55 l2cap_frame_clone_size(frame, source, source->size);
58 static inline void *l2cap_frame_pull(struct l2cap_frame *frame,
59 const struct l2cap_frame *source, uint16_t len)
63 l2cap_frame_clone(frame, source);
65 if (source->size < len)
68 data = (void *)frame->data;
69 frame->data = source->data + len;
70 frame->size = source->size - len;
75 static inline bool l2cap_frame_get_u8(struct l2cap_frame *frame, uint8_t *value)
77 if (frame->size < sizeof(*value))
81 *value = *((uint8_t *) frame->data);
83 l2cap_frame_pull(frame, frame, sizeof(*value));
88 static inline bool l2cap_frame_print_u8(struct l2cap_frame *frame,
93 if (!l2cap_frame_get_u8(frame, &u8)) {
94 print_text(COLOR_ERROR, "%s: invalid size", label);
98 print_field("%s: 0x%2.2x", label, u8);
103 static inline bool l2cap_frame_get_be16(struct l2cap_frame *frame,
106 if (frame->size < sizeof(*value))
110 *value = get_be16(frame->data);
112 l2cap_frame_pull(frame, frame, sizeof(*value));
117 static inline bool l2cap_frame_print_be16(struct l2cap_frame *frame,
122 if (!l2cap_frame_get_be16(frame, &u16)) {
123 print_text(COLOR_ERROR, "%s: invalid size", label);
127 print_field("%s: 0x%4.4x", label, u16);
132 static inline bool l2cap_frame_get_le16(struct l2cap_frame *frame,
135 if (frame->size < sizeof(*value))
139 *value = get_le16(frame->data);
141 l2cap_frame_pull(frame, frame, sizeof(*value));
146 static inline bool l2cap_frame_print_le16(struct l2cap_frame *frame,
151 if (!l2cap_frame_get_le16(frame, &u16)) {
152 print_text(COLOR_ERROR, "%s: invalid size", label);
156 print_field("%s: 0x%4.4x", label, u16);
161 static inline bool l2cap_frame_get_be24(struct l2cap_frame *frame,
164 if (frame->size < sizeof(uint24_t))
168 *value = get_be24(frame->data);
170 l2cap_frame_pull(frame, frame, sizeof(uint24_t));
175 static inline bool l2cap_frame_print_be24(struct l2cap_frame *frame,
180 if (!l2cap_frame_get_be24(frame, &u24)) {
181 print_text(COLOR_ERROR, "%s: invalid size", label);
185 print_field("%s: 0x%6.6x", label, u24);
190 static inline bool l2cap_frame_get_le24(struct l2cap_frame *frame,
193 if (frame->size < sizeof(uint24_t))
197 *value = get_le24(frame->data);
199 l2cap_frame_pull(frame, frame, sizeof(uint24_t));
204 static inline bool l2cap_frame_print_le24(struct l2cap_frame *frame,
209 if (!l2cap_frame_get_le24(frame, &u24)) {
210 print_text(COLOR_ERROR, "%s: invalid size", label);
214 print_field("%s: 0x%6.6x", label, u24);
219 static inline bool l2cap_frame_get_be32(struct l2cap_frame *frame,
222 if (frame->size < sizeof(*value))
226 *value = get_be32(frame->data);
228 l2cap_frame_pull(frame, frame, sizeof(*value));
233 static inline bool l2cap_frame_print_be32(struct l2cap_frame *frame,
238 if (!l2cap_frame_get_be32(frame, &u32)) {
239 print_text(COLOR_ERROR, "%s: invalid size", label);
243 print_field("%s: 0x%8.8x", label, u32);
248 static inline bool l2cap_frame_get_le32(struct l2cap_frame *frame,
251 if (frame->size < sizeof(*value))
255 *value = get_le32(frame->data);
257 l2cap_frame_pull(frame, frame, sizeof(*value));
262 static inline bool l2cap_frame_print_le32(struct l2cap_frame *frame,
267 if (!l2cap_frame_get_le32(frame, &u32)) {
268 print_text(COLOR_ERROR, "%s: invalid size", label);
272 print_field("%s: 0x%8.8x", label, u32);
277 static inline bool l2cap_frame_get_be64(struct l2cap_frame *frame,
280 if (frame->size < sizeof(*value))
284 *value = get_be64(frame->data);
286 l2cap_frame_pull(frame, frame, sizeof(*value));
291 static inline bool l2cap_frame_print_be64(struct l2cap_frame *frame,
296 if (!l2cap_frame_get_be64(frame, &u64)) {
297 print_text(COLOR_ERROR, "%s: invalid size", label);
301 print_field("%s: 0x%" PRIx64, label, u64);
306 static inline bool l2cap_frame_get_le64(struct l2cap_frame *frame,
309 if (frame->size < sizeof(*value))
313 *value = get_le64(frame->data);
315 l2cap_frame_pull(frame, frame, sizeof(*value));
320 static inline bool l2cap_frame_print_le64(struct l2cap_frame *frame,
325 if (!l2cap_frame_get_le64(frame, &u64)) {
326 print_text(COLOR_ERROR, "%s: invalid size", label);
330 print_field("%s: 0x%" PRIx64, label, u64);
335 static inline bool l2cap_frame_get_be128(struct l2cap_frame *frame,
336 uint64_t *lvalue, uint64_t *rvalue)
338 if (frame->size < (sizeof(*lvalue) + sizeof(*rvalue)))
341 if (lvalue && rvalue) {
342 *lvalue = get_be64(frame->data);
343 *rvalue = get_be64(frame->data);
346 l2cap_frame_pull(frame, frame, (sizeof(*lvalue) + sizeof(*rvalue)));
351 void l2cap_frame(uint16_t index, bool in, uint16_t handle, uint16_t cid,
352 uint16_t psm, const void *data, uint16_t size);
354 void l2cap_packet(uint16_t index, bool in, uint16_t handle, uint8_t flags,
355 const void *data, uint16_t size);
357 void rfcomm_packet(const struct l2cap_frame *frame);
359 void l2cap_dequeue_frame(struct timeval *delta, struct packet_conn_data *conn);