1/* $NetBSD: print.c,v 1.12 2020/06/07 00:12:00 thorpej Exp $ */ 2 3/*- 4 * Copyright (c) 2006 Itronix Inc. 5 * All rights reserved. 6 * 7 * Written by Iain Hibbert for Itronix Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. The name of Itronix Inc. may not be used to endorse 18 * or promote products derived from this software without specific 19 * prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY 25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 28 * ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33/* 34 * Copyright (c) 2004 Maksim Yevmenkin <m_evmenkin@yahoo.com> 35 * All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 46 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 49 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 56 * SUCH DAMAGE. 57 * 58 */ 59 60#include <sys/cdefs.h> 61__RCSID("$NetBSD: print.c,v 1.12 2020/06/07 00:12:00 thorpej Exp $"); 62 63#include <sys/types.h> 64 65#include <dev/bluetooth/btdev.h> 66#include <dev/bluetooth/bthidev.h> 67#include <dev/bluetooth/btsco.h> 68#include <dev/usb/usb.h> 69#include <dev/hid/hid.h> 70 71#include <prop/proplib.h> 72 73#include <bluetooth.h> 74#include <err.h> 75#include <usbhid.h> 76 77#include "btdevctl.h" 78 79static void cfg_bthidev(prop_dictionary_t dict); 80static void cfg_btsco(prop_dictionary_t dict); 81 82static void hid_dump_item(char const *, struct hid_item *); 83static void hid_parse(prop_data_t); 84 85void 86cfg_print(prop_dictionary_t dict) 87{ 88 prop_object_t obj; 89 uint16_t v; 90 91 obj = prop_dictionary_get(dict, BTDEVladdr); 92 if (prop_object_type(obj) != PROP_TYPE_DATA) { 93 return; 94 } 95 printf("local bdaddr: %s\n", bt_ntoa(prop_data_value(obj), NULL)); 96 97 obj = prop_dictionary_get(dict, BTDEVraddr); 98 if (prop_object_type(obj) != PROP_TYPE_DATA) { 99 return; 100 } 101 printf("remote bdaddr: %s\n", bt_ntoa(prop_data_value(obj), NULL)); 102 103 obj = prop_dictionary_get(dict, BTDEVmode); 104 if (prop_object_type(obj) == PROP_TYPE_STRING) 105 printf("link mode: %s\n", prop_string_value(obj)); 106 107 if (prop_dictionary_get_uint16(dict, BTDEVvendor, &v)) 108 printf("vendor id: 0x%04x\n", v); 109 110 if (prop_dictionary_get_uint16(dict, BTDEVproduct, &v)) 111 printf("product id: 0x%04x\n", v); 112 113 obj = prop_dictionary_get(dict, BTDEVtype); 114 if (prop_object_type(obj) != PROP_TYPE_STRING) { 115 printf("No device type!\n"); 116 return; 117 } 118 printf("device type: %s\n", prop_string_value(obj)); 119 120 if (prop_string_equals_string(obj, "bthidev")) { 121 cfg_bthidev(dict); 122 return; 123 } 124 125 if (prop_string_equals_string(obj, "btsco")) { 126 cfg_btsco(dict); 127 return; 128 } 129 130 printf("Unknown device type!\n"); 131} 132 133static void 134cfg_bthidev(prop_dictionary_t dict) 135{ 136 prop_object_t obj; 137 138 obj = prop_dictionary_get(dict, BTHIDEVcontrolpsm); 139 if (prop_object_type(obj) == PROP_TYPE_NUMBER) 140 printf("control psm: 0x%4.4" PRIx64 "\n", 141 prop_number_signed_value(obj)); 142 143 obj = prop_dictionary_get(dict, BTHIDEVinterruptpsm); 144 if (prop_object_type(obj) == PROP_TYPE_NUMBER) 145 printf("interrupt psm: 0x%4.4" PRIx64 "\n", 146 prop_number_signed_value(obj)); 147 148 obj = prop_dictionary_get(dict, BTHIDEVreconnect); 149 if (prop_bool_true(obj)) 150 printf("reconnect mode: true\n"); 151 152 obj = prop_dictionary_get(dict, BTHIDEVdescriptor); 153 if (prop_object_type(obj) == PROP_TYPE_DATA) 154 hid_parse(obj); 155} 156 157static void 158cfg_btsco(prop_dictionary_t dict) 159{ 160 prop_object_t obj; 161 162 obj = prop_dictionary_get(dict, BTSCOlisten); 163 printf("mode: %s\n", prop_bool_true(obj) ? "listen" : "connect"); 164 165 obj = prop_dictionary_get(dict, BTSCOchannel); 166 if (prop_object_type(obj) == PROP_TYPE_NUMBER) 167 printf("channel: %" PRId64 "\n", 168 prop_number_signed_value(obj)); 169} 170 171static void 172hid_parse(prop_data_t desc) 173{ 174 report_desc_t r; 175 hid_data_t d; 176 struct hid_item h; 177 178 hid_init(NULL); 179 180 r = hid_use_report_desc(prop_data_value(desc), 181 prop_data_size(desc)); 182 if (r == NULL) 183 return; 184 185 d = hid_start_parse(r, ~0, -1); 186 while (hid_get_item(d, &h)) { 187 switch (h.kind) { 188 case hid_collection: 189 printf("Collection page=%s usage=%s\n", 190 hid_usage_page(HID_PAGE(h.usage)), 191 hid_usage_in_page(h.usage)); 192 break; 193 194 case hid_endcollection: 195 printf("End collection\n"); 196 break; 197 198 case hid_input: 199 hid_dump_item(" Input", &h); 200 break; 201 202 case hid_output: 203 hid_dump_item(" Output", &h); 204 break; 205 206 case hid_feature: 207 hid_dump_item("Feature", &h); 208 break; 209 } 210 } 211 212 hid_end_parse(d); 213 hid_dispose_report_desc(r); 214} 215 216static void 217hid_dump_item(char const *label, struct hid_item *h) 218{ 219 220 printf("%s id=%u size=%u count=%u page=%s usage=%s%s%s%s%s%s%s%s%s%s", 221 label, (uint8_t) h->report_ID, h->report_size, h->report_count, 222 hid_usage_page(HID_PAGE(h->usage)), 223 hid_usage_in_page(h->usage), 224 (h->flags & HIO_CONST) ? " Const" : "", 225 (h->flags & HIO_VARIABLE) ? " Variable" : "", 226 (h->flags & HIO_RELATIVE) ? " Relative" : "", 227 (h->flags & HIO_WRAP) ? " Wrap" : "", 228 (h->flags & HIO_NONLINEAR) ? " NonLinear" : "", 229 (h->flags & HIO_NOPREF) ? " NoPref" : "", 230 (h->flags & HIO_NULLSTATE) ? " NullState" : "", 231 (h->flags & HIO_VOLATILE) ? " Volatile" : "", 232 (h->flags & HIO_BUFBYTES) ? " BufBytes" : ""); 233 234 printf(", logical range %d..%d", 235 h->logical_minimum, h->logical_maximum); 236 237 if (h->physical_minimum != h->physical_maximum) 238 printf(", physical range %d..%d", 239 h->physical_minimum, h->physical_maximum); 240 241 if (h->unit) 242 printf(", unit=0x%02x exp=%d", h->unit, h->unit_exponent); 243 244 printf("\n"); 245} 246