aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/nRF5_SDK_15.0.0_a53641a/examples/ble_central_and_peripheral/experimental/ble_app_interactive/cli_m.c
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/examples/ble_central_and_peripheral/experimental/ble_app_interactive/cli_m.c')
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/examples/ble_central_and_peripheral/experimental/ble_app_interactive/cli_m.c2121
1 files changed, 2121 insertions, 0 deletions
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/examples/ble_central_and_peripheral/experimental/ble_app_interactive/cli_m.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/examples/ble_central_and_peripheral/experimental/ble_app_interactive/cli_m.c
new file mode 100644
index 0000000..e551620
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/examples/ble_central_and_peripheral/experimental/ble_app_interactive/cli_m.c
@@ -0,0 +1,2121 @@
+/**
+ * Copyright (c) 2018 - 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.
+ *
+ */
+
+#include <ctype.h>
+#include "cli_m.h"
+#include "nrf_cli.h"
+#include "nrf_ble_gatt.h"
+#include "nrf_log.h"
+#include "ble_m.h"
+#include "ble_hci.h"
+#include "ble_conn_params.h"
+#include "peer_manager.h"
+#include "nfc_m.h"
+#include "nfc_central_m.h"
+#include "adafruit_pn532.h"
+
+#define UNKNOWN_PARAMETER "unknown parameter: "
+#define WRONG_PARAMETER_COUNT "wrong parameter count \r\n"
+#define KEY_PASSKEY_LEN (6U)
+
+#define UNIT_TO_MSEC(uint, resolution) (uint16_t)(((uint) * (resolution)) / 1000) /**< Macro for converting ticks into milliseconds. */
+
+#define SEC_PARAM_CENTRAL_DEFAULT \
+ { \
+ .bond = 1, \
+ .mitm = 0, \
+ .lesc = 0, \
+ .keypress = 0, \
+ .io_caps = BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY, \
+ .oob = 0, \
+ .min_key_size = BLE_SEC_PARAM_MIN_KEY_SIZE, \
+ .max_key_size = BLE_SEC_PARAM_MAX_KEY_SIZE, \
+ .kdist_own.enc = 1, \
+ .kdist_own.id = 1, \
+ .kdist_peer.enc = 1, \
+ .kdist_peer.id = 1, \
+ }
+
+typedef union
+{
+ char connect_addr_cmd_buffer[DEVICE_TO_FIND_MAX][CLI_MAX_CMD_LEN]; /**< Device address from scan buffer. */
+ char connected_cmd_buffer[NRF_BLE_LINK_COUNT][CLI_MAX_CMD_LEN]; /**< Connected device address buffer. */
+ char bond_cmd_buffer[BOND_DEVICE_MAX][CLI_MAX_CMD_LEN]; /**< Bonded device address buffer. */
+} cli_cmd_buffer_t;
+
+typedef struct
+{
+ cli_cmd_buffer_t buffer_type; /**< Dynamic command buffer type. */
+ uint8_t cmd_counter; /**< Dynamic command counter. */
+} cli_cmd_connect_addr_t;
+
+typedef enum
+{
+ CLI_CMD_CONNECT_ADDR, /**< Device address from scan. */
+ CLI_CMD_CONNECTED, /**< Connected device address. */
+ CLI_CMD_BONDED, /**< Bonded device address. */
+} cli_cmd_buffer_type_t;
+
+bool m_key_request_event = false; /**< Flag informing about a key request event. */
+char m_device_name[DEVICE_NAME_MAX_SIZE]; /**< Device name. */
+uint16_t m_conn_handle; /**< Connection handle for pairing and key request. */
+cli_cmd_connect_addr_t m_cli_connect_addr; /**< List of BLE address strings for all devices found during scanning using as CLI commands. */
+cli_cmd_connect_addr_t m_cli_connected; /**< List of connected devices address string using as CLI commands. */
+cli_cmd_connect_addr_t m_cli_bonded; /**< List of bonded devices address string using as CLI commands. */
+ble_gap_sec_params_t m_sec_params_central = SEC_PARAM_CENTRAL_DEFAULT;
+ble_gap_conn_params_t m_params_update =
+{
+ .min_conn_interval = MIN_CONNECTION_INTERVAL,
+ .max_conn_interval = MAX_CONNECTION_INTERVAL,
+ .slave_latency = SLAVE_LATENCY,
+ .conn_sup_timeout = SUPERVISION_TIMEOUT
+};
+
+
+/**@Function for verification connection handle.
+ */
+static inline bool conn_handle_is_valid(uint16_t conn_handle, nrf_cli_t const * p_cli)
+{
+ if (conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Invalid device address\r\n");
+ return false;
+ }
+
+ return true;
+}
+
+
+/**@Function for verification of the error code.
+ */
+static inline void ret_code_verify(ret_code_t err_code)
+{
+ if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE))
+ {
+ APP_ERROR_CHECK(err_code);
+ }
+}
+
+
+/* Function required by qsort */
+static int string_cmp(void const * p_a, void const * p_b)
+{
+ ASSERT(p_a);
+ ASSERT(p_b);
+ return strcmp( (char const *)p_a, (char const *)p_b);
+}
+
+
+/**@brief Function for adding BLE address string as command to the dynamic command buffer.
+ *
+ * @param[in] p_data BLE address to remove.
+ * @param[in] p_cli_buffer Dynamic command buffer.
+ * @param[in] type Type of the dynamic command buffer.
+ */
+static void cli_addr_string_to_command_add(uint8_t const * p_data,
+ cli_cmd_connect_addr_t * p_cli_buffer,
+ cli_cmd_buffer_type_t type)
+{
+ uint8_t idx;
+ uint8_t size;
+ uint8_t * p_cmd_counter = &p_cli_buffer->cmd_counter;
+ char (*p_buffer)[CLI_MAX_CMD_LEN];
+
+ switch (type)
+ {
+ case CLI_CMD_CONNECT_ADDR:
+ size = DEVICE_TO_FIND_MAX;
+ p_buffer = p_cli_buffer->buffer_type.connect_addr_cmd_buffer;
+ break;
+
+ case CLI_CMD_CONNECTED:
+ size = NRF_BLE_LINK_COUNT;
+ p_buffer = p_cli_buffer->buffer_type.connected_cmd_buffer;
+ break;
+
+ case CLI_CMD_BONDED:
+ size = BOND_DEVICE_MAX;
+ p_buffer = p_cli_buffer->buffer_type.bond_cmd_buffer;
+ break;
+
+ default:
+ return;
+
+ }
+
+ char string_buf[ADDR_STRING_LEN];
+
+ memset(string_buf, 0, ADDR_STRING_LEN);
+
+ // Address conversion to string.
+ int_addr_to_hex_str(string_buf, BLE_GAP_ADDR_LEN, p_data);
+
+ // If no place in buffer then return.
+ if (*p_cmd_counter >= size)
+ {
+ return;
+ }
+
+ // Check if the address is repeated.
+ for (idx = 0; idx < size; idx++)
+ {
+ if (!strcmp(p_buffer[idx], string_buf))
+ {
+ return;
+ }
+ }
+
+ //Add address to buffer.
+ sprintf(p_buffer[(*p_cmd_counter)++], "%s", string_buf);
+ qsort(p_buffer,
+ *p_cmd_counter,
+ sizeof(p_buffer[0]),
+ string_cmp);
+}
+
+
+/**@brief Function for removing a BLE address string from the dynamic command buffer.
+ *
+ * @param[in] p_data BLE address to remove.
+ * @param[in] p_cli_buffer Dynamic command buffer.
+ * @param[in] type Type of the dynamic command buffer.
+ */
+static void cli_addr_from_command_remove(char * const p_data,
+ cli_cmd_connect_addr_t * p_cli_buffer,
+ cli_cmd_buffer_type_t type)
+{
+ uint8_t size;
+ uint8_t * p_cmd_counter = &p_cli_buffer->cmd_counter;
+ char (*p_buffer)[CLI_MAX_CMD_LEN];
+
+ switch (type)
+ {
+ case CLI_CMD_CONNECT_ADDR:
+ size = DEVICE_TO_FIND_MAX;
+ p_buffer = p_cli_buffer->buffer_type.connect_addr_cmd_buffer;
+ break;
+
+ case CLI_CMD_CONNECTED:
+ size = NRF_BLE_LINK_COUNT;
+ p_buffer = p_cli_buffer->buffer_type.connected_cmd_buffer;
+ break;
+
+ case CLI_CMD_BONDED:
+ size = BOND_DEVICE_MAX;
+ p_buffer = p_cli_buffer->buffer_type.bond_cmd_buffer;
+ break;
+
+ default:
+ return;
+
+ }
+ for (uint8_t idx = 0; idx < *p_cmd_counter; idx++)
+ {
+ if (!strcmp(p_buffer[idx], p_data))
+ {
+ if (idx == size - 1)
+ {
+ p_buffer[idx][0] = '\0';
+ }
+ else
+ {
+ memmove(p_buffer[idx],
+ p_buffer[idx + 1],
+ sizeof(p_buffer[idx]) * (*p_cmd_counter - idx));
+ }
+
+ --(*p_cmd_counter);
+
+ return;
+ }
+ }
+}
+
+
+void connected_to_cmd_add(conn_peer_t * p_connected_peers, uint16_t conn_handle)
+{
+ ASSERT(p_connected_peers);
+
+ cli_addr_string_to_command_add(p_connected_peers[conn_handle].address.addr,
+ &m_cli_connected,
+ CLI_CMD_CONNECTED);
+}
+
+
+void connected_to_cmd_remove(conn_peer_t * p_connected_peers, uint16_t conn_handle)
+{
+ ASSERT(p_connected_peers);
+
+ char string_addr_buf[ADDR_STRING_LEN];
+
+ // Convert address to format XX:XX:XX:XX:XX:XX.
+ int_addr_to_hex_str(string_addr_buf,
+ BLE_GAP_ADDR_LEN,
+ p_connected_peers[conn_handle].address.addr);
+
+ // Remove address from command buffer.
+ cli_addr_from_command_remove(string_addr_buf,
+ &m_cli_connected,
+ CLI_CMD_CONNECTED);
+}
+
+
+void address_to_cmd_add(ble_gap_addr_t const * p_connected_addr)
+{
+ ASSERT(p_connected_addr);
+ // Add address to command buffer.
+ cli_addr_string_to_command_add(p_connected_addr->addr,
+ &m_cli_connect_addr,
+ CLI_CMD_CONNECT_ADDR);
+}
+
+
+void connect_addr_clear(void)
+{
+ /* Erasing the dynamically created command (address, name) and commands counters */
+ memset(&m_cli_connect_addr, 0, sizeof(m_cli_connect_addr));
+}
+
+
+void bond_get(void)
+{
+ ret_code_t err_code;
+ pm_peer_id_t current_peer_id = pm_next_peer_id_get(PM_PEER_ID_INVALID);
+
+ memset(&m_cli_bonded, 0, sizeof(m_cli_bonded));
+
+ // Reading all peer`s bonding data.
+ while (current_peer_id != PM_PEER_ID_INVALID)
+ {
+ pm_peer_data_bonding_t p_data;
+
+ err_code = pm_peer_data_bonding_load(current_peer_id, &p_data);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Add bonded device address to CLI commands.
+ cli_addr_string_to_command_add(p_data.peer_ble_id.id_addr_info.addr,
+ &m_cli_bonded,
+ CLI_CMD_BONDED);
+ }
+
+ current_peer_id = pm_next_peer_id_get(current_peer_id);
+ }
+}
+
+
+void bonds_delete(void)
+{
+ ret_code_t err_code;
+
+ // Delete all data stored for all peers.
+ err_code = pm_peers_delete();
+ APP_ERROR_CHECK(err_code);
+ memset(&m_cli_bonded, 0, sizeof(m_cli_bonded) );
+}
+
+
+void key_request_set(void)
+{
+ m_key_request_event = true;
+}
+
+
+/**@brief Function for setting the PHY.
+ *
+ * @param[in] value New PHY value.
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ */
+static void phy_set(nrf_cli_t const * p_cli, uint8_t value, uint16_t conn_handle)
+{
+ ble_gap_phys_t phy =
+ {
+ .rx_phys = value,
+ .tx_phys = value,
+ };
+
+ // Set new PHY value.
+ preferred_phy_set(&phy, conn_handle);
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Preferred PHY set to %s.\r\n", phy_str(&phy));
+}
+
+
+/**@brief Function for restoring the default connection parameters.
+ *
+ * @param[out] Pointer to conn_params.
+ */
+static void default_con_param(ble_gap_conn_params_t * p_params_update)
+{
+ p_params_update->min_conn_interval = MIN_CONNECTION_INTERVAL;
+ p_params_update->max_conn_interval = MAX_CONNECTION_INTERVAL;
+ p_params_update->slave_latency = SLAVE_LATENCY;
+ p_params_update->conn_sup_timeout = SUPERVISION_TIMEOUT;
+}
+
+
+/**@brief Function for printing the connectable devices.
+ *
+ *@details Function print list of available to connect device address and name (if exist).
+ * Display format: XX:XX:XX:XX:XX:XX device_name .
+ *
+ * @param[in] p_cli Pointer to the instance of the command line module.
+ * @param[in] device Pointer to the struct storing the scanned devices.
+ */
+static void device_list_print(nrf_cli_t const * p_cli, scanned_device_t * p_device)
+{
+ for (uint8_t i = 0; i < DEVICE_TO_FIND_MAX; i++)
+ {
+ if (p_device[i].is_not_empty)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Device ");
+
+ char buffer[ADDR_STRING_LEN];
+ int_addr_to_hex_str(buffer, BLE_GAP_ADDR_LEN, p_device[i].addr);
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%s %s\r\n", buffer, p_device[i].dev_name);
+ }
+ }
+}
+
+
+/**@brief Function for setting the CCCD Descriptor value.
+ *
+ * @param[in] p_cli Instance of the command line.
+ * @param[in] cccd New CCCD value.
+ * @param[in] addr Device address in string format.
+ * @param[in] uuid Characteristic UUID in string format.
+ */
+static void cccd_set(nrf_cli_t const * p_cli, uint16_t cccd, char * p_addr, char * p_uuid)
+{
+ uint16_t conn_handle;
+ uint16_t desc_handle;
+ ret_code_t err_code;
+ ble_gattc_write_params_t write_params;
+
+ // Search for connection handle.
+ conn_handle = addr_string_to_conn_handle(p_addr);
+
+ if(!conn_handle_is_valid(conn_handle, p_cli))
+ {
+ return;
+ }
+
+ memset(&write_params, 0, sizeof(write_params));
+
+ desc_handle = cccd_descriptors_handle_get(p_uuid);
+
+ if (desc_handle == BLE_GATT_HANDLE_INVALID)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "Wrong characteristic UUID or the CCCD descriptor has not been found yet\r\n");
+ return;
+ }
+
+ uint16_t cccd_val = cccd;
+ uint8_t data_buf[2] = {LSB_16(cccd_val), MSB_16(cccd_val)};
+ uint8_t data_len = sizeof(data_buf);
+
+ write_params.write_op = BLE_GATT_OP_WRITE_REQ;
+ write_params.handle = desc_handle;
+ write_params.len = data_len;
+ write_params.p_value = data_buf;
+ write_params.offset = 0;
+ write_params.flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE;
+
+ // Set CCCD descriptor value.
+ err_code = sd_ble_gattc_write(conn_handle, &write_params);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "wrong characteristic UUID or the CCCD descriptor has not been found yet\r\n");
+ }
+}
+
+
+/**@brief Command handler for displaying the connected devices.
+ */
+static void cmd_connected_display(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ ret_code_t err_code;
+ uint16_t conn_handle;
+ ble_gap_conn_sec_t security_params;
+ memset(&security_params, 0, sizeof(security_params));
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Connected devices:\r\n");
+
+ for (uint8_t i = 0; i < m_cli_connected.cmd_counter; i++)
+ {
+ conn_handle = addr_string_to_conn_handle(
+ m_cli_connected.buffer_type.connected_cmd_buffer[i]);
+
+ // Get connection security level.
+ err_code = sd_ble_gap_conn_sec_get(conn_handle, &security_params);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Security level reading has failed\r\n");
+
+ return;
+ }
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "%d. %s Security level: %d \r\n",
+ i,
+ m_cli_connected.buffer_type.connected_cmd_buffer[i],
+ security_params.sec_mode.lv);
+ }
+}
+
+
+static void cmd_privacy(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ UNUSED_VARIABLE(argv);
+
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s%s\r\n", UNKNOWN_PARAMETER, argv[1]);
+
+}
+
+/** @brief Command handler for setting privacy.
+ */
+static void cmd_privacy_on(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ UNUSED_VARIABLE(p_cli);
+ UNUSED_VARIABLE(argc);
+ UNUSED_VARIABLE(argv);
+
+ ret_code_t err_code;
+ ble_gap_privacy_params_t privacy_params;
+
+ // Privacy settings cannot be changed while advertising, scanning, or creating a connection.
+ (void)sd_ble_gap_scan_stop();
+ adv_stop();
+ err_code = sd_ble_gap_connect_cancel();
+ ret_code_verify(err_code);
+
+ memset(&privacy_params, 0, sizeof(privacy_params));
+
+ // Privacy setting.
+ privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY;
+ privacy_params.private_addr_type = BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE;
+ privacy_params.private_addr_cycle_s = PRIVATE_ADDRESS_INTERVAL;
+ privacy_params.p_device_irk = NULL;
+
+ // Set privacy.
+ err_code = sd_ble_gap_privacy_set(&privacy_params);
+ APP_ERROR_CHECK(err_code);
+
+ // Set device indentities list.
+ err_code = sd_ble_gap_device_identities_set(NULL, NULL, NRF_SDH_BLE_PERIPHERAL_LINK_COUNT);
+ APP_ERROR_CHECK(err_code);
+}
+
+/**@brief Command handler for disabling privacy.
+ */
+static void cmd_privacy_off(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ UNUSED_VARIABLE(p_cli);
+ UNUSED_VARIABLE(argc);
+ UNUSED_VARIABLE(argv);
+
+ ret_code_t err_code;
+ ble_gap_privacy_params_t privacy_params;
+
+ // Privacy settings cannot be changed while advertising, scanning, or creating a connection.
+ (void)sd_ble_gap_scan_stop();
+
+ adv_stop();
+
+ err_code = sd_ble_gap_connect_cancel();
+ ret_code_verify(err_code);
+
+ memset(&privacy_params, 0, sizeof(privacy_params));
+ privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_OFF;
+ privacy_params.private_addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC;
+ privacy_params.private_addr_cycle_s = BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S;
+ privacy_params.p_device_irk = NULL;
+
+ // Set privacy.
+ err_code = sd_ble_gap_privacy_set(&privacy_params);
+ APP_ERROR_CHECK(err_code);
+}
+
+
+static void cmd_numeric(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s\r\n", UNKNOWN_PARAMETER, argv[1]);
+}
+
+
+/**@brief Command handler for accepting a numeric value.
+ */
+static void cmd_numeric_accept(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ UNUSED_VARIABLE(argc);
+ UNUSED_VARIABLE(argv);
+
+ ret_code_t err_code;
+
+ if (is_numeric_match_requested())
+ {
+ // If numeric match request and keys on the both devices are the same then accept.
+ err_code = sd_ble_gap_auth_key_reply(numeric_match_request_conn_handle_get(),
+ BLE_GAP_AUTH_KEY_TYPE_PASSKEY, NULL); // Accept
+ APP_ERROR_CHECK(err_code);
+
+ // Clear numeric match flag.
+ numeric_match_request_clear();
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Numeric Match\r\n");
+ }
+ else
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "This command can be used only with numeric comparison pairing\r\n");
+ }
+}
+
+
+/**@brief Command handler for rejecting a numeric value.
+ */
+static void cmd_numeric_reject(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ UNUSED_VARIABLE(argc);
+ UNUSED_VARIABLE(argv);
+
+ ret_code_t err_code;
+
+ if (is_numeric_match_requested())
+ {
+ // If numeric match request and keys on both devices are not the same, then reject.
+ err_code = sd_ble_gap_auth_key_reply(numeric_match_request_conn_handle_get(),
+ BLE_GAP_AUTH_KEY_TYPE_NONE, NULL); // Reject
+ APP_ERROR_CHECK(err_code);
+
+ // Clear a numeric match flag.
+ numeric_match_request_clear();
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Numeric Reject\r\n");
+ }
+ else
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "This command can be used only with numeric comparison pairing\r\n");
+ }
+}
+
+
+#if NRF_MODULE_ENABLED(ADAFRUIT_SHIELD)
+static void cmd_nfc_reader(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s%s\r\n", UNKNOWN_PARAMETER, argv[1]);
+}
+
+
+/**@brief Command handler for pairing by NFC in central role.
+ */
+static void cmd_nfc_reader_on(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ UNUSED_VARIABLE(argv);
+
+ if (argc != 1)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, WRONG_PARAMETER_COUNT);
+ return;
+ }
+
+ ret_code_t err_code;
+
+ // In order to avoid a mistake when reusing the command.
+ nfc_pair_stop();
+ err_code = adafruit_pn532_field_off();
+ ret_code_verify(err_code);
+
+ // Turn on the Adafruit tag reader.
+ err_code = adafruit_pn532_field_on();
+ APP_ERROR_CHECK(err_code);
+
+ nfc_pair_start();
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "NFC reader ON\r\n");
+}
+
+
+/**@brief Command handler for disabling pairing by NFC in central role.
+ */
+static void cmd_nfc_reader_off(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ UNUSED_VARIABLE(argv);
+
+ ret_code_t err_code;
+
+ if (argc != 1)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, WRONG_PARAMETER_COUNT);
+ return;
+ }
+
+ nfc_pair_stop();
+ err_code = adafruit_pn532_field_off();
+ ret_code_verify(err_code);
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "NFC reader OFF\r\n");
+}
+
+
+#endif // ADAFRUIT_SHIELD
+
+static void cmd_gatt(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s%s\r\n", UNKNOWN_PARAMETER, argv[1]);
+}
+
+
+
+/**@brief Command handler for services discovery.
+ */
+static void cmd_services_discovery(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ ret_code_t err_code;
+ uint16_t conn_handle;
+
+ // Start handle to look for services.
+ uint16_t handle = 0x0001;
+ conn_handle = addr_string_to_conn_handle(argv[1]);
+ if(!conn_handle_is_valid(conn_handle, p_cli))
+ {
+ return;
+ }
+
+ // Discovery primary services.
+ err_code = sd_ble_gattc_primary_services_discover(conn_handle, handle, NULL);
+ APP_ERROR_CHECK(err_code);
+}
+
+
+/**@brief Command handler for characteristics discovery.
+ */
+static void cmd_char_get(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ uint16_t conn_handle;
+ ret_code_t err_code;
+
+ // Search for a connection handle.
+ conn_handle = addr_string_to_conn_handle(argv[1]);
+
+ if(!conn_handle_is_valid(conn_handle, p_cli))
+ {
+ return;
+ }
+
+ // Look for start handle range.
+ ble_gattc_handle_range_t * p_handle_range = handle_range_search(argv[2], conn_handle);
+
+ // Characteristic discovery.
+ err_code = sd_ble_gattc_characteristics_discover(conn_handle, p_handle_range);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "incorrect service UUID or service does not exist\r\n");
+ }
+}
+
+
+
+/**@brief Command handler for reading a characteristic value.
+ */
+static void cmd_char_read(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ uint16_t conn_handle;
+ uint16_t val_handle;
+ ret_code_t err_code;
+
+ // Search for a connection handle.
+ conn_handle = addr_string_to_conn_handle(argv[1]);
+
+ if(!conn_handle_is_valid(conn_handle, p_cli))
+ {
+ return;
+ }
+
+ // Search for a Characterisctic Value Handle.
+ val_handle = handle_value_search(argv[2]);
+ if (val_handle == BLE_GATT_HANDLE_INVALID)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s%s\r\n",
+ "The selected service does not contain the characteristic - ",
+ argv[2]);
+ return;
+ }
+
+ // Read characteristic data.
+ err_code = sd_ble_gattc_read(conn_handle, val_handle, 0);
+ APP_ERROR_CHECK(err_code);
+}
+
+
+/**@brief Command handler for writing a value to the characteristic.
+ */
+static void cmd_char_write(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ uint16_t conn_handle;
+ ret_code_t err_code;
+ ble_gattc_write_params_t write_params;
+ uint8_t data_buf[GATT_DATA_WRITE_SIZE];
+ uint16_t val_handle;
+
+ // Calculate data length, first 4 argv are commands, the rest of argv are data.
+ uint16_t data_len = argc - 4;
+
+ memset(&write_params, 0, sizeof(write_params));
+
+ if (!strcmp(argv[1], "command"))
+ {
+ write_params.write_op = BLE_GATT_OP_WRITE_CMD;
+ }
+ else if (!strcmp(argv[1], "request"))
+ {
+ write_params.write_op = BLE_GATT_OP_WRITE_REQ;
+ }
+ else
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s%s\r\n", UNKNOWN_PARAMETER, argv[1]);
+ return;
+ }
+
+ // Search for a connection handle.
+ conn_handle = addr_string_to_conn_handle(argv[2]);
+
+ if(!conn_handle_is_valid(conn_handle, p_cli))
+ {
+ return;
+ }
+
+ // Search for a Characteristic Value Handle.
+ val_handle = handle_value_search(argv[3]);
+
+ if (val_handle == BLE_GATT_HANDLE_INVALID)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s%s\r\n",
+ "The selected service does not contain the characteristic - ",
+ argv[3]);
+ return;
+ }
+
+ write_params.handle = val_handle;
+ write_params.len = data_len;
+ write_params.p_value = data_buf;
+ write_params.offset = 0;
+ write_params.flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE;
+
+ for (uint8_t i = 0; i < data_len; i++)
+ {
+ data_buf[i] = atoi(argv[i + 4]);
+ }
+
+ // Write data to characteristic.
+ err_code = sd_ble_gattc_write(conn_handle, &write_params);
+ APP_ERROR_CHECK(err_code);
+}
+
+
+static void cmd_notify(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s%s\r\n", UNKNOWN_PARAMETER, argv[1]);
+}
+
+/**@brief Command handler for enabling a notification.
+ */
+static void cmd_notify_on(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ UNUSED_VARIABLE(argc);
+
+ // In order to enable the notification, the CCCD descriptor should take the value 1.
+ cccd_set(p_cli, 0x01, argv[1], argv[2]);
+}
+
+
+/**@brief Command handler for disabling a notification.
+ */
+static void cmd_notify_off(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ UNUSED_VARIABLE(argc);
+ // In order to disable the notification, the CCCD descriptor should take the value 0.
+ cccd_set(p_cli, 0x00, argv[1], argv[2]);
+}
+
+
+static void cmd_ind(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s%s\r\n", UNKNOWN_PARAMETER, argv[1]);
+
+}
+
+
+/**@brief Command handler for enabling an indication.
+ */
+static void cmd_ind_on(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ UNUSED_VARIABLE(argc);
+
+ // In order to enable the indication, the CCCD descriptor should take the value 2.
+ cccd_set(p_cli, 0x02, argv[1], argv[2]);
+}
+
+
+/**@brief Command handler for disabling an indication.
+ */
+static void cmd_ind_off(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ UNUSED_VARIABLE(argc);
+
+ // In order to disable the indication, the CCCD descriptor should take the value 0.
+ cccd_set(p_cli, 0x00, argv[1], argv[2]);
+}
+
+
+/**@brief Command handler for setting link layer data length.
+ */
+static void cmd_data_length_set(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if (argc != 3)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, WRONG_PARAMETER_COUNT);
+ return;
+ }
+
+ uint16_t conn_handle;
+
+ for (uint8_t i = 0; i < strlen(argv[2]); i++)
+ {
+ if (!isdigit((int) argv[2][i]))
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "data length must be a number\r\n");
+ return;
+ }
+ }
+
+ // Search for connection handle.
+ conn_handle = addr_string_to_conn_handle(argv[1]);
+
+ if(!conn_handle_is_valid(conn_handle, p_cli))
+ {
+ return;
+ }
+
+ // Set new link layer data length.
+ link_layer_data_length_set(argv[2], conn_handle);
+}
+
+
+/**@brief Command handler for setting the PHY to 1 MBPS.
+ */
+static void cmd_phy_1m_set(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ UNUSED_VARIABLE(argc);
+
+ uint16_t conn_handle;
+
+ // Search for a connection handle.
+ conn_handle = addr_string_to_conn_handle(argv[1]);
+
+ if(!conn_handle_is_valid(conn_handle, p_cli))
+ {
+ return;
+ }
+
+ // PHY value set.
+ phy_set(p_cli, BLE_GAP_PHY_1MBPS, conn_handle);
+}
+
+
+
+/**@brief Command handler for setting the PHY to 2 MBPS.
+ */
+static void cmd_phy_2m_set(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ UNUSED_VARIABLE(argc);
+
+ uint16_t conn_handle;
+
+ // Search for a connection handle.
+ conn_handle = addr_string_to_conn_handle(argv[1]);
+
+ if(!conn_handle_is_valid(conn_handle, p_cli))
+ {
+ return;
+ }
+
+ // PHY value set.
+ phy_set(p_cli, BLE_GAP_PHY_2MBPS, conn_handle);
+}
+
+
+#ifdef NRF52840_XXAA
+/**@brief Command handler for setting the PHY to coded.
+ */
+static void cmd_phy_coded_set(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ UNUSED_VARIABLE(argc);
+
+ uint16_t conn_handle;
+
+ // Search for a connection handle.
+ conn_handle = addr_string_to_conn_handle(argv[1]);
+
+ if(!conn_handle_is_valid(conn_handle, p_cli))
+ {
+ return;
+ }
+
+ // PHY value set.
+ phy_set(p_cli, BLE_GAP_PHY_CODED, conn_handle);
+}
+
+
+#endif
+
+static void cmd_phy(nrf_cli_t const * p_cli, size_t argc, char * * argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s%s\r\n", UNKNOWN_PARAMETER, argv[1]);
+
+}
+
+
+static void cmd_parameters(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s%s\r\n", UNKNOWN_PARAMETER, argv[1]);
+}
+
+
+/**@brief Command handler for setting the MTU.
+ */
+static void cmd_mtu_set(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if (argc != 2)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, WRONG_PARAMETER_COUNT);
+ return;
+ }
+
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ for (uint8_t i = 0; i < strlen(argv[1]); i++)
+ {
+ if (!isdigit((int) argv[1][i]))
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "MTU must be a number\r\n");
+ return;
+ }
+ }
+
+ // Set a new MTU value.
+ gatt_mtu_set(argv[1]);
+}
+
+
+/**@brief Command handler for setting the Minimum Connection Interval.
+ */
+static void cmd_min_conn_interval_set(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ uint16_t value;
+
+ if (argc != 2)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, WRONG_PARAMETER_COUNT);
+ return;
+ }
+
+ for (uint8_t i = 0; i < strlen(argv[1]); i++)
+ {
+ if (!isdigit((int) argv[1][i]))
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "min_conn_interval must be a number\r\n");
+ return;
+ }
+ }
+
+ value = (uint16_t)MSEC_TO_UNITS(atoi(argv[1]), UNIT_1_25_MS);
+
+ // Checking the value is within the required range.
+ if ((value < MSEC_TO_UNITS(BLE_GAP_CP_MIN_CONN_INTVL_MIN, UNIT_1_25_MS)) ||
+ (value > MSEC_TO_UNITS(BLE_GAP_CP_MIN_CONN_INTVL_MAX, UNIT_1_25_MS)))
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s %d and %d.\r\n",
+ "Minimum connection interval must be between",
+ BLE_GAP_CP_MIN_CONN_INTVL_MIN,
+ BLE_GAP_CP_MIN_CONN_INTVL_MAX);
+ return;
+ }
+
+ m_params_update.min_conn_interval = value;
+}
+
+
+/**@brief Command handler for setting Maximum Connection Interval.
+ */
+static void cmd_max_conn_interval_set(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ uint16_t value;
+
+ if (argc != 2)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, WRONG_PARAMETER_COUNT);
+ return;
+ }
+
+ for (uint8_t i = 0; i < strlen(argv[1]); i++)
+ {
+ if (!isdigit((int) argv[1][i]))
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "max_conn_interval must be a number.\r\n");
+ return;
+ }
+ }
+
+ value = (uint16_t)MSEC_TO_UNITS(atoi(argv[1]), UNIT_1_25_MS);
+
+ // Checking whether the value is within the required range.
+ if ((value < MSEC_TO_UNITS(BLE_GAP_CP_MAX_CONN_INTVL_MIN, UNIT_1_25_MS)) ||
+ (value > MSEC_TO_UNITS(BLE_GAP_CP_MAX_CONN_INTVL_MAX, UNIT_1_25_MS)))
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s %d and %d.\r\n",
+ "Maximum connection interval must be between",
+ BLE_GAP_CP_MAX_CONN_INTVL_MIN,
+ BLE_GAP_CP_MAX_CONN_INTVL_MAX);
+ return;
+ }
+
+ m_params_update.max_conn_interval = value;
+}
+
+
+/**@brief Command handler for setting Slave Latency.
+ */
+static void cmd_slave_latency_set(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ uint16_t value;
+
+ if (argc != 2)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, WRONG_PARAMETER_COUNT);
+ return;
+ }
+
+ for (uint8_t i = 0; i < strlen(argv[1]); i++)
+ {
+ if (!isdigit((int) argv[1][i]))
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Slave latency must be a number\r\n");
+ return;
+ }
+ }
+
+ value = atoi(argv[1]);
+
+ if (value > BLE_GAP_CP_SLAVE_LATENCY_MAX)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s%d.\r\n",
+ "Slave latency should be less than: ",
+ BLE_GAP_CP_SLAVE_LATENCY_MAX);
+ return;
+ }
+
+ m_params_update.slave_latency = value;
+}
+
+
+/**@brief Command handler for setting Supervisory time-out.
+ */
+static void cmd_sup_timeout_set(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ uint16_t value;
+ uint16_t check;
+ uint16_t valid;
+
+ if (argc != 2)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, WRONG_PARAMETER_COUNT);
+ return;
+ }
+
+ for (uint8_t i = 0; i < strlen(argv[1]); i++)
+ {
+ if (!isdigit((int) argv[1][i]))
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "Supervision time-out must be a number.\r\n");
+ return;
+ }
+ }
+
+ check = atoi(argv[1]);
+ value = (uint16_t)MSEC_TO_UNITS(check, UNIT_10_MS);
+ valid = (1 + m_params_update.slave_latency) * UNIT_TO_MSEC(m_params_update.max_conn_interval,
+ UNIT_1_25_MS) * 2;
+ // Checking whether the value is within the required range.
+ if ((value < MSEC_TO_UNITS(BLE_GAP_CP_CONN_SUP_TIMEOUT_MIN, UNIT_10_MS)) ||
+ (value > MSEC_TO_UNITS(BLE_GAP_CP_CONN_SUP_TIMEOUT_MAX, UNIT_10_MS)))
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s %d and %d.\r\n",
+ "Supervision time-out must be between",
+ BLE_GAP_CP_CONN_SUP_TIMEOUT_MIN,
+ BLE_GAP_CP_CONN_SUP_TIMEOUT_MAX);
+ return;
+ }
+
+ if (check <= valid)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s \r\n%s%d\r\n",
+ "Supervision_Timeout in milliseconds shall be larger than:",
+ "(1 + Slave_Latency) * Conn_Interval_Max * 2 - ",
+ valid);
+ return;
+ }
+
+ m_params_update.conn_sup_timeout = value;
+}
+
+
+/**@brief Command handler for setting connection parameters.
+ */
+static void cmd_connection_params_set(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if (argc != 2)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, WRONG_PARAMETER_COUNT);
+ return;
+ }
+
+ ret_code_t err_code;
+ uint16_t conn_handle;
+
+ // Search for a connection handle.
+ conn_handle = addr_string_to_conn_handle(argv[1]);
+
+ if(!conn_handle_is_valid(conn_handle, p_cli))
+ {
+ return;
+ }
+
+ // Set connection parameters for the connection.
+ err_code = sd_ble_gap_conn_param_update(conn_handle, &m_params_update);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "Preferred connection parameters changed successfully\r\n");
+
+ default_con_param(&m_params_update);
+ }
+ else
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "Connection parameters could not be changed\r\n");
+ }
+}
+
+
+/**@brief Command handler for displaying connectable devices.
+ */
+static void cmd_devices_display(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if (argc >= 2)
+ {
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+ else
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s:%s%s\r\n",
+ argv[0],
+ " bad parameter ",
+ argv[1]);
+ return;
+ }
+ }
+
+ // Print connectable devices from scan data.
+ scanned_device_t * p_device_list = scan_device_info_get();
+ device_list_print(p_cli, p_device_list);
+}
+
+
+static void cmd_remove(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s%s\r\n", UNKNOWN_PARAMETER, argv[1]);
+}
+
+
+/**@brief Command handler for displaying bonded devices.
+ */
+static void cmd_bonded_devices_display(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if (argc > 1)
+ {
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, WRONG_PARAMETER_COUNT);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Peers count: %d \r\n", pm_peer_count());
+
+ pm_peer_id_t current_peer_id = pm_next_peer_id_get(PM_PEER_ID_INVALID);
+
+ // Display all bonded devices.
+ while (current_peer_id != PM_PEER_ID_INVALID)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "ID: %d address: ", current_peer_id);
+
+ ret_code_t err_code;
+ pm_peer_data_bonding_t data;
+ char string_addr_buf[ADDR_STRING_LEN];
+
+ // Get bonding data.
+ err_code = pm_peer_data_bonding_load(current_peer_id, &data);
+ APP_ERROR_CHECK(err_code);
+ current_peer_id = pm_next_peer_id_get(current_peer_id);
+
+ // Convert device address to string.
+ int_addr_to_hex_str(string_addr_buf,
+ BLE_GAP_ADDR_LEN,
+ data.peer_ble_id.id_addr_info.addr);
+
+ // Display bonded device.
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%s\r\n", string_addr_buf);
+ }
+}
+
+
+/**@brief Command handler for pairing with a device.
+ */
+static void cmd_device_pair(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ if (!strcmp(argv[1], "LESC"))
+ {
+ m_sec_params_central.lesc = 1;
+ }
+ else if (!strcmp(argv[1], "LEGACY"))
+ {
+ m_sec_params_central.lesc = 0;
+ }
+ else
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s:%s%s\r\n", argv[0], " wrong command ", argv[1]);
+ return;
+ }
+
+ ret_code_t err_code;
+
+ // Search for connection handle.
+ m_conn_handle = addr_string_to_conn_handle(argv[2]);
+
+ if(!conn_handle_is_valid(m_conn_handle, p_cli))
+ {
+ return;
+ }
+
+ if (!strcmp(argv[3], "mitm"))
+ {
+ m_sec_params_central.mitm = 1;
+ m_sec_params_central.io_caps = BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY;
+ }
+ else
+ {
+ m_sec_params_central.mitm = 0;
+ m_sec_params_central.io_caps = BLE_GAP_IO_CAPS_NONE;
+ }
+
+ if (!strcmp(argv[3], "oob"))
+ {
+ m_sec_params_central.mitm = 1;
+ m_sec_params_central.oob = 1;
+ m_sec_params_central.io_caps = BLE_GAP_IO_CAPS_NONE;
+ }
+
+ // Based on command parameters, set security parameters.
+ err_code = pm_sec_params_set(&m_sec_params_central);
+ APP_ERROR_CHECK(err_code);
+
+ // Establishing encryption on a connection, and optionally establishing a bond.
+ err_code = pm_conn_secure(m_conn_handle, false);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "Device is not connected or is already paired\r\n");
+ }
+ else
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Start pairing\r\n");
+ }
+}
+
+
+/**@brief Command handler for reply to BLE_GAP_EVT_AUTH_KEY_REQUEST.
+ */
+static void cmd_key_reply(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if (argc > 2)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, WRONG_PARAMETER_COUNT);
+ return;
+ }
+
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ if (!m_key_request_event)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "No key request\r\n");
+ return;
+ }
+
+ if (strlen(argv[1]) != KEY_PASSKEY_LEN)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s", "invalid key length!\r\n");
+ return;
+ }
+
+ ret_code_t err_code;
+ uint8_t key[KEY_PASSKEY_LEN];
+
+ for (uint8_t i = 0; i < KEY_PASSKEY_LEN; i++)
+ {
+ if (!isdigit((int) argv[1][i]))
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "the key must consist of digits\r\n");
+ return;
+ }
+
+ key[i] = argv[1][i];
+ }
+
+ // Reply with an authentication key.
+ err_code = sd_ble_gap_auth_key_reply(m_conn_handle,
+ BLE_GAP_AUTH_KEY_TYPE_PASSKEY,
+ key);
+ m_key_request_event = false;
+
+ if (err_code != NRF_SUCCESS)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Error sending key\r\n");
+ }
+ else
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Key sending success\r\n");
+ }
+}
+
+
+/**@brief Command handler for setting a device name.
+ */
+static void cmd_device_name_set(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ ret_code_t err_code;
+ ble_gap_conn_sec_mode_t sec_mode;
+ char buf[DEVICE_NAME_MAX_SIZE];
+
+ memset(buf, 0, DEVICE_NAME_MAX_SIZE);
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
+
+ for (uint8_t i = 1; i < argc; i++)
+ {
+ strcat(buf, argv[i]);
+
+ if (i == (argc - 1))
+ {
+ break;
+ }
+
+ strcat(buf, " ");
+ }
+
+ // Set new device name.
+ err_code = sd_ble_gap_device_name_set(&sec_mode,
+ (const uint8_t *)buf,
+ strlen(buf));
+
+ //Re-initialization of advertising with new device name.
+ advertising_init();
+ APP_ERROR_CHECK(err_code);
+}
+
+
+/**@brief Command handler for enabling advertising.
+ */
+static void cmd_advertise_on(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ ret_code_t err_code;
+
+ if (argc > 1)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, WRONG_PARAMETER_COUNT);
+ return;
+ }
+
+ adv_stop();
+ err_code = nfc_ble_pair_stop();
+ ret_code_verify(err_code);
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Advertising enabled\r\n");
+ adv_start();
+ err_code = nfc_ble_pair_start();
+ APP_ERROR_CHECK(err_code);
+}
+
+
+/**@brief Command handler for disabling advertising.
+ */
+static void cmd_advertise_off(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ ret_code_t err_code;
+
+ if (argc > 1)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, WRONG_PARAMETER_COUNT);
+ return;
+ }
+
+ adv_stop();
+ err_code = nfc_ble_pair_stop();
+ ret_code_verify(err_code);
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Advertising disabled\r\n");
+}
+
+
+static void cmd_advertise(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s%s\r\n", UNKNOWN_PARAMETER, argv[1]);
+}
+
+
+/**@brief Command handler for disabling scanning.
+ */
+static void cmd_scan_off(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if (argc != 1)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s %s: %s",
+ argv[-1],
+ argv[0],
+ WRONG_PARAMETER_COUNT);
+ return;
+ }
+
+ scan_stop();
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Scan stopped\r\n");
+}
+
+
+/**@brief Command handler for enabling scanning.
+ */
+static void cmd_scan_on(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if (argc != 1)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s %s: %s",
+ argv[-1],
+ argv[0],
+ WRONG_PARAMETER_COUNT);
+ return;
+ }
+
+ scan_start();
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Scan started\r\n");
+}
+
+
+static void cmd_scan(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s%s\r\n",
+ UNKNOWN_PARAMETER,
+ argv[1]);
+}
+
+
+/**@brief Command handler for establishing a connection.
+ */
+static void cmd_device_connect(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ if (argc == 2)
+ {
+ //Connect by peer ID if davice was bonded and using privacy.
+ if (strlen(argv[1]) < (ADDR_STRING_LEN - 1))
+ {
+ uint16_t pm_id;
+ pm_id = atoi(argv[1]);
+ private_connect(&pm_id);
+ return;
+ }
+
+ // If address or peer ID have incorrect format, then return.
+ if (strlen(argv[1]) != (ADDR_STRING_LEN - 1))
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "wrong address length - Correct format: XX:XX:XX:XX:XX:XX\r\n");
+ return;
+ }
+
+ //Connect by device address.
+ addr_store_value_set(argv[1]);
+ }
+ else
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, WRONG_PARAMETER_COUNT);
+ }
+}
+
+
+/**@brief Command handler for disconnecting from a device.
+ */
+static void cmd_device_disconnect(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ if (argc > 2)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s: %s", argv[0], WRONG_PARAMETER_COUNT);
+ return;
+ }
+
+ if (strlen(argv[1]) != (ADDR_STRING_LEN - 1))
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "wrong address length - Correct format: XX:XX:XX:XX:XX:XX\r\n");
+ return;
+ }
+
+ uint16_t conn_handle;
+ ret_code_t err_code;
+
+ // Search for a connection handle.
+ conn_handle = addr_string_to_conn_handle(argv[1]);
+
+ if(!conn_handle_is_valid(conn_handle, p_cli))
+ {
+ return;
+ }
+
+ // Disconnect from a device.
+ err_code = sd_ble_gap_disconnect(conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
+ ret_code_verify(err_code);
+}
+
+
+static void cmd_all_bonds_delete(nrf_cli_t const * p_cli, size_t argc, char * * argv)
+{
+ if (argc == 1)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Bonding data deleted\r\n");
+ bonds_delete();
+ return;
+ }
+
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s%s\r\n", UNKNOWN_PARAMETER, argv[1]);
+}
+
+
+/**@brief Command handler for removing device bonding data.
+ */
+static void cmd_device_remove(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ ret_code_t err_code;
+ pm_peer_id_t current_peer_id = pm_next_peer_id_get(PM_PEER_ID_INVALID);
+
+ // Search for device bondind data.
+ while (current_peer_id != PM_PEER_ID_INVALID)
+ {
+ pm_peer_data_bonding_t p_data;
+
+ err_code = pm_peer_data_bonding_load(current_peer_id, &p_data);
+ APP_ERROR_CHECK(err_code);
+
+ if (is_address_compare(&p_data.peer_ble_id.id_addr_info, argv[1]))
+ {
+ // If bonding data was found, then remove.
+ err_code = pm_peer_delete(current_peer_id);
+ APP_ERROR_CHECK(err_code);
+
+ // Remove device from bonded device command buffer.
+ cli_addr_from_command_remove(argv[1],
+ &m_cli_bonded,
+ CLI_CMD_BONDED);
+ }
+
+ current_peer_id = pm_next_peer_id_get(current_peer_id);
+ }
+}
+
+
+/* Dynamic command creation */
+static void connected_get(size_t idx, nrf_cli_static_entry_t * p_static)
+{
+ // Must be sorted alphabetically to ensure correct CLI completion.
+ p_static->p_syntax = (idx < m_cli_connected.cmd_counter) ?
+ m_cli_connected.buffer_type.connected_cmd_buffer[idx] : NULL;
+ p_static->handler = NULL;
+ p_static->p_subcmd = NULL;
+ p_static->p_help = 0;
+}
+
+
+/* Dynamic command creation */
+static void connect_addr_get(size_t idx, nrf_cli_static_entry_t * p_static)
+{
+ // Must be sorted alphabetically to ensure correct CLI completion.
+ p_static->p_syntax = (idx < m_cli_connect_addr.cmd_counter) ?
+ m_cli_connect_addr.buffer_type.connect_addr_cmd_buffer[idx] : NULL;
+ p_static->handler = NULL;
+ p_static->p_subcmd = NULL;
+ p_static->p_help = "Connect with address.";
+}
+
+
+/* Dynamic command creation */
+static void delete_bond_get(size_t idx, nrf_cli_static_entry_t * p_static)
+{
+ // Must be sorted alphabetically to ensure correct CLI completion.
+ p_static->p_syntax = (idx < m_cli_bonded.cmd_counter) ?
+ m_cli_bonded.buffer_type.bond_cmd_buffer[idx] : NULL;
+ p_static->handler = NULL;
+ p_static->p_subcmd = NULL;
+ p_static->p_help = "Delete device bond by address.";
+}
+
+
+
+
+
+/* Creating subcommands (level 1) for command "LESC and Legacy */
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_pairing_opt)
+{
+ NRF_CLI_CMD(mitm, NULL, "MITM protection", NULL),
+ NRF_CLI_CMD(oob, NULL, "OOB pair mode", NULL),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+
+/* Dynamic command creation */
+static void pairing_get(size_t idx, nrf_cli_static_entry_t * p_static)
+{
+ // Must be sorted alphabetically to ensure correct CLI completion.
+ p_static->p_syntax = (idx < m_cli_connected.cmd_counter) ?
+ m_cli_connected.buffer_type.connected_cmd_buffer[idx] : NULL;
+ p_static->handler = NULL;
+ p_static->p_subcmd = &m_sub_pairing_opt;
+ p_static->p_help = NULL;
+}
+
+
+/* Creating dynamic subcommands (level 2) */
+NRF_CLI_CREATE_DYNAMIC_CMD(m_sub_connect_addr_collection, connect_addr_get);
+NRF_CLI_CREATE_DYNAMIC_CMD(m_sub_pairing_set, pairing_get);
+
+/* Creating dynamic subcommands (level 1) */
+NRF_CLI_CREATE_DYNAMIC_CMD(m_sub_connected_collection, connected_get);
+NRF_CLI_CREATE_DYNAMIC_CMD(m_sub_delete_bond_collection, delete_bond_get);
+
+/* Creating subcommands (level 2) for command "phy" */
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_phy)
+{
+ NRF_CLI_CMD(1M,
+ &m_sub_connected_collection,
+ "Set preferred PHY to 1 Mbps.",
+ cmd_phy_1m_set),
+ NRF_CLI_CMD(2M,
+ &m_sub_connected_collection,
+ "Set preferred PHY to 2 Mbps.",
+ cmd_phy_2m_set),
+#ifdef NRF52840_XXAA
+ NRF_CLI_CMD(coded,
+ &m_sub_connected_collection,
+ "Set preferred PHY to Coded.",
+ cmd_phy_coded_set),
+#endif
+ NRF_CLI_SUBCMD_SET_END
+};
+
+/* Creating subcommands (level 2)*/
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_write)
+{
+ NRF_CLI_CMD(command,
+ &m_sub_connected_collection,
+ "<char_uuid> <value> Write characteristic value(request).",
+ NULL),
+ NRF_CLI_CMD(request,
+ &m_sub_connected_collection,
+ "<char_uuid> <value> Write characteristic value(command).",
+ NULL),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_notify)
+{
+ NRF_CLI_CMD(off, &m_sub_connected_collection, "Notifications off.", cmd_notify_off),
+ NRF_CLI_CMD(on, &m_sub_connected_collection, "Notifications on.", cmd_notify_on),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_ind)
+{
+ NRF_CLI_CMD(off, &m_sub_connected_collection, "Indications off.", cmd_ind_off),
+ NRF_CLI_CMD(on, &m_sub_connected_collection, "Indications on.", cmd_ind_on),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+/* Creating subcommands (level 1)*/
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_privacy)
+{
+ NRF_CLI_CMD(off, NULL, "Privacy advertising mode off.", cmd_privacy_off),
+ NRF_CLI_CMD(on, NULL, "Privacy advertising mode on.", cmd_privacy_on),
+ NRF_CLI_SUBCMD_SET_END
+};
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_numeric)
+{
+ NRF_CLI_CMD(accept, NULL, "Accepts pin value.", cmd_numeric_accept),
+ NRF_CLI_CMD(reject, NULL, "Reject pin value.", cmd_numeric_reject),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+#if NRF_MODULE_ENABLED(ADAFRUIT_SHIELD)
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_nfc_reader)
+{
+ NRF_CLI_CMD(off, NULL, "NFC reader off.", cmd_nfc_reader_off),
+ NRF_CLI_CMD(on, NULL, "NFC reader on.", cmd_nfc_reader_on),
+ NRF_CLI_SUBCMD_SET_END
+};
+#endif // ADAFRUIT_SHIELD
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_gatt)
+{
+ NRF_CLI_CMD(characteristics,
+ &m_sub_connected_collection,
+ "<address> <serv_uuid> Get information about the contents of a service.",
+ cmd_char_get),
+ NRF_CLI_CMD(indication,
+ &m_sub_ind,
+ "<sub_cmd> <address> <char_uuid> Change indication state.",
+ cmd_ind),
+ NRF_CLI_CMD(notification,
+ &m_sub_notify,
+ "<sub_cmd> <address> <char_uuid> Change notification state.",
+ cmd_notify),
+ NRF_CLI_CMD(read,
+ &m_sub_connected_collection,
+ "<address> <char_uuid> Read characteristic value.",
+ cmd_char_read),
+ NRF_CLI_CMD(services,
+ &m_sub_connected_collection,
+ "<address> Download list of services.",
+ cmd_services_discovery),
+ NRF_CLI_CMD(write,
+ &m_sub_write,
+ "<sub_cmd> <address> <char_uuid> <value> Write characteristic value.",
+ cmd_char_write),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_parameters)
+{
+ NRF_CLI_CMD(apply,
+ &m_sub_connected_collection,
+ "<address> Change connection parameters for the device.",
+ cmd_connection_params_set),
+ NRF_CLI_CMD(data_length,
+ &m_sub_connected_collection,
+ "<address> <value> Data length change.",
+ cmd_data_length_set),
+ NRF_CLI_CMD(max_conn_interval,
+ NULL,
+ "<value> Set maximum connection interval.",
+ cmd_max_conn_interval_set),
+ NRF_CLI_CMD(min_conn_interval,
+ NULL,
+ "<value> Set minimum connection interval.",
+ cmd_min_conn_interval_set),
+ NRF_CLI_CMD(mtu, NULL, "<value> Change MTU value.", cmd_mtu_set),
+ NRF_CLI_CMD(phy, &m_sub_phy, "<subcmd> <address> PHY change. ", cmd_phy),
+ NRF_CLI_CMD(slave_latency, NULL, "<value> Set slave latency.", cmd_slave_latency_set),
+ NRF_CLI_CMD(sup_timeout, NULL, "<value> Set connection supervision time-out.", cmd_sup_timeout_set),
+ NRF_CLI_SUBCMD_SET_END
+};
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_remove)
+{
+ NRF_CLI_CMD(all, NULL, "Remove all bonded devices.", cmd_all_bonds_delete),
+ NRF_CLI_CMD(device,
+ &m_sub_delete_bond_collection,
+ "<address> Remove one bonded device.",
+ cmd_device_remove),
+ NRF_CLI_SUBCMD_SET_END
+};
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_pairing)
+{
+ NRF_CLI_CMD(LEGACY, &m_sub_pairing_set, "Legacy pairing mode.", NULL),
+ NRF_CLI_CMD(LESC, &m_sub_pairing_set, "LESC pairing mode.", NULL),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_advertise)
+{
+ NRF_CLI_CMD(off, NULL, "Advertising off.", cmd_advertise_off),
+ NRF_CLI_CMD(on, NULL, "Advertising on.", cmd_advertise_on),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_scan)
+{
+ NRF_CLI_CMD(off, NULL, "Stop scanning.", cmd_scan_off),
+ NRF_CLI_CMD(on, NULL, "Start scanning.", cmd_scan_on),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+/* Creating root (level 0) command */
+NRF_CLI_CMD_REGISTER(connected_devices,
+ NULL,
+ "Display connected devices and information about security level.",
+ cmd_connected_display);
+NRF_CLI_CMD_REGISTER(privacy, &m_sub_privacy, "Set privacy settings.", cmd_privacy);
+NRF_CLI_CMD_REGISTER(numeric,
+ &m_sub_numeric,
+ "Confirm or reject the value of the pin code.",
+ cmd_numeric);
+#if NRF_MODULE_ENABLED(ADAFRUIT_SHIELD)
+NRF_CLI_CMD_REGISTER(nfc_read,
+ &m_sub_nfc_reader,
+ "Turn on NFC for reading <on/off>.",
+ cmd_nfc_reader);
+#endif // ADAFRUIT_SHIELD
+NRF_CLI_CMD_REGISTER(gatt, &m_sub_gatt, "Gatt options.", cmd_gatt);
+NRF_CLI_CMD_REGISTER(parameters,
+ &m_sub_parameters,
+ "<subcmd> Change connection and link layer parameters.",
+ cmd_parameters);
+NRF_CLI_CMD_REGISTER(bonded_devices,
+ NULL,
+ "List bonded devices (The devices are identified by public address).",
+ cmd_bonded_devices_display);
+NRF_CLI_CMD_REGISTER(devices, NULL, "List available devices.", cmd_devices_display);
+NRF_CLI_CMD_REGISTER(remove_bond, &m_sub_remove, "<subcmd> Remove bonded device.", cmd_remove);
+NRF_CLI_CMD_REGISTER(key_reply, NULL, "<key> Enter key from another device.", cmd_key_reply);
+NRF_CLI_CMD_REGISTER(pair,
+ &m_sub_pairing,
+ "<subcmd> <address> <option> Start pairing with a evice.",
+ cmd_device_pair);
+NRF_CLI_CMD_REGISTER(device_name, NULL, "<name> Set device name.", cmd_device_name_set);
+NRF_CLI_CMD_REGISTER(advertise, &m_sub_advertise, "Turn advertising <on/off>.", cmd_advertise);
+NRF_CLI_CMD_REGISTER(scan, &m_sub_scan, "Scan options", cmd_scan);
+NRF_CLI_CMD_REGISTER(connect,
+ &m_sub_connect_addr_collection,
+ "<address/peer_id> Connect with a device.",
+ cmd_device_connect);
+NRF_CLI_CMD_REGISTER(disconnect,
+ &m_sub_connected_collection,
+ "<address> Disconnect from a device.",
+ cmd_device_disconnect);