Loading system/vendor_libs/test_vendor_lib/model/devices/scripted_beacon.cc +92 −117 Original line number Diff line number Diff line Loading @@ -19,16 +19,14 @@ #include <fstream> #include <cstdint> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <sys/types.h> #include <sys/inotify.h> #include "model/devices/scripted_beacon_ble_payload.pb.h" #include "model/setup/device_boutique.h" #include "os/log.h" using std::vector; using std::chrono::steady_clock; using std::chrono::system_clock; namespace test_vendor_lib { bool ScriptedBeacon::registered_ = Loading Loading @@ -73,39 +71,8 @@ ScriptedBeacon::ScriptedBeacon() { LOG_INFO("%s scripted_beacon registered %s", __func__, registered_ ? "true" : "false"); } bool ScriptedBeacon::is_config_file_ready() { if (access(config_file_.c_str(), F_OK) == -1) { if (!file_absence_logged_) { LOG_INFO("%s: playback file %s not available", __func__, config_file_.c_str()); add_event(PlaybackEvent::WAITING_FOR_FILE); file_absence_logged_ = true; } return false; } if (access(config_file_.c_str(), R_OK) == -1) { LOG_ERROR("%s: playback file %s is not readable", __func__, config_file_.c_str()); add_event(PlaybackEvent::FILE_NOT_READABLE); return false; } LOG_INFO("%s: playback file %s is available and readable", __func__, config_file_.c_str()); return true; } bool has_time_elapsed(std::chrono::steady_clock::time_point time_point) { std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); if (now > time_point) { return true; } else { return false; } bool has_time_elapsed(steady_clock::time_point time_point) { return steady_clock::now() > time_point; } void ScriptedBeacon::Initialize(const vector<std::string>& args) { Loading @@ -122,18 +89,13 @@ void ScriptedBeacon::Initialize(const vector<std::string>& args) { } config_file_ = args[2]; events_file_ = args[3]; playback_events_.clear_events(); LOG_INFO("Initialized scripted beacon %s", __func__); set_state(PlaybackEvent::INITIALIZED); } void ScriptedBeacon::populate_event(PlaybackEvent * event, PlaybackEvent::PlaybackEventType type) { struct timespec ts_now = {}; clock_gettime(CLOCK_REALTIME, &ts_now); uint64_t timestamp_sec = (uint64_t) ts_now.tv_sec; LOG_INFO("%s: adding event: %d", __func__, type); event->set_type(type); event->set_secs_since_epoch(timestamp_sec); event->set_secs_since_epoch(system_clock::now().time_since_epoch().count()); } // Adds events to events file; we won't be able to post anything to the file Loading @@ -141,89 +103,102 @@ void ScriptedBeacon::populate_event(PlaybackEvent * event, PlaybackEvent::Playba // when we copy playback file. Until then we capture all the events in write // it to the events file when it becomes available. There after we should be // able to write events to file as soon as they are posted. void ScriptedBeacon::add_event(PlaybackEvent::PlaybackEventType type) { void ScriptedBeacon::set_state(PlaybackEvent::PlaybackEventType state) { PlaybackEvent event; if (prev_event_type_ == type) { return; } current_state_ = state; if (!events_ostream_.is_open()) { events_ostream_.open(events_file_, std::ios::out | std::ios::binary | std::ios::trunc); // Check if we have successfully opened; if (!events_ostream_.is_open()) { LOG_INFO("%s: Events file not opened yet, for event: %d", __func__, type); populate_event(playback_events_.add_events(), type); prev_event_type_ = type; LOG_INFO("%s: Events file not opened yet, for event: %d", __func__, state); return; } else { // write all events until now for (const PlaybackEvent& event : playback_events_.events()) { event.SerializeToOstream(&events_ostream_); } } } prev_event_type_ = type; populate_event(&event, type); populate_event(&event, state); event.SerializeToOstream(&events_ostream_); events_ostream_.flush(); } void ScriptedBeacon::TimerTick() { if (!scanned_once_) { switch (current_state_) { case PlaybackEvent::INITIALIZED: Beacon::TimerTick(); } else { next_check_time_ = std::chrono::steady_clock::now(); if (!play_back_on_) { break; case PlaybackEvent::SCANNED_ONCE: next_check_time_ = steady_clock::now() + steady_clock::duration(std::chrono::seconds(1)); set_state(PlaybackEvent::WAITING_FOR_FILE); break; case PlaybackEvent::WAITING_FOR_FILE: if (!has_time_elapsed(next_check_time_)) { return; } if (!is_config_file_ready()) { next_check_time_ = std::chrono::steady_clock::now() + std::chrono::steady_clock::duration(std::chrono::seconds(1)); next_check_time_ = steady_clock::now() + steady_clock::duration(std::chrono::seconds(1)); if (access(config_file_.c_str(), F_OK) == -1) { return; } // Give time for the file to be written completely before being read { write_delay_next_check_time_ = std::chrono::steady_clock::now() + std::chrono::steady_clock::duration(std::chrono::seconds(1)); if (!has_time_elapsed(write_delay_next_check_time_)) { set_state(PlaybackEvent::WAITING_FOR_FILE_TO_BE_READABLE); break; case PlaybackEvent::WAITING_FOR_FILE_TO_BE_READABLE: if (access(config_file_.c_str(), R_OK) == -1) { return; } set_state(PlaybackEvent::PARSING_FILE); break; case PlaybackEvent::PARSING_FILE: { if (!has_time_elapsed(next_check_time_)) { return; } std::fstream input(config_file_, std::ios::in | std::ios::binary); if (!ble_ad_list_.ParseFromIstream(&input)) { LOG_ERROR("%s: Cannot parse playback file %s", __func__, config_file_.c_str()); LOG_ERROR("%s: Cannot parse playback file %s", __func__, config_file_.c_str()); set_state(PlaybackEvent::FILE_PARSING_FAILED); return; } input.close(); LOG_INFO("%s: Starting Ble advertisement playback from file: %s", __func__, config_file_.c_str()); add_event(PlaybackEvent::PLAYBACK_STARTED); play_back_on_ = true; } else { set_state(PlaybackEvent::PLAYBACK_STARTED); LOG_INFO("%s: Starting Ble advertisement playback from file: %s", __func__, config_file_.c_str()); next_ad_.ad_time = steady_clock::now(); get_next_advertisement(); input.close(); } } break; case PlaybackEvent::PLAYBACK_STARTED: { std::shared_ptr<model::packets::LinkLayerPacketBuilder> to_send; std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); elapsed_time_ += now - last_timer_tick_; while (play_back_on_ && !play_back_complete_ && next_ad_.ad_time < now) { while (has_time_elapsed(next_ad_.ad_time)) { auto ad = model::packets::LeAdvertisementBuilder::Create( next_ad_.address, Address::kEmpty /* Destination */, model::packets::AddressType::RANDOM, model::packets::AdvertisementType::ADV_NONCONN_IND, next_ad_.ad); to_send = std::move(ad); for (auto phy : phy_layers_[Phy::Type::LOW_ENERGY]) { for (const auto& phy : phy_layers_[Phy::Type::LOW_ENERGY]) { phy->Send(to_send); } if (packet_num_ < ble_ad_list_.advertisements().size()) { get_next_advertisement(); } else { set_state(PlaybackEvent::PLAYBACK_ENDED); if (events_ostream_.is_open()) { events_ostream_.close(); } LOG_INFO("%s: Completed Ble advertisement playback from file: %s", __func__, config_file_.c_str()); break; } last_timer_tick_ = now; } } break; case PlaybackEvent::FILE_PARSING_FAILED: case PlaybackEvent::PLAYBACK_ENDED: case PlaybackEvent::UNKNOWN: return; } } void ScriptedBeacon::IncomingPacket( model::packets::LinkLayerPacketView packet) { if (!scanned_once_) { if (current_state_ == PlaybackEvent::INITIALIZED) { if (packet.GetDestinationAddress() == properties_.GetLeAddress() && packet.GetType() == model::packets::PacketType::LE_SCAN) { auto scan_response = model::packets::LeScanResponseBuilder::Create( Loading @@ -234,9 +209,8 @@ void ScriptedBeacon::IncomingPacket( properties_.GetLeScanResponse()); std::shared_ptr<model::packets::LinkLayerPacketBuilder> to_send = std::move(scan_response); scanned_once_ = true; Address::FromString("12:34:56:78:9A:BC", next_ad_.address); for (auto phy : phy_layers_[Phy::Type::LOW_ENERGY]) { set_state(PlaybackEvent::SCANNED_ONCE); for (const auto& phy : phy_layers_[Phy::Type::LOW_ENERGY]) { phy->Send(to_send); } } Loading @@ -244,23 +218,24 @@ void ScriptedBeacon::IncomingPacket( } void ScriptedBeacon::get_next_advertisement() { if (packet_num_ < ble_ad_list_.advertisements().size()) { std::string payload = ble_ad_list_.advertisements(packet_num_).payload(); std::string mac_address = ble_ad_list_.advertisements(packet_num_).mac_address(); std::string mac_address = ble_ad_list_.advertisements(packet_num_).mac_address(); uint32_t delay_before_send_ms = ble_ad_list_.advertisements(packet_num_).delay_before_send_ms(); next_ad_.ad.assign(payload.begin(), payload.end()); if (Address::IsValidAddress(mac_address)) { // formatted string with colons like "12:34:56:78:9a:bc" Address::FromString(mac_address, next_ad_.address); next_ad_.ad_time = std::chrono::steady_clock::now() + std::chrono::steady_clock::duration( std::chrono::milliseconds(delay_before_send_ms)); packet_num_++; } else if (mac_address.size() == Address::kLength) { // six-byte binary address std::vector<uint8_t> mac_vector(mac_address.cbegin(), mac_address.cend()); next_ad_.address.Address::FromOctets(mac_vector.data()); } else { play_back_complete_ = true; add_event(PlaybackEvent::PLAYBACK_ENDED); events_ostream_.close(); LOG_INFO("%s: Completed Ble advertisement playback from file: %s", __func__, config_file_.c_str()); Address::FromString("BA:D0:AD:BA:D0:AD", next_ad_.address); } next_ad_.ad_time += steady_clock::duration(std::chrono::milliseconds(delay_before_send_ms)); packet_num_++; } } // namespace test_vendor_lib system/vendor_libs/test_vendor_lib/model/devices/scripted_beacon.h +4 −17 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ #include "beacon.h" using android::bluetooth::test_vendor_lib::model::devices::ScriptedBeaconBleAdProto::PlaybackEvent; using android::bluetooth::test_vendor_lib::model::devices::ScriptedBeaconBleAdProto::PlaybackEvents; namespace test_vendor_lib { // Pretend to be a lot of beacons by advertising from a file. Loading Loading @@ -55,13 +54,9 @@ class ScriptedBeacon : public Beacon { private: static bool registered_; bool scanned_once_{false}; std::chrono::steady_clock::duration elapsed_time_{}; std::chrono::steady_clock::time_point last_timer_tick_{}; std::string config_file_{}; std::string events_file_{}; std::ofstream events_ostream_; PlaybackEvent::PlaybackEventType prev_event_type_{PlaybackEvent::NOT_READY}; struct Advertisement { std::vector<uint8_t> ad; Address address; Loading @@ -72,22 +67,14 @@ class ScriptedBeacon : public Beacon { void get_next_advertisement(); bool is_config_file_ready(); void add_event(android::bluetooth::test_vendor_lib::model::devices::ScriptedBeaconBleAdProto::PlaybackEvent::PlaybackEventType type); void set_state( android::bluetooth::test_vendor_lib::model::devices:: ScriptedBeaconBleAdProto::PlaybackEvent::PlaybackEventType type); Advertisement next_ad_{}; int packet_num_{0}; bool file_absence_logged_{false}; PlaybackEvents playback_events_{}; PlaybackEvent::PlaybackEventType current_state_{PlaybackEvent::UNKNOWN}; std::chrono::steady_clock::time_point next_check_time_{}; std::chrono::steady_clock::time_point write_delay_next_check_time_{}; android::bluetooth::test_vendor_lib::model::devices::ScriptedBeaconBleAdProto::BleAdvertisementList ble_ad_list_; bool play_back_on_{false}; bool play_back_complete_{false}; }; } // namespace test_vendor_lib system/vendor_libs/test_vendor_lib/model/devices/scripted_beacon_ble_payload.proto +11 −10 Original line number Diff line number Diff line Loading @@ -15,18 +15,19 @@ message BleAdvertisementList { } message PlaybackEvent { // These events should occur in order, starting from INITIALIZED enum PlaybackEventType { NOT_READY = 0; WAITING_FOR_FILE = 1; FILE_NOT_READABLE = 2; PLAYBACK_STARTED = 3; PLAYBACK_ENDED = 4; UNKNOWN = 0; INITIALIZED = 1; SCANNED_ONCE = 2; WAITING_FOR_FILE = 3; WAITING_FOR_FILE_TO_BE_READABLE = 4; PARSING_FILE = 5; PLAYBACK_STARTED = 6; PLAYBACK_ENDED = 7; // Error conditions FILE_PARSING_FAILED = 8; } optional PlaybackEventType type = 1; optional uint64 secs_since_epoch = 2; } message PlaybackEvents { repeated PlaybackEvent events = 1; } Loading
system/vendor_libs/test_vendor_lib/model/devices/scripted_beacon.cc +92 −117 Original line number Diff line number Diff line Loading @@ -19,16 +19,14 @@ #include <fstream> #include <cstdint> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <sys/types.h> #include <sys/inotify.h> #include "model/devices/scripted_beacon_ble_payload.pb.h" #include "model/setup/device_boutique.h" #include "os/log.h" using std::vector; using std::chrono::steady_clock; using std::chrono::system_clock; namespace test_vendor_lib { bool ScriptedBeacon::registered_ = Loading Loading @@ -73,39 +71,8 @@ ScriptedBeacon::ScriptedBeacon() { LOG_INFO("%s scripted_beacon registered %s", __func__, registered_ ? "true" : "false"); } bool ScriptedBeacon::is_config_file_ready() { if (access(config_file_.c_str(), F_OK) == -1) { if (!file_absence_logged_) { LOG_INFO("%s: playback file %s not available", __func__, config_file_.c_str()); add_event(PlaybackEvent::WAITING_FOR_FILE); file_absence_logged_ = true; } return false; } if (access(config_file_.c_str(), R_OK) == -1) { LOG_ERROR("%s: playback file %s is not readable", __func__, config_file_.c_str()); add_event(PlaybackEvent::FILE_NOT_READABLE); return false; } LOG_INFO("%s: playback file %s is available and readable", __func__, config_file_.c_str()); return true; } bool has_time_elapsed(std::chrono::steady_clock::time_point time_point) { std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); if (now > time_point) { return true; } else { return false; } bool has_time_elapsed(steady_clock::time_point time_point) { return steady_clock::now() > time_point; } void ScriptedBeacon::Initialize(const vector<std::string>& args) { Loading @@ -122,18 +89,13 @@ void ScriptedBeacon::Initialize(const vector<std::string>& args) { } config_file_ = args[2]; events_file_ = args[3]; playback_events_.clear_events(); LOG_INFO("Initialized scripted beacon %s", __func__); set_state(PlaybackEvent::INITIALIZED); } void ScriptedBeacon::populate_event(PlaybackEvent * event, PlaybackEvent::PlaybackEventType type) { struct timespec ts_now = {}; clock_gettime(CLOCK_REALTIME, &ts_now); uint64_t timestamp_sec = (uint64_t) ts_now.tv_sec; LOG_INFO("%s: adding event: %d", __func__, type); event->set_type(type); event->set_secs_since_epoch(timestamp_sec); event->set_secs_since_epoch(system_clock::now().time_since_epoch().count()); } // Adds events to events file; we won't be able to post anything to the file Loading @@ -141,89 +103,102 @@ void ScriptedBeacon::populate_event(PlaybackEvent * event, PlaybackEvent::Playba // when we copy playback file. Until then we capture all the events in write // it to the events file when it becomes available. There after we should be // able to write events to file as soon as they are posted. void ScriptedBeacon::add_event(PlaybackEvent::PlaybackEventType type) { void ScriptedBeacon::set_state(PlaybackEvent::PlaybackEventType state) { PlaybackEvent event; if (prev_event_type_ == type) { return; } current_state_ = state; if (!events_ostream_.is_open()) { events_ostream_.open(events_file_, std::ios::out | std::ios::binary | std::ios::trunc); // Check if we have successfully opened; if (!events_ostream_.is_open()) { LOG_INFO("%s: Events file not opened yet, for event: %d", __func__, type); populate_event(playback_events_.add_events(), type); prev_event_type_ = type; LOG_INFO("%s: Events file not opened yet, for event: %d", __func__, state); return; } else { // write all events until now for (const PlaybackEvent& event : playback_events_.events()) { event.SerializeToOstream(&events_ostream_); } } } prev_event_type_ = type; populate_event(&event, type); populate_event(&event, state); event.SerializeToOstream(&events_ostream_); events_ostream_.flush(); } void ScriptedBeacon::TimerTick() { if (!scanned_once_) { switch (current_state_) { case PlaybackEvent::INITIALIZED: Beacon::TimerTick(); } else { next_check_time_ = std::chrono::steady_clock::now(); if (!play_back_on_) { break; case PlaybackEvent::SCANNED_ONCE: next_check_time_ = steady_clock::now() + steady_clock::duration(std::chrono::seconds(1)); set_state(PlaybackEvent::WAITING_FOR_FILE); break; case PlaybackEvent::WAITING_FOR_FILE: if (!has_time_elapsed(next_check_time_)) { return; } if (!is_config_file_ready()) { next_check_time_ = std::chrono::steady_clock::now() + std::chrono::steady_clock::duration(std::chrono::seconds(1)); next_check_time_ = steady_clock::now() + steady_clock::duration(std::chrono::seconds(1)); if (access(config_file_.c_str(), F_OK) == -1) { return; } // Give time for the file to be written completely before being read { write_delay_next_check_time_ = std::chrono::steady_clock::now() + std::chrono::steady_clock::duration(std::chrono::seconds(1)); if (!has_time_elapsed(write_delay_next_check_time_)) { set_state(PlaybackEvent::WAITING_FOR_FILE_TO_BE_READABLE); break; case PlaybackEvent::WAITING_FOR_FILE_TO_BE_READABLE: if (access(config_file_.c_str(), R_OK) == -1) { return; } set_state(PlaybackEvent::PARSING_FILE); break; case PlaybackEvent::PARSING_FILE: { if (!has_time_elapsed(next_check_time_)) { return; } std::fstream input(config_file_, std::ios::in | std::ios::binary); if (!ble_ad_list_.ParseFromIstream(&input)) { LOG_ERROR("%s: Cannot parse playback file %s", __func__, config_file_.c_str()); LOG_ERROR("%s: Cannot parse playback file %s", __func__, config_file_.c_str()); set_state(PlaybackEvent::FILE_PARSING_FAILED); return; } input.close(); LOG_INFO("%s: Starting Ble advertisement playback from file: %s", __func__, config_file_.c_str()); add_event(PlaybackEvent::PLAYBACK_STARTED); play_back_on_ = true; } else { set_state(PlaybackEvent::PLAYBACK_STARTED); LOG_INFO("%s: Starting Ble advertisement playback from file: %s", __func__, config_file_.c_str()); next_ad_.ad_time = steady_clock::now(); get_next_advertisement(); input.close(); } } break; case PlaybackEvent::PLAYBACK_STARTED: { std::shared_ptr<model::packets::LinkLayerPacketBuilder> to_send; std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); elapsed_time_ += now - last_timer_tick_; while (play_back_on_ && !play_back_complete_ && next_ad_.ad_time < now) { while (has_time_elapsed(next_ad_.ad_time)) { auto ad = model::packets::LeAdvertisementBuilder::Create( next_ad_.address, Address::kEmpty /* Destination */, model::packets::AddressType::RANDOM, model::packets::AdvertisementType::ADV_NONCONN_IND, next_ad_.ad); to_send = std::move(ad); for (auto phy : phy_layers_[Phy::Type::LOW_ENERGY]) { for (const auto& phy : phy_layers_[Phy::Type::LOW_ENERGY]) { phy->Send(to_send); } if (packet_num_ < ble_ad_list_.advertisements().size()) { get_next_advertisement(); } else { set_state(PlaybackEvent::PLAYBACK_ENDED); if (events_ostream_.is_open()) { events_ostream_.close(); } LOG_INFO("%s: Completed Ble advertisement playback from file: %s", __func__, config_file_.c_str()); break; } last_timer_tick_ = now; } } break; case PlaybackEvent::FILE_PARSING_FAILED: case PlaybackEvent::PLAYBACK_ENDED: case PlaybackEvent::UNKNOWN: return; } } void ScriptedBeacon::IncomingPacket( model::packets::LinkLayerPacketView packet) { if (!scanned_once_) { if (current_state_ == PlaybackEvent::INITIALIZED) { if (packet.GetDestinationAddress() == properties_.GetLeAddress() && packet.GetType() == model::packets::PacketType::LE_SCAN) { auto scan_response = model::packets::LeScanResponseBuilder::Create( Loading @@ -234,9 +209,8 @@ void ScriptedBeacon::IncomingPacket( properties_.GetLeScanResponse()); std::shared_ptr<model::packets::LinkLayerPacketBuilder> to_send = std::move(scan_response); scanned_once_ = true; Address::FromString("12:34:56:78:9A:BC", next_ad_.address); for (auto phy : phy_layers_[Phy::Type::LOW_ENERGY]) { set_state(PlaybackEvent::SCANNED_ONCE); for (const auto& phy : phy_layers_[Phy::Type::LOW_ENERGY]) { phy->Send(to_send); } } Loading @@ -244,23 +218,24 @@ void ScriptedBeacon::IncomingPacket( } void ScriptedBeacon::get_next_advertisement() { if (packet_num_ < ble_ad_list_.advertisements().size()) { std::string payload = ble_ad_list_.advertisements(packet_num_).payload(); std::string mac_address = ble_ad_list_.advertisements(packet_num_).mac_address(); std::string mac_address = ble_ad_list_.advertisements(packet_num_).mac_address(); uint32_t delay_before_send_ms = ble_ad_list_.advertisements(packet_num_).delay_before_send_ms(); next_ad_.ad.assign(payload.begin(), payload.end()); if (Address::IsValidAddress(mac_address)) { // formatted string with colons like "12:34:56:78:9a:bc" Address::FromString(mac_address, next_ad_.address); next_ad_.ad_time = std::chrono::steady_clock::now() + std::chrono::steady_clock::duration( std::chrono::milliseconds(delay_before_send_ms)); packet_num_++; } else if (mac_address.size() == Address::kLength) { // six-byte binary address std::vector<uint8_t> mac_vector(mac_address.cbegin(), mac_address.cend()); next_ad_.address.Address::FromOctets(mac_vector.data()); } else { play_back_complete_ = true; add_event(PlaybackEvent::PLAYBACK_ENDED); events_ostream_.close(); LOG_INFO("%s: Completed Ble advertisement playback from file: %s", __func__, config_file_.c_str()); Address::FromString("BA:D0:AD:BA:D0:AD", next_ad_.address); } next_ad_.ad_time += steady_clock::duration(std::chrono::milliseconds(delay_before_send_ms)); packet_num_++; } } // namespace test_vendor_lib
system/vendor_libs/test_vendor_lib/model/devices/scripted_beacon.h +4 −17 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ #include "beacon.h" using android::bluetooth::test_vendor_lib::model::devices::ScriptedBeaconBleAdProto::PlaybackEvent; using android::bluetooth::test_vendor_lib::model::devices::ScriptedBeaconBleAdProto::PlaybackEvents; namespace test_vendor_lib { // Pretend to be a lot of beacons by advertising from a file. Loading Loading @@ -55,13 +54,9 @@ class ScriptedBeacon : public Beacon { private: static bool registered_; bool scanned_once_{false}; std::chrono::steady_clock::duration elapsed_time_{}; std::chrono::steady_clock::time_point last_timer_tick_{}; std::string config_file_{}; std::string events_file_{}; std::ofstream events_ostream_; PlaybackEvent::PlaybackEventType prev_event_type_{PlaybackEvent::NOT_READY}; struct Advertisement { std::vector<uint8_t> ad; Address address; Loading @@ -72,22 +67,14 @@ class ScriptedBeacon : public Beacon { void get_next_advertisement(); bool is_config_file_ready(); void add_event(android::bluetooth::test_vendor_lib::model::devices::ScriptedBeaconBleAdProto::PlaybackEvent::PlaybackEventType type); void set_state( android::bluetooth::test_vendor_lib::model::devices:: ScriptedBeaconBleAdProto::PlaybackEvent::PlaybackEventType type); Advertisement next_ad_{}; int packet_num_{0}; bool file_absence_logged_{false}; PlaybackEvents playback_events_{}; PlaybackEvent::PlaybackEventType current_state_{PlaybackEvent::UNKNOWN}; std::chrono::steady_clock::time_point next_check_time_{}; std::chrono::steady_clock::time_point write_delay_next_check_time_{}; android::bluetooth::test_vendor_lib::model::devices::ScriptedBeaconBleAdProto::BleAdvertisementList ble_ad_list_; bool play_back_on_{false}; bool play_back_complete_{false}; }; } // namespace test_vendor_lib
system/vendor_libs/test_vendor_lib/model/devices/scripted_beacon_ble_payload.proto +11 −10 Original line number Diff line number Diff line Loading @@ -15,18 +15,19 @@ message BleAdvertisementList { } message PlaybackEvent { // These events should occur in order, starting from INITIALIZED enum PlaybackEventType { NOT_READY = 0; WAITING_FOR_FILE = 1; FILE_NOT_READABLE = 2; PLAYBACK_STARTED = 3; PLAYBACK_ENDED = 4; UNKNOWN = 0; INITIALIZED = 1; SCANNED_ONCE = 2; WAITING_FOR_FILE = 3; WAITING_FOR_FILE_TO_BE_READABLE = 4; PARSING_FILE = 5; PLAYBACK_STARTED = 6; PLAYBACK_ENDED = 7; // Error conditions FILE_PARSING_FAILED = 8; } optional PlaybackEventType type = 1; optional uint64 secs_since_epoch = 2; } message PlaybackEvents { repeated PlaybackEvent events = 1; }