View | Details | Raw Unified | Return to bug 247051
Collapse All | Expand All

(-)usr.sbin/bluetooth/hccontrol/hccontrol.8 (+2 lines)
Lines 162-167 Link Here
162
.It Cm LE_Add_Device_To_White_List
162
.It Cm LE_Add_Device_To_White_List
163
.It Cm LE_Remove_Device_From_White_List
163
.It Cm LE_Remove_Device_From_White_List
164
.It Cm LE_Connect
164
.It Cm LE_Connect
165
.It Cm LE_Read_Channel_Map
166
.It Cm LE_Read_Remote_Features
165
.El
167
.El
166
.Pp
168
.Pp
167
The currently supported node commands in
169
The currently supported node commands in
(-)usr.sbin/bluetooth/hccontrol/hccontrol.h (+1 lines)
Lines 82-87 Link Here
82
char const * 	hci_addrtype2str    (int type);
82
char const * 	hci_addrtype2str    (int type);
83
char const *    hci_role2str        (int role);
83
char const *    hci_role2str        (int role);
84
char const *    hci_mc_accuracy2str (int accuracy);
84
char const *    hci_mc_accuracy2str (int accuracy);
85
char const * 	hci_le_chanmap2str  (uint8_t *, char *, int);
85
86
86
void dump_adv_data(int len, uint8_t* advdata);
87
void dump_adv_data(int len, uint8_t* advdata);
87
void print_adv_data(int len, uint8_t* advdata);
88
void print_adv_data(int len, uint8_t* advdata);
(-)usr.sbin/bluetooth/hccontrol/host_controller_baseband.c (-2 / +2 lines)
Lines 1526-1532 Link Here
1526
	switch (argc) {
1526
	switch (argc) {
1527
	case 2:
1527
	case 2:
1528
		if (sscanf(argv[1], "%d", &n) != 1 || (n != 0 && n != 1)){
1528
		if (sscanf(argv[1], "%d", &n) != 1 || (n != 0 && n != 1)){
1529
			printf("ARGC2: %d\n", n);
1529
			printf("-ARGC2: %d\n", n);
1530
			return (USAGE);
1530
			return (USAGE);
1531
		}
1531
		}
1532
		cp.simultaneous_le_host = (n &1);
1532
		cp.simultaneous_le_host = (n &1);
Lines 1533-1539 Link Here
1533
		
1533
		
1534
	case 1:
1534
	case 1:
1535
		if (sscanf(argv[0], "%d", &n) != 1 || (n != 0 && n != 1)){
1535
		if (sscanf(argv[0], "%d", &n) != 1 || (n != 0 && n != 1)){
1536
			printf("ARGC1: %d\n", n);
1536
			printf("+ARGC1: %d\n", n);
1537
			return (USAGE);
1537
			return (USAGE);
1538
		}
1538
		}
1539
1539
(-)usr.sbin/bluetooth/hccontrol/le.c (+140 lines)
Lines 69-74 Link Here
69
static int le_remove_device_from_white_list(int s, int argc, char *argv[]);
69
static int le_remove_device_from_white_list(int s, int argc, char *argv[]);
70
static int le_connect(int s, int argc, char *argv[]);
70
static int le_connect(int s, int argc, char *argv[]);
71
static void handle_le_connection_event(ng_hci_event_pkt_t* e, bool verbose);
71
static void handle_le_connection_event(ng_hci_event_pkt_t* e, bool verbose);
72
static int le_read_channel_map(int s, int argc, char *argv[]);
73
static void handle_le_remote_features_event(ng_hci_event_pkt_t* e);
72
74
73
static int
75
static int
74
le_set_scan_param(int s, int argc, char *argv[])
76
le_set_scan_param(int s, int argc, char *argv[])
Lines 1086-1091 Link Here
1086
	return;
1088
	return;
1087
}
1089
}
1088
1090
1091
static int
1092
le_read_channel_map(int s, int argc, char *argv[])
1093
{
1094
	ng_hci_le_read_channel_map_cp	cp;
1095
	ng_hci_le_read_channel_map_rp	rp;
1096
	int				n;
1097
	char 				buffer[2048];
1098
1099
	/* parse command parameters */
1100
	switch (argc) {
1101
	case 1:
1102
		/* connection handle */
1103
		if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
1104
			return (USAGE);
1105
1106
		cp.connection_handle = (uint16_t) (n & 0x0fff);
1107
		cp.connection_handle = htole16(cp.connection_handle);
1108
		break;
1109
1110
	default:
1111
		return (USAGE);
1112
	}
1113
1114
	n = sizeof(rp);
1115
	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE,
1116
		NG_HCI_OCF_LE_READ_CHANNEL_MAP), 
1117
		(void *)&cp, sizeof(cp), (void *)&rp, &n) == ERROR)
1118
		return (ERROR);
1119
1120
	if (rp.status != 0x00) {
1121
		fprintf(stdout,
1122
			"Read channel map failed. Status: %s [%#02x]\n", 
1123
			hci_status2str(rp.status), rp.status);
1124
		return (FAILED);
1125
	}
1126
1127
	fprintf(stdout, "Connection handle: %d\n",
1128
		le16toh(rp.connection_handle));
1129
	fprintf(stdout, "Used channels:\n");
1130
	fprintf(stdout, "\n%s\n", hci_le_chanmap2str(rp.le_channel_map, 
1131
		buffer, sizeof(buffer)));
1132
1133
	return (OK);
1134
} /* le_read_channel_map */
1135
1136
static int
1137
le_read_remote_features(int s, int argc, char *argv[])
1138
{
1139
	ng_hci_le_read_remote_used_features_cp	cp;
1140
	ng_hci_status_rp 			rp;
1141
	int					n, bufsize;
1142
	char 					b[512];
1143
1144
	ng_hci_event_pkt_t	*e = (ng_hci_event_pkt_t *) b;
1145
1146
	/* parse command parameters */
1147
	switch (argc) {
1148
	case 1:
1149
		/* connection handle */
1150
		if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
1151
			return (USAGE);
1152
1153
		cp.connection_handle = (uint16_t) (n & 0x0fff);
1154
		cp.connection_handle = htole16(cp.connection_handle);
1155
		break;
1156
1157
	default:
1158
		return (USAGE);
1159
	}
1160
1161
	n = sizeof(rp);
1162
	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE,
1163
		NG_HCI_OCF_LE_READ_REMOTE_USED_FEATURES), 
1164
		(void *)&cp, sizeof(cp), (void *)&rp, &n) == ERROR)
1165
		return (ERROR);
1166
1167
	if (rp.status != 0x00) {
1168
		fprintf(stdout,
1169
			"Read remote features failed. Status: %s [%#02x]\n", 
1170
			hci_status2str(rp.status), rp.status);
1171
		return (FAILED);
1172
	}
1173
1174
	/* wait for connection events */
1175
	bufsize = sizeof(b);
1176
	if (hci_recv(s, b, &bufsize) == ERROR) {
1177
		return (ERROR);
1178
	}
1179
1180
	if (bufsize < sizeof(*e)) {
1181
		errno = EIO;
1182
		return (ERROR);
1183
	}
1184
	if (e->event == NG_HCI_EVENT_LE) {
1185
		handle_le_remote_features_event(e);
1186
	}
1187
1188
	return (OK);
1189
} /* le_read_remote_features */
1190
1191
static void handle_le_remote_features_event(ng_hci_event_pkt_t* e) 
1192
{
1193
	ng_hci_le_ep	*ev_pkt;
1194
	ng_hci_le_read_remote_features_ep *feat_event;
1195
	char	buffer[2048];
1196
1197
	ev_pkt = (ng_hci_le_ep *)(e + 1);
1198
1199
	if (ev_pkt->subevent_code == NG_HCI_LEEV_READ_REMOTE_FEATURES_COMPL) {
1200
		feat_event =(ng_hci_le_read_remote_features_ep *)(ev_pkt + 1);
1201
		fprintf(stdout, "Handle: %d\n",
1202
			le16toh(feat_event->connection_handle));
1203
		fprintf(stdout,
1204
			"Status: %s\n",
1205
			hci_status2str(feat_event->status));
1206
		fprintf(stdout, "Features:\n%s\n",
1207
			hci_le_features2str(feat_event->features,
1208
				buffer, sizeof(buffer)));
1209
	}
1210
1211
	return;
1212
} /* handle_le_remote_features_event */
1213
1214
1215
1089
struct hci_command le_commands[] = {
1216
struct hci_command le_commands[] = {
1090
{
1217
{
1091
	"le_enable",
1218
	"le_enable",
Lines 1196-1199 Link Here
1196
	  "Connect to an LE device",
1323
	  "Connect to an LE device",
1197
	  &le_connect
1324
	  &le_connect
1198
  },
1325
  },
1326
  {
1327
	  "le_read_channel_map",
1328
	  "le_read_channel_map <connection_handle>\n"
1329
	  "Read the channel map for a connection",
1330
	  &le_read_channel_map
1331
  },
1332
  {
1333
	  "le_read_remote_features",
1334
	  "le_read_remote_features <connection_handle>\n"
1335
	  "Read supported features for the device\n"
1336
	  "identified by the connection handle",
1337
	  &le_read_remote_features
1338
  },
1199
};
1339
};
(-)usr.sbin/bluetooth/hccontrol/util.c (+43 lines)
Lines 3322-3324 Link Here
3322
3322
3323
	return (accuracy >= SIZE(acc)? "Unknown accuracy" : acc[accuracy]);
3323
	return (accuracy >= SIZE(acc)? "Unknown accuracy" : acc[accuracy]);
3324
} /* hci_mc_accuracy2str */
3324
} /* hci_mc_accuracy2str */
3325
3326
char const *
3327
hci_le_chanmap2str(uint8_t *map, char *buffer, int size)
3328
{
3329
	char	chantxt[4];
3330
	if (buffer != NULL && size > 0) {
3331
		int n, i, len0, len1;
3332
3333
		memset(buffer, 0, size);
3334
		len1 = 0;
3335
		size--;
3336
3337
		for (n = 0; n < 5; n++) {
3338
			fprintf(stdout, "%02x ", map[n]);
3339
			for (i = 0; i < 8; i++) {
3340
				len0 = strlen(buffer);
3341
				if (len0 >= size)
3342
					goto done;
3343
3344
				if (map[n] & (1 << i)) {
3345
					if (len1 + 3 > 60) {
3346
						len1 = 0;
3347
						buffer[len0 - 1] = '\n';
3348
					}
3349
3350
					len1 += 3;
3351
					snprintf(
3352
						chantxt,
3353
						sizeof(chantxt),
3354
						"%02d ",
3355
						(n * 8 + i));
3356
					strncat(
3357
						buffer,
3358
						chantxt,
3359
						size - len0);
3360
				}
3361
			}
3362
		}
3363
		fprintf(stdout, "\n");
3364
	}
3365
done:
3366
	return (buffer);
3367
}

Return to bug 247051