ERR_CODE State::writeToStorage(uint8_t type, uint8_t* payload, uint8_t length, bool persistent) { switch(type) { // uint32_t variables case STATE_RESET_COUNTER: { if (length == 2) { uint32_t value = ((uint32_t*) payload)[0]; if (value == 0) { return set(type, payload, length); } } else { LOGe(FMT_WRONG_PAYLOAD_LENGTH, length); return ERR_WRONG_PAYLOAD_LENGTH; } break; } // variables with write disabled case STATE_SWITCH_STATE: case STATE_TEMPERATURE: case STATE_FACTORY_RESET: default: LOGw(FMT_STATE_NOT_FOUND, type); } return ERR_WRITE_DISABLED; }
ERR_CODE State::verify(uint8_t type, uint16_t size) { bool success; switch(type) { case STATE_RESET_COUNTER: case STATE_SWITCH_STATE: case STATE_ACCUMULATED_ENERGY: case STATE_POWER_USAGE: case STATE_OPERATION_MODE: case STATE_TEMPERATURE: case STATE_FACTORY_RESET: case STATE_TIME: case STATE_ERRORS: case STATE_ERROR_OVER_CURRENT: case STATE_ERROR_OVER_CURRENT_PWM: case STATE_ERROR_CHIP_TEMP: case STATE_ERROR_PWM_TEMP: case STATE_IGNORE_BITMASK: case STATE_IGNORE_ALL: case STATE_IGNORE_LOCATION: case STATE_ERROR_DIMMER_ON_FAILURE: case STATE_ERROR_DIMMER_OFF_FAILURE: { success = size == getStateItemSize(type); break; } case STATE_TRACKED_DEVICES: case STATE_SCHEDULE: case STATE_LEARNED_SWITCHES: { success = size <= getStateItemSize(type); break; } default: { LOGw(FMT_STATE_NOT_FOUND, type); return ERR_UNKNOWN_TYPE; } } if (success) { return ERR_SUCCESS; } else { LOGw(FMT_VERIFICATION_FAILED, type); return ERR_WRONG_PAYLOAD_LENGTH; } }
uint16_t State::getStateItemSize(uint8_t type) { switch(type) { case STATE_RESET_COUNTER: { return sizeof(reset_counter_t); } case STATE_SWITCH_STATE: { return sizeof(uint8_t); } case STATE_ACCUMULATED_ENERGY: { return sizeof(accumulated_energy_t); } case STATE_POWER_USAGE: { return sizeof(_powerUsage); } case STATE_TRACKED_DEVICES: { return sizeof(tracked_device_list_t); } case STATE_SCHEDULE: { return sizeof(schedule_list_t); } case STATE_OPERATION_MODE: case STATE_ERROR_OVER_CURRENT: case STATE_ERROR_OVER_CURRENT_PWM: case STATE_ERROR_CHIP_TEMP: case STATE_ERROR_PWM_TEMP: case STATE_IGNORE_LOCATION: case STATE_IGNORE_ALL: case STATE_ERROR_DIMMER_ON_FAILURE: case STATE_ERROR_DIMMER_OFF_FAILURE: { return sizeof(uint8_t); } case STATE_TEMPERATURE: { return sizeof(_temperature); } case STATE_FACTORY_RESET: { return sizeof(_factoryResetState); } case STATE_TIME: { return sizeof(_time); } case STATE_LEARNED_SWITCHES: { return MAX_SWITCHES * sizeof(learned_enocean_t); } case STATE_ERRORS: { return sizeof(state_errors_t); } case STATE_IGNORE_BITMASK: { return sizeof(state_ignore_bitmask_t); } default: { LOGw(FMT_STATE_NOT_FOUND, type); return 0; } } }
/** * Nordic bug: We have to clear the entire block! */ void Storage::clearBlock(pstorage_handle_t handle, ps_storage_id storageID) { storage_config_t* config; if (!(config = getStorageConfig(storageID))) { // if no config was found for the given storage ID return return; } pstorage_handle_t block_handle; BLE_CALL ( pstorage_block_identifier_get,(&handle, 0, &block_handle) ); LOGw("Nordic bug: clear entire block before writing to it"); BLE_CALL (pstorage_clear, (&block_handle, config->storage_size) ); }
uint32_t mesh_gatt_value_set(rbc_mesh_value_handle_t handle, uint8_t* data, uint8_t length) { if (length > RBC_MESH_VALUE_MAX_LEN) { return NRF_ERROR_INVALID_LENGTH; } if (m_active_conn_handle != CONN_HANDLE_INVALID) { if (nb_full()) { LOGw(FMT_BUFFER_FULL, "Notification"); return NRF_ERROR_NO_MEM; } else { if (notifactionsPending && !m_mesh_service.notification_enabled) { notifactionsPending = false; nb_clear(); } // todo: continue here: check if we can put on the scheduler waiting_notification_t* notification = nb_next(); notification->offset = 0; memcpy(notification->data, data, length); notification->length = length; notification->handle = handle; if (!notifactionsPending) { // LOGd("put into scheduler"); app_sched_event_put(NULL, 0, value_set_handler); // printArray(notification, sizeof(waiting_notification_t)); } else { #ifdef PRINT_MESH_VERBOSE LOGd("notification pending already"); #endif return BLE_ERROR_NO_TX_BUFFERS; } } } else { return BLE_ERROR_INVALID_CONN_HANDLE; } }
/** * Finalize bio_entry cache. */ void bio_entry_exit(void) { int cnt; cnt = atomic_dec_return(&shared_cnt_); if (cnt < 0) { LOGe("bio_entry_init() is not called yet.\n"); atomic_inc(&shared_cnt_); return; } #ifdef WALB_DEBUG if (cnt == 0) { const uint nr = atomic_read(&n_allocated_pages_); if (nr > 0) LOGw("n_allocated_pages %u\n", nr); } #endif }
/** * Decide flush support or not. */ void walb_decide_flush_support(struct walb_dev *wdev) { struct request_queue *q; const struct request_queue *lq, *dq; bool lq_flush, dq_flush, lq_fua, dq_fua; ASSERT(wdev); /* Get queues. */ q = wdev->queue; ASSERT(q); lq = bdev_get_queue(wdev->ldev); dq = bdev_get_queue(wdev->ddev); /* Get flush/fua flags. */ lq_flush = lq->flush_flags & REQ_FLUSH; dq_flush = dq->flush_flags & REQ_FLUSH; lq_fua = lq->flush_flags & REQ_FUA; dq_fua = dq->flush_flags & REQ_FUA; LOGn("flush/fua flags: log_device %d/%d data_device %d/%d\n", lq_flush, lq_fua, dq_flush, dq_fua); /* Check REQ_FLUSH/REQ_FUA supports. */ wdev->support_flush = false; wdev->support_fua = false; if (lq_flush && dq_flush) { uint flush_flags = REQ_FLUSH; LOGn("Supports REQ_FLUSH."); wdev->support_flush = true; if (lq_fua) { flush_flags |= REQ_FUA; LOGn("Supports REQ_FUA."); wdev->support_fua = true; } blk_queue_flush(q, flush_flags); blk_queue_flush_queueable(q, true); } else { LOGw("REQ_FLUSH is not supported!\n" "WalB can not guarantee data consistency" "in sudden crashes of underlying devices.\n"); } }
bool PowerSamples::init() { //! Allocate memory _buffer = (power_samples_t*)calloc(1, sizeof(power_samples_t)); if (_buffer == NULL) { LOGw(STR_ERR_ALLOCATE_MEMORY); return false; } #ifdef PRINT_POWERSAMPLES_VERBOSE LOGd(FMT_ALLOCATE_MEMORY, _buffer); #endif _allocatedSelf = true; _currentBuffer.assign((buffer_ptr_t)&_buffer->_currentSamples, sizeof(_buffer->_currentSamples)); _voltageBuffer.assign((buffer_ptr_t)&_buffer->_voltageSamples, sizeof(_buffer->_voltageSamples)); //! Also call clear to make sure we start with a clean buffer clear(); return true; }
void State::factoryReset(uint32_t resetCode) { if (resetCode != FACTORY_RESET_CODE) { LOGe("wrong reset code!"); return; } LOGw("resetting state variables"); // clear the storage in flash _storage->clearStorage(PS_ID_STATE); _storage->clearStorage(PS_ID_GENERAL); // reload struct memset(&_storageStruct, 0xFF, sizeof(_storageStruct)); // loadPersistentStorage(); // reset the cyclic storage objects #ifdef SWITCH_STATE_PERSISTENT _switchState->reset(); #endif _resetCounter->reset(); _accumulatedEnergy->reset(); }
ERR_CODE State::readFromStorage(uint8_t type, StreamBuffer<uint8_t>* streamBuffer) { uint16_t size; ERR_CODE error_code; switch(type) { case STATE_RESET_COUNTER: { size = sizeof(uint16_t); break; } case STATE_SWITCH_STATE: { size = sizeof(uint8_t); break; } case STATE_TEMPERATURE: { size = sizeof(int32_t); break; } case STATE_FACTORY_RESET: { size = sizeof(uint8_t); break; } case STATE_TIME: { size = sizeof(uint32_t); break; } case STATE_ERRORS: { size = sizeof(state_errors_t); break; } case STATE_TRACKED_DEVICES: { size = sizeof(tracked_device_list_t); //! TODO: setPayload already copies, why do we have to allocate a whole tracked_device_list_t uint8_t listBuffer[size]; //! wrap in an object to get correct size TrackedDeviceList list; list.assign(listBuffer, size); //! clear the list to make sure it is correctly //! initialized list.clear(); //! read the list from storage error_code = get(type, listBuffer, size); if (SUCCESS(error_code)) { //! get the size from the list size = list.getDataLength(); streamBuffer->setPayload(listBuffer, size); streamBuffer->setType(type); } return error_code; } case STATE_SCHEDULE: { size = sizeof(schedule_list_t); //! TODO: setPayload already copies, why do we have to allocate a whole schedule_list_t uint8_t listBuffer[size]; //! wrap in an object to get correct size ScheduleList list; list.assign(listBuffer, size); // //! clear the list to make sure it is correctly // //! initialized // list.clear(); //! read the list from storage error_code = get(type, listBuffer, size); if (SUCCESS(error_code)) { //! get the size from the list size = list.getDataLength(); streamBuffer->setPayload(listBuffer, size); streamBuffer->setType(type); } return error_code; } case STATE_LEARNED_SWITCHES: default: { LOGw(FMT_STATE_NOT_FOUND, type); return ERR_UNKNOWN_TYPE; } } uint8_t payload[size]; error_code = get(type, payload, size); if (SUCCESS(error_code)) { streamBuffer->setPayload(payload, size); streamBuffer->setType(type); } return error_code; }