2KB main config structure (NET_PARAM is 4096 so 2048 bytes left free)

This commit is contained in:
openshwprojects
2022-04-17 00:30:45 +02:00
parent 1d8914c3e2
commit eeba31415f
19 changed files with 541 additions and 1498 deletions

View File

@@ -50,7 +50,7 @@ void RepeatingEvents_OnEverySecond() {
cur = cur->next;
}
addLogAdv(LOG_INFO, LOG_FEATURE_CMD,"RepeatingEvents_OnEverySecond checked %i events, ran %i\n",c_checked,c_ran);
//addLogAdv(LOG_INFO, LOG_FEATURE_CMD,"RepeatingEvents_OnEverySecond checked %i events, ran %i\n",c_checked,c_ran);
}
int RepeatingEvents_Cmd_AddRepeatingEvent(const void *context, const char *cmd, const char *args) {
int interval;

View File

@@ -1,611 +0,0 @@
#include "../new_common.h"
#include "drv_model_pub.h"
#include "net_param_pub.h"
#include "flash_pub.h"
#if CFG_SUPPORT_ALIOS
#include "hal/soc/soc.h"
#else
#include "BkDriverFlash.h"
#include "BkDriverUart.h"
#endif
#include "../logging/logging.h"
#include "flash_config.h"
//#define DEBUG_FLASH_CONFIG
#ifndef DEBUG_FLASH_CONFIG
#undef ADDLOG_DEBUG
#define ADDLOG_DEBUG(x, y, ...)
#endif
// temporary storage for table.
static TLV_HEADER_ST *g_table = NULL;
static UINT32 flashaddr;
static UINT32 flashlen;
static int changes = 0;
static int flashwrites = -1;
static int OTAwrites = 0;
extern int g_savecfg;
static int config_compress_table();
static int config_save_table();
int config_getflashinfo();
int increment_flashcounts(int config, int ota);
static INFO_ITEM_ST *_search_item(INFO_ITEM_ST *item, UINT32 *p_usedlen);
static SemaphoreHandle_t config_mutex = 0;
char *hex = "0123456789ABCDEF";
int config_dump(void* obj, int len){
unsigned char *addr = (unsigned char *)obj;
char tmp[40];
int i;
ADDLOG_DEBUG(LOG_FEATURE_CFG, "dump of 0x%08X", addr);
for(i = 0; i < len; i++){
if (i && !(i%16)){
ADDLOG_DEBUG(LOG_FEATURE_CFG, tmp);
}
tmp[(i%16) * 2] = hex[((*addr) >> 4) & 0xf];
tmp[(i%16) * 2+1] = hex[(*addr) & 0xf];
tmp[(i%16) * 2+2] = '\0';
addr++;
}
ADDLOG_DEBUG(LOG_FEATURE_CFG, tmp);
return 0;
}
int config_get_item(void *container) {
INFO_ITEM_ST *res;
INFO_ITEM_ST *p_item = (INFO_ITEM_ST *)container;
int ret = 0;
BaseType_t taken;
if (!config_mutex) {
config_mutex = xSemaphoreCreateMutex( );
}
taken = xSemaphoreTake( config_mutex, 100 );
res = _search_item(p_item, NULL);
if (res){
os_memcpy(p_item, res, sizeof(INFO_ITEM_ST) + p_item->len);
ret = 1;
}
if (taken == pdTRUE){
xSemaphoreGive( config_mutex );
}
return ret;
}
int config_get_tableOffsets(int tableID, int *outStart, int *outLen) {
bk_logic_partition_t *pt;
pt = bk_flash_get_info(tableID);
*outStart = 0;
*outLen = 0;
if(pt == 0)
return 1;
*outStart = pt->partition_start_addr;
*outLen = pt->partition_length;
return 0;
}
int config_get_tbl(int readit){
UINT32 ret = 0, status;
DD_HANDLE flash_handle;
TLV_HEADER_ST head;
bk_logic_partition_t *pt = bk_flash_get_info(BK_PARTITION_NET_PARAM);
int cfg_len = 0;
flashaddr = pt->partition_start_addr;
flashlen = pt->partition_length;
if (g_table){
if(INFO_TLV_HEADER != g_table->type){
ADDLOG_DEBUG(LOG_FEATURE_CFG, "get_tbl g_table corrupted");
config_dump((unsigned char *)g_table, 32);
cfg_len = 0;
return cfg_len;
}
cfg_len = g_table->len + sizeof(TLV_HEADER_ST);
if (cfg_len > flashlen){
ADDLOG_DEBUG(LOG_FEATURE_CFG, "get_tbl table too big? %d > %d bytes", cfg_len, flashlen);
cfg_len = 0;
}
ADDLOG_DEBUG(LOG_FEATURE_CFG, "get_tbl got existing table len", cfg_len);
return cfg_len;
}
hal_flash_lock();
flash_handle = ddev_open(FLASH_DEV_NAME, &status, 0);
ddev_read(flash_handle, (char *)&head, sizeof(TLV_HEADER_ST), flashaddr);
if(INFO_TLV_HEADER == head.type)
{
cfg_len = head.len + sizeof(TLV_HEADER_ST);
ret = cfg_len;
if (readit){
g_table = os_malloc(cfg_len);
ddev_read(flash_handle, ((char *)g_table), cfg_len, flashaddr);
ADDLOG_DEBUG(LOG_FEATURE_CFG, "get_tbl read %d bytes", cfg_len);
}
}
ddev_close(flash_handle);
hal_flash_unlock();
// should happen only on first read.
if (flashwrites == -1){
flashwrites = 0;
config_getflashinfo();
}
//config_dump((unsigned char *)g_table, cfg_len);
#ifdef DEBUG_FLASH_CONFIG
config_dump_table();
#endif
return ret;
}
int config_release_tbl(){
void *table;
BaseType_t taken;
if (!config_mutex) {
config_mutex = xSemaphoreCreateMutex( );
}
taken = xSemaphoreTake( config_mutex, 100 );
table = g_table;
if(INFO_TLV_HEADER != g_table->type){
ADDLOG_DEBUG(LOG_FEATURE_CFG, "release_tbl g_table corrupted");
}
if (!table) {
if (taken == pdTRUE){
xSemaphoreGive( config_mutex );
}
return 0;
}
if (changes){
config_save_table();
}
g_table = NULL;
os_free(table);
if (taken == pdTRUE){
xSemaphoreGive( config_mutex );
}
ADDLOG_DEBUG(LOG_FEATURE_CFG, "release_tbl");
return 0;
}
static INFO_ITEM_ST *_search_item(INFO_ITEM_ST *item, UINT32 *p_usedlen)
{
UINT32 addr, end_addr;
INFO_ITEM_ST *head;
INFO_ITEM_ST *target = NULL;
UINT32 usedlen = 0;
UINT32 type = 0;
UINT32 tablelen = config_get_tbl(1);
if (!tablelen){
if (p_usedlen) *p_usedlen = usedlen;
return NULL;
}
if(INFO_TLV_HEADER != g_table->type){
ADDLOG_DEBUG(LOG_FEATURE_CFG, "_search_item g_table corrupted");
return NULL;
}
if (item){
type = item->type;
}
head = (INFO_ITEM_ST *) (((char *)g_table) + sizeof(TLV_HEADER_ST));
usedlen = sizeof(TLV_HEADER_ST);
addr = sizeof(TLV_HEADER_ST);
end_addr = tablelen;
while(addr < end_addr) {
if(type == head->type) {
target = head;
ADDLOG_DEBUG(LOG_FEATURE_CFG, "_search_item found %x at %d", type, addr);
} else {
ADDLOG_DEBUG(LOG_FEATURE_CFG, "_search_item not %x at %d", type, addr);
}
addr += sizeof(INFO_ITEM_ST);
addr += head->len;
if (0 != head->type) {
usedlen += sizeof(INFO_ITEM_ST);
usedlen += head->len;
}
head = (INFO_ITEM_ST *) (((char *)g_table) + addr);
}
if (p_usedlen) *p_usedlen = usedlen;
return target;
}
static int tbl_used_data_len(){
UINT32 len = 0;
_search_item(NULL, &len);
return (int)len;
}
INFO_ITEM_ST *config_search_item(INFO_ITEM_ST *item){
return _search_item(item, NULL);
}
INFO_ITEM_ST *config_search_item_type(UINT32 type){
INFO_ITEM_ST item;
item.type = type;
return _search_item(&item, NULL);
}
int bekken_hal_flash_read(const uint32_t addr, void *dst, const UINT32 size)
{
UINT32 status;
if(NULL == dst) {
return 1;
}
hal_flash_lock();
DD_HANDLE flash_handle;
flash_handle = ddev_open(FLASH_DEV_NAME, &status, 0);
ddev_read(flash_handle, dst, size, addr);
ddev_close(flash_handle);
hal_flash_unlock();
return 0;
}
int config_delete_item(UINT32 type)
{
UINT32 addr, end_addr;
INFO_ITEM_ST *head;
UINT32 deleted = 0;
UINT32 tablelen;
BaseType_t taken;
if (!config_mutex) {
config_mutex = xSemaphoreCreateMutex( );
}
taken = xSemaphoreTake( config_mutex, 100 );
tablelen = config_get_tbl(1);
if (!tablelen){
if (taken == pdTRUE) xSemaphoreGive( config_mutex );
return 0;
}
addr = sizeof(TLV_HEADER_ST);
end_addr = tablelen;
head = (INFO_ITEM_ST *) (((char *)g_table) + addr);
while(addr < end_addr) {
if(type == head->type) {
head->type = 0;
deleted++;
}
addr += sizeof(INFO_ITEM_ST);
addr += head->len;
head = (INFO_ITEM_ST *) (((char *)g_table) + addr);
}
if (deleted){
ADDLOG_DEBUG(LOG_FEATURE_CFG, "Deleted %d items type 0x%08X", deleted, type);
config_compress_table();
}
if (taken == pdTRUE) xSemaphoreGive( config_mutex );
return deleted;
}
//////////////////////////////////////////
// remove redundant entries
static int config_compress_table()
{
UINT32 addr1, addr2, end_addr;
INFO_ITEM_ST *head;
UINT32 usedlen = 0;
UINT32 tablelen;
BaseType_t taken;
if (!config_mutex) {
config_mutex = xSemaphoreCreateMutex( );
}
taken = xSemaphoreTake( config_mutex, 100 );
tablelen = config_get_tbl(1);
if (!tablelen){
if (taken == pdTRUE) xSemaphoreGive( config_mutex );
return 0;
}
head = (INFO_ITEM_ST *) (((char *)g_table) + sizeof(TLV_HEADER_ST));
usedlen = sizeof(TLV_HEADER_ST);
addr1 = sizeof(TLV_HEADER_ST);
addr2 = sizeof(TLV_HEADER_ST);
end_addr = tablelen;
while(addr1 < end_addr) {
int len = head->len;
int type = head->type;
if (addr1 != addr2){
INFO_ITEM_ST *newhead = (INFO_ITEM_ST *) (((char *)g_table) + addr2);
os_memmove(newhead, head, sizeof(INFO_ITEM_ST)+head->len);
}
if (0 != type) {
addr2 += sizeof(INFO_ITEM_ST);
addr2 += len;
usedlen += sizeof(INFO_ITEM_ST);
usedlen += len;
}
addr1 += sizeof(INFO_ITEM_ST);
addr1 += len;
head = (INFO_ITEM_ST *) (((char *)g_table) + addr1);
}
if (addr1 != addr2) {
ADDLOG_DEBUG(LOG_FEATURE_CFG, "Compress table from %d to %d bytes", g_table->len, usedlen);
changes++;
}
g_table->len = addr2 - sizeof(TLV_HEADER_ST);
if (taken == pdTRUE) xSemaphoreGive( config_mutex );
if (addr1 != addr2) {
return addr2; // maybe should save
}
return 0;
}
static int config_save_table(){
UINT32 tablelen = 0;
bk_logic_partition_t *pt = bk_flash_get_info(BK_PARTITION_NET_PARAM);
flashaddr = pt->partition_start_addr;
flashlen = pt->partition_length;
BaseType_t taken;
if (!config_mutex) {
config_mutex = xSemaphoreCreateMutex( );
}
taken = xSemaphoreTake( config_mutex, 100 );
if (!g_table) {
ADDLOG_ERROR(LOG_FEATURE_CFG, "save_table - no table to save");
if (taken == pdTRUE) xSemaphoreGive( config_mutex );
return 0;
}
// should already have it...
increment_flashcounts(1, 0);
tablelen = config_get_tbl(1);
if (tablelen > flashlen){
ADDLOG_ERROR(LOG_FEATURE_CFG, "save_table - table too big - can't save");
if (taken == pdTRUE) xSemaphoreGive( config_mutex );
return 0;
}
hal_flash_lock();
bk_flash_enable_security(FLASH_PROTECT_NONE);
bk_flash_erase(BK_PARTITION_NET_PARAM,0,tablelen);
bk_flash_write(BK_PARTITION_NET_PARAM,0,(uint8_t *)g_table,tablelen);
bk_flash_enable_security(FLASH_PROTECT_ALL);
hal_flash_unlock();
changes = 0;
if (taken == pdTRUE) xSemaphoreGive( config_mutex );
ADDLOG_DEBUG(LOG_FEATURE_CFG, "would save_table %d bytes", tablelen);
return 1;
}
int config_save_item(void *itemin)
{
UINT32 item_len;
INFO_ITEM_ST_PTR item_head_ptr;
INFO_ITEM_ST *item;
BaseType_t taken;
if (!config_mutex) {
config_mutex = xSemaphoreCreateMutex( );
}
taken = xSemaphoreTake( config_mutex, 100 );
item = itemin;
item_len = sizeof(INFO_ITEM_ST) + item->len;
UINT32 tablelen = config_get_tbl(1);
if(g_table && (INFO_TLV_HEADER != g_table->type)){
ADDLOG_DEBUG(LOG_FEATURE_CFG, "save_item g_table corrupted");
if (taken == pdTRUE){
xSemaphoreGive( config_mutex );
}
return 0;
}
ADDLOG_DEBUG(LOG_FEATURE_CFG, "save_item type %08X len %d, tablelen %d", item->type, item->len, tablelen);
if (!tablelen){
// no table, creat it.
int cfg_len = item_len + sizeof(TLV_HEADER_ST);
g_table = os_malloc(cfg_len);
g_table->type = INFO_TLV_HEADER;
g_table->len = item_len;
item_head_ptr = (INFO_ITEM_ST *) (((char *)g_table) + sizeof(TLV_HEADER_ST));
os_memcpy(item_head_ptr, item, item_len);
tablelen = cfg_len;
ADDLOG_DEBUG(LOG_FEATURE_CFG, "save_item, new table created");
changes++;
} else {
// have table - do we have existing item?
item_head_ptr = config_search_item(item);
ADDLOG_DEBUG(LOG_FEATURE_API, "save search found %x len %d, our len %d", item_head_ptr, (item_head_ptr?item_head_ptr->len:0), item->len);
if (item_head_ptr){
// if length mismatch, then zap this entry, and add on end
if (item_head_ptr->len != item->len){
ADDLOG_WARN(LOG_FEATURE_CFG, "save_item - item length mismatch type 0x%08X %d != %d",
item->type, item->len, item_head_ptr->len);
item_head_ptr->type = 0;
item_head_ptr = NULL;
} else {
ADDLOG_DEBUG(LOG_FEATURE_CFG, "save_item - will replace item - same length type 0x%08X %d",
item->type, item->len);
}
} else {
ADDLOG_DEBUG(LOG_FEATURE_CFG, "save_item new item");
}
// if we STILL have an item, lengths match.
// just copy in data and write whole table
if (item_head_ptr){
if (os_memcmp(item_head_ptr, item, item_len)){
os_memcpy(item_head_ptr, item, item_len);
changes++;
}
} else {
UINT32 newlen = 0;
// add to end
TLV_HEADER_ST *oldtable;
TLV_HEADER_ST *newtable;
oldtable = g_table;
newtable = os_malloc(tablelen + item_len);
if(!newtable){
ADDLOG_DEBUG(LOG_FEATURE_CFG, "allocation failure for %d bytes - save aborted",
tablelen + item_len);
if (taken == pdTRUE){
xSemaphoreGive( config_mutex );
}
return 0;
}
ADDLOG_DEBUG(LOG_FEATURE_CFG, "copy from %x to %x len %d",
g_table, newtable, tablelen);
os_memcpy(newtable, g_table, tablelen);
item_head_ptr = (INFO_ITEM_ST *) (((char *)newtable) + tablelen);
os_memcpy(item_head_ptr, item, item_len);
tablelen += item_len;
newtable->len = tablelen - sizeof(TLV_HEADER_ST);
g_table = newtable;
os_free(oldtable);
newlen = config_compress_table();
if (newlen){
tablelen = newlen;
}
changes++;
}
}
if (taken == pdTRUE){
xSemaphoreGive( config_mutex );
}
if (changes){
// save config in 3 seconds....
if (!g_savecfg){
g_savecfg = 3;
}
}
return 1;
}
int config_dump_table()
{
UINT32 addr, end_addr;
INFO_ITEM_ST *head;
UINT32 usedlen = 0;
UINT32 tablelen = config_get_tbl(1);
if (!tablelen){
ADDLOG_ERROR(LOG_FEATURE_CFG, "dump_table - no table");
return 0;
}
ADDLOG_DEBUG(LOG_FEATURE_CFG, "dump_table - table len %d(0x%X)", tablelen, tablelen);
head = (INFO_ITEM_ST *) (((char *)g_table) + sizeof(TLV_HEADER_ST));
usedlen = sizeof(TLV_HEADER_ST);
addr = sizeof(TLV_HEADER_ST);
end_addr = tablelen;
while(addr < end_addr) {
ADDLOG_DEBUG(LOG_FEATURE_CFG, "item type 0x%08X len %d at 0x%04X",
head->type, head->len, addr);
config_dump(head, head->len);
addr += sizeof(INFO_ITEM_ST);
addr += head->len;
if (0 != head->type) {
usedlen += sizeof(INFO_ITEM_ST);
usedlen += head->len;
}
head = (INFO_ITEM_ST *) (((char *)g_table) + addr);
}
ADDLOG_DEBUG(LOG_FEATURE_CFG, "dump_table end - table len %d(0x%X) used len %d(0x%X)",
tablelen, tablelen,
usedlen, usedlen
);
return 1;
}
int config_commit(){
if (changes){
config_save_table();
return 1;
}
// free config memory;
config_release_tbl();
return 0;
}
int config_getflashinfo(){
ITEM_FLASHIINFO_CONFIG flash_info;
CONFIG_INIT_ITEM(CONFIG_TYPE_FLASH_INFO, &flash_info);
if (config_get_item(&flash_info)){
flashwrites = flash_info.flash_write_count;
OTAwrites = flash_info.OTA_count;
}
return 0;
}
int increment_flashcounts(int config, int ota){
ITEM_FLASHIINFO_CONFIG flash_info;
CONFIG_INIT_ITEM(CONFIG_TYPE_FLASH_INFO, &flash_info);
flashwrites += config;
OTAwrites += ota;
flash_info.flash_write_count = flashwrites;
flash_info.OTA_count = OTAwrites;
config_save_item(&flash_info);
ADDLOG_DEBUG(LOG_FEATURE_CFG, "Flash info - config writes %d, OTA %d",
flashwrites,
OTAwrites
);
return 1;
}
int increment_OTA_count(){
return increment_flashcounts(0, 1);
}

View File

@@ -1,125 +1,3 @@
#include "net_param_pub.h"
/////////////////////////////////////////////////////
// mutex protected functions:
// copy a config item of type to 'container'
// 'container' should have been initialised with CONFIG_INIT_ITEM
// then it will have the right type and len..
int config_get_item(void *container);
// save an item to config.
// item should start with INFO_ITEM_ST, and be initialised with CONFIG_INIT_ITEM
// will trigger config save 3s later
int config_save_item(void *item);
// delete ALL items of type
int config_delete_item(UINT32 type);
// save pending changes NOW and release the config memory
int config_commit();
int increment_OTA_count();
/////////////////////////////////////////////////////
// other functions, not protected.
// internal
int config_get_tbl(int readit);
// release memory (saves if changes)
int config_release_tbl();
// return a ptr to the item, unprotected
INFO_ITEM_ST *config_search_item(INFO_ITEM_ST *item);
// return a ptr to the item, unprotected
INFO_ITEM_ST *config_search_item_type(UINT32 type);
// list table contetn by type & len to debug
int config_dump_table();
// debug
int config_get_tableOffsets(int tableID, int *outStart, int *outLen);
// copy of tuya_hal_flash_read (in BK7231T it was in SDK source, but in BK7231N it was in tuya lib)
int bekken_hal_flash_read(const uint32_t addr, void *dst, const UINT32 size);
/////////////////////////////////////////
// config types not defined by beken
//
// structure is ITEM_URL_CONFIG
#define CONFIG_TYPE_WEBAPP_ROOT ((UINT32) *((UINT32*)"WEB"))
// structure is ITEM_FLASHIINFO_CONFIG
#define CONFIG_TYPE_FLASH_INFO ((UINT32) *((UINT32*)"FLSH"))
// 'new' structure
#define CONFIG_TYPE_WIFI ((UINT32) *((UINT32*)"WIFI"))
#define CONFIG_TYPE_MQTT ((UINT32) *((UINT32*)"MQTT"))
#define CONFIG_TYPE_PINS ((UINT32) *((UINT32*)"PINS"))
// OLD VALUES moved from SDK
#define OLD_PINS_CONFIG 0xAAAAAAAA
#define OLD_WIFI_CONFIG 0xBBBBBBBB
#define OLD_MQTT_CONFIG 0xCCCCCCCC
#define CONFIG_INIT_ITEM(t, ptr) { (ptr)->head.len = sizeof(*(ptr)) - sizeof((ptr)->head); (ptr)->head.type = t; }
/////////////////////////////////////////
// config structures not defined by beken
#define CONFIG_URL_SIZE_MAX 64
typedef struct item_url_config
{
INFO_ITEM_ST head;
char url[CONFIG_URL_SIZE_MAX];
}ITEM_URL_CONFIG,*ITEM_URL_CONFIG_PTR;
typedef struct item_flashinfo_config
{
INFO_ITEM_ST head;
int flash_write_count;
int OTA_count;
}ITEM_FLASHIINFO_CONFIG,*ITEM_FLASHINFO_CONFIG_PTR;
// added for OpenBK7231T
typedef struct item_new_wifi_config2
{
INFO_ITEM_ST head;
char scrap[8];
char ssid[32];
char pass[64];
}ITEM_NEW_WIFI_CONFIG2,*ITEM_NEW_WIFI_CONFIG2_PTR;
typedef struct item_new_mqtt_config2
{
INFO_ITEM_ST head;
char scrap[8];
char brokerName[64];
char userName[64];
int port;
char hostName[64];
// Home Assistant default password is 64 chars..
char pass[128];
}ITEM_NEW_MQTT_CONFIG2,*ITEM_NEW_MQTT_CONFIG2_PTR;
// added for OpenBK7231T
typedef struct item_new_new_wifi_config
{
INFO_ITEM_ST head;
char ssid[32];
char pass[64];
}ITEM_NEW_NEW_WIFI_CONFIG,*ITEM_NEW_NEW_WIFI_CONFIG_PTR;
// added for OpenBK7231T
typedef struct item_new_new_mqtt_config
{
INFO_ITEM_ST head;
char brokerName[64];
char userName[64];
int port;
char hostName[64];
// Home Assistant default password is 64 chars..
char pass[128];
}ITEM_NEW_NEW_MQTT_CONFIG,*ITEM_NEW_NEW_MQTT_CONFIG_PTR;

View File

@@ -0,0 +1,111 @@
#include "../hal_flashConfig.h"
#include "drv_model_pub.h"
#include "net_param_pub.h"
#include "flash_pub.h"
#include "BkDriverFlash.h"
#include "BkDriverUart.h"
#include "../../logging/logging.h"
static SemaphoreHandle_t config_mutex = 0;
int config_get_tableOffsets(int tableID, int *outStart, int *outLen) {
bk_logic_partition_t *pt;
pt = bk_flash_get_info(tableID);
*outStart = 0;
*outLen = 0;
if(pt == 0)
return 1;
*outStart = pt->partition_start_addr;
*outLen = pt->partition_length;
return 0;
}
int HAL_Configuration_ReadConfigMemory(void *target, int dataLen){
UINT32 flashaddr, flashlen;
UINT32 status;
DD_HANDLE flash_handle;
bk_logic_partition_t *pt = bk_flash_get_info(BK_PARTITION_NET_PARAM);
flashaddr = pt->partition_start_addr;
flashlen = pt->partition_length;
if (dataLen > flashlen){
ADDLOG_ERROR(LOG_FEATURE_CFG, "HAL_Configuration_ReadConfigMemory - table too big - can't save");
return 0;
}
hal_flash_lock();
flash_handle = ddev_open(FLASH_DEV_NAME, &status, 0);
ddev_read(flash_handle, (char *)target, dataLen, flashaddr);
ddev_close(flash_handle);
hal_flash_unlock();
ADDLOG_DEBUG(LOG_FEATURE_CFG, "HAL_Configuration_ReadConfigMemory: read %d bytes to %d", dataLen, flashaddr);
return dataLen;
}
int bekken_hal_flash_read(const uint32_t addr, void *dst, const UINT32 size)
{
UINT32 status;
if(NULL == dst) {
return 1;
}
hal_flash_lock();
DD_HANDLE flash_handle;
flash_handle = ddev_open(FLASH_DEV_NAME, &status, 0);
ddev_read(flash_handle, dst, size, addr);
ddev_close(flash_handle);
hal_flash_unlock();
return 0;
}
int HAL_Configuration_SaveConfigMemory(void *src, int dataLen){
UINT32 flashaddr, flashlen;
bk_logic_partition_t *pt = bk_flash_get_info(BK_PARTITION_NET_PARAM);
flashaddr = pt->partition_start_addr;
flashlen = pt->partition_length;
BaseType_t taken;
if (!config_mutex) {
config_mutex = xSemaphoreCreateMutex( );
}
taken = xSemaphoreTake( config_mutex, 100 );
if (dataLen > flashlen){
ADDLOG_ERROR(LOG_FEATURE_CFG, "HAL_Configuration_SaveConfigMemory - table too big - can't save");
if (taken == pdTRUE)
xSemaphoreGive( config_mutex );
return 0;
}
hal_flash_lock();
bk_flash_enable_security(FLASH_PROTECT_NONE);
bk_flash_erase(BK_PARTITION_NET_PARAM,0,dataLen);
bk_flash_write(BK_PARTITION_NET_PARAM,0,(uint8_t *)src,dataLen);
bk_flash_enable_security(FLASH_PROTECT_ALL);
hal_flash_unlock();
if (taken == pdTRUE)
xSemaphoreGive( config_mutex );
ADDLOG_DEBUG(LOG_FEATURE_CFG, "HAL_Configuration_SaveConfigMemory: saved %d bytes to %d", dataLen, flashaddr);
return dataLen;
}

View File

@@ -40,7 +40,23 @@ const char *HAL_GetMyIPString(){
void getMAC(unsigned char *mac){
net_get_if_macaddr(mac, net_get_sta_handle());
}
int WiFI_SetMacAddress(char *mac) {
#if WINDOWS
return 0;
#elif PLATFORM_BL602
return 0;
#elif PLATFORM_XR809
#else
if(wifi_set_mac_address((char *)mac))
return 1;
return 0; // error
#endif
}
void WiFI_GetMacAddress(char *mac) {
wifi_get_mac_address((char *)mac, CONFIG_ROLE_STA);
}
const char *HAL_GetMACStr(char *macstr){
unsigned char mac[6];
getMAC(mac);

13
src/hal/hal_flashConfig.h Normal file
View File

@@ -0,0 +1,13 @@
#include "../new_common.h"
// debug
int config_get_tableOffsets(int tableID, int *outStart, int *outLen);
// copy of tuya_hal_flash_read (in BK7231T it was in SDK source, but in BK7231N it was in tuya lib)
int bekken_hal_flash_read(const uint32_t addr, void *dst, const UINT32 size);
int HAL_Configuration_ReadConfigMemory(void *target, int dataLen);
int HAL_Configuration_SaveConfigMemory(void *src, int dataLen);

View File

@@ -9,7 +9,8 @@
#include "../driver/drv_public.h"
#include "../logging/logging.h"
#include "../hal/hal_wifi.h"
#include "../hal/hal_pins.h"
#include "../hal/hal_pins.h"
#include "../hal/hal_flashConfig.h"
#ifdef WINDOWS
// nothing
@@ -216,6 +217,7 @@ int http_fn_index(http_request_t *request) {
poststr(request,"<form action=\"about\"><input type=\"submit\" value=\"About\"/></form>");
hprintf128(request,"<h3>Cfg size: %i, change counter: %i, ota counter: %i!</h3>",sizeof(g_cfg),g_cfg.changeCounter,g_cfg.otaCounter);
poststr(request,htmlReturnToMenu);
HTTP_AddBuildFooter(request);
@@ -300,14 +302,8 @@ int http_fn_cfg_mqtt_set(http_request_t *request) {
if(http_getArg(request->url,"client",tmpA,sizeof(tmpA))) {
CFG_SetMQTTBrokerName(tmpA);
}
if(CFG_SaveMQTT()) {
poststr(request,"MQTT mode set!");
} else {
poststr(request,"Error saving MQTT settings to flash!");
}
poststr(request,"Please wait for module to connect... if there is problem, restart it...");
poststr(request,"Please wait for module to connect... if there is problem, restart it from Index html page...");
poststr(request,"<br>");
poststr(request,"<a href=\"cfg_mqtt\">Return to MQTT settings</a>");
@@ -483,9 +479,9 @@ int http_fn_cfg_wifi_set(http_request_t *request) {
}
poststr(request,"WiFi mode set: connect to WLAN.");
}
addLogAdv(LOG_INFO, LOG_FEATURE_HTTP,"HTTP_ProcessPacket: calling CFG_SaveWiFi \r\n");
CFG_SaveWiFi();
addLogAdv(LOG_INFO, LOG_FEATURE_HTTP,"HTTP_ProcessPacket: done CFG_SaveWiFi \r\n");
addLogAdv(LOG_INFO, LOG_FEATURE_HTTP,"HTTP_ProcessPacket: calling CFG_Save_IfThereArePendingChanges \r\n");
CFG_Save_IfThereArePendingChanges();
addLogAdv(LOG_INFO, LOG_FEATURE_HTTP,"HTTP_ProcessPacket: done CFG_Save_IfThereArePendingChanges \r\n");
poststr(request,"Please wait for module to reset...");
RESET_ScheduleModuleReset(3);
@@ -777,16 +773,9 @@ int http_fn_config_dump_table(http_request_t *request) {
http_setup(request, httpMimeTypeHTML);
poststr(request,htmlHeader);
poststr(request,g_header);
#if WINDOWS
poststr(request,"Not implemented <br>");
#elif PLATFORM_XR809
poststr(request,"Not implemented <br>");
#elif PLATFORM_BL602
poststr(request,"Not implemented <br>");
#else
poststr(request,"Dumped to log <br>");
config_dump_table();
#endif
poststr(request,htmlReturnToCfg);
HTTP_AddBuildFooter(request);
poststr(request,htmlEnd);
@@ -1032,7 +1021,7 @@ int http_fn_cfg_pins(http_request_t *request) {
}
}
if(iChangedRequested>0) {
PIN_SaveToFlash();
CFG_Save_IfThereArePendingChanges();
hprintf128(request, "Pins update - %i reqs, %i changed!<br><br>",iChangedRequested,iChanged);
}
// strcat(outbuf,"<button type=\"button\">Click Me!</button>");

View File

@@ -535,13 +535,6 @@ static int http_rest_get_seriallog(http_request_t *request){
static int http_rest_get_pins(http_request_t *request){
int i;
/*typedef struct pinsState_s {
byte roles[32];
byte channels[32];
} pinsState_t;
extern pinsState_t g_pins;
*/
http_setup(request, httpMimeTypeJson);
poststr(request, "{\"rolenames\":[");
for (i = 0; i < IOR_Total_Options; i++){
@@ -555,17 +548,17 @@ static int http_rest_get_pins(http_request_t *request){
for (i = 0; i < 32; i++){
if (i){
hprintf128(request, ",%d", g_pins.roles[i]);
hprintf128(request, ",%d", g_cfg.pins.roles[i]);
} else {
hprintf128(request, "%d", g_pins.roles[i]);
hprintf128(request, "%d", g_cfg.pins.roles[i]);
}
}
poststr(request, "],\"channels\":[");
for (i = 0; i < 32; i++){
if (i){
hprintf128(request, ",%d", g_pins.channels[i]);
hprintf128(request, ",%d", g_cfg.pins.channels[i]);
} else {
hprintf128(request, "%d", g_pins.channels[i]);
hprintf128(request, "%d", g_cfg.pins.channels[i]);
}
}
poststr(request, "]}");
@@ -770,7 +763,7 @@ static int http_rest_post_pins(http_request_t *request){
}
}
if (iChanged){
PIN_SaveToFlash();
CFG_Save_IfThereArePendingChanges();
ADDLOG_DEBUG(LOG_FEATURE_API, "Changed %d - saved to flash", iChanged);
}
@@ -911,12 +904,7 @@ static int http_rest_get_flash(http_request_t *request, int startaddr, int len){
static int http_rest_get_dumpconfig(http_request_t *request){
#if PLATFORM_XR809
#elif PLATFORM_BL602
#else
config_dump_table();
#endif
http_setup(request, httpMimeTypeText);
poststr(request, NULL);
@@ -937,70 +925,7 @@ ITEM_NEW_TEST_CONFIG testconfig;
#endif
static int http_rest_get_testconfig(http_request_t *request){
#ifdef TESTCONFIG_ENABLE
INFO_ITEM_ST *ret;
int intres;
testconfig.head.type = (UINT32) *((UINT32*)"TEST");
testconfig.head.len = sizeof(testconfig) - sizeof(testconfig.head);
strcpy(testconfig.somename, "test it here");
config_dump_table();
ret = config_search_item((INFO_ITEM_ST *)&testconfig);
ADDLOG_DEBUG(LOG_FEATURE_API, "search found %x", ret);
config_dump_table();
intres = config_delete_item(testconfig.head.type);
ADDLOG_DEBUG(LOG_FEATURE_API, "delete_item returned %d", intres);
intres = config_save_item((INFO_ITEM_ST *)&testconfig);
ADDLOG_DEBUG(LOG_FEATURE_API, "save_item returned %d", intres);
ret = config_search_item((INFO_ITEM_ST *)&testconfig);
ADDLOG_DEBUG(LOG_FEATURE_API, "search2 found %x len %d", ret, (ret?ret->len:0));
intres = config_save_item((INFO_ITEM_ST *)&testconfig);
ADDLOG_DEBUG(LOG_FEATURE_API, "save_item returned %d", intres);
ret = config_search_item((INFO_ITEM_ST *)&testconfig);
ADDLOG_DEBUG(LOG_FEATURE_API, "search3 found %x len %d", ret, (ret?ret->len:0));
if (ret){
if (os_memcmp(ret, &testconfig, sizeof(testconfig))){
ADDLOG_DEBUG(LOG_FEATURE_API, "content mismatch");
} else {
ADDLOG_DEBUG(LOG_FEATURE_API, "content match");
}
}
testconfig.head.len = sizeof(testconfig) - sizeof(testconfig.head) - 1;
intres = config_save_item((INFO_ITEM_ST *)&testconfig);
ADDLOG_DEBUG(LOG_FEATURE_API, "save_item returned %d", intres);
ret = config_search_item((INFO_ITEM_ST *)&testconfig);
ADDLOG_DEBUG(LOG_FEATURE_API, "search4 found %x len %d", ret, (ret?ret->len:0));
config_dump_table();
intres = config_delete_item(testconfig.head.type);
ADDLOG_DEBUG(LOG_FEATURE_API, "delete_item returned %d", intres);
config_dump_table();
config_release_tbl();
config_dump_table();
http_setup(request, httpMimeTypeText);
poststr(request, NULL);
#else
return http_rest_error(request, 400, "unsupported");
#endif
return 0;
}

View File

@@ -3,18 +3,19 @@
// but for now let's use that
#include "new_common.h"
#include "new_pins.h"
#include "new_cfg.h"
void Setup_Device_Empty() {
PIN_ClearPins();
CFG_ClearPins();
PIN_SaveToFlash();
CFG_Save_IfThereArePendingChanges();
}
// https://www.elektroda.pl/rtvforum/topic3804553.html
// SmartSwitch Tuya WL-SW01_16 16A
void Setup_Device_TuyaWL_SW01_16A() {
PIN_ClearPins();
CFG_ClearPins();
PIN_SetPinRoleForPinIndex(7, IOR_Relay);
PIN_SetPinChannelForPinIndex(7, 1);
@@ -22,12 +23,12 @@ void Setup_Device_TuyaWL_SW01_16A() {
PIN_SetPinRoleForPinIndex(26, IOR_Button);
PIN_SetPinChannelForPinIndex(26, 1);
PIN_SaveToFlash();
CFG_Save_IfThereArePendingChanges();
}
// https://www.elektroda.pl/rtvforum/topic3822484.html
// WiFi Tuya SmartLife 4CH 10A
void Setup_Device_TuyaSmartLife4CH10A() {
PIN_ClearPins();
CFG_ClearPins();
PIN_SetPinRoleForPinIndex(7, IOR_Button);
PIN_SetPinChannelForPinIndex(7, 1);
@@ -47,13 +48,13 @@ void Setup_Device_TuyaSmartLife4CH10A() {
PIN_SetPinRoleForPinIndex(26, IOR_Relay);
PIN_SetPinChannelForPinIndex(26, 4);
PIN_SaveToFlash();
CFG_Save_IfThereArePendingChanges();
}
// Tuya "12W" smart light bulb
// "Tuya Wifi Smart Life Light Bulb Lamp E27 LED RGBCW Dimmable For Alexa/Google 18W
// See this topic: https://www.elektroda.pl/rtvforum/viewtopic.php?t=3880540&highlight=
void Setup_Device_BK7231N_TuyaLightBulb_RGBCW_5PWMs() {
PIN_ClearPins();
CFG_ClearPins();
// RGBCW, in that order
// Raw PWMS (no I2C)
@@ -78,11 +79,11 @@ void Setup_Device_BK7231N_TuyaLightBulb_RGBCW_5PWMs() {
PIN_SetPinRoleForPinIndex(6, IOR_PWM);
PIN_SetPinChannelForPinIndex(6, 5);
PIN_SaveToFlash();
CFG_Save_IfThereArePendingChanges();
}
// https://www.elektroda.pl/rtvforum/viewtopic.php?p=19743751#19743751
void Setup_Device_IntelligentLife_NF101A() {
PIN_ClearPins();
CFG_ClearPins();
// TODO: LED
@@ -93,11 +94,11 @@ void Setup_Device_IntelligentLife_NF101A() {
PIN_SetPinChannelForPinIndex(6, 1);
PIN_SaveToFlash();
CFG_Save_IfThereArePendingChanges();
}
// https://www.elektroda.pl/rtvforum/topic3798114.html
void Setup_Device_TuyaLEDDimmerSingleChannel() {
PIN_ClearPins();
CFG_ClearPins();
// pin 8 has PWM
PIN_SetPinRoleForPinIndex(8, IOR_Relay);
@@ -108,7 +109,7 @@ void Setup_Device_TuyaLEDDimmerSingleChannel() {
PIN_SetPinChannelForPinIndex(1, 1);
PIN_SaveToFlash();
CFG_Save_IfThereArePendingChanges();
}
@@ -121,7 +122,7 @@ void Setup_Device_CalexLEDDimmerFiveChannel() {
// warm white - PWM5 = P26
// cold white - PWM4 = P24
PIN_ClearPins();
CFG_ClearPins();
// red
PIN_SetPinChannelForPinIndex(7, 1);
@@ -139,7 +140,7 @@ void Setup_Device_CalexLEDDimmerFiveChannel() {
PIN_SetPinChannelForPinIndex(26, 5);
PIN_SetPinRoleForPinIndex(26, IOR_PWM);
PIN_SaveToFlash();
CFG_Save_IfThereArePendingChanges();
}
void Setup_Device_CalexPowerStrip_900018_1v1_0UK() {
@@ -151,7 +152,7 @@ void Setup_Device_CalexPowerStrip_900018_1v1_0UK() {
// warm white - PWM5 = P26
// cold white - PWM4 = P24
PIN_ClearPins();
CFG_ClearPins();
// relays - 4 sockets + 1 USB
PIN_SetPinChannelForPinIndex(6, 5);
@@ -177,7 +178,7 @@ void Setup_Device_CalexPowerStrip_900018_1v1_0UK() {
PIN_SetPinChannelForPinIndex(24, 2);
PIN_SetPinRoleForPinIndex(24, IOR_LED);
PIN_SaveToFlash();
CFG_Save_IfThereArePendingChanges();
}
// https://www.bunnings.com.au/arlec-grid-connect-smart-9w-cct-led-downlight_p0168694
@@ -188,7 +189,7 @@ void Setup_Device_ArlecCCTDownlight() {
// cold white - PWM1 = P6
// warm white - PWM2 = P24
PIN_ClearPins();
CFG_ClearPins();
// cold white
PIN_SetPinChannelForPinIndex(6, 1);
@@ -197,7 +198,7 @@ void Setup_Device_ArlecCCTDownlight() {
PIN_SetPinChannelForPinIndex(24, 2);
PIN_SetPinRoleForPinIndex(24, IOR_PWM);
PIN_SaveToFlash();
CFG_Save_IfThereArePendingChanges();
}
// https://www.elektroda.pl/rtvforum/topic3804553.html
@@ -214,7 +215,7 @@ void Setup_Device_NedisWIFIPO120FWT_16A() {
// Relay - PWM5 - P26
PIN_ClearPins();
CFG_ClearPins();
// LEd
PIN_SetPinRoleForPinIndex(6, IOR_LED);
PIN_SetPinChannelForPinIndex(6, 1);
@@ -225,7 +226,7 @@ void Setup_Device_NedisWIFIPO120FWT_16A() {
PIN_SetPinRoleForPinIndex(26, IOR_Relay_n);
PIN_SetPinChannelForPinIndex(26, 1);
PIN_SaveToFlash();
CFG_Save_IfThereArePendingChanges();
}
// https://www.elektroda.pl/rtvforum/topic3804553.html
@@ -239,7 +240,7 @@ void Setup_Device_NedisWIFIP130FWT_10A() {
// Relay - PWM5 - P26
PIN_ClearPins();
CFG_ClearPins();
// Led
PIN_SetPinRoleForPinIndex(6, IOR_LED);
PIN_SetPinChannelForPinIndex(6, 1);
@@ -250,7 +251,7 @@ void Setup_Device_NedisWIFIP130FWT_10A() {
PIN_SetPinRoleForPinIndex(26, IOR_Relay);
PIN_SetPinChannelForPinIndex(26, 1);
PIN_SaveToFlash();
CFG_Save_IfThereArePendingChanges();
}
// https://www.elektroda.com/rtvforum/topic3819498.html
@@ -273,7 +274,7 @@ void Setup_Device_EmaxHome_EDU8774() {
// Led - PWM5 - P26
PIN_ClearPins();
CFG_ClearPins();
// Button
PIN_SetPinRoleForPinIndex(10, IOR_Button);
PIN_SetPinChannelForPinIndex(10, 1);
@@ -284,7 +285,7 @@ void Setup_Device_EmaxHome_EDU8774() {
PIN_SetPinRoleForPinIndex(26, IOR_Relay);
PIN_SetPinChannelForPinIndex(26, 1);
PIN_SaveToFlash();
CFG_Save_IfThereArePendingChanges();
}
@@ -295,7 +296,7 @@ void Setup_Device_BK7231N_CB2S_QiachipSmartSwitch() {
PIN_ClearPins();
CFG_ClearPins();
// Button
PIN_SetPinRoleForPinIndex(7, IOR_Button);
PIN_SetPinChannelForPinIndex(7, 1);
@@ -304,21 +305,21 @@ void Setup_Device_BK7231N_CB2S_QiachipSmartSwitch() {
PIN_SetPinChannelForPinIndex(8, 1);
// Led
PIN_SaveToFlash();
CFG_Save_IfThereArePendingChanges();
}
void Setup_Device_BK7231T_WB2S_QiachipSmartSwitch() {
PIN_ClearPins();
// Button
PIN_SetPinRoleForPinIndex(7, IOR_Button);
PIN_SetPinChannelForPinIndex(7, 1);
// Relay
PIN_SetPinRoleForPinIndex(6, IOR_Relay_n);
PIN_SetPinChannelForPinIndex(6, 1);
// Led
PIN_SetPinRoleForPinIndex(10, IOR_LED);
PIN_SetPinChannelForPinIndex(10, 1);
CFG_ClearPins();
// Button
PIN_SetPinRoleForPinIndex(7, IOR_Button);
PIN_SetPinChannelForPinIndex(7, 1);
// Relay
PIN_SetPinRoleForPinIndex(6, IOR_Relay_n);
PIN_SetPinChannelForPinIndex(6, 1);
// Led
PIN_SetPinRoleForPinIndex(10, IOR_LED);
PIN_SetPinChannelForPinIndex(10, 1);
PIN_SaveToFlash();
CFG_Save_IfThereArePendingChanges();
}
@@ -331,7 +332,7 @@ void Setup_Device_BK7231T_Raw_PrimeWiFiSmartOutletsOutdoor_CCWFIO232PK() {
PIN_ClearPins();
CFG_ClearPins();
// Relay
PIN_SetPinRoleForPinIndex(6, IOR_Relay);
PIN_SetPinChannelForPinIndex(6, 1);
@@ -350,7 +351,7 @@ void Setup_Device_BK7231T_Raw_PrimeWiFiSmartOutletsOutdoor_CCWFIO232PK() {
PIN_SetPinChannelForPinIndex(24, 1);
PIN_SaveToFlash();
CFG_Save_IfThereArePendingChanges();
}
@@ -360,7 +361,7 @@ void Setup_Device_BK7231T_Raw_PrimeWiFiSmartOutletsOutdoor_CCWFIO232PK() {
// Button PWM5 P26
// LED PWM1 P7
void Setup_Device_TuyaSmartPFW02G() {
PIN_ClearPins();
CFG_ClearPins();
PIN_SetPinRoleForPinIndex(24, IOR_Relay_n);
PIN_SetPinChannelForPinIndex(24, 1);
@@ -372,7 +373,7 @@ void Setup_Device_TuyaSmartPFW02G() {
PIN_SetPinChannelForPinIndex(7, 1);
PIN_SaveToFlash();
CFG_Save_IfThereArePendingChanges();
}
@@ -392,7 +393,7 @@ void Setup_Device_AvatarASL04() {
// audio input ???? - most likely P23/ADC?
PIN_ClearPins();
CFG_ClearPins();
// red
PIN_SetPinChannelForPinIndex(24, 1);
@@ -416,12 +417,12 @@ void Setup_Device_AvatarASL04() {
PIN_SetPinChannelForPinIndex(14, 3);
PIN_SaveToFlash();
CFG_Save_IfThereArePendingChanges();
}
void Setup_Device_TuyaSmartWIFISwith_4Gang_CB3S(){
PIN_ClearPins();
CFG_ClearPins();
PIN_SetPinRoleForPinIndex(24, IOR_Button);
PIN_SetPinChannelForPinIndex(24, 1);
@@ -444,5 +445,10 @@ void Setup_Device_TuyaSmartWIFISwith_4Gang_CB3S(){
PIN_SetPinRoleForPinIndex(22, IOR_LED_WIFI);
PIN_SetPinChannelForPinIndex(22, 1);
PIN_SaveToFlash();
CFG_Save_IfThereArePendingChanges();
}

View File

@@ -1,424 +1,208 @@
#include "new_common.h"
#include "logging/logging.h"
#include "httpserver/new_http.h"
#include "new_pins.h"
#include "new_cfg.h"
#include "hal/hal_wifi.h"
#include "hal/hal_flashConfig.h"
#if WINDOWS
mainConfig_t g_cfg;
#elif PLATFORM_BL602
static int g_cfg_pendingChanges = 0;
#elif PLATFORM_XR809
// XR809 sysinfo is used to save configuration to flash
#include "common/framework/sysinfo.h"
#else
#include "flash_config/flash_config.h"
#include "../../beken378/func/include/net_param_pub.h"
#include "../../beken378/app/config/param_config.h"
#endif
#define CFG_IDENT_0 'C'
#define CFG_IDENT_1 'F'
#define CFG_IDENT_2 'G'
#define MAIN_CFG_VERSION 1
// added for OpenBK7231T
#define NEW_WEBAPP_CONFIG_SIZE 64
//NEW_PINS_CONFIG
static int g_mqtt_port = 1883;
static char g_mqtt_host[64] = "192.168.0.113";
static char g_mqtt_brokerName[64] = "test";
static char g_mqtt_userName[64] = "homeassistant";
static char g_mqtt_pass[128] = "qqqqqqqqqq";
static char g_wifi_ssid[64] = { 0 };
static char g_wifi_pass[64] = { 0 };
#if PLATFORM_XR809 || WINDOWS || PLATFORM_BL602
#define CONFIG_URL_SIZE_MAX 64
#endif
static char g_webappRoot[CONFIG_URL_SIZE_MAX] = "https://openbekeniot.github.io/webapp/";
// Long unique device name, like OpenBK7231T_AABBCCDD
char g_deviceName[64] = "testDev";
// Short unique device name, like obkAABBCCDD
char g_shortDeviceName[64] = "td01";
const char *CFG_LoadWebappRoot(){
#if WINDOWS
#elif PLATFORM_XR809
#elif PLATFORM_BL602
#else
ITEM_URL_CONFIG item;
int res;
CONFIG_INIT_ITEM(CONFIG_TYPE_WEBAPP_ROOT, &item);
res = config_get_item(&item);
if (res)
strcpy_safe(g_webappRoot, item.url,sizeof(g_webappRoot));
#endif
return g_webappRoot;
}
const char *CFG_GetWebappRoot(){
return g_webappRoot;
}
int CFG_SetWebappRoot(const char *s) {
#if WINDOWS
strcpy_safe(g_webappRoot, s,sizeof(g_webappRoot));
return 1; // ok
#elif PLATFORM_BL602
return 1; // ok
#elif PLATFORM_XR809
strcpy_safe(g_webappRoot, s,sizeof(g_webappRoot));
return 1; // ok
#else
ITEM_URL_CONFIG item;
int res;
CONFIG_INIT_ITEM(CONFIG_TYPE_WEBAPP_ROOT, &item);
res = config_get_item(&item);
strcpy_safe(item.url, s,sizeof(item.url));
strcpy_safe(g_webappRoot, item.url,sizeof(g_webappRoot));
if(config_save_item(&item)) {
return 1;
}
return 0;
#endif
}
const char *CFG_GetDeviceName(){
return g_deviceName;
}
const char *CFG_GetShortDeviceName(){
return g_shortDeviceName;
}
#if WINDOWS
#define DEVICENAME_PREFIX_FULL "WinTest"
#define DEVICENAME_PREFIX_SHORT "WT"
#elif PLATFORM_XR809
#define DEVICENAME_PREFIX_FULL "OpenXR809"
#define DEVICENAME_PREFIX_SHORT "oxr"
#elif PLATFORM_BK7231N
#define DEVICENAME_PREFIX_FULL "OpenBK7231N"
#define DEVICENAME_PREFIX_SHORT "obk"
#elif PLATFORM_BK7231T
#define DEVICENAME_PREFIX_FULL "OpenBK7231T"
#define DEVICENAME_PREFIX_SHORT "obk"
#elif PLATFORM_BL602
#define DEVICENAME_PREFIX_FULL "OpenBL602"
#define DEVICENAME_PREFIX_SHORT "obl"
#else
#error "You must define a platform.."
This platform is not supported, error!
#endif
void WiFI_GetMacAddress(char *mac) {
#if WINDOWS
#elif PLATFORM_BL602
#elif PLATFORM_XR809
sysinfo_t *inf;
inf = sysinfo_get();
if(inf == 0) {
mac[0] = 'E'; mac[1] = 'R'; mac[2] = 'R'; mac[3] = 'O'; mac[4] = 'R'; mac[5] = '!';
printf("WiFI_GetMacAddress: sysinfo_get returned 0!\n\r");
return;
}
memcpy(mac,inf->mac_addr,6);
#else
wifi_get_mac_address((char *)mac, CONFIG_ROLE_STA);
#endif
}
int WiFI_SetMacAddress(char *mac) {
#if WINDOWS
return 0;
#elif PLATFORM_BL602
return 0;
#elif PLATFORM_XR809
sysinfo_t *inf;
int res;
inf = sysinfo_get();
if(inf == 0) {
printf("WiFI_SetMacAddress: sysinfo_get returned 0!\n\r");
return 0; // error
}
memcpy(inf->mac_addr,mac,6);
res = sysinfo_save_wrapper();
if(res != 0) {
printf("WiFI_SetMacAddress: sysinfo_save error - %i!\n\r",res);
return 0; // error
}
return 1;
#else
if(wifi_set_mac_address((char *)mac))
return 1;
return 0; // error
#endif
}
void CFG_CreateDeviceNameUnique()
{
// must be unsigned, else print below prints negatives as e.g. FFFFFFFe
unsigned char mac[32] = { 0 };
WiFI_GetMacAddress((char *)mac);
sprintf(g_deviceName,DEVICENAME_PREFIX_FULL"_%02X%02X%02X%02X",mac[2],mac[3],mac[4],mac[5]);
sprintf(g_shortDeviceName,DEVICENAME_PREFIX_SHORT"%02X%02X%02X%02X",mac[2],mac[3],mac[4],mac[5]);
// NOT WORKING, I done it other way, see ethernetif.c
//net_dhcp_hostname_set(g_shortDeviceName);
}
int CFG_GetMQTTPort() {
return g_mqtt_port;
}
void CFG_SetMQTTPort(int p) {
g_mqtt_port = p;
}
void CFG_SetOpenAccessPoint() {
g_wifi_ssid[0] = 0;
g_wifi_pass[0] = 0;
}
const char *CFG_GetWiFiSSID(){
return g_wifi_ssid;
}
const char *CFG_GetWiFiPass(){
return g_wifi_pass;
}
void CFG_SetWiFiSSID(const char *s) {
strcpy_safe(g_wifi_ssid,s,sizeof(g_wifi_ssid));
}
void CFG_SetWiFiPass(const char *s) {
strcpy_safe(g_wifi_pass,s,sizeof(g_wifi_pass));
}
const char *CFG_GetMQTTHost() {
return g_mqtt_host;
}
const char *CFG_GetMQTTBrokerName() {
return g_mqtt_brokerName;
}
const char *CFG_GetMQTTUserName() {
return g_mqtt_userName;
}
const char *CFG_GetMQTTPass() {
return g_mqtt_pass;
}
void CFG_SetMQTTHost(const char *s) {
strcpy_safe(g_mqtt_host,s,sizeof(g_mqtt_host));
}
void CFG_SetMQTTBrokerName(const char *s) {
strcpy_safe(g_mqtt_brokerName,s,sizeof(g_mqtt_brokerName));
}
void CFG_SetMQTTUserName(const char *s) {
strcpy_safe(g_mqtt_userName,s,sizeof(g_mqtt_userName));
}
void CFG_SetMQTTPass(const char *s) {
strcpy_safe(g_mqtt_pass,s,sizeof(g_mqtt_pass));
}
void CFG_SaveWiFi() {
#if WINDOWS
#elif PLATFORM_BL602
#elif PLATFORM_XR809
sysinfo_t *inf;
int res;
inf = sysinfo_get();
if(inf == 0) {
printf("CFG_SaveWiFi: sysinfo_get returned 0!\n\r");
return;
}
strcpy_safe((char*)inf->wlan_sta_param.ssid, g_wifi_ssid, sizeof(inf->wlan_sta_param.ssid));
strcpy_safe((char*)inf->wlan_sta_param.psk, g_wifi_pass, sizeof(inf->wlan_sta_param.psk));
res = sysinfo_save_wrapper();
if(res != 0) {
printf("CFG_SaveWiFi: sysinfo_save error - %i!\n\r",res);
}
#else
ITEM_NEW_WIFI_CONFIG container;
os_memset(&container, 0, sizeof(container));
CONFIG_INIT_ITEM(CONFIG_TYPE_WIFI, &container);
strcpy_safe(container.ssid, g_wifi_ssid, sizeof(container.ssid));
strcpy_safe(container.pass, g_wifi_pass, sizeof(container.pass));
config_save_item(&container);
#endif
}
void CFG_LoadWiFi() {
#if WINDOWS
#elif PLATFORM_BL602
#elif PLATFORM_XR809
sysinfo_t *inf;
inf = sysinfo_get();
if(inf == 0) {
printf("CFG_LoadWiFi: sysinfo_get returned 0!\n\r");
return;
}
strcpy_safe(g_wifi_ssid,(char*)inf->wlan_sta_param.ssid,sizeof(g_wifi_ssid));
strcpy_safe(g_wifi_pass,(char*)inf->wlan_sta_param.psk,sizeof(g_wifi_pass));
#else
{
// try to read 'old' structure with extra 8 bytes
// if we find it, delete and re-save with new structure
ITEM_NEW_WIFI_CONFIG2 container;
CONFIG_INIT_ITEM(OLD_WIFI_CONFIG, &container);
if (config_get_item(&container) != 0){
strcpy_safe(g_wifi_ssid,container.ssid,sizeof(g_wifi_ssid));
strcpy_safe(g_wifi_pass,container.pass,sizeof(g_wifi_pass));
// delete and re-save
config_delete_item(OLD_WIFI_CONFIG);
CFG_SaveWiFi();
}
}
{
ITEM_NEW_NEW_WIFI_CONFIG container;
CONFIG_INIT_ITEM(CONFIG_TYPE_WIFI, &container);
if (config_get_item(&container) != 0){
strcpy_safe(g_wifi_ssid,container.ssid,sizeof(g_wifi_ssid));
strcpy_safe(g_wifi_pass,container.pass,sizeof(g_wifi_pass));
}
}
#endif
}
#if PLATFORM_XR809
int sysinfo_checksum(sysinfo_t *inf) {
int crc = 0;
crc ^= Tiny_CRC8((const char*)&inf->mac_addr,sizeof(inf->mac_addr));
crc ^= Tiny_CRC8((const char*)&inf->wlan_mode,sizeof(inf->wlan_mode));
crc ^= Tiny_CRC8((const char*)&inf->wlan_sta_param,sizeof(inf->wlan_sta_param));
crc ^= Tiny_CRC8((const char*)&inf->wlan_ap_param,sizeof(inf->wlan_ap_param));
crc ^= Tiny_CRC8((const char*)&inf->netif_sta_param,sizeof(inf->netif_sta_param));
crc ^= Tiny_CRC8((const char*)&inf->netif_ap_param,sizeof(inf->netif_ap_param));
crc ^= Tiny_CRC8((const char*)&inf->mqtt_param,sizeof(inf->mqtt_param));
static byte CFG_CalcChecksum(mainConfig_t *inf) {
byte crc = 0;
crc ^= Tiny_CRC8((const char*)&inf->version,sizeof(inf->version));
crc ^= Tiny_CRC8((const char*)&inf->changeCounter,sizeof(inf->changeCounter));
crc ^= Tiny_CRC8((const char*)&inf->otaCounter,sizeof(inf->otaCounter));
crc ^= Tiny_CRC8((const char*)&inf->genericFlags,sizeof(inf->genericFlags));
crc ^= Tiny_CRC8((const char*)&inf->genericFlags2,sizeof(inf->genericFlags2));
crc ^= Tiny_CRC8((const char*)&inf->wifi_ssid,sizeof(inf->wifi_ssid));
crc ^= Tiny_CRC8((const char*)&inf->wifi_pass,sizeof(inf->wifi_pass));
crc ^= Tiny_CRC8((const char*)&inf->mqtt_host,sizeof(inf->mqtt_host));
crc ^= Tiny_CRC8((const char*)&inf->mqtt_brokerName,sizeof(inf->mqtt_brokerName));
crc ^= Tiny_CRC8((const char*)&inf->mqtt_userName,sizeof(inf->mqtt_userName));
crc ^= Tiny_CRC8((const char*)&inf->mqtt_pass,sizeof(inf->mqtt_pass));
crc ^= Tiny_CRC8((const char*)&inf->mqtt_port,sizeof(inf->mqtt_port));
crc ^= Tiny_CRC8((const char*)&inf->webappRoot,sizeof(inf->webappRoot));
crc ^= Tiny_CRC8((const char*)&inf->mac,sizeof(inf->mac));
crc ^= Tiny_CRC8((const char*)&inf->shortDeviceName,sizeof(inf->shortDeviceName));
crc ^= Tiny_CRC8((const char*)&inf->longDeviceName,sizeof(inf->longDeviceName));
crc ^= Tiny_CRC8((const char*)&inf->pins,sizeof(inf->pins));
crc ^= Tiny_CRC8((const char*)&inf->unusedSectorA,sizeof(inf->unusedSectorA));
crc ^= Tiny_CRC8((const char*)&inf->unusedSectorB,sizeof(inf->unusedSectorB));
crc ^= Tiny_CRC8((const char*)&inf->unusedSectorC,sizeof(inf->unusedSectorC));
crc ^= Tiny_CRC8((const char*)&inf->initCommandLine,sizeof(inf->initCommandLine));
return crc;
}
int sysinfo_save_wrapper() {
sysinfo_t *inf;
int res;
inf = sysinfo_get();
if(inf == 0) {
printf("sysinfo_save_wrapper: sysinfo_get returned 0!\n\r");
return -1;
}
printf("sysinfo_save_wrapper: going to calc checksum!\n\r");
inf->checksum = sysinfo_checksum(inf);
printf("sysinfo_save_wrapper: going to call save!\n\r");
res = sysinfo_save();
if(res != 0) {
printf("sysinfo_save_wrapper: sysinfo_save returned error!\n\r");
}
printf("sysinfo_save_wrapper: done!\n\r");
return 0;
static void CFG_SetDefaultConfig() {
// must be unsigned, else print below prints negatives as e.g. FFFFFFFe
unsigned char mac[6] = { 0 };
WiFI_GetMacAddress((char *)mac);
memset(&g_cfg,0,sizeof(mainConfig_t));
g_cfg.mqtt_port = 1883;
g_cfg.ident0 = CFG_IDENT_0;
g_cfg.ident1 = CFG_IDENT_1;
g_cfg.ident2 = CFG_IDENT_2;
strcpy(g_cfg.mqtt_host, "192.168.0.113");
strcpy(g_cfg.mqtt_brokerName, "test");
strcpy(g_cfg.mqtt_userName, "homeassistant");
strcpy(g_cfg.mqtt_pass, "qqqqqqqqqq");
// already zeroed but just to remember, open AP by default
g_cfg.wifi_ssid[0] = 0;
g_cfg.wifi_pass[0] = 0;
// i am not sure about this, because some platforms might have no way to store mac outside our cfg?
memcpy(g_cfg.mac,mac,6);
strcpy(g_cfg.webappRoot, "https://openbekeniot.github.io/webapp/");
// Long unique device name, like OpenBK7231T_AABBCCDD
sprintf(g_cfg.longDeviceName,DEVICENAME_PREFIX_FULL"_%02X%02X%02X%02X",mac[2],mac[3],mac[4],mac[5]);
sprintf(g_cfg.shortDeviceName,DEVICENAME_PREFIX_SHORT"%02X%02X%02X%02X",mac[2],mac[3],mac[4],mac[5]);
}
#endif
int CFG_SaveMQTT() {
#if WINDOWS
return 0;
#elif PLATFORM_BL602
return 0;
#elif PLATFORM_XR809
sysinfo_t *inf;
int res;
inf = sysinfo_get();
if(inf == 0) {
printf("CFG_SaveMQTT: sysinfo_get returned 0!\n\r");
return 0;
}
strcpy_safe(inf->mqtt_param.userName, g_mqtt_userName, sizeof(inf->mqtt_param.userName));
strcpy_safe(inf->mqtt_param.pass, g_mqtt_pass, sizeof(inf->mqtt_param.pass));
strcpy_safe(inf->mqtt_param.hostName, g_mqtt_host, sizeof(inf->mqtt_param.hostName));
strcpy_safe(inf->mqtt_param.brokerName, g_mqtt_brokerName, sizeof(inf->mqtt_param.brokerName));
inf->mqtt_param.port = g_mqtt_port;
printf("CFG_SaveMQTT: sysinfo will save inf->mqtt_param.userName - %s!\n\r",inf->mqtt_param.userName);
printf("CFG_SaveMQTT: sysinfo will save inf->mqtt_param.hostName - %s!\n\r",inf->mqtt_param.hostName);
res = sysinfo_save_wrapper();
if(res != 0) {
printf("CFG_SaveMQTT: sysinfo_save error - %i!\n\r",res);
return 0;
}
#else
ITEM_NEW_MQTT_CONFIG container;
os_memset(&container, 0, sizeof(container));
CONFIG_INIT_ITEM(CONFIG_TYPE_MQTT, &container);
strcpy_safe(container.userName, g_mqtt_userName, sizeof(container.userName));
strcpy_safe(container.pass, g_mqtt_pass, sizeof(container.pass));
strcpy_safe(container.hostName, g_mqtt_host, sizeof(container.hostName));
strcpy_safe(container.brokerName, g_mqtt_brokerName, sizeof(container.brokerName));
container.port = g_mqtt_port;
if(config_save_item(&container))
return 1;
return 0;
#endif
const char *CFG_GetWebappRoot(){
return g_cfg.webappRoot;
}
void CFG_LoadMQTT() {
#if WINDOWS
#elif PLATFORM_BL602
int CFG_SetWebappRoot(const char *s) {
// this will return non-zero if there were any changes
if(strcpy_safe_checkForChanges(g_cfg.webappRoot, s,sizeof(g_cfg.webappRoot))) {
// mark as dirty (value has changed)
g_cfg_pendingChanges++;
}
return 1;
}
#elif PLATFORM_XR809
sysinfo_t *inf;
inf = sysinfo_get();
if(inf == 0) {
printf("CFG_LoadMQTT: sysinfo_get returned 0!\n\r");
const char *CFG_GetDeviceName(){
return g_cfg.longDeviceName;
}
const char *CFG_GetShortDeviceName(){
return g_cfg.shortDeviceName;
}
int CFG_GetMQTTPort() {
return g_cfg.mqtt_port;
}
void CFG_SetMQTTPort(int p) {
// is there a change?
if(g_cfg.mqtt_port != p) {
g_cfg.mqtt_port = p;
// mark as dirty (value has changed)
g_cfg_pendingChanges++;
}
}
void CFG_SetOpenAccessPoint() {
// is there a change?
if(g_cfg.wifi_ssid[0] == 0 && g_cfg.wifi_pass[0] == 0) {
return;
}
strcpy_safe(g_mqtt_userName,inf->mqtt_param.userName,sizeof(g_mqtt_userName));
strcpy_safe(g_mqtt_pass,inf->mqtt_param.pass,sizeof(g_mqtt_pass));
strcpy_safe(g_mqtt_host,inf->mqtt_param.hostName,sizeof(g_mqtt_host));
strcpy_safe(g_mqtt_brokerName,inf->mqtt_param.brokerName,sizeof(g_mqtt_brokerName));
g_mqtt_port = inf->mqtt_param.port;
printf("CFG_LoadMQTT: sysinfo has been loaded!\n\r");
printf("CFG_LoadMQTT: SYSINFO_SIZE is %i!\n\r",SYSINFO_SIZE);
printf("CFG_LoadMQTT: g_mqtt_userName is %s!\n\r",g_mqtt_userName);
printf("CFG_LoadMQTT: g_mqtt_host is %s!\n\r",g_mqtt_host);
#else
{
ITEM_NEW_MQTT_CONFIG2 container;
CONFIG_INIT_ITEM(NEW_MQTT_CONFIG, &container);
if (config_get_item(&container) != 0){
strcpy_safe(g_mqtt_userName,container.userName,sizeof(g_mqtt_userName));
strcpy_safe(g_mqtt_pass,container.pass,sizeof(g_mqtt_pass));
strcpy_safe(g_mqtt_host,container.hostName,sizeof(g_mqtt_host));
strcpy_safe(g_mqtt_brokerName,container.brokerName,sizeof(g_mqtt_brokerName));
g_mqtt_port = container.port;
// delete and re-save
config_delete_item(OLD_MQTT_CONFIG);
CFG_SaveMQTT();
}
g_cfg.wifi_ssid[0] = 0;
g_cfg.wifi_pass[0] = 0;
// mark as dirty (value has changed)
g_cfg_pendingChanges++;
}
const char *CFG_GetWiFiSSID(){
return g_cfg.wifi_ssid;
}
const char *CFG_GetWiFiPass(){
return g_cfg.wifi_pass;
}
void CFG_SetWiFiSSID(const char *s) {
// this will return non-zero if there were any changes
if(strcpy_safe_checkForChanges(g_cfg.wifi_ssid, s,sizeof(g_cfg.wifi_ssid))) {
// mark as dirty (value has changed)
g_cfg_pendingChanges++;
}
{
ITEM_NEW_NEW_MQTT_CONFIG container;
CONFIG_INIT_ITEM(CONFIG_TYPE_MQTT, &container);
if (config_get_item(&container) != 0){
strcpy_safe(g_mqtt_userName,container.userName,sizeof(g_mqtt_userName));
strcpy_safe(g_mqtt_pass,container.pass,sizeof(g_mqtt_pass));
strcpy_safe(g_mqtt_host,container.hostName,sizeof(g_mqtt_host));
strcpy_safe(g_mqtt_brokerName,container.brokerName,sizeof(g_mqtt_brokerName));
g_mqtt_port = container.port;
}
}
void CFG_SetWiFiPass(const char *s) {
// this will return non-zero if there were any changes
if(strcpy_safe_checkForChanges(g_cfg.wifi_pass, s,sizeof(g_cfg.wifi_pass))) {
// mark as dirty (value has changed)
g_cfg_pendingChanges++;
}
}
const char *CFG_GetMQTTHost() {
return g_cfg.mqtt_host;
}
const char *CFG_GetMQTTBrokerName() {
return g_cfg.mqtt_brokerName;
}
const char *CFG_GetMQTTUserName() {
return g_cfg.mqtt_userName;
}
const char *CFG_GetMQTTPass() {
return g_cfg.mqtt_pass;
}
void CFG_SetMQTTHost(const char *s) {
// this will return non-zero if there were any changes
if(strcpy_safe_checkForChanges(g_cfg.mqtt_host, s,sizeof(g_cfg.mqtt_host))) {
// mark as dirty (value has changed)
g_cfg_pendingChanges++;
}
}
void CFG_SetMQTTBrokerName(const char *s) {
// this will return non-zero if there were any changes
if(strcpy_safe_checkForChanges(g_cfg.mqtt_brokerName, s,sizeof(g_cfg.mqtt_brokerName))) {
// mark as dirty (value has changed)
g_cfg_pendingChanges++;
}
}
void CFG_SetMQTTUserName(const char *s) {
// this will return non-zero if there were any changes
if(strcpy_safe_checkForChanges(g_cfg.mqtt_userName, s,sizeof(g_cfg.mqtt_userName))) {
// mark as dirty (value has changed)
g_cfg_pendingChanges++;
}
}
void CFG_SetMQTTPass(const char *s) {
// this will return non-zero if there were any changes
if(strcpy_safe_checkForChanges(g_cfg.mqtt_pass, s,sizeof(g_cfg.mqtt_pass))) {
// mark as dirty (value has changed)
g_cfg_pendingChanges++;
}
}
void CFG_ClearPins() {
memset(&g_cfg.pins,0,sizeof(g_cfg.pins));
g_cfg_pendingChanges++;
}
void CFG_IncrementOTACount() {
g_cfg.otaCounter++;
g_cfg_pendingChanges++;
}
void CFG_Save_IfThereArePendingChanges() {
if(g_cfg_pendingChanges > 0) {
g_cfg.changeCounter++;
g_cfg.crc = CFG_CalcChecksum(&g_cfg);
HAL_Configuration_SaveConfigMemory(&g_cfg,sizeof(g_cfg));
g_cfg_pendingChanges = 0;
}
#endif
}
void CFG_InitAndLoad() {
CFG_CreateDeviceNameUnique();
CFG_LoadWebappRoot();
CFG_LoadWiFi();
CFG_LoadMQTT();
PIN_LoadFromFlash();
byte chkSum;
HAL_Configuration_ReadConfigMemory(&g_cfg,sizeof(g_cfg));
chkSum = CFG_CalcChecksum(&g_cfg);
if(g_cfg.ident0 != CFG_IDENT_0 || g_cfg.ident1 != CFG_IDENT_1 || g_cfg.ident2 != CFG_IDENT_2
|| chkSum != g_cfg.crc) {
addLogAdv(LOG_WARN, LOG_FEATURE_CFG, "CFG_InitAndLoad: Config crc or ident mismatch. Default config will be loaded.");
CFG_SetDefaultConfig();
// mark as changed
g_cfg_pendingChanges ++;
} else {
addLogAdv(LOG_WARN, LOG_FEATURE_CFG, "CFG_InitAndLoad: Correct config has been loaded with %i changes count.",g_cfg.changeCounter);
}
}

View File

@@ -1,5 +1,7 @@
const char *CFG_GetDeviceName();
const char *CFG_GetShortDeviceName();
void CFG_CreateDeviceNameUnique();
@@ -18,12 +20,11 @@ void CFG_SetMQTTHost(const char *s);
void CFG_SetMQTTBrokerName(const char *s);
void CFG_SetMQTTUserName(const char *s);
void CFG_SetMQTTPass(const char *s);
void CFG_SaveWiFi();
void CFG_LoadWiFi();
int CFG_SaveMQTT();
void CFG_LoadMQTT();
const char *CFG_GetWebappRoot();
const char *CFG_LoadWebappRoot();
int CFG_SetWebappRoot(const char *s);
void CFG_InitAndLoad();
void CFG_InitAndLoad();
void CFG_Save_IfThereArePendingChanges();
void CFG_IncrementOTACount();

View File

@@ -30,6 +30,33 @@ int strcat_safe(char *tg, const char *src, int tgMaxLen) {
}
int strcpy_safe_checkForChanges(char *tg, const char *src, int tgMaxLen) {
int changesFound = 0;
// keep space for 1 more char
int curOfs = 1;
// copy
while(*src != 0) {
if(*tg != *src) {
changesFound++;
*tg = *src;
}
src++;
tg++;
curOfs++;
if(curOfs >= tgMaxLen - 1) {
if(*tg != 0) {
changesFound++;
*tg = 0;
}
return 0;
}
}
if(*tg != 0) {
changesFound++;
*tg = 0;
}
return changesFound;
}
int strcpy_safe(char *tg, const char *src, int tgMaxLen) {
// keep space for 1 more char
int curOfs = 1;

View File

@@ -10,6 +10,30 @@
#include "obk_config.h"
#if WINDOWS
#define DEVICENAME_PREFIX_FULL "WinTest"
#define DEVICENAME_PREFIX_SHORT "WT"
#elif PLATFORM_XR809
#define DEVICENAME_PREFIX_FULL "OpenXR809"
#define DEVICENAME_PREFIX_SHORT "oxr"
#elif PLATFORM_BK7231N
#define DEVICENAME_PREFIX_FULL "OpenBK7231N"
#define DEVICENAME_PREFIX_SHORT "obk"
#elif PLATFORM_BK7231T
#define DEVICENAME_PREFIX_FULL "OpenBK7231T"
#define DEVICENAME_PREFIX_SHORT "obk"
#elif PLATFORM_BL602
#define DEVICENAME_PREFIX_FULL "OpenBL602"
#define DEVICENAME_PREFIX_SHORT "obl"
#else
#error "You must define a platform.."
This platform is not supported, error!
#endif
#if WINDOWS
@@ -169,6 +193,7 @@ int wal_stricmp(const char *a, const char *b) ;
int strcat_safe(char *tg, const char *src, int tgMaxLen);
int strcpy_safe(char *tg, const char *src, int tgMaxLen);
int strcpy_safe_checkForChanges(char *tg, const char *src, int tgMaxLen);
void urldecode2_safe(char *dst, const char *srcin, int maxDstLen);
int Time_getUpTimeSeconds();
char Tiny_CRC8(const char *data,int length);

View File

@@ -49,168 +49,36 @@ typedef struct pinButton_ {
// if zero, all hardware action is disabled.
char g_enable_pins = 0;
#if WINDOWS
#elif PLATFORM_BL602
#include "bl_gpio.h"
#include <bl_pwm.h>
#elif PLATFORM_XR809
// XR809 sysinfo is used to save configuration to flash
#include "common/framework/sysinfo.h"
#else
#include "flash_config/flash_config.h"
#include "../../beken378/func/include/net_param_pub.h"
typedef struct item_pins_config
{
INFO_ITEM_ST head;
pinsState_t pins;
}ITEM_PINS_CONFIG,*ITEM_PINS_CONFIG_PTR;
#endif
/*
// from BkDriverPwm.h"
OSStatus bk_pwm_start(bk_pwm_t pwm);
OSStatus bk_pwm_update_param(bk_pwm_t pwm, uint32_t frequency, uint32_t duty_cycle);
OSStatus bk_pwm_stop(bk_pwm_t pwm);
*/
//char g_pwmIndexForPinIndexMapping []
//{
// // pin 0
//
//
//};
// pwm mqtt
// https://community.home-assistant.io/t/shelly-dimmer-with-mqtt/149871
// https://community.home-assistant.io/t/mqtt-light-problems-with-dimmer-devices/120822
// https://community.home-assistant.io/t/mqtt-dimming/96447/2
// https://community.home-assistant.io/t/mqtt-dimmer-switch-doesnt-display-brightness-slider/15471/2
// it was nice to have it as bits but now that we support PWM...
//int g_channelStates;
int g_channelValues[GPIO_MAX] = { 0 };
// channel content types, mostly not required to set
int g_channelTypes[GPIO_MAX] = { 0 };
pinButton_s g_buttons[GPIO_MAX];
pinsState_t g_pins;
void (*g_channelChangeCallback)(int idx, int iVal) = 0;
void (*g_doubleClickCallback)(int pinIndex) = 0;
void PIN_SaveToFlash() {
#if WINDOWS
#elif PLATFORM_BL602
#elif PLATFORM_XR809
sysinfo_t *inf;
int res;
inf = sysinfo_get();
if(inf == 0) {
printf("PIN_SaveToFlash: sysinfo_get returned 0!\n\r");
return;
}
memcpy(&inf->pins, &g_pins, sizeof(inf->pins));
if(sizeof(inf->pins) != sizeof(g_pins)) {
printf("PIN_SaveToFlash: FATAL ERROR - pin structures size mismatch! %i vs %i\r\n",sizeof(inf->pins),sizeof(g_pins));
}
res = sysinfo_save_wrapper();
if(res != 0) {
printf("PIN_SaveToFlash: sysinfo_save error - %i!\n\r",res);
}
#else
ITEM_PINS_CONFIG pins;
memcpy(&pins.pins, &g_pins, sizeof(pins.pins));
CONFIG_INIT_ITEM(CONFIG_TYPE_PINS, &pins);
config_save_item(&pins);
// delete old if it exists
config_delete_item(OLD_PINS_CONFIG);
#endif
}
void PIN_LoadFromFlash() {
//int i;
#if WINDOWS
#elif PLATFORM_BL602
#elif PLATFORM_XR809
sysinfo_t *inf;
#else
int res;
ITEM_PINS_CONFIG pins;
#endif
addLogAdv(LOG_INFO, LOG_FEATURE_GENERAL,"PIN_LoadFromFlash called - going to load pins.\r\n");
addLogAdv(LOG_INFO, LOG_FEATURE_GENERAL,"UART log breaking after that means that you changed the role of TX pin to digital IO or smth else.\r\n");
#if WINDOWS
#elif PLATFORM_BL602
#elif PLATFORM_XR809
inf = sysinfo_get();
if(inf == 0) {
printf("PIN_LoadFromFlash: sysinfo_get returned 0!\n\r");
return;
}
memcpy(&g_pins, &inf->pins, sizeof(g_pins));
if(sizeof(inf->pins) != sizeof(g_pins)) {
printf("PIN_LoadFromFlash: FATAL ERROR - pin structures size mismatch! %i vs %i\r\n",sizeof(inf->pins),sizeof(g_pins));
}
#else
CONFIG_INIT_ITEM(CONFIG_TYPE_PINS, &pins);
res = config_get_item(&pins);
if (res){
memcpy(&g_pins, &pins.pins, sizeof(g_pins));
}
#endif
}
// call after PIN_LoadFromFlash() - if you want to actually set them
void PIN_SetupPins() {
int i;
for(i = 0; i < GPIO_MAX; i++) {
PIN_SetPinRoleForPinIndex(i,g_pins.roles[i]);
PIN_SetPinRoleForPinIndex(i,g_cfg.pins.roles[i]);
}
addLogAdv(LOG_INFO, LOG_FEATURE_GENERAL,"PIN_LoadFromFlash pins have been set up.\r\n");
addLogAdv(LOG_INFO, LOG_FEATURE_GENERAL,"PIN_SetupPins pins have been set up.\r\n");
}
void PIN_ClearPins() {
memset(&g_pins,0,sizeof(g_pins));
}
int PIN_GetPinRoleForPinIndex(int index) {
return g_pins.roles[index];
return g_cfg.pins.roles[index];
}
int PIN_GetPinChannelForPinIndex(int index) {
return g_pins.channels[index];
return g_cfg.pins.channels[index];
}
int PIN_GetPinChannel2ForPinIndex(int index) {
return g_pins.channels2[index];
return g_cfg.pins.channels2[index];
}
void RAW_SetPinValue(int index, int iVal){
if (g_enable_pins) {
@@ -220,24 +88,24 @@ void RAW_SetPinValue(int index, int iVal){
void Button_OnShortClick(int index)
{
addLogAdv(LOG_INFO, LOG_FEATURE_GENERAL,"%i key_short_press\r\n", index);
if(g_pins.roles[index] == IOR_Button_ToggleAll || g_pins.roles[index] == IOR_Button_ToggleAll_n)
if(g_cfg.pins.roles[index] == IOR_Button_ToggleAll || g_cfg.pins.roles[index] == IOR_Button_ToggleAll_n)
{
CHANNEL_DoSpecialToggleAll();
return;
}
// first click toggles FIRST CHANNEL linked to this button
CHANNEL_Toggle(g_pins.channels[index]);
CHANNEL_Toggle(g_cfg.pins.channels[index]);
}
void Button_OnDoubleClick(int index)
{
addLogAdv(LOG_INFO, LOG_FEATURE_GENERAL,"%i key_double_press\r\n", index);
if(g_pins.roles[index] == IOR_Button_ToggleAll || g_pins.roles[index] == IOR_Button_ToggleAll_n)
if(g_cfg.pins.roles[index] == IOR_Button_ToggleAll || g_cfg.pins.roles[index] == IOR_Button_ToggleAll_n)
{
CHANNEL_DoSpecialToggleAll();
return;
}
// double click toggles SECOND CHANNEL linked to this button
CHANNEL_Toggle(g_pins.channels2[index]);
CHANNEL_Toggle(g_cfg.pins.channels2[index]);
if(g_doubleClickCallback!=0) {
g_doubleClickCallback(index);
@@ -248,7 +116,7 @@ void Button_OnLongPressHold(int index) {
}
bool BTN_ShouldInvert(int index) {
if(g_pins.roles[index] == IOR_Button_n || g_pins.roles[index] == IOR_Button_ToggleAll_n|| g_pins.roles[index] == IOR_DigitalInput_n) {
if(g_cfg.pins.roles[index] == IOR_Button_n || g_cfg.pins.roles[index] == IOR_Button_ToggleAll_n|| g_cfg.pins.roles[index] == IOR_DigitalInput_n) {
return true;
}
return false;
@@ -293,8 +161,8 @@ int CHANNEL_GetType(int ch) {
bool CHANNEL_IsInUse(int ch) {
int i;
for(i = 0; i < GPIO_MAX; i++){
if(g_pins.channels[i] == ch) {
switch(g_pins.roles[i])
if(g_cfg.pins.channels[i] == ch) {
switch(g_cfg.pins.roles[i])
{
case IOR_LED:
case IOR_LED_n:
@@ -316,7 +184,7 @@ void CHANNEL_SetAll(int iVal, bool bForce) {
for(i = 0; i < GPIO_MAX; i++) {
switch(g_pins.roles[i])
switch(g_cfg.pins.roles[i])
{
case IOR_Button:
case IOR_Button_n:
@@ -330,10 +198,10 @@ void CHANNEL_SetAll(int iVal, bool bForce) {
case IOR_LED_n:
case IOR_Relay:
case IOR_Relay_n:
CHANNEL_Set(g_pins.channels[i],iVal,bForce);
CHANNEL_Set(g_cfg.pins.channels[i],iVal,bForce);
break;
case IOR_PWM:
CHANNEL_Set(g_pins.channels[i],iVal,bForce);
CHANNEL_Set(g_cfg.pins.channels[i],iVal,bForce);
break;
default:
@@ -399,7 +267,7 @@ void PIN_SetPinRoleForPinIndex(int index, int role) {
}
#endif
if (g_enable_pins) {
switch(g_pins.roles[index])
switch(g_cfg.pins.roles[index])
{
case IOR_Button:
case IOR_Button_n:
@@ -428,7 +296,7 @@ void PIN_SetPinRoleForPinIndex(int index, int role) {
}
}
// set new role
g_pins.roles[index] = role;
g_cfg.pins.roles[index] = role;
if (g_enable_pins) {
// init new role
@@ -482,10 +350,10 @@ void PIN_SetPinRoleForPinIndex(int index, int role) {
}
void PIN_SetPinChannelForPinIndex(int index, int ch) {
g_pins.channels[index] = ch;
g_cfg.pins.channels[index] = ch;
}
void PIN_SetPinChannel2ForPinIndex(int index, int ch) {
g_pins.channels2[index] = ch;
g_cfg.pins.channels2[index] = ch;
}
void PIN_SetGenericDoubleClickCallback(void (*cb)(int pinIndex)) {
g_doubleClickCallback = cb;
@@ -508,25 +376,25 @@ void Channel_OnChanged(int ch) {
#endif
for(i = 0; i < GPIO_MAX; i++) {
if(g_pins.channels[i] == ch) {
if(g_pins.roles[i] == IOR_Relay || g_pins.roles[i] == IOR_LED) {
if(g_cfg.pins.channels[i] == ch) {
if(g_cfg.pins.roles[i] == IOR_Relay || g_cfg.pins.roles[i] == IOR_LED) {
RAW_SetPinValue(i,bOn);
if(g_channelChangeCallback != 0) {
g_channelChangeCallback(ch,bOn);
}
}
if(g_pins.roles[i] == IOR_Relay_n || g_pins.roles[i] == IOR_LED_n) {
if(g_cfg.pins.roles[i] == IOR_Relay_n || g_cfg.pins.roles[i] == IOR_LED_n) {
RAW_SetPinValue(i,!bOn);
if(g_channelChangeCallback != 0) {
g_channelChangeCallback(ch,bOn);
}
}
if(g_pins.roles[i] == IOR_DigitalInput) {
if(g_cfg.pins.roles[i] == IOR_DigitalInput) {
if(g_channelChangeCallback != 0) {
g_channelChangeCallback(ch,iVal);
}
}
if(g_pins.roles[i] == IOR_PWM) {
if(g_cfg.pins.roles[i] == IOR_PWM) {
if(g_channelChangeCallback != 0) {
g_channelChangeCallback(ch,iVal);
}
@@ -589,14 +457,14 @@ bool CHANNEL_Check(int ch) {
int CHANNEL_GetRoleForOutputChannel(int ch){
int i;
for (i = 0; i < 32; i++){
if (g_pins.channels[i] == ch){
switch(g_pins.roles[i]){
if (g_cfg.pins.channels[i] == ch){
switch(g_cfg.pins.roles[i]){
case IOR_Relay:
case IOR_Relay_n:
case IOR_LED:
case IOR_LED_n:
case IOR_PWM:
return g_pins.roles[i];
return g_cfg.pins.roles[i];
break;
case IOR_Button:
case IOR_Button_n:
@@ -725,15 +593,15 @@ void PIN_ticks(void *param)
int value;
for(i = 0; i < GPIO_MAX; i++) {
if(g_pins.roles[i] == IOR_Button || g_pins.roles[i] == IOR_Button_n
|| g_pins.roles[i] == IOR_Button_ToggleAll || g_pins.roles[i] == IOR_Button_ToggleAll_n) {
if(g_cfg.pins.roles[i] == IOR_Button || g_cfg.pins.roles[i] == IOR_Button_n
|| g_cfg.pins.roles[i] == IOR_Button_ToggleAll || g_cfg.pins.roles[i] == IOR_Button_ToggleAll_n) {
//addLogAdv(LOG_INFO, LOG_FEATURE_GENERAL,"Test hold %i\r\n",i);
PIN_Input_Handler(i);
}
else if(g_pins.roles[i] == IOR_DigitalInput || g_pins.roles[i] == IOR_DigitalInput_n) {
else if(g_cfg.pins.roles[i] == IOR_DigitalInput || g_cfg.pins.roles[i] == IOR_DigitalInput_n) {
// read pin digital value (and already invert it if needed)
value = PIN_ReadDigitalInputValue_WithInversionIncluded(i);
CHANNEL_Set(g_pins.channels[i], value,0);
CHANNEL_Set(g_cfg.pins.channels[i], value,0);
}
}
}
@@ -840,13 +708,13 @@ void PIN_set_wifi_led(int value){
int res = -1;
int i;
for ( i = 0; i < 32; i++){
if ((g_pins.roles[i] == IOR_LED_WIFI) || (g_pins.roles[i] == IOR_LED_WIFI_n)){
if ((g_cfg.pins.roles[i] == IOR_LED_WIFI) || (g_cfg.pins.roles[i] == IOR_LED_WIFI_n)){
res = i;
break;
}
}
if (res >= 0){
if (g_pins.roles[res] == IOR_LED_WIFI_n){
if (g_cfg.pins.roles[res] == IOR_LED_WIFI_n){
value = !value;
}
RAW_SetPinValue(res, value & 1);

View File

@@ -39,28 +39,74 @@ enum ChannelType {
ChType_Temperature_div10,
ChType_Toggle,
};
// NOTE: you must keep size of this structure in sync with
// structures in flash config code for both BK7231 and XR809
#define GPIO_MAX 27
#define CHANNEL_MAX 64
typedef struct pinsState_s {
// All above values are indexed by physical pin index
// (so we assume we have maximum of 32 pins)
byte roles[32];
byte channels[32];
// extra channels array - this is needed for
// buttons, so button can toggle one relay on single click
// and other relay on double click
byte channels2[32];
// This single field above, is indexed by CHANNEL INDEX
// (not by pin index)
byte channelTypes[CHANNEL_MAX];
} pinsState_t;
//
// Main config structure (less than 2KB)
//
// This config structure is supposed to be saved only when user
// changes the device configuration, so really not often.
// We should not worry about flash memory wear in this case.
// The saved-every-reboot values are stored elsewhere
// (i.e. saved channel states, reboot counter?)
typedef struct mainConfig_s {
byte ident0;
byte ident1;
byte ident2;
byte crc;
int version;
// unused
int genericFlags;
// unused
int genericFlags2;
unsigned short changeCounter;
unsigned short otaCounter;
// target wifi credentials
char wifi_ssid[64];
char wifi_pass[64];
// MQTT information for Home Assistant
char mqtt_host[256];
char mqtt_brokerName[64];
char mqtt_userName[64];
char mqtt_pass[128];
int mqtt_port;
// addon JavaScript panel is hosted on external server
char webappRoot[64];
// TODO?
byte mac[6];
// TODO?
char shortDeviceName[32];
char longDeviceName[64];
pinsState_t pins;
byte unusedSectorA[256];
byte unusedSectorB[128];
byte unusedSectorC[128];
char initCommandLine[512];
} mainConfig_t;
extern pinsState_t g_pins;
extern mainConfig_t g_cfg;
extern char g_enable_pins;
#define GPIO_MAX 27
#define CHANNEL_MAX 32
void PIN_Init(void);
void PIN_SetupPins();
void PIN_ClearPins();
void CFG_ClearPins();
int PIN_GetPinRoleForPinIndex(int index);
int PIN_GetPinChannelForPinIndex(int index);
int PIN_GetPinChannel2ForPinIndex(int index);
@@ -82,8 +128,7 @@ int CHANNEL_GetType(int ch);
void CHANNEL_SetAll(int iVal, bool bForce);
void CHANNEL_SetStateOnly(int iVal);
void PIN_SaveToFlash();
void PIN_LoadFromFlash();
void PIN_set_wifi_led(int value);
int PIN_GetPWMIndexForPinIndex(int pin);

View File

@@ -1,6 +1,7 @@
#include "ota.h"
#include "../new_common.h"
#include "../new_cfg.h"
#include "typedef.h"
#include "flash_pub.h"
//#include "flash.h"
@@ -127,9 +128,9 @@ int myhttpclientcallback(httprequest_t* request){
addLogAdv(LOG_INFO, LOG_FEATURE_OTA,"Rebooting in 1 seconds...");
// record this OTA
increment_OTA_count();
CFG_IncrementOTACount();
// make sure it's saved before reboot
config_commit();
CFG_Save_IfThereArePendingChanges();
rtos_delay_milliseconds(1000);
bk_reboot();

View File

@@ -46,8 +46,6 @@ static int g_connectToWiFi = 0;
static int bSafeMode = 0;
// reset after this number of seconds
static int g_reset = 0;
// save config in this number of seconds
int g_savecfg = 0;
// is connected to WiFi?
int g_bHasWiFiConnected = 0;
@@ -58,10 +56,7 @@ int g_bHasWiFiConnected = 0;
void boot_complete(){
}
int config_commit(){
return 0;
}
int boot_failures(){
return 0;
}
@@ -76,10 +71,7 @@ size_t xPortGetFreeHeapSize() {
void boot_complete(){
}
int config_commit(){
return 0;
}
int boot_failures(){
return 0;
}
@@ -228,7 +220,7 @@ void Main_OnEverySecond()
g_reset--;
if (!g_reset){
// ensure any config changes are saved before reboot.
config_commit();
CFG_Save_IfThereArePendingChanges();
ADDLOGF_INFO("Going to call HAL_RebootModule\r\n");
HAL_RebootModule();
} else {
@@ -237,12 +229,7 @@ void Main_OnEverySecond()
}
}
if (g_savecfg){
g_savecfg--;
if (!g_savecfg){
config_commit();
}
}
}
@@ -250,7 +237,6 @@ void app_on_generic_dbl_click(int btnIndex)
{
if(g_secondsElapsed < 5) {
CFG_SetOpenAccessPoint();
CFG_SaveWiFi();
}
}

View File

@@ -158,13 +158,12 @@ int __cdecl main(void)
Tokenizer_TokenizeString("dsfafd dasfdsaf dsaf dsaf dsa fdsaf dsafdsa");
PIN_ClearPins();
CFG_ClearPins();
PIN_SetPinChannelForPinIndex(1,1);
PIN_SetPinRoleForPinIndex(1,IOR_Relay);
PIN_SetPinChannelForPinIndex(2,2);
PIN_SetPinRoleForPinIndex(2,IOR_PWM);
//init_rest();
TuyaMCU_Init();

View File

@@ -207,26 +207,6 @@
/>
</FileConfiguration>
</File>
<File
RelativePath=".\src\flash_config\flash_config.c"
>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\src\httpserver\http_fns.c"
>
@@ -657,7 +637,7 @@
>
</File>
<File
RelativePath=".\src\new_http.h"
RelativePath=".\src\httpserver\new_http.h"
>
<FileConfiguration
Name="Release|Win32"
@@ -669,7 +649,7 @@
</FileConfiguration>
</File>
<File
RelativePath=".\src\httpserver\new_http.h"
RelativePath=".\src\new_http.h"
>
<FileConfiguration
Name="Release|Win32"