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

@@ -3,5 +3,8 @@
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

View File

@@ -8,6 +8,9 @@
"vector": "cpp",
"string_view": "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;
void AliyunIoTSDK::mqttCheckConnect() {
int AliyunIoTSDK::mqttCheckConnect() {
int mqttStatus = 0;
Serial.println("INFO:\tAlink MQTT connection checking...");
if (client != NULL && false == mqttConnecting) {
@@ -125,11 +127,13 @@ void AliyunIoTSDK::mqttCheckConnect() {
Serial.print("ERROR:\tMQTT Connect err:");
Serial.println(client->state());
delay(60000);
mqttStatus = -1;
}
mqttConnecting = false;
}
}
}
return mqttStatus;
}
void AliyunIoTSDK::begin(Client &espClient,
@@ -176,13 +180,21 @@ void AliyunIoTSDK::begin(Client &espClient,
mqttCheckConnect();
}
void AliyunIoTSDK::loop() {
int AliyunIoTSDK::loop() {
int mqttStatus = 0;
client->loop();
if (millis() - lastMs >= CHECK_INTERVAL) {
lastMs = millis();
mqttCheckConnect();
mqttStatus = mqttCheckConnect();
}
Serial.print("MQTT connect return: ");
Serial.println(mqttStatus);
if (0 == mqttStatus) {
messageBufferCheck();
}
return mqttStatus;
}
void AliyunIoTSDK::sendEvent(const char *eventId, const char *param) {

View File

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

View File

@@ -44,10 +44,20 @@
#include "IRbabyIRIS.h"
#include "IRbabyRF.h"
#include "IRbaby.h"
#define CREDENTIAL_INIT_RETRY_MAX (3)
extern char iris_server_address[];
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 IRAM_ATTR resetHandle(); // interrupt handle
@@ -107,18 +117,26 @@ void setup() {
do {
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;
}
} 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);
INFOF("credential matched : %s\n", iris_credential_token);
INFOF("credential get : %s\n", iris_credential_token);
settingsLoad(); // load user settings form fs
delay(5);
delay(1000);
connectToAliyunIoT();
#ifdef USE_RF
initRF(); // RF init
@@ -135,6 +153,11 @@ void setup() {
saveDataTask.attach_scheduled(SAVE_DATA_INTERVALS, settingsSave);
}
void wifiReset() {
WiFi.disconnect();
ESP.reset();
}
void loop() {
/* IR receive */
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 <WString.h>
#include "IRbabySerial.h"
#include "IRbabyAlink.h"
#include "IRbabyGlobal.h"
#include "IRbaby.h"
#define TOPIC_NAME_MAX (64)
#define IOT_RETRY_MAX (3)
#define PRODUCT_KEY "a1WlzsJh50b"
#define DEVICE_NAME "IRIS_Kit_Dev"
#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 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 irisAlinkCallback(const char *topic, uint8_t *data, int length);
static int iot_retry = 0;
static void sendIrisKitHeartBeat();
void connectToAliyunIoT() {
INFOLN("Try connecting to Aliyun IoT");
iot.begin(wifi_client, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET, REGION_ID);
INFOF("Try connecting to Aliyun IoT : %s, %s, %s, %s\n",
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");
snprintf(IRIS_UPSTREAM_TOPIC, TOPIC_NAME_MAX - 1, "/%s/%s/user/iris/upstream", PRODUCT_KEY,
DEVICE_NAME);
snprintf(IRIS_UPSTREAM_TOPIC, TOPIC_NAME_MAX - 1, "/%s/%s/user/iris/upstream",
g_product_key.c_str(), g_device_name.c_str());
registerCallback();
}
void checkAlinkMQTT() {
iot.loop();
int mqttStatus = 0;
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

View File

@@ -26,7 +26,8 @@
StaticJsonDocument<1024> recv_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;
WiFiClient wifi_client;

View File

@@ -39,37 +39,62 @@
#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 };
int fetchIrisCredential(String credential_token) {
int fetchIrisCredential(String credential_token,
String& product_key,
String& device_name,
String& device_secret) {
int ret = -1;
HTTPClient http_client;
String device_sn("IRbaby_");
String fetch_credential_url(iris_server_address);
HTTPClient http_client;
int tsi = 0;
int response_code = 0;
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());
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.addHeader("Content-Type", "application/json");
http_json_doc.clear();
http_json_doc["endpointSN"] = String(ESP.getChipId(), HEX);
http_json_doc["credentialToken"] = credential_token;
http_request_doc.clear();
http_request_doc["endpointSN"] = device_sn;
http_request_doc["credentialToken"] = credential_token;
String request_data = "";
serializeJson(http_json_doc, request_data);
serializeJson(http_request_doc, request_data);
response_code = http_client.POST(request_data);
if (response_code > 0) {
INFOF("HTTP response code: %d\n", response_code);
if (200 == response_code) {
INFOF("HTTP response code = %d\n", response_code);
String payload = http_client.getString();
INFOF("HTTP response payload = %s\n", payload.c_str());
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();

View File

@@ -29,7 +29,10 @@
#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);