bool nRF51822::unsubcribeRemoteCharacteristic(BLERemoteCharacteristic& characteristic) { bool success = false; for (int i = 0; i < this->_numRemoteCharacteristics; i++) { if (this->_remoteCharacteristicInfo[i].characteristic == &characteristic) { if (this->_remoteCharacteristicInfo[i].valueHandle && (this->_remoteCharacteristicInfo[i].properties.notify || this->_remoteCharacteristicInfo[i].properties.indicate)) { ble_gattc_write_params_t writeParams; uint16_t value = 0x0000; writeParams.write_op = BLE_GATT_OP_WRITE_REQ; #ifndef __RFduino__ writeParams.flags = 0; #endif writeParams.handle = (this->_remoteCharacteristicInfo[i].valueHandle + 1); // don't discover descriptors for now writeParams.offset = 0; writeParams.len = sizeof(value); writeParams.p_value = (uint8_t*)&value; this->_remoteRequestInProgress = true; success = (sd_ble_gattc_write(this->_connectionHandle, &writeParams) == NRF_SUCCESS); } break; } } return success; }
/**@brief Function for passing any pending request from the buffer to the stack. */ static void tx_buffer_process(void) { if (m_tx_index != m_tx_insert_index) { uint32_t err_code; if (m_tx_buffer[m_tx_index].type == READ_REQ) { err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle, m_tx_buffer[m_tx_index].req.read_handle, 0); } else { err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle, &m_tx_buffer[m_tx_index].req.write_req.gattc_params); } if (err_code == NRF_SUCCESS) { LOG("[BAS_C]: SD Read/Write API returns Success..\r\n"); m_tx_index++; m_tx_index &= TX_BUFFER_MASK; } else { LOG("[BAS_C]: SD Read/Write API returns error. This message sending will be " "attempted again..\r\n"); } } }
/**@brief Function for creating a message for writing to the CCCD. */ static uint32_t cccd_configure(uint16_t conn_handle, uint16_t cccd_handle, bool enable) { uint8_t buf[BLE_CCCD_VALUE_LEN]; buf[0] = enable ? BLE_GATT_HVX_NOTIFICATION : 0; buf[1] = 0; const ble_gattc_write_params_t write_params = { .write_op = BLE_GATT_OP_WRITE_REQ, .flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE, .handle = cccd_handle, .offset = 0, .len = sizeof(buf), .p_value = buf }; return sd_ble_gattc_write(conn_handle, &write_params); } uint32_t ble_nus_c_rx_notif_enable(ble_nus_c_t * p_ble_nus_c) { VERIFY_PARAM_NOT_NULL(p_ble_nus_c); if ( (p_ble_nus_c->conn_handle == BLE_CONN_HANDLE_INVALID) ||(p_ble_nus_c->handles.nus_rx_cccd_handle == BLE_GATT_HANDLE_INVALID) ) { return NRF_ERROR_INVALID_STATE; } return cccd_configure(p_ble_nus_c->conn_handle,p_ble_nus_c->handles.nus_rx_cccd_handle, true); }
bool nRF51822::writeRemoteCharacteristic(BLERemoteCharacteristic& characteristic, const unsigned char value[], unsigned char length) { bool success = false; for (int i = 0; i < this->_numRemoteCharacteristics; i++) { if (this->_remoteCharacteristicInfo[i].characteristic == &characteristic) { if (this->_remoteCharacteristicInfo[i].valueHandle && (this->_remoteCharacteristicInfo[i].properties.write_wo_resp || this->_remoteCharacteristicInfo[i].properties.write) && (this->_txBufferCount > 0)) { ble_gattc_write_params_t writeParams; writeParams.write_op = (this->_remoteCharacteristicInfo[i].properties.write) ? BLE_GATT_OP_WRITE_REQ : BLE_GATT_OP_WRITE_CMD; #ifndef __RFduino__ writeParams.flags = 0; #endif writeParams.handle = this->_remoteCharacteristicInfo[i].valueHandle; writeParams.offset = 0; writeParams.len = length; writeParams.p_value = (uint8_t*)value; this->_remoteRequestInProgress = true; this->_txBufferCount--; success = (sd_ble_gattc_write(this->_connectionHandle, &writeParams) == NRF_SUCCESS); } break; } } return success; }
/*Send the updated ctrls to the Ms. Pacman node*/ static void sendToMsPacman(MsPacmanCtrls ms_pacman) { ble_gattc_write_params_t write_params = {0}; uint8_t ms_pacman_buf[BLE_MS_PACMAN_CHARACTERISTIC_SIZE]; //Find the Ms. Pacman node uint32_t node_ndx = client_find_node(MS_PACMAN_NODE); client_t ms_pacman_node = m_client[node_ndx]; //Don't do anything if Ms. Pacman isn't connected if(ms_pacman_node.state == IDLE) { return; } //Fill in the buffer with the appropriate values ms_pacman_buf[BLE_MS_PACMAN_OFFSET_ARROW] = ms_pacman.arrow_direction; ms_pacman_buf[BLE_MS_PACMAN_OFFSET_BUTTON_A] = ms_pacman.button_a; ms_pacman_buf[BLE_MS_PACMAN_OFFSET_BUTTON_B] = ms_pacman.button_b; /* Central writes to CCCD of peripheral to receive indications */ write_params.write_op = BLE_GATT_OP_WRITE_REQ; write_params.handle = ms_pacman_node.srv_db.services[0].charateristics[ms_pacman_node.char_index].characteristic.handle_value; write_params.offset = 0; write_params.len = BLE_MS_PACMAN_CHARACTERISTIC_SIZE; write_params.p_value = ms_pacman_buf; sd_ble_gattc_write(ms_pacman_node.srv_db.conn_handle, &write_params); }
//Throws different errors that must be handeled u32 GATTController::bleWriteCharacteristic(u16 connectionHandle, u16 characteristicHandle, u8* data, u16 dataLength, bool reliable) { u32 err = 0; u8 t = ((connPacketHeader*)data)->messageType; if( t != 20 && t != 21 && t != 22 && t != 23 && t != 30 && t != 31 && t != 50 && t != 51 && t != 52 && t != 53 && t != 56 && t != 57 && t != 60 && t != 61 && t != 62 && t != 80 && t != 81){ logt("ERROR", "BOOOOOOH, WRONG DATAAAAAAAAAAAAAAAAA!!!!!!!!!"); } logt("CONN_DATA", "Data size is: %d, handles(%d, %d), reliable %d", dataLength, connectionHandle, characteristicHandle, reliable); char stringBuffer[100]; Logger::getInstance().convertBufferToHexString(data, dataLength, stringBuffer, 100); logt("CONN_DATA", "%s", stringBuffer); //Configure the write parameters with reliable/unreliable, writehandle, etc... ble_gattc_write_params_t writeParameters; memset(&writeParameters, 0, sizeof(ble_gattc_write_params_t)); writeParameters.handle = characteristicHandle; writeParameters.offset = 0; writeParameters.len = dataLength; writeParameters.p_value = data; if (reliable) { writeParameters.write_op = BLE_GATT_OP_WRITE_REQ; err = sd_ble_gattc_write(connectionHandle, &writeParameters); return err; } else { writeParameters.write_op = BLE_GATT_OP_WRITE_CMD; err = sd_ble_gattc_write(connectionHandle, &writeParameters); return err; } }
/**@brief Function for performing a Write procedure. * * @param[in] conn_handle Handle of the connection on which to perform the write operation. * @param[in] write_handle Handle of the attribute to be written. * @param[in] length Length of data to be written. * @param[in] p_value Data to be written. * * @return NRF_SUCCESS on success, otherwise an error code. */ static uint32_t write_characteristic_value(uint16_t conn_handle, uint16_t write_handle, uint16_t length, uint8_t * p_value) { ble_gattc_write_params_t write_params; memset(&write_params, 0, sizeof(write_params)); write_params.handle = write_handle; write_params.write_op = BLE_GATT_OP_WRITE_CMD; write_params.offset = 0; write_params.len = length; write_params.p_value = p_value; return sd_ble_gattc_write(conn_handle, &write_params); }
uint32_t ble_nus_c_string_send(ble_nus_c_t * p_ble_nus_c, uint8_t * p_string, uint16_t length) { VERIFY_PARAM_NOT_NULL(p_ble_nus_c); if (length > BLE_NUS_MAX_DATA_LEN) { NRF_LOG_WARNING("Content too long.\r\n"); return NRF_ERROR_INVALID_PARAM; } if (p_ble_nus_c->conn_handle == BLE_CONN_HANDLE_INVALID) { NRF_LOG_WARNING("Connection handle invalid.\r\n"); return NRF_ERROR_INVALID_STATE; } ble_gattc_write_params_t const write_params = { .write_op = BLE_GATT_OP_WRITE_CMD, .flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE, .handle = p_ble_nus_c->handles.nus_rx_handle, .offset = 0, .len = length, .p_value = p_string }; return sd_ble_gattc_write(p_ble_nus_c->conn_handle, &write_params); } uint32_t ble_nus_c_handles_assign(ble_nus_c_t * p_ble_nus, const uint16_t conn_handle, const ble_nus_c_handles_t * p_peer_handles) { VERIFY_PARAM_NOT_NULL(p_ble_nus); p_ble_nus->conn_handle = conn_handle; if (p_peer_handles != NULL) { p_ble_nus->handles.nus_tx_cccd_handle = p_peer_handles->nus_tx_cccd_handle; p_ble_nus->handles.nus_tx_handle = p_peer_handles->nus_tx_handle; p_ble_nus->handles.nus_rx_handle = p_peer_handles->nus_rx_handle; } return NRF_SUCCESS; }
/**@brief Function for handling enabling notifications. * * @param[in] p_client Client context information. */ static void notif_enable(client_t * p_client) { uint32_t err_code; ble_gattc_write_params_t write_params; uint8_t buf[BLE_CCCD_VALUE_LEN]; p_client->state = STATE_NOTIF_ENABLE; buf[0] = BLE_GATT_HVX_NOTIFICATION; buf[1] = 0; write_params.write_op = BLE_GATT_OP_WRITE_REQ; write_params.handle = p_client->srv_db.services[0].charateristics[p_client->char_index].cccd_handle; write_params.offset = 0; write_params.len = sizeof(buf); write_params.p_value = buf; err_code = sd_ble_gattc_write(p_client->srv_db.conn_handle, &write_params); APP_ERROR_CHECK(err_code); }
/**@brief Function for passing any pending request from the buffer to the stack. */ static void tx_buffer_process(void) { if (m_tx_index != m_tx_insert_index) { uint32_t err_code; if (m_tx_buffer[m_tx_index].type == READ_REQ) { err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle, m_tx_buffer[m_tx_index].req.read_handle, 0); } else { err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle, &m_tx_buffer[m_tx_index].req.write_req.gattc_params); } if (err_code == NRF_SUCCESS) { ++m_tx_index; m_tx_index &= TX_BUFFER_MASK; } } }
uint32_t ble_nus_c_string_send(ble_nus_c_t * p_ble_nus_c, uint8_t * p_string, uint16_t length) { VERIFY_PARAM_NOT_NULL(p_ble_nus_c); if (length > BLE_NUS_MAX_DATA_LEN) { return NRF_ERROR_INVALID_PARAM; } if ( p_ble_nus_c->conn_handle == BLE_CONN_HANDLE_INVALID) { return NRF_ERROR_INVALID_STATE; } const ble_gattc_write_params_t write_params = { .write_op = BLE_GATT_OP_WRITE_CMD, .flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE, .handle = p_ble_nus_c->nus_tx_handle, .offset = 0, .len = length, .p_value = p_string }; return sd_ble_gattc_write(p_ble_nus_c->conn_handle, &write_params); }
/**@brief Function for creating a message for writing to the CCCD. */ static uint32_t cccd_configure(uint16_t conn_handle, uint16_t cccd_handle, bool enable) { uint8_t buf[BLE_CCCD_VALUE_LEN]; buf[0] = enable ? BLE_GATT_HVX_NOTIFICATION : 0; buf[1] = 0; const ble_gattc_write_params_t write_params = { .write_op = BLE_GATT_OP_WRITE_REQ, .flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE, .handle = cccd_handle, .offset = 0, .len = sizeof(buf), .p_value = buf }; return sd_ble_gattc_write(conn_handle, &write_params); } uint32_t ble_nus_c_rx_notif_enable(ble_nus_c_t * p_ble_nus_c) { if (p_ble_nus_c == NULL) { return NRF_ERROR_NULL; } if ( (p_ble_nus_c->conn_handle == BLE_CONN_HANDLE_INVALID) ||(p_ble_nus_c->nus_rx_cccd_handle == BLE_GATT_HANDLE_INVALID) ) { return NRF_ERROR_INVALID_STATE; } return cccd_configure(p_ble_nus_c->conn_handle,p_ble_nus_c->nus_rx_cccd_handle, true); } uint32_t ble_nus_c_string_send(ble_nus_c_t * p_ble_nus_c, uint8_t * p_string, uint16_t length) { if (p_ble_nus_c == NULL) { return NRF_ERROR_NULL; } if (length > BLE_NUS_MAX_DATA_LEN) { return NRF_ERROR_INVALID_PARAM; } if ( p_ble_nus_c->conn_handle == BLE_CONN_HANDLE_INVALID) { return NRF_ERROR_INVALID_STATE; } const ble_gattc_write_params_t write_params = { .write_op = BLE_GATT_OP_WRITE_CMD, .flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE, .handle = p_ble_nus_c->nus_tx_handle, .offset = 0, .len = length, .p_value = p_string }; return sd_ble_gattc_write(p_ble_nus_c->conn_handle, &write_params); }