9 Commits

9 changed files with 1074 additions and 971 deletions

View File

@@ -36,6 +36,11 @@
#include <http-strings.h>
#include "stdlib.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mico.h"
#include "httpd_priv.h"
#include "app_httpd.h"
@@ -430,19 +435,62 @@ static int HttpGetWifiConfig(httpd_request_t *req) {
return err;
}
// 单个十六进制字符转数字(安全)
static int hex_char_to_int(char c) {
if ('0' <= c && c <= '9') return c - '0';
if ('a' <= c && c <= 'f') return c - 'a' + 10;
if ('A' <= c && c <= 'F') return c - 'A' + 10;
return -1;
}
// 健壮版 URL 解码函数
void url_decode(const char *src, char *dest, size_t max_len) {
size_t i = 0;
while (*src && i < max_len - 1) {
if (*src == '%') {
if (isxdigit((unsigned char)src[1]) && isxdigit((unsigned char)src[2])) {
int high = hex_char_to_int(src[1]);
int low = hex_char_to_int(src[2]);
if (high >= 0 && low >= 0) {
dest[i++] = (char)((high << 4) | low);
src += 3;
continue;
}
}
// 非法编码,跳过 %
src++;
} else if (*src == '+') {
dest[i++] = ' ';
src++;
} else {
dest[i++] = *src++;
}
}
dest[i] = '\0';
}
static int HttpSetWifiConfig(httpd_request_t *req) {
OSStatus err = kNoErr;
int buf_size = 97;
char *buf = malloc(buf_size);
int mode = -1;
char *wifi_ssid = malloc(32);
char *wifi_key = malloc(32);
char *buf = malloc(256);
char *ssid_enc = malloc(128);
char *key_enc = malloc(128);
char *wifi_ssid = malloc(128);
char *wifi_key = malloc(128);
int mode = -1;
err = httpd_get_data(req, buf, buf_size);
err = httpd_get_data(req, buf, 256);
require_noerr(err, exit);
sscanf(buf, "%d %s %s", &mode, wifi_ssid, wifi_key);
// 假设 httpd_get_data(req, buf, 256);
// tc1_log("wifi config %s",buf);
sscanf(buf, "%d %s %s", &mode, ssid_enc, key_enc);
// tc1_log("wifi config %s %s",ssid_enc,key_enc);
url_decode(ssid_enc, wifi_ssid,128);
url_decode(key_enc, wifi_key,128);
// tc1_log("wifi config decode %s %s",wifi_ssid,wifi_key);
if (mode == 1) {
WifiConnect(wifi_ssid, wifi_key);
} else {

View File

@@ -73,7 +73,7 @@
#define POWER_INFO_JSON "{'sockets':'%s','idx':%d,'len':%d,'p_count':%ld,'powers':[%s],'up_time':'%s','led_enabled':%d,'total_switch_on':%d,'socketNames':'%s','p_count_1_day_ago':%d,'p_count_2_days_ago':%d,'child_lock_enabled':%d,'deviceName':'%s','btnClicks':%s}"
int AppHttpdStart(void);
extern int AppHttpdStart(void);
int AppHttpdStop();
extern int AppHttpdStop();

View File

@@ -31,7 +31,7 @@
<div class="demo-layout mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
<header class="demo-header mdl-layout__header">
<div class="mdl-layout__header-row">
<button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon edit-device-name">
<button class="mdl-button mdl-button--icon edit-device-name">
<i class="material-icons">
<svg>
<use xlink:href="#icon-edit"/>
@@ -40,7 +40,7 @@
</button>
<span class="mdl-layout-title">TC1智能插座</span>
<div class="mdl-layout-spacer"></div>
<!-- <button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button&#45;&#45;icon"-->
<!-- <button class="mdl-button mdl-button&#45;&#45;icon"-->
<!-- id="hdrbtn">-->
<!-- <i class="material-icons">-->
<!-- <svg>-->
@@ -55,7 +55,7 @@
<!-- <li class="mdl-menu__item" onclick="ChangeLanguage('jp')">日本語</li>-->
<!-- </ul>-->
<button onclick="reboot()"
class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon"
class="mdl-button mdl-button--icon"
id="rebootbtn">
<i class="material-icons">
<svg>
@@ -176,7 +176,7 @@
</li>
<li class="mdl-list__item">
<span class="mdl-list__item-primary-content">
<button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon edit-socket-name">
<button class="mdl-button mdl-button--icon edit-socket-name">
<i class="material-icons">
<svg>
<use xlink:href="#icon-edit"/>
@@ -195,7 +195,7 @@
</li>
<li class="mdl-list__item">
<span class="mdl-list__item-primary-content">
<button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon edit-socket-name">
<button class="mdl-button mdl-button--icon edit-socket-name">
<i class="material-icons">
<svg>
<use xlink:href="#icon-edit"/>
@@ -214,7 +214,7 @@
</li>
<li class="mdl-list__item">
<span class="mdl-list__item-primary-content">
<button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon edit-socket-name">
<button class="mdl-button mdl-button--icon edit-socket-name">
<i class="material-icons">
<svg>
<use xlink:href="#icon-edit"/>
@@ -233,7 +233,7 @@
</li>
<li class="mdl-list__item">
<span class="mdl-list__item-primary-content">
<button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon edit-socket-name">
<button class="mdl-button mdl-button--icon edit-socket-name">
<i class="material-icons">
<svg>
<use xlink:href="#icon-edit"/>
@@ -252,7 +252,7 @@
</li>
<li class="mdl-list__item">
<span class="mdl-list__item-primary-content">
<button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon edit-socket-name">
<button class="mdl-button mdl-button--icon edit-socket-name">
<i class="material-icons">
<svg>
<use xlink:href="#icon-edit"/>
@@ -271,7 +271,7 @@
</li>
<li class="mdl-list__item">
<span class="mdl-list__item-primary-content">
<button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon edit-socket-name">
<button class="mdl-button mdl-button--icon edit-socket-name">
<i class="material-icons">
<svg>
<use xlink:href="#icon-edit"/>
@@ -368,10 +368,10 @@
</form>
</div>
<div class="mdl-card__actions mdl-card--border">
<a id="wifi_submit"
class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
<button type="button" id="wifi_submit"
class="mdl-button mdl-button--colored ">
提交
</a>
</button>
</div>
</div>
@@ -401,10 +401,10 @@
</form>
</div>
<div class="mdl-card__actions mdl-card--border">
<a id="mqtt_submit"
class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
<button type="button" id="mqtt_submit"
class="mdl-button mdl-button--colored ">
提交
</a>
</button>
</div>
</div>
@@ -422,10 +422,10 @@
</form>
</div>
<div class="mdl-card__actions mdl-card--border">
<a id="mqtt_freq_submit"
class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
<button type="button" id="mqtt_freq_submit"
class="mdl-button mdl-button--colored ">
提交
</a>
</button>
</div>
</div>
@@ -438,20 +438,6 @@
<th>循环</th>
<th>操作</th>
</tr>
<tr>
<td>02-15 07:11</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td><a>删除</a></td>
</tr>
<tr>
<td>2020-02-15<br>07:11:08</td>
<td>1</td>
<td>0</td>
<td>6</td>
<td><a>删除</a></td>
</tr>
</table>
</div>
@@ -519,10 +505,10 @@
</form>
</div>
<div class="mdl-card__actions mdl-card--border">
<a href="javascript:AddTimedTask();"
class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
<button type="button" onclick="AddTimedTask();"
class="mdl-button mdl-button--colored ">
提交
</a>
</button>
</div>
</div>
@@ -598,10 +584,10 @@
</form>
</div>
<div class="mdl-card__actions mdl-card--border">
<a href="javascript:addButtonEvent();"
class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
<button type="button" onclick="addButtonEvent();"
class="mdl-button mdl-button--colored ">
添加
</a>
</button>
</div>
</div>
@@ -610,23 +596,23 @@
<table class="mdl-data-table mdl-js-data-table">
<tr>
<th>版本</th>
<th id="info_version">v1.0.33</th>
<th id="info_version"></th>
</tr>
<tr>
<td>IP</td>
<td id="info_ip">192.168.33.222</td>
<td id="info_ip"></td>
</tr>
<tr>
<td>子网掩码</td>
<td id="info_mask">255.255.255.0</td>
<td id="info_mask"></td>
</tr>
<tr>
<td>网关</td>
<td id="info_gateway">192.168.33.1</td>
<td id="info_gateway"></td>
</tr>
<tr>
<td>启动时间</td>
<td id="uptime">10:13:43</td>
<td id="uptime"></td>
</tr>
</table>
<div class="mdl-card__actions mdl-card--border" style="display: flex; align-items: center; flex-wrap: wrap;">
@@ -638,7 +624,7 @@
</svg>
</i>
<!-- <span>2020-02-22</span> -->
<a class="mdl-button" id="st-date">2020-02-22</a>
<a class="mdl-button" id="st-date"></a>
</div>
</div>
@@ -655,10 +641,10 @@
</form>
</div>
<div class="mdl-card__actions mdl-card--border">
<a href="javascript:OtaStart();"
class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
<button type="button" onclick="OtaStart();" id="submit-ota-link"
class="mdl-button mdl-button--colored ">
提交
</a>
</button>
</div>
<div id="ota_status" class="mdl-progress mdl-js-progress"></div>
</div>
@@ -675,10 +661,11 @@
</form>
</div>
<div class="mdl-card__actions mdl-card--border">
<a href="javascript:OtaFileUpload();" class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
<button type="button" onclick="OtaFileUpload();" class="mdl-button mdl-button--colored " id="submit-ota-file">
上传 OTA 文件
</a>
</button>
</div>
<div id="upload_status" class="mdl-progress mdl-js-progress"></div>
</div>
<div class="page page7 mdl-cell mdl-cell--12-col demo-card-square mdl-card mdl-shadow--2dp">
@@ -689,10 +676,10 @@
<pre id="sys_log"></pre>
</div>
<div class="mdl-card__actions mdl-card--border">
<a href="javascript:GetSysLog();"
class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
<button type="button" onclick="GetSysLog();"
class="mdl-button mdl-button--colored ">
刷新
</a>
</button>
</div>
</div>
@@ -1235,15 +1222,15 @@ componentHandler.upgradeDom();
var mode = $("#custom_station").prop("checked") ? 1 : 0;
var ssid = $("#custom_ssid").val();
var passwd = $("#custom_password").val();
if (ContainQM(ssid) || ContainQM(passwd)) {
alert(qm_mess);
return;
}
//if (ContainQM(ssid) || ContainQM(passwd)) {
// alert(qm_mess);
// return;
//}
if (passwd.length < 8) {
alert(le_mess);
return;
}
var params = mode + " " + ssid + " " + passwd;
var params = mode + " " + encodeURIComponent(ssid) + " " + encodeURIComponent(passwd);
HttpPost("/wifi/config", function (re) {
ShowToast(re);
}, params);
@@ -1504,28 +1491,50 @@ HttpPost("/shortClickEvent", function (re) {
var ota_url = document.getElementById("ota_url").value;
var protocol = window.location.protocol;
var baseUrl = protocol+"//"+window.location.host;
document.getElementById("submit-ota-link").disabled = true;
HttpPost("/ota", function (re) {
OtaStatus();
}, ota_url);
}
var upload_status = document.querySelector('#upload_status');
upload_status.addEventListener('mdl-componentupgraded', function() {
this.MaterialProgress.setProgress(0);
});
function OtaFileUpload() {
//alert("假的假的是假的,忽略");
//return;
var fileInput = document.getElementById("ota_file");
if (fileInput.files.length === 0) {
alert("请选择要上传的 OTA 文件");
ShowToast("请选择要上传的 OTA 文件");
return;
}
clearTimeout(powerTimerId);
console.log(fileInput.files[0].size); // 应显示 647168 左右
fetch("/ota/fileUpload", {
method: "POST",
headers: { "Content-Type": "application/octet-stream" },
body: fileInput.files[0]
}).then(r => r.text()).then(alert).catch(alert);
}
document.getElementById("submit-ota-file").disabled = true;
const xhr = new XMLHttpRequest();
xhr.open("POST", "/ota/fileUpload");
xhr.upload.onprogress = function (e) {
if (e.lengthComputable) {
let percent = (e.loaded / e.total * 100).toFixed(1);
upload_status.MaterialProgress.setProgress(percent);
console.log(`上传进度:${percent}%`);
}
};
xhr.onload = function () {
alert("上传完成:" + xhr.responseText);
document.getElementById("submit-ota-file").disabled = false;
};
xhr.onerror = function () {
alert("上传失败");
document.getElementById("submit-ota-file").disabled = false;
};
xhr.setRequestHeader("Content-Type", "application/octet-stream");
xhr.send(fileInput.files[0]);
}
var ota_status = document.querySelector('#ota_status');
ota_status.addEventListener('mdl-componentupgraded', function() {

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,8 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "mico.h"
#include"http_server/web_log.h"
@@ -36,6 +38,9 @@ char* GetLogRecord()
tmp += strlen(tmp);
if (!log_record.logs[i%LOG_NUM]) continue;
sprintf(tmp, "%s\n", log_record.logs[i%LOG_NUM]);
if(i == log_record.idx){
sprintf(tmp, "%s\nFreeMem %d bytes\n",log_record.logs[i%LOG_NUM],MicoGetMemoryInfo()->free_memory);
}
}
return log_record_str;
}

View File

@@ -208,8 +208,6 @@ int application_start(void) {
if (user_config->task_top && now >= user_config->task_top->prs_time) {
ProcessTask();
}
if (now % 10 == 5) system_log("Free memory %d bytes", MicoGetMemoryInfo()->free_memory);
mico_thread_msleep(1000);
}

View File

@@ -16,7 +16,7 @@
#define wifi_log(M, ...) custom_log("WIFI", M, ##__VA_ARGS__); web_log("WIFI", M, ##__VA_ARGS__);
#define power_log(M, ...) custom_log("POWER", M, ##__VA_ARGS__); web_log("POWER", M, ##__VA_ARGS__);
#define VERSION "v2.2.4"
#define VERSION "v2.2.0"
#define TYPE 1
#define TYPE_NAME "TC1"

View File

@@ -105,16 +105,26 @@ OSStatus UserMqttDeInit(void) {
// 1. 请求线程退出
mqtt_thread_should_exit = true;
exit:
if (kNoErr != err)
mqtt_log("ERROR: UserMqttDeInit exit err: %d", err);
return err;
}
void clear_mqtt_msg_send_queue(void) {
if(mqtt_msg_send_queue == NULL){
return;
}
void *msg = NULL;
while (mico_rtos_is_queue_empty(&mqtt_msg_send_queue) == false) {
if (mico_rtos_pop_from_queue(&mqtt_msg_send_queue, &msg, 0) == kNoErr) {
if (msg) free(msg); // 释放消息内存,避免泄漏
}
}
}
/* Application entrance */
OSStatus UserMqttInit(void) {
OSStatus err = kNoErr;
if(mqtt_msg_send_queue != NULL)
return err;
sprintf(topic_set, MQTT_CLIENT_SUB_TOPIC1);
sprintf(topic_state, MQTT_CLIENT_PUB_TOPIC, str_mac);
//TODO size:0x800
@@ -149,13 +159,32 @@ OSStatus UserMqttInit(void) {
static OSStatus UserMqttClientRelease(Client *c, Network *n) {
OSStatus err = kNoErr;
if (c->isconnected) MQTTDisconnect(c);
if (c == NULL || n == NULL) return kParamErr;
n->disconnect(n); // close connection
if (c->isconnected) {
MQTTDisconnect(c);
c->isconnected = 0;
}
if (MQTT_SUCCESS != MQTTClientDeinit(c)) { mqtt_log("MQTTClientDeinit failed!");
if (c->buf) {
free(c->buf);
c->buf = NULL;
}
if (c->readbuf) {
free(c->readbuf);
c->readbuf = NULL;
}
if (n->disconnect) {
n->disconnect(n);
}
if (MQTT_SUCCESS != MQTTClientDeinit(c)) {
mqtt_log("MQTTClientDeinit failed!");
err = kDeletedErr;
}
return err;
}
@@ -190,6 +219,9 @@ static OSStatus MqttMsgPublish(Client *c, const char *topic, char qos, char reta
}
void registerMqttEvents(void) {
if(timer_status !=0){
mico_stop_timer(&timer_handle);
}
timer_status = 0;
mico_start_timer(&timer_handle);
}
@@ -215,6 +247,8 @@ void MqttClientThread(mico_thread_arg_t arg) {
/* create msg send queue event fd */
msg_send_event_fd = mico_create_event_fd(mqtt_msg_send_queue);
mico_init_timer(&timer_handle, 150, UserMqttTimerFunc, &arg);
require_action(msg_send_event_fd >= 0, exit,
mqtt_log("ERROR: create msg send queue event fd failed!!!"));
mqtt_thread_should_exit = false;
@@ -241,7 +275,8 @@ void MqttClientThread(mico_thread_arg_t arg) {
if (rc == MQTT_SUCCESS) break;
//mqtt_log("ERROR: MQTT network connect err=%d, reconnect after 3s...", rc);
}mqtt_log("MQTT network connect success!");
}
mqtt_log("MQTT network connect success!");
/* 2. init mqtt client */
//c.heartbeat_retry_max = 2;
@@ -262,7 +297,7 @@ void MqttClientThread(mico_thread_arg_t arg) {
rc = MQTTConnect(&c, &connectData);
require_noerr_string(rc, MQTT_reconnect, "ERROR: MQTT client connect err.");
mqtt_log("MQTT client connect success!");
mqtt_log("MQTT client connect success, result: %d ", rc);
UserLedSet(RelayOut() && user_config->power_led_enabled);
@@ -282,7 +317,6 @@ void MqttClientThread(mico_thread_arg_t arg) {
UserMqttSendTotalSocketState();
UserMqttSendChildLockState();
mico_init_timer(&timer_handle, 150, UserMqttTimerFunc, &arg);
registerMqttEvents();
/* 5. client loop for recv msg && keepalive */
while (!mqtt_thread_should_exit) {
@@ -311,13 +345,12 @@ void MqttClientThread(mico_thread_arg_t arg) {
err = MqttMsgPublish(&c, p_send_msg->topic, p_send_msg->qos, p_send_msg->retained,
(const unsigned char *) p_send_msg->data,
p_send_msg->datalen);
free(p_send_msg);
p_send_msg = NULL;
require_noerr_string(err, MQTT_reconnect, "ERROR: MQTT publish data err");
//mqtt_log("MQTT publish data success! send_topic=[%s], msg=[%ld].", p_send_msg->topic, p_send_msg->datalen);
no_mqtt_msg_exchange = false;
free(p_send_msg);
p_send_msg = NULL;
}
}
@@ -333,7 +366,7 @@ void MqttClientThread(mico_thread_arg_t arg) {
mqtt_log("Disconnect MQTT client, and reconnect after 5s, reason: mqtt_rc = %d, err = %d", rc, err);
timer_status = 100;
clear_mqtt_msg_send_queue();
UserMqttClientRelease(&c, &n);
isconnect = false;
UserLedSet(-1);
@@ -438,7 +471,9 @@ void ProcessHaCmd(char *cmd) {
childLockEnabled = on;
UserMqttSendChildLockState();
mico_system_context_update(sys_config);
}else if (strcmp(cmd, "reboot") == 0) {
}else if (strcmp(cmd, "reboot") == ' ') {
sscanf(cmd, "reboot %s", mac);
if (strcmp(mac, str_mac)) return;
MicoSystemReboot(); // 立即重启设备
}
}
@@ -446,7 +481,7 @@ void ProcessHaCmd(char *cmd) {
OSStatus UserMqttSendTopic(char *topic, char *arg, char retained) {
OSStatus err = kUnknownErr;
p_mqtt_send_msg_t p_send_msg = NULL;
if(mqtt_msg_send_queue == NULL){
if(mqtt_msg_send_queue == NULL|| !isconnect){
return err;
}
@@ -593,13 +628,13 @@ void UserMqttHassAutoRebootButton(void) {
"\"uniq_id\":\"tc1_%s_reboot\","
"\"object_id\":\"tc1_%s_reboot\","
"\"cmd_t\":\"device/ztc1/set\","
"\"pl_prs\":\"reboot\","
"\"pl_prs\":\"reboot %s\","
"\"device\":{"
"\"identifiers\":[\"tc1_%s\"],"
"\"name\":\"%s\","
"\"model\":\"TC1\","
"\"manufacturer\":\"PHICOMM\"}}",
str_mac,str_mac,str_mac, sys_config->micoSystemConfig.name);
str_mac,str_mac,str_mac,str_mac, sys_config->micoSystemConfig.name);
UserMqttSendTopic(topic_buf, send_buf, 1);
}
if (send_buf) free(send_buf);
@@ -790,7 +825,7 @@ void UserMqttHassAutoPower(void) {
char topic_buf[128] = {0};
char send_buf[128] = {0};
void UserMqttHassPower(void) {
extern void UserMqttHassPower(void) {
sprintf(topic_buf, "homeassistant/sensor/%s/power/state", str_mac);
sprintf(send_buf, "{\"power\":\"%.3f\"}", real_time_power / 10);
UserMqttSendTopic(topic_buf, send_buf, 0);

View File

@@ -39,17 +39,11 @@ OSStatus system_discovery_init( system_context_t * const inContext )
init.service_name = "_easylink._tcp.local.";
/* name#xxxxxx.local. */
snprintf( temp_txt, 100, "%s#%c%c%c%c%c%c.local.", inContext->flashContentInRam.micoSystemConfig.name,
inContext->micoStatus.mac[9], inContext->micoStatus.mac[10], \
inContext->micoStatus.mac[12], inContext->micoStatus.mac[13], \
inContext->micoStatus.mac[15], inContext->micoStatus.mac[16] );
snprintf( temp_txt, 100, "%s.local.", inContext->flashContentInRam.micoSystemConfig.name);
init.host_name = (char*)__strdup(temp_txt);
/* name#xxxxxx. */
snprintf( temp_txt, 100, "%s#%c%c%c%c%c%c", inContext->flashContentInRam.micoSystemConfig.name,
inContext->micoStatus.mac[9], inContext->micoStatus.mac[10], \
inContext->micoStatus.mac[12], inContext->micoStatus.mac[13], \
inContext->micoStatus.mac[15], inContext->micoStatus.mac[16] );
snprintf( temp_txt, 100, "%s", inContext->flashContentInRam.micoSystemConfig.name);
init.instance_name = (char*)__strdup(temp_txt);
#ifndef MICO_LOCAL_SERVER_PORT