rename interface component, update docs, added cleanup of old beacons

This commit is contained in:
Lurkars 2020-07-27 16:54:51 +02:00
parent 7dacb93369
commit 4e696f2fb4
30 changed files with 484 additions and 333 deletions

View File

@ -116,7 +116,7 @@ The ena module contains the main functions of eps-ena with bluetooth scanning an
Connection to german Exposure App ([Corona Warn App](https://github.com/corona-warn-app)) for download Exposure Key export (and maybe later report infection). Connection to german Exposure App ([Corona Warn App](https://github.com/corona-warn-app)) for download Exposure Key export (and maybe later report infection).
### ena-interface ### interface
Adds interface functionality via touch pads for control and setup. Adds interface functionality via touch pads for control and setup.

View File

@ -11,6 +11,12 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
/**
* @file
*
* @brief I2C driver for DS3231 Real Time Clock
*
*/
#ifndef _ds3231_H_ #ifndef _ds3231_H_
#define _ds3231_H_ #define _ds3231_H_

View File

@ -11,6 +11,14 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
/**
* @file
*
* @brief connection to german Exposure Notification App (Corona Warn App)
*
* This is for receiving the Exposure Key export for germany and for report own infection inside germany.
*
*/
#ifndef _ena_CWA_H_ #ifndef _ena_CWA_H_
#define _ena_CWA_H_ #define _ena_CWA_H_

View File

@ -1,10 +0,0 @@
idf_component_register(
SRCS
"ena-interface.c"
"ena-interface-datetime.c"
"ena-interface-menu.c"
"ena-interface-status.c"
INCLUDE_DIRS "include"
PRIV_REQUIRES
ena
)

View File

@ -1,78 +0,0 @@
// Copyright 2020 Lukas Haubaum
//
// Licensed under the GNU Affero General Public License, Version 3;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.gnu.org/licenses/agpl-3.0.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include "esp_log.h"
#include "ena-interface.h"
#include "driver/touch_pad.h"
#include "ena-interface-menu.h"
#include "ena-interface-datetime.h"
static int interface_datetime_state = ENA_INTERFACE_DATETIME_STATE_YEAR;
const uint32_t interface_datetime_steps[6] = {
31557600, 2629800, 86400, 3600, 60, 1};
void ena_interface_datetime_esc(void)
{
ena_interface_menu_start();
}
void ena_interface_datetime_ok(void)
{
interface_datetime_state++;
if (interface_datetime_state > ENA_INTERFACE_DATETIME_STATE_SECONDS)
{
interface_datetime_state = ENA_INTERFACE_DATETIME_STATE_YEAR;
}
ESP_LOGD(ENA_INTERFACE_LOG, "datetime to %d", interface_datetime_state);
}
void ena_interface_datetime_up(void)
{
time_t curtime = time(NULL);
curtime += interface_datetime_steps[interface_datetime_state];
struct timeval tv = {0};
tv.tv_sec = curtime;
settimeofday(&tv, NULL);
ESP_LOGD(ENA_INTERFACE_LOG, "increment %d about %u %s", interface_datetime_state, interface_datetime_steps[interface_datetime_state], ctime(&curtime));
}
void ena_interface_datetime_down(void)
{
time_t curtime = time(NULL);
curtime -= interface_datetime_steps[interface_datetime_state];
struct timeval tv = {0};
tv.tv_sec = curtime;
settimeofday(&tv, NULL);
ESP_LOGD(ENA_INTERFACE_LOG, "decrement %d about %u %s", interface_datetime_state, interface_datetime_steps[interface_datetime_state], ctime(&curtime));
}
void ena_interface_datetime_start(void)
{
ena_interface_set_state(ENA_INTERFACE_STATE_SET_DATETIME);
ena_interface_register_touch_callback(TOUCH_PAD_ESC, &ena_interface_datetime_esc);
ena_interface_register_touch_callback(TOUCH_PAD_OK, &ena_interface_datetime_ok);
ena_interface_register_touch_callback(TOUCH_PAD_UP, &ena_interface_datetime_up);
ena_interface_register_touch_callback(TOUCH_PAD_DOWN, &ena_interface_datetime_down);
ESP_LOGD(ENA_INTERFACE_LOG, "start datetime interface");
}
int ena_interface_datetime_state(void)
{
return interface_datetime_state;
}

View File

@ -1,88 +0,0 @@
// Copyright 2020 Lukas Haubaum
//
// Licensed under the GNU Affero General Public License, Version 3;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.gnu.org/licenses/agpl-3.0.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include "esp_log.h"
#include "driver/touch_pad.h"
#include "ena-interface.h"
#include "ena-interface-datetime.h"
#include "ena-interface-status.h"
#include "ena-interface-menu.h"
static int interface_menu_state = ENA_INTERFACE_MENU_STATE_IDLE;
void ena_interface_menu_ok(void)
{
if (interface_menu_state == ENA_INTERFACE_MENU_STATE_SELECT_TIME)
{
ena_interface_datetime_start();
}
else if (interface_menu_state == ENA_INTERFACE_MENU_STATE_SELECT_STATUS)
{
ena_interface_status_start();
}
else if (interface_menu_state == ENA_INTERFACE_MENU_STATE_SELECT_DEBUG)
{
}
else if (interface_menu_state == ENA_INTERFACE_MENU_STATE_IDLE)
{
if (ena_interface_get_state() == ENA_INTERFACE_STATE_MENU)
{
ena_interface_set_state(ENA_INTERFACE_STATE_IDLE);
ena_interface_register_touch_callback(TOUCH_PAD_UP, NULL);
ena_interface_register_touch_callback(TOUCH_PAD_DOWN, NULL);
}
else
{
ena_interface_menu_start();
}
}
}
void ena_interface_menu_up(void)
{
interface_menu_state--;
if (interface_menu_state < ENA_INTERFACE_MENU_STATE_IDLE)
{
interface_menu_state = ENA_INTERFACE_MENU_STATE_SELECT_STATUS;
}
ESP_LOGD(ENA_INTERFACE_LOG, "menu up to %d", interface_menu_state);
}
void ena_interface_menu_down(void)
{
interface_menu_state++;
if (interface_menu_state > ENA_INTERFACE_MENU_STATE_SELECT_STATUS)
{
interface_menu_state = ENA_INTERFACE_MENU_STATE_IDLE;
}
ESP_LOGD(ENA_INTERFACE_LOG, "menu down to %d", interface_menu_state);
}
void ena_interface_menu_start(void)
{
ena_interface_set_state(ENA_INTERFACE_STATE_MENU);
ena_interface_register_touch_callback(TOUCH_PAD_ESC, NULL);
ena_interface_register_touch_callback(TOUCH_PAD_OK, &ena_interface_menu_ok);
ena_interface_register_touch_callback(TOUCH_PAD_UP, &ena_interface_menu_up);
ena_interface_register_touch_callback(TOUCH_PAD_DOWN, &ena_interface_menu_down);
ESP_LOGD(ENA_INTERFACE_LOG, "start menu interface");
}
int ena_interface_menu_get_state(void)
{
return interface_menu_state;
}

View File

@ -1,7 +1,6 @@
menu "Exposure Notification API" menu "Exposure Notification API"
menu "Storage" menu "Storage"
config ENA_STORAGE_DUMP config ENA_STORAGE_DUMP
bool "Dump storage" bool "Dump storage"
default false default false
@ -53,6 +52,12 @@ menu "Exposure Notification API"
help help
Threshold in seconds after a received beacon is stored permanently. (Default 5 minutes) Threshold in seconds after a received beacon is stored permanently. (Default 5 minutes)
config ENA_BEACON_CLEANUP_TRESHOLD
int "Clean-Up threshold"
default 14
help
Threshold in days after stored beacons to be removed.
config ENA_SCANNING_TIME config ENA_SCANNING_TIME
int "Scanning time" int "Scanning time"
default 30 default 30
@ -67,12 +72,11 @@ menu "Exposure Notification API"
endmenu endmenu
menu "Advertising" menu "Advertising"
config ENA_BT_ROTATION_TIMEOUT_INTERVAL config ENA_BT_ROTATION_TIMEOUT_INTERVAL
int "Rotation timeout interval" int "Rotation timeout interval"
default 900 default 900
help help
Base rotation timeout interval in seconds for changing BT address and therefore the advertised beacon. (Default 5 minutes) Base rotation timeout interval in seconds for BT address change & therefore the advertised beacon.(Default 5 minutes)
config ENA_BT_RANDOMIZE_ROTATION_TIMEOUT_INTERVAL config ENA_BT_RANDOMIZE_ROTATION_TIMEOUT_INTERVAL
int "Randomize rotation timeout interval" int "Randomize rotation timeout interval"

View File

@ -74,6 +74,20 @@ void ena_beacons_temp_refresh(uint32_t unix_timestamp)
#endif #endif
} }
void ena_beacons_cleanup(uint32_t unix_timestamp)
{
uint32_t count = ena_storage_beacons_count();
ena_beacon_t beacon;
for (int i = count - 1; i >= 0; i--)
{
ena_storage_get_beacon(i, &beacon);
if (((unix_timestamp - beacon.timestamp_last) / (60 * 60 * 24)) > ENA_BEACON_CLEANUP_TRESHOLD)
{
ena_storage_remove_beacon(i);
}
}
}
void ena_beacon(uint32_t unix_timestamp, uint8_t *rpi, uint8_t *aem, int rssi) void ena_beacon(uint32_t unix_timestamp, uint8_t *rpi, uint8_t *aem, int rssi)
{ {
uint32_t beacon_index = ena_get_temp_beacon_index(rpi, aem); uint32_t beacon_index = ena_get_temp_beacon_index(rpi, aem);

View File

@ -276,6 +276,19 @@ void ena_storage_add_beacon(ena_beacon_t *beacon)
ESP_LOG_BUFFER_HEXDUMP(ENA_STORAGE_LOG, beacon->aem, ENA_AEM_METADATA_LENGTH, ESP_LOG_DEBUG); ESP_LOG_BUFFER_HEXDUMP(ENA_STORAGE_LOG, beacon->aem, ENA_AEM_METADATA_LENGTH, ESP_LOG_DEBUG);
} }
void ena_storage_remove_beacon(uint32_t index)
{
uint32_t count = ena_storage_beacons_count();
size_t address_from = ENA_STORAGE_BEACONS_START_ADDRESS + index * sizeof(ena_beacon_t);
size_t address_to = ENA_STORAGE_BEACONS_START_ADDRESS + count * sizeof(ena_beacon_t);
ena_storage_shift_delete(address_from, address_to, sizeof(ena_beacon_t));
count--;
ena_storage_write(ENA_STORAGE_BEACONS_COUNT_ADDRESS, &count, sizeof(uint32_t));
ESP_LOGD(ENA_STORAGE_LOG, "remove beacon: %u", index);
}
void ena_storage_erase(void) void ena_storage_erase(void)
{ {
const esp_partition_t *partition = esp_partition_find_first( const esp_partition_t *partition = esp_partition_find_first(

View File

@ -26,6 +26,7 @@
#include "ena-storage.h" #include "ena-storage.h"
#include "ena-bluetooth-scan.h" #include "ena-bluetooth-scan.h"
#include "ena-bluetooth-advertise.h" #include "ena-bluetooth-advertise.h"
#include "ena-beacons.h"
#include "ena.h" #include "ena.h"
@ -56,6 +57,8 @@ void ena_run(void)
// validity only to next day 00:00 // validity only to next day 00:00
last_tek.rolling_period = ENA_TEK_ROLLING_PERIOD - (last_tek.enin % ENA_TEK_ROLLING_PERIOD); last_tek.rolling_period = ENA_TEK_ROLLING_PERIOD - (last_tek.enin % ENA_TEK_ROLLING_PERIOD);
ena_storage_write_tek(&last_tek); ena_storage_write_tek(&last_tek);
// clean up old beacons
ena_beacons_cleanup(unix_timestamp);
} }
// change RPI // change RPI

View File

@ -11,11 +11,18 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
/**
* @file
*
* @brief handles scanned data by storing temporary beacons, check for threshold and store beacons permanently
*
*/
#ifndef _ena_BEACON_H_ #ifndef _ena_BEACON_H_
#define _ena_BEACON_H_ #define _ena_BEACON_H_
#define ENA_BEACON_LOG "ESP-ENA-beacon" // TAG for Logging #define ENA_BEACON_LOG "ESP-ENA-beacon" // TAG for Logging
#define ENA_BEACON_TRESHOLD (CONFIG_ENA_BEACON_TRESHOLD) // meet for longer than 5 minutes #define ENA_BEACON_TRESHOLD (CONFIG_ENA_BEACON_TRESHOLD) // meet for longer than 5 minutes
#define ENA_BEACON_CLEANUP_TRESHOLD (CONFIG_ENA_BEACON_CLEANUP_TRESHOLD) // threshold (in days) for stored beacons to be removed
/** /**
* @brief check temporary beacon for threshold or expiring * @brief check temporary beacon for threshold or expiring
@ -23,11 +30,21 @@
* This function checks all current temporary beacons if the contact threshold is * This function checks all current temporary beacons if the contact threshold is
* reached or if the temporary contact can be discarded. * reached or if the temporary contact can be discarded.
* *
* @param[in] unix_timestamp current time as UNIX timestamp to compate * @param[in] unix_timestamp current time as UNIX timestamp to compare
* *
*/ */
void ena_beacons_temp_refresh(uint32_t unix_timestamp); void ena_beacons_temp_refresh(uint32_t unix_timestamp);
/**
* @brief check stored beacons to expire
*
* This function checks for all stored beacons if the last timestamp is over a threshold to remove the beacon.
*
* @param[in] unix_timestamp current time as UNIX timestamp to compate
*
*/
void ena_beacons_cleanup(uint32_t unix_timestamp);
/** /**
* @brief handle new beacon received from a BLE scan * @brief handle new beacon received from a BLE scan
* *

View File

@ -11,6 +11,12 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
/**
* @file
*
* @brief BLE advertising to send own beacons
*
*/
#ifndef _ena_BLUETOOTH_ADVERTISE_H_ #ifndef _ena_BLUETOOTH_ADVERTISE_H_
#define _ena_BLUETOOTH_ADVERTISE_H_ #define _ena_BLUETOOTH_ADVERTISE_H_

View File

@ -11,6 +11,12 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
/**
* @file
*
* @brief BLE scans for detecting other beacons
*
*/
#ifndef _ena_BLUETOOTH_SCAN_H_ #ifndef _ena_BLUETOOTH_SCAN_H_
#define _ena_BLUETOOTH_SCAN_H_ #define _ena_BLUETOOTH_SCAN_H_

View File

@ -11,6 +11,12 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
/**
* @file
*
* @brief covers cryptography part (key creation, encryption etc.)
*
*/
#ifndef _ena_CRYPTO_H_ #ifndef _ena_CRYPTO_H_
#define _ena_CRYPTO_H_ #define _ena_CRYPTO_H_

View File

@ -11,6 +11,12 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
/**
* @file
*
* @brief decode Exposure Key export, compare with stored beacons, calculate score and risk
*
*/
#ifndef _ena_EXPOSURE_H_ #ifndef _ena_EXPOSURE_H_
#define _ena_EXPOSURE_H_ #define _ena_EXPOSURE_H_

View File

@ -11,6 +11,12 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
/**
* @file
*
* @brief storage part to store own TEKs and beacons
*
*/
#ifndef _ena_STORAGE_H_ #ifndef _ena_STORAGE_H_
#define _ena_STORAGE_H_ #define _ena_STORAGE_H_
@ -190,6 +196,13 @@ void ena_storage_get_beacon(uint32_t index, ena_beacon_t *beacon);
*/ */
void ena_storage_add_beacon(ena_beacon_t *beacon); void ena_storage_add_beacon(ena_beacon_t *beacon);
/**
* @brief remove beacon at given index
*
* @param[in] index the index of the beacon to remove
*/
void ena_storage_remove_beacon(uint32_t index);
/** /**
* @brief erase the storage * @brief erase the storage
* *

View File

@ -11,6 +11,12 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
/**
* @file
*
* @brief run all other ena parts together to time scanning, advertising and exposure checks
*
*/
#ifndef _ena_H_ #ifndef _ena_H_
#define _ena_H_ #define _ena_H_

View File

@ -11,6 +11,12 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
/**
* @file
*
* @brief start I2C driver for display and RTC.
*
*/
#ifndef _i2c_main_H_ #ifndef _i2c_main_H_
#define _i2c_main_H_ #define _i2c_main_H_

View File

@ -0,0 +1,10 @@
idf_component_register(
SRCS
"interface.c"
"interface-datetime.c"
"interface-menu.c"
"interface-status.c"
INCLUDE_DIRS "include"
PRIV_REQUIRES
ena
)

View File

@ -11,21 +11,27 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef _ena_INTERFACE_DATETIME_H_ /**
#define _ena_INTERFACE_DATETIME_H_ * @file
*
* @brief interface for changing current date and time
*
*/
#ifndef _interface__DATETIME_H_
#define _interface__DATETIME_H_
typedef enum typedef enum
{ {
ENA_INTERFACE_DATETIME_STATE_YEAR = 0, INTERFACE_DATETIME_STATE_YEAR = 0,
ENA_INTERFACE_DATETIME_STATE_MONTH, INTERFACE_DATETIME_STATE_MONTH,
ENA_INTERFACE_DATETIME_STATE_DAY, INTERFACE_DATETIME_STATE_DAY,
ENA_INTERFACE_DATETIME_STATE_HOUR, INTERFACE_DATETIME_STATE_HOUR,
ENA_INTERFACE_DATETIME_STATE_MINUTE, INTERFACE_DATETIME_STATE_MINUTE,
ENA_INTERFACE_DATETIME_STATE_SECONDS, INTERFACE_DATETIME_STATE_SECONDS,
} ena_inerface_datetime_state; } interface_datetime_state_t;
void ena_interface_datetime_start(void); void interface_datetime_start(void);
int ena_interface_datetime_state(void); int interface_datetime_state(void);
#endif #endif

View File

@ -11,19 +11,25 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef _ena_INTERFACE_MENU_H_ /**
#define _ena_INTERFACE_MENU_H_ * @file
*
* @brief interface menu to navigate through interface
*
*/
#ifndef _interface__MENU_H_
#define _interface__MENU_H_
typedef enum typedef enum
{ {
ENA_INTERFACE_MENU_STATE_IDLE = 0, INTERFACE_MENU_STATE_IDLE = 0,
ENA_INTERFACE_MENU_STATE_SELECT_TIME, INTERFACE_MENU_STATE_SELECT_TIME,
ENA_INTERFACE_MENU_STATE_SELECT_DEBUG, INTERFACE_MENU_STATE_SELECT_DEBUG,
ENA_INTERFACE_MENU_STATE_SELECT_STATUS, INTERFACE_MENU_STATE_SELECT_STATUS,
} ena_interface_menu_state; } interface_menu_state_t;
void ena_interface_menu_start(void); void interface_menu_start(void);
int ena_interface_menu_get_state(void); int interface_menu_get_state(void);
#endif #endif

View File

@ -11,9 +11,15 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef _ena_INTERFACE_STATUS_H_ /**
#define _ena_INTERFACE_STATUS_H_ * @file
*
* @brief interface to show current ENA status (infection risk etc.)
*
*/
#ifndef _interface__STATUS_H_
#define _interface__STATUS_H_
void ena_interface_status_start(void); void interface_status_start(void);
#endif #endif

View File

@ -11,10 +11,16 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef _ena_INTERFACE_H_ /**
#define _ena_INTERFACE_H_ * @file
*
* @brief interface functionality via touch pads for control and setup
*
*/
#ifndef _interface__H_
#define _interface__H_
#define ENA_INTERFACE_LOG "ESP-ENA-interface" // TAG for Logging #define INTERFACE_LOG "INTERFACE" // TAG for Logging
#define TOUCHPAD_FILTER_TOUCH_PERIOD (10) #define TOUCHPAD_FILTER_TOUCH_PERIOD (10)
#define TOUCH_PAD_COUNT (4) #define TOUCH_PAD_COUNT (4)
@ -28,16 +34,16 @@
*/ */
typedef enum typedef enum
{ {
ENA_INTERFACE_STATE_IDLE = 0, // ilde state, do nothing INTERFACE_STATE_IDLE = 0, // ilde state, do nothing
ENA_INTERFACE_STATE_MENU, // main menu INTERFACE_STATE_MENU, // main menu
ENA_INTERFACE_STATE_SET_DATETIME, // set current date and time INTERFACE_STATE_SET_DATETIME, // set current date and time
ENA_INTERFACE_STATE_STATUS, // current status INTERFACE_STATE_STATUS, // current status
} ena_interface_state; } interface_state_t;
/** /**
* @brief callback function on touch event * @brief callback function on touch event
*/ */
typedef void (*ena_interface_touch_callback)(void); typedef void (*interface_touch_callback)(void);
/** /**
* @brief register a callback function for touch event * @brief register a callback function for touch event
@ -45,7 +51,7 @@ typedef void (*ena_interface_touch_callback)(void);
* @param[in] touch_pad id of the touchpad to listen touch * @param[in] touch_pad id of the touchpad to listen touch
* @param[in] callback callback function * @param[in] callback callback function
*/ */
void ena_interface_register_touch_callback(int touch_pad, ena_interface_touch_callback callback); void interface_register_touch_callback(int touch_pad, interface_touch_callback callback);
/** /**
* @brief get current interface state * @brief get current interface state
@ -53,14 +59,14 @@ void ena_interface_register_touch_callback(int touch_pad, ena_interface_touch_ca
* @return * @return
* current state the interface is in * current state the interface is in
*/ */
int ena_interface_get_state(void); int interface_get_state(void);
/** /**
* @brief set current interface state * @brief set current interface state
* *
* @param[in] state new state to set * @param[in] state new state to set
*/ */
void ena_interface_set_state(ena_interface_state state); void interface_set_state(interface_state_t state);
/** /**
* @brief start interface logic * @brief start interface logic
@ -68,6 +74,6 @@ void ena_interface_set_state(ena_interface_state state);
* This will initialize the touch controls and start a task to listen to touch * This will initialize the touch controls and start a task to listen to touch
* inputs and calling the callbacks * inputs and calling the callbacks
*/ */
void ena_interface_start(void); void interface_start(void);
#endif #endif

View File

@ -0,0 +1,78 @@
// Copyright 2020 Lukas Haubaum
//
// Licensed under the GNU Affero General Public License, Version 3;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.gnu.org/licenses/agpl-3.0.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include "esp_log.h"
#include "interface.h"
#include "driver/touch_pad.h"
#include "interface-menu.h"
#include "interface-datetime.h"
static int current_interface_datetime_state = INTERFACE_DATETIME_STATE_YEAR;
const uint32_t interface_datetime_steps[6] = {
31557600, 2629800, 86400, 3600, 60, 1};
void interface_datetime_esc(void)
{
interface_menu_start();
}
void interface_datetime_ok(void)
{
current_interface_datetime_state++;
if (current_interface_datetime_state > INTERFACE_DATETIME_STATE_SECONDS)
{
current_interface_datetime_state = INTERFACE_DATETIME_STATE_YEAR;
}
ESP_LOGD(INTERFACE_LOG, "datetime to %d", current_interface_datetime_state);
}
void interface_datetime_up(void)
{
time_t curtime = time(NULL);
curtime += interface_datetime_steps[current_interface_datetime_state];
struct timeval tv = {0};
tv.tv_sec = curtime;
settimeofday(&tv, NULL);
ESP_LOGD(INTERFACE_LOG, "increment %d about %u %s", current_interface_datetime_state, interface_datetime_steps[current_interface_datetime_state], ctime(&curtime));
}
void interface_datetime_down(void)
{
time_t curtime = time(NULL);
curtime -= interface_datetime_steps[current_interface_datetime_state];
struct timeval tv = {0};
tv.tv_sec = curtime;
settimeofday(&tv, NULL);
ESP_LOGD(INTERFACE_LOG, "decrement %d about %u %s", current_interface_datetime_state, interface_datetime_steps[current_interface_datetime_state], ctime(&curtime));
}
void interface_datetime_start(void)
{
interface_set_state(INTERFACE_STATE_SET_DATETIME);
interface_register_touch_callback(TOUCH_PAD_ESC, &interface_datetime_esc);
interface_register_touch_callback(TOUCH_PAD_OK, &interface_datetime_ok);
interface_register_touch_callback(TOUCH_PAD_UP, &interface_datetime_up);
interface_register_touch_callback(TOUCH_PAD_DOWN, &interface_datetime_down);
ESP_LOGD(INTERFACE_LOG, "start datetime interface");
}
int interface_datetime_state(void)
{
return current_interface_datetime_state;
}

View File

@ -0,0 +1,88 @@
// Copyright 2020 Lukas Haubaum
//
// Licensed under the GNU Affero General Public License, Version 3;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.gnu.org/licenses/agpl-3.0.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include "esp_log.h"
#include "driver/touch_pad.h"
#include "interface.h"
#include "interface-datetime.h"
#include "interface-status.h"
#include "interface-menu.h"
static int current_interface_menu_state = INTERFACE_MENU_STATE_IDLE;
void interface_menu_ok(void)
{
if (current_interface_menu_state == INTERFACE_MENU_STATE_SELECT_TIME)
{
interface_datetime_start();
}
else if (current_interface_menu_state == INTERFACE_MENU_STATE_SELECT_STATUS)
{
interface_status_start();
}
else if (current_interface_menu_state == INTERFACE_MENU_STATE_SELECT_DEBUG)
{
}
else if (current_interface_menu_state == INTERFACE_MENU_STATE_IDLE)
{
if (interface_get_state() == INTERFACE_STATE_MENU)
{
interface_set_state(INTERFACE_STATE_IDLE);
interface_register_touch_callback(TOUCH_PAD_UP, NULL);
interface_register_touch_callback(TOUCH_PAD_DOWN, NULL);
}
else
{
interface_menu_start();
}
}
}
void interface_menu_up(void)
{
current_interface_menu_state--;
if (current_interface_menu_state < INTERFACE_MENU_STATE_IDLE)
{
current_interface_menu_state = INTERFACE_MENU_STATE_SELECT_STATUS;
}
ESP_LOGD(INTERFACE_LOG, "menu up to %d", current_interface_menu_state);
}
void interface_menu_down(void)
{
current_interface_menu_state++;
if (current_interface_menu_state > INTERFACE_MENU_STATE_SELECT_STATUS)
{
current_interface_menu_state = INTERFACE_MENU_STATE_IDLE;
}
ESP_LOGD(INTERFACE_LOG, "menu down to %d", current_interface_menu_state);
}
void interface_menu_start(void)
{
interface_set_state(INTERFACE_STATE_MENU);
interface_register_touch_callback(TOUCH_PAD_ESC, NULL);
interface_register_touch_callback(TOUCH_PAD_OK, &interface_menu_ok);
interface_register_touch_callback(TOUCH_PAD_UP, &interface_menu_up);
interface_register_touch_callback(TOUCH_PAD_DOWN, &interface_menu_down);
ESP_LOGD(INTERFACE_LOG, "start menu interface");
}
int interface_menu_get_state(void)
{
return current_interface_menu_state;
}

View File

@ -15,23 +15,23 @@
#include "esp_log.h" #include "esp_log.h"
#include "driver/touch_pad.h" #include "driver/touch_pad.h"
#include "ena-interface.h" #include "interface.h"
#include "ena-interface-menu.h" #include "interface-menu.h"
#include "ena-interface-status.h" #include "interface-status.h"
void ena_interface_status_esc(void) void interface_status_esc(void)
{ {
ena_interface_menu_start(); interface_menu_start();
} }
void ena_interface_status_start(void) void interface_status_start(void)
{ {
ena_interface_set_state(ENA_INTERFACE_STATE_STATUS); interface_set_state(INTERFACE_STATE_STATUS);
ena_interface_register_touch_callback(TOUCH_PAD_ESC, &ena_interface_status_esc); interface_register_touch_callback(TOUCH_PAD_ESC, &interface_status_esc);
ena_interface_register_touch_callback(TOUCH_PAD_OK, NULL); interface_register_touch_callback(TOUCH_PAD_OK, NULL);
ena_interface_register_touch_callback(TOUCH_PAD_UP, NULL); interface_register_touch_callback(TOUCH_PAD_UP, NULL);
ena_interface_register_touch_callback(TOUCH_PAD_DOWN, NULL); interface_register_touch_callback(TOUCH_PAD_DOWN, NULL);
ESP_LOGD(ENA_INTERFACE_LOG, "start status interface"); ESP_LOGD(INTERFACE_LOG, "start status interface");
} }

View File

@ -18,20 +18,20 @@
#include "driver/touch_pad.h" #include "driver/touch_pad.h"
#include "esp_log.h" #include "esp_log.h"
#include "ena-interface.h" #include "interface.h"
static int interface_state = ENA_INTERFACE_STATE_IDLE; static int current_interface_state = INTERFACE_STATE_IDLE;
static int touch_mapping[TOUCH_PAD_COUNT] = {0}; static int touch_mapping[TOUCH_PAD_COUNT] = {0};
static bool touch_status[TOUCH_PAD_COUNT] = {0}; static bool touch_status[TOUCH_PAD_COUNT] = {0};
static ena_interface_touch_callback touch_callbacks[TOUCH_PAD_MAX]; static interface_touch_callback touch_callbacks[TOUCH_PAD_MAX];
void ena_interface_register_touch_callback(int touch_pad, ena_interface_touch_callback callback) void interface_register_touch_callback(int touch_pad, interface_touch_callback callback)
{ {
touch_callbacks[touch_pad] = callback; touch_callbacks[touch_pad] = callback;
} }
void ena_interface_run(void *pvParameter) void interface_run(void *pvParameter)
{ {
static uint16_t touch_value; static uint16_t touch_value;
static uint16_t touch_thresh; static uint16_t touch_thresh;
@ -46,7 +46,7 @@ void ena_interface_run(void *pvParameter)
if (!touch_status[i] & touch_status_current[i]) if (!touch_status[i] & touch_status_current[i])
{ {
ESP_LOGD(ENA_INTERFACE_LOG, "touch %u at %d (thresh %u)", touch_value, touch_mapping[i], touch_thresh); ESP_LOGD(INTERFACE_LOG, "touch %u at %d (thresh %u)", touch_value, touch_mapping[i], touch_thresh);
if (touch_callbacks[touch_mapping[i]] != NULL) if (touch_callbacks[touch_mapping[i]] != NULL)
{ {
(*touch_callbacks[touch_mapping[i]])(); (*touch_callbacks[touch_mapping[i]])();
@ -59,7 +59,7 @@ void ena_interface_run(void *pvParameter)
} }
} }
void ena_interface_start(void) void interface_start(void)
{ {
ESP_ERROR_CHECK(touch_pad_init()); ESP_ERROR_CHECK(touch_pad_init());
ESP_ERROR_CHECK(touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V)); ESP_ERROR_CHECK(touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V));
@ -81,18 +81,18 @@ void ena_interface_start(void)
{ {
ESP_ERROR_CHECK(touch_pad_read_filtered(touch_mapping[i], &touch_value)); ESP_ERROR_CHECK(touch_pad_read_filtered(touch_mapping[i], &touch_value));
ESP_ERROR_CHECK(touch_pad_set_thresh(touch_mapping[i], touch_value * 2 / 3)); ESP_ERROR_CHECK(touch_pad_set_thresh(touch_mapping[i], touch_value * 2 / 3));
ESP_LOGD(ENA_INTERFACE_LOG, "calibrate %u at %u (thresh %u)", touch_mapping[i], touch_value, (touch_value * 2 / 3)); ESP_LOGD(INTERFACE_LOG, "calibrate %u at %u (thresh %u)", touch_mapping[i], touch_value, (touch_value * 2 / 3));
} }
xTaskCreate(&ena_interface_run, "ena_interface_run", 4096, NULL, 5, NULL); xTaskCreate(&interface_run, "interface_run", 4096, NULL, 5, NULL);
} }
int ena_interface_get_state(void) int interface_get_state(void)
{ {
return interface_state; return current_interface_state;
} }
void ena_interface_set_state(ena_interface_state state) void interface_set_state(interface_state_t state)
{ {
interface_state = state; current_interface_state = state;
} }

View File

@ -11,6 +11,12 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
/**
* @file
*
* @brief I2C driver for SSD1306 display
*
*/
#ifndef _ssd1306_H_ #ifndef _ssd1306_H_
#define _ssd1306_H_ #define _ssd1306_H_
@ -81,6 +87,7 @@ void ssd1306_start(uint8_t i2address);
* *
* @param[in] i2address I2C address of SSD1306 * @param[in] i2address I2C address of SSD1306
* @param[in] line the line to clear * @param[in] line the line to clear
* @param[in] invert if true, image is inverted
*/ */
void ssd1306_clear_line(uint8_t i2address, uint8_t line, bool invert); void ssd1306_clear_line(uint8_t i2address, uint8_t line, bool invert);
@ -107,6 +114,7 @@ void ssd1306_on(uint8_t i2address, bool on);
* @param[in] length length of data * @param[in] length length of data
* @param[in] line the line to write to * @param[in] line the line to write to
* @param[in] offset number of offset chars to start * @param[in] offset number of offset chars to start
* @param[in] invert if true, image is inverted
*/ */
void ssd1306_data(uint8_t i2address, uint8_t *data, size_t length, uint8_t line, uint8_t offset, bool invert); void ssd1306_data(uint8_t i2address, uint8_t *data, size_t length, uint8_t line, uint8_t offset, bool invert);
@ -117,6 +125,7 @@ void ssd1306_data(uint8_t i2address, uint8_t *data, size_t length, uint8_t line,
* @param[in] text text to display * @param[in] text text to display
* @param[in] line the line to write to * @param[in] line the line to write to
* @param[in] offset number of offset chars to start * @param[in] offset number of offset chars to start
* @param[in] invert if true, image is inverted
*/ */
void ssd1306_text_line_column(uint8_t i2address, char *text, uint8_t line, uint8_t offset, bool invert); void ssd1306_text_line_column(uint8_t i2address, char *text, uint8_t line, uint8_t offset, bool invert);
@ -126,6 +135,7 @@ void ssd1306_text_line_column(uint8_t i2address, char *text, uint8_t line, uint8
* @param[in] i2address I2C address of SSD1306 * @param[in] i2address I2C address of SSD1306
* @param[in] text text to display * @param[in] text text to display
* @param[in] line the line to write to * @param[in] line the line to write to
* @param[in] invert if true, image is inverted
*/ */
void ssd1306_text_line(uint8_t i2address, char *text, uint8_t line, bool invert); void ssd1306_text_line(uint8_t i2address, char *text, uint8_t line, bool invert);

View File

@ -22,9 +22,9 @@
#include "ds3231.h" #include "ds3231.h"
#include "ena-exposure.h" #include "ena-exposure.h"
#include "ena-interface.h" #include "interface.h"
#include "ena-interface-menu.h" #include "interface-menu.h"
#include "ena-interface-datetime.h" #include "interface-datetime.h"
#include "ssd1306.h" #include "ssd1306.h"
void interface_display_time(void *pvParameter) void interface_display_time(void *pvParameter)
@ -42,7 +42,7 @@ void interface_display_time(void *pvParameter)
gmtime_r(&curtime, &rtc_time); gmtime_r(&curtime, &rtc_time);
curtime_text = asctime(&rtc_time); curtime_text = asctime(&rtc_time);
ssd1306_text_line(SSD1306_ADDRESS, curtime_text, 1, false); ssd1306_text_line(SSD1306_ADDRESS, curtime_text, 1, false);
if (ena_interface_get_state() == ENA_INTERFACE_STATE_SET_DATETIME) if (interface_get_state() == INTERFACE_STATE_SET_DATETIME)
{ {
edit_invert = !edit_invert; edit_invert = !edit_invert;
ds3231_set_time(&rtc_time); ds3231_set_time(&rtc_time);
@ -52,30 +52,30 @@ void interface_display_time(void *pvParameter)
char edit_hour[2] = ""; char edit_hour[2] = "";
char edit_minute[2] = ""; char edit_minute[2] = "";
char edit_second[2] = ""; char edit_second[2] = "";
switch (ena_interface_datetime_state()) switch (interface_datetime_state())
{ {
case ENA_INTERFACE_DATETIME_STATE_YEAR: case INTERFACE_DATETIME_STATE_YEAR:
memcpy(&edit_year, &curtime_text[20], 4); memcpy(&edit_year, &curtime_text[20], 4);
ssd1306_text_line_column(SSD1306_ADDRESS, edit_year, 0, 20, edit_invert); ssd1306_text_line_column(SSD1306_ADDRESS, edit_year, 0, 20, edit_invert);
break; break;
case ENA_INTERFACE_DATETIME_STATE_MONTH: case INTERFACE_DATETIME_STATE_MONTH:
memcpy(&edit_month, &curtime_text[4], 3); memcpy(&edit_month, &curtime_text[4], 3);
ssd1306_text_line_column(SSD1306_ADDRESS, edit_month, 0, 4, edit_invert); ssd1306_text_line_column(SSD1306_ADDRESS, edit_month, 0, 4, edit_invert);
break; break;
case ENA_INTERFACE_DATETIME_STATE_DAY: case INTERFACE_DATETIME_STATE_DAY:
memcpy(&edit_day, &curtime_text[8], 2); memcpy(&edit_day, &curtime_text[8], 2);
ssd1306_text_line_column(SSD1306_ADDRESS, edit_day, 0, 8, edit_invert); ssd1306_text_line_column(SSD1306_ADDRESS, edit_day, 0, 8, edit_invert);
break; break;
case ENA_INTERFACE_DATETIME_STATE_HOUR: case INTERFACE_DATETIME_STATE_HOUR:
memcpy(&edit_hour, &curtime_text[11], 2); memcpy(&edit_hour, &curtime_text[11], 2);
ssd1306_text_line_column(SSD1306_ADDRESS, edit_hour, 0, 11, edit_invert); ssd1306_text_line_column(SSD1306_ADDRESS, edit_hour, 0, 11, edit_invert);
break; break;
case ENA_INTERFACE_DATETIME_STATE_MINUTE: case INTERFACE_DATETIME_STATE_MINUTE:
memcpy(&edit_minute, &curtime_text[14], 2); memcpy(&edit_minute, &curtime_text[14], 2);
ssd1306_text_line_column(SSD1306_ADDRESS, edit_minute, 0, 14, edit_invert); ssd1306_text_line_column(SSD1306_ADDRESS, edit_minute, 0, 14, edit_invert);
break; break;
case ENA_INTERFACE_DATETIME_STATE_SECONDS: case INTERFACE_DATETIME_STATE_SECONDS:
memcpy(&edit_second[0], &curtime_text[17], 2); memcpy(&edit_second[0], &curtime_text[17], 2);
ssd1306_text_line_column(SSD1306_ADDRESS, edit_second, 0, 17, edit_invert); ssd1306_text_line_column(SSD1306_ADDRESS, edit_second, 0, 17, edit_invert);
break; break;
@ -90,7 +90,7 @@ void interface_display_status(void *pvParameter)
static bool get_status = true; static bool get_status = true;
while (1) while (1)
{ {
if (ena_interface_get_state() == ENA_INTERFACE_STATE_STATUS) if (interface_get_state() == INTERFACE_STATE_STATUS)
{ {
if (get_status) if (get_status)
{ {
@ -122,7 +122,7 @@ void interface_display_idle(void *pvParameter)
static bool set_status = true; static bool set_status = true;
while (1) while (1)
{ {
if (ena_interface_get_state() == ENA_INTERFACE_STATE_IDLE) if (interface_get_state() == INTERFACE_STATE_IDLE)
{ {
if (set_status) if (set_status)
{ {
@ -144,8 +144,8 @@ void display_interface_start(void)
ssd1306_start(SSD1306_ADDRESS); ssd1306_start(SSD1306_ADDRESS);
ssd1306_clear(SSD1306_ADDRESS); ssd1306_clear(SSD1306_ADDRESS);
ena_interface_start(); interface_start();
ena_interface_menu_start(); interface_menu_start();
xTaskCreate(&interface_display_time, "interface_display_time", 4096, NULL, 5, NULL); xTaskCreate(&interface_display_time, "interface_display_time", 4096, NULL, 5, NULL);
xTaskCreate(&interface_display_status, "interface_display_status", 4096, NULL, 5, NULL); xTaskCreate(&interface_display_status, "interface_display_status", 4096, NULL, 5, NULL);

View File

@ -25,9 +25,10 @@
#include "ena-exposure.h" #include "ena-exposure.h"
#include "ena-bluetooth-advertise.h" #include "ena-bluetooth-advertise.h"
#include "ena-bluetooth-scan.h" #include "ena-bluetooth-scan.h"
#include "ena-interface.h" #include "interface.h"
#include "ena-cwa.h" #include "ena-cwa.h"
#include "ds3231.h" #include "ds3231.h"
#include "display-interface.h"
#include "wifi.h" #include "wifi.h"
#include "sdkconfig.h" #include "sdkconfig.h"
@ -43,7 +44,7 @@ void app_main(void)
esp_log_level_set(ENA_EXPOSURE_LOG, ESP_LOG_DEBUG); esp_log_level_set(ENA_EXPOSURE_LOG, ESP_LOG_DEBUG);
esp_log_level_set(ENA_STORAGE_LOG, ESP_LOG_INFO); esp_log_level_set(ENA_STORAGE_LOG, ESP_LOG_INFO);
esp_log_level_set(ENA_CWA_LOG, ESP_LOG_DEBUG); esp_log_level_set(ENA_CWA_LOG, ESP_LOG_DEBUG);
esp_log_level_set(ENA_INTERFACE_LOG, ESP_LOG_DEBUG); esp_log_level_set(INTERFACE_LOG, ESP_LOG_DEBUG);
esp_log_level_set(WIFI_LOG, ESP_LOG_DEBUG); esp_log_level_set(WIFI_LOG, ESP_LOG_DEBUG);
// set system time from DS3231 // set system time from DS3231
@ -55,12 +56,14 @@ void app_main(void)
tv.tv_sec = curtime; tv.tv_sec = curtime;
settimeofday(&tv, NULL); settimeofday(&tv, NULL);
// Hardcoded timezome of UTC+2 for now (consider POSIX notation!) // Hardcoded timezone of UTC+2 for now (consider POSIX notation!)
setenv("TZ", "UTC-2", 1); setenv("TZ", "UTC-2", 1);
tzset(); tzset();
ena_start(); ena_start();
display_interface_start();
while (1) while (1)
{ {
ena_run(); ena_run();