Data payload for ZigBee thermostat to change the system mode of the thermostat in API mode - xbee

Can anyone tell me what is the data payload to change the system mode of the ZigBee based thermostat?
I have found the cluster ID and attribute ID for the system mode i.e 0x0201 (cluster ID) & 0x001C (attribute ID) but unable to frame the data payload.
Zigbee walker output
Digi International -- ZDO/ZCL Walker v1.03
Started at Mon Nov 11 10:14:28 2019
Performing discovery on 00-0d-6f-00-0a-93-e5-40.
Endpoint 0x01 Profile 0x0104 Device 0x0301 Ver 0x00
input/server cluster 0x0000
attr 0x0000, type 0x20 (UNSIGNED_8BIT) 0x01 = 1
attr 0x0002, type 0x20 (UNSIGNED_8BIT) 0x02 = 2
attr 0x0003, type 0x20 (UNSIGNED_8BIT) 0x03 = 3
attr 0x0004, type 0x42 (STRING_CHAR) "Centralite"
attr 0x0005, type 0x42 (STRING_CHAR) "3157100-E"
attr 0x0007, type 0x30 (ENUM_8BIT) 0x81 = 129
input/server cluster 0x0001
attr 0x0020, type 0x20 (UNSIGNED_8BIT) 0x1C = 28
attr 0x0036, type 0x20 (UNSIGNED_8BIT) 0x00 = 0
attr 0x0037, type 0x20 (UNSIGNED_8BIT) 0x00 = 0
attr 0x0038, type 0x20 (UNSIGNED_8BIT) 0x00 = 0
attr 0x0039, type 0x20 (UNSIGNED_8BIT) 0x00 = 0
attr 0x003E, type 0x1B (BITMAP_32BIT) 0x00000000
input/server cluster 0x0003
attr 0x0000, type 0x21 (UNSIGNED_16BIT) 0x0000 = 0
input/server cluster 0x0020
attr 0x0000, type 0x23 (UNSIGNED_32BIT) 0x00000000 = 0
attr 0x0001, type 0x23 (UNSIGNED_32BIT) 0x0000001C = 28
attr 0x0002, type 0x21 (UNSIGNED_16BIT) 0x0001 = 1
attr 0x0003, type 0x21 (UNSIGNED_16BIT) 0x0014 = 20
attr 0x0004, type 0x23 (UNSIGNED_32BIT) 0x000000F0 = 240
attr 0x0005, type 0x23 (UNSIGNED_32BIT) 0x0000001C = 28
attr 0x0006, type 0x21 (UNSIGNED_16BIT) 0x0078 = 120
input/server cluster 0x0201
attr 0x0000, type 0x29 (SIGNED_16BIT) 0x0B39 = 2873
attr 0x0003, type 0x29 (SIGNED_16BIT) 0x02BC = 700
attr 0x0004, type 0x29 (SIGNED_16BIT) 0x0BB8 = 3000
attr 0x0005, type 0x29 (SIGNED_16BIT) 0x02BC = 700
attr 0x0006, type 0x29 (SIGNED_16BIT) 0x0C80 = 3200
attr 0x0009, type 0x18 (BITMAP_8BIT) 0xFF
attr 0x0010, type 0x28 (SIGNED_8BIT) 0x00 = 0
attr 0x0011, type 0x29 (SIGNED_16BIT) 0x029A = 666
attr 0x0012, type 0x29 (SIGNED_16BIT) 0x029A = 666
attr 0x0015, type 0x29 (SIGNED_16BIT) 0x02BC = 700
attr 0x0016, type 0x29 (SIGNED_16BIT) 0x0BB8 = 3000
attr 0x0017, type 0x29 (SIGNED_16BIT) 0x02BC = 700
attr 0x0018, type 0x29 (SIGNED_16BIT) 0x0BB8 = 3000
attr 0x0019, type 0x28 (SIGNED_8BIT) 0x0A = 10
attr 0x001B, type 0x30 (ENUM_8BIT) 0x05 = 5
attr 0x001C, type 0x30 (ENUM_8BIT) 0x00 = 0
attr 0x001E, type 0x30 (ENUM_8BIT) 0x00 = 0
attr 0x0023, type 0x30 (ENUM_8BIT) 0x00 = 0
attr 0x0024, type 0x21 (UNSIGNED_16BIT) 0xFFFF = 65535
attr 0x0025, type 0x18 (BITMAP_8BIT) 0x00
attr 0x0029, type 0x19 (BITMAP_16BIT) 0x0000
attr 0x0030, type 0x30 (ENUM_8BIT) 0x00 = 0
attr 0x0031, type 0x29 (SIGNED_16BIT) 0x8000 = 32768
input/server cluster 0x0202
attr 0x0000, type 0x30 (ENUM_8BIT) 0x05 = 5
attr 0x0001, type 0x30 (ENUM_8BIT) 0x04 = 4
input/server cluster 0x0204
attr 0x0000, type 0x30 (ENUM_8BIT) 0x00 = 0
attr 0x0001, type 0x30 (ENUM_8BIT) 0x00 = 0
input/server cluster 0x0B05
attr 0x0100, type 0x23 (UNSIGNED_32BIT) 0x08000000 = 134217728
attr 0x0101, type 0x23 (UNSIGNED_32BIT) 0x08000001 = 134217729
attr 0x0102, type 0x23 (UNSIGNED_32BIT) 0x08000157 = 134218071
attr 0x0103, type 0x23 (UNSIGNED_32BIT) 0x08006CA7 = 134245543
attr 0x0104, type 0x21 (UNSIGNED_16BIT) 0x01ED = 493
attr 0x0105, type 0x21 (UNSIGNED_16BIT) 0x01EF = 495
attr 0x0106, type 0x21 (UNSIGNED_16BIT) 0x023E = 574
attr 0x0107, type 0x21 (UNSIGNED_16BIT) 0x0218 = 536
attr 0x0108, type 0x21 (UNSIGNED_16BIT) 0x0050 = 80
attr 0x0109, type 0x21 (UNSIGNED_16BIT) 0x0048 = 72
attr 0x010A, type 0x21 (UNSIGNED_16BIT) 0x0000 = 0
attr 0x010B, type 0x21 (UNSIGNED_16BIT) 0x0000 = 0
attr 0x010C, type 0x21 (UNSIGNED_16BIT) 0x0000 = 0
attr 0x010D, type 0x21 (UNSIGNED_16BIT) 0x0003 = 3
attr 0x010E, type 0x21 (UNSIGNED_16BIT) 0x0000 = 0
attr 0x010F, type 0x21 (UNSIGNED_16BIT) 0x0000 = 0
attr 0x0110, type 0x21 (UNSIGNED_16BIT) 0x0000 = 0
attr 0x0111, type 0x21 (UNSIGNED_16BIT) 0x0000 = 0
attr 0x0112, type 0x21 (UNSIGNED_16BIT) 0x0000 = 0
attr 0x0113, type 0x21 (UNSIGNED_16BIT) 0x0000 = 0
attr 0x0114, type 0x21 (UNSIGNED_16BIT) 0x0000 = 0
attr 0x0115, type 0x21 (UNSIGNED_16BIT) 0x0001 = 1
attr 0x0116, type 0x21 (UNSIGNED_16BIT) 0x0000 = 0
attr 0x0117, type 0x21 (UNSIGNED_16BIT) 0x0000 = 0
attr 0x0118, type 0x21 (UNSIGNED_16BIT) 0x0000 = 0
attr 0x0119, type 0x21 (UNSIGNED_16BIT) 0x0000 = 0
attr 0x011A, type 0x21 (UNSIGNED_16BIT) 0x0000 = 0
attr 0x011B, type 0x21 (UNSIGNED_16BIT) 0x2401 = 9217
attr 0x011C, type 0x20 (UNSIGNED_8BIT) 0xFF = 255
attr 0x011D, type 0x28 (SIGNED_8BIT) 0xDA = 218
output/client cluster 0x000A
no attributes
output/client cluster 0x0019
attr 0x0000, type 0xF0 (IEEE_ADDR) ff-ff-ff-ff-ff-ff-ff-ff
attr 0x0001, type 0x23 (UNSIGNED_32BIT) 0xFFFFFFFF = 4294967295
attr 0x0002, type 0x23 (UNSIGNED_32BIT) 0x04045010 = 67391504
attr 0x0004, type 0x23 (UNSIGNED_32BIT) 0xFFFFFFFF = 4294967295
attr 0x0006, type 0x30 (ENUM_8BIT) 0x00 = 0
attr 0x0007, type 0x21 (UNSIGNED_16BIT) 0xC2DF = 49887
attr 0x0008, type 0x21 (UNSIGNED_16BIT) 0x0023 = 35
attr 0x0009, type 0x21 (UNSIGNED_16BIT) 0x1388 = 5000
attr 0x000A, type 0x23 (UNSIGNED_32BIT) 0x5BAF4865 = 1538213989
Completed at Mon Nov 11 10:15:02 2019
(34 seconds elapsed)
I am constructing the frame as per this - [Send Zigbee cluster library (ZCL) commands with the API][1]
Following is my constructed frame to change the system mode of the thermostat still the below frame is not changing the system mode(OFF,HEAT,Cool).
7E 00 19 11 01 00 0D 6F 00 0A 93 E5 40 FF FE 01 01 02 01 01 04 00 00 00 01 00 00 1C 8B
Can someone help me with the correct frame especially with data payload part to change the system mode of the thermostat?

Have you confirmed you can join the Nest thermostat's network? You'll need to manually assemble the ZCL (Zigbee Cluster Library) frame to read or write that attribute ID.
If you have an 802.15.4 sniffer, you might be able to monitor communications between the thermostat and another device to determine what's happening, and potentially figure out how to reproduce those frames from the XBee. It's been a while since I've worked with Zigbee networks, so I don't know what the standards are for Home Automation right now, and how difficult it is to join an existing HA network.
You didn't specify a language, but Digi provides an Open Source XBee Host C Library to interface with its XBee modules (which you specified in a tag) and it includes a ZCL and ZDO/ZDP (Zigbee Data Objects/Profile) layer. One of the samples (Zigbee Walker) uses ZDO and ZCL discovery to dump a list of endpoints, clusters and attributes on a device.

Related

Synchronous baud rate (RFC2217) encode/decode

I'm trying to implement RFC2217 in my code but I can't understand how the last parity bit (46H and 28H) is generated.
I'm using RS485 to Ethernet device.
What will be the code, if I'm using 2400,E,8,1?
Is it: 55 AA 55 09 60 1B XX?
Is 1B right?
What will be XX?
User manual: page 42 in https://www.sarcitalia.it/file_upload/prodotti//USR-N520-Manual-EN-V1.0.4.pdf
In the field for the baud rate you missed the MSByte. This field shall be 00 09 60.
Yes, 1B for "E,8,1" is correct. BTW, the table lists 2 bits for the 1-bit fields of "stop bit" and "parity enable", which is quite irritating.
The field "parity" is actually just a sum, without the header and the MSBit cleared. (I don't grasp the text of the explanation, but the document seems to be low quality anyway.)
01 C2 00 03: 0x01 + 0xC2 + 0x00 + 0x03 = 0xC6; without bit 7 = 0x46.
00 25 80 03: 0x00 + 0x25 + 0x80 + 0x03 = 0xA8; without bit 7 = 0x28.
Your telegram 00 09 60 1B: 0x00 + 0x09 + 0x60 + 0x1B = 0x84; without bit 7 = 0x04. So XX is 04.

Unpack Dec from Hex - via bit offsets

I have a block of hex data which inicludes settings of a sensor, I will include the beginning snippet of the hex (LSB first):
F501517C 8150D4DE 04010200 70010101
05F32A04 F4467000 00000AFF 0502D402
This comes straight from the documentation to decode this hex to dec:
3.1. Full identifier and settings record (0x7C)
Offset Length (bytes) Field description
0x00 6 Full identifier
0x06 40 Settings
3.1.1 Full identifier
Offset Field description
0x00 Product Type
0x01 Device Type
0x02 Software Major Version
0x03 Software Minor Version
0x04 Hardware Major Version
0x05 Hardware Minor Version
3.1.2 Settings
Offset Length(bit) Offset(bit) Default value Min Max Field Description
0x00 8 0 0 0 255 Country number
0x01 8 0 0 0 255 District number
0x02 16 0 0 0 9999 Sensor number
...
0x27
This being the only information I have to decode this. The offset column must be the trick to understanding this.
What are the hex values offset from?
I see 7C in the first hex string.
The Settings section goes to 0x27 = 39 in decimal which is stated in the 3.1 section as the length being 40.
The given hex bytes are byte offset from the beginning of the data.
Assuming that your given dump is little endian 32-bit, let's have a look:
Value in dump - separated in bytes - bytes in memory
F501517C - F5 01 51 7C - 7C 51 01 F5
8150D4DE - 81 50 D4 DE - DE D4 50 81
04010200 - 04 01 02 00 - 00 02 01 04
Now let's assign them to the fields. The next list has both records concatenated.
Byte Offset Field description
7C 0x00 Product Type
51 0x01 Device Type
01 0x02 Software Major Version
F5 0x03 Software Minor Version
DE 0x04 Hardware Major Version
D4 0x05 Hardware Minor Version
Byte Offset Length(bit) Offset(bit) Default value Min Max Field Description
50 0x00 8 0 0 0 255 Country number
81 0x01 8 0 0 0 255 District number
00,02 0x02 16 0 0 0 9999 Sensor number
Whether the result makes sense, is your decision:
Product Type = 0x7C
Device Type = 0x51 = 81 decimal (could also be ASCII 'Q')
Software Major.Minor Version = 0x01.0xF5 = 1.245 decimal
Hardware Major.Minor Version = 0xDE.0xD4 = 222.212
Country number = 0x50 = 80 decimal (could also be ASCII 'P')
District number = 0x81 = 129 decimal (perhaps 0x01 = 1 with bit 7 set?)
Sensor number = 0x0002 = 2 decimal (big endian assumed)

Decrypt Hidden Message with bitwise operator

I encountered this exercise where it asks you to Decrypt a hidden message in the encrypted code in the picture below.
This exercise is related to bitwise operators , so that I assume we need to use " XOR " operator to decrypt the code with 2-digit keys ranging from 00 to 99.
Here's my code.
char input[9] = "dEsxDI^I" , decrypt[9]; // Variable Declarations and Initializations.
int key;
printf("\n\n\nDecrpytion for the Encrypted code \"dEsxDI^I\" :\n\n\n");
for(key = 0 ; key <= 99 ; key++) // 00 to 99 Key Testing.
{
for (int i = 0; i < 8; i++) // Decryption Process.
{
decrypt[i] = input[i] ^ key;
printf("%c", decrypt[i]);
}
printf(" = Key No (%d)\n\n\n", key); // Displays Key No for each decryption.
}
printf("\n\n");
return 0;
The message I decrypted is " Hi_There " with the encryption key of " 44 ".
Just wondering is it the correct message or not? Since that's the most logical message of all the messages I decrypted.
There's no solution provided for this exercise , so I'm curious.
So , what are your output guys?
The message I decrypted is " Hi_There " with the encryption key of "
44 ". Just wondering is it the correct message or not?
There are no firm directions about whether your solution to the 8-character cipher must be an 8-character solution, but that is the general case. Absent clear instruction ("Your solution may, or may not, contain all characters in the cipher."), I would look for a solution that included 8-chars.
Though you have not provided specifics of your code, a simple brute-force loop over all possible keys is about as good as anything else. Since you are not provided with the solution, you cannot do any comparisons along the way. The best you can do is loop over all keys, applying it to each character in your cipher and outputting the result -- and then using you "good ole eyeballs" to pick out a solution. (If you knew the solution would be all upper/lower case characters -- you could impose that check before outputting each result for manual inspection).
It's not clear if you were told to XOR the key with each char, or whether you were just supposed to try all reasonable bitwise operations, but a general OR or XOR is a good place to start.
Putting that together for XOR, you could do something similar to:
#include <stdio.h>
int main (void) {
char *buf = "dEsxDI^I";
for (int key = 0; key < 100; key++) { /* loop over all keys */
char *p = buf; /* output key (and char) */
printf ("key: %2d ('%c') ", key, key >= ' ' ? key : 0);
while (*p) /* loop over all chars */
putchar (*p++ ^ key); /* output decrypted char */
putchar ('\n'); /* tidy up with '\n' */
}
return 0;
}
Example Use/Output
$ ./bin/keyfind2
key: 0 ('') dEsxDI^I
key: 1 ('') eDryEH_H
key: 2 ('') fGqzFK\K
key: 3 ('') gFp{GJ]J
key: 4 ('') `Aw|#MZM
key: 5 ('') a#v}AL[L
<snip>
key: 12 ('') hItHERE
<snip>
key: 43 ('+') OnXSobub
key: 44 (',') Hi_There
key: 45 ('-') Ih^Uidsd
<snip>
Using XOR to appy to the key and using the manual eyeballs to scan for solutions, key: 12 ('') hItHERE looks promising, but then it is only a 7-char solution, continuing key: 44 (',') Hi_There provides an 8-char solution and would be the better of the two answers.
So, "Yes", I think you found the correct solution.
Without Pointers using String Indexes
Since the use of the pointer p to iterate over your cipher string in buf seems to have left you scratching your head (don't worry, it will all soak in over time), you can easily do exactly the same thing with string indexes. A for loop is just as easily used with indexes. Eliminating pointers and using string indexes, you could do the following:
#include <stdio.h>
int main (void) {
char *buf = "dEsxDI^I";
for (int key = 0; key < 100; key++) { /* loop over all keys */
printf ("key: %2d ('%c') ", key, key >= ' ' ? key : 0);
for (int i = 0; buf[i]; i++) /* loop over all chars */
putchar (buf[i] ^ key); /* output decrypted char */
putchar ('\n'); /* tidy up with '\n' */
}
return 0;
}
(output is exactly the same)
Your question regarding the use of the ternary operator in the printf statement is a good question for someone not familiar with it. The ternary operator is a shorthand for an if/else statement where the result of the expression is based on a given test condition. Essentially the ternary operator is:
condition ? if_true_value : if_false_value
In my printf statement I simply do:
printf ("key: %2d ('%c') ", key, key >= ' ' ? key : 0);
Obviously the integer value of key is used with the %2d conversion specifier to insure all key values are printed two characters wide (that's the purpose of the 2 field-width specifier. Now let's just look at what character I want to print through %c.
key >= ' ' ? key : 0 // huh?
It's easy. The first printable ASCII value is 0x20 (hex) or 32 decimal which corresponds to the ' ' (space) character. See ASCII table below. So what is my test condition? If (key >= ' ') greater or equal to space. If it is, just print the character represented by key. If it isn't, then print the nul-character (which is decimal 0 or the equivalent character '\0' -- which just takes more typing). You could do the same thing with:
if (key >= ' ')
printf ("key: %2d ('%c') ", key, key);
else
printf ("key: %2d ('') ", key);
(it's just more typing :)
ASCII Table
Char Dec Oct Hex | Char Dec Oct Hex | Char Dec Oct Hex | Char Dec Oct Hex
-------------------------------------------------------------------------------------
(nul) 0 0000 0x00 | (sp) 32 0040 0x20 | # 64 0100 0x40 | ` 96 0140 0x60
(soh) 1 0001 0x01 | ! 33 0041 0x21 | A 65 0101 0x41 | a 97 0141 0x61
(stx) 2 0002 0x02 | " 34 0042 0x22 | B 66 0102 0x42 | b 98 0142 0x62
(etx) 3 0003 0x03 | # 35 0043 0x23 | C 67 0103 0x43 | c 99 0143 0x63
(eot) 4 0004 0x04 | $ 36 0044 0x24 | D 68 0104 0x44 | d 100 0144 0x64
(enq) 5 0005 0x05 | % 37 0045 0x25 | E 69 0105 0x45 | e 101 0145 0x65
(ack) 6 0006 0x06 | & 38 0046 0x26 | F 70 0106 0x46 | f 102 0146 0x66
(bel) 7 0007 0x07 | ' 39 0047 0x27 | G 71 0107 0x47 | g 103 0147 0x67
(bs) 8 0010 0x08 | ( 40 0050 0x28 | H 72 0110 0x48 | h 104 0150 0x68
(ht) 9 0011 0x09 | ) 41 0051 0x29 | I 73 0111 0x49 | i 105 0151 0x69
(nl) 10 0012 0x0a | * 42 0052 0x2a | J 74 0112 0x4a | j 106 0152 0x6a
(vt) 11 0013 0x0b | + 43 0053 0x2b | K 75 0113 0x4b | k 107 0153 0x6b
(np) 12 0014 0x0c | , 44 0054 0x2c | L 76 0114 0x4c | l 108 0154 0x6c
(cr) 13 0015 0x0d | - 45 0055 0x2d | M 77 0115 0x4d | m 109 0155 0x6d
(so) 14 0016 0x0e | . 46 0056 0x2e | N 78 0116 0x4e | n 110 0156 0x6e
(si) 15 0017 0x0f | / 47 0057 0x2f | O 79 0117 0x4f | o 111 0157 0x6f
(dle) 16 0020 0x10 | 0 48 0060 0x30 | P 80 0120 0x50 | p 112 0160 0x70
(dc1) 17 0021 0x11 | 1 49 0061 0x31 | Q 81 0121 0x51 | q 113 0161 0x71
(dc2) 18 0022 0x12 | 2 50 0062 0x32 | R 82 0122 0x52 | r 114 0162 0x72
(dc3) 19 0023 0x13 | 3 51 0063 0x33 | S 83 0123 0x53 | s 115 0163 0x73
(dc4) 20 0024 0x14 | 4 52 0064 0x34 | T 84 0124 0x54 | t 116 0164 0x74
(nak) 21 0025 0x15 | 5 53 0065 0x35 | U 85 0125 0x55 | u 117 0165 0x75
(syn) 22 0026 0x16 | 6 54 0066 0x36 | V 86 0126 0x56 | v 118 0166 0x76
(etb) 23 0027 0x17 | 7 55 0067 0x37 | W 87 0127 0x57 | w 119 0167 0x77
(can) 24 0030 0x18 | 8 56 0070 0x38 | X 88 0130 0x58 | x 120 0170 0x78
(em) 25 0031 0x19 | 9 57 0071 0x39 | Y 89 0131 0x59 | y 121 0171 0x79
(sub) 26 0032 0x1a | : 58 0072 0x3a | Z 90 0132 0x5a | z 122 0172 0x7a
(esc) 27 0033 0x1b | ; 59 0073 0x3b | [ 91 0133 0x5b | { 123 0173 0x7b
(fs) 28 0034 0x1c | < 60 0074 0x3c | \ 92 0134 0x5c | | 124 0174 0x7c
(gs) 29 0035 0x1d | = 61 0075 0x3d | ] 93 0135 0x5d | } 125 0175 0x7d
(rs) 30 0036 0x1e | > 62 0076 0x3e | ^ 94 0136 0x5e | ~ 126 0176 0x7e
(us) 31 0037 0x1f | ? 63 0077 0x3f | _ 95 0137 0x5f | (del) 127 0177 0x7f
I did XOR, ~XOR, AND, NAND, OR, NOR, left-shift, right-shift operations on your decrypted message.
naturally as any of us would have thought the answer key is 44.
I did not get any other readable message from that String.
although If you consider all possibilities :
XOR:
key 12 : hItHERE
key 44 : Hi_There
key 112 : 49.9____
replace underscores with spaces(not unprintable chars, just empty space)
OR:
key 14 : no~no~o
key 46 : no~no~o
yes they both are same, in fact OR produces a lot of Strings with repeating chars like '{{{{{{{{'
~XOR:
key 243: hItHERE
key 211: Hi_There
Now the definition of readable message depends on every individual.
hItHERE might be some marker for aerial strike.
no~no~o might be a call for help or denial of something.
49.9 might be the quantity of some secret ingredient in a bio-weapons lab.
0~99 is quite a limited range.
A goal should be to to automate the detection mechanism. Rather than find the decrypted phrase from an exhaustive list, form code than does it.
With some minor modifications to OP's code, the below calls various valid() to assess the decryption validity.
Recommend that OP further adjust valid() until it provides 1 "best" decryption. Then the "formula" for decryption is found.
For fun: Try finding the phone number of this spy and Google to determine the name. Her encrypted data is "0>?%=;81". Adjust valid() accordingly.
#include <stdio.h>
#if 1
int valid(const char *decrypt) {
size_t end = strspn(decrypt, " ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz");
return end == 8;
}
#else
int valid(const char *decrypt) {
size_t end = strspn(decrypt, " ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz");
if (end != 8) return 0;
for (int i=1; i<8; i++) {
if (isupper(decrypt[i-1]) && isupper(decrypt[i])) { //reject paired capital letters
return 0;
}
}
return 1;
}
#endif
int main(void) {
const char input[9] = "dEsxDI^I";
printf("Decryption for the Encrypted code \"dEsxDI^I\" :\n\n");
for (int key = 0; key <= 99; key++) {
char decrypt[9] = ""; // Variable Declarations and Initializations.
for (int i = 0; i < 8; i++) {
decrypt[i] = (char) (input[i] ^ key);
}
if (valid(decrypt)) {
printf("Key No %2d Decrypt:<%s>\n", key, decrypt);
}
}
return 0;
}
Output - 1st valid()
Decryption for the Encrypted code "dEsxDI^I" :
Key No 1 Decrypt:<eDryEH_H>
Key No 10 Decrypt:<nOyrNCTC>
Key No 11 Decrypt:<oNxsOBUB>
Key No 16 Decrypt:<tUchTYNY>
Key No 17 Decrypt:<uTbiUXOX>
Key No 22 Decrypt:<rSenR_H_>
Key No 28 Decrypt:<xYodXUBU>
Key No 29 Decrypt:<yXneYTCT>
Key No 39 Decrypt:<CbT_cnyn>
Key No 42 Decrypt:<NoYRnctc>
Key No 43 Decrypt:<OnXSobub>
Key No 44 Decrypt:<Hi_There>
Key No 48 Decrypt:<TuCHtyny>
Key No 49 Decrypt:<UtBIuxox>
Key No 60 Decrypt:<XyODxubu>
Key No 61 Decrypt:<YxNEytct>
Output - 2nd valid()
Decryption for the Encrypted code "dEsxDI^I" :
Key No 22 Decrypt:<rSenR_H_>
Key No 39 Decrypt:<CbT_cnyn>
Key No 44 Decrypt:<Hi_There>

Which Commands do I have to use SSD1306 over I²C?

I want to create a simple linux driver for the SSD1306 that I have connected to my Raspberry Pi over I²C.
Before I start coding, I want to get to know the device and which commands I have to send. I use the i2c-tools for linux to test my commands. I studied some Arduino projects and the datasheet of the SSD1306, but I could only recreate a few commands on the commandline:
Initializing the device: i2cset -y 1 0x3c 0xAE 0x20 0x10 0xb0 0xc8 0x00 0x10 0x40 0x81 0x7f 0xa1 0xa6 0xa8 0x3f 0xa4 0xd3 0x00 0xd5 0xf0 0xd9 0x22 0xda 0x12 0xdb 0x20 0x8d 0x14 0xaf i
Send data to the device's memory: i2cset -y 1 0x3c 0x40 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF i
This fills some Pixels from the current position to the right.
Jumping to the upper left pixels: i2cset -y 1 0x3c 0xb0 0x00 0x10 i
This didn't always work :(
0x3c is the address of my SSD1306 device
I would be glad if someone could tell me some more commands or knows where I can find a good example or tutorial with comments.
Thanks,
p0kR
here's an extended example inspired by https://www.mikrocontroller.net/topic/390980:
function display_off() {
i2cset -y 0 0x3c 0x00 0xAE # Display OFF (sleep mode)
sleep 0.1
}
function init_display() {
i2cset -y 0 0x3c 0x00 0xA8 # Set Multiplex Ratio
i2cset -y 0 0x3c 0x00 0x3F # value
i2cset -y 0 0x3c 0x00 0xD3 # Set Display Offset
i2cset -y 0 0x3c 0x00 0x00 # no vertical shift
i2cset -y 0 0x3c 0x00 0x40 # Set Display Start Line to 000000b
i2cset -y 0 0x3c 0x00 0xA1 # Set Segment Re-map, column address 127 ismapped to SEG0
i2cset -y 0 0x3c 0x00 0xC8 # Set COM Output Scan Direction, remapped mode. Scan from COM7 to COM0
#i2cset -y 0 0x3c 0x00 0xC0 # Set COM Output Scan Direction, remapped mode. Scan from COM7 to COM0
i2cset -y 0 0x3c 0x00 0xDA # Set COM Pins Hardware Configuration
#i2cset -y 0 0x3c 0x00 0x12 # Alternative COM pin configuration, Disable COM Left/Right remap
#i2cset -y 0 0x3c 0x00 0x2 # Sequential COM pin configuration, Disable COM Left/Right remap
#i2cset -y 0 0x3c 0x00 0x22 # Sequential COM pin configuration, Enable Left/Right remap (8pixels height)
i2cset -y 0 0x3c 0x00 0x32 # Alternative COM pin configuration, Enable Left/Right remap (4pixels height)
#i2cset -y 0 0x3c 0x00 0x81 # Set Contrast Control
#i2cset -y 0 0x3c 0x00 0xCF # value, 0x7F max.
i2cset -y 0 0x3c 0x00 0xA4 # display RAM content
i2cset -y 0 0x3c 0x00 0xA6 # non-inverting display mode - black dots on white background
i2cset -y 0 0x3c 0x00 0xD5 # Set Display Clock (Divide Ratio/Oscillator Frequency)
i2cset -y 0 0x3c 0x00 0x80 # max fequency, no divide ratio
i2cset -y 0 0x3c 0x00 0x8D # Charge Pump Setting
i2cset -y 0 0x3c 0x00 0x14 # enable charge pump
i2cset -y 0 0x3c 0x00 0x20 # page addressing mode
i2cset -y 0 0x3c 0x00 0x20 # horizontal addressing mode
#i2cset -y 0 0x3c 0x00 0x21 # vertical addressing mode
#i2cset -y 0 0x3c 0x00 0x22 # page addressing mode
}
function display_on() {
i2cset -y 0 0x3c 0x00 0xAF # Display ON (normal mode)
sleep 0.001
}
function reset_cursor() {
i2cset -y 0 0x3c 0x00 0x21 # set column address
i2cset -y 0 0x3c 0x00 0x00 # set start address
i2cset -y 0 0x3c 0x00 0x7F # set end address (127 max)
i2cset -y 0 0x3c 0x00 0x22 # set page address
i2cset -y 0 0x3c 0x00 0x00 # set start address
i2cset -y 0 0x3c 0x00 0x07 # set end address (7 max)
}
display_off
init_display
display_on
reset_cursor
# fill screen
for i in $(seq 1024)
do
i2cset -y 0 0x3c 0x40 0xff
done
reset_cursor
# clear screen
for i in $(seq 1024)
do
i2cset -y 0 0x3c 0x40 0x0
done
reset_cursor
# draw a pattern
for i in $(seq 146)
do
for i in 1 4 16 64 16 4 1
do
i2cset -y 0 0x3c 0x40 $i
done
done
it is quite slow but works. tested with 128x32 oled display + raspberry pi 1.

Base64 encode (byte) array in Google AppsScript?

In Google AppsScript, I'm trying to Base64 encode a byte array using the Utilities class.
UPDATE: Example of this here: https://script.google.com/d/15eLqgLHExpLG64JZhjUzKfBj4DgLhNZGBOkjwz7AkeeUbcgcaraP4y9X/edit?usp=sharing
// bytes to encode
var toenc = [ 0x52 , 0x49 , 0x46 , 0x46
, 0xBC , 0xAF , 0x01 , 0x00
, 0x57 , 0x41 , 0x56 , 0x45
, 0x66 , 0x6D , 0x74 , 0x20
, 0x10 , 0x00 , 0x00 , 0x00
, 0x01 , 0x00 , 0x01 , 0x00
, 0x40 , 0x1f , 0x00 , 0x00
, 0x40 , 0x1f , 0x00 , 0x00
, 0x01 , 0x00 , 0x08 , 0x00
, 0x64 , 0x61 , 0x74 , 0x61
, 0x98 , 0xaf , 0x01 , 0x00
];
// This errs with -- Cannot convert Array to (class)[]
Logger.log(Utilities.base64EncodeWebSafe(toenc));
// OK, typing issue? Following the doc, but still get same error :-(
Logger.log(Utilities.base64EncodeWebSafe(
Utilities.newBlob(toenc).getBytes()
));
Alas, the very same error Cannot convert Array to (class)[] on run.
If I have an array of (byte) numbers (effectively a string), am I able to employ the Utilities class to Base64 it?
Is a following script helpful for you? If I have misread your question, I apologize.
var toenc = [ 0x57 , 0x41 , 0x56 , 0x45
, 0x66 , 0x6D , 0x74 , 0x20
, 0x10 , 0x00 , 0x00 , 0x00
, 0x64 , 0x61 , 0x74 , 0x61
];
var a1 = Utilities.base64EncodeWebSafe(toenc);
var a2 = Utilities.base64DecodeWebSafe(a1, Utilities.Charset.UTF_8);
var a3 = Utilities.newBlob(a2).getDataAsString();
>>> a1 = V0FWRWZtdCAQAAAAZGF0YQ==
>>> a2 = [87, 65, 86, 69, 102, 109, 116, 32, 16, 0, 0, 0, 100, 97, 116, 97]
>>> a3 = WAVEfmt ���data
Found the answer. It deals with the fact the function wants a 2's compliment number. Solution:
function to64(arr) {
var bytes = [];
for (var i = 0; i < arr.length; i++)
bytes.push(arr[i]<128?arr[i]:arr[i]-256);
return Utilities.base64EncodeWebSafe(bytes)
} // to64
https://stackoverflow.com/a/20639942/199305

Resources