forked from Azure/azure-iot-sdk-node
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdmpatterns_fwupdate_device.js
158 lines (145 loc) · 4.78 KB
/
dmpatterns_fwupdate_device.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
'use strict';
var Client = require('azure-iot-device').Client;
var Protocol = require('azure-iot-device-mqtt').Mqtt;
var url = require('url');
var async = require('async');
// receive the IoT Hub device connection string as a command line parameter
if(process.argv.length < 3) {
console.error('Usage: node dmpatterns_fwupdate_device.js <<IoT Hub Device Connection String>>');
process.exit(1);
}
var connectionString = process.argv[2];
var client = Client.fromConnectionString(connectionString, Protocol);
client.open(function(err) {
if (!err) {
client.onDeviceMethod('firmwareUpdate', function(request, response) {
// Get the firmware image Uri from the body of the method request
var fwPackageUri = request.payload.fwPackageUri;
var fwPackageUriObj = url.parse(fwPackageUri);
// Ensure that the url is to a secure url
if (fwPackageUriObj.protocol !== 'https:') {
response.send(400, 'Invalid URL format. Must use https:// protocol.', function(err) {
if (err) console.error('Error sending method response :\n' + err.toString());
else console.log('Response to method \'' + request.methodName + '\' sent successfully.');
});
} else {
// Respond the cloud app for the device method
response.send(200, 'Firmware update started.', function(err) {
if (err) console.error('Error sending method response :\n' + err.toString());
else console.log('Response to method \'' + request.methodName + '\' sent successfully.');
});
initiateFirmwareUpdateFlow(fwPackageUri, function(err){
if (!err) console.log("Completed firmwareUpdate flow");
});
}
});
console.log('Client connected to IoT Hub. Waiting for firmwareUpdate device method.');
}
});
// Implementation of firmwareUpdate flow
function initiateFirmwareUpdateFlow(fwPackageUri, callback) {
async.waterfall([
function (callback) {
downloadImage(fwPackageUri, callback);
},
applyImage
], function(err) {
if (err) {
console.error('Error : ' + err.message);
}
callback(err);
});
}
// Function that implements the 'downloadImage' phase of the
// firmware update process.
function downloadImage(fwPackageUriVal, callback) {
var imageResult = '[Fake firmware image data]';
async.waterfall([
function (callback) {
reportFWUpdateThroughTwin ({
status: 'downloading',
startedDownloadingTime: new Date().toISOString()
},
callback);
},
function (callback) {
console.log("Downloading image from URI: " + fwPackageUriVal);
// Replace this line with the code to download the image. Delay used to simulate the download.
setTimeout(function() {
callback(null);
}, 4000);
},
function (callback) {
reportFWUpdateThroughTwin ({
status: 'download complete',
downloadCompleteTime : new Date().toISOString()
},
callback);
},
],
function(err) {
if (err) {
reportFWUpdateThroughTwin( { status : 'Download image failed' }, function(err) {
callback(err);
})
} else {
callback(null, imageResult);
}
});
}
// Implementation for the apply phase, which reports status after
// completing the image apply.
function applyImage(imageData, callback) {
async.waterfall([
function(callback) {
reportFWUpdateThroughTwin ({
status: 'applying',
startedApplyingImage: new Date().toISOString()
},
callback);
},
function (callback) {
console.log("Applying firmware image");
// Replace this line with the code to download the image. Delay used to simulate the download.
setTimeout(function() {
callback(null);
}, 4000);
},
function (callback) {
reportFWUpdateThroughTwin ({
status: 'apply firmware image complete',
lastFirmwareUpdate: new Date().toISOString()
},
callback);
},
],
function (err) {
if (err) {
reportFWUpdateThroughTwin({ status : 'Apply image failed' }, function(err) {
callback(err);
})
}
callback(null);
})
}
// Helper function to update the twin reported properties.
// Used by every phase of the firmware update.
function reportFWUpdateThroughTwin(firmwareUpdateValue, callback) {
var patch = {
iothubDM : {
firmwareUpdate : firmwareUpdateValue
}
};
console.log(JSON.stringify(patch, null, 2));
client.getTwin(function(err, twin) {
if (!err) {
twin.properties.reported.update(patch, function(err) {
callback(err);
});
} else {
callback(err);
}
});
};