Loading system/vendor_libs/test_vendor_lib/include/hci_transport.h +0 −1 Original line number Diff line number Diff line Loading @@ -88,7 +88,6 @@ class HciTransport : public base::MessageLoopForIO::Watcher { // transport object, although |hci_fd_| can be closed by the HCI in // TestVendorOp(). std::unique_ptr<base::ScopedFD> hci_fd_; std::unique_ptr<base::ScopedFD> vendor_fd_; DISALLOW_COPY_AND_ASSIGN(HciTransport); Loading system/vendor_libs/test_vendor_lib/include/packet_stream.h +17 −23 Original line number Diff line number Diff line Loading @@ -30,43 +30,37 @@ namespace test_vendor_lib { // and data from the HCI and to send controller events back to the host. class PacketStream { public: // Constructs an invalid PacketStream object whose file descriptor must be set // before use. PacketStream(); PacketStream() = default; virtual ~PacketStream() = default; // Reads a command packet and returns the packet back to the caller, along // with the responsibility of managing the packet. std::unique_ptr<CommandPacket> ReceiveCommand() const; // Reads a command packet from the file descriptor at |fd| and returns the // packet back to the caller, along with the responsibility of managing the // packet. std::unique_ptr<CommandPacket> ReceiveCommand(int fd) const; // Reads and interprets a single octet as a packet type octet. Validates the // type octet for correctness. serial_data_type_t ReceivePacketType() const; // Reads a single octet from |fd| and interprets it as a packet type octet. // Validates the type octet for correctness. serial_data_type_t ReceivePacketType(int fd) const; // Sends an event to the HCI. The ownership of the event is left with the // caller. bool SendEvent(const EventPacket& event) const; void SetFd(int fd); // Sends an event to file descriptor |fd|. The ownership of the event is left // with the caller. bool SendEvent(const EventPacket& event, int fd) const; private: // Checks if |type| is in the valid range from DATA_TYPE_COMMAND to // DATA_TYPE_SCO. bool ValidateTypeOctet(serial_data_type_t type) const; // Attempts to receive |num_octets_to_receive| into |destination|, returning // false if an error occurs. // Attempts to receive |num_octets_to_receive| into |destination| from |fd|, // returning false if an error occurs. bool ReceiveAll(std::vector<std::uint8_t>& destination, size_t num_octets_to_receive) const; size_t num_octets_to_receive, int fd) const; // Attempts to send |num_octets_to_send| from |source|, returning false if an // error occurs. // Attempts to send |num_octets_to_send| from |source| to |fd|, returning // false if an error occurs. bool SendAll(const std::vector<std::uint8_t>& source, size_t num_octets_to_send) const; // PacketStream does not take ownership of the file descriptor it uses. int fd_; size_t num_octets_to_send, int fd) const; }; } // namespace test_vendor_lib system/vendor_libs/test_vendor_lib/include/vendor_manager.h +25 −3 Original line number Diff line number Diff line Loading @@ -62,6 +62,25 @@ class VendorManager { bool Run(); private: // Test hook object for receiving run-time parameters and commands. class TestChannel { public: TestChannel() = default; ~TestChannel(); // Waits for a connection request from the test channel program and // allocates the file descriptor to receive run-time parameters. This file // descriptor gets stored in |fd_|. bool SetUp(); int GetFd(); private: // File descriptor to watch for test hook data. int fd_; }; VendorManager(); ~VendorManager() = default; Loading Loading @@ -90,9 +109,12 @@ class VendorManager { // descriptor. base::Thread thread_; // Used to handle further watching of the vendor's file descriptor after // WatchFileDescriptor() is called. base::MessageLoopForIO::FileDescriptorWatcher manager_watcher_; // Used to handle further watching of the vendor's/test channel's file // descriptor after WatchFileDescriptor() is called. base::MessageLoopForIO::FileDescriptorWatcher hci_watcher_; base::MessageLoopForIO::FileDescriptorWatcher test_channel_watcher_; TestChannel test_channel_; // This should remain the last member so it'll be destroyed and invalidate // its weak pointers before any other members are destroyed. Loading system/vendor_libs/test_vendor_lib/scripts/build_and_run.sh 0 → 100755 +119 −0 Original line number Diff line number Diff line #!/bin/bash # # Copyright 2015 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Builds and pushes the test vendor library to a connected device and starts # logcat with project-specific tag filters. If the --test-channel flag is set, # logcat is started in a separate process and the test channel is run in the # current shell. if [[ "$#" -ne 2 && "$#" -ne 4 ]]; then echo "Usage:" echo "./build_and_run.sh [/path/to/aosp] [device_name] or" echo "./build_and_run.sh [/path/to/aosp] [device_name] --test-channel [port]" exit 1 fi # Exit the script if any command fails. set -e # The home directory for AOSP. AOSP_ABS=$1 # The name of the device to build for. DEVICE=$2 # The location of Bluetooth within AOSP. BT_REL=/packages/modules/Bluetooth/system BT_ABS=${AOSP_ABS}${BT_REL} # The location of the test vendor library. TEST_VENDOR_LIB_REL=/vendor_libs/test_vendor_lib TEST_VENDOR_LIB_ABS=${BT_ABS}${TEST_VENDOR_LIB_REL} DEVICE_TARGET_REL=/out/target/product DEVICE_TARGET_ABS=${AOSP_ABS}${DEVICE_TARGET_REL} VENDOR_SYMBOLS_REL=/symbols/system/vendor/lib VENDOR_SYMBOLS_ABS=${DEVICE_TARGET_ABS}/${DEVICE}/${VENDOR_SYMBOLS_REL} # The name of the object built by the test vendor library. TEST_VENDOR_LIB=test-vendor.so # The name of the regular vendor object to be replaced by $TEST_VENDOR_LIB. VENDOR_LIB=libbt-vendor.so if [[ "$#" -eq 4 && $3 == "--test-channel" ]]; then TEST_CHANNEL_PORT=$4 TEST_CHANNEL_REL=/scripts TEST_CHANNEL_ABS=${TEST_VENDOR_LIB_ABS}${TEST_CHANNEL_REL} # Start logcat in a subshell. x-terminal-emulator -e "scripts/build_and_run.sh ${AOSP_ABS} ${DEVICE}" echo "Setting up build environment." cd ${AOSP_ABS} source build/envsetup.sh # Forward local port to the same port on the device. echo "Forwarding port ${TEST_CHANNEL_PORT} to device." adb forward tcp:${TEST_CHANNEL_PORT} tcp:${TEST_CHANNEL_PORT} # Turn Bluetooth on. Requires user approval via a dialog on the device. echo "Enabling Bluetooth. Please see dialog on device." adb shell am start -a android.bluetooth.adapter.action.REQUEST_ENABLE # Start the test channel once Bluetooth is on and logcat has started. read -p "Press [ENTER] once Bluetooth is enabling AND logcat has started." # Start the test channel. python ${TEST_CHANNEL_ABS}/test_channel.py localhost ${TEST_CHANNEL_PORT} else echo "Setting up build environment." cd ${AOSP_ABS} source build/envsetup.sh echo "Navigating to test vendor library: ${TEST_VENDOR_LIB_ABS}" cd ${TEST_VENDOR_LIB_ABS} echo "Building test vendor library." mm echo "Remounting device rootfs." adb shell mount -o remount,rw / adb remount # Replace the actual vendor library with the test vendor library. mv ${DEVICE_TARGET_ABS}/${DEVICE}/system/lib/${TEST_VENDOR_LIB} \ ${VENDOR_SYMBOLS_ABS}/${VENDOR_LIB} # Push the test vendor library to the device. echo "Pushing the test vendor library to device: $DEVICE" adb push ${VENDOR_SYMBOLS_ABS}/${VENDOR_LIB} /vendor/lib echo "Pushing libevent." adb push ${DEVICE_TARGET_ABS}/${DEVICE}/system/lib/libevent.so /system/lib/ echo "Pushing libchrome." adb push ${DEVICE_TARGET_ABS}/${DEVICE}/system/lib/libchrome.so /system/lib/ # Clear logcat. adb logcat -c # Run logcat with filters. adb logcat bt_btif:D bt_btif_core:D bt_hci:D bt_main:D bt_vendor:D \ bte_logmsg:D command_packet:D dual_mode_controller:D event_packet:D \ hci_transport:D hci_handler:D packet:D packet_stream:D vendor_manager:D *:S fi system/vendor_libs/test_vendor_lib/scripts/test_channel.py 0 → 100644 +110 −0 Original line number Diff line number Diff line # # Copyright 2015 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # """Script for sending testing parameters and commands to a Bluetooth device. This script provides a simple shell interface for sending data at run-time to a Bluetooth device. It is intended to be used in tandem with the test vendor library project. Usage: Option A: Script 1. Run build_and_run.sh in scripts/ with the --test-channel flag set and the port to use for the test channel. Option B: Manual 1. Choose a port to use for the test channel. Use 'adb forward tcp:<port> tcp:<port>' to forward the port to the device. 2. In a separate shell, build and push the test vendor library to the device using the script mentioned in option A (i.e. without the --test-channel flag set). 3. Once logcat has started, turn Bluetooth on from the device. 4. Run this program, in the shell from step 1, with address 'localhost' and the port, also from step 1, as arguments. """ #!/usr/bin/env python import cmd import socket import struct import sys class Connection(object): """Simple wrapper class for a socket object. Attributes: socket: The underlying socket created for the specified address and port. """ def __init__(self, address, port): self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._socket.connect((address, port)) def close(self): self._socket.close() def send(self, data): self._socket.send(data) class TestChannel(cmd.Cmd): """Shell for sending test channel data to controller. Manages the connection for the test channel to the controller and defines a set of commands the user can send to the controller as well. These commands are processed parallel to commands sent from the device stack and used to provide additional debugging/testing capabilities. Attributes: connection: The communication channel to send data to the controller. """ def __init__(self, address, port): print 'Type \'help\' for more information.' cmd.Cmd.__init__(self) self._connection = Connection(address, port) def do_hci_reset(self, arg): """Sends an HCIReset command to the controller.""" self._connection.send(struct.pack('4b', 1, 3, 0xC, 0)) def do_quit(self, arg): """Exits the test channel.""" self._connection.close() print 'Goodbye.' return True def main(argv): if len(argv) != 3: print 'Usage: python test_channel.py [address] [port]' return try: address = str(argv[1]) port = int(argv[2]) except ValueError: print 'Error parsing address or port.' else: try: test_channel = TestChannel(address, port) except socket.error, e: print 'Error connecting to socket: %s' % e except: print 'Error creating test channel (check arguments).' else: test_channel.prompt = '$ ' test_channel.cmdloop() if __name__ == '__main__': main(sys.argv) Loading
system/vendor_libs/test_vendor_lib/include/hci_transport.h +0 −1 Original line number Diff line number Diff line Loading @@ -88,7 +88,6 @@ class HciTransport : public base::MessageLoopForIO::Watcher { // transport object, although |hci_fd_| can be closed by the HCI in // TestVendorOp(). std::unique_ptr<base::ScopedFD> hci_fd_; std::unique_ptr<base::ScopedFD> vendor_fd_; DISALLOW_COPY_AND_ASSIGN(HciTransport); Loading
system/vendor_libs/test_vendor_lib/include/packet_stream.h +17 −23 Original line number Diff line number Diff line Loading @@ -30,43 +30,37 @@ namespace test_vendor_lib { // and data from the HCI and to send controller events back to the host. class PacketStream { public: // Constructs an invalid PacketStream object whose file descriptor must be set // before use. PacketStream(); PacketStream() = default; virtual ~PacketStream() = default; // Reads a command packet and returns the packet back to the caller, along // with the responsibility of managing the packet. std::unique_ptr<CommandPacket> ReceiveCommand() const; // Reads a command packet from the file descriptor at |fd| and returns the // packet back to the caller, along with the responsibility of managing the // packet. std::unique_ptr<CommandPacket> ReceiveCommand(int fd) const; // Reads and interprets a single octet as a packet type octet. Validates the // type octet for correctness. serial_data_type_t ReceivePacketType() const; // Reads a single octet from |fd| and interprets it as a packet type octet. // Validates the type octet for correctness. serial_data_type_t ReceivePacketType(int fd) const; // Sends an event to the HCI. The ownership of the event is left with the // caller. bool SendEvent(const EventPacket& event) const; void SetFd(int fd); // Sends an event to file descriptor |fd|. The ownership of the event is left // with the caller. bool SendEvent(const EventPacket& event, int fd) const; private: // Checks if |type| is in the valid range from DATA_TYPE_COMMAND to // DATA_TYPE_SCO. bool ValidateTypeOctet(serial_data_type_t type) const; // Attempts to receive |num_octets_to_receive| into |destination|, returning // false if an error occurs. // Attempts to receive |num_octets_to_receive| into |destination| from |fd|, // returning false if an error occurs. bool ReceiveAll(std::vector<std::uint8_t>& destination, size_t num_octets_to_receive) const; size_t num_octets_to_receive, int fd) const; // Attempts to send |num_octets_to_send| from |source|, returning false if an // error occurs. // Attempts to send |num_octets_to_send| from |source| to |fd|, returning // false if an error occurs. bool SendAll(const std::vector<std::uint8_t>& source, size_t num_octets_to_send) const; // PacketStream does not take ownership of the file descriptor it uses. int fd_; size_t num_octets_to_send, int fd) const; }; } // namespace test_vendor_lib
system/vendor_libs/test_vendor_lib/include/vendor_manager.h +25 −3 Original line number Diff line number Diff line Loading @@ -62,6 +62,25 @@ class VendorManager { bool Run(); private: // Test hook object for receiving run-time parameters and commands. class TestChannel { public: TestChannel() = default; ~TestChannel(); // Waits for a connection request from the test channel program and // allocates the file descriptor to receive run-time parameters. This file // descriptor gets stored in |fd_|. bool SetUp(); int GetFd(); private: // File descriptor to watch for test hook data. int fd_; }; VendorManager(); ~VendorManager() = default; Loading Loading @@ -90,9 +109,12 @@ class VendorManager { // descriptor. base::Thread thread_; // Used to handle further watching of the vendor's file descriptor after // WatchFileDescriptor() is called. base::MessageLoopForIO::FileDescriptorWatcher manager_watcher_; // Used to handle further watching of the vendor's/test channel's file // descriptor after WatchFileDescriptor() is called. base::MessageLoopForIO::FileDescriptorWatcher hci_watcher_; base::MessageLoopForIO::FileDescriptorWatcher test_channel_watcher_; TestChannel test_channel_; // This should remain the last member so it'll be destroyed and invalidate // its weak pointers before any other members are destroyed. Loading
system/vendor_libs/test_vendor_lib/scripts/build_and_run.sh 0 → 100755 +119 −0 Original line number Diff line number Diff line #!/bin/bash # # Copyright 2015 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Builds and pushes the test vendor library to a connected device and starts # logcat with project-specific tag filters. If the --test-channel flag is set, # logcat is started in a separate process and the test channel is run in the # current shell. if [[ "$#" -ne 2 && "$#" -ne 4 ]]; then echo "Usage:" echo "./build_and_run.sh [/path/to/aosp] [device_name] or" echo "./build_and_run.sh [/path/to/aosp] [device_name] --test-channel [port]" exit 1 fi # Exit the script if any command fails. set -e # The home directory for AOSP. AOSP_ABS=$1 # The name of the device to build for. DEVICE=$2 # The location of Bluetooth within AOSP. BT_REL=/packages/modules/Bluetooth/system BT_ABS=${AOSP_ABS}${BT_REL} # The location of the test vendor library. TEST_VENDOR_LIB_REL=/vendor_libs/test_vendor_lib TEST_VENDOR_LIB_ABS=${BT_ABS}${TEST_VENDOR_LIB_REL} DEVICE_TARGET_REL=/out/target/product DEVICE_TARGET_ABS=${AOSP_ABS}${DEVICE_TARGET_REL} VENDOR_SYMBOLS_REL=/symbols/system/vendor/lib VENDOR_SYMBOLS_ABS=${DEVICE_TARGET_ABS}/${DEVICE}/${VENDOR_SYMBOLS_REL} # The name of the object built by the test vendor library. TEST_VENDOR_LIB=test-vendor.so # The name of the regular vendor object to be replaced by $TEST_VENDOR_LIB. VENDOR_LIB=libbt-vendor.so if [[ "$#" -eq 4 && $3 == "--test-channel" ]]; then TEST_CHANNEL_PORT=$4 TEST_CHANNEL_REL=/scripts TEST_CHANNEL_ABS=${TEST_VENDOR_LIB_ABS}${TEST_CHANNEL_REL} # Start logcat in a subshell. x-terminal-emulator -e "scripts/build_and_run.sh ${AOSP_ABS} ${DEVICE}" echo "Setting up build environment." cd ${AOSP_ABS} source build/envsetup.sh # Forward local port to the same port on the device. echo "Forwarding port ${TEST_CHANNEL_PORT} to device." adb forward tcp:${TEST_CHANNEL_PORT} tcp:${TEST_CHANNEL_PORT} # Turn Bluetooth on. Requires user approval via a dialog on the device. echo "Enabling Bluetooth. Please see dialog on device." adb shell am start -a android.bluetooth.adapter.action.REQUEST_ENABLE # Start the test channel once Bluetooth is on and logcat has started. read -p "Press [ENTER] once Bluetooth is enabling AND logcat has started." # Start the test channel. python ${TEST_CHANNEL_ABS}/test_channel.py localhost ${TEST_CHANNEL_PORT} else echo "Setting up build environment." cd ${AOSP_ABS} source build/envsetup.sh echo "Navigating to test vendor library: ${TEST_VENDOR_LIB_ABS}" cd ${TEST_VENDOR_LIB_ABS} echo "Building test vendor library." mm echo "Remounting device rootfs." adb shell mount -o remount,rw / adb remount # Replace the actual vendor library with the test vendor library. mv ${DEVICE_TARGET_ABS}/${DEVICE}/system/lib/${TEST_VENDOR_LIB} \ ${VENDOR_SYMBOLS_ABS}/${VENDOR_LIB} # Push the test vendor library to the device. echo "Pushing the test vendor library to device: $DEVICE" adb push ${VENDOR_SYMBOLS_ABS}/${VENDOR_LIB} /vendor/lib echo "Pushing libevent." adb push ${DEVICE_TARGET_ABS}/${DEVICE}/system/lib/libevent.so /system/lib/ echo "Pushing libchrome." adb push ${DEVICE_TARGET_ABS}/${DEVICE}/system/lib/libchrome.so /system/lib/ # Clear logcat. adb logcat -c # Run logcat with filters. adb logcat bt_btif:D bt_btif_core:D bt_hci:D bt_main:D bt_vendor:D \ bte_logmsg:D command_packet:D dual_mode_controller:D event_packet:D \ hci_transport:D hci_handler:D packet:D packet_stream:D vendor_manager:D *:S fi
system/vendor_libs/test_vendor_lib/scripts/test_channel.py 0 → 100644 +110 −0 Original line number Diff line number Diff line # # Copyright 2015 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # """Script for sending testing parameters and commands to a Bluetooth device. This script provides a simple shell interface for sending data at run-time to a Bluetooth device. It is intended to be used in tandem with the test vendor library project. Usage: Option A: Script 1. Run build_and_run.sh in scripts/ with the --test-channel flag set and the port to use for the test channel. Option B: Manual 1. Choose a port to use for the test channel. Use 'adb forward tcp:<port> tcp:<port>' to forward the port to the device. 2. In a separate shell, build and push the test vendor library to the device using the script mentioned in option A (i.e. without the --test-channel flag set). 3. Once logcat has started, turn Bluetooth on from the device. 4. Run this program, in the shell from step 1, with address 'localhost' and the port, also from step 1, as arguments. """ #!/usr/bin/env python import cmd import socket import struct import sys class Connection(object): """Simple wrapper class for a socket object. Attributes: socket: The underlying socket created for the specified address and port. """ def __init__(self, address, port): self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._socket.connect((address, port)) def close(self): self._socket.close() def send(self, data): self._socket.send(data) class TestChannel(cmd.Cmd): """Shell for sending test channel data to controller. Manages the connection for the test channel to the controller and defines a set of commands the user can send to the controller as well. These commands are processed parallel to commands sent from the device stack and used to provide additional debugging/testing capabilities. Attributes: connection: The communication channel to send data to the controller. """ def __init__(self, address, port): print 'Type \'help\' for more information.' cmd.Cmd.__init__(self) self._connection = Connection(address, port) def do_hci_reset(self, arg): """Sends an HCIReset command to the controller.""" self._connection.send(struct.pack('4b', 1, 3, 0xC, 0)) def do_quit(self, arg): """Exits the test channel.""" self._connection.close() print 'Goodbye.' return True def main(argv): if len(argv) != 3: print 'Usage: python test_channel.py [address] [port]' return try: address = str(argv[1]) port = int(argv[2]) except ValueError: print 'Error parsing address or port.' else: try: test_channel = TestChannel(address, port) except socket.error, e: print 'Error connecting to socket: %s' % e except: print 'Error creating test channel (check arguments).' else: test_channel.prompt = '$ ' test_channel.cmdloop() if __name__ == '__main__': main(sys.argv)