Receiving a TypeError for UDP scan data - actions-on-google

Using the Local Home SDK developer preview for Google Assistant, I'm receiving a TypeError from my application during IDENTIFY that was previously working correctly. The error is claiming that UdpScanData is not a valid string when I try to decode the payload.
Example code:
const device = identifyRequest.inputs[0].payload.device;
const response = Buffer.from(device.udpScanData, "hex");
How do I access the UDP discovery payload?

In the 0.2.0 update to the developer preview SDK, we have migrated the UdpScanData parameter to be an interface instead of just a type alias for string (see the updated reference docs) to improve consistency with the other scan data types.
To access the response payload for a UDP scan in the latest SDK, update your package.json dependencies to use v0.2.0:
{
...
"dependencies": {
"#google/local-home-sdk": "^0.2.0"
}
}
Then, access the payload using the new data property:
const device = identifyRequest.inputs[0].payload.device;
const scanData = device.udpScanData;
const response = Buffer.from(scanData.data, "hex");

Related

Is there yet an idiomatic way to make native calls to AWS Lambda or API Gateway from a Flutter application?

Goal: Make a signed request (SigV4) to AWS Lambda or API Gateway from a Flutter application (iOS, for the sake of this question).
For context, AWS introduced support for "native calls to AWS backends in [...] Flutter or Dart applications" back in May of 2022. There is an example of how to sign a request to Cognito to gather information about a User Pool, but I have not seen any application of this concept for Lambda or API Gateway calls, yet.
I'm wondering if anyone else has had success using AWS's official Dart packages to send signed requests or knows of another way to securely call AWS from a Flutter application.
EDIT:
I was able to accomplish the goal. Here's how I did it:
The code (all-caps denotes placeholders for your own values):
import 'dart:convert';
import 'package:aws_common/aws_common.dart';
import 'package:aws_signature_v4/aws_signature_v4.dart';
const signer = AWSSigV4Signer(
credentialsProvider: AWSCredentialsProvider.dartEnvironment(),
);
const region = 'REGION';
Future<void> yourFunction() async {
final scope = AWSCredentialScope(
region: region,
service: AWSService.apiGatewayV2,
dateTime: AWSDateTime(DateTime.now()),
);
final request = AWSHttpRequest(
method: AWSHttpMethod.post,
uri: Uri.https('HOST.execute-api.REGION.amazonaws.com','/STAGE_NAME'),
headers: const {
AWSHeaders.contentType: 'application/x-amz-json-1.1',
},
body: json.encode({
'EVENT_KEY':'EVENT_VALUE',
}).codeUnits,
);
final signedRequest = await signer.sign(
request,
credentialScope: scope,
);
final resp = await signedRequest.send();
final respBody = await resp.decodeBody();
print('\n\n${signedRequest.headers}\n\n${respBody}\n\n${resp.statusCode}\n\n');
}
Within a single AWS region (except where n/a):
create IAM user with execute-api:Invoke permission and programmatic access; store keys securely for later use.
create a Lambda function (can be the default, for testing).
create API in API Gateway:
REST (not private)
Regional endpoint
Add method (for me, POST)
IAM authorization type
Integration type is Lambda
select the target Lambda function, but
do not use Lambda proxy
deploy the newly created API to a new stage (give it a name)
Edit your dart file to include the new resources, including the stage name.
Test your API within API Gateway (I was getting 502 until I unchecked "Lambda proxy integration").
Run the following in your terminal after a successful API test; be sure to insert the keys for the IAM user you created.
flutter run --dart-define=AWS_ACCESS_KEY_ID=... --dart-define=AWS_SECRET_ACCESS_KEY=...
Summary:
In my case, I have a button that executes this function. If you keep the print statement in the above dart code, you should hopefully see {"statusCode": 200, "body": "\"Hello from Lambda!\""} as the response body.
Hope this helps others. Cannot make any guarantees that my approach will work in another environment. I also may have forgotten to include something relevant in the steps above. Still open to questions and suggestions.
Thank you.

Azure IOT Hub Rest API Unauthorized

I am trying to use Azure Iot hub REST API to create device by following links
Create a new device identity
Control access to IoT Hub
And my http data is like
{
"status":"connected",
"authentication":{ "symmetricKey":{
"primaryKey":"key in shared access policies",
"secondaryKey":"key in shared access policies"}
},
"statusReason":"reason",
"deviceId":"test123"
}
My header is like
["Content-Type": "application/json", "Authorization": "SharedAccessSignature sig=(key in shared access policies public key)=&se=1481687791&skn=iothubowner&sr=(my iot hub name).azure-devices.net%2fdevices%2ftest123"]
But i get error 401
{"Message":"ErrorCode:IotHubUnauthorizedAccess;Unauthorized","ExceptionMessage":"Tracking ID:(tracking id )-TimeStamp:12/14/2016 03:15:17"}
Anyone know how to fixed it , or to track the exceptionMessage ?
The problem of 401 is, probably, in the way you are calculating the SAS.
The full process to calculate a SAS for the IoT Hub (in C#) is:
private static readonly DateTime epochTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
public static string SharedAccessSignature(string hostUrl, string policyName, string policyAccessKey, TimeSpan timeToLive)
{
if (string.IsNullOrWhiteSpace(hostUrl))
{
throw new ArgumentNullException(nameof(hostUrl));
}
var expires = Convert.ToInt64(DateTime.UtcNow.Add(timeToLive).Subtract(epochTime).TotalSeconds).ToString(CultureInfo.InvariantCulture);
var resourceUri = WebUtility.UrlEncode(hostUrl.ToLowerInvariant());
var toSign = string.Concat(resourceUri, "\n", expires);
var signed = Sign(toSign, policyAccessKey);
var sb = new StringBuilder();
sb.Append("sr=").Append(resourceUri)
.Append("&sig=").Append(WebUtility.UrlEncode(signed))
.Append("&se=").Append(expires);
if (!string.IsNullOrEmpty(policyName))
{
sb.Append("&skn=").Append(WebUtility.UrlEncode(policyName));
}
return sb.ToString();
}
private static string Sign(string requestString, string key)
{
using (var hmacshA256 = new HMACSHA256(Convert.FromBase64String(key)))
{
var hash = hmacshA256.ComputeHash(Encoding.UTF8.GetBytes(requestString));
return Convert.ToBase64String(hash);
}
}
If you want to create the device in the IoTHub you have to have a policy with full permissions that mean:
Registry read and write, Service connect and Device connect.
If you need a full functional example, in C#, about how use the IoT Hub REST API to create a device, check if a device exists and send messages to the IoT Hub I have wrote this post about it (the post is in spanish but I can imagine that what you need is just the code).
it looks like your SAS is wrong. It shouldn't include the devices part in the end. If you open the Iot Hub Device Explorer you can Generate SAS token to access the Iot Hub API. You should create the SAS for the IoT hub level and for a device level (which include the devive id in the SAS like you have).
So your SAS should look like this -
SharedAccessSignature sr={iot hub name}.azure-devices.net&sig={sig}&se={se}&skn=iothubowner
There are two edits you need to do:
In your http data, only deviceId is required, other are optional, you can do it like this:
{
deviceId: "test123"
}
Note that there are no double quotes around deviceId.
Like #shachar said, you need remove "%2fdevices%2ftest123" in SAS token of the header. About generating SAS token you can utilize Device Explorer.
This is my test result:
The format of SAS token you use is wrong. To create a device, you need to use SAS Token for IoT Hub. You could easily use Azure IoT Toolkit extension for Visual Studio Code to generate SAS Token for IoT Hub as below screenshot.
BTW, the format of SAS token for device is /^SharedAccessSignature sr=iot-hub-test.azure-devices.net%2Fdevices%2Fdevice1&sig=.+&se=.+$/, while the format of SAS token for IoT Hub is /^SharedAccessSignature sr=iot-hub-test.azure-devices.net&sig=.+&skn=iothubowner&se=.+$/
//Following code is to generate the SAS token programatically.
string sasToken = new SharedAccessSignatureBuilder()
{ KeyName = name,
Key = key,
Target = target,
TimeToLive = TimeSpan.FromDays(days)
}.ToSignature();
//use this sas token as authorization header before calling the iot restapi

Firebase: Authenticate an existing user using REST API and Firebases hidden Auth URL

For the past 3 years we have used HTML/Js only with Firebase but now we are using Unity as well.
The current Unity/Firebase only works on Android/iOS when deployed and 99% of our work is on the windows store.
I've actually got a pretty decent Unity/Firebase codebase going but it requires me to use a full App Secret.
All the other libraries expose a method to login with Email/Password but the REST API only allows the use of a token or your app secret that it then states is ill advised to put into your client; I guess the thinking is if you're using a different library that you'll have your own auth/user method which we don't...
Now, I've pulled apart the web version and got this:
https://auth.firebase.com/v2/<myfirebase>/auth/password?&email=dennis%40<mysite>&password=<mypassword>v=js-2.2.9&transport=json&suppress_status_codes=true
So there IS an endpoint that I can send stuff to and I've tested it inside unity with good results.
Obviously the URL isn't guaranteed to stay working but I'm wondering if there is any reason NOT to use this?
Also, Why not just expose this endpoint in the official REST API?
As I understand it, that URL will continue to work for your Legacy Firebase project. You will have to do the same sort of reverse engineering if you want to update to the new Firebase 3.0 API. However, if you are still using a legacy Firebase project -- I encourage you to take a look at this. It has not been updated to work with Firebase 3.0 -- so I needed to do something similar to what you did to allow login to the new API.
I was able to do this with the new API using C# as follows (where FirebaseManager is a Singleton I wrote for Global variables and functions to write and read from/to the DB :
Hashtable loginData = new Hashtable();
loginData.Add ("email", <EMAIL-GOES-HERE>);
loginData.Add ("password", <PASSWORD-GOES-HERE>);
loginData.Add ("returnSecureToken", true);
UnityHTTP.Request loginRequest = new UnityHTTP.Request ("post",
"https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key="
+ <YOUR-PROJECT-API-KEY-GOES-HERE>, loginData);
loginRequest.Send ((request) => {
Hashtable jsonResponse = (Hashtable)JSON.JsonDecode(request.response.Text);
if (jsonResponse == null) {
DisplayErrorMessage("Error logging in. Server returned null or malformed response");
}
FirebaseManager.Instance.idToken = (string)jsonResponse["idToken"]; // This is your auth token
FirebaseManager.Instance.uid = (string)jsonResponse["localId"]; // this is your "uid"
});
// I have a list of users in my db keyed by the "uid" -- I access them like this
UnityHTTP.Request fullnameRequest = new UnityHTTP.Request ("get",
<YOUR-DATABASE-ROOT-URL-HERE>
+ "/users/" + FirebaseManager.Instance.uid + ".json?auth=" + FirebaseManager.Instance.idToken);
fullnameRequest.Send ((request) => {
Debug.Log(request.response.Text);
Hashtable jsonResponse = (Hashtable)JSON.JsonDecode(request.response.Text);
if (jsonResponse == null) {
DisplayErrorMessage("Error getting user info. Server returned null or malformed response");
}
FirebaseManager.Instance.fullname = (string)jsonResponse["fullname"];
FirebaseManager.Instance.groupId = (string)jsonResponse["group"]; // just storing this in memory
});
So I don't think there is any harm in using the URL, just make sure you budget time for more work when things change.

Receiving data from Arduino by using Azure Mobile Services

I am working on a project where I need to read and write data from a particular column and a row from Azure Mobile Services to an Arduino. Simply, I need to read and write data to an azure mobile service by an Arduino. The writing part is pretty much done but I am facing a bit of problem in reading the data.
Here is my scenario
1: Upload sensor data from Arduino to Azure mobile service (completed almost)
2: Develop an windows phone app to access the data from azure mobile service (competed)
3: Develop an windows phone app to write data to the azure table(completed)
4: Use the data written in the above step to control my Arduino (STUCK)
Any help will be appreciated.
Assuming you have an HTTP client to do REST on your Arduino, you could do something like the following:
String read(String table) {
HttpClient http;
http_header_t headers[] = {
{ "X-ZUMO-APPLICATION", "applicationKeyHere" },
{ "Content-Type", "application/json" },
{ NULL, NULL } // NOTE: Always terminate headers with NULL
};
http_request_t request;
http_response_t response;
request.hostname = "mobileservicename.azure-mobile.net";
request.port = 80;
request.path = "/tables/" + table; //update with your table name
http.get(request, response, headers);
return response.body;
}

playready license server request only get

I use the following implementation for PlayReady on Samsung Smart TV SDK 3.5 & 4.x.
Now, in my network traces I see a plain GET Request to the license server URL being executed, but no data passed.
What could be the cause for this?
This is my code:
var VideoURL = '.........bution_deu_20_9000K.ism/Manifest';
var serverLicense = '...LicenseAcquisition.asmx';
var customData = '.....';
player.InitPlayer(VideoURL+"|COMPONENT=WMDRM");// + "|COMPONENT=WMDRM"
player.SetPlayerProperty(4, serverLicense, serverLicense.length);
player.SetPlayerProperty(3, customData, customData.length);
player.StartPlayback();
Thanks