Guest User

Untitled

a guest
Feb 28th, 2019
676
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 23.98 KB | None | 0 0
  1. /* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
  2.  *
  3.  * The information contained herein is property of Nordic Semiconductor ASA.
  4.  * Terms and conditions of usage are described in detail in NORDIC
  5.  * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
  6.  *
  7.  * Licensees are granted free, non-transferable use of the information. NO
  8.  * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
  9.  * the file.
  10.  *
  11.  */
  12.  
  13. #include "ble.h"
  14. #include "ble_gap.h"
  15. #include "ble_gattc.h"
  16. #include "ble_gatts.h"
  17. #include "ble_types.h"
  18. #include "nrf_error.h"
  19.  
  20. #include "sd_rpc.h"
  21. #include "sd_rpc_types.h"
  22.  
  23. #include <time.h>
  24. #include <string.h>
  25. #include <stdbool.h>
  26. #include <stdio.h>
  27.  
  28. #include "mydialog.h"
  29. #include <sstream>
  30.  
  31. #ifdef _WIN32
  32. #define UART_PORT_NAME "COM3"
  33. #endif
  34. #ifdef __APPLE__
  35. #define UART_PORT_NAME "/dev/tty.usbmodem00000"
  36. #endif
  37. #ifdef __linux__
  38. #define UART_PORT_NAME "/dev/ttyACM0"
  39. #endif
  40.  
  41. #define ADVERTISING_INTERVAL_40_MS  64 // * 0.625 ms = 40 ms
  42. #define ADVERTISING_TIMEOUT_3_MIN   180 // * 1 sec = 3 min
  43.  
  44. enum
  45. {
  46.     UNIT_0_625_MS = 625,                                /**< Number of microseconds in 0.625 milliseconds. */
  47.     UNIT_1_25_MS  = 1250,                               /**< Number of microseconds in 1.25 milliseconds. */
  48.     UNIT_10_MS    = 10000                               /**< Number of microseconds in 10 milliseconds. */
  49. };
  50.  
  51. #define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION))
  52.  
  53. #define SCAN_INTERVAL                    0x00A0                                         /**< Determines scan interval in units of 0.625 millisecond. */
  54. #define SCAN_WINDOW                      0x0050                                         /**< Determines scan window in units of 0.625 millisecond. */
  55.  
  56. #define MIN_CONNECTION_INTERVAL          MSEC_TO_UNITS(7.5, UNIT_1_25_MS)                /**< Determines maximum connection interval in millisecond. */
  57. #define MAX_CONNECTION_INTERVAL          MSEC_TO_UNITS(7.5, UNIT_1_25_MS)                /**< Determines maximum connection interval in millisecond. */
  58. #define SLAVE_LATENCY                    0                                              /**< Determines slave latency in counts of connection events. */
  59. #define SUPERVISION_TIMEOUT              MSEC_TO_UNITS(4000, UNIT_10_MS)                /**< Determines supervision time-out in units of 10 millisecond. */
  60.  
  61. #define TARGET_DEV_NAME                  "Nordic_HRM"                                      /**< Target device name that application is looking for. */
  62. #define MAX_PEER_COUNT                   1                                              /**< Maximum number of peer's application intends to manage. */
  63.  
  64. #define HRM_SERVICE_UUID                 0x180D
  65. #define HRM_MEAS_CHAR_UUID               0x2A37
  66. #define CCCD_UUID                        0x2902
  67. #define CCCD_NOTIFY                      0x01
  68.  
  69. #define STRING_BUFFER_SIZE               50
  70.  
  71. typedef struct
  72. {
  73.     uint8_t     * p_data;                                                      /**< Pointer to data. */
  74.     uint16_t      data_len;                                                    /**< Length of data. */
  75. } data_t;
  76.  
  77. static uint8_t  m_connected_devices = 0;
  78. static uint16_t m_connection_handle = 0;
  79. static uint16_t m_service_start_handle = 0;
  80. static uint16_t m_service_end_handle = 0;
  81. static uint16_t m_hrm_char_handle = 0;
  82. static uint16_t m_hrm_cccd_handle = 0;
  83. static bool     m_connection_is_in_progress = false;
  84. static adapter_t * m_adapter = NULL;
  85. static uint32_t m_hvx_count = 0;
  86. static clock_t m_hvx_start;
  87.  
  88. static const ble_gap_scan_params_t m_scan_param =
  89. {
  90.      1,                       // Active scanning set.
  91.      0,                       // Selective scanning not set.
  92. #if NRF_SD_BLE_API >= 2
  93.      0,
  94. #else
  95.      NULL,                    // White-list not set.
  96. #endif
  97.      (uint16_t)SCAN_INTERVAL, // Scan interval.
  98.      (uint16_t)SCAN_WINDOW,   // Scan window.
  99.      0                        // Never stop scanning unless explicit asked to.
  100. };
  101.  
  102. static const ble_gap_conn_params_t m_connection_param =
  103. {
  104.     (uint16_t)MIN_CONNECTION_INTERVAL,   // Minimum connection
  105.     (uint16_t)MAX_CONNECTION_INTERVAL,   // Maximum connection
  106.     0,                                   // Slave latency
  107.     (uint16_t)SUPERVISION_TIMEOUT        // Supervision time-out
  108. };
  109.  
  110.  
  111. /* Local function declarations */
  112. static void log_handler(adapter_t * adapter, sd_rpc_log_severity_t severity, const char * message);
  113. static void status_handler(adapter_t * adapter, sd_rpc_app_status_t code, const char * message);
  114. static uint32_t ble_stack_init();
  115. static uint32_t adv_report_parse(uint8_t type, data_t * p_advdata, data_t * p_typedata);
  116. static uint32_t scan_start();
  117. static uint32_t service_discovery_start();
  118. static uint32_t char_discovery_start();
  119. static uint32_t descr_discovery_start();
  120. static uint32_t hrm_cccd_set(uint8_t value);
  121. static void ble_address_to_string_convert(ble_gap_addr_t address, uint8_t * string_buffer);
  122.  
  123. static void log_handler(adapter_t * adapter, sd_rpc_log_severity_t severity, const char * message)
  124. {
  125.     switch (severity)
  126.     {
  127.     case SD_RPC_LOG_ERROR:
  128.         printf("Error: %s\n", message); fflush(stdout);
  129.         break;
  130.  
  131.     case SD_RPC_LOG_WARNING:
  132.         printf("Warning: %s\n", message); fflush(stdout);
  133.         break;
  134.  
  135.     case SD_RPC_LOG_INFO:
  136.         printf("Warning: %s\n", message); fflush(stdout);
  137.         break;
  138.  
  139.     default:
  140.         //printf("Log: %s\n", message); fflush(stdout);
  141.         break;
  142.     }
  143. }
  144.  
  145. static void status_handler(adapter_t *adapter, sd_rpc_app_status_t code, const char * message)
  146. {
  147.     printf("Status: %d, message: %s\n", (uint32_t)code, message);
  148. }
  149.  
  150. #define UNITS_TO_MSEC(U, RESOLUTION) (((U) * RESOLUTION) / (1000))
  151.  
  152. static void on_connected(const ble_gap_evt_t * const p_ble_gap_evt)
  153. {
  154.     printf("Connection established\n"); fflush(stdout);
  155.  
  156.     printf( "Final connection parameters\n" );
  157.     printf("min_conn_interval= %d units (%d ms)\n", p_ble_gap_evt->params.connected.conn_params.min_conn_interval, (uint16_t)UNITS_TO_MSEC(p_ble_gap_evt->params.connected.conn_params.min_conn_interval, UNIT_1_25_MS));
  158.     printf("max_conn_interval= %d units (%d ms)\n", p_ble_gap_evt->params.connected.conn_params.max_conn_interval, (uint16_t)UNITS_TO_MSEC(p_ble_gap_evt->params.connected.conn_params.max_conn_interval, UNIT_1_25_MS));
  159.     printf("slave_latency= %d\n", p_ble_gap_evt->params.connected.conn_params.slave_latency);
  160.     printf("conn_sup_timeout= %d units (%d ms)\n", p_ble_gap_evt->params.connected.conn_params.conn_sup_timeout, (uint16_t)UNITS_TO_MSEC(p_ble_gap_evt->params.connected.conn_params.conn_sup_timeout, UNIT_1_25_MS));
  161.  
  162.     m_connected_devices++;
  163.     m_connection_handle = p_ble_gap_evt->conn_handle;
  164.     m_connection_is_in_progress = false;
  165. #if NRF_SD_BLE_API >= 3
  166.     sd_ble_gattc_exchange_mtu_request(m_adapter, p_ble_gap_evt->conn_handle, 158);
  167. #endif
  168.     service_discovery_start();
  169. }
  170.  
  171. static void on_adv_report(const ble_gap_evt_t * const p_ble_gap_evt)
  172. {
  173.     uint32_t    err_code;
  174.     data_t      adv_data;
  175.     data_t      type_data;
  176.     uint8_t     str[STRING_BUFFER_SIZE] = {0};
  177.  
  178.     ble_address_to_string_convert(p_ble_gap_evt->params.adv_report.peer_addr, str);
  179.     printf("Received advertisment report, address: 0x%s\n", str); fflush(stdout);
  180.  
  181.     adv_data.p_data     = (uint8_t *)(p_ble_gap_evt->params.adv_report.data);
  182.     adv_data.data_len   = p_ble_gap_evt->params.adv_report.dlen;
  183.  
  184.     err_code = adv_report_parse(BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME,
  185.                                 &adv_data,
  186.                                 &type_data);
  187.     if (err_code != NRF_SUCCESS)
  188.     {
  189.         // Compare short local name in case complete name does not match.
  190.         err_code = adv_report_parse(BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME,
  191.                                     &adv_data,
  192.                                     &type_data);
  193.  
  194.         if (err_code != NRF_SUCCESS)
  195.         {
  196.             return;
  197.         }
  198.     }
  199.  
  200.     adv_data.p_data[adv_data.data_len] = 0;
  201.     printf("Name: %s\n", adv_data.p_data);
  202.  
  203.     if (0 == memcmp(TARGET_DEV_NAME, type_data.p_data, type_data.data_len))
  204.     {
  205.         if (m_connected_devices >= MAX_PEER_COUNT)
  206.         {
  207.             return;
  208.         }
  209.  
  210.         if (m_connection_is_in_progress)
  211.         {
  212.             return;
  213.         }
  214.  
  215.         err_code = sd_ble_gap_connect(m_adapter,
  216.                                       &(p_ble_gap_evt->params.adv_report.peer_addr),
  217.                                       &m_scan_param,
  218.                                       &m_connection_param);
  219.  
  220.         if (err_code != NRF_SUCCESS)
  221.         {
  222.             printf("Connection Request Failed, reason %d\n", err_code); fflush(stdout);
  223.             return;
  224.         }
  225.  
  226.         m_connection_is_in_progress = true;
  227.     }
  228. }
  229.  
  230. static void on_timeout(const ble_gap_evt_t * const p_ble_gap_evt)
  231. {
  232.     if (p_ble_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN)
  233.     {
  234.         m_connection_is_in_progress = false;
  235.     }
  236.     else if (p_ble_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_SCAN)
  237.     {
  238.         scan_start();
  239.     }
  240. }
  241.  
  242. static void on_service_discovery_response(const ble_gattc_evt_t * const p_ble_gattc_evt)
  243. {
  244.     int count;
  245.     int service_index;
  246.     const ble_gattc_service_t * service;
  247.  
  248.     if (p_ble_gattc_evt->gatt_status != NRF_SUCCESS)
  249.     {
  250.         printf("Error. Service discovery failed. Error code 0x%X\n",
  251.                 p_ble_gattc_evt->gatt_status);
  252.         fflush(stdout);
  253.         return;
  254.     }
  255.  
  256.     count = p_ble_gattc_evt->params.prim_srvc_disc_rsp.count;
  257.  
  258.     if (count == 0)
  259.     {
  260.         printf("Error. Service not found\n"); fflush(stdout);
  261.         return;
  262.     }
  263.  
  264.     printf("Received service discovery response\n"); fflush(stdout);
  265.  
  266.     service_index = 0; /* We specifically requested to discover Heart Rate service, so we can
  267.                         * safely select the first returned service. */
  268.  
  269.     service = &(p_ble_gattc_evt->params.prim_srvc_disc_rsp.services[service_index]);
  270.  
  271.     m_service_start_handle  = service->handle_range.start_handle;
  272.     m_service_end_handle    = service->handle_range.end_handle;
  273.  
  274.     printf("UUID: 0x%04X, start handle: 0x%04X, end handle: 0x%04X\n",
  275.         service->uuid.uuid, m_service_start_handle, m_service_end_handle);
  276.     fflush(stdout);
  277.  
  278.     char_discovery_start();
  279. }
  280.  
  281. static void on_characteristic_discover_response(const ble_gattc_evt_t * const p_ble_gattc_evt)
  282. {
  283.     int i;
  284.     int count;
  285.     ble_gattc_char_t * p_characteristic;
  286.  
  287.     if (p_ble_gattc_evt->gatt_status != NRF_SUCCESS)
  288.     {
  289.         printf("Error. Characteristic discovery failed. Error code 0x%X\n",
  290.                p_ble_gattc_evt->gatt_status);
  291.         fflush(stdout);
  292.         return;
  293.     }
  294.  
  295.     count = p_ble_gattc_evt->params.char_disc_rsp.count;
  296.  
  297.     printf("Received characteristic discovery response, characteristics count: %d\n", count);
  298.     fflush(stdout);
  299.  
  300.     for (i = 0; i < count; i++)
  301.     {
  302.         p_characteristic = (ble_gattc_char_t *)&(p_ble_gattc_evt->params.char_disc_rsp.chars[i]);
  303.         printf("Handle: 0x%04X, UUID: 0x%04X\n",
  304.             p_characteristic->handle_decl,
  305.             p_characteristic->uuid.uuid);
  306.         fflush(stdout);
  307.  
  308.         if (p_characteristic->uuid.uuid == HRM_MEAS_CHAR_UUID)
  309.         {
  310.             m_hrm_char_handle = p_characteristic->handle_decl;
  311.         }
  312.     }
  313.  
  314.     descr_discovery_start();
  315. }
  316.  
  317. static void on_descriptor_discover_response(const ble_gattc_evt_t * const p_ble_gattc_evt)
  318. {
  319.     int i;
  320.     int count;
  321.     ble_gattc_desc_t * p_descriptor;
  322.  
  323.     if (p_ble_gattc_evt->gatt_status != NRF_SUCCESS)
  324.     {
  325.         printf("Error. Descriptor discovery failed. Error code 0x%X\n",
  326.                 p_ble_gattc_evt->gatt_status);
  327.         fflush(stdout);
  328.         return;
  329.     }
  330.  
  331.     count = p_ble_gattc_evt->params.desc_disc_rsp.count;
  332.  
  333.     printf("Received descriptor discovery response, descriptor count: %d\n", count);
  334.     fflush(stdout);
  335.  
  336.     for (i = 0; i < count; i++)
  337.     {
  338.         p_descriptor = (ble_gattc_desc_t *)&(p_ble_gattc_evt->params.desc_disc_rsp.descs[i]);
  339.         printf("Handle: 0x%04X, UUID: 0x%04X\n", p_descriptor->handle, p_descriptor->uuid.uuid);
  340.         fflush(stdout);
  341.  
  342.         if (p_descriptor->uuid.uuid == CCCD_UUID)
  343.         {
  344.             m_hrm_cccd_handle = p_descriptor->handle;
  345.         }
  346.     }
  347.  
  348.     printf("Press enter to toggle notifications\n"); fflush(stdout);
  349. }
  350.  
  351. static void on_write_response(const ble_gattc_evt_t * const p_ble_gattc_evt)
  352. {
  353.     printf("Received write response.\n"); fflush(stdout);
  354.  
  355.     if (p_ble_gattc_evt->gatt_status != NRF_SUCCESS)
  356.     {
  357.         printf("Error. Write operation failed. Error code 0x%X\n",
  358.                 p_ble_gattc_evt->gatt_status);
  359.         fflush(stdout);
  360.         return;
  361.     }
  362. }
  363.  
  364. static MyDialog* notify_dialog = NULL;
  365. static void on_hvx(const ble_gattc_evt_t * const p_ble_gattc_evt)
  366. {
  367.     clock_t now = clock();
  368.  
  369.     if (!m_hvx_start) {
  370.         m_hvx_start = now;
  371.     }
  372.  
  373.     m_hvx_count++;
  374.  
  375.     float seconds = (float)(now - m_hvx_start) / CLOCKS_PER_SEC;
  376.  
  377.     if ( seconds >= 1 )
  378.     {
  379.         float pkt_per_sec = m_hvx_count / seconds;
  380.  
  381.         if ( notify_dialog )
  382.             notify_dialog->notify( m_hvx_count, pkt_per_sec );
  383.  
  384.         printf("pkts: %06d, pkt/s: %f\n", m_hvx_count, pkt_per_sec);
  385.  
  386.         fflush(stdout);
  387.  
  388.         // reset counters
  389.         m_hvx_start = clock();
  390.         m_hvx_count = 0;
  391.     }
  392. }
  393.  
  394. static void on_conn_params_update_request(const ble_gap_evt_t * const p_ble_gap_evt)
  395. {
  396.     uint32_t err_code;
  397.     err_code = sd_ble_gap_conn_param_update(m_adapter, m_connection_handle,
  398.                                             &(p_ble_gap_evt->params.conn_param_update_request.conn_params));
  399.     if (err_code != NRF_SUCCESS)
  400.     {
  401.         printf("Conn params update failed, err_code %d", err_code);
  402.     }
  403.  
  404. }
  405.  
  406. #if NRF_SD_BLE_API >= 3
  407. static void on_exchange_mtu_request(const ble_gatts_evt_t * const p_ble_gatts_evt)
  408. {
  409.     uint32_t err_code = sd_ble_gatts_exchange_mtu_reply(m_adapter, m_connection_handle,
  410.         GATT_MTU_SIZE_DEFAULT);
  411.  
  412.     if (err_code != NRF_SUCCESS)
  413.     {
  414.         printf("MTU exchange request failed, err_code %d", err_code);
  415.     }
  416. }
  417.  
  418. static void on_exchange_mtu_response(const ble_gattc_evt_t * const p_ble_gattc_evt)
  419. {
  420.     uint16_t server_rx_mtu = p_ble_gattc_evt->params.exchange_mtu_rsp.server_rx_mtu;
  421.     printf("MTU response received. New ATT_MTU is %d\n", server_rx_mtu);
  422. }
  423. #endif
  424.  
  425. static void ble_address_to_string_convert(ble_gap_addr_t address, uint8_t * string_buffer)
  426. {
  427.     const int address_length = 6;
  428.     char temp_str[3];
  429.     int i = 0;
  430.  
  431.     for (i = address_length - 1; i >= 0; --i)
  432.     {
  433.         sprintf(temp_str, "%02X", address.addr[i]);
  434.         strcat((char *)string_buffer, temp_str);
  435.     }
  436. }
  437.  
  438. static uint32_t adv_report_parse(uint8_t type, data_t * p_advdata, data_t * p_typedata)
  439. {
  440.     uint8_t * p_data;
  441.     uint32_t  index;
  442.  
  443.     p_data = p_advdata->p_data;
  444.     index = 0;
  445.  
  446.     while (index < p_advdata->data_len)
  447.     {
  448.         uint8_t field_length = p_data[index];
  449.         uint8_t field_type   = p_data[index+1];
  450.  
  451.         if (field_type == type)
  452.         {
  453.             p_typedata->p_data   = &p_data[index+2];
  454.             p_typedata->data_len = field_length-1;
  455.             return NRF_SUCCESS;
  456.         }
  457.         index += field_length+1;
  458.     }
  459.     return NRF_ERROR_NOT_FOUND;
  460. }
  461.  
  462. static uint32_t ble_stack_init()
  463. {
  464.     uint32_t err_code;
  465.     ble_enable_params_t ble_enable_params;
  466.     uint32_t * app_ram_base = NULL;
  467.  
  468.     memset(&ble_enable_params, 0, sizeof(ble_enable_params));
  469.  
  470. #if NRF_SD_BLE_API >= 3
  471.     ble_enable_params.gatt_enable_params.att_mtu = 158;
  472. #endif
  473.     ble_enable_params.gatts_enable_params.attr_tab_size   = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT;
  474.     ble_enable_params.gatts_enable_params.service_changed = false;
  475.     ble_enable_params.gap_enable_params.periph_conn_count = 1;
  476.     ble_enable_params.gap_enable_params.central_conn_count = 1;
  477.     ble_enable_params.gap_enable_params.central_sec_count = 1;
  478.     ble_enable_params.common_enable_params.p_conn_bw_counts = NULL;
  479.     ble_enable_params.common_enable_params.vs_uuid_count = 5;
  480.  
  481.     err_code = sd_ble_enable(m_adapter, &ble_enable_params, app_ram_base);
  482.  
  483.     if (err_code == NRF_SUCCESS)
  484.     {
  485.         return err_code;
  486.     }
  487.  
  488.     if (err_code == NRF_ERROR_INVALID_STATE)
  489.     {
  490.         printf("BLE stack already enabled\n"); fflush(stdout);
  491.         return NRF_SUCCESS;
  492.     }
  493.  
  494.     printf("Failed to enable BLE stack.\n"); fflush(stdout);
  495.     return err_code;
  496. }
  497.  
  498. static uint32_t ble_options_set()
  499. {
  500.     ble_opt_t opt;
  501.     ble_common_opt_t common_opt;
  502.     common_opt.conn_bw.role = BLE_GAP_ROLE_CENTRAL;
  503.     common_opt.conn_bw.conn_bw.conn_bw_rx = BLE_CONN_BW_HIGH;
  504.     common_opt.conn_bw.conn_bw.conn_bw_tx = BLE_CONN_BW_HIGH;
  505.     opt.common_opt = common_opt;
  506.  
  507.     uint32_t err_code = sd_ble_opt_set(m_adapter, BLE_COMMON_OPT_CONN_BW, &opt);
  508.  
  509.     return err_code;
  510. }
  511.  
  512. static uint32_t scan_start()
  513. {
  514.     uint32_t error_code = sd_ble_gap_scan_start(m_adapter, &m_scan_param);
  515.  
  516.     if (error_code != NRF_SUCCESS)
  517.     {
  518.         printf("Scan start failed\n"); fflush(stdout);
  519.         return error_code;
  520.     }
  521.  
  522.     printf("Scan started\n"); fflush(stdout);
  523.  
  524.     return NRF_SUCCESS;
  525. }
  526.  
  527. static uint32_t service_discovery_start()
  528. {
  529.     uint16_t start_handle;
  530.     uint32_t err_code;
  531.     ble_uuid_t srvc_uuid;
  532.  
  533.     printf("Discovering primary services\n"); fflush(stdout);
  534.     start_handle = 0x0001;
  535.  
  536.     srvc_uuid.type = BLE_UUID_TYPE_BLE;
  537.     srvc_uuid.uuid = HRM_SERVICE_UUID;
  538.  
  539.     err_code = sd_ble_gattc_primary_services_discover(m_adapter,
  540.                                                       m_connection_handle, start_handle,
  541.                                                       &srvc_uuid);
  542.     if (err_code != NRF_SUCCESS)
  543.     {
  544.         printf("Failed to discover primary services\n"); fflush(stdout);
  545.         return err_code;
  546.     }
  547.  
  548.     return NRF_SUCCESS;
  549. }
  550.  
  551. static uint32_t char_discovery_start()
  552. {
  553.     uint32_t err_code;
  554.     ble_gattc_handle_range_t handle_range;
  555.  
  556.     printf("Discovering characteristics\n"); fflush(stdout);
  557.  
  558.     handle_range.start_handle = m_service_start_handle;
  559.     handle_range.end_handle = m_service_end_handle;
  560.  
  561.     err_code = sd_ble_gattc_characteristics_discover(m_adapter, m_connection_handle, &handle_range);
  562.  
  563.     return err_code;
  564. }
  565.  
  566. static uint32_t descr_discovery_start()
  567. {
  568.     uint32_t err_code;
  569.     ble_gattc_handle_range_t handle_range;
  570.  
  571.     printf("Discovering descriptors\n"); fflush(stdout);
  572.  
  573.     if (m_hrm_char_handle == 0)
  574.     {
  575.         printf("Error. No HRM characteristic handle has been found\n"); fflush(stdout);
  576.         return NRF_ERROR_INVALID_STATE;
  577.     }
  578.  
  579.     handle_range.start_handle = m_hrm_char_handle;
  580.     handle_range.end_handle = m_service_end_handle;
  581.  
  582.     err_code = sd_ble_gattc_descriptors_discover(m_adapter, m_connection_handle, &handle_range);
  583.     return err_code;
  584. }
  585.  
  586. static uint32_t hrm_cccd_set(uint8_t value)
  587. {
  588.     uint32_t err_code;
  589.     ble_gattc_write_params_t write_params;
  590.     uint8_t cccd_value[2] = {value, 0};
  591.  
  592.     printf("Setting HRM CCCD\n"); fflush(stdout);
  593.  
  594.     if (m_hrm_cccd_handle == 0)
  595.     {
  596.         printf("Error. No CCCD handle has been found\n"); fflush(stdout);
  597.         return NRF_ERROR_INVALID_STATE;
  598.     }
  599.  
  600.     write_params.handle = m_hrm_cccd_handle;
  601.     write_params.len = 2;
  602.     write_params.p_value = cccd_value;
  603.     write_params.write_op = BLE_GATT_OP_WRITE_REQ;
  604.     write_params.offset = 0;
  605.     err_code = sd_ble_gattc_write(m_adapter, m_connection_handle, &write_params);
  606.  
  607.     return err_code;
  608. }
  609.  
  610. static void ble_evt_dispatch(adapter_t * adapter, ble_evt_t * p_ble_evt)
  611. {
  612.     if (p_ble_evt == NULL)
  613.     {
  614.         printf("Received empty ble_event\n"); fflush(stdout);
  615.         return;
  616.     }
  617.  
  618.     switch (p_ble_evt->header.evt_id)
  619.     {
  620.     case BLE_GAP_EVT_CONNECTED:
  621.         on_connected(&(p_ble_evt->evt.gap_evt));
  622.         break;
  623.  
  624.     case BLE_GAP_EVT_DISCONNECTED:
  625.         printf("Disconnected, reason: 0x%02X\n", p_ble_evt->evt.gap_evt.params.disconnected.reason);
  626.         fflush(stdout);
  627.         m_connected_devices--;
  628.         m_connection_handle = 0;
  629.         break;
  630.  
  631.     case BLE_GAP_EVT_ADV_REPORT:
  632.         on_adv_report(&(p_ble_evt->evt.gap_evt));
  633.         break;
  634.  
  635.     case BLE_GAP_EVT_TIMEOUT:
  636.         on_timeout(&(p_ble_evt->evt.gap_evt));
  637.         break;
  638.  
  639.     case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
  640.         on_service_discovery_response(&(p_ble_evt->evt.gattc_evt));
  641.         break;
  642.  
  643.     case BLE_GATTC_EVT_CHAR_DISC_RSP:
  644.         on_characteristic_discover_response(&(p_ble_evt->evt.gattc_evt));
  645.         break;
  646.  
  647.     case BLE_GATTC_EVT_DESC_DISC_RSP:
  648.         on_descriptor_discover_response(&(p_ble_evt->evt.gattc_evt));
  649.         break;
  650.  
  651.     case BLE_GATTC_EVT_WRITE_RSP:
  652.         on_write_response(&(p_ble_evt->evt.gattc_evt));
  653.         break;
  654.  
  655.     case BLE_GATTC_EVT_HVX:
  656.         on_hvx(&(p_ble_evt->evt.gattc_evt));
  657.         break;
  658.  
  659.     case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
  660.         on_conn_params_update_request(&(p_ble_evt->evt.gap_evt));
  661.         break;
  662.  
  663. #if NRF_SD_BLE_API >= 3
  664.     case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
  665.         on_exchange_mtu_request(&(p_ble_evt->evt.gatts_evt));
  666.         break;
  667.  
  668.     case BLE_GATTC_EVT_EXCHANGE_MTU_RSP:
  669.         on_exchange_mtu_response(&(p_ble_evt->evt.gattc_evt));
  670.         break;
  671. #endif
  672.  
  673.     default:
  674.         printf("Unhandled event with ID: %d\n", p_ble_evt->header.evt_id); fflush(stdout);
  675.         break;
  676.     }
  677. }
  678.  
  679. MyDialog::MyDialog()
  680. {
  681.     setLayout( new QVBoxLayout() );
  682.     QPushButton* button = new QPushButton( "Toggle", this );
  683.     connect( button, SIGNAL(clicked()), this, SLOT(toggle()) );
  684.  
  685.     layout()->addWidget( button );
  686.     layout()->addWidget( label = new QLabel( this ) );
  687.  
  688.     notify_dialog = this;
  689. }
  690.  
  691. MyDialog::~MyDialog()
  692. {
  693.     notify_dialog = NULL;
  694.     close();
  695. }
  696.  
  697. void MyDialog::showEvent( QShowEvent* event )
  698. {
  699.     QDialog::showEvent( event );
  700.     run();
  701. }
  702.  
  703. int MyDialog::run()
  704. {
  705.     uint32_t error_code;
  706.     char* serial_port;
  707.     physical_layer_t * phy;
  708.     data_link_layer_t * data_link_layer;
  709.     transport_layer_t * transport_layer;
  710.  
  711.         cccd_value = 0;
  712.  
  713.     serial_port = UART_PORT_NAME;
  714.  
  715.     printf("Serial port used: %s\n", serial_port); fflush(stdout);
  716.  
  717.     phy = sd_rpc_physical_layer_create_uart(serial_port, 1000000, SD_RPC_FLOW_CONTROL_NONE, SD_RPC_PARITY_NONE);
  718.  
  719.     data_link_layer = sd_rpc_data_link_layer_create_bt_three_wire(phy, 100);
  720.  
  721.     transport_layer = sd_rpc_transport_layer_create(data_link_layer, 100);
  722.  
  723.     m_adapter = sd_rpc_adapter_create(transport_layer);
  724.  
  725.     //sd_rpc_log_handler_severity_filter_set(adapter, SD_RPC_LOG_INFO);
  726.  
  727.     error_code = sd_rpc_open(m_adapter, status_handler, ble_evt_dispatch, log_handler);
  728.  
  729.     if (error_code != NRF_SUCCESS)
  730.     {
  731.         printf("Failed to open the nRF5 BLE Driver. Error code: 0x%02X\n", error_code);
  732.         fflush(stdout);
  733.         return error_code;
  734.     }
  735.  
  736.     error_code = ble_stack_init();
  737.  
  738.     if (error_code != NRF_SUCCESS)
  739.     {
  740.         return error_code;
  741.     }
  742.  
  743.     error_code = ble_options_set();
  744.  
  745.     if (error_code != NRF_SUCCESS)
  746.     {
  747.         return error_code;
  748.     }
  749.    
  750.     scan_start();
  751. }
  752.  
  753. void MyDialog::toggle()
  754. {
  755.     cccd_value ^= CCCD_NOTIFY;
  756.     hrm_cccd_set(cccd_value);
  757. }
  758.  
  759. uint32_t MyDialog::close()
  760. {
  761.     uint32_t error_code = sd_rpc_close(m_adapter);
  762.  
  763.     if (error_code != NRF_SUCCESS)
  764.     {
  765.         printf("Failed to close the nRF5 BLE Driver. Error code: 0x%02X\n", error_code);
  766.         fflush(stdout);
  767.         return error_code;
  768.     }
  769.  
  770.     printf("Closed\n"); fflush(stdout);
  771.  
  772.     return error_code;
  773. }
  774.  
  775. void MyDialog::notify( uint32_t count, float freq )
  776. {
  777.     std::stringstream str;
  778.     str << "During the last second, received " << count << " packets, frequency is " << freq << "Hz";
  779.     label->setText( str.str().c_str() );
  780. }
  781.  
  782. int main(int argc, char *argv[])
  783. {
  784.     QApplication app( argc, argv );
  785.     MyDialog frame;
  786.     frame.show();
  787.     return app.exec();
  788. }
Advertisement
Add Comment
Please, Sign In to add comment