mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Add rf tester commands to cordio hci driver. This adds commands that allow you to send the HCI commands HCI_LE_Receiver_Test, HCI_LE_Transmitter_Test and HCI_LE_Test_End. The results of the test are obtained by the command complete command for HCI_LE_Test_End and passed to the user by the callback register in the test start calls.
							parent
							
								
									51d1a30b8e
								
							
						
					
					
						commit
						fbe93123a5
					
				| 
						 | 
				
			
			@ -286,6 +286,83 @@ uint16_t CordioHCIDriver::write(uint8_t type, uint16_t len, uint8_t *pData)
 | 
			
		|||
void CordioHCIDriver::on_host_stack_inactivity()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
void CordioHCIDriver::handle_test_end(bool success, uint16_t packets) {
 | 
			
		||||
    if (_test_end_handler) {
 | 
			
		||||
        _test_end_handler(success, packets);
 | 
			
		||||
        _test_end_handler = nullptr;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ble_error_t CordioHCIDriver::rf_test_start_le_receiver_test(
 | 
			
		||||
    test_end_handler_t test_end_handler, uint8_t channel
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    if (_test_end_handler) {
 | 
			
		||||
        return BLE_ERROR_INVALID_STATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!test_end_handler) {
 | 
			
		||||
        return BLE_ERROR_INVALID_PARAM;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _test_end_handler = test_end_handler;
 | 
			
		||||
    uint8_t *buf = hciCmdAlloc(HCI_OPCODE_LE_RECEIVER_TEST, HCI_LEN_LE_RECEIVER_TEST);
 | 
			
		||||
 | 
			
		||||
    if (buf) {
 | 
			
		||||
        uint8_t* p = buf + HCI_CMD_HDR_LEN;
 | 
			
		||||
        UINT8_TO_BSTREAM(p, channel);
 | 
			
		||||
        hciCmdSend(buf);
 | 
			
		||||
 | 
			
		||||
        return BLE_ERROR_NONE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return BLE_ERROR_NO_MEM;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ble_error_t CordioHCIDriver::rf_test_start_le_transmitter_test(
 | 
			
		||||
    test_end_handler_t test_end_handler, uint8_t channel, uint8_t length, uint8_t type
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    if (_test_end_handler) {
 | 
			
		||||
        return BLE_ERROR_INVALID_STATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!test_end_handler) {
 | 
			
		||||
        return BLE_ERROR_INVALID_PARAM;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _test_end_handler = test_end_handler;
 | 
			
		||||
    uint8_t *buf = hciCmdAlloc(HCI_OPCODE_LE_TRANSMITTER_TEST, HCI_LEN_LE_TRANSMITTER_TEST);
 | 
			
		||||
 | 
			
		||||
    if (buf) {
 | 
			
		||||
        uint8_t* p = buf + HCI_CMD_HDR_LEN;
 | 
			
		||||
        UINT8_TO_BSTREAM(p, channel);
 | 
			
		||||
        UINT8_TO_BSTREAM(p, length);
 | 
			
		||||
        UINT8_TO_BSTREAM(p, type);
 | 
			
		||||
        hciCmdSend(buf);
 | 
			
		||||
 | 
			
		||||
        return BLE_ERROR_NONE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return BLE_ERROR_NO_MEM;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ble_error_t CordioHCIDriver::rf_test_end()
 | 
			
		||||
{
 | 
			
		||||
    if (!_test_end_handler) {
 | 
			
		||||
        return BLE_ERROR_INVALID_STATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint8_t *buf = hciCmdAlloc(HCI_OPCODE_LE_TEST_END, HCI_LEN_LE_TEST_END);
 | 
			
		||||
 | 
			
		||||
    if (buf) {
 | 
			
		||||
        hciCmdSend(buf);
 | 
			
		||||
 | 
			
		||||
        return BLE_ERROR_NONE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return BLE_ERROR_NO_MEM;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace cordio
 | 
			
		||||
} // namespace vendor
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,8 @@
 | 
			
		|||
#include <BLETypes.h>
 | 
			
		||||
#include "wsf_buf.h"
 | 
			
		||||
#include "CordioHCITransportDriver.h"
 | 
			
		||||
#include "ble/blecommon.h"
 | 
			
		||||
#include "mbed.h"
 | 
			
		||||
 | 
			
		||||
namespace ble {
 | 
			
		||||
namespace vendor {
 | 
			
		||||
| 
						 | 
				
			
			@ -144,6 +146,47 @@ public:
 | 
			
		|||
     */
 | 
			
		||||
     virtual void on_host_stack_inactivity();
 | 
			
		||||
 | 
			
		||||
     /* BLE Tester commands */
 | 
			
		||||
 | 
			
		||||
     /**
 | 
			
		||||
      * This will be called by host part of the stack to indicate the end of the test.
 | 
			
		||||
      *
 | 
			
		||||
      * @param success True if the TEST END command was a success.
 | 
			
		||||
      * @param packets Number of packets received during the test.
 | 
			
		||||
      * @return BLE_ERROR_NONE on success.
 | 
			
		||||
      */
 | 
			
		||||
     void handle_test_end(bool success, uint16_t packets);
 | 
			
		||||
 | 
			
		||||
     /** Callback to inform the caller of the result of the test, the parameters are success and the
 | 
			
		||||
      *  number of packets received.
 | 
			
		||||
      */
 | 
			
		||||
     typedef mbed::Callback<void(bool, uint16_t)> test_end_handler_t;
 | 
			
		||||
 | 
			
		||||
     /**
 | 
			
		||||
      * Start BLE receiver test. Call rf_test_end when you want to stop.
 | 
			
		||||
      * @param test_end_handler Handler that will be called with the number of packets received.
 | 
			
		||||
      * @param channel Channel to use.
 | 
			
		||||
      * @return BLE_ERROR_NONE on success.
 | 
			
		||||
      */
 | 
			
		||||
     ble_error_t rf_test_start_le_receiver_test(test_end_handler_t test_end_handler, uint8_t channel);
 | 
			
		||||
 | 
			
		||||
     /**
 | 
			
		||||
      * Start BLE transmitter test. Call rf_test_end when you want to stop.
 | 
			
		||||
      * @param test_end_handler Handler that will be called with status and the number of packets set to 0.
 | 
			
		||||
      * @param channel Channel to use.
 | 
			
		||||
      * @param length Size of payload.
 | 
			
		||||
      * @param type Type of pattern to transmit @see BLE spec Volume 6 Part F, Section 4.1.5.
 | 
			
		||||
      * @return BLE_ERROR_NONE on success.
 | 
			
		||||
      */
 | 
			
		||||
     ble_error_t rf_test_start_le_transmitter_test(test_end_handler_t test_end_handler, uint8_t channel,
 | 
			
		||||
                                                           uint8_t length, uint8_t type);
 | 
			
		||||
 | 
			
		||||
     /**
 | 
			
		||||
      * Complete the test. This will trigger the end test event which will call handle_test_end
 | 
			
		||||
      * @return BLE_ERROR_NONE on success.
 | 
			
		||||
      */
 | 
			
		||||
     ble_error_t rf_test_end();
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    /**
 | 
			
		||||
     * Return a default set of memory pool that the Cordio stack can use.
 | 
			
		||||
| 
						 | 
				
			
			@ -170,6 +213,9 @@ private:
 | 
			
		|||
     */
 | 
			
		||||
    virtual void do_terminate() = 0;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    test_end_handler_t _test_end_handler;
 | 
			
		||||
private:
 | 
			
		||||
    CordioHCITransportDriver& _transport_driver;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,6 +34,7 @@
 | 
			
		|||
#include "hci_drv.h"
 | 
			
		||||
#include "CordioBLE.h"
 | 
			
		||||
#include "mbed_assert.h"
 | 
			
		||||
#include "bstream.h"
 | 
			
		||||
 | 
			
		||||
#include "CordioPalAttClient.h"
 | 
			
		||||
#include "CordioPalSecurityManager.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -311,6 +312,22 @@ void BLE::processEvents()
 | 
			
		|||
            deviceInstance().initialization_status = INITIALIZED;
 | 
			
		||||
            _init_callback.call(&context);
 | 
			
		||||
        }   break;
 | 
			
		||||
#if MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS
 | 
			
		||||
        case DM_UNHANDLED_CMD_CMPL_EVT_IND: {
 | 
			
		||||
            // upcast to unhandled command complete event to access the payload
 | 
			
		||||
            hciUnhandledCmdCmplEvt_t* unhandled = (hciUnhandledCmdCmplEvt_t*)msg;
 | 
			
		||||
            if (unhandled->hdr.status == HCI_SUCCESS && unhandled->hdr.param == HCI_OPCODE_LE_TEST_END) {
 | 
			
		||||
                // unhandled events are not parsed so we need to parse the payload ourselves
 | 
			
		||||
                uint8_t status;
 | 
			
		||||
                uint16_t packet_number;
 | 
			
		||||
                status = unhandled->param[0];
 | 
			
		||||
                BYTES_TO_UINT16(packet_number, unhandled->param + 1);
 | 
			
		||||
 | 
			
		||||
                _hci_driver->handle_test_end(status == 0, packet_number);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
#endif // MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            impl::PalGapImpl::gap_handler(msg);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue