implemented alink connecting with credential fetch

This commit is contained in:
strawmanbobi
2022-02-16 11:28:46 +08:00
parent ea5e04d62a
commit 2bc257b109
10 changed files with 160 additions and 44 deletions

View File

@@ -1,7 +1,10 @@
{ {
// See http://go.microsoft.com/fwlink/?LinkId=827846 // See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format // for the documentation about the extensions.json format
"recommendations": [ "recommendations": [
"platformio.platformio-ide" "platformio.platformio-ide"
] ],
} "unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

View File

@@ -8,6 +8,9 @@
"vector": "cpp", "vector": "cpp",
"string_view": "cpp", "string_view": "cpp",
"initializer_list": "cpp", "initializer_list": "cpp",
"ranges": "cpp" "ranges": "cpp",
"memory": "cpp",
"random": "cpp",
"optional": "cpp"
} }
} }

View File

@@ -103,7 +103,9 @@ static void callback(char *topic, byte *payload, unsigned int length) {
} }
static bool mqttConnecting = false; static bool mqttConnecting = false;
void AliyunIoTSDK::mqttCheckConnect() { int AliyunIoTSDK::mqttCheckConnect() {
int mqttStatus = 0;
Serial.println("INFO:\tAlink MQTT connection checking..."); Serial.println("INFO:\tAlink MQTT connection checking...");
if (client != NULL && false == mqttConnecting) { if (client != NULL && false == mqttConnecting) {
@@ -125,11 +127,13 @@ void AliyunIoTSDK::mqttCheckConnect() {
Serial.print("ERROR:\tMQTT Connect err:"); Serial.print("ERROR:\tMQTT Connect err:");
Serial.println(client->state()); Serial.println(client->state());
delay(60000); delay(60000);
mqttStatus = -1;
} }
mqttConnecting = false; mqttConnecting = false;
} }
} }
} }
return mqttStatus;
} }
void AliyunIoTSDK::begin(Client &espClient, void AliyunIoTSDK::begin(Client &espClient,
@@ -176,13 +180,21 @@ void AliyunIoTSDK::begin(Client &espClient,
mqttCheckConnect(); mqttCheckConnect();
} }
void AliyunIoTSDK::loop() { int AliyunIoTSDK::loop() {
int mqttStatus = 0;
client->loop(); client->loop();
if (millis() - lastMs >= CHECK_INTERVAL) { if (millis() - lastMs >= CHECK_INTERVAL) {
lastMs = millis(); lastMs = millis();
mqttCheckConnect(); mqttStatus = mqttCheckConnect();
}
Serial.print("MQTT connect return: ");
Serial.println(mqttStatus);
if (0 == mqttStatus) {
messageBufferCheck(); messageBufferCheck();
} }
return mqttStatus;
} }
void AliyunIoTSDK::sendEvent(const char *eventId, const char *param) { void AliyunIoTSDK::sendEvent(const char *eventId, const char *param) {
@@ -192,7 +204,7 @@ void AliyunIoTSDK::sendEvent(const char *eventId, const char *param) {
sprintf(jsonBuf, ALINK_EVENT_BODY_FORMAT, param, eventId); sprintf(jsonBuf, ALINK_EVENT_BODY_FORMAT, param, eventId);
Serial.println(jsonBuf); Serial.println(jsonBuf);
boolean d = client->publish(topicKey, jsonBuf); boolean d = client->publish(topicKey, jsonBuf);
Serial.print("publish:0 successfully:"); Serial.print("publish: 0 successfully: ");
Serial.println(d); Serial.println(d);
} }

View File

@@ -46,7 +46,7 @@ private:
public: public:
// MQTT keep alive handler // MQTT keep alive handler
static void mqttCheckConnect(); static int mqttCheckConnect();
// offical defined topic templates (not used) // offical defined topic templates (not used)
static char ALINK_TOPIC_PROP_POST[150]; static char ALINK_TOPIC_PROP_POST[150];
@@ -54,7 +54,7 @@ public:
static char ALINK_TOPIC_EVENT[150]; static char ALINK_TOPIC_EVENT[150];
// MQTT keep alive task // MQTT keep alive task
static void loop(); static int loop();
/** /**
* Initialize and connect to AliyunIoT * Initialize and connect to AliyunIoT

View File

@@ -44,10 +44,20 @@
#include "IRbabyIRIS.h" #include "IRbabyIRIS.h"
#include "IRbabyRF.h" #include "IRbabyRF.h"
#include "IRbaby.h"
#define CREDENTIAL_INIT_RETRY_MAX (3)
extern char iris_server_address[]; extern char iris_server_address[];
extern char iris_credential_token[]; extern char iris_credential_token[];
extern String g_product_key;
extern String g_device_name;
extern String g_device_secret;
int credential_init_retry = 0;
void uploadIP(); // device info upload to devicehive void uploadIP(); // device info upload to devicehive
void IRAM_ATTR resetHandle(); // interrupt handle void IRAM_ATTR resetHandle(); // interrupt handle
@@ -95,7 +105,7 @@ void setup() {
wifi_manager.addParameter(&credential_token); wifi_manager.addParameter(&credential_token);
wifi_manager.autoConnect(); wifi_manager.autoConnect();
memset(iris_server_address, 0, URL_SHORT_MAX); memset(iris_server_address, 0, URL_SHORT_MAX);
strcpy(iris_server_address, server_address.getValue()); strcpy(iris_server_address, server_address.getValue());
@@ -107,18 +117,26 @@ void setup() {
do { do {
if(WiFi.status()== WL_CONNECTED) { if(WiFi.status()== WL_CONNECTED) {
if (0 == fetchIrisCredential(iris_credential_token)) { if (0 == fetchIrisCredential(iris_credential_token,
g_product_key,
g_device_name,
g_device_secret)) {
break; break;
} }
} else {
delay(1000);
} }
credential_init_retry++;
if (credential_init_retry >= CREDENTIAL_INIT_RETRY_MAX) {
ERRORLN("retried fetch credential for 3 times, reset WiFi");
wifiReset();
}
delay(1000);
} while (1); } while (1);
INFOF("credential matched : %s\n", iris_credential_token); INFOF("credential get : %s\n", iris_credential_token);
settingsLoad(); // load user settings form fs settingsLoad(); // load user settings form fs
delay(5); delay(1000);
connectToAliyunIoT(); connectToAliyunIoT();
#ifdef USE_RF #ifdef USE_RF
initRF(); // RF init initRF(); // RF init
@@ -135,6 +153,11 @@ void setup() {
saveDataTask.attach_scheduled(SAVE_DATA_INTERVALS, settingsSave); saveDataTask.attach_scheduled(SAVE_DATA_INTERVALS, settingsSave);
} }
void wifiReset() {
WiFi.disconnect();
ESP.reset();
}
void loop() { void loop() {
/* IR receive */ /* IR receive */
recvIR(); recvIR();

29
src/IRbaby.h Normal file
View File

@@ -0,0 +1,29 @@
/**
*
* Copyright (c) 2020-2022 IRbaby-IRext
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef IRBABY_H
#define IRBABY_H
void wifiReset();
#endif // IRBABY_H

View File

@@ -22,19 +22,21 @@
*/ */
#include <Arduino.h> #include <Arduino.h>
#include <WString.h>
#include "IRbabySerial.h" #include "IRbabySerial.h"
#include "IRbabyAlink.h" #include "IRbabyAlink.h"
#include "IRbabyGlobal.h" #include "IRbabyGlobal.h"
#define TOPIC_NAME_MAX (64) #include "IRbaby.h"
#define PRODUCT_KEY "a1WlzsJh50b" #define TOPIC_NAME_MAX (64)
#define DEVICE_NAME "IRIS_Kit_Dev" #define IOT_RETRY_MAX (3)
#define DEVICE_SECRET "9df2c6b48e4c66519718cc236fc9fb79"
#define REGION_ID "cn-shanghai"
#define USER_NAME "strawmanbobi@irext.net" String g_product_key = "";
String g_device_name = "";
String g_device_secret = "";
String g_region_id = "cn-shanghai";
static AliyunIoTSDK iot; static AliyunIoTSDK iot;
static char IRIS_UPSTREAM_TOPIC[TOPIC_NAME_MAX] = { 0 }; static char IRIS_UPSTREAM_TOPIC[TOPIC_NAME_MAX] = { 0 };
@@ -42,20 +44,35 @@ static ep_state_t endpoint_state = FSM_IDLE;
static void registerCallback(); static void registerCallback();
static void irisAlinkCallback(const char *topic, uint8_t *data, int length); static void irisAlinkCallback(const char *topic, uint8_t *data, int length);
static int iot_retry = 0;
static void sendIrisKitHeartBeat(); static void sendIrisKitHeartBeat();
void connectToAliyunIoT() { void connectToAliyunIoT() {
INFOLN("Try connecting to Aliyun IoT"); INFOF("Try connecting to Aliyun IoT : %s, %s, %s, %s\n",
iot.begin(wifi_client, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET, REGION_ID); g_product_key.c_str(), g_device_name.c_str(), g_device_secret.c_str(), g_region_id.c_str());
iot.begin(wifi_client, g_product_key.c_str(), g_device_name.c_str(), g_device_secret.c_str(), g_region_id.c_str());
INFOLN("Aliyun IoT connect done"); INFOLN("Aliyun IoT connect done");
snprintf(IRIS_UPSTREAM_TOPIC, TOPIC_NAME_MAX - 1, "/%s/%s/user/iris/upstream", PRODUCT_KEY, snprintf(IRIS_UPSTREAM_TOPIC, TOPIC_NAME_MAX - 1, "/%s/%s/user/iris/upstream",
DEVICE_NAME); g_product_key.c_str(), g_device_name.c_str());
registerCallback(); registerCallback();
} }
void checkAlinkMQTT() { void checkAlinkMQTT() {
iot.loop(); int mqttStatus = 0;
sendIrisKitHeartBeat(); mqttStatus = iot.loop();
if (0 == mqttStatus) {
iot_retry = 0;
sendIrisKitHeartBeat();
} else {
iot_retry++;
}
if (iot_retry >= IOT_RETRY_MAX) {
ERRORLN("Alink could not established, something went wrong, reset...");
wifiReset();
}
} }
// not only for IRIS related topic based session // not only for IRIS related topic based session

View File

@@ -26,7 +26,8 @@
StaticJsonDocument<1024> recv_msg_doc; StaticJsonDocument<1024> recv_msg_doc;
StaticJsonDocument<1024> send_msg_doc; StaticJsonDocument<1024> send_msg_doc;
StaticJsonDocument<1024> http_json_doc; StaticJsonDocument<1024> http_request_doc;
StaticJsonDocument<1024> http_response_doc;
WiFiManager wifi_manager; WiFiManager wifi_manager;
WiFiClient wifi_client; WiFiClient wifi_client;

View File

@@ -39,36 +39,61 @@
#define DOWNLOAD_SUFFIX ".bin" #define DOWNLOAD_SUFFIX ".bin"
extern StaticJsonDocument<1024> http_json_doc; extern StaticJsonDocument<1024> http_request_doc;
extern StaticJsonDocument<1024> http_response_doc;
char iris_server_address[URL_SHORT_MAX] = { 0 }; char iris_server_address[URL_SHORT_MAX] = { 0 };
int fetchIrisCredential(String credential_token) { int fetchIrisCredential(String credential_token,
String& product_key,
String& device_name,
String& device_secret) {
int ret = -1; int ret = -1;
HTTPClient http_client; String device_sn("IRbaby_");
String fetch_credential_url(iris_server_address); String fetch_credential_url(iris_server_address);
HTTPClient http_client;
int tsi = 0;
int response_code = 0; int response_code = 0;
fetch_credential_url.concat(String(FETCH_CREDENTIAL_SUFFIX)); fetch_credential_url.concat(String(FETCH_CREDENTIAL_SUFFIX));
device_sn.concat(String(ESP.getChipId(), HEX));
INFOF("fetch credential URL = %s\n", fetch_credential_url.c_str()); INFOF("fetch credential URL = %s\n", fetch_credential_url.c_str());
if (credential_token.isEmpty()) {
ERRORLN("credential token is empty");
return -1;
}
tsi = credential_token.indexOf(",");
if (-1 == tsi) {
ERRORLN("credential token format error");
return -1;
}
product_key = credential_token.substring(0, tsi);
device_name = credential_token.substring(tsi + 1);
http_client.begin(wifi_client, fetch_credential_url); http_client.begin(wifi_client, fetch_credential_url);
http_client.addHeader("Content-Type", "application/json"); http_client.addHeader("Content-Type", "application/json");
http_json_doc.clear(); http_request_doc.clear();
http_json_doc["endpointSN"] = String(ESP.getChipId(), HEX); http_request_doc["endpointSN"] = device_sn;
http_json_doc["credentialToken"] = credential_token; http_request_doc["credentialToken"] = credential_token;
String request_data = ""; String request_data = "";
serializeJson(http_json_doc, request_data); serializeJson(http_request_doc, request_data);
response_code = http_client.POST(request_data); response_code = http_client.POST(request_data);
if (response_code > 0) { if (200 == response_code) {
INFOF("HTTP response code: %d\n", response_code); INFOF("HTTP response code = %d\n", response_code);
String payload = http_client.getString(); String payload = http_client.getString();
INFOF("HTTP response payload = %s\n", payload.c_str()); INFOF("HTTP response payload = %s\n", payload.c_str());
ret = 0; http_response_doc.clear();
if (OK == deserializeJson(http_response_doc, payload.c_str())) {
String ds = http_response_doc["entity"];
device_secret = ds;
INFOF("HTTP response deserialized, PK = %s, DN = %s, DS = %s\n",
product_key.c_str(), device_name.c_str(), device_secret.c_str());
ret = 0;
}
} }
http_client.end(); http_client.end();

View File

@@ -29,7 +29,10 @@
#define URL_SHORT_MAX (128) #define URL_SHORT_MAX (128)
int fetchIrisCredential(String credential_token); int fetchIrisCredential(String credential_token,
String& product_key,
String& device_name,
String& device_secret);
void downLoadFile(String file, String path); void downLoadFile(String file, String path);