@alwaysai/device-agent 2.1.0-1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cloud-connection/bootstrap-agent.d.ts +16 -0
- package/lib/cloud-connection/bootstrap-agent.d.ts.map +1 -0
- package/lib/cloud-connection/{device-agent.js → bootstrap-agent.js} +47 -24
- package/lib/cloud-connection/bootstrap-agent.js.map +1 -0
- package/lib/cloud-connection/connection-manager.d.ts +18 -6
- package/lib/cloud-connection/connection-manager.d.ts.map +1 -1
- package/lib/cloud-connection/connection-manager.js +108 -41
- package/lib/cloud-connection/connection-manager.js.map +1 -1
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts.map +1 -1
- package/lib/cloud-connection/device-agent-cloud-connection.js +10 -4
- package/lib/cloud-connection/device-agent-cloud-connection.js.map +1 -1
- package/lib/cloud-connection/passthrough-handler.d.ts.map +1 -1
- package/lib/cloud-connection/passthrough-handler.js +50 -46
- package/lib/cloud-connection/passthrough-handler.js.map +1 -1
- package/lib/cloud-connection/publisher.d.ts +1 -1
- package/lib/cloud-connection/publisher.d.ts.map +1 -1
- package/lib/cloud-connection/publisher.js +22 -20
- package/lib/cloud-connection/publisher.js.map +1 -1
- package/package.json +2 -2
- package/src/cloud-connection/{device-agent.ts → bootstrap-agent.ts} +70 -39
- package/src/cloud-connection/connection-manager.ts +180 -54
- package/src/cloud-connection/device-agent-cloud-connection.ts +11 -9
- package/src/cloud-connection/passthrough-handler.ts +61 -56
- package/src/cloud-connection/publisher.ts +30 -28
- package/lib/cloud-connection/bootstrap-provision.d.ts +0 -2
- package/lib/cloud-connection/bootstrap-provision.d.ts.map +0 -1
- package/lib/cloud-connection/bootstrap-provision.js +0 -35
- package/lib/cloud-connection/bootstrap-provision.js.map +0 -1
- package/lib/cloud-connection/device-agent.d.ts +0 -21
- package/lib/cloud-connection/device-agent.d.ts.map +0 -1
- package/lib/cloud-connection/device-agent.js.map +0 -1
- package/lib/util/clean-certs.d.ts +0 -2
- package/lib/util/clean-certs.d.ts.map +0 -1
- package/lib/util/clean-certs.js +0 -17
- package/lib/util/clean-certs.js.map +0 -1
- package/src/cloud-connection/bootstrap-provision.ts +0 -43
- package/src/util/clean-certs.ts +0 -16
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"passthrough-handler.js","sourceRoot":"","sources":["../../src/cloud-connection/passthrough-handler.ts"],"names":[],"mappings":";;;AAIA,4CAAmD;AACnD,gCAAgC;AAChC,gDAAgE;AAChE,6DAIuC;AACvC,+EAGgD;AAChD,2CAAwC;AACxC,yCAAkC;AAIlC,MAAM,
|
|
1
|
+
{"version":3,"file":"passthrough-handler.js","sourceRoot":"","sources":["../../src/cloud-connection/passthrough-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@ export declare class Publisher {
|
|
|
8
8
|
private readonly toCloudTopic;
|
|
9
9
|
constructor(connectionManager: ConnectionManager, clientId: string);
|
|
10
10
|
publish(topic: string, payload: string, customLogger?: winston.LeveledLogMethod): void;
|
|
11
|
-
publishToCloudWithAck(payload: string
|
|
11
|
+
publishToCloudWithAck(payload: string): Promise<boolean>;
|
|
12
12
|
publishDeviceAgentMessage(topic: string, message: ToClientMessage | ToCloudMessage, logger?: winston.LeveledLogMethod): void;
|
|
13
13
|
publishToClient(message: ToClientMessage, logger?: winston.LeveledLogMethod): void;
|
|
14
14
|
publishToCloud(message: ToCloudMessage, logger?: winston.LeveledLogMethod): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publisher.d.ts","sourceRoot":"","sources":["../../src/cloud-connection/publisher.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,cAAc,EAGf,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"publisher.d.ts","sourceRoot":"","sources":["../../src/cloud-connection/publisher.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,cAAc,EAGf,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGzD,qBAAa,SAAS;IACpB,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAE1B,iBAAiB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM;IAO3D,OAAO,CACZ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,YAAY,GAAE,OAAO,CAAC,gBAA+B;IAsB1C,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAuB9D,yBAAyB,CAC9B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,eAAe,GAAG,cAAc,EACzC,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB;IAM5B,eAAe,CACpB,OAAO,EAAE,eAAe,EACxB,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB;IAK5B,cAAc,CACnB,OAAO,EAAE,cAAc,EACvB,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB;IAM5B,WAAW,IAAI,MAAM;CAG7B"}
|
|
@@ -13,29 +13,31 @@ class Publisher {
|
|
|
13
13
|
publish(topic, payload, customLogger = logger_1.logger.debug) {
|
|
14
14
|
// TODO: topic validation
|
|
15
15
|
// By default, log the published message at debug level, unless otherwise specified
|
|
16
|
+
const publishPacket = {
|
|
17
|
+
topicName: topic,
|
|
18
|
+
qos: this.connectionManager.qos,
|
|
19
|
+
payload: Buffer.from(payload)
|
|
20
|
+
};
|
|
16
21
|
customLogger(`Publishing message:\nTopic: ${topic}\nMessage: ${JSON.stringify(JSON.parse(payload), null, 2)}`);
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
.publish(topic, payload, (err) => {
|
|
20
|
-
if (err) {
|
|
21
|
-
logger_1.logger.error(`Error publishing message: \nTopic: ${topic}\nMessage: ${payload}\nError: ${err}`);
|
|
22
|
-
}
|
|
23
|
-
});
|
|
22
|
+
// TODO: Change publish() to async and resolve issues where it's used synchronously.
|
|
23
|
+
void this.connectionManager.getIoTDevice().publish(publishPacket);
|
|
24
24
|
}
|
|
25
|
-
publishToCloudWithAck(payload
|
|
25
|
+
async publishToCloudWithAck(payload) {
|
|
26
26
|
const topic = this.toCloudTopic;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
27
|
+
const publishPacket = {
|
|
28
|
+
topicName: topic,
|
|
29
|
+
qos: this.connectionManager.qos,
|
|
30
|
+
payload: Buffer.from(payload)
|
|
31
|
+
};
|
|
32
|
+
try {
|
|
33
|
+
await this.connectionManager.getIoTDevice().publish(publishPacket);
|
|
34
|
+
logger_1.logger.debug(`Successfully published message:\nTopic: ${topic}\nMessage: ${payload}`);
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
logger_1.logger.error(`Error publishing message:\nTopic: ${topic}\nMessage: ${payload}\nError: ${err}`);
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
39
41
|
}
|
|
40
42
|
publishDeviceAgentMessage(topic, message, logger) {
|
|
41
43
|
const messageStr = JSON.stringify(message);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publisher.js","sourceRoot":"","sources":["../../src/cloud-connection/publisher.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AACxC,yEAKwC;
|
|
1
|
+
{"version":3,"file":"publisher.js","sourceRoot":"","sources":["../../src/cloud-connection/publisher.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AACxC,yEAKwC;AAKxC,MAAa,SAAS;IAMpB,YAAY,iBAAoC,EAAE,QAAgB;QAChE,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;QAC3C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,aAAa,GAAG,IAAA,uCAAgB,EAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrD,IAAI,CAAC,YAAY,GAAG,IAAA,sCAAe,EAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrD,CAAC;IAEM,OAAO,CACZ,KAAa,EACb,OAAe,EACf,eAAyC,eAAM,CAAC,KAAK;QAErD,yBAAyB;QACzB,mFAAmF;QACnF,MAAM,aAAa,GAAwB;YACzC,SAAS,EAAE,KAAK;YAChB,GAAG,EAAE,IAAI,CAAC,iBAAiB,CAAC,GAAG;YAC/B,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;SAC9B,CAAC;QAEF,YAAY,CACV,+BAA+B,KAAK,cAAc,IAAI,CAAC,SAAS,CAC9D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EACnB,IAAI,EACJ,CAAC,CACF,EAAE,CACJ,CAAC;QAEF,oFAAoF;QACpF,KAAK,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IACpE,CAAC;IAEM,KAAK,CAAC,qBAAqB,CAAC,OAAe;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC;QAEhC,MAAM,aAAa,GAAwB;YACzC,SAAS,EAAE,KAAK;YAChB,GAAG,EAAE,IAAI,CAAC,iBAAiB,CAAC,GAAG;YAC/B,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;SAC9B,CAAC;QAEF,IAAI;YACF,MAAM,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;YACnE,eAAM,CAAC,KAAK,CACV,2CAA2C,KAAK,cAAc,OAAO,EAAE,CACxE,CAAC;YACF,OAAO,IAAI,CAAC;SACb;QAAC,OAAO,GAAG,EAAE;YACZ,eAAM,CAAC,KAAK,CACV,qCAAqC,KAAK,cAAc,OAAO,YAAY,GAAG,EAAE,CACjF,CAAC;YACF,OAAO,KAAK,CAAC;SACd;IACH,CAAC;IAEM,yBAAyB,CAC9B,KAAa,EACb,OAAyC,EACzC,MAAiC;QAEjC,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAEM,eAAe,CACpB,OAAwB,EACxB,MAAiC;QAEjC,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACtE,CAAC;IAEM,cAAc,CACnB,OAAuB,EACvB,MAAiC;QAEjC,kDAAkD;QAClD,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACrE,CAAC;IAEM,WAAW;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAxFD,8BAwFC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alwaysai/device-agent",
|
|
3
3
|
"description": "The alwaysAI Device Agent",
|
|
4
|
-
"version": "2.1.0
|
|
4
|
+
"version": "2.1.0",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
7
7
|
"publishConfig": {
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"ajv": "8.11.0",
|
|
43
43
|
"alwaysai": "2.8.0",
|
|
44
44
|
"amqplib": "0.10.3",
|
|
45
|
-
"aws-iot-device-sdk": "
|
|
45
|
+
"aws-iot-device-sdk-v2": "1.21.4",
|
|
46
46
|
"docker-compose": "0.24.8",
|
|
47
47
|
"lodash": "4.17.21",
|
|
48
48
|
"node-os-utils": "1.3.7",
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
// eslint-disable-next-line
|
|
2
|
-
const awsIot = require('aws-iot-device-sdk');
|
|
3
1
|
import { getTargetHardwareUuid } from 'alwaysai/lib/core/app';
|
|
4
2
|
import {
|
|
5
3
|
DEVICE_CERTIFICATE_FILE_NAME,
|
|
6
4
|
DEVICE_CERTIFICATE_ID_FILE_NAME,
|
|
7
5
|
DEVICE_PRIVATE_KEY_FILE_NAME,
|
|
8
|
-
LOCAL_CERT_AND_KEY_DIR
|
|
6
|
+
LOCAL_CERT_AND_KEY_DIR,
|
|
7
|
+
LocalDeviceCertificates
|
|
9
8
|
} from 'alwaysai/lib/infrastructure';
|
|
10
9
|
import { JsSpawner } from 'alwaysai/lib/util';
|
|
11
10
|
import {
|
|
@@ -14,18 +13,20 @@ import {
|
|
|
14
13
|
} from '../infrastructure/device-certificate';
|
|
15
14
|
import { getDeviceUuid } from '../util/get-device-id';
|
|
16
15
|
import { logger } from '../util/logger';
|
|
16
|
+
import { ConnectionManager, DeviceAgentConfigType } from './connection-manager';
|
|
17
|
+
import { Publisher } from './publisher';
|
|
18
|
+
import { MessageHandler } from './message-dispatcher';
|
|
19
|
+
import {
|
|
20
|
+
getBootstrapCertificateFilePath,
|
|
21
|
+
getBootstrapPrivateKeyFilePath
|
|
22
|
+
} from '../infrastructure/device-certificate';
|
|
23
|
+
import { getIoTCoreEndpointUrl } from '../infrastructure/urls';
|
|
24
|
+
``;
|
|
25
|
+
import { AWS_ROOT_CERTIFICATE_FILE_PATH } from '../util/directories';
|
|
17
26
|
|
|
18
27
|
// eslint-disable-next-line
|
|
19
28
|
const process = require('process');
|
|
20
29
|
|
|
21
|
-
interface DeviceAgentConfigType {
|
|
22
|
-
keyPath: string;
|
|
23
|
-
certPath: string;
|
|
24
|
-
caPath: string;
|
|
25
|
-
clientId: string;
|
|
26
|
-
host: string;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
30
|
interface FleetProvisionTemplateMessageType {
|
|
30
31
|
certificateOwnershipToken: string;
|
|
31
32
|
parameters: {
|
|
@@ -36,49 +37,49 @@ interface FleetProvisionTemplateMessageType {
|
|
|
36
37
|
};
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
export class
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
export class BootstrapAgent implements MessageHandler {
|
|
41
|
+
private connectionManager: ConnectionManager;
|
|
42
|
+
private publisher: Publisher;
|
|
43
|
+
private readonly clientId = getDeviceUuid();
|
|
44
|
+
private readonly host = getIoTCoreEndpointUrl();
|
|
45
|
+
private readonly port = 8883;
|
|
46
|
+
|
|
47
|
+
constructor() {
|
|
48
|
+
// Initialize & setup the connection
|
|
49
|
+
const bootstrapAgentConfig = {
|
|
50
|
+
clientId: this.clientId,
|
|
51
|
+
host: this.host,
|
|
52
|
+
port: this.port,
|
|
53
|
+
keyPath: getBootstrapPrivateKeyFilePath(),
|
|
54
|
+
certPath: getBootstrapCertificateFilePath(),
|
|
55
|
+
caPath: AWS_ROOT_CERTIFICATE_FILE_PATH
|
|
56
|
+
};
|
|
57
|
+
this.connectionManager = new ConnectionManager(bootstrapAgentConfig);
|
|
58
|
+
|
|
59
|
+
this.publisher = new Publisher(
|
|
60
|
+
this.connectionManager,
|
|
61
|
+
bootstrapAgentConfig.clientId
|
|
62
|
+
);
|
|
42
63
|
}
|
|
43
64
|
|
|
44
|
-
public deviceType = 'aai-device';
|
|
45
|
-
public device = awsIot.device;
|
|
46
65
|
public hardwareId = async () => await getTargetHardwareUuid(JsSpawner());
|
|
47
66
|
public deviceId = getDeviceUuid();
|
|
67
|
+
public deviceType = 'aai-device';
|
|
48
68
|
|
|
49
69
|
public publishMessage(topic: string, message: string) {
|
|
50
|
-
this.
|
|
70
|
+
this.publisher.publish(topic, message);
|
|
51
71
|
}
|
|
52
|
-
}
|
|
53
72
|
|
|
54
|
-
|
|
55
|
-
public async subscribeToAllTopics() {
|
|
56
|
-
const AWS_CERTIFICATE_ACCEPT_TOPIC =
|
|
57
|
-
'$aws/certificates/create/json/accepted';
|
|
58
|
-
const PROVISIONING_ACCEPTED_TOPIC =
|
|
59
|
-
'$aws/provisioning-templates/FleetProvisionTemplate/provision/json/accepted';
|
|
60
|
-
|
|
61
|
-
const topics = [AWS_CERTIFICATE_ACCEPT_TOPIC, PROVISIONING_ACCEPTED_TOPIC];
|
|
62
|
-
const resp = this.device.subscribe(
|
|
63
|
-
topics,
|
|
64
|
-
function (err: any, granted: { topic: string; qos: number }[]) {
|
|
65
|
-
logger.debug(`Bootstrap Agent: ${JSON.stringify(granted, null, 2)}`);
|
|
66
|
-
}
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
public async handleAwsCertificateTopics(topic: string, payload: any) {
|
|
73
|
+
public async handle(payload: any, topic: string) {
|
|
71
74
|
switch (topic) {
|
|
72
75
|
case '$aws/certificates/create/json/accepted': {
|
|
73
|
-
logger.debug(
|
|
74
|
-
`Received Certs: ${JSON.stringify(JSON.parse(payload), null, 2)}`
|
|
75
|
-
);
|
|
76
|
+
logger.debug(`Received Certs: ${JSON.stringify(payload, null, 2)}`);
|
|
76
77
|
const {
|
|
77
78
|
certificateId,
|
|
78
79
|
certificatePem,
|
|
79
80
|
privateKey,
|
|
80
81
|
certificateOwnershipToken
|
|
81
|
-
} =
|
|
82
|
+
} = payload;
|
|
82
83
|
|
|
83
84
|
const certSpawner = JsSpawner({ path: LOCAL_CERT_AND_KEY_DIR });
|
|
84
85
|
|
|
@@ -124,4 +125,34 @@ export class BootstrapAgent extends DeviceAgent {
|
|
|
124
125
|
}
|
|
125
126
|
}
|
|
126
127
|
}
|
|
128
|
+
|
|
129
|
+
public async bootstrapProvision() {
|
|
130
|
+
const rmBootstrapCertsAndClose = async () => {
|
|
131
|
+
const deviceCertificates = new LocalDeviceCertificates();
|
|
132
|
+
const spawner = JsSpawner();
|
|
133
|
+
await spawner.rimraf(getBootstrapCertificateDirectoryPath());
|
|
134
|
+
await spawner.rimraf(deviceCertificates.getCertificateDirectoryPath());
|
|
135
|
+
logger.error('Could not provision device. Try again.');
|
|
136
|
+
process.exit(1);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
setTimeout(rmBootstrapCertsAndClose, 60000);
|
|
140
|
+
|
|
141
|
+
this.connectionManager.initConnectionHandlers(() => {
|
|
142
|
+
logger.info('Your device is being provisioned');
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
await this.connectionManager.waitForConnection();
|
|
146
|
+
|
|
147
|
+
this.connectionManager.registerHandler(
|
|
148
|
+
'$aws/certificates/create/json/accepted',
|
|
149
|
+
this
|
|
150
|
+
);
|
|
151
|
+
this.connectionManager.registerHandler(
|
|
152
|
+
'$aws/provisioning-templates/FleetProvisionTemplate/provision/json/accepted',
|
|
153
|
+
this
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
this.publishMessage('$aws/certificates/create/json', '{}');
|
|
157
|
+
}
|
|
127
158
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { mqtt5, iot } from 'aws-iot-device-sdk-v2';
|
|
2
2
|
import {
|
|
3
3
|
DEVICE_CERTIFICATE_FILE_PATH,
|
|
4
4
|
DEVICE_PRIVATE_KEY_FILE_PATH
|
|
@@ -9,35 +9,64 @@ import { logger } from '../util/logger';
|
|
|
9
9
|
import { promisify } from 'util';
|
|
10
10
|
import { exec } from 'child_process';
|
|
11
11
|
import { MessageDispatcher, MessageHandler } from './message-dispatcher';
|
|
12
|
+
import { once } from 'events';
|
|
12
13
|
|
|
13
14
|
const exec_promise = promisify(exec);
|
|
14
15
|
|
|
16
|
+
// replace with direct params: instead of interface
|
|
17
|
+
export interface DeviceAgentConfigType {
|
|
18
|
+
clientId: string;
|
|
19
|
+
host: string;
|
|
20
|
+
port: number;
|
|
21
|
+
keyPath?: string;
|
|
22
|
+
certPath?: string;
|
|
23
|
+
caPath?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
15
26
|
export class ConnectionManager extends MessageDispatcher<any> {
|
|
16
27
|
private clientId: string;
|
|
17
28
|
private host: string;
|
|
18
29
|
private port: number;
|
|
19
|
-
private
|
|
30
|
+
private config: mqtt5.Mqtt5ClientConfig;
|
|
31
|
+
private client: mqtt5.Mqtt5Client;
|
|
20
32
|
private subscribedTopics: Set<string> = new Set();
|
|
21
33
|
private connected = false;
|
|
34
|
+
readonly qos: mqtt5.QoS;
|
|
22
35
|
|
|
23
|
-
constructor(
|
|
36
|
+
constructor(deviceAgentConfig: DeviceAgentConfigType) {
|
|
24
37
|
super();
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
this.
|
|
28
|
-
this.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
38
|
+
|
|
39
|
+
// Use config values if provided, otherwise use defaults
|
|
40
|
+
this.clientId = deviceAgentConfig.clientId;
|
|
41
|
+
this.host = deviceAgentConfig.host;
|
|
42
|
+
this.port = deviceAgentConfig.port;
|
|
43
|
+
this.qos = mqtt5.QoS.AtLeastOnce;
|
|
44
|
+
|
|
45
|
+
const certPath = deviceAgentConfig.certPath || DEVICE_CERTIFICATE_FILE_PATH;
|
|
46
|
+
const keyPath = deviceAgentConfig.keyPath || DEVICE_PRIVATE_KEY_FILE_PATH;
|
|
47
|
+
const caPath = deviceAgentConfig.caPath || AWS_ROOT_CERTIFICATE_FILE_PATH;
|
|
48
|
+
|
|
49
|
+
const builder =
|
|
50
|
+
iot.AwsIotMqtt5ClientConfigBuilder.newDirectMqttBuilderWithMtlsFromPath(
|
|
51
|
+
this.host,
|
|
52
|
+
certPath,
|
|
53
|
+
keyPath
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
builder.withConnectProperties({
|
|
32
57
|
clientId: this.clientId,
|
|
33
|
-
|
|
34
|
-
port: this.port,
|
|
35
|
-
keepalive: 10 // time before re-connect attempt on dropped connection, default is 400 seconds
|
|
58
|
+
keepAliveIntervalSeconds: 10
|
|
36
59
|
});
|
|
60
|
+
|
|
61
|
+
builder.withCertificateAuthorityFromPath(undefined, caPath);
|
|
62
|
+
|
|
63
|
+
this.config = builder.build();
|
|
64
|
+
this.client = new mqtt5.Mqtt5Client(this.config);
|
|
65
|
+
this.client.start();
|
|
37
66
|
}
|
|
38
67
|
|
|
39
68
|
public getIoTDevice() {
|
|
40
|
-
return this.
|
|
69
|
+
return this.client;
|
|
41
70
|
}
|
|
42
71
|
|
|
43
72
|
public isConnected(): boolean {
|
|
@@ -46,76 +75,173 @@ export class ConnectionManager extends MessageDispatcher<any> {
|
|
|
46
75
|
|
|
47
76
|
public registerHandler(topic: string, handler: MessageHandler) {
|
|
48
77
|
super.registerHandler(topic, handler);
|
|
49
|
-
this.subscribe(topic);
|
|
78
|
+
void this.subscribe(topic);
|
|
50
79
|
}
|
|
51
80
|
|
|
52
|
-
public disconnect(): void {
|
|
53
|
-
this.
|
|
54
|
-
|
|
81
|
+
public async disconnect(): Promise<void> {
|
|
82
|
+
const stopped = once(this.client, mqtt5.Mqtt5Client.STOPPED);
|
|
83
|
+
this.client.stop();
|
|
84
|
+
await stopped;
|
|
85
|
+
logger.info(`Device Agent has been disconnected from the AWS IoT Core.`);
|
|
55
86
|
}
|
|
56
87
|
|
|
57
|
-
public subscribe(topic: string): void {
|
|
88
|
+
public async subscribe(topic: string): Promise<void> {
|
|
58
89
|
if (!this.subscribedTopics.has(topic)) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
90
|
+
try {
|
|
91
|
+
const suback = await this.client.subscribe({
|
|
92
|
+
subscriptions: [{ qos: mqtt5.QoS.AtLeastOnce, topicFilter: topic }]
|
|
93
|
+
});
|
|
94
|
+
this.subscribedTopics.add(topic);
|
|
95
|
+
logger.debug(
|
|
96
|
+
`Subscribed to topic: ${topic}, result: ${JSON.stringify(suback)}`
|
|
97
|
+
);
|
|
98
|
+
// Based on documentation here: https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901178
|
|
99
|
+
suback.reasonCodes.forEach((code, index) => {
|
|
100
|
+
if ([0, 1, 2].includes(code)) {
|
|
101
|
+
logger.debug(
|
|
102
|
+
`SUBACK success for topic index ${index}: reason code ${code}`
|
|
103
|
+
);
|
|
104
|
+
} else {
|
|
105
|
+
logger.error(
|
|
106
|
+
`SUBACK error for topic index ${index}: unexpected reason code ${code}`
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
} catch (error) {
|
|
111
|
+
logger.error(
|
|
112
|
+
`Failed to subscribe to topic: ${topic}. Error: ${stringifyError(
|
|
113
|
+
error
|
|
114
|
+
)}`
|
|
115
|
+
);
|
|
116
|
+
}
|
|
62
117
|
}
|
|
63
118
|
}
|
|
64
119
|
|
|
65
|
-
public unsubscribe(topic: string): void {
|
|
120
|
+
public async unsubscribe(topic: string): Promise<void> {
|
|
66
121
|
if (this.subscribedTopics.has(topic)) {
|
|
67
|
-
this.
|
|
122
|
+
const unsuback = await this.client.unsubscribe({
|
|
123
|
+
topicFilters: [topic]
|
|
124
|
+
});
|
|
125
|
+
logger.debug(
|
|
126
|
+
`Unsubscribed from topic: ${topic}, result: ${JSON.stringify(unsuback)}`
|
|
127
|
+
);
|
|
68
128
|
this.subscribedTopics.delete(topic);
|
|
69
|
-
logger.debug(`Unsubscribed from topic: ${topic}`);
|
|
70
129
|
}
|
|
71
130
|
}
|
|
72
131
|
|
|
73
132
|
public initConnectionHandlers(connectCallback: () => void): void {
|
|
74
|
-
this.
|
|
75
|
-
logger.
|
|
76
|
-
this.connected = true;
|
|
77
|
-
connectCallback();
|
|
133
|
+
this.client.on('attemptingConnect', () => {
|
|
134
|
+
logger.debug(`Device Agent is attempting connection`);
|
|
78
135
|
});
|
|
79
136
|
|
|
80
|
-
this.
|
|
81
|
-
|
|
137
|
+
this.client.on(
|
|
138
|
+
'connectionSuccess',
|
|
139
|
+
(eventData: mqtt5.ConnectionSuccessEvent) => {
|
|
140
|
+
logger.info('Device Agent has connected to the cloud.');
|
|
141
|
+
logger.debug(`Connack: ${JSON.stringify(eventData.connack)}`);
|
|
142
|
+
logger.debug(`Settings: ${JSON.stringify(eventData.settings)}`);
|
|
143
|
+
this.connected = true;
|
|
144
|
+
connectCallback();
|
|
145
|
+
}
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
this.client.on('disconnection', (eventData: mqtt5.DisconnectionEvent) => {
|
|
149
|
+
logger.info('Device Agent has been disconnected from the cloud');
|
|
150
|
+
logger.info(`Disconnection event: ${eventData.error.toString()}`);
|
|
151
|
+
if (eventData.disconnect !== undefined) {
|
|
152
|
+
logger.debug(
|
|
153
|
+
'Disconnect packet: ' + JSON.stringify(eventData.disconnect)
|
|
154
|
+
);
|
|
155
|
+
}
|
|
82
156
|
this.connected = false;
|
|
83
157
|
});
|
|
84
158
|
|
|
85
|
-
this.
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
159
|
+
this.client.on(
|
|
160
|
+
'connectionFailure',
|
|
161
|
+
(eventData: mqtt5.ConnectionFailureEvent) => {
|
|
162
|
+
logger.error(
|
|
163
|
+
`Error connecting to the AWS IoT Core! Disconnection event: ${eventData.error.toString()}`
|
|
164
|
+
);
|
|
165
|
+
if (eventData.connack) {
|
|
166
|
+
logger.debug(
|
|
167
|
+
'Disconnect packet: ' + JSON.stringify(eventData.connack)
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
this.connected = false;
|
|
172
|
+
}
|
|
173
|
+
);
|
|
90
174
|
|
|
91
|
-
this.
|
|
175
|
+
this.client.on('error', (error) => {
|
|
92
176
|
logger.error(
|
|
93
|
-
`Error connecting to the AWS IoT Core! Error:\n${stringifyError(
|
|
177
|
+
`Error connecting to the AWS IoT Core! Error:\n${stringifyError(
|
|
178
|
+
error as Error
|
|
179
|
+
)}`
|
|
94
180
|
);
|
|
95
181
|
this.connected = false;
|
|
96
182
|
});
|
|
97
183
|
|
|
98
|
-
this.
|
|
99
|
-
logger.warn(
|
|
100
|
-
this.connected = false;
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
this.device.on('offline', () => {
|
|
104
|
-
logger.warn(`Device Agent is offline ${new Date().toLocaleString()}`);
|
|
184
|
+
this.client.on('stopped', () => {
|
|
185
|
+
logger.warn(`Device Agent has stopped ${new Date().toLocaleString()}`);
|
|
105
186
|
void this.logConnectionInfo();
|
|
106
187
|
this.connected = false;
|
|
107
188
|
});
|
|
108
189
|
|
|
109
|
-
this.
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
190
|
+
this.client.on(
|
|
191
|
+
'messageReceived',
|
|
192
|
+
(eventData: mqtt5.MessageReceivedEvent) => {
|
|
193
|
+
const topic = eventData.message.topicName;
|
|
194
|
+
const payloadBuffer = eventData.message.payload as ArrayBuffer;
|
|
195
|
+
try {
|
|
196
|
+
const payloadString = payloadBuffer
|
|
197
|
+
? Buffer.from(new Uint8Array(payloadBuffer)).toString('utf-8')
|
|
198
|
+
: null;
|
|
199
|
+
logger.debug(
|
|
200
|
+
`Message received on topic: ${topic}:\n${payloadString}`
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
if (payloadString) {
|
|
204
|
+
const parsed = JSON.parse(payloadString);
|
|
205
|
+
this.dispatch(eventData.message.topicName, parsed);
|
|
206
|
+
} else {
|
|
207
|
+
logger.warn(`Empty payload received on topic: ${topic}`);
|
|
208
|
+
}
|
|
209
|
+
} catch (e) {
|
|
210
|
+
logger.error(
|
|
211
|
+
`Error parsing message on topic ${
|
|
212
|
+
eventData.message.topicName
|
|
213
|
+
}!:\n${stringifyError(e)}`
|
|
214
|
+
);
|
|
215
|
+
}
|
|
118
216
|
}
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
public waitForConnection(timeoutMs = 10000): Promise<void> {
|
|
221
|
+
return new Promise((resolve, reject) => {
|
|
222
|
+
if (this.connected) {
|
|
223
|
+
return resolve(); // already connected
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const timeout = setTimeout(() => {
|
|
227
|
+
reject(new Error('Timed out waiting for MQTT connection'));
|
|
228
|
+
}, timeoutMs);
|
|
229
|
+
|
|
230
|
+
this.client.on('connectionSuccess', () => {
|
|
231
|
+
clearTimeout(timeout);
|
|
232
|
+
this.connected = true;
|
|
233
|
+
resolve();
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
this.client.on('disconnection', (event) => {
|
|
237
|
+
const errorString = event.error
|
|
238
|
+
? event.error.toString()
|
|
239
|
+
: 'Unknown reason';
|
|
240
|
+
logger.warn(
|
|
241
|
+
`Disconnected while waiting for connection: ${errorString}`
|
|
242
|
+
);
|
|
243
|
+
reject(new Error(`Disconnected: ${errorString}`));
|
|
244
|
+
});
|
|
119
245
|
});
|
|
120
246
|
}
|
|
121
247
|
|
|
@@ -15,16 +15,16 @@ import { getDeviceAgentVersion } from '../util/check-for-updates';
|
|
|
15
15
|
import { getDeviceUuid } from '../util/get-device-id';
|
|
16
16
|
import { logger } from '../util/logger';
|
|
17
17
|
import sleep from '../util/sleep';
|
|
18
|
-
import { bootstrapProvision } from './bootstrap-provision';
|
|
19
18
|
import { LiveUpdatesHandler } from './live-updates-handler';
|
|
20
19
|
import { PassthroughHandler } from './passthrough-handler';
|
|
21
20
|
import { Publisher } from './publisher';
|
|
22
21
|
import { ShadowHandler, ProjectShadowMessageHandler } from './shadow-handler';
|
|
23
22
|
import { JobHandler } from '../jobs/job-handler';
|
|
24
23
|
import { TransactionManager } from './transaction-manager';
|
|
25
|
-
import { ConnectionManager } from './connection-manager';
|
|
24
|
+
import { ConnectionManager, DeviceAgentConfigType } from './connection-manager';
|
|
26
25
|
import { DeviceAgentMessageHandler } from './device-agent-message-handler';
|
|
27
26
|
import { HandlerContext } from './base-message-handler';
|
|
27
|
+
import { BootstrapAgent } from './bootstrap-agent';
|
|
28
28
|
|
|
29
29
|
export class DeviceAgentCloudConnection {
|
|
30
30
|
private connectionManager: ConnectionManager;
|
|
@@ -42,11 +42,12 @@ export class DeviceAgentCloudConnection {
|
|
|
42
42
|
|
|
43
43
|
constructor() {
|
|
44
44
|
// Initialize & setup the connection
|
|
45
|
-
|
|
46
|
-
this.clientId,
|
|
47
|
-
this.host,
|
|
48
|
-
this.port
|
|
49
|
-
|
|
45
|
+
const deviceAgentConfig: DeviceAgentConfigType = {
|
|
46
|
+
clientId: this.clientId,
|
|
47
|
+
host: this.host,
|
|
48
|
+
port: this.port
|
|
49
|
+
};
|
|
50
|
+
this.connectionManager = new ConnectionManager(deviceAgentConfig);
|
|
50
51
|
|
|
51
52
|
this.publisher = new Publisher(this.connectionManager, this.clientId);
|
|
52
53
|
this.shadowHandler = new ShadowHandler(this.clientId, this.publisher);
|
|
@@ -153,7 +154,7 @@ export class DeviceAgentCloudConnection {
|
|
|
153
154
|
// lost since we aren't waiting for responses so sleep for a short time to
|
|
154
155
|
// receive them
|
|
155
156
|
await sleep(1000);
|
|
156
|
-
this.connectionManager.disconnect();
|
|
157
|
+
await this.connectionManager.disconnect();
|
|
157
158
|
}
|
|
158
159
|
|
|
159
160
|
// CLI methods
|
|
@@ -180,7 +181,8 @@ export async function runDeviceAgentCloudInterface() {
|
|
|
180
181
|
`Starting alwaysAI Device Agent v${await getDeviceAgentVersion()}`
|
|
181
182
|
);
|
|
182
183
|
if (existsSync(getBootstrapPrivateKeyFilePath())) {
|
|
183
|
-
|
|
184
|
+
const bootstrapAgent = new BootstrapAgent();
|
|
185
|
+
await bootstrapAgent.bootstrapProvision();
|
|
184
186
|
return;
|
|
185
187
|
}
|
|
186
188
|
|