Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
	}
}
Exemplo n.º 3
0
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;
	}
	}
}
Exemplo n.º 4
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) );
}
Exemplo n.º 5
0
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;
	}
}
Exemplo n.º 6
0
/**
 * 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
}
Exemplo n.º 7
0
/**
 * 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");
	}
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
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();
}
Exemplo n.º 10
0
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;
}