Formatted

This commit is contained in:
Indu Prakash
2022-10-14 21:08:38 -05:00
parent 7562fd9049
commit fd4aaeef13
9 changed files with 3541 additions and 3464 deletions

View File

@ -16,36 +16,36 @@ Sensor - https://www.home-assistant.io/integrations/sensor.mqtt/
//CFG_GetShortDeviceName and clientId so it needs to be bigger than them. +64 for light/switch/etc.
static char g_hassBuffer[CGF_MQTT_CLIENT_ID_SIZE + 64];
static char *STATE_TOPIC_KEY = "stat_t";
static char *COMMAND_TOPIC_KEY = "cmd_t";
static char* STATE_TOPIC_KEY = "stat_t";
static char* COMMAND_TOPIC_KEY = "cmd_t";
/// @brief Populates HomeAssistant unique id for the entity.
/// @param type Entity type
/// @param index Entity index (Ignored for RGB)
/// @param uniq_id Array to populate (should be of size HASS_UNIQUE_ID_SIZE)
void hass_populate_unique_id(ENTITY_TYPE type, int index, char *uniq_id){
//https://developers.home-assistant.io/docs/entity_registry_index/#unique-id-requirements
//mentions that mac can be used for unique_id and deviceName contains that.
const char *longDeviceName = CFG_GetDeviceName();
switch(type){
case ENTITY_LIGHT_PWM:
sprintf(uniq_id,"%s_%s_%d", longDeviceName, "light", index);
break;
void hass_populate_unique_id(ENTITY_TYPE type, int index, char* uniq_id) {
//https://developers.home-assistant.io/docs/entity_registry_index/#unique-id-requirements
//mentions that mac can be used for unique_id and deviceName contains that.
const char* longDeviceName = CFG_GetDeviceName();
case ENTITY_LIGHT_RGB:
case ENTITY_LIGHT_RGBCW:
sprintf(uniq_id,"%s_%s", longDeviceName, "light");
break;
case ENTITY_RELAY:
sprintf(uniq_id,"%s_%s_%d", longDeviceName, "relay", index);
break;
switch (type) {
case ENTITY_LIGHT_PWM:
sprintf(uniq_id, "%s_%s_%d", longDeviceName, "light", index);
break;
case ENTITY_SENSOR:
sprintf(uniq_id,"%s_%s_%d", longDeviceName, "sensor", index);
break;
}
case ENTITY_LIGHT_RGB:
case ENTITY_LIGHT_RGBCW:
sprintf(uniq_id, "%s_%s", longDeviceName, "light");
break;
case ENTITY_RELAY:
sprintf(uniq_id, "%s_%s_%d", longDeviceName, "relay", index);
break;
case ENTITY_SENSOR:
sprintf(uniq_id, "%s_%s_%d", longDeviceName, "sensor", index);
break;
}
}
/// @brief Prints HomeAssistant unique id for the entity.
@ -53,52 +53,52 @@ void hass_populate_unique_id(ENTITY_TYPE type, int index, char *uniq_id){
/// @param fmt
/// @param type Entity type
/// @param index Entity index
void hass_print_unique_id(http_request_t *request, const char *fmt, ENTITY_TYPE type, int index){
char uniq_id[HASS_UNIQUE_ID_SIZE];
hass_populate_unique_id(type, index, uniq_id);
hprintf128(request, fmt, uniq_id);
void hass_print_unique_id(http_request_t* request, const char* fmt, ENTITY_TYPE type, int index) {
char uniq_id[HASS_UNIQUE_ID_SIZE];
hass_populate_unique_id(type, index, uniq_id);
hprintf128(request, fmt, uniq_id);
}
/// @brief Populates HomeAssistant device configuration MQTT channel e.g. switch/enbrighten_9de8f9_relay_0/config.
/// @param type Entity type
/// @param uniq_id Entity unique id
/// @param info Device info
void hass_populate_device_config_channel(ENTITY_TYPE type, char *uniq_id, HassDeviceInfo *info){
switch(type){
case ENTITY_LIGHT_PWM:
case ENTITY_LIGHT_RGB:
case ENTITY_LIGHT_RGBCW:
sprintf(info->channel, "light/%s/config", uniq_id);
break;
case ENTITY_RELAY:
sprintf(info->channel, "switch/%s/config", uniq_id);
break;
case ENTITY_SENSOR:
sprintf(info->channel, "sensor/%s/config", uniq_id);
break;
}
void hass_populate_device_config_channel(ENTITY_TYPE type, char* uniq_id, HassDeviceInfo* info) {
switch (type) {
case ENTITY_LIGHT_PWM:
case ENTITY_LIGHT_RGB:
case ENTITY_LIGHT_RGBCW:
sprintf(info->channel, "light/%s/config", uniq_id);
break;
case ENTITY_RELAY:
sprintf(info->channel, "switch/%s/config", uniq_id);
break;
case ENTITY_SENSOR:
sprintf(info->channel, "sensor/%s/config", uniq_id);
break;
}
}
/// @brief Builds HomeAssistant device discovery info. The caller needs to free the returned pointer.
/// @param ids
cJSON *hass_build_device_node(cJSON *ids) {
cJSON *dev = cJSON_CreateObject();
cJSON_AddItemToObject(dev, "ids", ids); //identifiers
cJSON_AddStringToObject(dev, "name", CFG_GetShortDeviceName());
cJSON* hass_build_device_node(cJSON* ids) {
cJSON* dev = cJSON_CreateObject();
cJSON_AddItemToObject(dev, "ids", ids); //identifiers
cJSON_AddStringToObject(dev, "name", CFG_GetShortDeviceName());
#ifdef USER_SW_VER
cJSON_AddStringToObject(dev, "sw", USER_SW_VER); //sw_version
#endif
#ifdef USER_SW_VER
cJSON_AddStringToObject(dev, "sw", USER_SW_VER); //sw_version
#endif
cJSON_AddStringToObject(dev, "mf", MANUFACTURER); //manufacturer
cJSON_AddStringToObject(dev, "mdl", PLATFORM_MCU_NAME); //Using chipset for model
cJSON_AddStringToObject(dev, "mf", MANUFACTURER); //manufacturer
cJSON_AddStringToObject(dev, "mdl", PLATFORM_MCU_NAME); //Using chipset for model
sprintf(g_hassBuffer,"http://%s/index",HAL_GetMyIPString());
cJSON_AddStringToObject(dev, "cu", g_hassBuffer); //configuration_url
return dev;
sprintf(g_hassBuffer, "http://%s/index", HAL_GetMyIPString());
cJSON_AddStringToObject(dev, "cu", g_hassBuffer); //configuration_url
return dev;
}
/// @brief Initializes HomeAssistant device discovery storage with common values.
@ -107,162 +107,162 @@ cJSON *hass_build_device_node(cJSON *ids) {
/// @param payload_on
/// @param payload_off
/// @return
HassDeviceInfo *hass_init_device_info(ENTITY_TYPE type, int index, char *payload_on, char *payload_off){
HassDeviceInfo *info = os_malloc(sizeof(HassDeviceInfo));
addLogAdv(LOG_INFO, LOG_FEATURE_HASS, "hass_init_device_info=%p", info);
hass_populate_unique_id(type, index, info->unique_id);
hass_populate_device_config_channel(type, info->unique_id, info);
info->ids = cJSON_CreateArray();
cJSON_AddItemToArray(info->ids, cJSON_CreateString(CFG_GetDeviceName()));
HassDeviceInfo* hass_init_device_info(ENTITY_TYPE type, int index, char* payload_on, char* payload_off) {
HassDeviceInfo* info = os_malloc(sizeof(HassDeviceInfo));
addLogAdv(LOG_INFO, LOG_FEATURE_HASS, "hass_init_device_info=%p", info);
info->device = hass_build_device_node(info->ids);
hass_populate_unique_id(type, index, info->unique_id);
hass_populate_device_config_channel(type, info->unique_id, info);
info->root = cJSON_CreateObject();
cJSON_AddItemToObject(info->root, "dev", info->device); //device
switch(type){
case ENTITY_LIGHT_PWM:
case ENTITY_RELAY:
sprintf(g_hassBuffer,"%s %i",CFG_GetShortDeviceName(),index);
break;
case ENTITY_LIGHT_RGB:
case ENTITY_LIGHT_RGBCW:
//There can only be one RGB so we can skip including index in the name
sprintf(g_hassBuffer,"%s",CFG_GetShortDeviceName());
break;
case ENTITY_SENSOR:
info->ids = cJSON_CreateArray();
cJSON_AddItemToArray(info->ids, cJSON_CreateString(CFG_GetDeviceName()));
info->device = hass_build_device_node(info->ids);
info->root = cJSON_CreateObject();
cJSON_AddItemToObject(info->root, "dev", info->device); //device
switch (type) {
case ENTITY_LIGHT_PWM:
case ENTITY_RELAY:
sprintf(g_hassBuffer, "%s %i", CFG_GetShortDeviceName(), index);
break;
case ENTITY_LIGHT_RGB:
case ENTITY_LIGHT_RGBCW:
//There can only be one RGB so we can skip including index in the name
sprintf(g_hassBuffer, "%s", CFG_GetShortDeviceName());
break;
case ENTITY_SENSOR:
#ifndef OBK_DISABLE_ALL_DRIVERS
sprintf(g_hassBuffer,"%s %s",CFG_GetShortDeviceName(), sensor_mqttNames[index]);
sprintf(g_hassBuffer, "%s %s", CFG_GetShortDeviceName(), sensor_mqttNames[index]);
#endif
break;
}
cJSON_AddStringToObject(info->root, "name", g_hassBuffer);
break;
}
cJSON_AddStringToObject(info->root, "name", g_hassBuffer);
cJSON_AddStringToObject(info->root, "~", CFG_GetMQTTClientId()); //base topic
cJSON_AddStringToObject(info->root, "~", CFG_GetMQTTClientId()); //base topic
cJSON_AddStringToObject(info->root, "avty_t", "~/connected"); //availability_topic, `online` value is broadcasted
cJSON_AddStringToObject(info->root, "avty_t", "~/connected"); //availability_topic, `online` value is broadcasted
cJSON_AddStringToObject(info->root, "pl_on", payload_on); //payload_on
cJSON_AddStringToObject(info->root, "pl_off", payload_off); //payload_off
cJSON_AddStringToObject(info->root, "pl_on", payload_on); //payload_on
cJSON_AddStringToObject(info->root, "pl_off", payload_off); //payload_off
cJSON_AddStringToObject(info->root, "uniq_id", info->unique_id); //unique_id
cJSON_AddStringToObject(info->root, "uniq_id", info->unique_id); //unique_id
addLogAdv(LOG_DEBUG, LOG_FEATURE_HASS, "root=%p", info->root);
return info;
addLogAdv(LOG_DEBUG, LOG_FEATURE_HASS, "root=%p", info->root);
return info;
}
/// @brief Initializes HomeAssistant relay device discovery storage.
/// @param index
/// @return
HassDeviceInfo *hass_init_relay_device_info(int index){
HassDeviceInfo *info = hass_init_device_info(ENTITY_RELAY, index, "1", "0");
cJSON_AddNumberToObject(info->root, "qos", 1);
HassDeviceInfo* hass_init_relay_device_info(int index) {
HassDeviceInfo* info = hass_init_device_info(ENTITY_RELAY, index, "1", "0");
cJSON_AddNumberToObject(info->root, "qos", 1);
sprintf(g_hassBuffer,"~/%i/get",index);
cJSON_AddStringToObject(info->root, STATE_TOPIC_KEY, g_hassBuffer); //state_topic
sprintf(g_hassBuffer,"~/%i/set",index);
cJSON_AddStringToObject(info->root, COMMAND_TOPIC_KEY, g_hassBuffer); //command_topic
sprintf(g_hassBuffer, "~/%i/get", index);
cJSON_AddStringToObject(info->root, STATE_TOPIC_KEY, g_hassBuffer); //state_topic
sprintf(g_hassBuffer, "~/%i/set", index);
cJSON_AddStringToObject(info->root, COMMAND_TOPIC_KEY, g_hassBuffer); //command_topic
return info;
return info;
}
/// @brief Initializes HomeAssistant light device discovery storage.
/// @param type
/// @param index Ignored for RGB, for sensor this corresponds to sensor_mqttNames.
/// @return
HassDeviceInfo *hass_init_light_device_info(ENTITY_TYPE type, int index){
const char *clientId = CFG_GetMQTTClientId();
HassDeviceInfo *info = NULL;
HassDeviceInfo* hass_init_light_device_info(ENTITY_TYPE type, int index) {
const char* clientId = CFG_GetMQTTClientId();
HassDeviceInfo* info = NULL;
switch(type){
case ENTITY_LIGHT_RGBCW:
case ENTITY_LIGHT_RGB:
info = hass_init_device_info(type, index, "1", "0");
switch (type) {
case ENTITY_LIGHT_RGBCW:
case ENTITY_LIGHT_RGB:
info = hass_init_device_info(type, index, "1", "0");
cJSON_AddStringToObject(info->root, "rgb_cmd_tpl","{{'#%02x%02x%02x0000'|format(red,green,blue)}}"); //rgb_command_template
cJSON_AddStringToObject(info->root, "rgb_val_tpl","{{value[1:3]|int(base=16)}},{{value[3:5]|int(base=16)}},{{value[5:7]|int(base=16)}}"); //rgb_value_template
cJSON_AddStringToObject(info->root, "rgb_cmd_tpl", "{{'#%02x%02x%02x0000'|format(red,green,blue)}}"); //rgb_command_template
cJSON_AddStringToObject(info->root, "rgb_val_tpl", "{{value[1:3]|int(base=16)}},{{value[3:5]|int(base=16)}},{{value[5:7]|int(base=16)}}"); //rgb_value_template
cJSON_AddStringToObject(info->root, "rgb_stat_t", "~/led_basecolor_rgb/get"); //rgb_state_topic
sprintf(g_hassBuffer,"cmnd/%s/led_basecolor_rgb",clientId);
cJSON_AddStringToObject(info->root, "rgb_cmd_t", g_hassBuffer); //rgb_command_topic
cJSON_AddStringToObject(info->root, "rgb_stat_t", "~/led_basecolor_rgb/get"); //rgb_state_topic
sprintf(g_hassBuffer, "cmnd/%s/led_basecolor_rgb", clientId);
cJSON_AddStringToObject(info->root, "rgb_cmd_t", g_hassBuffer); //rgb_command_topic
cJSON_AddStringToObject(info->root, STATE_TOPIC_KEY, "~/led_enableAll/get"); //state_topic
sprintf(g_hassBuffer,"cmnd/%s/led_enableAll",clientId);
cJSON_AddStringToObject(info->root, COMMAND_TOPIC_KEY, g_hassBuffer); //command_topic
cJSON_AddStringToObject(info->root, STATE_TOPIC_KEY, "~/led_enableAll/get"); //state_topic
sprintf(g_hassBuffer, "cmnd/%s/led_enableAll", clientId);
cJSON_AddStringToObject(info->root, COMMAND_TOPIC_KEY, g_hassBuffer); //command_topic
cJSON_AddStringToObject(info->root, "bri_stat_t", "~/led_dimmer/get"); //brightness_state_topic
sprintf(g_hassBuffer,"cmnd/%s/led_dimmer",clientId);
cJSON_AddStringToObject(info->root, "bri_cmd_t", g_hassBuffer); //brightness_command_topic
cJSON_AddStringToObject(info->root, "bri_stat_t", "~/led_dimmer/get"); //brightness_state_topic
sprintf(g_hassBuffer, "cmnd/%s/led_dimmer", clientId);
cJSON_AddStringToObject(info->root, "bri_cmd_t", g_hassBuffer); //brightness_command_topic
cJSON_AddNumberToObject(info->root, "bri_scl", 100); //brightness_scale
cJSON_AddNumberToObject(info->root, "bri_scl", 100); //brightness_scale
if (type == ENTITY_LIGHT_RGBCW){
sprintf(g_hassBuffer,"cmnd/%s/led_temperature",clientId);
cJSON_AddStringToObject(info->root, "clr_temp_cmd_t", g_hassBuffer); //color_temp_command_topic
if (type == ENTITY_LIGHT_RGBCW) {
sprintf(g_hassBuffer, "cmnd/%s/led_temperature", clientId);
cJSON_AddStringToObject(info->root, "clr_temp_cmd_t", g_hassBuffer); //color_temp_command_topic
cJSON_AddStringToObject(info->root, "clr_temp_stat_t", "~/led_temperature/get"); //color_temp_state_topic
}
cJSON_AddStringToObject(info->root, "clr_temp_stat_t", "~/led_temperature/get"); //color_temp_state_topic
}
break;
break;
case ENTITY_LIGHT_PWM:
info = hass_init_device_info(type, index, "99", "0");
cJSON_AddStringToObject(info->root, "on_cmd_type", "brightness"); //on_command_type
cJSON_AddNumberToObject(info->root, "bri_scl", 99); //brightness_scale
cJSON_AddBoolToObject(info->root, "opt", cJSON_True); //optimistic
cJSON_AddNumberToObject(info->root, "qos", 1);
cJSON_AddStringToObject(info->root, "bri_stat_t", "~/led_dimmer/get"); //brightness_state_topic
sprintf(g_hassBuffer,"cmnd/%s/led_dimmer",clientId);
cJSON_AddStringToObject(info->root, "bri_cmd_t", g_hassBuffer); //brightness_command_topic
case ENTITY_LIGHT_PWM:
info = hass_init_device_info(type, index, "99", "0");
cJSON_AddStringToObject(info->root, "on_cmd_type", "brightness"); //on_command_type
cJSON_AddNumberToObject(info->root, "bri_scl", 99); //brightness_scale
cJSON_AddBoolToObject(info->root, "opt", cJSON_True); //optimistic
cJSON_AddNumberToObject(info->root, "qos", 1);
sprintf(g_hassBuffer,"~/%i/get",index);
cJSON_AddStringToObject(info->root, STATE_TOPIC_KEY, g_hassBuffer); //state_topic
sprintf(g_hassBuffer,"~/%i/set",index);
cJSON_AddStringToObject(info->root, COMMAND_TOPIC_KEY, g_hassBuffer); //command_topic
cJSON_AddStringToObject(info->root, "bri_stat_t", "~/led_dimmer/get"); //brightness_state_topic
sprintf(g_hassBuffer, "cmnd/%s/led_dimmer", clientId);
cJSON_AddStringToObject(info->root, "bri_cmd_t", g_hassBuffer); //brightness_command_topic
break;
case ENTITY_SENSOR:
sprintf(g_hassBuffer, "~/%i/get", index);
cJSON_AddStringToObject(info->root, STATE_TOPIC_KEY, g_hassBuffer); //state_topic
sprintf(g_hassBuffer, "~/%i/set", index);
cJSON_AddStringToObject(info->root, COMMAND_TOPIC_KEY, g_hassBuffer); //command_topic
break;
case ENTITY_SENSOR:
#ifndef OBK_DISABLE_ALL_DRIVERS
info = hass_init_device_info(type, index, "1", "0");
info = hass_init_device_info(type, index, "1", "0");
//https://developers.home-assistant.io/docs/core/entity/sensor/#available-device-classes
//device_class automatically assigns unit,icon
cJSON_AddStringToObject(info->root, "dev_cla", sensor_mqttNames[index]); //device_class=voltage,current,power
sprintf(g_hassBuffer,"%s/%s/get",clientId,sensor_mqttNames[index]);
cJSON_AddStringToObject(info->root, STATE_TOPIC_KEY, g_hassBuffer);
//https://developers.home-assistant.io/docs/core/entity/sensor/#available-device-classes
//device_class automatically assigns unit,icon
cJSON_AddStringToObject(info->root, "dev_cla", sensor_mqttNames[index]); //device_class=voltage,current,power
sprintf(g_hassBuffer, "%s/%s/get", clientId, sensor_mqttNames[index]);
cJSON_AddStringToObject(info->root, STATE_TOPIC_KEY, g_hassBuffer);
#endif
break;
break;
default:
addLogAdv(LOG_ERROR, LOG_FEATURE_HASS, "Unsupported light type %s", type);
}
return info;
default:
addLogAdv(LOG_ERROR, LOG_FEATURE_HASS, "Unsupported light type %s", type);
}
return info;
}
/// @brief Returns the discovery JSON.
/// @param info
/// @return
char *hass_build_discovery_json(HassDeviceInfo *info){
cJSON_PrintPreallocated(info->root, info->json, HASS_JSON_SIZE, 0);
return info->json;
char* hass_build_discovery_json(HassDeviceInfo* info) {
cJSON_PrintPreallocated(info->root, info->json, HASS_JSON_SIZE, 0);
return info->json;
}
/// @brief Release allocated memory.
/// @param info
void hass_free_device_info(HassDeviceInfo *info){
if (info == NULL) return;
addLogAdv(LOG_DEBUG, LOG_FEATURE_HASS, "hass_free_device_info \r\n");
if (info->root != NULL){
cJSON_Delete(info->root);
}
void hass_free_device_info(HassDeviceInfo* info) {
if (info == NULL) return;
addLogAdv(LOG_DEBUG, LOG_FEATURE_HASS, "hass_free_device_info \r\n");
os_free(info);
if (info->root != NULL) {
cJSON_Delete(info->root);
}
os_free(info);
}

View File

@ -6,10 +6,10 @@
typedef enum {
ENTITY_RELAY = 0,
ENTITY_LIGHT_PWM = 1,
ENTITY_LIGHT_RGB = 2,
ENTITY_LIGHT_RGBCW = 3,
ENTITY_SENSOR = 4,
ENTITY_LIGHT_PWM = 1,
ENTITY_LIGHT_RGB = 2,
ENTITY_LIGHT_RGBCW = 3,
ENTITY_SENSOR = 4,
} ENTITY_TYPE;
//unique_id is defined in hass_populate_unique_id and is based on CFG_GetDeviceName() whose size is CGF_DEVICE_NAME_SIZE.
@ -24,18 +24,18 @@ typedef enum {
#define HASS_JSON_SIZE (MQTT_PUBLISH_ITEM_VALUE_LENGTH - 1)
/// @brief HomeAssistant device discovery information
typedef struct HassDeviceInfo_s{
char unique_id[HASS_UNIQUE_ID_SIZE];
char channel[HASS_CHANNEL_SIZE];
char json[HASS_JSON_SIZE];
typedef struct HassDeviceInfo_s {
char unique_id[HASS_UNIQUE_ID_SIZE];
char channel[HASS_CHANNEL_SIZE];
char json[HASS_JSON_SIZE];
cJSON *root;
cJSON *device;
cJSON *ids;
cJSON* root;
cJSON* device;
cJSON* ids;
} HassDeviceInfo;
void hass_print_unique_id(http_request_t *request, const char *fmt, ENTITY_TYPE type, int index);
HassDeviceInfo *hass_init_relay_device_info(int index);
HassDeviceInfo *hass_init_light_device_info(ENTITY_TYPE type, int index);
char *hass_build_discovery_json(HassDeviceInfo *info);
void hass_free_device_info(HassDeviceInfo *info);
void hass_print_unique_id(http_request_t* request, const char* fmt, ENTITY_TYPE type, int index);
HassDeviceInfo* hass_init_relay_device_info(int index);
HassDeviceInfo* hass_init_light_device_info(ENTITY_TYPE type, int index);
char* hass_build_discovery_json(HassDeviceInfo* info);
void hass_free_device_info(HassDeviceInfo* info);

File diff suppressed because it is too large Load Diff

View File

@ -2,34 +2,34 @@
int http_fn_about(http_request_t *request);
int http_fn_cfg_mqtt(http_request_t *request);
int http_fn_cfg_mqtt_set(http_request_t *request);
int http_fn_cfg_webapp(http_request_t *request);
int http_fn_config_dump_table(http_request_t *request);
int http_fn_cfg_webapp_set(http_request_t *request);
int http_fn_cfg_wifi_set(http_request_t *request);
int http_fn_cfg_name(http_request_t *request);
int http_fn_cfg_loglevel_set(http_request_t *request);
int http_fn_cfg_wifi(http_request_t *request);
int http_fn_cfg_mac(http_request_t *request);
int http_fn_flash_read_tool(http_request_t *request);
int http_fn_cmd_tool(http_request_t *request);
int http_fn_uart_tool(http_request_t *request);
int http_fn_cfg_quick(http_request_t *request);
int http_fn_ha_cfg(http_request_t *request);
int http_fn_ha_discovery(http_request_t *request);
int http_fn_cfg(http_request_t *request);
int http_fn_cfg_pins(http_request_t *request);
int http_fn_cfg_ping(http_request_t *request);
int http_fn_index(http_request_t *request);
int http_fn_testmsg(http_request_t *request);
int http_fn_ota_exec(http_request_t *request);
int http_fn_ota(http_request_t *request);
int http_fn_empty_url(http_request_t *request);
int http_fn_other(http_request_t *request);
int http_fn_cm(http_request_t *request);
int http_fn_startup_command(http_request_t *request);
int http_fn_cfg_generic(http_request_t *request);
int http_fn_cfg_startup(http_request_t *request);
int http_fn_cfg_dgr(http_request_t *request);
int http_fn_about(http_request_t* request);
int http_fn_cfg_mqtt(http_request_t* request);
int http_fn_cfg_mqtt_set(http_request_t* request);
int http_fn_cfg_webapp(http_request_t* request);
int http_fn_config_dump_table(http_request_t* request);
int http_fn_cfg_webapp_set(http_request_t* request);
int http_fn_cfg_wifi_set(http_request_t* request);
int http_fn_cfg_name(http_request_t* request);
int http_fn_cfg_loglevel_set(http_request_t* request);
int http_fn_cfg_wifi(http_request_t* request);
int http_fn_cfg_mac(http_request_t* request);
int http_fn_flash_read_tool(http_request_t* request);
int http_fn_cmd_tool(http_request_t* request);
int http_fn_uart_tool(http_request_t* request);
int http_fn_cfg_quick(http_request_t* request);
int http_fn_ha_cfg(http_request_t* request);
int http_fn_ha_discovery(http_request_t* request);
int http_fn_cfg(http_request_t* request);
int http_fn_cfg_pins(http_request_t* request);
int http_fn_cfg_ping(http_request_t* request);
int http_fn_index(http_request_t* request);
int http_fn_testmsg(http_request_t* request);
int http_fn_ota_exec(http_request_t* request);
int http_fn_ota(http_request_t* request);
int http_fn_empty_url(http_request_t* request);
int http_fn_other(http_request_t* request);
int http_fn_cm(http_request_t* request);
int http_fn_startup_command(http_request_t* request);
int http_fn_cfg_generic(http_request_t* request);
int http_fn_cfg_startup(http_request_t* request);
int http_fn_cfg_dgr(http_request_t* request);

View File

@ -22,187 +22,187 @@
#endif
static void tcp_server_thread( beken_thread_arg_t arg );
static void tcp_client_thread( beken_thread_arg_t arg );
static void tcp_server_thread(beken_thread_arg_t arg);
static void tcp_client_thread(beken_thread_arg_t arg);
xTaskHandle g_http_thread = NULL;
void HTTPServer_Start()
{
OSStatus err = kNoErr;
OSStatus err = kNoErr;
err = rtos_create_thread( &g_http_thread, BEKEN_APPLICATION_PRIORITY,
"TCP_server",
(beken_thread_function_t)tcp_server_thread,
0x800,
(beken_thread_arg_t)0 );
if(err != kNoErr)
{
ADDLOG_ERROR(LOG_FEATURE_HTTP, "create \"TCP_server\" thread failed with %i!\r\n",err);
}
err = rtos_create_thread(&g_http_thread, BEKEN_APPLICATION_PRIORITY,
"TCP_server",
(beken_thread_function_t)tcp_server_thread,
0x800,
(beken_thread_arg_t)0);
if (err != kNoErr)
{
ADDLOG_ERROR(LOG_FEATURE_HTTP, "create \"TCP_server\" thread failed with %i!\r\n", err);
}
}
int sendfn(int fd, char * data, int len){
if (fd){
return send( fd, data, len, 0 );
}
return -1;
int sendfn(int fd, char* data, int len) {
if (fd) {
return send(fd, data, len, 0);
}
return -1;
}
static void tcp_client_thread( beken_thread_arg_t arg )
static void tcp_client_thread(beken_thread_arg_t arg)
{
OSStatus err = kNoErr;
int fd = (int) arg;
//fd_set readfds, errfds, readfds2;
char *buf = NULL;
char *reply = NULL;
OSStatus err = kNoErr;
int fd = (int)arg;
//fd_set readfds, errfds, readfds2;
char* buf = NULL;
char* reply = NULL;
int replyBufferSize = REPLY_BUFFER_SIZE;
//int res;
//char reply[8192];
//my_fd = fd;
reply = (char*) os_malloc( replyBufferSize );
buf = (char*) os_malloc( INCOMING_BUFFER_SIZE );
reply = (char*)os_malloc(replyBufferSize);
buf = (char*)os_malloc(INCOMING_BUFFER_SIZE);
if ( buf == 0 || reply == 0)
{
ADDLOG_ERROR(LOG_FEATURE_HTTP, "TCP Client failed to malloc buffer" );
goto exit;
}
http_request_t request;
os_memset(&request, 0, sizeof(request));
if (buf == 0 || reply == 0)
{
ADDLOG_ERROR(LOG_FEATURE_HTTP, "TCP Client failed to malloc buffer");
goto exit;
}
http_request_t request;
os_memset(&request, 0, sizeof(request));
request.fd = fd;
request.received = buf;
request.receivedLenmax = INCOMING_BUFFER_SIZE-2;
request.responseCode = HTTP_RESPONSE_OK;
request.receivedLen = recv( fd, request.received, request.receivedLenmax, 0 );
request.received[request.receivedLen] = 0;
request.fd = fd;
request.received = buf;
request.receivedLenmax = INCOMING_BUFFER_SIZE - 2;
request.responseCode = HTTP_RESPONSE_OK;
request.receivedLen = recv(fd, request.received, request.receivedLenmax, 0);
request.received[request.receivedLen] = 0;
request.reply = reply;
request.replylen = 0;
reply[0] = '\0';
request.reply = reply;
request.replylen = 0;
reply[0] = '\0';
request.replymaxlen = replyBufferSize - 1;
request.replymaxlen = replyBufferSize - 1;
if ( request.receivedLen <= 0 )
{
ADDLOG_ERROR(LOG_FEATURE_HTTP, "TCP Client is disconnected, fd: %d", fd );
goto exit;
}
if (request.receivedLen <= 0)
{
ADDLOG_ERROR(LOG_FEATURE_HTTP, "TCP Client is disconnected, fd: %d", fd);
goto exit;
}
//addLog( "TCP received string %s\n",buf );
// returns length to be sent if any
// ADDLOG_DEBUG(LOG_FEATURE_HTTP, "TCP will process packet of len %i\n", request.receivedLen );
int lenret = HTTP_ProcessPacket(&request);
if (lenret > 0){
ADDLOG_DEBUG(LOG_FEATURE_HTTP, "TCP sending reply len %i\n",lenret );
send( fd, reply, lenret, 0 );
}
//addLog( "TCP received string %s\n",buf );
// returns length to be sent if any
// ADDLOG_DEBUG(LOG_FEATURE_HTTP, "TCP will process packet of len %i\n", request.receivedLen );
int lenret = HTTP_ProcessPacket(&request);
if (lenret > 0) {
ADDLOG_DEBUG(LOG_FEATURE_HTTP, "TCP sending reply len %i\n", lenret);
send(fd, reply, lenret, 0);
}
rtos_delay_milliseconds(10);
rtos_delay_milliseconds(10);
exit:
if ( err != kNoErr )
ADDLOG_ERROR(LOG_FEATURE_HTTP, "TCP client thread exit with err: %d", err );
if (err != kNoErr)
ADDLOG_ERROR(LOG_FEATURE_HTTP, "TCP client thread exit with err: %d", err);
if ( buf != NULL )
os_free( buf );
if ( reply != NULL )
os_free( reply );
if (buf != NULL)
os_free(buf);
if (reply != NULL)
os_free(reply);
lwip_close( fd );;
lwip_close(fd);;
#if DISABLE_SEPARATE_THREAD_FOR_EACH_TCP_CLIENT
#else
rtos_delete_thread( NULL );
rtos_delete_thread(NULL);
#endif
}
/* TCP server listener thread */
static void tcp_server_thread( beken_thread_arg_t arg )
static void tcp_server_thread(beken_thread_arg_t arg)
{
(void)( arg );
OSStatus err = kNoErr;
struct sockaddr_in server_addr, client_addr;
socklen_t sockaddr_t_size = sizeof(client_addr);
char client_ip_str[16];
int tcp_listen_fd = -1, client_fd = -1;
fd_set readfds;
(void)(arg);
OSStatus err = kNoErr;
struct sockaddr_in server_addr, client_addr;
socklen_t sockaddr_t_size = sizeof(client_addr);
char client_ip_str[16];
int tcp_listen_fd = -1, client_fd = -1;
fd_set readfds;
tcp_listen_fd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
tcp_listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;/* Accept conenction request on all network interface */
server_addr.sin_port = htons( HTTP_SERVER_PORT );/* Server listen on port: 20000 */
err = bind( tcp_listen_fd, (struct sockaddr *) &server_addr, sizeof(server_addr) );
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;/* Accept conenction request on all network interface */
server_addr.sin_port = htons(HTTP_SERVER_PORT);/* Server listen on port: 20000 */
err = bind(tcp_listen_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
err = listen( tcp_listen_fd, 0 );
err = listen(tcp_listen_fd, 0);
while ( 1 )
{
FD_ZERO( &readfds );
FD_SET( tcp_listen_fd, &readfds );
while (1)
{
FD_ZERO(&readfds);
FD_SET(tcp_listen_fd, &readfds);
select( tcp_listen_fd + 1, &readfds, NULL, NULL, NULL);
select(tcp_listen_fd + 1, &readfds, NULL, NULL, NULL);
if ( FD_ISSET( tcp_listen_fd, &readfds ) )
{
client_fd = accept( tcp_listen_fd, (struct sockaddr *) &client_addr, &sockaddr_t_size );
if ( client_fd >= 0 )
{
if (FD_ISSET(tcp_listen_fd, &readfds))
{
client_fd = accept(tcp_listen_fd, (struct sockaddr*)&client_addr, &sockaddr_t_size);
if (client_fd >= 0)
{
#if PLATFORM_XR809
#if DISABLE_SEPARATE_THREAD_FOR_EACH_TCP_CLIENT
#else
OS_Thread_t clientThreadUnused ;
OS_Thread_t clientThreadUnused;
#endif
#endif
os_strcpy( client_ip_str, inet_ntoa( client_addr.sin_addr ) );
// ADDLOG_DEBUG(LOG_FEATURE_HTTP, "TCP Client %s:%d connected, fd: %d", client_ip_str, client_addr.sin_port, client_fd );
os_strcpy(client_ip_str, inet_ntoa(client_addr.sin_addr));
// ADDLOG_DEBUG(LOG_FEATURE_HTTP, "TCP Client %s:%d connected, fd: %d", client_ip_str, client_addr.sin_port, client_fd );
#if DISABLE_SEPARATE_THREAD_FOR_EACH_TCP_CLIENT
// Use main server thread (blocking all other clients)
// right now, I am getting OS_ThreadCreate everytime on XR809 platform
tcp_client_thread((beken_thread_arg_t)client_fd);
#else
// Create separate thread for client
if ( kNoErr !=
if (kNoErr !=
#if PLATFORM_XR809
OS_ThreadCreate(&clientThreadUnused,
"HTTP Client",
tcp_client_thread,
client_fd,
OS_THREAD_PRIO_CONSOLE,
0x400)
"HTTP Client",
tcp_client_thread,
client_fd,
OS_THREAD_PRIO_CONSOLE,
0x400)
#else
rtos_create_thread( NULL, BEKEN_APPLICATION_PRIORITY,
"HTTP Client",
(beken_thread_function_t)tcp_client_thread,
0x800,
(beken_thread_arg_t)client_fd )
rtos_create_thread(NULL, BEKEN_APPLICATION_PRIORITY,
"HTTP Client",
(beken_thread_function_t)tcp_client_thread,
0x800,
(beken_thread_arg_t)client_fd)
#endif
)
{
ADDLOG_DEBUG(LOG_FEATURE_HTTP, "TCP Client %s:%d thread creation failed! fd: %d", client_ip_str, client_addr.sin_port, client_fd );
lwip_close( client_fd );
client_fd = -1;
}
)
{
ADDLOG_DEBUG(LOG_FEATURE_HTTP, "TCP Client %s:%d thread creation failed! fd: %d", client_ip_str, client_addr.sin_port, client_fd);
lwip_close(client_fd);
client_fd = -1;
}
#endif
}
}
}
}
}
}
if ( err != kNoErr )
ADDLOG_ERROR(LOG_FEATURE_HTTP, "Server listerner thread exit with err: %d", err );
if (err != kNoErr)
ADDLOG_ERROR(LOG_FEATURE_HTTP, "Server listerner thread exit with err: %d", err);
lwip_close( tcp_listen_fd );
lwip_close(tcp_listen_fd);
rtos_delete_thread( NULL );
rtos_delete_thread(NULL);
}
@ -211,14 +211,14 @@ static void tcp_server_thread( beken_thread_arg_t arg )
xTaskHandle g_http_thread = NULL;
int sendfn(int fd, char * data, int len){
if (fd){
return send( fd, data, len, 0 );
int sendfn(int fd, char* data, int len) {
if (fd) {
return send(fd, data, len, 0);
}
return -1;
}
static void tcp_client_thread( int fd, char *buf, char *reply )
static void tcp_client_thread(int fd, char* buf, char* reply)
{
//OSStatus err = kNoErr;
@ -229,7 +229,7 @@ static void tcp_client_thread( int fd, char *buf, char *reply )
request.received = buf;
request.receivedLenmax = INCOMING_BUFFER_SIZE - 1;
request.responseCode = HTTP_RESPONSE_OK;
request.receivedLen = recv( fd, request.received, request.receivedLenmax, 0 );
request.receivedLen = recv(fd, request.received, request.receivedLenmax, 0);
request.received[request.receivedLen] = 0;
request.reply = reply;
@ -238,88 +238,88 @@ static void tcp_client_thread( int fd, char *buf, char *reply )
request.replymaxlen = REPLY_BUFFER_SIZE - 1;
if ( request.receivedLen <= 0 )
if (request.receivedLen <= 0)
{
ADDLOG_ERROR(LOG_FEATURE_HTTP, "TCP Client is disconnected, fd: %d", fd );
ADDLOG_ERROR(LOG_FEATURE_HTTP, "TCP Client is disconnected, fd: %d", fd);
return;
}
int lenret = HTTP_ProcessPacket(&request);
if (lenret > 0){
send( fd, reply, lenret, 0 );
if (lenret > 0) {
send(fd, reply, lenret, 0);
}
rtos_delay_milliseconds(10);
}
/* TCP server listener thread */
static void tcp_server_thread( beken_thread_arg_t arg )
static void tcp_server_thread(beken_thread_arg_t arg)
{
(void)( arg );
OSStatus err = kNoErr;
struct sockaddr_in server_addr, client_addr;
socklen_t sockaddr_t_size = sizeof(client_addr);
char client_ip_str[16];
int tcp_listen_fd = -1, client_fd = -1;
fd_set readfds;
char *buf = NULL;
char *reply = NULL;
(void)(arg);
OSStatus err = kNoErr;
struct sockaddr_in server_addr, client_addr;
socklen_t sockaddr_t_size = sizeof(client_addr);
char client_ip_str[16];
int tcp_listen_fd = -1, client_fd = -1;
fd_set readfds;
char* buf = NULL;
char* reply = NULL;
tcp_listen_fd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
tcp_listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;/* Accept conenction request on all network interface */
server_addr.sin_port = htons( HTTP_SERVER_PORT );/* Server listen on port: 20000 */
err = bind( tcp_listen_fd, (struct sockaddr *) &server_addr, sizeof(server_addr) );
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;/* Accept conenction request on all network interface */
server_addr.sin_port = htons(HTTP_SERVER_PORT);/* Server listen on port: 20000 */
err = bind(tcp_listen_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
err = listen( tcp_listen_fd, 0 );
err = listen(tcp_listen_fd, 0);
reply = (char*) os_malloc( REPLY_BUFFER_SIZE );
buf = (char*) os_malloc( INCOMING_BUFFER_SIZE );
reply = (char*)os_malloc(REPLY_BUFFER_SIZE);
buf = (char*)os_malloc(INCOMING_BUFFER_SIZE);
while ( 1 )
{
FD_ZERO( &readfds );
FD_SET( tcp_listen_fd, &readfds );
while (1)
{
FD_ZERO(&readfds);
FD_SET(tcp_listen_fd, &readfds);
select( tcp_listen_fd + 1, &readfds, NULL, NULL, NULL);
select(tcp_listen_fd + 1, &readfds, NULL, NULL, NULL);
if ( FD_ISSET( tcp_listen_fd, &readfds ) )
{
client_fd = accept( tcp_listen_fd, (struct sockaddr *) &client_addr, &sockaddr_t_size );
if ( client_fd >= 0 )
{
os_strcpy( client_ip_str, inet_ntoa( client_addr.sin_addr ) );
// ADDLOG_DEBUG(LOG_FEATURE_HTTP, "TCP Client %s:%d connected, fd: %d", client_ip_str, client_addr.sin_port, client_fd );
if (FD_ISSET(tcp_listen_fd, &readfds))
{
client_fd = accept(tcp_listen_fd, (struct sockaddr*)&client_addr, &sockaddr_t_size);
if (client_fd >= 0)
{
os_strcpy(client_ip_str, inet_ntoa(client_addr.sin_addr));
// ADDLOG_DEBUG(LOG_FEATURE_HTTP, "TCP Client %s:%d connected, fd: %d", client_ip_str, client_addr.sin_port, client_fd );
tcp_client_thread(client_fd,reply,buf);
tcp_client_thread(client_fd, reply, buf);
lwip_close( client_fd );
}
}
}
lwip_close(client_fd);
}
}
}
if ( err != kNoErr )
ADDLOG_ERROR(LOG_FEATURE_HTTP, "Server listerner thread exit with err: %d", err );
if (err != kNoErr)
ADDLOG_ERROR(LOG_FEATURE_HTTP, "Server listerner thread exit with err: %d", err);
lwip_close( tcp_listen_fd );
lwip_close(tcp_listen_fd);
rtos_delete_thread( NULL );
rtos_delete_thread(NULL);
}
void HTTPServer_Start()
{
OSStatus err = kNoErr;
OSStatus err = kNoErr;
err = rtos_create_thread( &g_http_thread, BEKEN_APPLICATION_PRIORITY,
"TCP_server",
(beken_thread_function_t)tcp_server_thread,
0x800,
(beken_thread_arg_t)0 );
if(err != kNoErr)
{
ADDLOG_ERROR(LOG_FEATURE_HTTP, "create \"TCP_server\" thread failed with %i!\r\n",err);
}
err = rtos_create_thread(&g_http_thread, BEKEN_APPLICATION_PRIORITY,
"TCP_server",
(beken_thread_function_t)tcp_server_thread,
0x800,
(beken_thread_arg_t)0);
if (err != kNoErr)
{
ADDLOG_ERROR(LOG_FEATURE_HTTP, "create \"TCP_server\" thread failed with %i!\r\n", err);
}
}

View File

@ -14,65 +14,65 @@
// define the feature ADDLOGF_XXX will use
#define LOG_FEATURE LOG_FEATURE_HTTP
const char httpHeader[] = "HTTP/1.1 %d OK\nContent-type: %s" ; // HTTP header
const char httpMimeTypeHTML[] = "text/html" ; // HTML MIME type
const char httpMimeTypeText[] = "text/plain" ; // TEXT MIME type
const char httpMimeTypeJson[] = "application/json" ; // TEXT MIME type
const char httpMimeTypeBinary[] = "application/octet-stream" ; // binary/file MIME type
const char httpHeader[] = "HTTP/1.1 %d OK\nContent-type: %s"; // HTTP header
const char httpMimeTypeHTML[] = "text/html"; // HTML MIME type
const char httpMimeTypeText[] = "text/plain"; // TEXT MIME type
const char httpMimeTypeJson[] = "application/json"; // TEXT MIME type
const char httpMimeTypeBinary[] = "application/octet-stream"; // binary/file MIME type
const char htmlDoctype[] =
"<!DOCTYPE html><html>";
"<!DOCTYPE html><html>";
const char htmlHeadMain[] =
"<meta charset=\"utf-8\">"
"<meta name=\"viewport\" content=\"width=device-width,initial-scale=1,user-scalable=no\">"
"<meta name=\"robots\" content=\"none\">";
"<meta charset=\"utf-8\">"
"<meta name=\"viewport\" content=\"width=device-width,initial-scale=1,user-scalable=no\">"
"<meta name=\"robots\" content=\"none\">";
const char htmlBodyStart[] =
"<body>"
"<noscript>To use this device, please enable JavaScript.<br></noscript>"
"<div id=\"main\">"
"<h1>"
"<a target=\"_blank\" href=\"https://github.com/openshwprojects/OpenBK7231T_App/\">";
"<body>"
"<noscript>To use this device, please enable JavaScript.<br></noscript>"
"<div id=\"main\">"
"<h1>"
"<a target=\"_blank\" href=\"https://github.com/openshwprojects/OpenBK7231T_App/\">";
const char htmlBodyStart2[] =
"</a></h1>";
const char htmlBodyEnd[] = "</div></body></html>" ;
"</a></h1>";
const char htmlBodyEnd[] = "</div></body></html>";
const char htmlFooterReturnToMenu[] = "<a href=\"index\">Return to menu</a>";
const char htmlFooterRefreshLink[] = "<a href=\"index\">Refresh</a>";
const char htmlFooterReturnToCfgLink[] = "<a href=\"cfg\">Return to cfg</a>";
const char htmlFooterInfo[] =
"<a target=\"_blank\" "
"href=\"https://www.elektroda.com/rtvforum/"
"viewtopic.php?p=19841301#19841301\">Read more</a> | "
"<a target=\"_blank\" "
"href=\"https://paypal.me/openshwprojects\">Support project</a><br>";
"<a target=\"_blank\" "
"href=\"https://www.elektroda.com/rtvforum/"
"viewtopic.php?p=19841301#19841301\">Read more</a> | "
"<a target=\"_blank\" "
"href=\"https://paypal.me/openshwprojects\">Support project</a><br>";
// make sure that USER_SW_VER is set on all platforms
// Automatic Github builds are setting it externally,
// but it may not be set while doing a test build on developer PC
#ifndef USER_SW_VER
#ifdef WINDOWS
#define USER_SW_VER "Win_Test"
#elif PLATFORM_XR809
#define USER_SW_VER "XR809_Test"
#elif defined(PLATFORM_BK7231N)
#define USER_SW_VER "BK7231N_Test"
#elif defined(PLATFORM_BK7231T)
#define USER_SW_VER "BK7231T_Test"
#elif defined(PLATFORM_BL602)
#define USER_SW_VER "BL602_Test"
#elif defined(PLATFORM_W600)
#define USER_SW_VER "W600_Test"
#elif defined(PLATFORM_W800)
#define USER_SW_VER "W800_Test"
#else
#define USER_SW_VER "unknown"
#endif
#ifdef WINDOWS
#define USER_SW_VER "Win_Test"
#elif PLATFORM_XR809
#define USER_SW_VER "XR809_Test"
#elif defined(PLATFORM_BK7231N)
#define USER_SW_VER "BK7231N_Test"
#elif defined(PLATFORM_BK7231T)
#define USER_SW_VER "BK7231T_Test"
#elif defined(PLATFORM_BL602)
#define USER_SW_VER "BL602_Test"
#elif defined(PLATFORM_W600)
#define USER_SW_VER "W600_Test"
#elif defined(PLATFORM_W800)
#define USER_SW_VER "W800_Test"
#else
#define USER_SW_VER "unknown"
#endif
const char *g_build_str = "Build on " __DATE__ " " __TIME__ " version " USER_SW_VER; // Show GIT version at Build line;
#endif
const char* g_build_str = "Build on " __DATE__ " " __TIME__ " version " USER_SW_VER; // Show GIT version at Build line;
const char httpCorsHeaders[] = "Access-Control-Allow-Origin: *\r\nAccess-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept" ; // TEXT MIME type
const char httpCorsHeaders[] = "Access-Control-Allow-Origin: *\r\nAccess-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept"; // TEXT MIME type
const char *methodNames[] = {
const char* methodNames[] = {
"GET",
"PUT",
"POST",
@ -80,36 +80,36 @@ const char *methodNames[] = {
};
#if WINDOWS
#define os_free free
#define os_malloc malloc
#define os_free free
#define os_malloc malloc
#endif
void misc_formatUpTimeString(int totalSeconds, char *o);
void misc_formatUpTimeString(int totalSeconds, char* o);
int Time_getUpTimeSeconds();
typedef struct http_callback_tag {
char *url;
int method;
http_callback_fn callback;
char* url;
int method;
http_callback_fn callback;
} http_callback_t;
#define MAX_HTTP_CALLBACKS 32
static http_callback_t *callbacks[MAX_HTTP_CALLBACKS];
static http_callback_t* callbacks[MAX_HTTP_CALLBACKS];
static int numCallbacks = 0;
int HTTP_RegisterCallback( const char *url, int method, http_callback_fn callback){
if (!url || !callback){
int HTTP_RegisterCallback(const char* url, int method, http_callback_fn callback) {
if (!url || !callback) {
return -1;
}
if (numCallbacks >= MAX_HTTP_CALLBACKS){
if (numCallbacks >= MAX_HTTP_CALLBACKS) {
return -4;
}
callbacks[numCallbacks] = (http_callback_t*)os_malloc(sizeof(http_callback_t));
if (!callbacks[numCallbacks]){
if (!callbacks[numCallbacks]) {
return -2;
}
callbacks[numCallbacks]->url = (char *)os_malloc(strlen(url)+1);
if (!callbacks[numCallbacks]->url){
callbacks[numCallbacks]->url = (char*)os_malloc(strlen(url) + 1);
if (!callbacks[numCallbacks]->url) {
os_free(callbacks[numCallbacks]);
return -3;
}
@ -123,9 +123,9 @@ int HTTP_RegisterCallback( const char *url, int method, http_callback_fn callbac
return 0;
}
int my_strnicmp(char *a, char *b, int len){
int my_strnicmp(char* a, char* b, int len) {
int i;
for (i = 0; i < len; i++){
for (i = 0; i < len; i++) {
char x = *a;
char y = *b;
if (!x || !y) return 1;
@ -136,11 +136,11 @@ int my_strnicmp(char *a, char *b, int len){
return 0;
}
bool http_startsWith(const char *base, const char *substr) {
while(*substr != 0) {
if(*base != *substr)
bool http_startsWith(const char* base, const char* substr) {
while (*substr != 0) {
if (*base != *substr)
return false;
if(*base == 0)
if (*base == 0)
return false;
base++;
substr++;
@ -148,29 +148,29 @@ bool http_startsWith(const char *base, const char *substr) {
return true;
}
bool http_checkUrlBase(const char *base, const char *fileName) {
while(*base != 0 && *base != '?' && *base != ' ') {
if(*base != *fileName)
bool http_checkUrlBase(const char* base, const char* fileName) {
while (*base != 0 && *base != '?' && *base != ' ') {
if (*base != *fileName)
return false;
if(*base == 0)
if (*base == 0)
return false;
base++;
fileName++;
}
if(*fileName != 0)
if (*fileName != 0)
return false;
return true;
}
void http_setup(http_request_t *request, const char *type){
void http_setup(http_request_t* request, const char* type) {
hprintf128(request, httpHeader, request->responseCode, type);
poststr(request,"\r\n"); // next header
poststr(request,httpCorsHeaders);
poststr(request,"\r\n"); // end headers with double CRLF
poststr(request,"\r\n");
poststr(request, "\r\n"); // next header
poststr(request, httpCorsHeaders);
poststr(request, "\r\n"); // end headers with double CRLF
poststr(request, "\r\n");
}
void http_html_start(http_request_t *request, const char *pagename) {
void http_html_start(http_request_t* request, const char* pagename) {
poststr(request, htmlDoctype);
poststr(request, "<title>");
poststr(request, CFG_GetDeviceName()); // todo: check escaping
@ -186,7 +186,7 @@ void http_html_start(http_request_t *request, const char *pagename) {
poststr(request, htmlBodyStart2);
}
void http_html_end(http_request_t *request) {
void http_html_end(http_request_t* request) {
char upTimeStr[128];
unsigned char mac[32];
@ -197,22 +197,22 @@ void http_html_end(http_request_t *request) {
hprintf128(request, "<br>Online for&nbsp;<span id=\"onlineFor\" data-initial=\"%i\">-</span>", Time_getUpTimeSeconds());
WiFI_GetMacAddress((char *)mac);
WiFI_GetMacAddress((char*)mac);
sprintf(upTimeStr, "<br>Device MAC: %02X:%02X:%02X:%02X:%02X:%02X",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
sprintf(upTimeStr, "<br>Device MAC: %02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
poststr(request, upTimeStr);
sprintf(upTimeStr, "<br>Short name: %s, Chipset %s",CFG_GetShortDeviceName(),PLATFORM_MCU_NAME);
sprintf(upTimeStr, "<br>Short name: %s, Chipset %s", CFG_GetShortDeviceName(), PLATFORM_MCU_NAME);
poststr(request, upTimeStr);
poststr(request, htmlBodyEnd);
poststr(request, pageScript);
}
const char *http_checkArg(const char *p, const char *n) {
while(1) {
if(*n == 0 && (*p == 0 || *p == '='))
const char* http_checkArg(const char* p, const char* n) {
while (1) {
if (*n == 0 && (*p == 0 || *p == '='))
return p;
if(*p != *n)
if (*p != *n)
return 0;
p++;
n++;
@ -220,63 +220,65 @@ const char *http_checkArg(const char *p, const char *n) {
return p;
}
void http_copyCarg(const char *atin, char *to, int maxSize) {
void http_copyCarg(const char* atin, char* to, int maxSize) {
int a, b;
const unsigned char *at = (unsigned char *)atin;
const unsigned char* at = (unsigned char*)atin;
while(*at != 0 && *at != '&' && *at != ' ' && maxSize > 1) {
while (*at != 0 && *at != '&' && *at != ' ' && maxSize > 1) {
#if 0
*to = *at;
* to = *at;
to++;
at++;
maxSize--;
#else
if ((*at == '%') &&
((a = at[1]) && (b = at[2])) &&
(isxdigit(a) && isxdigit(b))) {
if (a >= 'a')
a -= 'a'-'A';
if (a >= 'A')
a -= ('A' - 10);
else
a -= '0';
if (b >= 'a')
b -= 'a'-'A';
if (b >= 'A')
b -= ('A' - 10);
else
b -= '0';
*to++ = 16*a+b;
at+=3;
} else if (*at == '+') {
*to++ = ' ';
at++;
} else {
*to++ = *at++;
}
if ((*at == '%') &&
((a = at[1]) && (b = at[2])) &&
(isxdigit(a) && isxdigit(b))) {
if (a >= 'a')
a -= 'a' - 'A';
if (a >= 'A')
a -= ('A' - 10);
else
a -= '0';
if (b >= 'a')
b -= 'a' - 'A';
if (b >= 'A')
b -= ('A' - 10);
else
b -= '0';
*to++ = 16 * a + b;
at += 3;
}
else if (*at == '+') {
*to++ = ' ';
at++;
}
else {
*to++ = *at++;
}
maxSize--;
#endif
}
*to = 0;
}
int http_getArg(const char *base, const char *name, char *o, int maxSize) {
int http_getArg(const char* base, const char* name, char* o, int maxSize) {
*o = '\0';
while(*base != '?') {
if(*base == 0)
while (*base != '?') {
if (*base == 0)
return 0;
base++;
}
base++;
while(*base) {
const char *at = http_checkArg(base,name);
if(at) {
while (*base) {
const char* at = http_checkArg(base, name);
if (at) {
at++;
http_copyCarg(at,o,maxSize);
http_copyCarg(at, o, maxSize);
return 1;
}
while(*base != '&') {
if(*base == 0) {
while (*base != '&') {
if (*base == 0) {
return 0;
}
base++;
@ -285,14 +287,14 @@ int http_getArg(const char *base, const char *name, char *o, int maxSize) {
}
return 0;
}
int http_getArgInteger(const char *base, const char *name) {
int http_getArgInteger(const char* base, const char* name) {
char tmp[16];
if(http_getArg(base,name,tmp,sizeof(tmp))==0)
if (http_getArg(base, name, tmp, sizeof(tmp)) == 0)
return 0;
return atoi(tmp);
}
const char *htmlPinRoleNames[] = {
const char* htmlPinRoleNames[] = {
" ",
"Rel",
"Rel_n",
@ -330,52 +332,52 @@ const char *htmlPinRoleNames[] = {
"error",
};
int PIN_ParsePinRoleName(const char *name) {
int PIN_ParsePinRoleName(const char* name) {
int i;
for(i = 0; i < IOR_Total_Options; i++) {
if(!stricmp(name,htmlPinRoleNames[i]))
for (i = 0; i < IOR_Total_Options; i++) {
if (!stricmp(name, htmlPinRoleNames[i]))
return i;
}
return IOR_Total_Options;
}
void setupAllWB2SPinsAsButtons() {
PIN_SetPinRoleForPinIndex(6,IOR_Button);
PIN_SetPinChannelForPinIndex(6,1);
PIN_SetPinRoleForPinIndex(6, IOR_Button);
PIN_SetPinChannelForPinIndex(6, 1);
PIN_SetPinRoleForPinIndex(7,IOR_Button);
PIN_SetPinChannelForPinIndex(7,1);
PIN_SetPinRoleForPinIndex(7, IOR_Button);
PIN_SetPinChannelForPinIndex(7, 1);
PIN_SetPinRoleForPinIndex(8,IOR_Button);
PIN_SetPinChannelForPinIndex(8,1);
PIN_SetPinRoleForPinIndex(8, IOR_Button);
PIN_SetPinChannelForPinIndex(8, 1);
PIN_SetPinRoleForPinIndex(23,IOR_Button);
PIN_SetPinChannelForPinIndex(23,1);
PIN_SetPinRoleForPinIndex(23, IOR_Button);
PIN_SetPinChannelForPinIndex(23, 1);
PIN_SetPinRoleForPinIndex(24,IOR_Button);
PIN_SetPinChannelForPinIndex(24,1);
PIN_SetPinRoleForPinIndex(24, IOR_Button);
PIN_SetPinChannelForPinIndex(24, 1);
PIN_SetPinRoleForPinIndex(26,IOR_Button);
PIN_SetPinChannelForPinIndex(26,1);
PIN_SetPinRoleForPinIndex(26, IOR_Button);
PIN_SetPinChannelForPinIndex(26, 1);
PIN_SetPinRoleForPinIndex(27,IOR_Button);
PIN_SetPinChannelForPinIndex(27,1);
PIN_SetPinRoleForPinIndex(27, IOR_Button);
PIN_SetPinChannelForPinIndex(27, 1);
}
// add some more output safely, sending if necessary.
// call with str == NULL to force send. - can be binary.
// supply length
int postany(http_request_t *request, const char *str, int len){
int postany(http_request_t* request, const char* str, int len) {
#if PLATFORM_BL602
send(request->fd,str,len,0);
send(request->fd, str, len, 0);
return 0;
#else
int currentlen;
int addlen = len;
if (NULL == str){
if(request->replylen > 0) {
if (NULL == str) {
if (request->replylen > 0) {
send(request->fd, request->reply, request->replylen, 0);
}
request->reply[0] = 0;
@ -384,25 +386,25 @@ int postany(http_request_t *request, const char *str, int len){
}
currentlen = request->replylen;
if (currentlen + addlen >= request->replymaxlen){
if (currentlen + addlen >= request->replymaxlen) {
send(request->fd, request->reply, request->replylen, 0);
request->reply[0] = 0;
request->replylen = 0;
currentlen = 0;
}
while (addlen >= request->replymaxlen){
if(request->replylen > 0) {
while (addlen >= request->replymaxlen) {
if (request->replylen > 0) {
send(request->fd, request->reply, request->replylen, 0);
request->replylen = 0;
}
send(request->fd, str, (request->replymaxlen-1), 0);
addlen -= (request->replymaxlen-1);
str += (request->replymaxlen-1);
send(request->fd, str, (request->replymaxlen - 1), 0);
addlen -= (request->replymaxlen - 1);
str += (request->replymaxlen - 1);
rtos_delay_milliseconds(1);
}
memcpy( request->reply+request->replylen, str, addlen );
memcpy(request->reply + request->replylen, str, addlen);
request->replylen += addlen;
return (currentlen + addlen);
#endif
@ -411,16 +413,16 @@ int postany(http_request_t *request, const char *str, int len){
// add some more output safely, sending if necessary.
// call with str == NULL to force send.
int poststr(http_request_t *request, const char *str){
if (str == NULL){
int poststr(http_request_t* request, const char* str) {
if (str == NULL) {
return postany(request, NULL, 0);
}
return postany(request, str, strlen(str));
}
int hprintf128(http_request_t *request, const char *fmt, ...){
va_list argList;
//BaseType_t taken;
int hprintf128(http_request_t* request, const char* fmt, ...) {
va_list argList;
//BaseType_t taken;
char tmp[256];
va_start(argList, fmt);
vsprintf(tmp, fmt, argList);
@ -429,39 +431,40 @@ int hprintf128(http_request_t *request, const char *fmt, ...){
}
int HTTP_ProcessPacket(http_request_t *request) {
int HTTP_ProcessPacket(http_request_t* request) {
int i;
char *p;
char *headers;
char *protocol;
char* p;
char* headers;
char* protocol;
//int bChanged = 0;
char *urlStr = "";
char* urlStr = "";
if (request->received == 0){
if (request->received == 0) {
ADDLOGF_ERROR("You gave request with NULL input");
return 0;
}
char *recvbuf = request->received;
for ( i = 0; i < sizeof(methodNames)/sizeof(*methodNames); i++){
if (http_startsWith(recvbuf, methodNames[i])){
char* recvbuf = request->received;
for (i = 0; i < sizeof(methodNames) / sizeof(*methodNames); i++) {
if (http_startsWith(recvbuf, methodNames[i])) {
urlStr = recvbuf + strlen(methodNames[i]) + 2; // skip method name plus space, plus slash
request->method = i;
break;
}
}
if (request->method == -1){
if (request->method == -1) {
ADDLOGF_ERROR("unsupported method %7s", recvbuf);
return 0;
}
if (request->reply == 0){
if (request->reply == 0) {
ADDLOGF_ERROR("You gave request with NULL buffer");
return 0;
}
if (request->method == HTTP_GET) {
//ADDLOG_INFO(LOG_FEATURE_HTTP, "HTTP request\n");
} else {
}
else {
//ADDLOG_INFO(LOG_FEATURE_HTTP, "Other request\n");
}
@ -492,7 +495,8 @@ int HTTP_ProcessPacket(http_request_t *request) {
*p = '\0';
p++; // past \r
p++; // past \n
} else {
}
else {
ADDLOGF_ERROR("invalid request\n");
return 0;
}
@ -501,14 +505,14 @@ int HTTP_ProcessPacket(http_request_t *request) {
headers = p;
do {
p = strchr(headers, '\r');
if (p != headers){
if (p){
if (request->numheaders < 16){
if (p != headers) {
if (p) {
if (request->numheaders < 16) {
request->headers[request->numheaders] = headers;
request->numheaders++;
}
// pick out contentLength
if (!my_strnicmp(headers, "Content-Length:", 15)){
if (!my_strnicmp(headers, "Content-Length:", 15)) {
request->contentLength = atoi(headers + 15);
}
@ -516,78 +520,79 @@ int HTTP_ProcessPacket(http_request_t *request) {
p++; // past \r
p++; // past \n
headers = p;
} else {
}
else {
break;
}
}
if (*p == '\r'){
if (*p == '\r') {
// end of headers
*p = 0;
p++;
p++;
break;
}
} while(1);
} while (1);
request->bodystart = p;
request->bodylen = request->receivedLen - (p - request->received);
#if 0
postany(request,"test",4);
postany(request, "test", 4);
return 0;
#elif 0
return http_fn_empty_url(request);
#endif
// look for a callback with this URL and method, or HTTP_ANY
for (i = 0; i < numCallbacks; i++){
char *url = callbacks[i]->url;
if (http_startsWith(urlStr, &url[1])){
for (i = 0; i < numCallbacks; i++) {
char* url = callbacks[i]->url;
if (http_startsWith(urlStr, &url[1])) {
int method = callbacks[i]->method;
if(method == HTTP_ANY || method == request->method){
if (method == HTTP_ANY || method == request->method) {
return callbacks[i]->callback(request);
}
}
}
if(http_checkUrlBase(urlStr,"")) return http_fn_empty_url(request);
if (http_checkUrlBase(urlStr, "")) return http_fn_empty_url(request);
if(http_checkUrlBase(urlStr,"testmsg")) return http_fn_testmsg(request);
if(http_checkUrlBase(urlStr,"index")) return http_fn_index(request);
if (http_checkUrlBase(urlStr, "testmsg")) return http_fn_testmsg(request);
if (http_checkUrlBase(urlStr, "index")) return http_fn_index(request);
if(http_checkUrlBase(urlStr,"about")) return http_fn_about(request);
if (http_checkUrlBase(urlStr, "about")) return http_fn_about(request);
if(http_checkUrlBase(urlStr,"cfg_mqtt")) return http_fn_cfg_mqtt(request);
if(http_checkUrlBase(urlStr,"cfg_mqtt_set")) return http_fn_cfg_mqtt_set(request);
if (http_checkUrlBase(urlStr, "cfg_mqtt")) return http_fn_cfg_mqtt(request);
if (http_checkUrlBase(urlStr, "cfg_mqtt_set")) return http_fn_cfg_mqtt_set(request);
if(http_checkUrlBase(urlStr,"cfg_webapp")) return http_fn_cfg_webapp(request);
if(http_checkUrlBase(urlStr,"cfg_webapp_set")) return http_fn_cfg_webapp_set(request);
if (http_checkUrlBase(urlStr, "cfg_webapp")) return http_fn_cfg_webapp(request);
if (http_checkUrlBase(urlStr, "cfg_webapp_set")) return http_fn_cfg_webapp_set(request);
if(http_checkUrlBase(urlStr,"cfg_wifi")) return http_fn_cfg_wifi(request);
if(http_checkUrlBase(urlStr,"cfg_name")) return http_fn_cfg_name(request);
if(http_checkUrlBase(urlStr,"cfg_wifi_set")) return http_fn_cfg_wifi_set(request);
if (http_checkUrlBase(urlStr, "cfg_wifi")) return http_fn_cfg_wifi(request);
if (http_checkUrlBase(urlStr, "cfg_name")) return http_fn_cfg_name(request);
if (http_checkUrlBase(urlStr, "cfg_wifi_set")) return http_fn_cfg_wifi_set(request);
if(http_checkUrlBase(urlStr,"cfg_loglevel_set")) return http_fn_cfg_loglevel_set(request);
if(http_checkUrlBase(urlStr,"cfg_mac")) return http_fn_cfg_mac(request);
if (http_checkUrlBase(urlStr, "cfg_loglevel_set")) return http_fn_cfg_loglevel_set(request);
if (http_checkUrlBase(urlStr, "cfg_mac")) return http_fn_cfg_mac(request);
if(http_checkUrlBase(urlStr,"flash_read_tool")) return http_fn_flash_read_tool(request);
if(http_checkUrlBase(urlStr,"uart_tool")) return http_fn_uart_tool(request);
if(http_checkUrlBase(urlStr,"cmd_tool")) return http_fn_cmd_tool(request);
if(http_checkUrlBase(urlStr,"config_dump_table")) return http_fn_config_dump_table(request);
if(http_checkUrlBase(urlStr,"startup_command")) return http_fn_startup_command(request);
if(http_checkUrlBase(urlStr,"cfg_generic")) return http_fn_cfg_generic(request);
if(http_checkUrlBase(urlStr,"cfg_startup")) return http_fn_cfg_startup(request);
if(http_checkUrlBase(urlStr,"cfg_dgr")) return http_fn_cfg_dgr(request);
if (http_checkUrlBase(urlStr, "flash_read_tool")) return http_fn_flash_read_tool(request);
if (http_checkUrlBase(urlStr, "uart_tool")) return http_fn_uart_tool(request);
if (http_checkUrlBase(urlStr, "cmd_tool")) return http_fn_cmd_tool(request);
if (http_checkUrlBase(urlStr, "config_dump_table")) return http_fn_config_dump_table(request);
if (http_checkUrlBase(urlStr, "startup_command")) return http_fn_startup_command(request);
if (http_checkUrlBase(urlStr, "cfg_generic")) return http_fn_cfg_generic(request);
if (http_checkUrlBase(urlStr, "cfg_startup")) return http_fn_cfg_startup(request);
if (http_checkUrlBase(urlStr, "cfg_dgr")) return http_fn_cfg_dgr(request);
if(http_checkUrlBase(urlStr,"cfg_quick")) return http_fn_cfg_quick(request);
if(http_checkUrlBase(urlStr,"ha_cfg")) return http_fn_ha_cfg(request);
if(http_checkUrlBase(urlStr,"ha_discovery")) return http_fn_ha_discovery(request);
if(http_checkUrlBase(urlStr,"cfg")) return http_fn_cfg(request);
if (http_checkUrlBase(urlStr, "cfg_quick")) return http_fn_cfg_quick(request);
if (http_checkUrlBase(urlStr, "ha_cfg")) return http_fn_ha_cfg(request);
if (http_checkUrlBase(urlStr, "ha_discovery")) return http_fn_ha_discovery(request);
if (http_checkUrlBase(urlStr, "cfg")) return http_fn_cfg(request);
if(http_checkUrlBase(urlStr,"cfg_pins")) return http_fn_cfg_pins(request);
if(http_checkUrlBase(urlStr,"cfg_ping")) return http_fn_cfg_ping(request);
if (http_checkUrlBase(urlStr, "cfg_pins")) return http_fn_cfg_pins(request);
if (http_checkUrlBase(urlStr, "cfg_ping")) return http_fn_cfg_ping(request);
if(http_checkUrlBase(urlStr,"ota")) return http_fn_ota(request);
if(http_checkUrlBase(urlStr,"ota_exec")) return http_fn_ota_exec(request);
if(http_checkUrlBase(urlStr,"cm")) return http_fn_cm(request);
if (http_checkUrlBase(urlStr, "ota")) return http_fn_ota(request);
if (http_checkUrlBase(urlStr, "ota_exec")) return http_fn_ota_exec(request);
if (http_checkUrlBase(urlStr, "cm")) return http_fn_cm(request);
return http_fn_other(request);
}
@ -603,13 +608,13 @@ And then run `gulp` which will automatically update the fields.
*/
//region_start htmlHeadStyle
const char htmlHeadStyle[]="<style>div,fieldset,input,select{padding:5px;font-size:1em;margin:0 0 .2em}fieldset{background:#4f4f4f}p{margin:.5em 0}input{width:100%;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;background:#ddd;color:#000}form{margin-bottom:.5em}input[type=checkbox],input[type=radio]{width:1em;margin-right:6px;vertical-align:-1px}input[type=range]{width:99%}select{width:100%;background:#ddd;color:#000}textarea{resize:vertical;width:98%;height:318px;padding:5px;overflow:auto;background:#1f1f1f;color:#65c115}body{text-align:center;font-family:verdana,sans-serif}body,h1 a{background:#21333e;color:#eaeaea}td{padding:0}button,input[type=submit]{border:0;border-radius:.3rem;background:#1fa3ec;color:#faffff;line-height:2.4rem;font-size:1.2rem;cursor:pointer}input[type=submit]{width:100%;transition-duration:.4s}input[type=submit]:hover{background:#0e70a4}.bred{background:#d43535!important}.bred:hover{background:#931f1f!important}.bgrn{background:#47c266!important}.bgrn:hover{background:#5aaf6f!important}a{color:#1fa3ec;text-decoration:none}.p{float:left;text-align:left}.q{float:right;text-align:right}.r{border-radius:.3em;padding:2px;margin:6px 2px}.hf{display:none}.hdiv{width:95%;white-space:nowrap}.hele{width:210px;display:inline-block;margin-left:2px}div#state{padding:0}div#changed{padding:0;height:23px}div#main{text-align:left;display:inline-block;color:#eaeaea;min-width:340px;max-width:800px}table{table-layout:fixed}</style>";
const char htmlHeadStyle[] = "<style>div,fieldset,input,select{padding:5px;font-size:1em;margin:0 0 .2em}fieldset{background:#4f4f4f}p{margin:.5em 0}input{width:100%;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;background:#ddd;color:#000}form{margin-bottom:.5em}input[type=checkbox],input[type=radio]{width:1em;margin-right:6px;vertical-align:-1px}input[type=range]{width:99%}select{width:100%;background:#ddd;color:#000}textarea{resize:vertical;width:98%;height:318px;padding:5px;overflow:auto;background:#1f1f1f;color:#65c115}body{text-align:center;font-family:verdana,sans-serif}body,h1 a{background:#21333e;color:#eaeaea}td{padding:0}button,input[type=submit]{border:0;border-radius:.3rem;background:#1fa3ec;color:#faffff;line-height:2.4rem;font-size:1.2rem;cursor:pointer}input[type=submit]{width:100%;transition-duration:.4s}input[type=submit]:hover{background:#0e70a4}.bred{background:#d43535!important}.bred:hover{background:#931f1f!important}.bgrn{background:#47c266!important}.bgrn:hover{background:#5aaf6f!important}a{color:#1fa3ec;text-decoration:none}.p{float:left;text-align:left}.q{float:right;text-align:right}.r{border-radius:.3em;padding:2px;margin:6px 2px}.hf{display:none}.hdiv{width:95%;white-space:nowrap}.hele{width:210px;display:inline-block;margin-left:2px}div#state{padding:0}div#changed{padding:0;height:23px}div#main{text-align:left;display:inline-block;color:#eaeaea;min-width:340px;max-width:800px}table{table-layout:fixed}</style>";
//region_end htmlHeadStyle
//region_start pageScript
const char pageScript[]="<script type='text/javascript'>var firstTime,lastTime,onlineFor,req=null,onlineForEl=null,getElement=e=>document.getElementById(e);function showState(){clearTimeout(firstTime),clearTimeout(lastTime),null!=req&&req.abort(),(req=new XMLHttpRequest).onreadystatechange=()=>{4==req.readyState&&200==req.status&&((\"INPUT\"!=document.activeElement.tagName||\"number\"!=document.activeElement.type&&\"color\"!=document.activeElement.type)&&(getElement(\"state\").innerHTML=req.responseText),clearTimeout(firstTime),clearTimeout(lastTime),lastTime=setTimeout(showState,3e3))},req.open(\"GET\",\"index?state=1\",!0),req.send(),firstTime=setTimeout(showState,3e3)}function fmtUpTime(e){var t,n,o=Math.floor(e/86400);return e%=86400,t=Math.floor(e/3600),e%=3600,n=Math.floor(e/60),e=e%60,0<o?o+` days, ${t} hours, ${n} minutes and ${e} seconds`:0<t?t+` hours, ${n} minutes and ${e} seconds`:0<n?n+` minutes and ${e} seconds`:`just ${e} seconds`}function updateOnlineFor(){onlineForEl.textContent=fmtUpTime(++onlineFor)}function onLoad(){(onlineForEl=getElement(\"onlineFor\"))&&(onlineFor=parseInt(onlineForEl.dataset.initial,10))&&setInterval(updateOnlineFor,1e3),showState()}window.addEventListener(\"load\",onLoad),history.pushState(null,\"\",\"index\"),setTimeout(()=>{getElement(\"changed\").innerHTML=\"\"},5e3);</script>";
const char pageScript[] = "<script type='text/javascript'>var firstTime,lastTime,onlineFor,req=null,onlineForEl=null,getElement=e=>document.getElementById(e);function showState(){clearTimeout(firstTime),clearTimeout(lastTime),null!=req&&req.abort(),(req=new XMLHttpRequest).onreadystatechange=()=>{4==req.readyState&&200==req.status&&((\"INPUT\"!=document.activeElement.tagName||\"number\"!=document.activeElement.type&&\"color\"!=document.activeElement.type)&&(getElement(\"state\").innerHTML=req.responseText),clearTimeout(firstTime),clearTimeout(lastTime),lastTime=setTimeout(showState,3e3))},req.open(\"GET\",\"index?state=1\",!0),req.send(),firstTime=setTimeout(showState,3e3)}function fmtUpTime(e){var t,n,o=Math.floor(e/86400);return e%=86400,t=Math.floor(e/3600),e%=3600,n=Math.floor(e/60),e=e%60,0<o?o+` days, ${t} hours, ${n} minutes and ${e} seconds`:0<t?t+` hours, ${n} minutes and ${e} seconds`:0<n?n+` minutes and ${e} seconds`:`just ${e} seconds`}function updateOnlineFor(){onlineForEl.textContent=fmtUpTime(++onlineFor)}function onLoad(){(onlineForEl=getElement(\"onlineFor\"))&&(onlineFor=parseInt(onlineForEl.dataset.initial,10))&&setInterval(updateOnlineFor,1e3),showState()}window.addEventListener(\"load\",onLoad),history.pushState(null,\"\",\"index\"),setTimeout(()=>{getElement(\"changed\").innerHTML=\"\"},5e3);</script>";
//region_end pageScript
//region_start ha_discovery_script
const char ha_discovery_script[]="<script type='text/javascript'>function send_ha_disc(){var e=new XMLHttpRequest;e.open(\"GET\",\"/ha_discovery?prefix=\"+document.getElementById(\"ha_disc_topic\").value,!1),e.onload=function(){200===e.status?alert(\"MQTT discovery queued\"):404===e.status&&alert(\"Error invoking ha_discovery\")},e.onerror=function(){alert(\"Error invoking ha_discovery\")},e.send()}</script>";
const char ha_discovery_script[] = "<script type='text/javascript'>function send_ha_disc(){var e=new XMLHttpRequest;e.open(\"GET\",\"/ha_discovery?prefix=\"+document.getElementById(\"ha_disc_topic\").value,!1),e.onload=function(){200===e.status?alert(\"MQTT discovery queued\"):404===e.status&&alert(\"Error invoking ha_discovery\")},e.onerror=function(){alert(\"Error invoking ha_discovery\")},e.send()}</script>";
//region_end ha_discovery_script

View File

@ -12,9 +12,9 @@ extern const char htmlFooterReturnToMenu[];
extern const char htmlFooterRefreshLink[];
extern const char htmlFooterReturnToCfgLink[];
extern const char *htmlPinRoleNames[];
extern const char* htmlPinRoleNames[];
extern const char *g_build_str;
extern const char* g_build_str;
extern const char htmlHeadStyle[];
extern const char pageScript[];
@ -27,58 +27,58 @@ extern const char ha_discovery_script[];
#define MAX_QUERY 16
#define MAX_HEADERS 16
typedef struct http_request_tag {
char *received; // partial or whole received data, up to 1024
int receivedLen;
int receivedLenmax; // sizeof received
char* received; // partial or whole received data, up to 1024
int receivedLen;
int receivedLenmax; // sizeof received
// filled by HTTP_ProcessPacket
int method;
char *url;
int numqueryitems;
char *querynames[MAX_QUERY];
char *queryvalues[MAX_QUERY];
int numheaders;
char *headers[MAX_HEADERS];
char *bodystart; /// start start of the body (maybe all of it)
int bodylen;
int contentLength;
int responseCode;
// filled by HTTP_ProcessPacket
int method;
char* url;
int numqueryitems;
char* querynames[MAX_QUERY];
char* queryvalues[MAX_QUERY];
int numheaders;
char* headers[MAX_HEADERS];
char* bodystart; /// start start of the body (maybe all of it)
int bodylen;
int contentLength;
int responseCode;
// used to respond
char *reply;
int replylen;
int replymaxlen;
int fd;
// used to respond
char* reply;
int replylen;
int replymaxlen;
int fd;
} http_request_t;
int HTTP_ProcessPacket(http_request_t *request);
void http_setup(http_request_t *request, const char *type);
void http_html_start(http_request_t *request, const char *pagename);
void http_html_end(http_request_t *request);
int poststr(http_request_t *request, const char *str);
int postany(http_request_t *request, const char *str, int len);
void misc_formatUpTimeString(int totalSeconds, char *o);
int HTTP_ProcessPacket(http_request_t* request);
void http_setup(http_request_t* request, const char* type);
void http_html_start(http_request_t* request, const char* pagename);
void http_html_end(http_request_t* request);
int poststr(http_request_t* request, const char* str);
int postany(http_request_t* request, const char* str, int len);
void misc_formatUpTimeString(int totalSeconds, char* o);
// void HTTP_AddBuildFooter(http_request_t *request);
// void HTTP_AddHeader(http_request_t *request);
int http_getArg(const char *base, const char *name, char *o, int maxSize);
int http_getArgInteger(const char *base, const char *name);
int http_getArg(const char* base, const char* name, char* o, int maxSize);
int http_getArgInteger(const char* base, const char* name);
// poststr with format - for results LESS THAN 128
int hprintf128(http_request_t *request, const char *fmt, ...);
int hprintf128(http_request_t* request, const char* fmt, ...);
typedef enum {
HTTP_ANY = -1,
HTTP_GET = 0,
HTTP_PUT = 1,
HTTP_POST = 2,
HTTP_OPTIONS = 3
HTTP_ANY = -1,
HTTP_GET = 0,
HTTP_PUT = 1,
HTTP_POST = 2,
HTTP_OPTIONS = 3
} METHODS;
// callback function for http
typedef int (*http_callback_fn)(http_request_t *request);
typedef int (*http_callback_fn)(http_request_t* request);
// url MUST start with '/'
// urls must be unique (i.e. you can't have /about and /aboutme or /about/me)
int HTTP_RegisterCallback( const char *url, int method, http_callback_fn callback);
int HTTP_RegisterCallback(const char* url, int method, http_callback_fn callback);
#endif

File diff suppressed because it is too large Load Diff