Direct method failing when using Azure IOT Direct methods - azure-iot-hub

I am currently using the azure-iot-sdk-c on the TI CC-3235 microcontroller. I tried using the Azure Direct methods to invoke a method (blinkLED1) on the microcontroller. Azure IoT hub gives me an error saying "not registered" like below:
{"message":"Device {\"Message\":\"{\\\"errorCode\\\":404103,\\\"trackingId\\\":\\\"c1763a63a5b54381aa555198de1e884c-TimeStamp:07/01/2020 12:03:39\\\",\\\"message\\\":\\\"Timed out waiting for device to connect.\\\",\\\"info\\\":{\\\"timeout\\\":\\\"00:03:45\\\"},\\\"timestampUtc\\\":\\\"2020-07-01T12:03:39.1927271Z\\\"}\",\"ExceptionMessage\":\"\"} not registered"}
The code below is a modification of the example code from TI/Microsoft. The microcontroller C code is below:
{
(void)userContextCallback;
(void)payload;
Display_printf(display, 0, 0, "\r\nDevice Method called");
Display_printf(display, 0, 0, "Device Method name: %s", method_name);
Display_printf(display, 0, 0, "Device Method payload: %.*s", (int)size, (const char*)payload);
int status = 200;
char* RESPONSE_STRING = "{ \"Response\": \"This is the response from the device\" }";
Display_printf(display, 0, 0, "\r\nResponse status: %d", status);
Display_printf(display, 0, 0, "Response payload: %s\r\n", RESPONSE_STRING);
if(strcmp("blinkLED1",method_name)==0){
const char deviceMethodResponse[] = "{\"Response\":\"LED Blink1 Received\"}";
Display_printf(display, 0, 0, "\r\nDevice Method called");
*resp_size = sizeof(deviceMethodResponse)-1;
*response = malloc(*resp_size);
(void)memcpy(*response, deviceMethodResponse, *resp_size);
status = 200;
}
*resp_size = strlen(RESPONSE_STRING);
if ((*response = malloc(*resp_size)) == NULL)
{
status = -1;
}
else
{
(void)memcpy(*response, RESPONSE_STRING, *resp_size);
}
g_continueRunning = false;
return status;
}
TI Example reference:iothub_client_sample_device_method
Azure IoT SDK C Reference :Run a simple device Twin C sample on Windows

Related

LWIP CGI handler how to post data to webpage as JSON

LWIP CGI on STM32 web server application cgi callback is receiving on CGI handler properly but the handler return the html page tag name , instead of that how could we send a requested data from web the cgi handler is as below
const char *CGIsetting_Handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[])
{
if (iIndex == 1)
{
}
return "/index.html";
}
Instead of this how send a data the html
webpage is expecting data as below
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4) {
if (this.status == 200) {
console.log(JSON.parse(this.responseText));
document.getElementById("infoDesc").innerHTML = JSON.parse(this.responseText).Description;
document.getElementById("infoSerial").innerHTML = JSON.parse(this.responseText).Serial_Number;
document.getElementById("infoTag").innerHTML = JSON.parse(this.responseText).Device_Tag;
document.getElementById("infoContact").innerHTML = JSON.parse(this.responseText).Contact;
document.getElementById("infoVersion").innerHTML = JSON.parse(this.responseText).Firmware_Version;
} else {
console.log("response ", this.status);
}
}
};
xhttp.open("GET", "getSystemSettings.cgi", true);
xhttp.send();
On const char *CGIsetting_Handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[])
you can return like
return "/logList.json";
But then you should provide some data in
int fs_open_custom(struct fs_file *file, const char *name){
if (!strcmp(name, "/logList.json")) {
memset(file, 0, sizeof(struct fs_file));
file->pextension = (void *)&generated_logfile;
if (file->pextension != NULL)
{
int result;
result = generate_json_logfile(file);
if (result < 0)
{
return 0;
}
// 0 - 404
// 1 - 200
return 1;}}}
In my case generate_json_logfile is static char buffer which filled with formatted output. If you put correct json data in that buffer it would be enough for browser.

For loop inside a Redis queue does not work as expected in NestJs

I have the following code, basically it is doing a bruteforce on a key of a hash in the first 4 bytes. Then I loop through each of these positions to test all possible combinations. If I put this code inside the service it runs normally and takes about 200 seconds to find all possible combinations of the first 4 bytes.
But when you're doing long operations, it's good to have a queue to do this in the background. That's what I did, I added it to a nestjs queue with redis but inside the queue when I use for it seems that they are shuffled and they all end together in less than 5 seconds, besides that I don't find the correct combination. And if I use a forEach it either doesn't work or the program crashes during execution.
Basically the first 4 bytes are [192, 156, 127, 0, ...] but it doesn't find it when it's inside a queue. How can I make the background queue run normally as if it were in the service?
import * as crypto from 'crypto';
const DIFFICULTY = {
legendary: {
maxValues: [255, 255, 255, 1],
},
hard: {
maxValues: [255, 255, 255, 0],
},
medium: {
maxValues: [255, 255, 127, 0],
},
easy: {
maxValues: [255, 255, 64, 0],
},
};
#Processor('decrypt-queue')
export class DecryptConsumer {
constructor(
#InjectRepository(Chest) private readonly repository: Repository<Chest>,
) {}
#Process('decrypt-job')
async decryptJob(job: Job) {
const code = job.data;
await job.progress(50);
const chest = await this.repository.findOne({
where: {
code: code,
},
});
await this.repository.save({
...chest,
status: ChestStatus.Oppening,
});
const iv = Buffer.from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
const original = chest.key;
const range = ({
from = 0,
to,
step = 1,
length = Math.ceil((to - from) / step),
}): number[] => Array.from({ length }, (_, i) => from + i * step);
const first = range({
from: 0,
to: DIFFICULTY[chest.difficulty].maxValues[0],
step: 1,
});
const second = range({
from: 0,
to: DIFFICULTY[chest.difficulty].maxValues[1],
step: 1,
});
const third = range({
from: 0,
to: DIFFICULTY[chest.difficulty].maxValues[2],
step: 1,
});
let four = range({
from: 0,
to: DIFFICULTY[chest.difficulty].maxValues[3],
step: 1,
});
four = [0];
// first.forEach(async (i) => {
// second.forEach(async (j) => {
// third.forEach(async (k) => {
// four.forEach(async (l) => {
// console.log(i, j, k, l);
// if (
// i === original[0] &&
// j === original[1] &&
// k === original[2] &&
// l === original[3]
// ) {
// console.log(i, j, k, l, end());
// const decipher = await crypto.createDecipheriv(
// 'aes-128-cbc',
// Buffer.from([i, j, k, l, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
// iv,
// );
// let decrypted = await decipher.update(code, 'hex', 'utf8');
// decrypted += decipher.final('utf8');
// if (decrypted.includes('Hello')) {
// await this.repository.save({
// ...chest,
// status: ChestStatus.Openned,
// });
// await job.progress(100);
// // return {
// // decrypted,
// // };
// } else {
// }
// }
// });
// });
// });
// });
for (let i = 0; i < DIFFICULTY[chest.difficulty].maxValues[0]; i++) {
for (let j = 0; j < DIFFICULTY[chest.difficulty].maxValues[1]; j++) {
for (let k = 0; k < DIFFICULTY[chest.difficulty].maxValues[2]; k++) {
for (let l = 0; l < DIFFICULTY[chest.difficulty].maxValues[3]; l++) {
if (
i === original[0] &&
j === original[1] &&
k === original[2] &&
l === original[3]
) {
console.log(i, j, k, l, end());
const decipher = await crypto.createDecipheriv(
'aes-128-cbc',
Buffer.from([i, j, k, l, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
iv,
);
let decrypted = await decipher.update(code, 'hex', 'utf8');
decrypted += decipher.final('utf8');
if (decrypted.includes('Hello')) {
await this.repository.save({
...chest,
status: ChestStatus.Openned,
});
await job.progress(100);
// return {
// decrypted,
// };
} else {
}
}
}
}
}
}
await this.repository.save({
...chest,
status: ChestStatus.Locked,
});
await job.progress(100);
// return {
// decrypted: false,
// };
}
}

Agora cloud recording not saving video in azure

static startRecording = async (resourceId, channelName, idsToUse) => {
let startDateTime = Date.now();
console.log("Total ID USER MAP Time = " + (Date.now() - startDateTime) / 1000);
try {
const request = {
uid: '999',
cname: `${channelName}`,
clientRequest: {
token: EventService.getRecordingToken(channelName),//tocken of 999
recordingConfig: {
maxIdleTime: 120,
streamTypes: 2,
channelType: 0,
videoStreamType: 0,
subscribeVideoUids: [idsToUse.uId + ""],
subscribeAudioUids: [idsToUse.uId + ""],
subscribeUidGroup: 0
},
recordingFileConfig: {
avFileType: ["hls"]
},
storageConfig: {
accessKey: "ACCESS KEY",
region: 0,//The region parameter has no effect, whether or not it is set.(Ref:https://docs.agora.io/en/cloud-recording/cloud_recording_api_rest?platform=RESTful)
bucket: `azure-recordings/${channelName}`,
secretKey: "SECRET KEY",
vendor: 5
}
}
};
console.log("agoraApiCallConfig", agoraApiCallConfig);
console.log("req", request);
const requestUrl = `${AgoraBaseUrl}/v1/apps/${AgoraAppID}/cloud_recording/resourceid/${resourceId}/mode/individual/start`;
const start = Date.now();
console.log("req--", requestUrl);
const response = await axios.post(requestUrl, request, agoraApiCallConfig);
const stop = Date.now();
const elapsed = stop - start;
//console.log("Total Start Recording Time = " + elapsed / 1000);
console.log("response.data", response.data);
if (response.status == 200 || response.status == 201) {
return response.data;
}
log(response.data, "error");
throw Error("Recording starting failed with status code: " + response.status);
} catch (e) {
appInsightLogHelper.trackException(e, 4);
throw e;
}
};
this is my code for recording and storing data in azure can anyone guide me why the data is not moving in azure?
I am going live on my app and then I try to record that live with a bot user and then store that in blob service in azure storage container.
I too was struggling with Agora.io and Azure integration just yesterday, and had same-ish troubles.
After asking their support, I came to understand that storageConfig for Azure Storage Account must be set as follows:
{
vendor: 5,
region = 0,
accessKey = <storage account name>,
secretKey = <access key>,
bucket = <container name>,
fileNamePrefix = ["directory", "subdirectory"]
}
Therefore if you want to save to storage account named "junaidstorageaccount", in container "azure-recordings" and directory {channelName}, the config you should use would be as follows:
{
vendor: 5,
region: 0,
accessKey: 'junaidstorageaccount',
secretKey: <access key>,
bucket: 'azure-recordings',
fileNamePrefix: [channelName]
}
Notes:
region is unused, you can omit it or set to anything, I prefer to set to zero
Replace with access key to the Storage Account
fileNamePrefix: an array representing the path of directories in which to store the files. So if you want to store files in my/beautiful/directory, you'll have to pass ['my', 'beautiful', 'directory']
As per Agora documentation (https://docs.agora.io/en/cloud-recording/integration_best_practices?platform=RESTful#a-namestart_successaensure-the-recording-service-starts-successfully), you should call query after calling start to check the recording status (it should be 4 or 5), and keep checking for all the recording duration, at intervals less than maxIdleTime.
Wishing you best of luck!

Swift 5 AES Encryption/Decryption using CommonCrypto

I've been trying to use the CommonCrypto in iOS to do a blockwise decryption of a larger Data object, but I can't get it to work. I've been reading the documentation, and looked at several examples from Objective-C - none of which I managed to get to work in an Objective-C environment. After 3 days of coding this I'm starting to wear out and I need some help.
I can decrypt and encrypt fine using the CCCrypto approach, but since I use rather large files this eats up too much memory for iOS to allow me to use this method. Thus I need to do this more efficiently and I decided to try an approach where I decipher one block at a time and then replace the block I deciphered with the resulting data block. The code runs, it seems to be working except for the fact that the data I get won't decode back to an UTF8 String.
Code for using CCCryptoCreate() with symmetric block deciphering (DataExtension)
mutating func decryptUsingCCCryptoCreate() {
// Get the first 16 bytes as IV
let IV = self.prefix(kCCBlockSizeAES128)
// Get key as array of bytes
let key = "ABCDEFGHIJKLMNOPQRSABCDEFGHIJKLM".data(using: .utf8) ?? Data()
// Setup totalSize
let totalSize = self.count
let operation = kCCDecrypt
let algorithm = kCCAlgorithmAES
let options = kCCOptionPKCS7Padding
var cryptorRef: CCCryptorRef?
// Step one is to create the CCCryptor with correct parameters for AES128 decryption
var status = CCCryptorCreate(CCOperation(operation), CCAlgorithm(algorithm), CCOptions(options), key.withUnsafeBytes { $0.baseAddress }, key.count, IV.withUnsafeBytes { $0.baseAddress }, &cryptorRef)
if status != kCCSuccess {
print("Failed on create: \(status.description)")
return
}
var dataOutMoved: size_t = 0 // The actual data moved
var dataInLength: size_t = kCCBlockSizeAES128 // The in size will always be the size of a kCCBlockSizeAES128
var dataOutLength: size_t = CCCryptorGetOutputLength(cryptorRef, dataInLength, false) // DataOutLength is always less than or equal to the dataInLength
var totalLength: size_t = 0 // The actual length of the deciphered data
var filePtr: size_t = 0 // Keeps track of the current position in the deciphering process
var startByte: Int = 0 // Increments each time with the kCCBlockSizeAES128 until we are done
var dataIn = Data() // Buffer to store the encrypted block to be deciphered
var dataOut = Data() // Buffer to store the decrypted block result
// While startByte is less than totalSize we continue to decrypt the next block
while startByte <= totalSize {
if startByte + kCCBlockSizeAES128 > totalSize {
dataInLength = totalSize - startByte
} else {
dataInLength = kCCBlockSizeAES128
}
// Next block to decrypt
guard let rangeToDecrypt = Range(NSRange(location: startByte, length: dataInLength)) else { return }
dataIn = self.subdata(in: rangeToDecrypt)
// Decipher the block
status = CCCryptorUpdate(cryptorRef, dataIn.withUnsafeBytes { $0.baseAddress }, dataInLength, dataOut.withUnsafeMutableBytes { $0.baseAddress }, dataOutLength, &dataOutMoved)
if status != kCCSuccess {
print("Failed on Update: \(status.description)")
return
}
// Replace the encrypted block with the decrypted block
let rangeToReplace = Range(NSRange(location: filePtr, length: dataOutMoved))!
self.replaceSubrange(rangeToReplace, with: dataOut.withUnsafeBytes { $0.baseAddress! }, count: dataOutMoved)
totalLength += dataOutMoved
filePtr += dataOutMoved
startByte += kCCBlockSizeAES128
}
// Finalize the deciphering
status = CCCryptorFinal(cryptorRef, dataOut.withUnsafeMutableBytes { $0.baseAddress }, dataOutLength, &dataOutMoved)
totalLength += dataOutMoved
if status != kCCSuccess {
print("Failed on final: \(status.description)")
return
}
// We replace the final deciphered block
let decryptedRange = Range(NSRange(location: filePtr, length: dataOutMoved))!
self.replaceSubrange(decryptedRange, with: dataOut.withUnsafeBytes { $0.baseAddress! }, count: dataOut.count)
// Since we are using padding the CCCryptorFinal can contain padding which needs to be truncated.
self = self.prefix(totalLength)
// Finish the CCCryptor process
CCCryptorRelease(cryptorRef)
}
Code for the encryption using CCCrypto()
mutating func encryptUsingCCCrypto() {
let sa = String(data: self, encoding: .utf8) ?? ""
print("Before encryption: \(sa)")
let now = Date()
let key = "ABCDEFGHIJKLMNOPQRSABCDEFGHIJKLM".data(using: .utf8) ?? Data()
let ivRandomData = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
let blockSize = kCCBlockSizeAES128
let bufferSize = self.count + blockSize
var encryptedSize = 0
let cryptStatus = CCCrypt(UInt32(kCCEncrypt),
UInt32(kCCAlgorithmAES),
UInt32(kCCOptionPKCS7Padding),
key.withUnsafeBytes { $0.baseAddress },
key.count,
ivRandomData.withUnsafeBytes { $0.baseAddress },
self.withUnsafeBytes { $0.baseAddress },
self.count,
self.withUnsafeMutableBytes { $0.baseAddress },
bufferSize,
&encryptedSize)
self = self.prefix(encryptedSize)
let s = String(data: self, encoding: .utf8) ?? ""
print("Result: \(s)")
}
I use the code like this:
let string = "1234123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234"
var data = string.data(using: .utf8) ?? Data()
data.encryptUsingCCCrypto()
data.decryptUsingCCCryptoCreate() // I get a Data object with 112 bytes here
let s = String(data: data, encoding: .utf8) ?? "" // String is nil, and is provided ""

Dynamics CRM Web Api Function: Illegal characters in path when using encodeURIComponent

I'm trying to use the Search Function (https://msdn.microsoft.com/en-us/library/mt608029.aspx) via the Dynamics CRM 2016 Web API. This is my code:
var start = new Date(2016, 2, 1, 17, 0, 0);
var end = new Date(2016, 2, 10, 18, 0, 0);
var request = new Object();
request.AppointmentRequest = new Object();
request.AppointmentRequest.SearchWindowStart = start.toISOString();
request.AppointmentRequest.SearchWindowEnd = end.toISOString();
request.AppointmentRequest.ServiceId = "5f3b6e7f-48c0-e511-80d7-d89d67631c44";
request.AppointmentRequest.Direction = 0;
request.AppointmentRequest.NumberOfResults = 10;
request.AppointmentRequest.UserTimeZone = 1;
var req = new XMLHttpRequest()
req.open("GET", clientUrl + "/api/data/v8.0/Search(" + encodeURIComponent( JSON.stringify(request) ) +")", true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.onreadystatechange = function () {
if (req.readyState == 4 && req.status == 200) {
alert(req.responseText);
}
else {
alert(req.response);
}
};
req.send();
When I initially tried this using CRM Online I received the following error:
"An error has occurred.
Try this action again. If the problem continues, check the Microsoft Dynamics >CRM Community for solutions or contact your organization's Microsoft >Dynamics CRM Administrator. Finally, you can contact Microsoft Support."
When I try this with an On-Premise deployment with DevErrors="On" in the web.config, I see the following error in the Event Viewer:
Exception information:
Exception type: HttpException
Exception message: A potentially dangerous Request.Path value was detected >from the client (:).
at System.Web.HttpRequest.ValidateInputIfRequiredByConfig()
at System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext >context)
Request information:
Request URL: http://win-0e5dfqgqorm:444/ORG/api/data/v8.0/Search({"AppointmentRequest":{"SearchWindowStart":"2016-03-01T17:00:00.000Z","SearchWindowEnd":"2016-03-10T18:00:00.000Z","ServiceId":"5f3b6e7f-48c0-e511-80d7-d89d67631c44","Direction":0,"NumberOfResults":10,"UserTimeZone":1}})
Request path: /SHUDEV/api/data/v8.0/Search({"AppointmentRequest":{"SearchWindowStart":"2016-03-01T17:00:00.000Z","SearchWindowEnd":"2016-03-10T18:00:00.000Z","ServiceId":"5f3b6e7f-48c0-e511-80d7-d89d67631c44","Direction":0,"NumberOfResults":10,"UserTimeZone":1}})
The JSON object is encoded so I'm not sure why it's detected illegal characters. The SDK documentation for the Web Api is light and doesn't go into too much detail as to how to pass a ComplexType to a Web Api function, has anyone seen this issue before/managed to pass a ComplexType to a Web Api function?
Thanks in advance.
I managed to resolve this issue. The key is to pass the JSON object in as a query parameter:
var request = new Object();
request.SearchWindowStart = start.toISOString();
request.SearchWindowEnd = end.toISOString();
request.ServiceId = "5f3b6e7f-48c0-e511-80d7-d89d67631c44";
request.Direction = '0';
request.NumberOfResults = 10;
request.UserTimeZoneCode = 1;
var req = new XMLHttpRequest()
req.open("GET", clientUrl + "/api/data/v8.0/Search(AppointmentRequest=#request)?#request=" + JSON.stringify(request) , true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.onreadystatechange = function () {
if (req.readyState == 4 && req.status == 200) {
alert(req.responseText);
}
else {
alert(req.response);
}
};
req.send();
This is documented in the SDK: https://msdn.microsoft.com/en-us/library/gg309638.aspx.
Hope this helps anyone who runs into a similar issue.