iot-device-mqtt-sdk
Version:
all in one IoT MQTT SDK for aliyun,huawei,tencent,OneNET,CTWing
256 lines (180 loc) • 6.54 kB
JavaScript
const mqtt = require('mqtt');
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const CryptoJS = require('crypto-js');
/**
* options
productKey
deviceName
deviceSecret
host
*/
exports.getIoTClient = function(opts) {
if (!opts || !opts.host ) {
throw new Error('options need host');
}
if (opts.host.indexOf('aliyuncs.com') > 0) {
return getAliyunIoTClient(opts);
} else if (opts.host.indexOf('huaweicloud.com') > 0) {
return getHuaweiIoTClient(opts);
} else if (opts.host.indexOf('tencentdevices.com') > 0) {
return getTencentIoTClient(opts);
} else if (opts.host.indexOf('heclouds.com') > 0) {
return getOneNETIoTClient(opts);
} else if (opts.host.indexOf('ctwing.cn') > 0) {
return getCTWingIoTClient(opts);
}
return null;
}
/*
aliyun IoT
*/
exports.getAliyunIoTClient = getAliyunIoTClient;
function getAliyunIoTClient(opts) {
opts.ca = fs.readFileSync(path.join(__dirname, './root-ca-file/aliyun_iot_root.crt'));
if (!opts || !opts.productKey ||
!opts.deviceName || !opts.deviceSecret) {
throw new Error('options need productKey,deviceName,deviceSecret');
}
if (!opts.host) {
throw new Error('options need');
}
const options = {
productKey: opts.productKey,
deviceName: opts.deviceName,
timestamp: Date.now(),
clientId: Math.random().toString(36).substr(2)
}
let keys = Object.keys(options).sort();
// 按字典序排序
keys = keys.sort();
const list = [];
keys.map((key) => {
list.push(`${key}${options[key]}`);
});
const contentStr = list.join('');
opts.password = crypto.createHmac('sha1', opts.deviceSecret).update(contentStr).digest('hex');
opts.clientId = `${options.clientId}|securemode=2,signmethod=hmacsha1,timestamp=${options.timestamp}|`;
opts.username = `${options.deviceName}&${options.productKey}`;
opts.port = opts.port || 1883;
opts.protocol = 'mqtts';
opts.rejectUnauthorized = false;
delete opts.productKey;
delete opts.deviceName;
delete opts.deviceSecret;
return mqtt.connect(opts);
}
/*
Huawei IoT
*/
exports.getHuaweiIoTClient = getHuaweiIoTClient;
function getHuaweiIoTClient(opts) {
if (!opts || !opts.deviceName ||
!opts.deviceSecret || !opts.host) {
throw new Error('options need deviceName,deviceSecret,host');
}
opts.rejectUnauthorized = false;
opts.keepalive = opts.keepalive || 120;
const timestamp = getIoTUTCString();
opts.password = crypto.createHmac('sha256', timestamp).update(opts.deviceSecret).digest('hex');
opts.clientId = opts.deviceName + '_0_1_' + timestamp;
opts.username = opts.deviceName;
opts.port = 8883;
opts.protocol = 'mqtts';
opts.ca = fs.readFileSync(path.join(__dirname, './root-ca-file/hw_iot_root.pem'));
delete opts.deviceName;
delete opts.deviceSecret;
return mqtt.connect(opts);
}
function getIoTUTCString() {
const d = new Date();
const utcYear = d.getUTCFullYear();
const utcMonth = prefix(2, d.getUTCMonth() + 1);
const utcDay = prefix(2, d.getUTCDate());
const utcHours = prefix(2, d.getUTCHours());
return utcYear + '' + utcMonth + '' + utcDay + '' + utcHours;
}
function prefix(num, val) {
return (new Array(num).join('0') + val).slice(-num);
}
/*
OneNET IoT
*/
exports.getOneNETIoTClient = getOneNETIoTClient;
function getOneNETIoTClient(opts) {
if (!opts || !opts.productKey || !opts.deviceName ||
!opts.deviceSecret || !opts.host) {
throw new Error('options need productKey,deviceName,deviceSecret,host');
}
opts.password = getOneNETToken(opts.productKey, opts.deviceName, opts.deviceSecret)
opts.clientId = opts.deviceName;
opts.username = opts.productKey;
opts.port = 1883;
opts.protocol = 'mqtt';
opts.clean = true
delete opts.productKey;
delete opts.deviceName;
delete opts.deviceSecret;
return mqtt.connect(opts);
}
function getOneNETToken(productId, deviceName, deviceKey) {
const res = `products/${productId}/devices/${deviceName}`
const version = "2018-10-31"; // 参数组版本号
const et = parseInt(Date.now() / 1000) + 100 * 24 * 60 * 60 // 访问过期时间 expirationTime (有效期为1小时)
const method = "md5";
// 对access_key进行base64解码
const key = CryptoJS.enc.Base64.parse(deviceKey);
// 计算sign
const contentStr = et + "\n" + method + "\n" + res + "\n" + version;
const sign_b = CryptoJS.HmacMD5(contentStr, key);
// 签名
const sign = CryptoJS.enc.Base64.stringify(sign_b);
// 拼接token
return "version=" + version + "&res=" + encodeURIComponent(res) + "&et=" + et + "&method=" + method + "&sign=" + encodeURIComponent(sign);
}
/*
Tencent IoT
*/
exports.getTencentIoTClient = getTencentIoTClient;
function getTencentIoTClient(opts) {
if (!opts || !opts.productKey ||
!opts.deviceSecret || !opts.deviceName) {
throw new Error('options need productKey,deviceName,deviceSecret');
}
//CONNECT参数
const options = {};
const sdkappid = "12010126";
const connid = "JS" + Date.now();
const expiry = parseInt(Date.now() / 1000 + 5 * 60); //秒数
//生成clientId,username,password
opts.username = opts.productKey + opts.deviceName + ";" + sdkappid + ";" + connid + ";" + expiry;
opts.clientId = opts.productKey + opts.deviceName;
opts.password = crypto.createHmac('sha1', Buffer.from(opts.deviceSecret, 'base64')).update(opts.username).digest('hex') + ";hmacsha1";
opts.keepalive = opts.keepalive || 120
opts.port = 1883;
opts.protocol = 'mqtt';
delete opts.productKey;
delete opts.deviceName;
delete opts.deviceSecret;
return mqtt.connect(opts);
}
/*
CTWing IoT
*/
exports.getCTWingIoTClient = getCTWingIoTClient;
function getCTWingIoTClient(opts) {
if (!opts || !opts.deviceName ||
!opts.deviceSecret || !opts.host) {
throw new Error('options need deviceName,deviceSecret,host');
}
opts.password = opts.deviceSecret;
opts.clientId = opts.deviceName;
opts.username = opts.deviceName + Date.now();
opts.port = opts.port || 1883;
opts.protocol = 'mqtt';
delete opts.deviceName;
delete opts.deviceSecret;
return mqtt.connect(opts);
}
;