send c-like struct as arrayBuffer via udp chrome socket - google-chrome

i'm using chrome.sockets to send udp messages.
i need to send this c-like struct:
UInt16 ID=0,
UInt Size=20,
UInt16 CRC=0,
UInt16 MsgCount=0,
UInt32 App=0,
UInt32 Port=55555,
UInt32 Token=0
the chrome.udp.send needs to get an arrayBuffer.
what i did in my code is this:
var arrayBuffer = new ArrayBuffer(20);
var dv = new DataView(arrayBuffer,0);
dv.setUint16(0,0);
dv.setUint16(2,20);
dv.setUint16(4,0);
dv.setUint16(6,0);
dv.setUint32(8,0);
dv.setUint32(12,55555);
dv.setUint32(16,0);
but when i
console.log(arrayBuffer);
i get
ArrayBuffer {}
it is empty.
How can i send a c-like struct like this correctly?
Thanks!

ArrayBuffer stores bytes - any byte values at all.
console.log() expects human-readable ASCII strings, so that it can display them.
Unfortunately, logging an ArrayBuffer doesn't help - as soon as there's an ASCII NUL character (and your data has one in the very first byte) the string stops. You will need to write a different function to accept an ArrayBuffer and produce a Hex string that you can pass to console.log()

Related

json-c json_object_to_json_string() equivalent api in jansson library

In the Current code i'm using json-c. i'm migrating to jansson.
need an equivalent api in jansson which converts the json_object_to_json_string.
i found one but it needs a json string object otherwise it is returning null.
const char *json_string_value(const json_t *string) - not working
but my input is a JSON object not a JSON string
sample:
json_object *jobj = json_object_new_object();
....
const char *final_string = json_object_to_json_string(jobj);
Thanks.
I was in your position just recently, I believe the function you are looking for is:
char *json_dumps(const json_t *json, size_t flags)
Returns the JSON representation of json as a string, or NULL on error. flags is described above. The return value must be freed by the caller using free().
https://jansson.readthedocs.io/en/2.8/apiref.html#c.json_dumps

Decode of json uint8 array

I received the uint8 array json style data and print it as strings, it shown like: AADAfwAAwH8AAMB/AAAAAAAAwH8AAMB/AADAfwAAAAAAAMB/AADAfwAAwH8AAAAAAADAfwAAwH8AAMB/AAAA
It should be some numbers, so I don't know how to decode it, it looks like Base64 but actually I cannot decode like that.
What language?
C# to decode from JSON to bytes:
byte[] bytes = Encoding.Default.GetBytes(json);
C++ to decode from JSON to bytes:
(uint8*)TCHAR_TO_UTF8(json)

parse json file from internet (with lots of quotes: " (not \")) with the Arduino JSON library

i need to parse a json file from the internet with my arduino uno r3
(i cannot change the output / file), i have to use it as it is...
My json file i get from the internet looks like this: (example from https://github.com/bblanchon/ArduinoJson)
char json[] = "{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}";
The problem are the quotes "" inside the brackets,
If i change all quotes to \" everything works:
I provide an working Example from ArduinoJson library page:
char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
StaticJsonBuffer<200> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(json);
const char* sensor = root["sensor"];
long time = root["time"];
double latitude = root["data"][0];
double longitude = root["data"][1];
QUESTION:
How to replace the quotes, change them on the fly, or create the variable directly without the quotes, i need to parse the content afterwards.
Your problem is how you get the data from the client.
You only read one char and not all the data.
Try something like this:
I don't have a wifi or ethernet shield I cannot test, so I don't know if your lib will skip the http headers.
Try to print data after the loop to check.
char data[1024];
void loop(void ) {
int pos = 0;
memset(&data, 0, sizeof(data));
/* here your code for the GET
client.println("GET live.kvv.de/webapp/departures/bystop/…);
*/
while (client.available() && pos < sizeof(data) - 1) {
data[pos++] = client.read();
}
/* now you have all the data
XXX: check if you need to skip http headers
TODO: trigger an error is data is too small
*/
jsonBuffer.parseObject(data);

Strange Base64 encode/decode problem

I'm using Grails 1.3.7. I have some code that uses the built-in base64Encode function and base64Decode function. It all works fine in simple test cases where I encode some binary data and then decode the resulting string and write it to a new file. In this case the files are identical.
But then I wrote a web service that took the base64 encoded data as a parameter in a POST call. Although the length of the base64 data is identical to the string I passed into the function, the contents of the base64 data are being modified. I spend DAYS debugging this and finally wrote a test controller that passed the data in base64 to post and also took the name of a local file with the correct base64 encoded data, as in:
data=AAA-base-64-data...&testFilename=/name/of/file/with/base64data
Within the test function I compared every byte in the incoming data parameter with the appropriate byte in the test file. I found that somehow every "+" character in the input data parameter had been replaced with a " " (space, ordinal ascii 32). Huh? What could have done that?
To be sure I was correct, I added a line that said:
data = data.replaceAll(' ', '+')
and sure enough the data decoded exactly right. I tried it with arbitrarily long binary files and it now works every time. But I can't figure out for the life of me what would be modifying the data parameter in the post to convert the ord(43) character to ord(32)? I know that the plus sign is one of the 2 somewhat platform dependent characters in the base64 spec, but given that I am doing the encoding and decoding on the same machine for now I am super puzzled what caused this. Sure I have a "fix" since I can make it work, but I am nervous about "fixes" that I don't understand.
The code is too big to post here, but I get the base64 encoding like so:
def inputFile = new File(inputFilename)
def rawData = inputFile.getBytes()
def encoded = rawData.encodeBase64().toString()
I then write that encoded string out to new a file so I can use it for testing later. If I load that file back in as so I get the same rawData:
def encodedFile = new File(encodedFilename)
String encoded = encodedFile.getText()
byte[] rawData = encoded.decodeBase64()
So all that is good. Now assume I take the "encoded" variable and add it to a param to a POST function like so:
String queryString = "data=$encoded"
String url = "http://localhost:8080/some_web_service"
def results = urlPost(url, queryString)
def urlPost(String urlString, String queryString) {
def url = new URL(urlString)
def connection = url.openConnection()
connection.setRequestMethod("POST")
connection.doOutput = true
def writer = new OutputStreamWriter(connection.outputStream)
writer.write(queryString)
writer.flush()
writer.close()
connection.connect()
return (connection.responseCode == 200) ? connection.content.text : "error $connection.responseCode, $connection.responseMessage"
}
on the web service side, in the controller I get the parameter like so:
String data = params?.data
println "incoming data parameter has length of ${data.size()}" //confirm right size
//unless I run the following line, the data does not decode to the same source
data = data.replaceAll(' ', '+')
//as long as I replace spaces with plus, this decodes correctly, why?
byte[] bytedata = data.decodeBase64()
Sorry for the long rant, but I'd really love to understand why I had to do the "replace space with plus sign" to get this to decode correctly. Is there some problem with the plus sign being used in a request parameter?
Whatever populates params expects the request to be a URL-encoded form (specifically, application/x-www-form-urlencoded, where "+" means space), but you didn't URL-encode it. I don't know what functions your language provides, but in pseudo code, queryString should be constructed from
concat(uri_escape("data"), "=", uri_escape(base64_encode(rawBytes)))
which simplifies to
concat("data=", uri_escape(base64_encode(rawBytes)))
The "+" characters will be replaced with "%2B".
You have to use a special base64encode which is also url-safe. The problem is that standard base64encode includes +, / and = characters which are replaced by the percent-encoded version.
http://en.wikipedia.org/wiki/Base64#URL_applications
I'm using the following code in php:
/**
* Custom base64 encoding. Replace unsafe url chars
*
* #param string $val
* #return string
*/
static function base64_url_encode($val) {
return strtr(base64_encode($val), '+/=', '-_,');
}
/**
* Custom base64 decode. Replace custom url safe values with normal
* base64 characters before decoding.
*
* #param string $val
* #return string
*/
static function base64_url_decode($val) {
return base64_decode(strtr($val, '-_,', '+/='));
}
Because it is a parameter to a POST you must URL encode the data.
See http://en.wikipedia.org/wiki/Percent-encoding
paraquote from the wikipedia link
The encoding used by default is based
on a very early version of the general
URI percent-encoding rules, with a
number of modifications such as
newline normalization and replacing
spaces with "+" instead of "%20"
another hidden pitfall everyday web developers like myself know little about

Get the byte length of a string

Is there an easy way to get the byte length of a string in AS3? String.length works in many cases, but breaks if it encounters mulibyte unicode characters.
(in this particular case, I need to know this so I can preface messages sent across a TCP socket with the message length. This is in standard netstring format e.g. "length:message,").
Use a ByteArray like so:
var b:ByteArray = new ByteArray();
b.writeUTFBytes("This is my test string");
trace("Byte length: " + b.length);
Info on ByteArray here: http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/utils/ByteArray.html