CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
orangepi-xunlong

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: orangepi-xunlong/orangepi-build
Path: blob/next/external/cache/sources/hcitools/monitor/lmp.c
Views: 3959
1
/*
2
*
3
* BlueZ - Bluetooth protocol stack for Linux
4
*
5
* Copyright (C) 2011-2012 Intel Corporation
6
* Copyright (C) 2004-2010 Marcel Holtmann <[email protected]>
7
*
8
*
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 2 of the License, or
12
* (at your option) any later version.
13
*
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
18
*
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
*
23
*/
24
25
#ifdef HAVE_CONFIG_H
26
#include <config.h>
27
#endif
28
29
#include <stdio.h>
30
31
#include "display.h"
32
#include "packet.h"
33
#include "lmp.h"
34
35
#define COLOR_OPCODE COLOR_MAGENTA
36
#define COLOR_OPCODE_UNKNOWN COLOR_WHITE_BG
37
38
#define ESC4(x) ((127 << 8) | (x))
39
40
struct lmp_data {
41
uint16_t opcode;
42
const char *str;
43
void (*func) (const void *data, uint8_t size);
44
uint8_t size;
45
bool fixed;
46
};
47
48
static const struct lmp_data lmp_table[] = {
49
{ 1, "LMP_name_req" },
50
{ 2, "LMP_name_res" },
51
{ 3, "LMP_accepted" },
52
{ 4, "LMP_not_accepted" },
53
{ 5, "LMP_clkoffset_req" },
54
{ 6, "LMP_clkoffset_res" },
55
{ 7, "LMP_detach" },
56
{ 8, "LMP_in_rand" },
57
{ 9, "LMP_comb_key" },
58
{ 10, "LMP_unit_key" },
59
{ 11, "LMP_au_rand" },
60
{ 12, "LMP_sres" },
61
{ 13, "LMP_temp_rand" },
62
{ 14, "LMP_temp_key" },
63
{ 15, "LMP_encryption_mode_req" },
64
{ 16, "LMP_encryption_key_size_req" },
65
{ 17, "LMP_start_encryption_req" },
66
{ 18, "LMP_stop_encryption_req" },
67
{ 19, "LMP_switch_req" },
68
{ 20, "LMP_hold" },
69
{ 21, "LMP_hold_req" },
70
{ 22, "LMP_sniff" },
71
{ 23, "LMP_sniff_req" },
72
{ 24, "LMP_unsniff_req" },
73
{ 25, "LMP_park_req" },
74
{ 26, "LMP_park" },
75
{ 27, "LMP_set_broadcast_scan_window" },
76
{ 28, "LMP_modify_beacon" },
77
{ 29, "LMP_unpark_BD_ADDR_req" },
78
{ 30, "LMP_unpark_PM_ADDR_req" },
79
{ 31, "LMP_incr_power_req" },
80
{ 32, "LMP_decr_power_req" },
81
{ 33, "LMP_max_power" },
82
{ 34, "LMP_min_power" },
83
{ 35, "LMP_auto_rate" },
84
{ 36, "LMP_preferred_rate" },
85
{ 37, "LMP_version_req" },
86
{ 38, "LMP_version_res" },
87
{ 39, "LMP_features_req" },
88
{ 40, "LMP_features_res" },
89
{ 41, "LMP_quality_of_service" },
90
{ 42, "LMP_quality_of_service_req" },
91
{ 43, "LMP_SCO_link_req" },
92
{ 44, "LMP_remove_SCO_link_req" },
93
{ 45, "LMP_max_slot" },
94
{ 46, "LMP_max_slot_req" },
95
{ 47, "LMP_timing_accuracy_req" },
96
{ 48, "LMP_timing_accuracy_res" },
97
{ 49, "LMP_setup_complete" },
98
{ 50, "LMP_use_semi_permanent_key" },
99
{ 51, "LMP_host_connection_req" },
100
{ 52, "LMP_slot_offset" },
101
{ 53, "LMP_page_mode_req" },
102
{ 54, "LMP_Page_scan_mode_req" },
103
{ 55, "LMP_supervision_timeout" },
104
{ 56, "LMP_test_activate" },
105
{ 57, "LMP_test_control" },
106
{ 58, "LMP_encryption_key_size_mask_req" },
107
{ 59, "LMP_encryption_key_size_mask_res" },
108
{ 60, "LMP_set_AFH" },
109
{ 61, "LMP_encapsulated_header" },
110
{ 62, "LMP_encapsulated_payload" },
111
{ 63, "LMP_simple_pairing_confirm" },
112
{ 64, "LMP_simple_pairing_number" },
113
{ 65, "LMP_DHkey_check" },
114
{ 66, "LMP_pause_encryption_aes_req" },
115
{ ESC4(1), "LMP_accepted_ext" },
116
{ ESC4(2), "LMP_not_accepted_ext" },
117
{ ESC4(3), "LMP_features_req_ext" },
118
{ ESC4(4), "LMP_features_res_ext" },
119
{ ESC4(5), "LMP_clk_adj" },
120
{ ESC4(6), "LMP_clk_adj_ack" },
121
{ ESC4(7), "LMP_clk_adj_req" },
122
{ ESC4(11), "LMP_packet_type_table" },
123
{ ESC4(12), "LMP_eSCO_link_req" },
124
{ ESC4(13), "LMP_remove_eSCO_link_req" },
125
{ ESC4(16), "LMP_channel_classification_req" },
126
{ ESC4(17), "LMP_channel_classification" },
127
{ ESC4(21), "LMP_sniff_subrating_req" },
128
{ ESC4(22), "LMP_sniff_subrating_res" },
129
{ ESC4(23), "LMP_pause_encryption_req" },
130
{ ESC4(24), "LMP_resume_encryption_req" },
131
{ ESC4(25), "LMP_IO_capability_req" },
132
{ ESC4(26), "LMP_IO_capability_res" },
133
{ ESC4(27), "LMP_numeric_comparision_failed" },
134
{ ESC4(28), "LMP_passkey_failed" },
135
{ ESC4(29), "LMP_oob_failed" },
136
{ ESC4(30), "LMP_keypress_notification" },
137
{ ESC4(31), "LMP_power_control_req" },
138
{ ESC4(32), "LMP_power_control_res" },
139
{ ESC4(33), "LMP_ping_req" },
140
{ ESC4(34), "LMP_ping_res" },
141
{ }
142
};
143
144
145
void lmp_packet(const void *data, uint8_t size)
146
{
147
const struct lmp_data *lmp_data = NULL;
148
const char *opcode_color, *opcode_str;
149
uint16_t opcode;
150
uint8_t tid, off;
151
int i;
152
153
tid = ((const uint8_t *) data)[0] & 0x01;
154
opcode = (((const uint8_t *) data)[0] & 0xfe) >> 1;
155
156
switch (opcode) {
157
case 127:
158
opcode = ESC4(((const uint8_t *) data)[1]);
159
off = 2;
160
break;
161
case 126:
162
case 125:
163
case 124:
164
return;
165
default:
166
off = 1;
167
break;
168
}
169
170
for (i = 0; lmp_table[i].str; i++) {
171
if (lmp_table[i].opcode == opcode) {
172
lmp_data = &lmp_table[i];
173
break;
174
}
175
}
176
177
if (lmp_data) {
178
if (lmp_data->func)
179
opcode_color = COLOR_OPCODE;
180
else
181
opcode_color = COLOR_OPCODE_UNKNOWN;
182
opcode_str = lmp_data->str;
183
} else {
184
opcode_color = COLOR_OPCODE_UNKNOWN;
185
opcode_str = "Unknown";
186
}
187
188
if (opcode & 0xff00)
189
print_indent(6, opcode_color, "", opcode_str, COLOR_OFF,
190
" (%d/%d) TID %d", opcode >> 8, opcode & 0xff, tid);
191
else
192
print_indent(6, opcode_color, "", opcode_str, COLOR_OFF,
193
" (%d) TID %d", opcode, tid);
194
195
if (!lmp_data || !lmp_data->func) {
196
packet_hexdump(data + off, size - off);
197
return;
198
}
199
200
if (lmp_data->fixed) {
201
if (size - 1 != lmp_data->size) {
202
print_text(COLOR_ERROR, "invalid packet size");
203
packet_hexdump(data + off, size - off);
204
return;
205
}
206
} else {
207
if (size - 1 < lmp_data->size) {
208
print_text(COLOR_ERROR, "too short packet");
209
packet_hexdump(data + off, size - off);
210
return;
211
}
212
}
213
214
lmp_data->func(data + off, size - off);
215
}
216
217