mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-04-15 14:42:31 +00:00
hid_host: implement set report and get protocol response
This commit is contained in:
parent
baccf17d8f
commit
4a4b5586fb
@ -213,6 +213,19 @@ static void hid_emit_event(hid_host_connection_t * context, uint8_t subevent_typ
|
||||
hid_callback(HCI_EVENT_PACKET, context->hid_cid, &event[0], pos);
|
||||
}
|
||||
|
||||
static void hid_emit_event_with_status(hid_host_connection_t * context, uint8_t subevent_type, hid_handshake_param_type_t status){
|
||||
uint8_t event[6];
|
||||
uint16_t pos = 0;
|
||||
event[pos++] = HCI_EVENT_HID_META;
|
||||
pos++; // skip len
|
||||
event[pos++] = subevent_type;
|
||||
little_endian_store_16(event,pos,context->hid_cid);
|
||||
pos += 2;
|
||||
event[pos++] = status;
|
||||
event[1] = pos - 2;
|
||||
hid_callback(HCI_EVENT_PACKET, context->hid_cid, &event[0], pos);
|
||||
}
|
||||
|
||||
static void hid_emit_incoming_connection_event(hid_host_connection_t * context){
|
||||
uint8_t event[13];
|
||||
uint16_t pos = 0;
|
||||
@ -243,6 +256,20 @@ static void hid_setup_get_report_event(hid_host_connection_t * context, hid_hand
|
||||
buffer[1] = pos + report_len - 2;
|
||||
}
|
||||
|
||||
static void hid_emit_get_protocol_event(hid_host_connection_t * context, hid_handshake_param_type_t status, hid_protocol_mode_t protocol_mode){
|
||||
uint8_t event[7];
|
||||
uint16_t pos = 0;
|
||||
event[pos++] = HCI_EVENT_HID_META;
|
||||
pos++; // skip len
|
||||
event[pos++] = HID_SUBEVENT_GET_PROTOCOL_RESPONSE;
|
||||
little_endian_store_16(event,pos,context->hid_cid);
|
||||
pos += 2;
|
||||
event[pos++] = status;
|
||||
event[pos++] = protocol_mode;
|
||||
event[1] = pos - 2;
|
||||
hid_callback(HCI_EVENT_PACKET, context->hid_cid, &event[0], pos);
|
||||
}
|
||||
|
||||
// HID Host
|
||||
|
||||
static uint16_t hid_host_get_next_cid(void){
|
||||
@ -520,7 +547,8 @@ static void hid_host_handle_control_packet(hid_host_connection_t * connection, u
|
||||
uint8_t param;
|
||||
hid_message_type_t message_type;
|
||||
hid_handshake_param_type_t message_status;
|
||||
// hid_report_type_t report_type;
|
||||
hid_protocol_mode_t protocol_mode;
|
||||
|
||||
uint8_t * in_place_event;
|
||||
uint8_t status;
|
||||
|
||||
@ -537,12 +565,13 @@ static void hid_host_handle_control_packet(hid_host_connection_t * connection, u
|
||||
}
|
||||
}
|
||||
|
||||
message_status = (hid_handshake_param_type_t)(packet[0] & 0x0F);
|
||||
|
||||
switch (connection->state){
|
||||
case HID_HOST_W4_GET_REPORT_RESPONSE:
|
||||
switch (message_type){
|
||||
case HID_MESSAGE_TYPE_HANDSHAKE:{
|
||||
uint8_t event[8];
|
||||
message_status = (hid_handshake_param_type_t)(packet[0] & 0x0F);
|
||||
hid_setup_get_report_event(connection, message_status, event, 0);
|
||||
hid_callback(HCI_EVENT_PACKET, connection->hid_cid, event, sizeof(event));
|
||||
break;
|
||||
@ -557,18 +586,37 @@ static void hid_host_handle_control_packet(hid_host_connection_t * connection, u
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case HID_HOST_W4_SET_REPORT_RESPONSE:
|
||||
printf("HID_HOST_W4_SET_REPORT_RESPONSE \n");
|
||||
hid_emit_event_with_status(connection, HID_SUBEVENT_SET_REPORT_RESPONSE, message_status);
|
||||
break;
|
||||
|
||||
case HID_HOST_W4_GET_PROTOCOL_RESPONSE:
|
||||
printf("HID_HOST_W4_GET_PROTOCOL_RESPONSE \n");
|
||||
break;
|
||||
case HID_HOST_W4_SEND_REPORT_RESPONSE:
|
||||
printf("HID_HOST_W4_SEND_REPORT_RESPONSE\n");
|
||||
protocol_mode = connection->protocol_mode;
|
||||
|
||||
switch (message_type){
|
||||
case HID_MESSAGE_TYPE_DATA:
|
||||
protocol_mode = (hid_protocol_mode_t)packet[1];
|
||||
switch (protocol_mode){
|
||||
case HID_PROTOCOL_MODE_BOOT:
|
||||
case HID_PROTOCOL_MODE_REPORT:
|
||||
message_status = HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL;
|
||||
break;
|
||||
default:
|
||||
message_status = HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
hid_emit_get_protocol_event(connection, message_status, protocol_mode);
|
||||
break;
|
||||
|
||||
case HID_HOST_W4_SET_PROTOCOL_RESPONSE:
|
||||
printf("HID_HOST_W4_SET_PROTOCOL_RESPONSE \n");
|
||||
message_status = (hid_handshake_param_type_t)(packet[0] & 0x0F);
|
||||
hid_emit_event_with_status(connection, HID_SUBEVENT_SET_PROTOCOL_RESPONSE, message_status);
|
||||
|
||||
switch (message_status){
|
||||
case HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL:
|
||||
switch(connection->protocol_mode){
|
||||
@ -591,6 +639,11 @@ static void hid_host_handle_control_packet(hid_host_connection_t * connection, u
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case HID_HOST_W4_SEND_REPORT_RESPONSE:
|
||||
printf("HID_HOST_W4_SEND_REPORT_RESPONSE\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("HID_MESSAGE_TYPE_DATA ???\n");
|
||||
break;
|
||||
@ -1046,10 +1099,14 @@ static uint8_t hid_host_send_set_report(uint16_t hid_cid, hid_report_type_t repo
|
||||
}
|
||||
|
||||
if (connection->state != HID_HOST_CONNECTION_ESTABLISHED){
|
||||
printf("hid_host_send_set_report: unexpected state 0%02x\n", HID_HOST_CONNECTION_ESTABLISHED);
|
||||
log_info("hid_host_send_set_report: unexpected state 0%02x", HID_HOST_CONNECTION_ESTABLISHED);
|
||||
return ERROR_CODE_COMMAND_DISALLOWED;
|
||||
}
|
||||
|
||||
if ((l2cap_max_mtu() - 2) < report_len ){
|
||||
return ERROR_CODE_COMMAND_DISALLOWED;
|
||||
}
|
||||
|
||||
connection->state = HID_HOST_W2_SEND_SET_REPORT;
|
||||
connection->report_type = report_type;
|
||||
connection->report_id = report_id;
|
||||
@ -1074,11 +1131,14 @@ uint8_t hid_host_send_set_input_report(uint16_t hid_cid, uint8_t report_id, uint
|
||||
|
||||
uint8_t hid_host_send_get_protocol(uint16_t hid_cid){
|
||||
hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid);
|
||||
if (!connection || !connection->control_cid) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
|
||||
if (connection->state != HID_HOST_CONNECTION_ESTABLISHED) return ERROR_CODE_COMMAND_DISALLOWED;
|
||||
if (!connection || !connection->control_cid){
|
||||
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
|
||||
}
|
||||
if (connection->state != HID_HOST_CONNECTION_ESTABLISHED){
|
||||
return ERROR_CODE_COMMAND_DISALLOWED;
|
||||
}
|
||||
|
||||
connection->state = HID_HOST_W2_SEND_GET_PROTOCOL;
|
||||
|
||||
l2cap_request_can_send_now_event(connection->control_cid);
|
||||
return ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -10,15 +10,15 @@ HID11/HOS/HCR/BV-03-I: c, U, c, "OK"
|
||||
HID11/HOS/HCR/BV-04-I: c
|
||||
|
||||
HID11/HOS/HCT/BV-01-C: c, 1, 2, 3
|
||||
HID11/HOS/HCT/BV-02-C:
|
||||
HID11/HOS/HCT/BV-03-C:
|
||||
HID11/HOS/HCT/BV-04-C:
|
||||
HID11/HOS/HCT/BV-05-C:
|
||||
HID11/HOS/HCT/BV-06-C:
|
||||
HID11/HOS/HCT/BV-07-C:
|
||||
HID11/HOS/HCT/BV-08-C:
|
||||
HID11/HOS/HCT/BI-01-C:
|
||||
HID11/HOS/HCT/BI-02-C:
|
||||
HID11/HOS/HCT/BV-02-C: c, 4
|
||||
HID11/HOS/HCT/BV-03-C: c, 5
|
||||
HID11/HOS/HCT/BV-04-C: c, p
|
||||
HID11/HOS/HCT/BV-05-C: c, r
|
||||
HID11/HOS/HCT/BV-06-C: c,
|
||||
HID11/HOS/HCT/BV-07-C: c,
|
||||
HID11/HOS/HCT/BV-08-C: c,
|
||||
HID11/HOS/HCT/BI-01-C: c,
|
||||
HID11/HOS/HCT/BI-02-C: c,
|
||||
|
||||
HID11/HOS/BHCT/BV-03-C:
|
||||
HID11/HOS/BHCT/BI-01-C:
|
||||
|
@ -166,7 +166,7 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
|
||||
case HID_SUBEVENT_GET_REPORT_RESPONSE:
|
||||
status = hid_subevent_get_report_response_get_handshake_status(packet);
|
||||
if (status != HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL){
|
||||
printf("Error get report result, status 0x%02x\n", status);
|
||||
printf("Error get report, status 0x%02x\n", status);
|
||||
break;
|
||||
}
|
||||
printf("Received report[%d]: ", hid_subevent_get_report_response_get_report_len(packet));
|
||||
@ -174,6 +174,42 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
|
||||
printf("\n");
|
||||
break;
|
||||
|
||||
case HID_SUBEVENT_SET_REPORT_RESPONSE:
|
||||
status = hid_subevent_set_report_response_get_handshake_status(packet);
|
||||
if (status != HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL){
|
||||
printf("Error set report, status 0x%02x\n", status);
|
||||
break;
|
||||
}
|
||||
printf("Report set.\n");
|
||||
break;
|
||||
|
||||
case HID_SUBEVENT_GET_PROTOCOL_RESPONSE:
|
||||
status = hid_subevent_get_protocol_response_get_handshake_status(packet);
|
||||
if (status != HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL){
|
||||
printf("Error get report, status 0x%02x\n", status);
|
||||
break;
|
||||
}
|
||||
switch ((hid_protocol_mode_t)hid_subevent_get_protocol_response_get_protocol_mode(packet)){
|
||||
case HID_PROTOCOL_MODE_BOOT:
|
||||
printf("HID device is in BOOT mode.\n");
|
||||
break;
|
||||
case HID_PROTOCOL_MODE_REPORT:
|
||||
printf("HID device is in REPORT mode.\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case HID_SUBEVENT_SET_PROTOCOL_RESPONSE:
|
||||
status = hid_subevent_set_report_response_get_handshake_status(packet);
|
||||
if (status != HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL){
|
||||
printf("Error set protocol, status 0x%02x\n", status);
|
||||
break;
|
||||
}
|
||||
printf("Protocol set.\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -206,9 +242,18 @@ static void show_usage(void){
|
||||
printf("\n");
|
||||
printf("1 - Get report with id 0x05\n");
|
||||
printf("2 - Get report with id 0x03\n");
|
||||
printf("3 - Get input report from with id 0x02\n");
|
||||
printf("3 - Get report with id 0x02\n");
|
||||
|
||||
printf("\n");
|
||||
printf("4 - Set report with id 0x03\n");
|
||||
printf("5 - Set report with id 0x05\n");
|
||||
// printf("6 - Set report with id 0x02\n");
|
||||
|
||||
printf("\n");
|
||||
printf("p - Get protocol\n");
|
||||
printf("r - Set protocol in REPORT mode\n");
|
||||
printf("b - Set protocol in BOOT mode\n");
|
||||
|
||||
printf("o - get output report\n");
|
||||
printf("Ctrl-c - exit\n");
|
||||
printf("---\n");
|
||||
}
|
||||
@ -216,22 +261,6 @@ static void show_usage(void){
|
||||
static void stdin_process(char cmd){
|
||||
uint8_t status = ERROR_CODE_SUCCESS;
|
||||
switch (cmd){
|
||||
|
||||
case 'R':
|
||||
printf("Set Protocol mode\n");
|
||||
boot_mode = false;
|
||||
status = hid_host_send_set_protocol_mode(hid_host_cid, HID_PROTOCOL_MODE_REPORT);
|
||||
break;
|
||||
case 'b':
|
||||
printf("Set Boot mode\n");
|
||||
boot_mode = false;
|
||||
status = hid_host_send_set_protocol_mode(hid_host_cid, HID_PROTOCOL_MODE_BOOT);
|
||||
break;
|
||||
case 'B':
|
||||
printf("Set Boot mode\n");
|
||||
boot_mode = true;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
if (unplugged){
|
||||
printf("Cannot connect, host is unplugged.\n");
|
||||
@ -251,6 +280,23 @@ static void stdin_process(char cmd){
|
||||
hid_host_disconnect(hid_host_cid);
|
||||
break;
|
||||
|
||||
|
||||
case 'p':
|
||||
printf("Get protocol\n");
|
||||
status = hid_host_send_get_protocol(hid_host_cid);
|
||||
break;
|
||||
case 'r':
|
||||
printf("Set protocol in REPORT mode");
|
||||
boot_mode = false;
|
||||
status = hid_host_send_set_protocol_mode(hid_host_cid, HID_PROTOCOL_MODE_REPORT);
|
||||
break;
|
||||
case 'b':
|
||||
printf("Set protocol in BOOT mode\n");
|
||||
boot_mode = true;
|
||||
status = hid_host_send_set_protocol_mode(hid_host_cid, HID_PROTOCOL_MODE_BOOT);
|
||||
break;
|
||||
|
||||
|
||||
case 's':
|
||||
printf("Send \'Suspend\'\n");
|
||||
hid_host_send_suspend(hid_host_cid);
|
||||
@ -295,22 +341,21 @@ static void stdin_process(char cmd){
|
||||
break;
|
||||
}
|
||||
|
||||
case '6':{
|
||||
uint8_t report[] = {0, 0, 0, 0};
|
||||
printf("Set input report with id 0x02\n");
|
||||
status = hid_host_send_set_input_report(hid_host_cid, 0x02, report, sizeof(report));
|
||||
break;
|
||||
}
|
||||
// case '6':{
|
||||
// uint8_t report[] = {0, 0, 0, 0};
|
||||
// printf("Set input report with id 0x02\n");
|
||||
// status = hid_host_send_set_input_report(hid_host_cid, 0x02, report, sizeof(report));
|
||||
// break;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
case '7':{
|
||||
uint8_t report[] = {0,0,0, 0,0,0, 0,0};
|
||||
printf("Set output report with id 0x01\n");
|
||||
status = hid_host_send_set_output_report(hid_host_cid, 0x01, report, sizeof(report));
|
||||
break;
|
||||
}
|
||||
case 'p':
|
||||
printf("Get Protocol\n");
|
||||
status = hid_host_send_get_protocol(hid_host_cid);
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
printf("Set send through interrupt channel\n");
|
||||
|
Loading…
x
Reference in New Issue
Block a user