void ble_do_events() { spi_old = SPCR; SPI.setBitOrder(LSBFIRST); SPI.setClockDivider(SPI_CLOCK_DIV8); SPI.setDataMode(SPI_MODE0); if (lib_aci_is_pipe_available(&aci_state, PIPE_UART_OVER_BTLE_UART_TX_TX)) { if(tx_buffer_len > 0) { unsigned char Index = 0; while(tx_buffer_len > 20) { if(true == lib_aci_send_data(PIPE_UART_OVER_BTLE_UART_TX_TX, &tx_buff[Index], 20)) { Serial.print("data transmmit success! Length: "); Serial.print(20, DEC); Serial.print(" "); } else { Serial.println("data transmmit fail !"); } tx_buffer_len -= 20; Index += 20; aci_state.data_credit_available--; Serial.print("Data Credit available: "); Serial.println(aci_state.data_credit_available,DEC); ack = 0; while (!ack) process_events(); } if(true == lib_aci_send_data(PIPE_UART_OVER_BTLE_UART_TX_TX,& tx_buff[Index], tx_buffer_len)) { Serial.print("data transmmit success! Length: "); Serial.print(tx_buffer_len, DEC); Serial.print(" "); } else { Serial.println("data transmmit fail !"); } tx_buffer_len = 0; aci_state.data_credit_available--; Serial.print("Data Credit available: "); Serial.println(aci_state.data_credit_available,DEC); ack = 0; while (!ack) process_events(); } } process_events(); SPCR = spi_old; }
void ble_do_events() { if (lib_aci_is_pipe_available(&aci_state, PIPE_UART_OVER_BTLE_UART_TX_TX)) { if(tx_buffer_len > 0) { unsigned char Index = 0; while(tx_buffer_len > 20) { if(true == lib_aci_send_data(PIPE_UART_OVER_BTLE_UART_TX_TX, &tx_buff[Index], 20)) { Serial.print("data transmmit success! Length: "); Serial.print(20, DEC); Serial.print(" "); } else { Serial.println("data transmmit fail !"); } tx_buffer_len -= 20; Index += 20; aci_state.data_credit_available--; Serial.print("Data Credit available: "); Serial.println(aci_state.data_credit_available,DEC); ack = 0; while (!ack) process_events(); } if(true == lib_aci_send_data(PIPE_UART_OVER_BTLE_UART_TX_TX,& tx_buff[Index], tx_buffer_len)) { Serial.print("data transmmit success! Length: "); Serial.print(tx_buffer_len, DEC); Serial.print(" "); } else { Serial.println("data transmmit fail !"); } tx_buffer_len = 0; aci_state.data_credit_available--; Serial.print("Data Credit available: "); Serial.println(aci_state.data_credit_available,DEC); ack = 0; while (!ack) process_events(); } } process_events(); }
size_t Adafruit_BLE_UART::write(uint8_t * buffer, uint8_t len) { uint8_t bytesThisPass, sent = 0; #ifdef BLE_RW_DEBUG Serial.print(F("\tWriting out to BTLE:")); for (uint8_t i=0; i<len; i++) { Serial.print(F(" 0x")); Serial.print(buffer[i], HEX); } Serial.println(); #endif while(len) { // Parcelize into chunks bytesThisPass = len; if(bytesThisPass > ACI_PIPE_TX_DATA_MAX_LEN) bytesThisPass = ACI_PIPE_TX_DATA_MAX_LEN; if(!lib_aci_is_pipe_available(&aci_state, PIPE_UART_OVER_BTLE_UART_TX_TX)) { pollACI(); continue; } lib_aci_send_data(PIPE_UART_OVER_BTLE_UART_TX_TX, &buffer[sent], bytesThisPass); aci_state.data_credit_available--; delay(35); // required delay between sends if(!(len -= bytesThisPass)) break; sent += bytesThisPass; } return sent; }
bool ancs_send_buffered_command() { if (!command_send_enable && ((millis() - last_command_send) < 1000)) { return true; } uint8_t* buffer; size_t len = fifo_pop(buffer_commands, &buffer); if (len == 0) { return false; } uint8_t cmd, aid; uint32_t uid; unpack(buffer, "BIB", &cmd, &uid, &aid); debug_print(F("[ANCS CP] Command sent 0x")); debug_print(cmd, HEX); debug_print(F(" for notification #")); debug_print(uid, DEC); debug_print(F(" attribute 0x")); debug_print(aid, HEX); debug_println(); if (lib_aci_send_data(PIPE_ANCS_CONTROL_POINT_TX_ACK, buffer, len)) { command_send_enable = false; last_command_send = millis(); } else { Serial.print(F("!! Error sending data for notification #")); Serial.println(uid, DEC); } free(buffer); return true; }
boolean BLE::writeBufferToPipe(uint8_t *buffer, uint8_t byteCount, uint8_t pipe) { boolean success = false; if (lib_aci_is_pipe_available(&aci_state, pipe) && (aci_state.data_credit_available >= 1)) { #ifdef ACI_DEBUG Serial.print(byteCount); Serial.println(F(" bytes sent to pipe")); #endif success = lib_aci_send_data(pipe, buffer, byteCount); if (success) { aci_state.data_credit_available--; waitForDataCredit(); } else Serial.println(F("lib_aci_send_data() failed")); } else { /* notification pipe not available when no client ask for notification */ //Serial.println(F("Pipe not available or no remaining data credits: ")); } return success; }
size_t Adafruit_BLE_UART::write(uint8_t buffer) { bool status = false; size_t sent = 0; #ifdef BLE_RW_DEBUG Serial.print(F("\tWriting one byte 0x")); Serial.println(buffer, HEX); #endif if (lib_aci_is_pipe_available(&aci_state, PIPE_UART_OVER_BTLE_UART_TX_TX)) { // Get back whether we actually sent this bit or not status = lib_aci_send_data(PIPE_UART_OVER_BTLE_UART_TX_TX, &buffer, 1); // Validate that we actually sent the bit then // move the counter if ( status ) { aci_state.data_credit_available--; sent = 1; } delay(BLE_W_DELAY); // required delay between sends return sent; } pollACI(); return sent; }
size_t Adafruit_BLE_UART::write(uint8_t buffer) { /* Blocking delay waiting for available credit(s) */ while (0 == aci_state.data_credit_available) { pollACI(); delay(10); } #ifdef BLE_RW_DEBUG Serial.print(F("\tWriting one byte 0x")); Serial.println(buffer, HEX); #endif if (lib_aci_is_pipe_available(&aci_state, PIPE_UART_OVER_BTLE_UART_TX_TX)) { lib_aci_send_data(PIPE_UART_OVER_BTLE_UART_TX_TX, &buffer, 1); aci_state.data_credit_available--; delay(35); // required delay between sends return 1; } pollACI(); return 0; }
void send_battery_update(aci_state_t *aci_state, uint8_t percent_level) { if (lib_aci_send_data(PIPE_BATTERY_BATTERY_LEVEL_TX, &percent_level, sizeof(percent_level))) //Sending battery level over the air { aci_state->data_credit_available--; } }
bool GoosciBleGatt::sendData(const char *buffer, int size) { const uint8_t max_packet_size = BTLE_BUFFER_SIZE - 2; /* Force size/max_packet_size to round up */ uint8_t num_packets = (size + max_packet_size - 1) / max_packet_size; bool send_complete = true; for (uint8_t ii = 0; ii < num_packets; ii++) { bool is_last_packet = ((num_packets - 1) == ii); /* There are 3 possibilities for current_packet_size 1) It is the last packet and the remaining data is smaller than our allocated buffer (size % max_packet_size) 2) It is the last packet and the remaining data is equal to our allocated buffer (max_packet_size) 3) It is not the last packet (max_packet_size) */ uint8_t current_packet_size = (is_last_packet ? ((size % max_packet_size == 0) ? max_packet_size : (size % max_packet_size)) : max_packet_size); packet[0] = current_packet_size; packet[1] = is_last_packet; memcpy((void*)(packet + 2), buffer + ii * max_packet_size, current_packet_size); /* If send fails then we give up */ if (!(send_complete = lib_aci_send_data(PIPE_GOOSCI_SENSOR_VALUE_TX, packet, current_packet_size + 2))) break; aci_state.data_credit_available--; while (!is_last_packet && !isReadyToSend()) pollACI(); } return send_complete; }
void update_battery(aci_state_t *aci_stat, uint8_t percent_level) { bool is_discharging = false; uint8_t level_difference = 0; // Serial.print(F(" Is discharging: ")); // Serial.print(is_discharging); // Serial.print(F(" level_difference: ")); // Serial.print(level_difference); // Serial.print(F(" BATTERY_LVL_CHANGE_THRESHOLD: ")); // Serial.println(BATTERY_LVL_CHANGE_THRESHOLD); is_discharging = get_battery_evolution(&level_difference, percent_level); if (level_difference >= BATTERY_LVL_CHANGE_THRESHOLD) { //Serial.print(F(" Setting battery level ...")); lib_aci_set_local_data(aci_stat, PIPE_BATTERY_BATTERY_LEVEL_SET, &percent_level, sizeof(percent_level)); if(lib_aci_is_pipe_available(aci_stat, PIPE_BATTERY_BATTERY_LEVEL_TX)) { //Serial.print(F(" Sending battery level over the air ...")); if (lib_aci_send_data(PIPE_BATTERY_BATTERY_LEVEL_TX, &percent_level, sizeof(percent_level))) { aci_stat->data_credit_available--; } } previous_battery_level = percent_level; } }
void battery_on_pipe_status(aci_state_t *aci_stat) { if (percent_level_on_connect != battery_level_on_disconnect) { if(lib_aci_is_pipe_available(aci_stat, PIPE_BATTERY_BATTERY_LEVEL_TX)) { lib_aci_send_data(PIPE_BATTERY_BATTERY_LEVEL_TX, &percent_level_on_connect, sizeof(percent_level_on_connect)); } } }
bool heart_rate_send_hr(uint8_t meas_hr) { uint8_t data_index = 0; current_heart_rate_data[data_index] &= ~HEART_RATE_FLAGS_MEAS_SIZE_BIT; current_heart_rate_data[data_index] &= ~HEART_RATE_FLAGS_ENERGY_EXPENDED_STATUS_BIT; current_heart_rate_data[data_index] &= ~HEART_RATE_FLAGS_RR_INTERVAL_SUPPORT_BIT; data_index++; current_heart_rate_data[data_index++] = meas_hr; return lib_aci_send_data(PIPE_HEART_RATE_HEART_RATE_MEASUREMENT_TX, (uint8_t *)¤t_heart_rate_data[0] ,data_index); }
bool heart_rate_send_hr_expended_energy(uint8_t meas_hr, uint16_t expended_energy) { uint8_t data_index = 0; current_heart_rate_data[data_index] &= ~HEART_RATE_FLAGS_MEAS_SIZE_BIT; current_heart_rate_data[data_index] |= HEART_RATE_FLAGS_ENERGY_EXPENDED_STATUS_BIT; current_heart_rate_data[data_index] &= ~HEART_RATE_FLAGS_RR_INTERVAL_SUPPORT_BIT; data_index++; current_heart_rate_data[data_index++] = meas_hr; current_heart_rate_data[data_index++] = (uint8_t)expended_energy; current_heart_rate_data[data_index++] = (uint8_t)(expended_energy>>8); return lib_aci_send_data(PIPE_HEART_RATE_HEART_RATE_MEASUREMENT_TX, (uint8_t *)¤t_heart_rate_data[0] ,data_index); }
bool heart_rate_send_hr_bulk(int meas_hr[], short index) { uint8_t data_index = 0; current_heart_rate_data[data_index] &= ~HEART_RATE_FLAGS_MEAS_SIZE_BIT; current_heart_rate_data[data_index] &= ~HEART_RATE_FLAGS_ENERGY_EXPENDED_STATUS_BIT; current_heart_rate_data[data_index] &= ~HEART_RATE_FLAGS_RR_INTERVAL_SUPPORT_BIT; data_index++; while(data_index < HR_MAX_PAYLOAD || data_index < index) { current_heart_rate_data[data_index] = meas_hr[data_index -1]; data_index++; } return lib_aci_send_data(PIPE_HEART_RATE_HEART_RATE_MEASUREMENT_TX, (uint8_t *)¤t_heart_rate_data[0] ,data_index); }
bool nRF8001MeteoStation::send_humidity(float p_humidity) { if ((m_ack_humidity_measure_pending == false) && (p_humidity != m_last_hum)) { if (lib_aci_is_pipe_available(&aci_state, PIPE_METEO_STATION_HUMIDITY_MEASUREMENT_TX_ACK)) { m_hum_measure.measurement[0] = 0; m_hum_measure.measurement[1] = p_humidity; m_ack_humidity_measure_pending = lib_aci_send_data(PIPE_METEO_STATION_HUMIDITY_MEASUREMENT_TX_ACK, (uint8_t *)&m_hum_measure, PIPE_METEO_STATION_HUMIDITY_MEASUREMENT_TX_ACK_MAX_SIZE); if (m_ack_humidity_measure_pending) m_last_hum = p_humidity; return m_ack_humidity_measure_pending; } } return false; }
void RCTelemetry_BLE::sendRSSI(uint8_t rssi) { if (lib_aci_is_pipe_available(&aci_state, PIPE_RC_TELEMETRY_RSSI_TX)) { lib_aci_send_data(PIPE_RC_TELEMETRY_RSSI_TX, &rssi, 1); aci_state.data_credit_available--; delay(35); // required delay between sends return; } pollACI(); // TODO: how to handle when pipe is not available? retry? cache for later? warning on overriding cache? }
bool Adafruit_BLE_UART::uart_tx(uint8_t *buffer, uint8_t buffer_len) { bool status = false; if (lib_aci_is_pipe_available(&aci_state, PIPE_UART_OVER_BTLE_UART_TX_TX) && (aci_state.data_credit_available >= 1)) { status = lib_aci_send_data(PIPE_UART_OVER_BTLE_UART_TX_TX, buffer, buffer_len); if (status) { aci_state.data_credit_available--; } } return status; }
bool heart_rate_send_hr_rr_interval(uint8_t meas_hr, uint16_t *p_rr_intervals, uint8_t nb_intervals) { uint8_t data_index = 0, i; current_heart_rate_data[data_index] &= ~HEART_RATE_FLAGS_MEAS_SIZE_BIT; current_heart_rate_data[data_index] |= HEART_RATE_FLAGS_RR_INTERVAL_SUPPORT_BIT; current_heart_rate_data[data_index] &= ~HEART_RATE_FLAGS_ENERGY_EXPENDED_STATUS_BIT; data_index++; current_heart_rate_data[data_index++] = meas_hr; for(i = 0; i < nb_intervals; i ++) { current_heart_rate_data[data_index++] = (uint8_t) (p_rr_intervals[i]); current_heart_rate_data[data_index++] = (uint8_t)((p_rr_intervals[i])>>8); } return lib_aci_send_data(PIPE_HEART_RATE_HEART_RATE_MEASUREMENT_TX, (uint8_t *)¤t_heart_rate_data[0] ,data_index); }
bool health_thermometer_send_measure(uint32_t meas_temp) { uint8_t measurement_size = 5; uint8_t *p_in_val = (uint8_t *)&meas_temp; if (0 != (h_temperature.flags&H_THERMOMETER_FLAGS_TYPE_BIT)) { measurement_size++; h_temperature.time_type[H_THERMOMETER_POS_TYPE_NO_TSTAMP] = current_type; } h_temperature.flags &= ~H_THERMOMETER_FLAGS_T_STAMP_BIT; h_temperature.measurement[H_THERMOMETER_POS_TEMP_LSB0] = p_in_val[0];//p_in_val[3]; h_temperature.measurement[H_THERMOMETER_POS_TEMP_LSB1] = p_in_val[1];//p_in_val[2]; h_temperature.measurement[H_THERMOMETER_POS_TEMP_MSB0] = p_in_val[2];//p_in_val[1]; h_temperature.measurement[H_THERMOMETER_POS_TEMP_MSB1] = p_in_val[3];//p_in_val[0]; return lib_aci_send_data(PIPE_HEALTH_THERMOMETER_TEMPERATURE_MEASUREMENT_TX_ACK, (uint8_t *)&h_temperature, measurement_size); }
bool nRF8001MeteoStation::send_temperature(float p_temperature) { // if the last sending was acquitted and the temperature to send is different // from the earlier temperature, it checks if the pipe is available if ((m_ack_temperature_measure_pending == false) && (p_temperature != m_last_temp)) { if (lib_aci_is_pipe_available(&aci_state, PIPE_METEO_STATION_TEMPERATURE_MEASUREMENT_TX_ACK)) { // sets the structure with the corresponding flags (cf. .h) and the temperature with the given parameter m_temp_measure.flags = TEMPERATURE_MEASUREMENT_FLAGS; m_temp_measure.measurement[0] = p_temperature; m_temp_measure.measurement[1] = 0; m_temp_measure.measurement[2] = 0; m_temp_measure.measurement[3] = 0; // sends the temperature structure (Pipe, structure address, size) m_ack_temperature_measure_pending = lib_aci_send_data(PIPE_METEO_STATION_TEMPERATURE_MEASUREMENT_TX_ACK, (uint8_t *)&m_temp_measure, 5); // if the value was sent correctly, it stores the temperature if (m_ack_temperature_measure_pending) m_last_temp = p_temperature; return m_ack_temperature_measure_pending; } } return false; }
/** * This is the default write method. * * @param buffer - the data buffer * @param length - the data length * @returns bool - the write status */ bool NRF8001Driver::write(uint8_t* buffer, uint8_t length){ // Satus container bool status = false; // Check if we have a pipe free if (lib_aci_is_pipe_available(this->_aci_state, PIPE_UART_OVER_BTLE_UART_TX_TX) && (this->_aci_state->data_credit_available > 0)){ // Send the data status = lib_aci_send_data(PIPE_UART_OVER_BTLE_UART_TX_TX, buffer, length); // If we have a good status if (status){ // Decrease the write tokens this->_aci_state->data_credit_available--; } } // Return the status return status; }
boolean BLE::writeBufferToPipe(uint8_t *buffer, uint8_t byteCount, uint8_t pipe) { boolean success = false; if (lib_aci_is_pipe_available(&aci_state, pipe) && (aci_state.data_credit_available >= 1)) { // Serial.print(byteCount); // Serial.println(F(" bytes sent to pipe")); success = lib_aci_send_data(pipe, buffer, byteCount); if (success) { aci_state.data_credit_available--; waitForDataCredit(); } else Serial.println(F("lib_aci_send_data() failed")); } //else Serial.println(F("Pipe not available or no remaining data credits")); return success; }
bool health_thermometer_send_measure_with_t_stamp(uint32_t meas_temp, time_stamp_t *t_stamp, bool is_freshest_sample) { uint8_t measurement_size = 12; uint8_t *p_in_val = (uint8_t *)&meas_temp; if (0 != (h_temperature.flags&H_THERMOMETER_FLAGS_TYPE_BIT)) { measurement_size++; h_temperature.time_type[H_THERMOMETER_POS_TYPE_WITH_TSTAMP] = current_type; } h_temperature.measurement[H_THERMOMETER_POS_TEMP_LSB0] = p_in_val[3]; h_temperature.measurement[H_THERMOMETER_POS_TEMP_LSB1] = p_in_val[2]; h_temperature.measurement[H_THERMOMETER_POS_TEMP_MSB0] = p_in_val[1]; h_temperature.measurement[H_THERMOMETER_POS_TEMP_MSB1] = p_in_val[0]; h_temperature.time_type[H_THERMOMETER_POS_YEAR_LSB] = (uint8_t)(t_stamp->year); h_temperature.time_type[H_THERMOMETER_POS_YEAR_MSB] = (uint8_t)((t_stamp->year)>>8); h_temperature.time_type[H_THERMOMETER_POS_MOUNTH ] = t_stamp->month ; h_temperature.time_type[H_THERMOMETER_POS_DAY ] = t_stamp->day ; h_temperature.time_type[H_THERMOMETER_POS_HOUR ] = t_stamp->hour ; h_temperature.time_type[H_THERMOMETER_POS_MINUTE ] = t_stamp->minute ; h_temperature.time_type[H_THERMOMETER_POS_SECOND ] = t_stamp->seconds; h_temperature.flags |= H_THERMOMETER_FLAGS_T_STAMP_BIT; return lib_aci_send_data(PIPE_HEALTH_THERMOMETER_TEMPERATURE_MEASUREMENT_TX_ACK, (uint8_t *)&h_temperature, measurement_size); }
bool nrf8001_usart_tx(const uint8_t* buffer, uint16_t len) { return lib_aci_send_data(PIPE_UART_OVER_BTLE_UART_TX_TX, (uint8_t*)buffer, len); }
void uart_tx() { lib_aci_send_data(PIPE_UART_OVER_BTLE_UART_TX_TX, uart_buffer, uart_buffer_len); aci_state.data_credit_available--; }