Loading system/test/rootcanal/bluetooth_hci.cc +3 −1 Original line number Original line Diff line number Diff line Loading @@ -191,8 +191,10 @@ Return<void> BluetoothHci::initialize_impl( test_channel_.AddDeviceToPhy({"3", "1"}); test_channel_.AddDeviceToPhy({"3", "1"}); test_channel_.Add( test_channel_.Add( {"scripted_beacon", "5b:ea:c1:00:00:03", {"scripted_beacon", "5b:ea:c1:00:00:03", "/data/vendor/bluetooth/bluetooth_sim_ble_playback_file"}); "/data/vendor/bluetooth/bluetooth_sim_ble_playback_file", "/data/vendor/bluetooth/bluetooth_sim_ble_playback_events"}); test_channel_.AddDeviceToPhy({"4", "1"}); test_channel_.AddDeviceToPhy({"4", "1"}); test_channel_.List({}); unlink_cb_ = [this, cb](sp<BluetoothDeathRecipient>& death_recipient) { unlink_cb_ = [this, cb](sp<BluetoothDeathRecipient>& death_recipient) { if (death_recipient->getHasDied()) if (death_recipient->getHasDied()) Loading system/vendor_libs/test_vendor_lib/model/devices/scripted_beacon.cc +51 −1 Original line number Original line Diff line number Diff line Loading @@ -79,6 +79,7 @@ bool ScriptedBeacon::is_config_file_ready() { LOG_INFO("%s: playback file %s not available", LOG_INFO("%s: playback file %s not available", __func__, __func__, config_file_.c_str()); config_file_.c_str()); add_event(PlaybackEvent::WAITING_FOR_FILE); file_absence_logged = true; file_absence_logged = true; } } return false; return false; Loading @@ -88,6 +89,7 @@ bool ScriptedBeacon::is_config_file_ready() { LOG_ERROR("%s: playback file %s is not readable", LOG_ERROR("%s: playback file %s is not readable", __func__, __func__, config_file_.c_str()); config_file_.c_str()); add_event(PlaybackEvent::FILE_NOT_READABLE); return false; return false; } } LOG_INFO("%s: playback file %s is available and readable", LOG_INFO("%s: playback file %s is available and readable", Loading @@ -112,9 +114,53 @@ void ScriptedBeacon::Initialize(const vector<std::string>& args) { Address addr{}; Address addr{}; if (Address::FromString(args[1], addr)) properties_.SetLeAddress(addr); if (Address::FromString(args[1], addr)) properties_.SetLeAddress(addr); if (args.size() < 3) return; if (args.size() < 4) return; config_file_ = args[2]; config_file_ = args[2]; events_file_ = args[3]; } 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); } // Adds events to events file; we won't be able to post anything to the file // until we set to permissive mode in tests. We set permissive mode in tests // 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) { static PlaybackEvents playback_events; PlaybackEvent event; if (prev_event_type_ == type) { return; } 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; 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); event.SerializeToOstream(&events_ostream_); events_ostream_.flush(); } } void ScriptedBeacon::TimerTick() { void ScriptedBeacon::TimerTick() { Loading Loading @@ -147,7 +193,9 @@ void ScriptedBeacon::TimerTick() { 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()); return; return; } } input.close(); LOG_INFO("%s: Starting Ble advertisement playback from file: %s", __func__, config_file_.c_str()); LOG_INFO("%s: Starting Ble advertisement playback from file: %s", __func__, config_file_.c_str()); add_event(PlaybackEvent::PLAYBACK_STARTED); play_back_on_ = true; play_back_on_ = true; get_next_advertisement(); get_next_advertisement(); } } Loading Loading @@ -208,6 +256,8 @@ void ScriptedBeacon::get_next_advertisement() { packet_num++; packet_num++; } else { } else { play_back_complete_ = true; 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()); LOG_INFO("%s: Completed Ble advertisement playback from file: %s", __func__, config_file_.c_str()); } } } } Loading system/vendor_libs/test_vendor_lib/model/devices/scripted_beacon.h +11 −0 Original line number Original line Diff line number Diff line Loading @@ -18,10 +18,14 @@ #include <cstdint> #include <cstdint> #include <vector> #include <vector> #include <fstream> #include "model/devices/scripted_beacon_ble_payload.pb.h" #include "model/devices/scripted_beacon_ble_payload.pb.h" #include "beacon.h" #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 { namespace test_vendor_lib { // Pretend to be a lot of beacons by advertising from a file. // Pretend to be a lot of beacons by advertising from a file. class ScriptedBeacon : public Beacon { class ScriptedBeacon : public Beacon { Loading Loading @@ -55,16 +59,23 @@ class ScriptedBeacon : public Beacon { std::chrono::steady_clock::duration elapsed_time_{}; std::chrono::steady_clock::duration elapsed_time_{}; std::chrono::steady_clock::time_point last_timer_tick_{}; std::chrono::steady_clock::time_point last_timer_tick_{}; std::string config_file_{}; std::string config_file_{}; std::string events_file_{}; std::ofstream events_ostream_; PlaybackEvent::PlaybackEventType prev_event_type_{PlaybackEvent::NOT_READY}; struct Advertisement { struct Advertisement { std::vector<uint8_t> ad; std::vector<uint8_t> ad; Address address; Address address; std::chrono::steady_clock::time_point ad_time; std::chrono::steady_clock::time_point ad_time; }; }; void populate_event(PlaybackEvent * event, PlaybackEvent::PlaybackEventType type); void get_next_advertisement(); void get_next_advertisement(); bool is_config_file_ready(); bool is_config_file_ready(); void add_event(android::bluetooth::test_vendor_lib::model::devices::ScriptedBeaconBleAdProto::PlaybackEvent::PlaybackEventType type); Advertisement next_ad_{}; Advertisement next_ad_{}; android::bluetooth::test_vendor_lib::model::devices::ScriptedBeaconBleAdProto::BleAdvertisementList ble_ad_list_; android::bluetooth::test_vendor_lib::model::devices::ScriptedBeaconBleAdProto::BleAdvertisementList ble_ad_list_; Loading system/vendor_libs/test_vendor_lib/model/devices/scripted_beacon_ble_payload.proto +17 −0 Original line number Original line Diff line number Diff line Loading @@ -13,3 +13,20 @@ message BleAdvertisement { message BleAdvertisementList { message BleAdvertisementList { repeated BleAdvertisement advertisements = 1; repeated BleAdvertisement advertisements = 1; } } message PlaybackEvent { enum PlaybackEventType { NOT_READY = 0; WAITING_FOR_FILE = 1; FILE_NOT_READABLE = 2; PLAYBACK_STARTED = 3; PLAYBACK_ENDED = 4; } optional PlaybackEventType type = 1; optional uint64 secs_since_epoch = 2; } message PlaybackEvents { repeated PlaybackEvent events = 1; } Loading
system/test/rootcanal/bluetooth_hci.cc +3 −1 Original line number Original line Diff line number Diff line Loading @@ -191,8 +191,10 @@ Return<void> BluetoothHci::initialize_impl( test_channel_.AddDeviceToPhy({"3", "1"}); test_channel_.AddDeviceToPhy({"3", "1"}); test_channel_.Add( test_channel_.Add( {"scripted_beacon", "5b:ea:c1:00:00:03", {"scripted_beacon", "5b:ea:c1:00:00:03", "/data/vendor/bluetooth/bluetooth_sim_ble_playback_file"}); "/data/vendor/bluetooth/bluetooth_sim_ble_playback_file", "/data/vendor/bluetooth/bluetooth_sim_ble_playback_events"}); test_channel_.AddDeviceToPhy({"4", "1"}); test_channel_.AddDeviceToPhy({"4", "1"}); test_channel_.List({}); unlink_cb_ = [this, cb](sp<BluetoothDeathRecipient>& death_recipient) { unlink_cb_ = [this, cb](sp<BluetoothDeathRecipient>& death_recipient) { if (death_recipient->getHasDied()) if (death_recipient->getHasDied()) Loading
system/vendor_libs/test_vendor_lib/model/devices/scripted_beacon.cc +51 −1 Original line number Original line Diff line number Diff line Loading @@ -79,6 +79,7 @@ bool ScriptedBeacon::is_config_file_ready() { LOG_INFO("%s: playback file %s not available", LOG_INFO("%s: playback file %s not available", __func__, __func__, config_file_.c_str()); config_file_.c_str()); add_event(PlaybackEvent::WAITING_FOR_FILE); file_absence_logged = true; file_absence_logged = true; } } return false; return false; Loading @@ -88,6 +89,7 @@ bool ScriptedBeacon::is_config_file_ready() { LOG_ERROR("%s: playback file %s is not readable", LOG_ERROR("%s: playback file %s is not readable", __func__, __func__, config_file_.c_str()); config_file_.c_str()); add_event(PlaybackEvent::FILE_NOT_READABLE); return false; return false; } } LOG_INFO("%s: playback file %s is available and readable", LOG_INFO("%s: playback file %s is available and readable", Loading @@ -112,9 +114,53 @@ void ScriptedBeacon::Initialize(const vector<std::string>& args) { Address addr{}; Address addr{}; if (Address::FromString(args[1], addr)) properties_.SetLeAddress(addr); if (Address::FromString(args[1], addr)) properties_.SetLeAddress(addr); if (args.size() < 3) return; if (args.size() < 4) return; config_file_ = args[2]; config_file_ = args[2]; events_file_ = args[3]; } 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); } // Adds events to events file; we won't be able to post anything to the file // until we set to permissive mode in tests. We set permissive mode in tests // 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) { static PlaybackEvents playback_events; PlaybackEvent event; if (prev_event_type_ == type) { return; } 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; 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); event.SerializeToOstream(&events_ostream_); events_ostream_.flush(); } } void ScriptedBeacon::TimerTick() { void ScriptedBeacon::TimerTick() { Loading Loading @@ -147,7 +193,9 @@ void ScriptedBeacon::TimerTick() { 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()); return; return; } } input.close(); LOG_INFO("%s: Starting Ble advertisement playback from file: %s", __func__, config_file_.c_str()); LOG_INFO("%s: Starting Ble advertisement playback from file: %s", __func__, config_file_.c_str()); add_event(PlaybackEvent::PLAYBACK_STARTED); play_back_on_ = true; play_back_on_ = true; get_next_advertisement(); get_next_advertisement(); } } Loading Loading @@ -208,6 +256,8 @@ void ScriptedBeacon::get_next_advertisement() { packet_num++; packet_num++; } else { } else { play_back_complete_ = true; 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()); LOG_INFO("%s: Completed Ble advertisement playback from file: %s", __func__, config_file_.c_str()); } } } } Loading
system/vendor_libs/test_vendor_lib/model/devices/scripted_beacon.h +11 −0 Original line number Original line Diff line number Diff line Loading @@ -18,10 +18,14 @@ #include <cstdint> #include <cstdint> #include <vector> #include <vector> #include <fstream> #include "model/devices/scripted_beacon_ble_payload.pb.h" #include "model/devices/scripted_beacon_ble_payload.pb.h" #include "beacon.h" #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 { namespace test_vendor_lib { // Pretend to be a lot of beacons by advertising from a file. // Pretend to be a lot of beacons by advertising from a file. class ScriptedBeacon : public Beacon { class ScriptedBeacon : public Beacon { Loading Loading @@ -55,16 +59,23 @@ class ScriptedBeacon : public Beacon { std::chrono::steady_clock::duration elapsed_time_{}; std::chrono::steady_clock::duration elapsed_time_{}; std::chrono::steady_clock::time_point last_timer_tick_{}; std::chrono::steady_clock::time_point last_timer_tick_{}; std::string config_file_{}; std::string config_file_{}; std::string events_file_{}; std::ofstream events_ostream_; PlaybackEvent::PlaybackEventType prev_event_type_{PlaybackEvent::NOT_READY}; struct Advertisement { struct Advertisement { std::vector<uint8_t> ad; std::vector<uint8_t> ad; Address address; Address address; std::chrono::steady_clock::time_point ad_time; std::chrono::steady_clock::time_point ad_time; }; }; void populate_event(PlaybackEvent * event, PlaybackEvent::PlaybackEventType type); void get_next_advertisement(); void get_next_advertisement(); bool is_config_file_ready(); bool is_config_file_ready(); void add_event(android::bluetooth::test_vendor_lib::model::devices::ScriptedBeaconBleAdProto::PlaybackEvent::PlaybackEventType type); Advertisement next_ad_{}; Advertisement next_ad_{}; android::bluetooth::test_vendor_lib::model::devices::ScriptedBeaconBleAdProto::BleAdvertisementList ble_ad_list_; android::bluetooth::test_vendor_lib::model::devices::ScriptedBeaconBleAdProto::BleAdvertisementList ble_ad_list_; Loading
system/vendor_libs/test_vendor_lib/model/devices/scripted_beacon_ble_payload.proto +17 −0 Original line number Original line Diff line number Diff line Loading @@ -13,3 +13,20 @@ message BleAdvertisement { message BleAdvertisementList { message BleAdvertisementList { repeated BleAdvertisement advertisements = 1; repeated BleAdvertisement advertisements = 1; } } message PlaybackEvent { enum PlaybackEventType { NOT_READY = 0; WAITING_FOR_FILE = 1; FILE_NOT_READABLE = 2; PLAYBACK_STARTED = 3; PLAYBACK_ENDED = 4; } optional PlaybackEventType type = 1; optional uint64 secs_since_epoch = 2; } message PlaybackEvents { repeated PlaybackEvent events = 1; }