aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/nRF5_SDK_15.0.0_a53641a/examples/proprietary_rf/gzll/gzp_desktop_emulator/main_mouse_keyboard_emulator.c
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/examples/proprietary_rf/gzll/gzp_desktop_emulator/main_mouse_keyboard_emulator.c')
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/examples/proprietary_rf/gzll/gzp_desktop_emulator/main_mouse_keyboard_emulator.c417
1 files changed, 417 insertions, 0 deletions
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/examples/proprietary_rf/gzll/gzp_desktop_emulator/main_mouse_keyboard_emulator.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/examples/proprietary_rf/gzll/gzp_desktop_emulator/main_mouse_keyboard_emulator.c
new file mode 100644
index 0000000..b3eb994
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/examples/proprietary_rf/gzll/gzp_desktop_emulator/main_mouse_keyboard_emulator.c
@@ -0,0 +1,417 @@
+/**
+ * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**
+ * This project can be used as a starting point for developing a nRF5x series
+ * mouse or keyboard using Gazell for communicating with a legacy nRF24LU1
+ * USB dongle. It can communicate "out of the box" with the
+ * Dongle reference design and the nRFreadySimplePairing.exe application,
+ * that can be found in the nRFready Desktop v1.2.3.
+ *
+ * This project sends mouse movement packets to the USB dongle when pin 1
+ * is low (button connected to pin 1 pressed) and sends the 'a' keyboard
+ * character to the USB dongle when pin 2 goes from high to low (button
+ * connected to pin 2 pressed).
+ */
+
+#include <stdio.h>
+#include "nrf_gzll.h"
+#include "nrf_gzp.h"
+#include "bsp.h"
+#include "nordic_common.h"
+#include "nrf_gzllde_params.h"
+#include "mouse_sensor_emulator.h"
+#include "keyboard_emulator.h"
+#include "nrf_gzll_error.h"
+
+
+#include "nrf_log.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_log_default_backends.h"
+
+/*****************************************************************************/
+/** @name Configuration */
+/*****************************************************************************/
+#define SEND_KEYBOARD_DATA_BUTTON_ID 0 ///< GPIO pin for reading from a button to emulate a keypress.
+#define SEND_MOUSE_DATA_BUTTON_ID 1 ///< GPIO pin for reading from a button to emulate a mouse movement.
+
+
+/*****************************************************************************/
+/** @name Static (internal) functions. */
+/*****************************************************************************/
+
+/**
+ * Checks to see whether the mouse sensor has data to send. If so, adds this
+ * to the (unencrypted) Gazell TX FIFO on pipe NRFR_MOUSE_EP.
+ */
+static void read_mouse_and_send(void);
+
+
+/**
+ * Checks to see whether the mouse sensor has data and send unencrypted.
+ *
+ * If so, adds this to the (unencrypted) Gazell TX FIFO on pipe NRFR_MOUSE_EP.
+ */
+
+/**
+ * Checks to see whether the keyboard has data and send encrypted.
+ *
+ * If the Device does net yet have the system address it will try to
+ * obtain it. After obtaining the system address it will attempt to obtain
+ * the Host ID.
+ * The keyboard data is discarded if pairing is not successful.
+ * It may take a few attempts to obtain the Host ID as this may not be
+ * yet generated at the Host.
+ */
+static void read_keyboard_and_send(void);
+
+/**
+ * Send a Host ID request and process the response.
+ *
+ * If the request was rejected or failed (i.e. timed out), system_addr_received
+ * will be reset and the pairing process will begin on the next keypress.
+ *
+ * If the request was received, subsequent keyboard data will be transmitted
+ * on an encrypted link.
+ *
+ * If teh request is still pending, nothing is done. Further keypresses
+ * will initiate another
+ *
+ * @return The result of the Host ID request.
+ */
+static gzp_id_req_res_t send_host_id_req(void);
+/** @} */
+
+static void error_report(void);
+
+static bool host_id_received = false; ///< Host ID received.
+static bool system_addr_received = false; ///< System address receivedfrom Host.
+static bool dyn_key_ok = false; ///< Dynamic key is up to date.
+
+static bool prev_host_id_received = true; ///< Host ID received.
+static bool prev_system_addr_received = true; ///< System address receivedfrom Host.
+static bool prev_dyn_key_ok = true; ///< Dynamic key is up to date.
+
+
+/*****************************************************************************/
+/**
+ * @brief Main function.
+ *
+ * @return ANSI required int return type.
+ */
+/*****************************************************************************/
+
+
+int main()
+{
+ bool result_value = false;
+ uint32_t err_code;
+
+// lint -save -e514 Unusual use of a boolean expression (use of &= assignment).
+
+ UNUSED_VARIABLE(bsp_init(BSP_INIT_BUTTONS, NULL));
+
+ err_code = NRF_LOG_INIT(NULL);
+ APP_ERROR_CHECK(err_code);
+
+ NRF_LOG_DEFAULT_BACKENDS_INIT();
+
+ NRF_LOG_INFO("Desktop emulator example");
+ NRF_LOG_FLUSH();
+
+ // Initialize and enable "mouse sensor"
+ result_value = mouse_sensor_init(MOUSE_SENSOR_SAMPLE_PERIOD_8_MS);
+ APP_ERROR_CHECK_BOOL(result_value);
+
+ mouse_sensor_enable();
+
+ // Initialize and enable Gazell
+ result_value = nrf_gzll_init(NRF_GZLL_MODE_DEVICE);
+ GAZELLE_ERROR_CODE_CHECK(result_value);
+
+ // Ensure Gazell parameters are configured.
+ nrf_gzll_set_max_tx_attempts(150);
+
+ result_value = nrf_gzll_set_device_channel_selection_policy(
+ NRF_GZLLDE_DEVICE_CHANNEL_SELECTION_POLICY);
+ GAZELLE_ERROR_CODE_CHECK(result_value);
+
+ result_value = nrf_gzll_set_timeslot_period(NRF_GZLLDE_RXPERIOD_DIV_2);
+ GAZELLE_ERROR_CODE_CHECK(result_value);
+
+ result_value = nrf_gzll_set_sync_lifetime(0); // Asynchronous mode, more efficient for pairing.
+ GAZELLE_ERROR_CODE_CHECK(result_value);
+
+ switch (gzp_get_pairing_status())
+ {
+ case -2:
+ host_id_received = false;
+ system_addr_received = false;
+ break;
+
+ case -1:
+ host_id_received = false;
+ system_addr_received = true;
+ break;
+
+ default:
+ host_id_received = true;
+ system_addr_received = true;
+ }
+
+ gzp_init();
+
+ result_value = nrf_gzll_enable();
+ GAZELLE_ERROR_CODE_CHECK(result_value);
+
+ while (1)
+ {
+ // If BUTTON_SEND_MOUSE_DATA button is pressed.
+ if ( bsp_button_is_pressed(SEND_MOUSE_DATA_BUTTON_ID))
+ {
+ read_mouse_and_send();
+ }
+
+ // If BUTTON_SEND_KEYBOARD_DATA button is pressed
+ if (bsp_button_is_pressed(SEND_KEYBOARD_DATA_BUTTON_ID))
+ {
+ read_keyboard_and_send();
+ }
+
+ error_report();
+
+ }
+// lint -restore
+}
+
+
+void mouse_sensor_new_sample_generated_cb()
+{
+ /*
+ This callback is called every time the mouse sensor
+ generates a new sample. We could select to add mouse packets to the
+ TX FIFO here.
+ */
+}
+
+
+static void read_mouse_and_send(void)
+{
+// lint -save -e514 Unusual use of a boolean expression (use of &= assignment).
+ bool mouse_send_ok;
+
+ // If the "mouse sensor" has data ready for read-out.
+ if (mouse_sensor_data_is_ready())
+ {
+ uint8_t mouse_packet[NRFR_MOUSE_MOV_PACKET_LENGTH];
+
+ // Get packet from "mouse sensor".
+ if (mouse_sensor_read(mouse_packet))
+ {
+ // Wait in case the FIFOs are full.
+ while (!nrf_gzll_ok_to_add_packet_to_tx_fifo(NRFR_MOUSE_EP))
+ ;
+
+ // Add mouse packet to the mouse pipe's TX FIFO.
+ mouse_send_ok = nrf_gzll_add_packet_to_tx_fifo(NRFR_MOUSE_EP,
+ mouse_packet,
+ NRFR_MOUSE_MOV_PACKET_LENGTH);
+ if (mouse_send_ok)
+ {
+ NRF_LOG_INFO("Mouse sent OK");
+ }
+ else
+ {
+ NRF_LOG_INFO("Mouse sent FAILED");
+ }
+
+ NRF_LOG_FLUSH();
+ }
+ }
+
+
+// lint -restore
+}
+
+
+static void read_keyboard_and_send(void)
+{
+ uint8_t keyboard_packet[NRFR_KEYBOARD_PACKET_LENGTH];
+
+ // "Scan" keyboard.
+ keyboard_get_non_empty_packet(keyboard_packet);
+
+ // Send address request if required.
+ if (!host_id_received && !system_addr_received)
+ {
+ system_addr_received = gzp_address_req_send();
+ }
+
+ /* Send Host ID request if required. This may take a few attempts
+ * as the Host may require some time to generate the Host ID. */
+ if (!host_id_received && system_addr_received )
+ {
+ while (send_host_id_req() == GZP_ID_RESP_PENDING)
+ ;
+ }
+
+ /* After receiving the Host ID we send one packet in order
+ * to update the dynamic key.
+ */
+ if (host_id_received && !dyn_key_ok)
+ {
+ bool keyboard_send_ok = true;
+ keyboard_send_ok = gzp_crypt_data_send(keyboard_packet,
+ NRFR_KEYBOARD_PACKET_LENGTH);
+
+ if (!keyboard_send_ok)
+ {
+ host_id_received = false;
+ }
+ else
+ {
+ dyn_key_ok = true;
+ }
+ }
+
+ /* If we have the Host ID and dynamic key we can transmit encrypted data.
+ */
+ if (host_id_received && dyn_key_ok)
+ {
+ bool keyboard_send_ok = true;
+ keyboard_send_ok = gzp_crypt_data_send(keyboard_packet,
+ NRFR_KEYBOARD_PACKET_LENGTH);
+
+ if (keyboard_send_ok)
+ {
+ NRF_LOG_INFO("Keyboard sent OK");
+ }
+ else
+ {
+ NRF_LOG_INFO("Keyboard sent FAILED");
+ }
+
+ if (keyboard_send_ok)
+ {
+ // Wait until button is released.
+ while (bsp_button_is_pressed(SEND_KEYBOARD_DATA_BUTTON_ID))
+ {
+ }
+
+ // Send empty keyboard packet to release all keys.
+ keyboard_get_empty_packet(keyboard_packet);
+ keyboard_send_ok = gzp_crypt_data_send(keyboard_packet, NRFR_KEYBOARD_PACKET_LENGTH);
+ }
+
+ if (!keyboard_send_ok)
+ {
+ dyn_key_ok = false;
+ }
+
+ NRF_LOG_FLUSH();
+ }
+
+}
+
+
+static gzp_id_req_res_t send_host_id_req(void)
+{
+ gzp_id_req_res_t id_resp;
+
+ // Try sending "Host ID" request
+ id_resp = gzp_id_req_send();
+
+ switch (id_resp)
+ {
+ case GZP_ID_RESP_REJECTED:
+ case GZP_ID_RESP_FAILED:
+ host_id_received = false;
+ system_addr_received = false;
+ break;
+
+ case GZP_ID_RESP_GRANTED:
+ host_id_received = true;
+ system_addr_received = true;
+ break;
+
+ case GZP_ID_RESP_PENDING:
+ default:
+ break;
+ }
+
+ return id_resp;
+}
+
+
+static void error_report(void)
+{
+ if (~system_addr_received & prev_system_addr_received)
+ {
+ prev_system_addr_received = false;
+ NRF_LOG_INFO("System address not received");
+ }
+ else if (system_addr_received)
+ {
+ prev_system_addr_received = true;
+ }
+
+ if (~host_id_received & prev_host_id_received)
+ {
+ prev_host_id_received = false;
+ NRF_LOG_INFO("Host ID not received");
+ }
+ else if (host_id_received)
+ {
+ prev_host_id_received = true;
+ }
+
+ if (~dyn_key_ok & prev_dyn_key_ok)
+ {
+ prev_dyn_key_ok = false;
+ NRF_LOG_INFO("Dyn Key not received");
+ }
+ else if (dyn_key_ok)
+ {
+ prev_dyn_key_ok = true;
+ }
+
+ NRF_LOG_FLUSH();
+}
+
+