19 #include "nrf_assert.h"
42 ble_gap_addr_t prev_received_adv_packet_addr;
43 ble_gap_addr_t curr_device_connecting;
44 ble_gap_scan_params_t scan_params;
45 uint32_t time_set_p_tx_in_reference;
47 bool scanning_reqested;
50 bool mode_trans_in_progess;
51 uint8_t ignored_adv_from_same_pru_cnt;
52 uint8_t nof_connections;
53 uint32_t ticks_at_mt_end;
57 uint8_t nof_samples_taken;
58 uint8_t variation_duration;
60 } ptu_cm_timeset_data_t;
90 static void m_connect(ble_gap_addr_t
const * p_addr)
92 ble_gap_scan_params_t scan_params;
93 uint32_t err_code, diff;
101 memcpy(&
m_status.curr_device_connecting, p_addr,
sizeof(ble_gap_addr_t));
103 memcpy(&scan_params, &
m_status.scan_params,
sizeof(scan_params));
104 scan_params.timeout = 1;
111 err_code = app_timer_cnt_get(&ticks_now);
112 APP_ERROR_CHECK(err_code);
115 scan_params.timeout += diff;
120 err_code = sd_ble_gap_connect(p_addr, &scan_params, &
m_conn_params);
121 }
while(err_code == NRF_ERROR_BUSY);
123 APP_ERROR_CHECK(err_code);
134 uint32_t err_code = sd_ble_gap_disconnect(conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
136 if((err_code != NRF_ERROR_INVALID_STATE) && (err_code != BLE_ERROR_INVALID_CONN_HANDLE))
137 APP_ERROR_CHECK(err_code);
141 static void m_on_fully_accepted_adv_packet(
ptu_reg_item_t * reg_item_p, ble_gap_evt_adv_report_t * p_adv_report);
152 ASSERT(reg_item != NULL);
155 err_code = app_timer_stop(reg_item->
timer_id);
156 APP_ERROR_CHECK(err_code);
160 APP_ERROR_CHECK(err_code);
173 err_code = sd_ble_gap_connect_cancel();
174 APP_ERROR_CHECK(err_code);
188 static void m_mode_trans_timer_handle(
void * p_context)
196 m_status.mode_trans_in_progess =
false;
199 static void m_set_reg_item_fully_accepted(
ptu_reg_item_t * reg_item_p)
201 #if PTU_REVOKE_ACCEPTED_STATE
210 err_code =
TIMER_START( reg_item_p->
timer_id, ptu_revoke_accepted_state_timeout_ms, reg_item_p);
211 APP_ERROR_CHECK(err_code);
212 #endif // PTU_REVOKE_ACCEPTED_STATE == true
217 static void m_reg_timer_handle(
void * p_context)
220 reg_item_p = p_context;
224 m_set_reg_item_fully_accepted(reg_item_p);
229 m_on_reg_timeout(p_context);
233 static void m_send_ctrl_denied_due_to_cc(
ptu_reg_item_t * reg_item_p)
248 static void m_stop_time_set_procedure(ptu_cm_timeset_data_t * p_ts)
252 err_code = app_timer_stop(m_time_set_check_timer_id);
253 APP_ERROR_CHECK(err_code);
257 p_ts->nof_samples_taken = 0;
258 p_ts->variation_duration = 0;
259 p_ts->load_variation =
false;
272 static ptu_cm_timeset_data_t ts;
278 APP_ERROR_CHECK(err_code);
281 APP_ERROR_CHECK(err_code);
285 ts.variation_duration+= 2;
286 ts.load_variation =
true;
289 else if(ts.load_variation)
294 m_stop_time_set_procedure(&ts);
297 ts.variation_duration = 0;
298 ts.load_variation =
false;
304 m_stop_time_set_procedure(&ts);
305 m_send_ctrl_denied_due_to_cc(reg_item_p);
333 err_code = sd_ble_gap_scan_start(&
m_status.scan_params);
334 }
while(err_code != NRF_SUCCESS);
346 err_code = sd_ble_gap_scan_stop();
347 }
while(err_code != NRF_SUCCESS);
353 static bool m_imp_shift_required(uint8_t adv_flags)
355 uint8_t pru_category;
360 static void m_update_pre_connect_adv_cnt_for_reg_item(
ptu_reg_item_t * reg_item_p)
368 APP_ERROR_CHECK(err_code);
379 m_set_reg_item_fully_accepted(reg_item_p);
385 if (*reg_item_p == NULL)
389 if(*reg_item_p == NULL)
393 if(*reg_item_p != NULL)
400 if(*reg_item_p != NULL)
410 static bool m_load_var_detected(
void)
415 APP_ERROR_CHECK(err_code);
419 static void m_on_partially_accepted_adv_packet(
ptu_reg_item_t * reg_item_p, ble_gap_evt_adv_report_t * p_adv_report)
426 m_update_pre_connect_adv_cnt_for_reg_item(reg_item_p);
430 static void m_on_fully_accepted_adv_packet(
ptu_reg_item_t * reg_item_p, ble_gap_evt_adv_report_t * p_adv_report)
432 if(p_adv_report != NULL)
435 if(reg_item_p != NULL)
450 bool imp_shift_ok, rssi_ok, fully_accepted, state_ok;
452 #ifndef PTU_DISABLE_DISTANT_LIST
454 #endif //PTU_DISABLE_DISTANT_LIST
461 if(reg_item_p != NULL && reg_item_p->
reconnect)
471 imp_shift_ok = ((m_imp_shift_required(adv_flags) && m_load_var_detected()) || (!m_imp_shift_required(adv_flags) || !
PTU_CCA_ADV_IMP_SHIFT_ENABLE));
475 if(fully_accepted && state_ok)
477 m_on_fully_accepted_adv_packet(reg_item_p, &p_ble_evt->evt.gap_evt.params.adv_report);
480 else if(rssi_ok || imp_shift_ok)
482 m_on_partially_accepted_adv_packet(reg_item_p, &p_ble_evt->evt.gap_evt.params.adv_report);
499 if( reg_item_p != NULL &&
508 static void m_device_registration_complete(
ptu_reg_item_t * reg_item_p)
512 err_code = app_timer_stop(reg_item_p->
timer_id);
513 APP_ERROR_CHECK(err_code);
516 m_status.mode_trans_in_progess =
false;
517 err_code = app_timer_stop(m_mode_trans_timer_id);
518 APP_ERROR_CHECK(err_code);
538 if(reg_item_p != NULL)
544 memset(&
m_status.curr_device_connecting, 0,
sizeof(ble_gap_addr_t));
558 err_code = app_timer_stop(reg_item_p->
timer_id);
559 APP_ERROR_CHECK(err_code);
563 APP_ERROR_CHECK(err_code);
582 if(p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN)
590 if(reg_item_p == NULL)
600 else if(p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_SECURITY_REQUEST)
615 uint8_t zero_address[BLE_GAP_ADDR_LEN];
617 memset(zero_address, 0, BLE_GAP_ADDR_LEN);
623 if(memcmp(reg_item_p->
address.addr, zero_address, BLE_GAP_ADDR_LEN) == 0)
628 else if(reg_item_p != NULL)
633 APP_ERROR_CHECK(err_code);
642 APP_ERROR_CHECK(err_code);
673 ble_gap_sec_params_t sec_params;
674 memset(&sec_params, 0,
sizeof(ble_gap_sec_params_t));
675 sec_params.io_caps = BLE_GAP_IO_CAPS_NONE;
679 err_code = sd_ble_gap_authenticate(conn_handle, &sec_params);
680 APP_ERROR_CHECK(err_code);
689 if(p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION)
711 err_code = sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, NULL, NULL);
712 APP_ERROR_CHECK(err_code);
724 if(reg_item_p != NULL)
727 switch(reg_item_p->
state)
758 ASSERT(p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.sm == 1);
759 ASSERT(p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv == 2);
768 uint8_t mode_trans_val;
771 err_code = app_timer_cnt_get(&
m_status.ticks_at_mt_end);
772 APP_ERROR_CHECK(err_code);
781 ASSERT(p_reg_item != NULL);
783 switch(mode_trans_val)
786 err_code = app_timer_start(m_mode_trans_timer_id, APP_TIMER_TICKS(2000,
APP_TIMER_PRESCALER), NULL);
787 APP_ERROR_CHECK(err_code);
792 err_code = app_timer_start(m_mode_trans_timer_id, APP_TIMER_TICKS(3000,
APP_TIMER_PRESCALER), NULL);
793 APP_ERROR_CHECK(err_code);
798 err_code = app_timer_start(m_mode_trans_timer_id, APP_TIMER_TICKS(6000,
APP_TIMER_PRESCALER), NULL);
799 APP_ERROR_CHECK(err_code);
803 m_status.mode_trans_in_progess =
true;
817 if(reg_entry != NULL)
840 err_code = app_timer_stop(reg_item_p->
timer_id);
841 APP_ERROR_CHECK(err_code);
857 return m_status.mode_trans_in_progess;
867 if(sm_handler == NULL)
868 return NRF_ERROR_INVALID_PARAM;
871 memset(&
m_status, 0,
sizeof(ptu_cm_status_t));
878 APP_ERROR_CHECK(err_code);
880 err_code = app_timer_create(&(reg_item->
timer_id), APP_TIMER_MODE_SINGLE_SHOT, m_reg_timer_handle);
881 APP_ERROR_CHECK(err_code);
886 APP_ERROR_CHECK(err_code);
888 err_code = app_timer_create(&m_mode_trans_timer_id, APP_TIMER_MODE_SINGLE_SHOT, m_mode_trans_timer_handle);
889 APP_ERROR_CHECK(err_code);
898 switch (p_ble_evt->header.evt_id)
900 case BLE_GAP_EVT_ADV_REPORT:
902 if( p_ble_evt->evt.gap_evt.params.adv_report.scan_rsp == 0)
915 case BLE_GAP_EVT_CONNECTED:
919 case BLE_GAP_EVT_TIMEOUT:
923 case BLE_GAP_EVT_DISCONNECTED:
927 case BLE_GATTC_EVT_READ_RSP:
928 case BLE_GATTC_EVT_WRITE_RSP:
932 case BLE_GAP_EVT_SEC_REQUEST:
936 case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
940 case BLE_GAP_EVT_CONN_SEC_UPDATE:
957 if (reg_item_p != NULL)
959 switch (p_wpts_c_evt->
type)
981 APP_ERROR_CHECK(err_code);
996 m_device_registration_complete(reg_item_p);
998 err_code = app_timer_stop(reg_item_p->
timer_id);
999 APP_ERROR_CHECK(err_code);
1006 APP_ERROR_CHECK(err_code);
1022 m_on_wpt_alert(p_wpts_c, p_wpts_c_evt);
1034 m_status.scanning_reqested =
false;
1053 APP_ERROR_CHECK(err_code);
1064 for(uint8_t i = 0; i < n_reg_devices; i++)
PTU Static Parameter structure.
#define PTU_P_TX_IN_LOAD_DETECT
void ptu_reg_item_delete(ptu_reg_item_t *item)
Delete item that has previoulsy been added to registry.
uint32_t ble_wpts_service_data_read(ble_gap_evt_adv_report_t *p_adv_report, ble_wpts_service_data_t *p_service_data)
static void m_scan_maintain(void)
APP_TIMER_DEF(m_mode_trans_timer_id)
union ble_wpts_c_evt_t::@1 data
#define BLE_WPTS_PTU_STATIC_MAX_LOAD_RESISTANCE_VAL
ptu_reg_item_t * ptu_reg_item_add(ble_gap_evt_adv_report_t *p_adv_report, ptu_reg_item_state_t init_state)
Initiate registration of new device.
WPT Service Client structure. This contains various status information for the service.
void(* ptu_sm_handler_t)(ptu_sm_signal_type_t signal)
#define PTU_ADV_IGNORE_TIMEOUT_MS
#define BLE_WPTS_PTU_STATIC_NUM_DEVICES_BITVAL
#define BLE_WPTS_PRU_ALERT_MODE_NO_MODE_TRANSITION_VAL
PRU Alert Mode transition.
uint32_t ptu_sensors_read(void)
Read sensors. This function should typically be called regularly by a timer and can generate events b...
#define BLE_WPTS_UUID16
WPT Service UUIDs.
uint8_t ptu_reg_registered_devices_get(ptu_reg_item_t **registered_devices)
Get handles for all registered devices.
uint32_t ticks_diff(uint32_t ticks_now, uint32_t ticks_old)
uint32_t ble_wpts_c_enable_pru_alert_notification(ble_wpts_c_t *p_wpts_c)
Enable alert notifications to be sent from PRU.
#define BLE_WPTS_PRU_ALERT_MODE_2S_MODE_TRANSITION_VAL
static void m_connect(ble_gap_addr_t const *p_addr)
static void m_connection_init(ptu_reg_item_t *reg_item)
#define PTU_TIME_SET_500_MS_OF_SAMPLES
#define BLE_WPTS_ADV_FLAG_IMPEDANCE_SHIFT_BITPOS
uint32_t ptu_cm_init(ptu_sm_handler_t sm_handler)
Initialize connection manager.
static void m_on_scan_response(ble_evt_t *p_ble_evt)
uint32_t ble_wpts_c_read_pru_static(ble_wpts_c_t *p_wpts_c)
Read the PRU Static Parameter characterisic value from the PRU server.
uint32_t ble_wpts_c_write_ptu_static(ble_wpts_c_t *p_wpts_c, ptu_static_t *p_wpts_ptu_static)
Write the PTU Static characteristic to the PRU server.
ptu_reg_item_t * ptu_reg_item_get_from_address(ble_gap_addr_t *address)
Get registry item from GAP address.
uint32_t ptu_reg_item_get_from_index(uint8_t index, ptu_reg_item_t **item_p)
Get registry item from index in database. Index must be < PTU_MAX_CONNECTIONS.
uint8_t ptu_reg_n_entries_get(void)
Get the number of devices currently in registry. This will include all connected devices, as well as all devices which is currently being registered.
uint8_t enable_pru_output
#define PTU_MAX_CONN_INTERVAL
#define PTU_TIME_SET_CHECK_INTERVAL_MS
void ptu_cm_disconnect_all(void)
Disconnect all PRUs.
#define BLE_WPTS_PRU_CATEGORY_NO_IMP_SHIFT
PRU Static characteristic PRU Category field.
#define PTU_REVOKE_ACCEPTED_STATE_POWER_SAVE_MS
static void m_ptu_time_set_check_timer_handler(void *p_context)
Timeout handler for the time set functionality.
#define PTU_MIN_CONN_INTERVAL
#define PTU_TIME_SET_UPPER_LIMIT_MS
#define APP_ERROR_CHECK_ALLOW_DISCONNECT(ERR_CODE)
Macro equivalent to APP_ERROR_CHECK, except that error codes returned if connection is lost will be a...
static void m_pairing_start(uint16_t conn_handle)
static void m_on_evt_rw_response(ble_evt_t *p_ble_evt)
Struct holding contents of "Service data AD type".
uint32_t ble_wpts_c_read_pru_dynamic(ble_wpts_c_t *p_wpts_c)
Read the PRU Dynamic characterisic value from the PRU server.
static void m_on_evt_timeout(ble_evt_t *p_ble_evt)
static void ptu_char_pru_dynamic_read(uint16_t conn_handle)
Set pending dynamic read for PRU.
#define PTU_PROTOCOL_REVISION
#define PTU_NORMAL_SCAN_WINDOW
uint8_t pending_ctl_write
#define PTU_REVOKE_ACCEPTED_STATE_NON_POWER_SAVE_MS
bool ptu_dlh_device_is_in_distant_list(ble_gap_addr_t const *p_addr)
Check if device with provided address is in the distant list.
#define PTU_SLAVE_LATENCY
#define PTU_POWER_SAVE_STATE_SCAN_INTERVAL
void ptu_cm_on_ble_evt(ble_evt_t *p_ble_evt)
BLE event handler.
#define PTU_SEC_MAX_KEYSIZE
void ptu_power_ctrl_set_disable_power_amplifier_adjustments(bool val)
Enable/Disable adjustments of power amplifier (I_TX_COIL).
static void m_on_evt_seq_request(ble_evt_t *p_ble_evt)
void ptu_dlh_on_wpt_adv_report(ble_gap_addr_t const *p_addr, uint8_t adv_flags)
Distance list handler WPT Advertisement report handler.
#define PTU_RECONNECT_TIMEOUT_MS
void ptu_cm_scan_disable(void)
Disable scanning.
ptu_reg_item_state_t
Registry item status.
static void m_on_evt_sec_params_request(ble_evt_t *p_ble_evt)
#define BLE_WPTS_PRU_ALERT_MODE_6S_MODE_TRANSITION_VAL
ble_wpts_c_evt_type_t type
static void m_on_evt_disconnected(ble_evt_t *p_ble_evt)
uint8_t option_valid_max_imp
#define PTU_TIME_SET_LOWER_LIMIT_MS
#define BLE_WPTS_PTU_STATIC_MAX_SOURCE_IMPEDANCE_VAL
static void m_disconnect(uint16_t conn_handle)
pru_static_t prev_pru_static
static const ble_gap_conn_params_t m_conn_params
void ptu_cm_scan_enable(void)
Enable scanning.
#define BLE_WPTS_PRU_ALERT_MODE_3S_MODE_TRANSITION_VAL
WPT Service Client event.
static void m_on_evt_connected(ble_evt_t *p_ble_evt)
#define APP_TIMER_PRESCALER
#define PTU_CCA_RSSI_ENABLE
uint8_t pending_charge_disable
ptu_reg_item_t * ptu_reg_item_oldest_get(ptu_reg_item_state_t state)
Get oldest registry item having a specific state.
#define TIMER_START(timer_id, ms, p_ctx)
static void m_on_evt_conn_sec_update(ble_evt_t *p_ble_evt)
ptu_reg_item_t * ptu_reg_item_get_from_conn_handle(uint16_t conn_handle)
Get registry item from connection handle.
static ptu_sm_handler_t m_sm_handler
State machine event handler.
void ptu_cm_dynamic_read_all(void)
Issue read request for the PRU dynamic characteristic to all registerred PRUs.
#define PTU_NORMAL_SCAN_INTERVAL
uint8_t device_address[BLE_GAP_ADDR_LEN]
uint32_t ptu_sensors_data_get(const ptu_sensor_data_t **sensors_data)
Get the latest data read from the PTU sensors.
#define PTU_ADV_PRE_CONNECT_ALLOW
void ptu_cm_remove_device(ptu_reg_item_t *reg_item_p)
Disconnect and/or unregister any device.
static ptu_cm_status_t m_status
static void m_on_wpt_adv_report(ble_evt_t *p_ble_evt, uint8_t adv_flags)
#define BLE_WPTS_ADV_FLAG_IMPEDANCE_SHIFT_BITMSK
bool ptu_cm_mode_trans_in_progress(void)
Get mode transition status.
#define BLE_WPTS_PTU_POWER
#define BLE_WPTS_PTU_STATIC_MAX_SOURCE_IMPEDANCE_VALID
#define PTU_SM_CURRENT_STATE()
#define PTU_MAX_CONNECTIONS
void ptu_cm_on_wpt_service_evt(ble_wpts_c_t *p_wpts_c, ble_wpts_c_evt_t *const p_wpts_c_evt)
Handle service events.
#define PTU_POWER_SAVE_STATE_SCAN_WINDOW
#define BLE_WPTS_BITFIELD_READ(bitfield, msk, pos)
Read bitfield.
uint32_t ble_wpts_c_send_pru_control(ble_wpts_c_t *p_wpts_c, pru_control_t *p_wpts_pru_control)
Send a PRU Control message to the PRU server.
ptu_reg_item_state_t state
#define PTU_CONN_SUP_TIMEOUT
#define PTU_SEC_MIN_KEYSIZE
#define PTU_CCA_ADV_IMP_SHIFT_ENABLE
#define PTU_REG_TIMEOUT_MS
static ptu_static_t m_ptu_static
Definition of PTU sensor data.
#define BLE_WPTS_ADV_FLAG_TIME_SET_SUPPORT_BITMSK
ptu_sm_state_t ptu_sm_execute(ptu_sm_signal_type_t signal, ptu_sm_state_vars_t *p_state)
State machine input signal handler.
#define BLE_WPTS_ADV_FLAG_TIME_SET_SUPPORT_BITPOS
#define BLE_WPTS_PTU_STATIC_MAX_LOAD_RESISTANCE_VALID