diff options
author | Michał Łabędzki <michal.labedzki@wireshark.org> | 2018-04-01 17:32:58 +0200 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2018-07-01 13:31:32 +0000 |
commit | 17a39db773f0f548b862db559d7dcc81f3ab8283 (patch) | |
tree | d9ac21321d7c65ad08a925cc55f6b4451f9bb36a | |
parent | e7b0e9aa9033be61e63298fb04380b613079f502 (diff) |
Bluetooth: ATT: Implement 0x2A0B-0x2A1B remaining characteristics
- 0x2A0B Exact Time 100
- 0x2A10 Secondary Time Zone
- 0x2A15 Time Broadcast
- 0x2A1A Battery Power State
- 0x2A1B Battery Level State
Change-Id: I857a8ff6e38b0093d2d746c789d8f33ec59eb553
Reviewed-on: https://code.wireshark.org/review/28553
Petri-Dish: Michal Labedzki <michal.labedzki@wireshark.org>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r-- | epan/dissectors/packet-btatt.c | 179 |
1 files changed, 174 insertions, 5 deletions
diff --git a/epan/dissectors/packet-btatt.c b/epan/dissectors/packet-btatt.c index 9e6787075c..d1b8b1e1b4 100644 --- a/epan/dissectors/packet-btatt.c +++ b/epan/dissectors/packet-btatt.c @@ -160,6 +160,7 @@ static int hf_btatt_hours = -1; static int hf_btatt_minutes = -1; static int hf_btatt_seconds = -1; static int hf_btatt_day_of_week = -1; +static int hf_btatt_fractions100 = -1; static int hf_btatt_fractions256 = -1; static int hf_btatt_dst_offset = -1; static int hf_btatt_model_number_string = -1; @@ -179,6 +180,11 @@ static int hf_btatt_time_update_control_point = -1; static int hf_btatt_time_current_state = -1; static int hf_btatt_time_result = -1; static int hf_btatt_battery_level = -1; +static int hf_btatt_battery_power_state = -1; +static int hf_btatt_battery_power_state_present = -1; +static int hf_btatt_battery_power_state_discharging = -1; +static int hf_btatt_battery_power_state_charging = -1; +static int hf_btatt_battery_power_state_level = -1; static int hf_btatt_temperature_type = -1; static int hf_btatt_measurement_interval = -1; static int hf_btatt_time_adjust_reason = -1; @@ -992,6 +998,9 @@ static int hf_btatt_regulatory_certification_data_list_item_authorizing_body_dat static int hf_btatt_regulatory_certification_data_list_item_authorizing_body_data_certified_device_class = -1; static int hf_btatt_regulatory_certification_data_list_item_regulation_bit_field_type = -1; static int hf_btatt_regulatory_certification_data_list_item_data = -1; +static int hf_btatt_timezone_information = -1; +static int hf_btatt_timezone_information_information = -1; +static int hf_btatt_timezone_information_information_type = -1; static int hf_gatt_nordic_uart_tx = -1; static int hf_gatt_nordic_uart_rx = -1; static int hf_gatt_nordic_dfu_packet = -1; @@ -1909,6 +1918,20 @@ static const int *hfx_btgatt_microbit_io_pins[] = { NULL }; +static const int *hfx_btatt_timezone_information[] = { + &hf_btatt_timezone_information_information, + &hf_btatt_timezone_information_information_type, + NULL +}; + +static const int *hfx_btatt_battery_power_state[] = { + &hf_btatt_battery_power_state_present, + &hf_btatt_battery_power_state_discharging, + &hf_btatt_battery_power_state_charging, + &hf_btatt_battery_power_state_level, + NULL +}; + /* Initialize the subtree pointers */ static gint ett_btatt = -1; static gint ett_btatt_list = -1; @@ -3531,6 +3554,15 @@ static const value_string tds_result_code_vals[] = { {0, NULL } }; +static const value_string timezone_information_vals[] = { + { 0x00, "Signification Unknown" }, + { 0x01, "Manually Set Time Zone" }, + { 0x02, "Time Zone at Place of Departure" }, + { 0x03, "Time Zone at Destination" }, + { 0x04, "Time Zone at Home" }, + {0, NULL } +}; + static const value_string ots_action_opcode_vals[] = { { 0x00, "Reserved" }, { 0x01, "Create" }, @@ -3629,6 +3661,38 @@ static const value_string btgatt_microbit_button_state_vals[] = { {0, NULL } }; +static const value_string battery_power_state_present_vals[] = { + { 0x00, "Unknown" }, + { 0x01, "Not Supported" }, + { 0x02, "Not Present" }, + { 0x03, "Present" }, + {0, NULL } +}; + +static const value_string battery_power_state_discharging_vals[] = { + { 0x00, "Unknown" }, + { 0x01, "Not Supported" }, + { 0x02, "Not Discharging" }, + { 0x03, "Discharging" }, + {0, NULL } +}; + +static const value_string battery_power_state_charging_vals[] = { + { 0x00, "Unknown" }, + { 0x01, "Not Chargeable" }, + { 0x02, "Not Charging " }, + { 0x03, "Charging" }, + {0, NULL } +}; + +static const value_string battery_power_state_level_vals[] = { + { 0x00, "Unknown" }, + { 0x01, "Not Supported" }, + { 0x02, "Good Level" }, + { 0x03, "Critically Low Level" }, + {0, NULL } +}; + static const true_false_string control_point_mask_value_tfs = { "Leave as Default", "Turn Off" }; @@ -3659,6 +3723,11 @@ static const true_false_string microbit_io_tfs = { "Output" }; +static const true_false_string timezone_information_type_tfs = { + "Information relative to local time", + "Information relative to UTC" +}; + union request_parameters_union { void *data; @@ -5041,6 +5110,7 @@ dissect_attribute_value(proto_tree *tree, proto_item *patron_item, packet_info * break; case 0x2A0A: /* Day Date Time */ + case 0x2A0B: /* Exact Time 100 */ case 0x2A0C: /* Exact Time 256 */ case 0x2A2B: /* Current Time */ if (uuid.bt_uuid == 0x2A2B) {/* Current Time */ @@ -5081,12 +5151,15 @@ dissect_attribute_value(proto_tree *tree, proto_item *patron_item, packet_info * if (uuid.bt_uuid == 0x2A0C || uuid.bt_uuid == 0x2A2B) { proto_tree_add_item(tree, hf_btatt_fractions256, tvb, offset, 1, ENC_NA); offset += 1; + } else if (uuid.bt_uuid == 0x2A0B) { + proto_tree_add_item(tree, hf_btatt_fractions100, tvb, offset, 1, ENC_NA); + offset += 1; } - if (uuid.bt_uuid == 0x2A2B) { + if (uuid.bt_uuid == 0x2A2B) { proto_tree_add_bitmask(tree, tvb, offset, hf_btatt_time_adjust_reason, ett_btatt_value, hfx_btatt_time_adjust_reason, ENC_NA); offset += 1; - } + } break; case 0x2A0D: /* DST Offset */ @@ -5106,6 +5179,7 @@ dissect_attribute_value(proto_tree *tree, proto_item *patron_item, packet_info * break; case 0x2A0F: /* Local Time Information */ + case 0x2A10: /* Secondary Time Zone */ if (service_uuid.bt_uuid == GATT_SERVICE_CURRENT_TIME_SERVICE) { if (is_readable_request(att_data->opcode) || is_writeable_response(att_data->opcode)) break; @@ -5118,6 +5192,11 @@ dissect_attribute_value(proto_tree *tree, proto_item *patron_item, packet_info * if (bluetooth_gatt_has_no_parameter(att_data->opcode)) break; + if (uuid.bt_uuid == 0x2A10) { + proto_tree_add_bitmask(tree, tvb, offset, hf_btatt_timezone_information, ett_btatt_value, hfx_btatt_timezone_information, ENC_NA); + offset += 1; + } + proto_tree_add_item(tree, hf_btatt_timezone, tvb, offset, 1, ENC_NA); offset += 1; @@ -5200,6 +5279,20 @@ dissect_attribute_value(proto_tree *tree, proto_item *patron_item, packet_info * offset += 1; break; + case 0x2A15: /* Time Broadcast */ + if (bluetooth_gatt_has_no_parameter(att_data->opcode)) + break; + + call_dissector_with_data(find_dissector("btgatt.uuid0x2A0C"), tvb_new_subset_length_caplen(tvb, offset, 9, 9), pinfo, tree, att_data); + offset += 9; + + call_dissector_with_data(find_dissector("btgatt.uuid0x2A0F"), tvb_new_subset_length_caplen(tvb, offset, 2, 2), pinfo, tree, att_data); + offset += 2; + + call_dissector_with_data(find_dissector("btgatt.uuid0x2A14"), tvb_new_subset_length_caplen(tvb, offset, 4, 4), pinfo, tree, att_data); + offset += 4; + + break; case 0x2A16: /* Time Update Control Point */ if (service_uuid.bt_uuid == GATT_SERVICE_REFERENCE_TIME_UPDATE_SERVICE) { if (att_data->opcode != ATT_OPCODE_WRITE_COMMAND) @@ -5295,7 +5388,7 @@ dissect_attribute_value(proto_tree *tree, proto_item *patron_item, packet_info * } break; - case 0x2A19: /* Battery Level */ + case 0x2A19: /* Battery Level */ { if (service_uuid.bt_uuid == GATT_SERVICE_BATTERY_SERVICE) { if (is_readable_request(att_data->opcode)) break; @@ -5307,9 +5400,40 @@ dissect_attribute_value(proto_tree *tree, proto_item *patron_item, packet_info * if (bluetooth_gatt_has_no_parameter(att_data->opcode)) break; - proto_tree_add_item(tree, hf_btatt_battery_level, tvb, offset, 1, ENC_NA); + guint32 battery_level; + sub_item = proto_tree_add_item_ret_uint(tree, hf_btatt_battery_level, tvb, offset, 1, ENC_NA, &battery_level); + if (battery_level > 100) + expert_add_info(pinfo, sub_item, &ei_btatt_bad_data); + offset += 1; + + } + break; + case 0x2A1A: /* Battery Power State */ + if (bluetooth_gatt_has_no_parameter(att_data->opcode)) + break; + + proto_tree_add_bitmask(tree, tvb, offset, hf_btatt_battery_power_state, ett_btatt_value, hfx_btatt_battery_power_state, ENC_NA); + flags = tvb_get_guint8(tvb, offset); + offset += 1; + + break; + case 0x2A1B: /* Battery Level State */ { + if (bluetooth_gatt_has_no_parameter(att_data->opcode)) + break; + + guint32 battery_level; + sub_item = proto_tree_add_item_ret_uint(tree, hf_btatt_battery_level, tvb, offset, 1, ENC_NA, &battery_level); + if (battery_level > 100) + expert_add_info(pinfo, sub_item, &ei_btatt_bad_data); offset += 1; + if (tvb_reported_length_remaining(tvb, offset) >= 1) { /* optional field */ + proto_tree_add_bitmask(tree, tvb, offset, hf_btatt_battery_power_state, ett_btatt_value, hfx_btatt_battery_power_state, ENC_NA); + flags = tvb_get_guint8(tvb, offset); + offset += 1; + } + + } break; case 0x2A1C: /* Temperature Measurement */ case 0x2A1E: /* Intermediate Temperature */ @@ -11810,6 +11934,11 @@ proto_register_btatt(void) FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL} }, + {&hf_btatt_fractions100, + {"Fractions100", "btatt.fractions100", + FT_UINT8, BASE_DEC, NULL, 0x0, + "1/100th of a second", HFILL} + }, {&hf_btatt_fractions256, {"Fractions256", "btatt.fractions256", FT_UINT8, BASE_DEC, NULL, 0x0, @@ -11902,7 +12031,32 @@ proto_register_btatt(void) }, {&hf_btatt_battery_level, {"Battery Level", "btatt.battery_level", - FT_UINT8, BASE_DEC, NULL, 0x0, + FT_UINT8, BASE_DEC | BASE_UNIT_STRING, &units_percent, 0x0, + NULL, HFILL} + }, + {&hf_btatt_battery_power_state, + {"Battery Power State", "btatt.battery_power_state", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_battery_power_state_level, + {"Level", "btatt.battery_power_state.level", + FT_UINT8, BASE_HEX, VALS(battery_power_state_level_vals), 0x0, + NULL, HFILL} + }, + {&hf_btatt_battery_power_state_charging, + {"Charging", "btatt.battery_power_state.charging", + FT_UINT8, BASE_HEX, VALS(battery_power_state_charging_vals), 0x0, + NULL, HFILL} + }, + {&hf_btatt_battery_power_state_discharging, + {"Discharging", "btatt.battery_power_state.discharging", + FT_UINT8, BASE_HEX, VALS(battery_power_state_discharging_vals), 0x0, + NULL, HFILL} + }, + {&hf_btatt_battery_power_state_present, + {"Present", "btatt.battery_power_state.present", + FT_UINT8, BASE_HEX, VALS(battery_power_state_present_vals), 0x0, NULL, HFILL} }, {&hf_btatt_temperature_type, @@ -15988,6 +16142,21 @@ proto_register_btatt(void) FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL} }, + {&hf_btatt_timezone_information, + {"Timezone Information", "btatt.timezone_information", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, + {&hf_btatt_timezone_information_information, + {"Information", "btatt.timezone_information.information", + FT_UINT8, BASE_DEC, VALS(timezone_information_vals), 0x7F, + NULL, HFILL} + }, + {&hf_btatt_timezone_information_information_type, + {"Type", "btatt.timezone_information.information_type", + FT_BOOLEAN, 8, TFS(&timezone_information_type_tfs), 0x80, + NULL, HFILL} + }, {&hf_request_in_frame, {"Request in Frame", "btatt.request_in_frame", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0x0, |