void mesh_gatt_sd_ble_event_handle(ble_evt_t* p_ble_evt) { switch (p_ble_evt->header.evt_id) { case BLE_GATTS_EVT_WRITE: { if (p_ble_evt->evt.gatts_evt.params.write.handle == m_mesh_service.ble_val_char_handles.value_handle) { mesh_gatt_evt_t* p_gatt_evt = (mesh_gatt_evt_t*) p_ble_evt->evt.gatts_evt.params.write.data; switch ((mesh_gatt_evt_opcode_t) p_gatt_evt->opcode) { case MESH_GATT_EVT_OPCODE_DATA: { if (p_gatt_evt->param.data_update.handle == RBC_MESH_INVALID_HANDLE) { mesh_gatt_cmd_rsp_push( (mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_INVALID_HANDLE); break; } vh_data_status_t vh_data_status = vh_local_update( p_gatt_evt->param.data_update.handle, p_gatt_evt->param.data_update.data, p_gatt_evt->param.data_update.data_len); rbc_mesh_event_t mesh_evt; mesh_evt.data = p_gatt_evt->param.data_update.data; mesh_evt.data_len = p_gatt_evt->param.data_update.data_len; mesh_evt.value_handle = p_gatt_evt->param.data_update.handle; mesh_evt.version_delta = 1; bool send_event = true; switch (vh_data_status) { case VH_DATA_STATUS_CONFLICTING: mesh_evt.event_type = RBC_MESH_EVENT_TYPE_CONFLICTING_VAL; break; case VH_DATA_STATUS_NEW: mesh_evt.event_type = RBC_MESH_EVENT_TYPE_NEW_VAL; break; case VH_DATA_STATUS_UPDATED: mesh_evt.event_type = RBC_MESH_EVENT_TYPE_UPDATE_VAL; break; default: mesh_gatt_cmd_rsp_push( (mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_BUSY); send_event = false; } if (send_event) { APP_ERROR_CHECK(rbc_mesh_event_push(&mesh_evt)); mesh_gatt_cmd_rsp_push( (mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_SUCCESS); } } break; case MESH_GATT_EVT_OPCODE_FLAG_SET: switch ((mesh_gatt_evt_flag_t) p_gatt_evt->param.flag_update.flag) { case MESH_GATT_EVT_FLAG_PERSISTENT: if (vh_value_persistence_set( p_gatt_evt->param.flag_update.handle, !!(p_gatt_evt->param.flag_update.value)) != NRF_SUCCESS) { mesh_gatt_cmd_rsp_push( (mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_INVALID_HANDLE); break; } mesh_gatt_cmd_rsp_push( (mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_SUCCESS); break; case MESH_GATT_EVT_FLAG_DO_TX: if (p_gatt_evt->param.flag_update.value) { if (vh_value_enable( p_gatt_evt->param.flag_update.handle) != NRF_SUCCESS) { mesh_gatt_cmd_rsp_push( (mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_INVALID_HANDLE); break; } mesh_gatt_cmd_rsp_push( (mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_SUCCESS); } else { if (vh_value_disable( p_gatt_evt->param.flag_update.handle) != NRF_SUCCESS) { mesh_gatt_cmd_rsp_push( (mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_INVALID_HANDLE); break; } mesh_gatt_cmd_rsp_push( (mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_SUCCESS); } break; default: mesh_gatt_cmd_rsp_push( (mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_UNKNOWN_FLAG); } break; case MESH_GATT_EVT_OPCODE_FLAG_REQ: switch ((mesh_gatt_evt_flag_t) p_gatt_evt->param.flag_update.flag) { case MESH_GATT_EVT_FLAG_PERSISTENT: { if (p_gatt_evt->param.flag_update.handle == RBC_MESH_INVALID_HANDLE) { mesh_gatt_cmd_rsp_push( (mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_INVALID_HANDLE); break; } bool is_persistent = false; if (vh_value_persistence_get( p_gatt_evt->param.flag_update.handle, &is_persistent) != NRF_SUCCESS) { mesh_gatt_cmd_rsp_push( (mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_NOT_FOUND); break; } mesh_gatt_evt_t rsp_evt; rsp_evt.opcode = MESH_GATT_EVT_OPCODE_FLAG_RSP; rsp_evt.param.flag_update.handle = p_gatt_evt->param.flag_update.handle; rsp_evt.param.flag_update.flag = p_gatt_evt->param.flag_update.flag; rsp_evt.param.flag_update.value = (uint8_t) is_persistent; mesh_gatt_evt_push(&rsp_evt); } break; case MESH_GATT_EVT_FLAG_DO_TX: { bool is_enabled; if (vh_value_is_enabled( p_gatt_evt->param.flag_update.handle, &is_enabled) != NRF_SUCCESS) { mesh_gatt_cmd_rsp_push( (mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_INVALID_HANDLE); break; } mesh_gatt_evt_t rsp_evt; rsp_evt.opcode = MESH_GATT_EVT_OPCODE_FLAG_RSP; rsp_evt.param.flag_update.handle = p_gatt_evt->param.flag_update.handle; rsp_evt.param.flag_update.flag = p_gatt_evt->param.flag_update.flag; rsp_evt.param.flag_update.value = (uint8_t) is_enabled; mesh_gatt_evt_push(&rsp_evt); } break; default: mesh_gatt_cmd_rsp_push( (mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_UNKNOWN_FLAG); } break; default: mesh_gatt_cmd_rsp_push( (mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_INVALID_OPCODE); } } else if (p_ble_evt->evt.gatts_evt.params.write.handle == m_mesh_service.ble_md_char_handles.value_handle) { mesh_metadata_char_t* p_md = (mesh_metadata_char_t*) p_ble_evt->evt.gatts_evt.params.write.data; tc_radio_params_set(p_md->mesh_access_addr, p_md->mesh_channel); vh_min_interval_set(p_md->mesh_interval_min_ms); } else if (p_ble_evt->evt.gatts_evt.params.write.handle == m_mesh_service.ble_val_char_handles.cccd_handle) { m_mesh_service.notification_enabled = (p_ble_evt->evt.gatts_evt.params.write.data[0] != 0); } break; } case BLE_GAP_EVT_CONNECTED: { m_active_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; } case BLE_GAP_EVT_DISCONNECTED: { m_active_conn_handle = CONN_HANDLE_INVALID; // clear notification buffer on disconnect notifactionsPending = false; nb_clear(); break; } case BLE_EVT_TX_COMPLETE: { if (notifactionsPending) { resume_notifications(); } break; } } }
void mesh_gatt_sd_ble_event_handle(ble_evt_t* p_ble_evt) { if (p_ble_evt->header.evt_id == BLE_GATTS_EVT_WRITE) { if (p_ble_evt->evt.gatts_evt.params.write.handle == m_mesh_service.ble_val_char_handles.value_handle) { mesh_gatt_evt_t* p_gatt_evt = (mesh_gatt_evt_t*) p_ble_evt->evt.gatts_evt.params.write.data; switch ((mesh_gatt_evt_opcode_t) p_gatt_evt->opcode) { case MESH_GATT_EVT_OPCODE_DATA: { if (p_gatt_evt->param.data_update.handle == RBC_MESH_INVALID_HANDLE) { mesh_gatt_cmd_rsp_push((mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_INVALID_HANDLE); break; } uint32_t error_code = vh_local_update( p_gatt_evt->param.data_update.handle, p_gatt_evt->param.data_update.data, p_gatt_evt->param.data_update.data_len); if (error_code == NRF_SUCCESS) { rbc_mesh_event_t mesh_evt; mesh_evt.type = RBC_MESH_EVENT_TYPE_UPDATE_VAL; mesh_evt.params.rx.p_data = p_gatt_evt->param.data_update.data; mesh_evt.params.rx.data_len = p_gatt_evt->param.data_update.data_len; mesh_evt.params.rx.value_handle = p_gatt_evt->param.data_update.handle; mesh_evt.params.rx.version_delta = 1; mesh_evt.params.rx.timestamp_us = timer_now(); if (rbc_mesh_event_push(&mesh_evt) != NRF_SUCCESS) { mesh_gatt_cmd_rsp_push((mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_BUSY); } else { mesh_gatt_cmd_rsp_push((mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_SUCCESS); } } else { mesh_gatt_cmd_rsp_push((mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_BUSY); } } break; case MESH_GATT_EVT_OPCODE_FLAG_SET: switch ((mesh_gatt_evt_flag_t) p_gatt_evt->param.flag_update.flag) { case MESH_GATT_EVT_FLAG_PERSISTENT: if (vh_value_persistence_set(p_gatt_evt->param.flag_update.handle, !!(p_gatt_evt->param.flag_update.value)) != NRF_SUCCESS) { mesh_gatt_cmd_rsp_push((mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_INVALID_HANDLE); break; } mesh_gatt_cmd_rsp_push((mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_SUCCESS); break; case MESH_GATT_EVT_FLAG_DO_TX: if (p_gatt_evt->param.flag_update.value) { if (vh_value_enable(p_gatt_evt->param.flag_update.handle) != NRF_SUCCESS) { mesh_gatt_cmd_rsp_push((mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_INVALID_HANDLE); break; } mesh_gatt_cmd_rsp_push((mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_SUCCESS); } else { if (vh_value_disable(p_gatt_evt->param.flag_update.handle) != NRF_SUCCESS) { mesh_gatt_cmd_rsp_push((mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_INVALID_HANDLE); break; } mesh_gatt_cmd_rsp_push((mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_SUCCESS); } break; default: mesh_gatt_cmd_rsp_push((mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_UNKNOWN_FLAG); } break; case MESH_GATT_EVT_OPCODE_FLAG_REQ: switch ((mesh_gatt_evt_flag_t) p_gatt_evt->param.flag_update.flag) { case MESH_GATT_EVT_FLAG_PERSISTENT: { if (p_gatt_evt->param.flag_update.handle == RBC_MESH_INVALID_HANDLE) { mesh_gatt_cmd_rsp_push((mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_INVALID_HANDLE); break; } bool is_persistent = false; if (vh_value_persistence_get(p_gatt_evt->param.flag_update.handle, &is_persistent) != NRF_SUCCESS) { mesh_gatt_cmd_rsp_push((mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_NOT_FOUND); break; } mesh_gatt_evt_t rsp_evt; rsp_evt.opcode = MESH_GATT_EVT_OPCODE_FLAG_RSP; rsp_evt.param.flag_update.handle = p_gatt_evt->param.flag_update.handle; rsp_evt.param.flag_update.flag = p_gatt_evt->param.flag_update.flag; rsp_evt.param.flag_update.value = (uint8_t) is_persistent; mesh_gatt_evt_push(&rsp_evt); } break; case MESH_GATT_EVT_FLAG_DO_TX: { bool is_enabled; if (vh_value_is_enabled(p_gatt_evt->param.flag_update.handle, &is_enabled) != NRF_SUCCESS) { mesh_gatt_cmd_rsp_push((mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_INVALID_HANDLE); break; } mesh_gatt_evt_t rsp_evt; rsp_evt.opcode = MESH_GATT_EVT_OPCODE_FLAG_RSP; rsp_evt.param.flag_update.handle = p_gatt_evt->param.flag_update.handle; rsp_evt.param.flag_update.flag = p_gatt_evt->param.flag_update.flag; rsp_evt.param.flag_update.value = (uint8_t) is_enabled; mesh_gatt_evt_push(&rsp_evt); } break; default: mesh_gatt_cmd_rsp_push((mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_UNKNOWN_FLAG); } break; default: mesh_gatt_cmd_rsp_push((mesh_gatt_evt_opcode_t) p_gatt_evt->opcode, MESH_GATT_RESULT_ERROR_INVALID_OPCODE); } } else if (p_ble_evt->evt.gatts_evt.params.write.handle == m_mesh_service.ble_md_char_handles.value_handle) { mesh_metadata_char_t* p_md = (mesh_metadata_char_t*) p_ble_evt->evt.gatts_evt.params.write.data; tc_radio_params_set(p_md->mesh_access_addr, p_md->mesh_channel); vh_min_interval_set(p_md->mesh_interval_min_ms); } else if (p_ble_evt->evt.gatts_evt.params.write.handle == m_mesh_service.ble_val_char_handles.cccd_handle) { m_mesh_service.notification_enabled = (p_ble_evt->evt.gatts_evt.params.write.data[0] != 0); } } else if (p_ble_evt->header.evt_id == BLE_GAP_EVT_CONNECTED) { m_active_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; } else if (p_ble_evt->header.evt_id == BLE_GAP_EVT_DISCONNECTED) { m_active_conn_handle = CONN_HANDLE_INVALID; } }