Upgrade bluez5_37 :Merge the code from private
[platform/upstream/bluez.git] / tools / parser / csr.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2004-2011  Marcel Holtmann <marcel@holtmann.org>
6  *
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdio.h>
29 #include <errno.h>
30 #include <unistd.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 #include "parser.h"
35
36 #define CSR_U8(frm)  (p_get_u8(frm))
37 #define CSR_U16(frm) (btohs(htons(p_get_u16(frm))))
38 #define CSR_U32(frm) ((CSR_U16(frm) << 16) + CSR_U16(frm))
39 #define CSR_S16(frm) (btohs(htons(p_get_u16(frm))))
40
41 static char *type2str(uint16_t type)
42 {
43         switch (type) {
44         case 0x0000:
45                 return "Get req";
46         case 0x0001:
47                 return "Get rsp";
48         case 0x0002:
49                 return "Set req";
50         default:
51                 return "Reserved";
52         }
53 }
54
55 static inline void valueless_dump(int level, char *str, struct frame *frm)
56 {
57         p_indent(level, frm);
58         printf("%s\n", str);
59 }
60
61 static inline void complex_dump(int level, char *str, struct frame *frm)
62 {
63         p_indent(level, frm);
64         printf("%s\n", str);
65
66         raw_dump(level, frm);
67 }
68
69 static inline void bool_dump(int level, char *str, struct frame *frm)
70 {
71         uint16_t value;
72
73         value = CSR_U16(frm);
74
75         p_indent(level, frm);
76         printf("%s: value %s (%d)\n", str, value ? "TRUE" : "FALSE", value);
77 }
78
79 static inline void int8_dump(int level, char *str, struct frame *frm)
80 {
81         int16_t value;
82
83         value = CSR_S16(frm);
84
85         p_indent(level, frm);
86         printf("%s: value %d (0x%2.2x)\n", str, value, value);
87 }
88
89 static inline void int16_dump(int level, char *str, struct frame *frm)
90 {
91         int16_t value;
92
93         value = CSR_S16(frm);
94
95         p_indent(level, frm);
96         printf("%s: value %d (0x%2.2x)\n", str, value, value);
97 }
98
99 static inline void uint16_dump(int level, char *str, struct frame *frm)
100 {
101         uint16_t value;
102
103         value = CSR_U16(frm);
104
105         p_indent(level, frm);
106         printf("%s: value %d (0x%4.4x)\n", str, value, value);
107 }
108
109 static inline void uint32_dump(int level, char *str, struct frame *frm)
110 {
111         uint32_t value;
112
113         value = CSR_U32(frm);
114
115         p_indent(level, frm);
116         printf("%s: value %d (0x%4.4x)\n", str, value, value);
117 }
118
119 static inline void bdaddr_dump(int level, char *str, struct frame *frm)
120 {
121         char addr[18];
122
123         p_ba2str(frm->ptr, addr);
124
125         p_indent(level, frm);
126         printf("%s: bdaddr %s\n", str, addr);
127 }
128
129 static inline void features_dump(int level, char *str, struct frame *frm)
130 {
131         unsigned char features[8];
132         int i;
133
134         memcpy(features, frm->ptr, 8);
135
136         p_indent(level, frm);
137         printf("%s: features", str);
138         for (i = 0; i < 8; i++)
139                 printf(" 0x%02x", features[i]);
140         printf("\n");
141 }
142
143 static inline void commands_dump(int level, char *str, struct frame *frm)
144 {
145         unsigned char commands[64];
146         unsigned int i;
147
148         memcpy(commands, frm->ptr, frm->len);
149
150         p_indent(level, frm);
151         printf("%s: commands", str);
152         for (i = 0; i < frm->len; i++)
153                 printf(" 0x%02x", commands[i]);
154         printf("\n");
155 }
156
157 static inline void handle_length_dump(int level, char *str, struct frame *frm)
158 {
159         uint16_t handle, length;
160
161         handle = CSR_U16(frm);
162         length = CSR_U16(frm);
163
164         p_indent(level, frm);
165         printf("%s: handle %d length %d\n", str, handle, length);
166 }
167
168 static inline void handle_clock_dump(int level, char *str, struct frame *frm)
169 {
170         uint16_t handle;
171         uint32_t clock;
172
173         handle = CSR_U16(frm);
174         clock  = CSR_U32(frm);
175
176         p_indent(level, frm);
177         printf("%s: handle %d clock 0x%4.4x\n", str, handle, clock);
178 }
179
180 static inline void radiotest_dump(int level, char *str, struct frame *frm)
181 {
182         uint16_t testid;
183
184         testid = CSR_U16(frm);
185
186         p_indent(level, frm);
187         printf("%s: test id %d\n", str, testid);
188
189         raw_dump(level, frm);
190 }
191
192 static inline void psmemtype_dump(int level, char *str, struct frame *frm)
193 {
194         uint16_t store, type;
195
196         store = CSR_U16(frm);
197         type  = CSR_U16(frm);
198
199         p_indent(level, frm);
200         printf("%s: store 0x%4.4x type %d\n", str, store, type);
201 }
202
203 static inline void psnext_dump(int level, char *str, struct frame *frm)
204 {
205         uint16_t key, stores, next;
206
207         key    = CSR_U16(frm);
208         stores = CSR_U16(frm);
209         next   = CSR_U16(frm);
210
211         p_indent(level, frm);
212         printf("%s: key 0x%4.4x stores 0x%4.4x next 0x%4.4x\n", str, key, stores, next);
213 }
214
215 static inline void pssize_dump(int level, char *str, struct frame *frm)
216 {
217         uint16_t key, length;
218
219         key    = CSR_U16(frm);
220         length = CSR_U16(frm);
221
222         p_indent(level, frm);
223         printf("%s: key 0x%4.4x %s 0x%4.4x\n", str, key,
224                                 frm->in ? "len" : "stores", length);
225 }
226
227 static inline void psstores_dump(int level, char *str, struct frame *frm)
228 {
229         uint16_t key, stores;
230
231         key    = CSR_U16(frm);
232         stores = CSR_U16(frm);
233
234         p_indent(level, frm);
235         printf("%s: key 0x%4.4x stores 0x%4.4x\n", str, key, stores);
236 }
237
238 static inline void pskey_dump(int level, struct frame *frm)
239 {
240         uint16_t key, length, stores;
241
242         key    = CSR_U16(frm);
243         length = CSR_U16(frm);
244         stores = CSR_U16(frm);
245
246         p_indent(level, frm);
247         printf("PSKEY: key 0x%4.4x len %d stores 0x%4.4x\n", key, length, stores);
248
249         switch (key) {
250         case 0x0001:
251                 bdaddr_dump(level + 1, "BDADDR", frm);
252                 break;
253         case 0x0002:
254                 uint16_dump(level + 1, "COUNTRYCODE", frm);
255                 break;
256         case 0x0003:
257                 uint32_dump(level + 1, "CLASSOFDEVICE", frm);
258                 break;
259         case 0x0004:
260                 uint16_dump(level + 1, "DEVICE_DRIFT", frm);
261                 break;
262         case 0x0005:
263                 uint16_dump(level + 1, "DEVICE_JITTER", frm);
264                 break;
265         case 0x000d:
266                 uint16_dump(level + 1, "MAX_ACLS", frm);
267                 break;
268         case 0x000e:
269                 uint16_dump(level + 1, "MAX_SCOS", frm);
270                 break;
271         case 0x000f:
272                 uint16_dump(level + 1, "MAX_REMOTE_MASTERS", frm);
273                 break;
274         case 0x00da:
275                 uint16_dump(level + 1, "ENC_KEY_LMIN", frm);
276                 break;
277         case 0x00db:
278                 uint16_dump(level + 1, "ENC_KEY_LMAX", frm);
279                 break;
280         case 0x00ef:
281                 features_dump(level + 1, "LOCAL_SUPPORTED_FEATURES", frm);
282                 break;
283         case 0x0106:
284                 commands_dump(level + 1, "LOCAL_SUPPORTED_COMMANDS", frm);
285                 break;
286         case 0x010d:
287                 uint16_dump(level + 1, "HCI_LMP_LOCAL_VERSION", frm);
288                 break;
289         case 0x010e:
290                 uint16_dump(level + 1, "LMP_REMOTE_VERSION", frm);
291                 break;
292         case 0x01a5:
293                 bool_dump(level + 1, "HOSTIO_USE_HCI_EXTN", frm);
294                 break;
295         case 0x01ab:
296                 bool_dump(level + 1, "HOSTIO_MAP_SCO_PCM", frm);
297                 break;
298         case 0x01be:
299                 uint16_dump(level + 1, "UART_BAUDRATE", frm);
300                 break;
301         case 0x01f6:
302                 uint16_dump(level + 1, "ANA_FTRIM", frm);
303                 break;
304         case 0x01f9:
305                 uint16_dump(level + 1, "HOST_INTERFACE", frm);
306                 break;
307         case 0x01fe:
308                 uint16_dump(level + 1, "ANA_FREQ", frm);
309                 break;
310         case 0x02be:
311                 uint16_dump(level + 1, "USB_VENDOR_ID", frm);
312                 break;
313         case 0x02bf:
314                 uint16_dump(level + 1, "USB_PRODUCT_ID", frm);
315                 break;
316         case 0x02cb:
317                 uint16_dump(level + 1, "USB_DFU_PRODUCT_ID", frm);
318                 break;
319         case 0x03cd:
320                 int16_dump(level + 1, "INITIAL_BOOTMODE", frm);
321                 break;
322         default:
323                 raw_dump(level + 1, frm);
324                 break;
325         }
326 }
327
328 static inline void bccmd_dump(int level, struct frame *frm)
329 {
330         uint16_t type, length, seqno, varid, status;
331
332         type   = CSR_U16(frm);
333         length = CSR_U16(frm);
334         seqno  = CSR_U16(frm);
335         varid  = CSR_U16(frm);
336         status = CSR_U16(frm);
337
338         p_indent(level, frm);
339         printf("BCCMD: %s: len %d seqno %d varid 0x%4.4x status %d\n",
340                         type2str(type), length, seqno, varid, status);
341
342         if (!(parser.flags & DUMP_VERBOSE)) {
343                 raw_dump(level + 1, frm);
344                 return;
345         }
346
347         switch (varid) {
348         case 0x000b:
349                 valueless_dump(level + 1, "PS_CLR_ALL", frm);
350                 break;
351         case 0x000c:
352                 valueless_dump(level + 1, "PS_FACTORY_SET", frm);
353                 break;
354         case 0x082d:
355                 uint16_dump(level + 1, "PS_CLR_ALL_STORES", frm);
356                 break;
357         case 0x2801:
358                 uint16_dump(level + 1, "BC01_STATUS", frm);
359                 break;
360         case 0x2819:
361                 uint16_dump(level + 1, "BUILDID", frm);
362                 break;
363         case 0x281a:
364                 uint16_dump(level + 1, "CHIPVER", frm);
365                 break;
366         case 0x281b:
367                 uint16_dump(level + 1, "CHIPREV", frm);
368                 break;
369         case 0x2825:
370                 uint16_dump(level + 1, "INTERFACE_VERSION", frm);
371                 break;
372         case 0x282a:
373                 uint16_dump(level + 1, "RAND", frm);
374                 break;
375         case 0x282c:
376                 uint16_dump(level + 1, "MAX_CRYPT_KEY_LENGTH", frm);
377                 break;
378         case 0x2833:
379                 uint16_dump(level + 1, "E2_APP_SIZE", frm);
380                 break;
381         case 0x2836:
382                 uint16_dump(level + 1, "CHIPANAREV", frm);
383                 break;
384         case 0x2838:
385                 uint16_dump(level + 1, "BUILDID_LOADER", frm);
386                 break;
387         case 0x2c00:
388                 uint32_dump(level + 1, "BT_CLOCK", frm);
389                 break;
390         case 0x3005:
391                 psnext_dump(level + 1, "PS_NEXT", frm);
392                 break;
393         case 0x3006:
394                 pssize_dump(level + 1, "PS_SIZE", frm);
395                 break;
396         case 0x3008:
397                 handle_length_dump(level + 1, "CRYPT_KEY_LENGTH", frm);
398                 break;
399         case 0x3009:
400                 handle_clock_dump(level + 1, "PICONET_INSTANCE", frm);
401                 break;
402         case 0x300a:
403                 complex_dump(level + 1, "GET_CLR_EVT", frm);
404                 break;
405         case 0x300b:
406                 complex_dump(level + 1, "GET_NEXT_BUILDDEF", frm);
407                 break;
408         case 0x300e:
409                 complex_dump(level + 1, "E2_DEVICE", frm);
410                 break;
411         case 0x300f:
412                 complex_dump(level + 1, "E2_APP_DATA", frm);
413                 break;
414         case 0x3012:
415                 psmemtype_dump(level + 1, "PS_MEMORY_TYPE", frm);
416                 break;
417         case 0x301c:
418                 complex_dump(level + 1, "READ_BUILD_NAME", frm);
419                 break;
420         case 0x4001:
421                 valueless_dump(level + 1, "COLD_RESET", frm);
422                 break;
423         case 0x4002:
424                 valueless_dump(level + 1, "WARM_RESET", frm);
425                 break;
426         case 0x4003:
427                 valueless_dump(level + 1, "COLD_HALT", frm);
428                 break;
429         case 0x4004:
430                 valueless_dump(level + 1, "WARM_HALT", frm);
431                 break;
432         case 0x4005:
433                 valueless_dump(level + 1, "INIT_BT_STACK", frm);
434                 break;
435         case 0x4006:
436                 valueless_dump(level + 1, "ACTIVATE_BT_STACK", frm);
437                 break;
438         case 0x4007:
439                 valueless_dump(level + 1, "ENABLE_TX", frm);
440                 break;
441         case 0x4008:
442                 valueless_dump(level + 1, "DISABLE_TX", frm);
443                 break;
444         case 0x4009:
445                 valueless_dump(level + 1, "RECAL", frm);
446                 break;
447         case 0x400d:
448                 valueless_dump(level + 1, "PS_FACTORY_RESTORE", frm);
449                 break;
450         case 0x400e:
451                 valueless_dump(level + 1, "PS_FACTORY_RESTORE_ALL", frm);
452                 break;
453         case 0x400f:
454                 valueless_dump(level + 1, "PS_DEFRAG_RESET", frm);
455                 break;
456         case 0x4011:
457                 valueless_dump(level + 1, "HOPPING_ON", frm);
458                 break;
459         case 0x4012:
460                 valueless_dump(level + 1, "CANCEL_PAGE", frm);
461                 break;
462         case 0x4818:
463                 uint16_dump(level + 1, "PS_CLR", frm);
464                 break;
465         case 0x481c:
466                 uint16_dump(level + 1, "MAP_SCO_PCM", frm);
467                 break;
468         case 0x482e:
469                 uint16_dump(level + 1, "SINGLE_CHAN", frm);
470                 break;
471         case 0x5004:
472                 radiotest_dump(level + 1, "RADIOTEST", frm);
473                 break;
474         case 0x500c:
475                 psstores_dump(level + 1, "PS_CLR_STORES", frm);
476                 break;
477         case 0x6000:
478                 valueless_dump(level + 1, "NO_VARIABLE", frm);
479                 break;
480         case 0x6802:
481                 uint16_dump(level + 1, "CONFIG_UART", frm);
482                 break;
483         case 0x6805:
484                 uint16_dump(level + 1, "PANIC_ARG", frm);
485                 break;
486         case 0x6806:
487                 uint16_dump(level + 1, "FAULT_ARG", frm);
488                 break;
489         case 0x6827:
490                 int8_dump(level + 1, "MAX_TX_POWER", frm);
491                 break;
492         case 0x682b:
493                 int8_dump(level + 1, "DEFAULT_TX_POWER", frm);
494                 break;
495         case 0x7003:
496                 pskey_dump(level + 1, frm);
497                 break;
498         default:
499                 raw_dump(level + 1, frm);
500                 break;
501         }
502 }
503
504 static char *cid2str(uint8_t cid)
505 {
506         switch (cid & 0x3f) {
507         case 0:
508                 return "BCSP Internal";
509         case 1:
510                 return "BCSP Link";
511         case 2:
512                 return "BCCMD";
513         case 3:
514                 return "HQ";
515         case 4:
516                 return "Device Mgt";
517         case 5:
518                 return "HCI Cmd/Evt";
519         case 6:
520                 return "HCI ACL";
521         case 7:
522                 return "HCI SCO";
523         case 8:
524                 return "L2CAP";
525         case 9:
526                 return "RFCOMM";
527         case 10:
528                 return "SDP";
529         case 11:
530                 return "Debug";
531         case 12:
532                 return "DFU";
533         case 13:
534                 return "VM";
535         case 14:
536                 return "Unused";
537         case 15:
538                 return "Reserved";
539         default:
540                 return "Unknown";
541         }
542 }
543
544 static char *frag2str(uint8_t frag)
545 {
546         switch (frag & 0xc0) {
547         case 0x00:
548                 return " middle fragment";
549         case 0x40:
550                 return " first fragment";
551         case 0x80:
552                 return " last fragment";
553         default:
554                 return "";
555         }
556 }
557
558 void csr_dump(int level, struct frame *frm)
559 {
560         uint8_t desc, cid, type;
561         uint16_t handle, master, addr;
562
563         desc = CSR_U8(frm);
564
565         cid = desc & 0x3f;
566
567         switch (cid) {
568         case 2:
569                 bccmd_dump(level, frm);
570                 break;
571
572         case 20:
573                 type = CSR_U8(frm);
574
575                 if (!p_filter(FILT_LMP)) {
576                         switch (type) {
577                         case 0x0f:
578                                 frm->handle =  ((uint8_t *) frm->ptr)[17];
579                                 frm->master = 0;
580                                 frm->len--;
581                                 lmp_dump(level, frm);
582                                 return;
583                         case 0x10:
584                                 frm->handle = ((uint8_t *) frm->ptr)[17];
585                                 frm->master = 1;
586                                 frm->len--;
587                                 lmp_dump(level, frm);
588                                 return;
589                         case 0x12:
590                                 handle = CSR_U16(frm);
591                                 master = CSR_U16(frm);
592                                 addr = CSR_U16(frm);
593                                 p_indent(level, frm);
594                                 printf("FHS: handle %d addr %d (%s)\n", handle,
595                                         addr, master ? "master" : "slave");
596                                 if (!master) {
597                                         char addr[18];
598                                         p_ba2str((bdaddr_t *) frm->ptr, addr);
599                                         p_indent(level + 1, frm);
600                                         printf("bdaddr %s class "
601                                                 "0x%2.2x%2.2x%2.2x\n", addr,
602                                                 ((uint8_t *) frm->ptr)[8],
603                                                 ((uint8_t *) frm->ptr)[7],
604                                                 ((uint8_t *) frm->ptr)[6]);
605                                 }
606                                 return;
607                         case 0x7b:
608                                 p_indent(level, frm);
609                                 printf("LMP(r): duplicate (same SEQN)\n");
610                                 return;
611                         }
612                 }
613
614                 p_indent(level, frm);
615                 printf("CSR: Debug (type 0x%2.2x)\n", type);
616                 raw_dump(level, frm);
617                 break;
618
619         default:
620                 p_indent(level, frm);
621                 printf("CSR: %s (channel %d)%s\n", cid2str(cid), cid, frag2str(desc));
622                 raw_dump(level, frm);
623                 break;
624         }
625 }