Files
MySensors/drivers/Linux/SoftEeprom.cpp
T
Olivier 8bb3cfb2e1 MySensors 2.1.1 release (#752)
* Bump version to 2.2.0-beta (#713)

* OTA: Add incoming FW block check (#718)

* Linux: Add support for SPIDEV (#734)

RPi and Linux refactor.

Add GPIO Sysfs for GPIO operations.

Update configure script.

Fix some cppcheck warnings.

Add serial emulation that prints to stdout.

Fix some file headers.

* Fix getControllerConfig() (#737)

* Rename MyHwATmega328 to MyHwAVR (#738)

* AVR: Restrict fast pin function use (#739)

* Fix signing presentation bug (#740)

* Consolidate open PRs for bugfix release (#741)

* Revert "Bump version to 2.2.0-beta" (#744)

* Merge Master into Dev (#745)

* Fix spi flash error when compiling in Arduino IDE 1.6.6

* Bump minor version

* Fixed "invalid suffix on literal" warning

* Fix addressing bug in _doSign bitfield

* Make sure nodes not supporting signing informs GW

A node that does not support signing, still needs to inform the
gateway about this to make sure the gateway carries a valid signing
requirement table when a node Id that was requiering signing stops
doing this.
This fixes #286.

* Prevent SecureActuator from accepting ACKs as commands

As ACKs are not currently signed, allowing ACKs as commands
is a considerable security hole for this sketch. This is now resolved.

* Backport of bugfix (#259) in repeaters when forwarding signed messages

* Bumped version to 1.5.2

* Corrected doSign variable name (was _doSign)

* Bumped version to 1.5.3

* Add NULL termination to payloads

Messages addressed to "this" node, will have a null char
appended to the payload after message verification is
done, because some "getters" assume the message being a
string.

* MySensors 2.1.1 release
2017-01-18 21:57:07 +01:00

157 lines
4.1 KiB
C++

/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2017 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#include "log.h"
#include "SoftEeprom.h"
SoftEeprom::SoftEeprom(const char *fileName, size_t length)
{
struct stat fileInfo;
_fileName = strdup(fileName);
if (_fileName == NULL) {
logError("Error: %s\n", strerror(errno));
exit(1);
}
_length = length;
_values = new uint8_t[_length];
for (size_t i = 0; i < _length; ++i) {
_values[i] = 0xFF;
}
if (stat(_fileName, &fileInfo) != 0) {
//File does not exist. Create it.
logInfo("Config file %s does not exist, creating new config file.\n", _fileName);
std::ofstream myFile(_fileName, std::ios::out | std::ios::binary);
if (!myFile) {
logError("Unable to create config file %s.\n", _fileName);
exit(1);
}
myFile.write((const char*)_values, _length);
myFile.close();
} else if (fileInfo.st_size < 0 || (size_t)fileInfo.st_size != _length) {
logError("Config file %s is not the correct size of %zu. Please remove the file and a new one will be created.\n",
_fileName, _length);
exit(1);
} else {
//Read config into local memory.
std::ifstream myFile(_fileName, std::ios::in | std::ios::binary);
if (!myFile) {
logError("Unable to open config to file %s for reading.\n", _fileName);
exit(1);
}
myFile.read((char*)_values, _length);
myFile.close();
}
}
SoftEeprom::SoftEeprom(const SoftEeprom& other)
{
_fileName = strdup(other._fileName);
_length = other._length;
_values = new uint8_t[_length];
for (size_t i = 0; i < _length; ++i) {
_values[i] = other._values[i];
}
}
SoftEeprom::~SoftEeprom()
{
delete[] _values;
free(_fileName);
}
void SoftEeprom::readBlock(void* buf, void* addr, size_t length)
{
static bool config_to_mem = false;
unsigned long int offs = reinterpret_cast<unsigned long int>(addr);
if (!config_to_mem) {
//Read config into local memory.
std::ifstream myFile(_fileName, std::ios::in | std::ios::binary);
if (!myFile) {
logError("Unable to open config to file %s for reading.\n", _fileName);
exit(1);
}
myFile.read((char*)_values, _length);
myFile.close();
config_to_mem = true;
}
if (length && offs + length <= _length) {
memcpy(buf, _values+offs, length);
}
}
void SoftEeprom::writeBlock(void* buf, void* addr, size_t length)
{
unsigned long int offs = reinterpret_cast<unsigned long int>(addr);
if (length && offs + length <= _length) {
memcpy(_values+offs, buf, length);
std::ofstream myFile(_fileName, std::ios::out | std::ios::in | std::ios::binary);
if (!myFile) {
logError("Unable to write config to file %s.\n", _fileName);
return;
}
myFile.seekp(offs);
myFile.write((const char*)buf, length);
myFile.close();
}
}
uint8_t SoftEeprom::readByte(int addr)
{
uint8_t value = 0xFF;
readBlock(&value, reinterpret_cast<void*>(addr), 1);
return value;
}
void SoftEeprom::writeByte(int addr, uint8_t value)
{
uint8_t curr = readByte(addr);
if (curr != value) {
writeBlock(&value, reinterpret_cast<void*>(addr), 1);
}
}
SoftEeprom& SoftEeprom::operator=(const SoftEeprom& other)
{
if (this != &other) {
_fileName = strdup(other._fileName);
_length = other._length;
_values = new uint8_t[_length];
for (size_t i = 0; i < _length; ++i) {
_values[i] = other._values[i];
}
}
return *this;
}