<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.exploitee.rs/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Luke-Jr</id>
	<title>Exploitee.rs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.exploitee.rs/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Luke-Jr"/>
	<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Special:Contributions/Luke-Jr"/>
	<updated>2026-05-08T07:57:13Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.45.0-alpha</generator>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2072</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2072"/>
		<updated>2014-08-10T21:13:51Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Backplate state */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
* Display serial number is located in U-Boot environment variable &amp;quot;serial#&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - get Mono/TFE id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get Mono/TFE version|0098 - Get Mono/TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get Mono/TFE version|0018 - Get Mono/TFE version (response)]]&lt;br /&gt;
 Send [[#Get Mono/TFE build info|0099 - Get Mono/TFE build info]]&lt;br /&gt;
 Recv [[#Get Mono/TFE build info|0019 - Get Mono/TFE build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - get BSL id (no data; responds with 001d)&lt;br /&gt;
   Recv 001d - bsl id (response to 009d; 16-bit data)&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - get BSL info (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version|009e - Get hardware version]]&lt;br /&gt;
 Recv [[#Get hardware version|001e - Get hardware version (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
NOTE: Most of this documentation is reverse engineered from firmware version BSL-2.1 and/or TFE_BP_D2-4.0.21 for Backplate-2.x.&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - get Mono/TFE id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get Mono/TFE version|0098 - Get Mono/TFE version]]&lt;br /&gt;
 [[#Get Mono/TFE build info|0099 - Get Mono/TFE build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - get BSL info (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - get BSL id (no data; responds with 001d)&lt;br /&gt;
 [[#Get hardware version|009e - Get hardware version]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - quiet (16-bit max sleep seconds)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - set wakeup mask (16-bit data)&lt;br /&gt;
 00b1 - &amp;quot;temperature lock&amp;quot; (sent when button pressed/unpressed; no data)&lt;br /&gt;
 00b3 - set humidity thresholds (32-bit data)&lt;br /&gt;
 00b5 - set near pir threshold (16-bit data)&lt;br /&gt;
 00b7 - set pir thresholds (??? data)&lt;br /&gt;
 00b8 - set proximity thresholds (??? data)&lt;br /&gt;
 00b9 - set als thresholds (32-bit data)&lt;br /&gt;
 00ba - set vergence mode (48-bit data)&lt;br /&gt;
 00c2 - set wakeup temperatures (48-bit data)&lt;br /&gt;
 00c3 - set temp comp mode request (??? data)&lt;br /&gt;
 00fe - DEBUG MODE&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - pir? (32-bit data)&lt;br /&gt;
 0006 - &amp;quot;ack switch&amp;quot; (data: 8-bit switch id, 8-bit state)&lt;br /&gt;
 0007 - near pid? (every second; 16-bit data)&lt;br /&gt;
 0008 - proximity?&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - als? (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - sensor? (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 000e - power?&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0012 - ?&lt;br /&gt;
 0013 - &amp;quot;Wakeup&amp;quot;?&lt;br /&gt;
 0014 - &amp;quot;WakeVector&amp;quot; (16-bit data)&lt;br /&gt;
 [[#Get Mono/TFE version|0018 - Get Mono/TFE version (response)]]&lt;br /&gt;
 [[#Get Mono/TFE build info|0019 - Get Mono/TFE build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - bsl id (response to 009d; 16-bit data)&lt;br /&gt;
 [[#Get hardware version|001e - Get hardware version (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - buffered temperature reading (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - BufferedSourceTemperature (3x 16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - BufferedNearPir (16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - BufferedPassiveInfrared (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - BufferedAmbientLightSensor (48-bit data; likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - BufferedPowerData (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
** Bit 0x40 = charger off (?)&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* ? 16-bit &amp;quot;sw&amp;quot; fraction (0800 = 08/00)&lt;br /&gt;
* ? 8-bit &amp;quot;p2&amp;quot;&lt;br /&gt;
* ? 16-bit &amp;quot;voc&amp;quot;&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;pins&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;wires&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
Buffers:&lt;br /&gt;
 [[#Temperature reading|0022 - Temperature reading]]&lt;br /&gt;
 0023 - BufferedSourceTemperature (not sure what that means)&lt;br /&gt;
 0025 - BufferedNearPir&lt;br /&gt;
 0027 - BufferedPassiveInfrared&lt;br /&gt;
 0029 - BufferedAmbientLightSensor&lt;br /&gt;
 002b - BufferedPowerData&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, C, RC, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, C, RC, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
0009 seems to indicate a wire is physically plugged in, while 0004 indicates that it is connected to something (?).&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get Mono/TFE build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get Mono/TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Power management ===&lt;br /&gt;
Wake vector bits:&lt;br /&gt;
 0001 - timer&lt;br /&gt;
 0002 - buffers full&lt;br /&gt;
 0004 - temperature&lt;br /&gt;
 0008 - pir&lt;br /&gt;
 0010 - proximity&lt;br /&gt;
 0020 - humidity&lt;br /&gt;
 0040 - near pir&lt;br /&gt;
 0080 - als&lt;br /&gt;
 0100 - &amp;quot;vbat&amp;quot;&lt;br /&gt;
 0200 - &amp;quot;vergence&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
See also: [[#&amp;quot;Buffers&amp;quot;|&amp;quot;Buffers&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2071</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2071"/>
		<updated>2014-08-10T21:08:05Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Backplate to display */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
* Display serial number is located in U-Boot environment variable &amp;quot;serial#&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - get Mono/TFE id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get Mono/TFE version|0098 - Get Mono/TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get Mono/TFE version|0018 - Get Mono/TFE version (response)]]&lt;br /&gt;
 Send [[#Get Mono/TFE build info|0099 - Get Mono/TFE build info]]&lt;br /&gt;
 Recv [[#Get Mono/TFE build info|0019 - Get Mono/TFE build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - get BSL id (no data; responds with 001d)&lt;br /&gt;
   Recv 001d - bsl id (response to 009d; 16-bit data)&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - get BSL info (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version|009e - Get hardware version]]&lt;br /&gt;
 Recv [[#Get hardware version|001e - Get hardware version (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
NOTE: Most of this documentation is reverse engineered from firmware version BSL-2.1 and/or TFE_BP_D2-4.0.21 for Backplate-2.x.&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - get Mono/TFE id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get Mono/TFE version|0098 - Get Mono/TFE version]]&lt;br /&gt;
 [[#Get Mono/TFE build info|0099 - Get Mono/TFE build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - get BSL info (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - get BSL id (no data; responds with 001d)&lt;br /&gt;
 [[#Get hardware version|009e - Get hardware version]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - quiet (16-bit max sleep seconds)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - set wakeup mask (16-bit data)&lt;br /&gt;
 00b1 - &amp;quot;temperature lock&amp;quot; (sent when button pressed/unpressed; no data)&lt;br /&gt;
 00b3 - set humidity thresholds (32-bit data)&lt;br /&gt;
 00b5 - set near pir threshold (16-bit data)&lt;br /&gt;
 00b7 - set pir thresholds (??? data)&lt;br /&gt;
 00b8 - set proximity thresholds (??? data)&lt;br /&gt;
 00b9 - set als thresholds (32-bit data)&lt;br /&gt;
 00ba - set vergence mode (48-bit data)&lt;br /&gt;
 00c2 - set wakeup temperatures (48-bit data)&lt;br /&gt;
 00c3 - set temp comp mode request (??? data)&lt;br /&gt;
 00fe - DEBUG MODE&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - pir? (32-bit data)&lt;br /&gt;
 0006 - &amp;quot;ack switch&amp;quot; (data: 8-bit switch id, 8-bit state)&lt;br /&gt;
 0007 - near pid? (every second; 16-bit data)&lt;br /&gt;
 0008 - proximity?&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - als? (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - sensor? (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 000e - power?&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0012 - ?&lt;br /&gt;
 0013 - &amp;quot;Wakeup&amp;quot;?&lt;br /&gt;
 0014 - &amp;quot;WakeVector&amp;quot; (16-bit data)&lt;br /&gt;
 [[#Get Mono/TFE version|0018 - Get Mono/TFE version (response)]]&lt;br /&gt;
 [[#Get Mono/TFE build info|0019 - Get Mono/TFE build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - bsl id (response to 009d; 16-bit data)&lt;br /&gt;
 [[#Get hardware version|001e - Get hardware version (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - buffered temperature reading (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - BufferedSourceTemperature (3x 16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - BufferedNearPir (16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - BufferedPassiveInfrared (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - BufferedAmbientLightSensor (48-bit data; likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - BufferedPowerData (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
** Bit 0x40 = charger off (?)&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* ? 16-bit &amp;quot;sw&amp;quot; fraction (0800 = 08/00)&lt;br /&gt;
* ? 8-bit &amp;quot;p2&amp;quot;&lt;br /&gt;
* ? 16-bit &amp;quot;voc&amp;quot;&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
Buffers:&lt;br /&gt;
 [[#Temperature reading|0022 - Temperature reading]]&lt;br /&gt;
 0023 - BufferedSourceTemperature (not sure what that means)&lt;br /&gt;
 0025 - BufferedNearPir&lt;br /&gt;
 0027 - BufferedPassiveInfrared&lt;br /&gt;
 0029 - BufferedAmbientLightSensor&lt;br /&gt;
 002b - BufferedPowerData&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, C, RC, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, C, RC, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
0009 seems to indicate a wire is physically plugged in, while 0004 indicates that it is connected to something (?).&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get Mono/TFE build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get Mono/TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Power management ===&lt;br /&gt;
Wake vector bits:&lt;br /&gt;
 0001 - timer&lt;br /&gt;
 0002 - buffers full&lt;br /&gt;
 0004 - temperature&lt;br /&gt;
 0008 - pir&lt;br /&gt;
 0010 - proximity&lt;br /&gt;
 0020 - humidity&lt;br /&gt;
 0040 - near pir&lt;br /&gt;
 0080 - als&lt;br /&gt;
 0100 - &amp;quot;vbat&amp;quot;&lt;br /&gt;
 0200 - &amp;quot;vergence&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
See also: [[#&amp;quot;Buffers&amp;quot;|&amp;quot;Buffers&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2070</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2070"/>
		<updated>2014-08-10T21:01:08Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Backplate state */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
* Display serial number is located in U-Boot environment variable &amp;quot;serial#&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - get Mono/TFE id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get Mono/TFE version|0098 - Get Mono/TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get Mono/TFE version|0018 - Get Mono/TFE version (response)]]&lt;br /&gt;
 Send [[#Get Mono/TFE build info|0099 - Get Mono/TFE build info]]&lt;br /&gt;
 Recv [[#Get Mono/TFE build info|0019 - Get Mono/TFE build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - get BSL id (no data; responds with 001d)&lt;br /&gt;
   Recv 001d - bsl id (response to 009d; 16-bit data)&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - get BSL info (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version|009e - Get hardware version]]&lt;br /&gt;
 Recv [[#Get hardware version|001e - Get hardware version (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
NOTE: Most of this documentation is reverse engineered from firmware version BSL-2.1 and/or TFE_BP_D2-4.0.21 for Backplate-2.x.&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - get Mono/TFE id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get Mono/TFE version|0098 - Get Mono/TFE version]]&lt;br /&gt;
 [[#Get Mono/TFE build info|0099 - Get Mono/TFE build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - get BSL info (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - get BSL id (no data; responds with 001d)&lt;br /&gt;
 [[#Get hardware version|009e - Get hardware version]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - quiet (16-bit max sleep seconds)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - set wakeup mask (16-bit data)&lt;br /&gt;
 00b1 - &amp;quot;temperature lock&amp;quot; (sent when button pressed/unpressed; no data)&lt;br /&gt;
 00b3 - set humidity thresholds (32-bit data)&lt;br /&gt;
 00b5 - set near pir threshold (16-bit data)&lt;br /&gt;
 00b7 - set pir thresholds (??? data)&lt;br /&gt;
 00b8 - set proximity thresholds (??? data)&lt;br /&gt;
 00b9 - set als thresholds (32-bit data)&lt;br /&gt;
 00ba - set vergence mode (48-bit data)&lt;br /&gt;
 00c2 - set wakeup temperatures (48-bit data)&lt;br /&gt;
 00c3 - set temp comp mode request (??? data)&lt;br /&gt;
 00fe - DEBUG MODE&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - pir? (32-bit data)&lt;br /&gt;
 0006 - ack switch?&lt;br /&gt;
 0007 - near pid? (every second; 16-bit data)&lt;br /&gt;
 0008 - proximity?&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - als? (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - sensor? (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 000e - power?&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0012 - ?&lt;br /&gt;
 0013 - &amp;quot;Wakeup&amp;quot;?&lt;br /&gt;
 0014 - &amp;quot;WakeVector&amp;quot; (16-bit data)&lt;br /&gt;
 [[#Get Mono/TFE version|0018 - Get Mono/TFE version (response)]]&lt;br /&gt;
 [[#Get Mono/TFE build info|0019 - Get Mono/TFE build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - bsl id (response to 009d; 16-bit data)&lt;br /&gt;
 [[#Get hardware version|001e - Get hardware version (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - buffered temperature reading (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - BufferedSourceTemperature (3x 16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - BufferedNearPir (16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - BufferedPassiveInfrared (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - BufferedAmbientLightSensor (48-bit data; likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - BufferedPowerData (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
** Bit 0x40 = charger off (?)&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* ? 16-bit &amp;quot;sw&amp;quot; fraction (0800 = 08/00)&lt;br /&gt;
* ? 8-bit &amp;quot;p2&amp;quot;&lt;br /&gt;
* ? 16-bit &amp;quot;voc&amp;quot;&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
Buffers:&lt;br /&gt;
 [[#Temperature reading|0022 - Temperature reading]]&lt;br /&gt;
 0023 - BufferedSourceTemperature (not sure what that means)&lt;br /&gt;
 0025 - BufferedNearPir&lt;br /&gt;
 0027 - BufferedPassiveInfrared&lt;br /&gt;
 0029 - BufferedAmbientLightSensor&lt;br /&gt;
 002b - BufferedPowerData&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, C, RC, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, C, RC, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
0009 seems to indicate a wire is physically plugged in, while 0004 indicates that it is connected to something (?).&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get Mono/TFE build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get Mono/TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Power management ===&lt;br /&gt;
Wake vector bits:&lt;br /&gt;
 0001 - timer&lt;br /&gt;
 0002 - buffers full&lt;br /&gt;
 0004 - temperature&lt;br /&gt;
 0008 - pir&lt;br /&gt;
 0010 - proximity&lt;br /&gt;
 0020 - humidity&lt;br /&gt;
 0040 - near pir&lt;br /&gt;
 0080 - als&lt;br /&gt;
 0100 - &amp;quot;vbat&amp;quot;&lt;br /&gt;
 0200 - &amp;quot;vergence&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
See also: [[#&amp;quot;Buffers&amp;quot;|&amp;quot;Buffers&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2069</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2069"/>
		<updated>2014-08-10T07:32:26Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Power management */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
* Display serial number is located in U-Boot environment variable &amp;quot;serial#&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - get Mono/TFE id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get Mono/TFE version|0098 - Get Mono/TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get Mono/TFE version|0018 - Get Mono/TFE version (response)]]&lt;br /&gt;
 Send [[#Get Mono/TFE build info|0099 - Get Mono/TFE build info]]&lt;br /&gt;
 Recv [[#Get Mono/TFE build info|0019 - Get Mono/TFE build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - get BSL id (no data; responds with 001d)&lt;br /&gt;
   Recv 001d - bsl id (response to 009d; 16-bit data)&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - get BSL info (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version|009e - Get hardware version]]&lt;br /&gt;
 Recv [[#Get hardware version|001e - Get hardware version (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
NOTE: Most of this documentation is reverse engineered from firmware version BSL-2.1 and/or TFE_BP_D2-4.0.21 for Backplate-2.x.&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - get Mono/TFE id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get Mono/TFE version|0098 - Get Mono/TFE version]]&lt;br /&gt;
 [[#Get Mono/TFE build info|0099 - Get Mono/TFE build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - get BSL info (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - get BSL id (no data; responds with 001d)&lt;br /&gt;
 [[#Get hardware version|009e - Get hardware version]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - quiet (16-bit max sleep seconds)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - set wakeup mask (16-bit data)&lt;br /&gt;
 00b1 - &amp;quot;temperature lock&amp;quot; (sent when button pressed/unpressed; no data)&lt;br /&gt;
 00b3 - set humidity thresholds (32-bit data)&lt;br /&gt;
 00b5 - set near pir threshold (16-bit data)&lt;br /&gt;
 00b7 - set pir thresholds (??? data)&lt;br /&gt;
 00b8 - set proximity thresholds (??? data)&lt;br /&gt;
 00b9 - set als thresholds (32-bit data)&lt;br /&gt;
 00ba - set vergence mode (48-bit data)&lt;br /&gt;
 00c2 - set wakeup temperatures (48-bit data)&lt;br /&gt;
 00c3 - set temp comp mode request (??? data)&lt;br /&gt;
 00fe - DEBUG MODE&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - pir? (32-bit data)&lt;br /&gt;
 0006 - ack switch?&lt;br /&gt;
 0007 - near pid? (every second; 16-bit data)&lt;br /&gt;
 0008 - proximity?&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - als? (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - sensor? (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 000e - power?&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0012 - ?&lt;br /&gt;
 0013 - &amp;quot;Wakeup&amp;quot;?&lt;br /&gt;
 0014 - &amp;quot;WakeVector&amp;quot; (16-bit data)&lt;br /&gt;
 [[#Get Mono/TFE version|0018 - Get Mono/TFE version (response)]]&lt;br /&gt;
 [[#Get Mono/TFE build info|0019 - Get Mono/TFE build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - bsl id (response to 009d; 16-bit data)&lt;br /&gt;
 [[#Get hardware version|001e - Get hardware version (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - buffered temperature reading (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - BufferedSourceTemperature (3x 16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - BufferedNearPir (16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - BufferedPassiveInfrared (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - BufferedAmbientLightSensor (48-bit data; likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - BufferedPowerData (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
** Bit 0x40 = charger off (?)&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
Buffers:&lt;br /&gt;
 [[#Temperature reading|0022 - Temperature reading]]&lt;br /&gt;
 0023 - BufferedSourceTemperature (not sure what that means)&lt;br /&gt;
 0025 - BufferedNearPir&lt;br /&gt;
 0027 - BufferedPassiveInfrared&lt;br /&gt;
 0029 - BufferedAmbientLightSensor&lt;br /&gt;
 002b - BufferedPowerData&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, C, RC, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, C, RC, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
0009 seems to indicate a wire is physically plugged in, while 0004 indicates that it is connected to something (?).&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get Mono/TFE build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get Mono/TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Power management ===&lt;br /&gt;
Wake vector bits:&lt;br /&gt;
 0001 - timer&lt;br /&gt;
 0002 - buffers full&lt;br /&gt;
 0004 - temperature&lt;br /&gt;
 0008 - pir&lt;br /&gt;
 0010 - proximity&lt;br /&gt;
 0020 - humidity&lt;br /&gt;
 0040 - near pir&lt;br /&gt;
 0080 - als&lt;br /&gt;
 0100 - &amp;quot;vbat&amp;quot;&lt;br /&gt;
 0200 - &amp;quot;vergence&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
See also: [[#&amp;quot;Buffers&amp;quot;|&amp;quot;Buffers&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2068</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2068"/>
		<updated>2014-08-10T04:51:23Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Backplate state */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
* Display serial number is located in U-Boot environment variable &amp;quot;serial#&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - get Mono/TFE id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get Mono/TFE version|0098 - Get Mono/TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get Mono/TFE version|0018 - Get Mono/TFE version (response)]]&lt;br /&gt;
 Send [[#Get Mono/TFE build info|0099 - Get Mono/TFE build info]]&lt;br /&gt;
 Recv [[#Get Mono/TFE build info|0019 - Get Mono/TFE build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - get BSL id (no data; responds with 001d)&lt;br /&gt;
   Recv 001d - bsl id (response to 009d; 16-bit data)&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - get BSL info (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version|009e - Get hardware version]]&lt;br /&gt;
 Recv [[#Get hardware version|001e - Get hardware version (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
NOTE: Most of this documentation is reverse engineered from firmware version BSL-2.1 and/or TFE_BP_D2-4.0.21 for Backplate-2.x.&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - get Mono/TFE id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get Mono/TFE version|0098 - Get Mono/TFE version]]&lt;br /&gt;
 [[#Get Mono/TFE build info|0099 - Get Mono/TFE build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - get BSL info (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - get BSL id (no data; responds with 001d)&lt;br /&gt;
 [[#Get hardware version|009e - Get hardware version]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - quiet (16-bit max sleep seconds)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - set wakeup mask (16-bit data)&lt;br /&gt;
 00b1 - &amp;quot;temperature lock&amp;quot; (sent when button pressed/unpressed; no data)&lt;br /&gt;
 00b3 - set humidity thresholds (32-bit data)&lt;br /&gt;
 00b5 - set near pir threshold (16-bit data)&lt;br /&gt;
 00b7 - set pir thresholds (??? data)&lt;br /&gt;
 00b8 - set proximity thresholds (??? data)&lt;br /&gt;
 00b9 - set als thresholds (32-bit data)&lt;br /&gt;
 00ba - set vergence mode (48-bit data)&lt;br /&gt;
 00c2 - set wakeup temperatures (48-bit data)&lt;br /&gt;
 00c3 - set temp comp mode request (??? data)&lt;br /&gt;
 00fe - DEBUG MODE&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - pir? (32-bit data)&lt;br /&gt;
 0006 - ack switch?&lt;br /&gt;
 0007 - near pid? (every second; 16-bit data)&lt;br /&gt;
 0008 - proximity?&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - als? (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - sensor? (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 000e - power?&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0012 - ?&lt;br /&gt;
 0013 - &amp;quot;Wakeup&amp;quot;?&lt;br /&gt;
 0014 - &amp;quot;WakeVector&amp;quot; (16-bit data)&lt;br /&gt;
 [[#Get Mono/TFE version|0018 - Get Mono/TFE version (response)]]&lt;br /&gt;
 [[#Get Mono/TFE build info|0019 - Get Mono/TFE build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - bsl id (response to 009d; 16-bit data)&lt;br /&gt;
 [[#Get hardware version|001e - Get hardware version (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - buffered temperature reading (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - BufferedSourceTemperature (3x 16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - BufferedNearPir (16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - BufferedPassiveInfrared (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - BufferedAmbientLightSensor (48-bit data; likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - BufferedPowerData (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
** Bit 0x40 = charger off (?)&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
Buffers:&lt;br /&gt;
 [[#Temperature reading|0022 - Temperature reading]]&lt;br /&gt;
 0023 - BufferedSourceTemperature (not sure what that means)&lt;br /&gt;
 0025 - BufferedNearPir&lt;br /&gt;
 0027 - BufferedPassiveInfrared&lt;br /&gt;
 0029 - BufferedAmbientLightSensor&lt;br /&gt;
 002b - BufferedPowerData&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, C, RC, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, C, RC, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
0009 seems to indicate a wire is physically plugged in, while 0004 indicates that it is connected to something (?).&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get Mono/TFE build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get Mono/TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
See also: [[#&amp;quot;Buffers&amp;quot;|&amp;quot;Buffers&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2067</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2067"/>
		<updated>2014-08-09T07:51:17Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Display to backplate */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
* Display serial number is located in U-Boot environment variable &amp;quot;serial#&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - get Mono/TFE id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get Mono/TFE version|0098 - Get Mono/TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get Mono/TFE version|0018 - Get Mono/TFE version (response)]]&lt;br /&gt;
 Send [[#Get Mono/TFE build info|0099 - Get Mono/TFE build info]]&lt;br /&gt;
 Recv [[#Get Mono/TFE build info|0019 - Get Mono/TFE build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - get BSL id (no data; responds with 001d)&lt;br /&gt;
   Recv 001d - bsl id (response to 009d; 16-bit data)&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - get BSL info (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version|009e - Get hardware version]]&lt;br /&gt;
 Recv [[#Get hardware version|001e - Get hardware version (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
NOTE: Most of this documentation is reverse engineered from firmware version BSL-2.1 and/or TFE_BP_D2-4.0.21 for Backplate-2.x.&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - get Mono/TFE id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get Mono/TFE version|0098 - Get Mono/TFE version]]&lt;br /&gt;
 [[#Get Mono/TFE build info|0099 - Get Mono/TFE build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - get BSL info (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - get BSL id (no data; responds with 001d)&lt;br /&gt;
 [[#Get hardware version|009e - Get hardware version]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - quiet (16-bit max sleep seconds)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - set wakeup mask (16-bit data)&lt;br /&gt;
 00b1 - &amp;quot;temperature lock&amp;quot; (sent when button pressed/unpressed; no data)&lt;br /&gt;
 00b3 - set humidity thresholds (32-bit data)&lt;br /&gt;
 00b5 - set near pir threshold (16-bit data)&lt;br /&gt;
 00b7 - set pir thresholds (??? data)&lt;br /&gt;
 00b8 - set proximity thresholds (??? data)&lt;br /&gt;
 00b9 - set als thresholds (32-bit data)&lt;br /&gt;
 00ba - set vergence mode (48-bit data)&lt;br /&gt;
 00c2 - set wakeup temperatures (48-bit data)&lt;br /&gt;
 00c3 - set temp comp mode request (??? data)&lt;br /&gt;
 00fe - DEBUG MODE&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - pir? (32-bit data)&lt;br /&gt;
 0006 - ack switch?&lt;br /&gt;
 0007 - near pid? (every second; 16-bit data)&lt;br /&gt;
 0008 - proximity?&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - als? (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - sensor? (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 000e - power?&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0012 - ?&lt;br /&gt;
 0013 - &amp;quot;Wakeup&amp;quot;?&lt;br /&gt;
 0014 - &amp;quot;WakeVector&amp;quot; (16-bit data)&lt;br /&gt;
 [[#Get Mono/TFE version|0018 - Get Mono/TFE version (response)]]&lt;br /&gt;
 [[#Get Mono/TFE build info|0019 - Get Mono/TFE build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - bsl id (response to 009d; 16-bit data)&lt;br /&gt;
 [[#Get hardware version|001e - Get hardware version (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - buffered temperature reading (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - BufferedSourceTemperature (3x 16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - BufferedNearPir (16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - BufferedPassiveInfrared (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - BufferedAmbientLightSensor (48-bit data; likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - BufferedPowerData (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
Buffers:&lt;br /&gt;
 [[#Temperature reading|0022 - Temperature reading]]&lt;br /&gt;
 0023 - BufferedSourceTemperature (not sure what that means)&lt;br /&gt;
 0025 - BufferedNearPir&lt;br /&gt;
 0027 - BufferedPassiveInfrared&lt;br /&gt;
 0029 - BufferedAmbientLightSensor&lt;br /&gt;
 002b - BufferedPowerData&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, C, RC, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, C, RC, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
0009 seems to indicate a wire is physically plugged in, while 0004 indicates that it is connected to something (?).&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get Mono/TFE build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get Mono/TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
See also: [[#&amp;quot;Buffers&amp;quot;|&amp;quot;Buffers&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2066</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2066"/>
		<updated>2014-08-09T06:40:18Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Backplate to display */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
* Display serial number is located in U-Boot environment variable &amp;quot;serial#&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - get Mono/TFE id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get Mono/TFE version|0098 - Get Mono/TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get Mono/TFE version|0018 - Get Mono/TFE version (response)]]&lt;br /&gt;
 Send [[#Get Mono/TFE build info|0099 - Get Mono/TFE build info]]&lt;br /&gt;
 Recv [[#Get Mono/TFE build info|0019 - Get Mono/TFE build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - get BSL id (no data; responds with 001d)&lt;br /&gt;
   Recv 001d - bsl id (response to 009d; 16-bit data)&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - get BSL info (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version|009e - Get hardware version]]&lt;br /&gt;
 Recv [[#Get hardware version|001e - Get hardware version (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
NOTE: Most of this documentation is reverse engineered from firmware version BSL-2.1 and/or TFE_BP_D2-4.0.21 for Backplate-2.x.&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - get Mono/TFE id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get Mono/TFE version|0098 - Get Mono/TFE version]]&lt;br /&gt;
 [[#Get Mono/TFE build info|0099 - Get Mono/TFE build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - get BSL info (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - get BSL id (no data; responds with 001d)&lt;br /&gt;
 [[#Get hardware version|009e - Get hardware version]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - quiet (16-bit max sleep seconds)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - set wakeup mask (16-bit data)&lt;br /&gt;
 00b1 - &amp;quot;temperature lock&amp;quot; (sent when button pressed/unpressed; no data)&lt;br /&gt;
 00b3 - set humidity thresholds (32-bit data)&lt;br /&gt;
 00b5 - set near pir threshold (16-bit data)&lt;br /&gt;
 00b7 - set pir thresholds (??? data)&lt;br /&gt;
 00b8 - set proximity thresholds (??? data)&lt;br /&gt;
 00b9 - set als thresholds (32-bit data)&lt;br /&gt;
 00ba - set vergence mode (48-bit data)&lt;br /&gt;
 00c2 - set wakeup temperatures (48-bit data)&lt;br /&gt;
 00c3 - set temp comp mode request (??? data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - pir? (32-bit data)&lt;br /&gt;
 0006 - ack switch?&lt;br /&gt;
 0007 - near pid? (every second; 16-bit data)&lt;br /&gt;
 0008 - proximity?&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - als? (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - sensor? (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 000e - power?&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0012 - ?&lt;br /&gt;
 0013 - &amp;quot;Wakeup&amp;quot;?&lt;br /&gt;
 0014 - &amp;quot;WakeVector&amp;quot; (16-bit data)&lt;br /&gt;
 [[#Get Mono/TFE version|0018 - Get Mono/TFE version (response)]]&lt;br /&gt;
 [[#Get Mono/TFE build info|0019 - Get Mono/TFE build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - bsl id (response to 009d; 16-bit data)&lt;br /&gt;
 [[#Get hardware version|001e - Get hardware version (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - buffered temperature reading (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - BufferedSourceTemperature (3x 16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - BufferedNearPir (16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - BufferedPassiveInfrared (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - BufferedAmbientLightSensor (48-bit data; likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - BufferedPowerData (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
Buffers:&lt;br /&gt;
 [[#Temperature reading|0022 - Temperature reading]]&lt;br /&gt;
 0023 - BufferedSourceTemperature (not sure what that means)&lt;br /&gt;
 0025 - BufferedNearPir&lt;br /&gt;
 0027 - BufferedPassiveInfrared&lt;br /&gt;
 0029 - BufferedAmbientLightSensor&lt;br /&gt;
 002b - BufferedPowerData&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, C, RC, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, C, RC, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
0009 seems to indicate a wire is physically plugged in, while 0004 indicates that it is connected to something (?).&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get Mono/TFE build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get Mono/TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
See also: [[#&amp;quot;Buffers&amp;quot;|&amp;quot;Buffers&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2065</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2065"/>
		<updated>2014-08-09T04:08:06Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Backplate to display */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
* Display serial number is located in U-Boot environment variable &amp;quot;serial#&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - get Mono/TFE id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get Mono/TFE version|0098 - Get Mono/TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get Mono/TFE version|0018 - Get Mono/TFE version (response)]]&lt;br /&gt;
 Send [[#Get Mono/TFE build info|0099 - Get Mono/TFE build info]]&lt;br /&gt;
 Recv [[#Get Mono/TFE build info|0019 - Get Mono/TFE build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - get BSL id (no data; responds with 001d)&lt;br /&gt;
   Recv 001d - bsl id (response to 009d; 16-bit data)&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - get BSL info (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version|009e - Get hardware version]]&lt;br /&gt;
 Recv [[#Get hardware version|001e - Get hardware version (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
NOTE: Most of this documentation is reverse engineered from firmware version BSL-2.1 and/or TFE_BP_D2-4.0.21 for Backplate-2.x.&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - get Mono/TFE id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get Mono/TFE version|0098 - Get Mono/TFE version]]&lt;br /&gt;
 [[#Get Mono/TFE build info|0099 - Get Mono/TFE build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - get BSL info (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - get BSL id (no data; responds with 001d)&lt;br /&gt;
 [[#Get hardware version|009e - Get hardware version]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - quiet (16-bit max sleep seconds)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - set wakeup mask (16-bit data)&lt;br /&gt;
 00b1 - &amp;quot;temperature lock&amp;quot; (sent when button pressed/unpressed; no data)&lt;br /&gt;
 00b3 - set humidity thresholds (32-bit data)&lt;br /&gt;
 00b5 - set near pir threshold (16-bit data)&lt;br /&gt;
 00b7 - set pir thresholds (??? data)&lt;br /&gt;
 00b8 - set proximity thresholds (??? data)&lt;br /&gt;
 00b9 - set als thresholds (32-bit data)&lt;br /&gt;
 00ba - set vergence mode (48-bit data)&lt;br /&gt;
 00c2 - set wakeup temperatures (48-bit data)&lt;br /&gt;
 00c3 - set temp comp mode request (??? data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0006 - ?&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 0008 - ?&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 000e - ?&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0012 - ?&lt;br /&gt;
 0013 - ?&lt;br /&gt;
 0014 - &amp;quot;WakeVector&amp;quot; (16-bit data)&lt;br /&gt;
 [[#Get Mono/TFE version|0018 - Get Mono/TFE version (response)]]&lt;br /&gt;
 [[#Get Mono/TFE build info|0019 - Get Mono/TFE build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - bsl id (response to 009d; 16-bit data)&lt;br /&gt;
 [[#Get hardware version|001e - Get hardware version (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - buffered temperature reading (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - BufferedSourceTemperature (3x 16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - BufferedNearPir (16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - BufferedPassiveInfrared (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - BufferedAmbientLightSensor (48-bit data; likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - BufferedPowerData (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
Buffers:&lt;br /&gt;
 [[#Temperature reading|0022 - Temperature reading]]&lt;br /&gt;
 0023 - BufferedSourceTemperature (not sure what that means)&lt;br /&gt;
 0025 - BufferedNearPir&lt;br /&gt;
 0027 - BufferedPassiveInfrared&lt;br /&gt;
 0029 - BufferedAmbientLightSensor&lt;br /&gt;
 002b - BufferedPowerData&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, C, RC, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, C, RC, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
0009 seems to indicate a wire is physically plugged in, while 0004 indicates that it is connected to something (?).&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get Mono/TFE build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get Mono/TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
See also: [[#&amp;quot;Buffers&amp;quot;|&amp;quot;Buffers&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2064</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2064"/>
		<updated>2014-08-08T21:16:00Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
* Display serial number is located in U-Boot environment variable &amp;quot;serial#&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - get Mono/TFE id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get Mono/TFE version|0098 - Get Mono/TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get Mono/TFE version|0018 - Get Mono/TFE version (response)]]&lt;br /&gt;
 Send [[#Get Mono/TFE build info|0099 - Get Mono/TFE build info]]&lt;br /&gt;
 Recv [[#Get Mono/TFE build info|0019 - Get Mono/TFE build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - get BSL id (no data; responds with 001d)&lt;br /&gt;
   Recv 001d - bsl id (response to 009d; 16-bit data)&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - get BSL info (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version|009e - Get hardware version]]&lt;br /&gt;
 Recv [[#Get hardware version|001e - Get hardware version (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
NOTE: Most of this documentation is reverse engineered from firmware version BSL-2.1 and/or TFE_BP_D2-4.0.21 for Backplate-2.x.&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - get Mono/TFE id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get Mono/TFE version|0098 - Get Mono/TFE version]]&lt;br /&gt;
 [[#Get Mono/TFE build info|0099 - Get Mono/TFE build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - get BSL info (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - get BSL id (no data; responds with 001d)&lt;br /&gt;
 [[#Get hardware version|009e - Get hardware version]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - quiet (16-bit max sleep seconds)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - set wakeup mask (16-bit data)&lt;br /&gt;
 00b1 - &amp;quot;temperature lock&amp;quot; (sent when button pressed/unpressed; no data)&lt;br /&gt;
 00b3 - set humidity thresholds (32-bit data)&lt;br /&gt;
 00b5 - set near pir threshold (16-bit data)&lt;br /&gt;
 00b7 - set pir thresholds (??? data)&lt;br /&gt;
 00b8 - set proximity thresholds (??? data)&lt;br /&gt;
 00b9 - set als thresholds (32-bit data)&lt;br /&gt;
 00ba - set vergence mode (48-bit data)&lt;br /&gt;
 00c2 - set wakeup temperatures (48-bit data)&lt;br /&gt;
 00c3 - set temp comp mode request (??? data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - &amp;quot;WakeVector&amp;quot; (16-bit data)&lt;br /&gt;
 [[#Get Mono/TFE version|0018 - Get Mono/TFE version (response)]]&lt;br /&gt;
 [[#Get Mono/TFE build info|0019 - Get Mono/TFE build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - bsl id (response to 009d; 16-bit data)&lt;br /&gt;
 [[#Get hardware version|001e - Get hardware version (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - buffered temperature reading (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - BufferedSourceTemperature (3x 16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - BufferedNearPir (16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - BufferedPassiveInfrared (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - BufferedAmbientLightSensor (48-bit data; likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - BufferedPowerData (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
Buffers:&lt;br /&gt;
 [[#Temperature reading|0022 - Temperature reading]]&lt;br /&gt;
 0023 - BufferedSourceTemperature (not sure what that means)&lt;br /&gt;
 0025 - BufferedNearPir&lt;br /&gt;
 0027 - BufferedPassiveInfrared&lt;br /&gt;
 0029 - BufferedAmbientLightSensor&lt;br /&gt;
 002b - BufferedPowerData&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, C, RC, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, C, RC, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
0009 seems to indicate a wire is physically plugged in, while 0004 indicates that it is connected to something (?).&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get Mono/TFE build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get Mono/TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
See also: [[#&amp;quot;Buffers&amp;quot;|&amp;quot;Buffers&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2063</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2063"/>
		<updated>2014-08-08T20:48:17Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
* Display serial number is located in U-Boot environment variable &amp;quot;serial#&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - get mono id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - get bsl id (no data; responds with 001d)&lt;br /&gt;
   Recv 001d - bsl id (response to 009d; 16-bit data)&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
NOTE: Most of this documentation is reverse engineered from firmware version BSL-2.1 and/or TFE_BP_D2-4.0.21 for Backplate-2.x.&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - get mono id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - get bsl id (no data; responds with 001d)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - quiet (16-bit max sleep seconds)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - set wakeup mask (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - set humidity thresholds (32-bit data)&lt;br /&gt;
 00b5 - set near pir threshold (16-bit data)&lt;br /&gt;
 00b9 - set als thresholds (32-bit data)&lt;br /&gt;
 00ba - set vergence mode (48-bit data)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - &amp;quot;WakeVector&amp;quot; (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - bsl id (response to 009d; 16-bit data)&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - buffered temperature reading (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - BufferedSourceTemperature (3x 16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - BufferedNearPir (16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - BufferedPassiveInfrared (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - BufferedAmbientLightSensor (48-bit data; likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - BufferedPowerData (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
Buffers:&lt;br /&gt;
 [[#Temperature reading|0022 - Temperature reading]]&lt;br /&gt;
 0023 - BufferedSourceTemperature (not sure what that means)&lt;br /&gt;
 0025 - BufferedNearPir&lt;br /&gt;
 0027 - BufferedPassiveInfrared&lt;br /&gt;
 0029 - BufferedAmbientLightSensor&lt;br /&gt;
 002b - BufferedPowerData&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, C, RC, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, C, RC, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
0009 seems to indicate a wire is physically plugged in, while 0004 indicates that it is connected to something (?).&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
See also: [[#&amp;quot;Buffers&amp;quot;|&amp;quot;Buffers&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2062</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2062"/>
		<updated>2014-08-08T20:29:27Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
* Display serial number is located in U-Boot environment variable &amp;quot;serial#&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - get mono id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d)&lt;br /&gt;
   Recv 001d - Response to 009d (16-bit data)&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
NOTE: Most of this documentation is reverse engineered from firmware version BSL-2.1 and/or TFE_BP_D2-4.0.21 for Backplate-2.x.&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - get mono id (no data; response 0010 with 3 bytes)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - quiet (16-bit max sleep seconds)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - set wakeup mask (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - set humidity thresholds (32-bit data)&lt;br /&gt;
 00b5 - set near pir threshold (16-bit data)&lt;br /&gt;
 00b9 - set als thresholds (32-bit data)&lt;br /&gt;
 00ba - set vergence mode (48-bit data)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - &amp;quot;WakeVector&amp;quot; (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d (16-bit data)&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - buffered temperature reading (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - BufferedSourceTemperature (3x 16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - BufferedNearPir (16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - BufferedPassiveInfrared (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - BufferedAmbientLightSensor (48-bit data; likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - BufferedPowerData (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
Buffers:&lt;br /&gt;
 [[#Temperature reading|0022 - Temperature reading]]&lt;br /&gt;
 0023 - BufferedSourceTemperature (not sure what that means)&lt;br /&gt;
 0025 - BufferedNearPir&lt;br /&gt;
 0027 - BufferedPassiveInfrared&lt;br /&gt;
 0029 - BufferedAmbientLightSensor&lt;br /&gt;
 002b - BufferedPowerData&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, C, RC, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, C, RC, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
0009 seems to indicate a wire is physically plugged in, while 0004 indicates that it is connected to something (?).&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
See also: [[#&amp;quot;Buffers&amp;quot;|&amp;quot;Buffers&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2061</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2061"/>
		<updated>2014-08-08T18:40:32Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
* Display serial number is located in U-Boot environment variable &amp;quot;serial#&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with 3 bytes)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d)&lt;br /&gt;
   Recv 001d - Response to 009d (16-bit data)&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
NOTE: Most of this documentation is reverse engineered from firmware version BSL-2.1 and/or TFE_BP_D2-4.0.21 for Backplate-2.x.&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with 3 bytes)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data)&lt;br /&gt;
 00b5 - (16-bit data)&lt;br /&gt;
 00b9 - (32-bit data)&lt;br /&gt;
 00ba - (48-bit data)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - &amp;quot;WakeVector&amp;quot; (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d (16-bit data)&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - buffered temperature reading (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - BufferedSourceTemperature (3x 16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - BufferedNearPir (16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - BufferedPassiveInfrared (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - BufferedAmbientLightSensor (48-bit data; likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - BufferedPowerData (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
Buffers:&lt;br /&gt;
 [[#Temperature reading|0022 - Temperature reading]]&lt;br /&gt;
 0023 - BufferedSourceTemperature (not sure what that means)&lt;br /&gt;
 0025 - BufferedNearPir&lt;br /&gt;
 0027 - BufferedPassiveInfrared&lt;br /&gt;
 0029 - BufferedAmbientLightSensor&lt;br /&gt;
 002b - BufferedPowerData&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, C, RC, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, C, RC, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
0009 seems to indicate a wire is physically plugged in, while 0004 indicates that it is connected to something (?).&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
See also: [[#&amp;quot;Buffers&amp;quot;|&amp;quot;Buffers&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2060</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2060"/>
		<updated>2014-08-08T03:23:22Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
* Display serial number is located in U-Boot environment variable &amp;quot;serial#&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
NOTE: Most of this documentation is reverse engineered from firmware version BSL-2.1 and/or TFE_BP_D2-4.0.21 for Backplate-2.x.&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - &amp;quot;WakeVector&amp;quot; (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - buffered temperature reading (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - BufferedSourceTemperature (3x 16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - BufferedNearPir (16-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - BufferedPassiveInfrared (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - BufferedAmbientLightSensor (48-bit data; likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - BufferedPowerData (64-bit data; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
Buffers:&lt;br /&gt;
 [[#Temperature reading|0022 - Temperature reading]]&lt;br /&gt;
 0023 - BufferedSourceTemperature (not sure what that means)&lt;br /&gt;
 0025 - BufferedNearPir&lt;br /&gt;
 0027 - BufferedPassiveInfrared&lt;br /&gt;
 0029 - BufferedAmbientLightSensor&lt;br /&gt;
 002b - BufferedPowerData&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, C, RC, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, C, RC, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
0009 seems to indicate a wire is physically plugged in, while 0004 indicates that it is connected to something (?).&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
See also: [[#&amp;quot;Buffers&amp;quot;|&amp;quot;Buffers&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2059</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2059"/>
		<updated>2014-08-08T03:10:36Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
* Display serial number is located in U-Boot environment variable &amp;quot;serial#&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
NOTE: Most of this documentation is reverse engineered from firmware version BSL-2.1 and/or TFE_BP_D2-4.0.21 for Backplate-2.x.&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - &amp;quot;WakeVector&amp;quot; (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - buffered temperature reading (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - 16-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
Buffers:&lt;br /&gt;
 [[#Temperature reading|0022 - Temperature reading]]&lt;br /&gt;
 0023 - BufferedSourceTemperature (not sure what that means)&lt;br /&gt;
 0025 - ? BufferedPassiveInfrared or BufferedNearPir&lt;br /&gt;
 0027 - ? BufferedPassiveInfrared or BufferedNearPir&lt;br /&gt;
 0029 - BufferedAmbientLightSensor&lt;br /&gt;
 002b - BufferedPowerData&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, C, RC, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, C, RC, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
0009 seems to indicate a wire is physically plugged in, while 0004 indicates that it is connected to something (?).&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
See also: [[#&amp;quot;Buffers&amp;quot;|&amp;quot;Buffers&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2058</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2058"/>
		<updated>2014-08-08T03:03:51Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* &amp;quot;Buffers&amp;quot; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
* Display serial number is located in U-Boot environment variable &amp;quot;serial#&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
NOTE: Most of this documentation is reverse engineered from firmware version BSL-2.1 and/or TFE_BP_D2-4.0.21 for Backplate-2.x.&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - buffered temperature reading (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - 16-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
Buffers:&lt;br /&gt;
 [[#Temperature reading|0022 - Temperature reading]]&lt;br /&gt;
 0023 - BufferedSourceTemperature (not sure what that means)&lt;br /&gt;
 0025 - ? BufferedPassiveInfrared or BufferedNearPir&lt;br /&gt;
 0027 - ? BufferedPassiveInfrared or BufferedNearPir&lt;br /&gt;
 0029 - BufferedAmbientLightSensor&lt;br /&gt;
 002b - BufferedPowerData&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, C, RC, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, C, RC, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
0009 seems to indicate a wire is physically plugged in, while 0004 indicates that it is connected to something (?).&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
See also: [[#&amp;quot;Buffers&amp;quot;|&amp;quot;Buffers&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2057</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2057"/>
		<updated>2014-08-08T02:51:56Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* &amp;quot;Buffers&amp;quot; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
* Display serial number is located in U-Boot environment variable &amp;quot;serial#&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
NOTE: Most of this documentation is reverse engineered from firmware version BSL-2.1 and/or TFE_BP_D2-4.0.21 for Backplate-2.x.&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - buffered temperature reading (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - 16-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
Buffers:&lt;br /&gt;
 [[#Temperature reading|0022 - Temperature reading]]&lt;br /&gt;
 0023 - BufferedSourceTemperature (not sure what that means)&lt;br /&gt;
 0025 - ?&lt;br /&gt;
 0027 - ?&lt;br /&gt;
 0029 - ?&lt;br /&gt;
 002b - ?&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, C, RC, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, C, RC, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
0009 seems to indicate a wire is physically plugged in, while 0004 indicates that it is connected to something (?).&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
See also: [[#&amp;quot;Buffers&amp;quot;|&amp;quot;Buffers&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2056</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2056"/>
		<updated>2014-08-08T02:50:38Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: Temperature buffer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
* Display serial number is located in U-Boot environment variable &amp;quot;serial#&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
NOTE: Most of this documentation is reverse engineered from firmware version BSL-2.1 and/or TFE_BP_D2-4.0.21 for Backplate-2.x.&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - buffered temperature reading (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - 16-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
Buffers:&lt;br /&gt;
 [[#Temperature reading|0022 - Temperature reading]]&lt;br /&gt;
 0023 - ?&lt;br /&gt;
 0025 - ?&lt;br /&gt;
 0027 - ?&lt;br /&gt;
 0029 - ?&lt;br /&gt;
 002b - ?&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, C, RC, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, C, RC, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
0009 seems to indicate a wire is physically plugged in, while 0004 indicates that it is connected to something (?).&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
See also: [[#&amp;quot;Buffers&amp;quot;|&amp;quot;Buffers&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2055</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2055"/>
		<updated>2014-08-08T02:28:48Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* FET presence */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
* Display serial number is located in U-Boot environment variable &amp;quot;serial#&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
NOTE: Most of this documentation is reverse engineered from firmware version BSL-2.1 and/or TFE_BP_D2-4.0.21 for Backplate-2.x.&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - 32-bit data (likely 2x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - 16-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, C, RC, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, C, RC, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
0009 seems to indicate a wire is physically plugged in, while 0004 indicates that it is connected to something (?).&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2054</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2054"/>
		<updated>2014-08-07T02:50:07Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Nest backplate interface */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
* Display serial number is located in U-Boot environment variable &amp;quot;serial#&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
NOTE: Most of this documentation is reverse engineered from firmware version BSL-2.1 and/or TFE_BP_D2-4.0.21 for Backplate-2.x.&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - 32-bit data (likely 2x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - 16-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2053</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2053"/>
		<updated>2014-08-07T02:48:34Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Info */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
* Display serial number is located in U-Boot environment variable &amp;quot;serial#&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - 32-bit data (likely 2x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - 16-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2052</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2052"/>
		<updated>2014-08-07T02:33:56Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Nest backplate interface */ ABC order&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - 32-bit data (likely 2x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - 16-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2051</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2051"/>
		<updated>2014-08-07T02:33:00Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* FET control */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - 32-bit data (likely 2x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - 16-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Buffers&amp;quot; ===&lt;br /&gt;
The 00a2 message requests the backplate send the contents of various &amp;quot;buffers&amp;quot;, which are returned in messages [0025], [0027], 0022, 0023, [0029], and [002b] (empty ones will NOT be sent; brackets infer commonly-empty buffers).&lt;br /&gt;
00a2 also triggers 000c immediately following these.&lt;br /&gt;
After all the buffers (including 000c) have been sent, the message 002f indicates &amp;quot;end of buffers&amp;quot;.&lt;br /&gt;
The display is then expected to acknowledge it with message 00a3.&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2050</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2050"/>
		<updated>2014-08-07T02:29:58Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Display to backplate */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a3 - ACK to 002f (no data)]]&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - 32-bit data (likely 2x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - 16-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2049</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2049"/>
		<updated>2014-08-07T02:29:26Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Command ids */ Group &amp;quot;buffers&amp;quot; together&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|00a2 - Request &amp;quot;buffers&amp;quot; (every 30 seconds; no data; triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)]]&lt;br /&gt;
 00a3 - (every 30 seconds; no data; likely ACK to 002f)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av; included in [[#&amp;quot;Buffers&amp;quot;|&amp;quot;buffers&amp;quot; data]])&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0022 - 32-bit data (likely 2x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0023 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0025 - 16-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0027 - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|0029 - 48-bit data (likely 3x 16-bit; possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002b - 64-bit data (possibly multiple times)]]&lt;br /&gt;
 [[#&amp;quot;Buffers&amp;quot;|002f - End of &amp;quot;buffers&amp;quot; (16-bit data)]]&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2048</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2048"/>
		<updated>2014-08-07T02:21:33Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Display to backplate */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data; likely triggers [0025] [0027] 0022 0023 [0029] [002b] 000c 002f)&lt;br /&gt;
 00a3 - (every 30 seconds; no data; likely ACK to 002f)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2047</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2047"/>
		<updated>2014-08-07T02:08:24Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: 002f is serial number&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 Recv [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get serial number|009f - Get serial number]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get serial number|001f - Get serial number (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get serial number ===&lt;br /&gt;
Message 009f (no data) requests the backplate report its serial number (a 64-bit hexadecimal value).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2046</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2046"/>
		<updated>2014-08-07T02:05:05Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Backplate to display */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 2x(?) 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2045</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2045"/>
		<updated>2014-08-07T01:56:03Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Info */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
** Nest turns off wifi below 3.7 V, and waits until 3.8 V to automatically reconnect&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2044</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2044"/>
		<updated>2014-08-07T01:53:02Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Info */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
* /sys/class/hwmon/hwmon0/device/in0_battery_type * 0.003 is battery voltage&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2043</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2043"/>
		<updated>2014-08-06T02:09:29Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Hardware */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[https://www.ifixit.com/Teardown/Nest+Learning+Thermostat+2nd+Generation+Teardown/13818 Pictures]&lt;br /&gt;
&lt;br /&gt;
=== Backplate ===&lt;br /&gt;
* ST Microelectronics STM32L151VB ultra-low-power 32 MHz ARM Cortex-M3 MCU&lt;br /&gt;
* Sensirion SHT20 humidity and temperature sensor&lt;br /&gt;
* Texas Instruments LW051A 8-channel CMOS analog multiplexer/demultiplexer&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
* Texas Instruments AM3703CUS Sitara ARM Cortex A8 microprocessor&lt;br /&gt;
* Texas Instruments TPS65921B power management and USB single chip&lt;br /&gt;
* Samsung K4X51163PK 512 Mb mobile DRAM&lt;br /&gt;
* Ember EM357 integrated ZigBee/802.15.4 system-on-chip&lt;br /&gt;
* Micron MT29F2G16ABBEAH4 2 Gb NAND flash memory&lt;br /&gt;
* Skyworks 2436L high power 2.4 GHz 802.15.4 front-end module&lt;br /&gt;
* Texas Instruments WL1270B 802.11 b/g/n Wi-Fi solution&lt;br /&gt;
* Avago ADBM-A350 optical finger navigation module (knob movement sensor)&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2042</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2042"/>
		<updated>2014-08-04T07:14:04Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Backplate initialisation */ Serial config&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
* TSL2571 Light-to-Digital Converter&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 tcflush(fd, TCIFLUSH)&lt;br /&gt;
 Set baud to 115200 (-opost -isig -icanon -echo ...)&lt;br /&gt;
 tcflush(fd, TCIOFLUSH)&lt;br /&gt;
 tcsendbreak(fd, 1)&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2041</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2041"/>
		<updated>2014-08-03T20:15:25Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* FET presence */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
* TSL2571 Light-to-Digital Converter&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
In a power outage condition, 0004 will report all absent (including unknown ones), whereas 0009 will continue to report the same as when power is available.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2040</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2040"/>
		<updated>2014-07-30T17:42:42Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
* TSL2571 Light-to-Digital Converter&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 [[#Periodic status|0083 - Periodic status request]]&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Periodic status ===&lt;br /&gt;
Sending message 0083 (no data) will trigger various periodic messages:&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
&lt;br /&gt;
The Nest client sends 0083 every 30 seconds, but at least the periodic temperature status will continue on for an hour before stopping.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2038</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2038"/>
		<updated>2014-07-28T03:27:31Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Backplate firmware */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
* TSL2571 Light-to-Digital Converter&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 12 different firmwares in the file:&lt;br /&gt;
* Test vs Production&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
Python script to extract them into individual files: [http://luke.dashjr.org/programs/freeabode/kindling/extract-fw.py extract-fw.py]&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2037</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2037"/>
		<updated>2014-07-28T01:50:35Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Backplate firmware upload */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
* TSL2571 Light-to-Digital Converter&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 6 different firmwares in the file:&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
For uploading the firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=0000&amp;lt;firmware type&amp;gt;&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
Uploading the BSL firmware was followed by the TFE firmware, so it may be required (though uploading the TFE firmware does &#039;&#039;not&#039;&#039; require uploading the BSL).&lt;br /&gt;
&lt;br /&gt;
Firmware type is either 4d for TFE or 42 for BSL.&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2036</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2036"/>
		<updated>2014-07-28T01:38:03Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Backplate to display */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
* TSL2571 Light-to-Digital Converter&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 6 different firmwares in the file:&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload (ACK)]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
At least for uploading the TFE firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=00004d&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2035</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2035"/>
		<updated>2014-07-28T01:37:48Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Display to backplate */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
* TSL2571 Light-to-Digital Converter&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 6 different firmwares in the file:&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload (start)]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0093 - Backplate firmware upload (finish)]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
At least for uploading the TFE firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=00004d&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2034</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2034"/>
		<updated>2014-07-28T00:01:50Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Backplate communications */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
* TSL2571 Light-to-Digital Converter&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
Note that nest-intercept.c also has a &amp;quot;hack&amp;quot; variable which can be set to 0 (default is 2) in order to corrupt the TFE version response and trigger nlclient into uploading the firmware again.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 6 different firmwares in the file:&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
At least for uploading the TFE firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=00004d&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2033</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2033"/>
		<updated>2014-07-27T23:57:17Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Backplate firmware upload */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
* TSL2571 Light-to-Digital Converter&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded (half-duplex for now - only reads) in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 6 different firmwares in the file:&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
At least for uploading the TFE firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=00004d&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 Send 0092 data=a901...&lt;br /&gt;
 Recv 0011 data=a901&lt;br /&gt;
 Send 0093 data=aa01&lt;br /&gt;
 Recv 0011 data=aa01&lt;br /&gt;
Following the upload, the [[#Backplate initialisation|backplate initialisation process]] begins immediately (that is, without message 00ff being sent to order a reset).&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2032</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2032"/>
		<updated>2014-07-27T23:36:10Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Backplate firmware upload */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
* TSL2571 Light-to-Digital Converter&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded (half-duplex for now - only reads) in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 6 different firmwares in the file:&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware upload ===&lt;br /&gt;
At least for uploading the TFE firmware, the following sequence is used:&lt;br /&gt;
 Send 0091 data=00004d&lt;br /&gt;
 Recv 0011 data=0000&lt;br /&gt;
 Send 0092 data=0100...&lt;br /&gt;
 Recv 0011 data=0100&lt;br /&gt;
 Send 0092 data=0200...&lt;br /&gt;
 Recv 0011 data=0200&lt;br /&gt;
 ...&lt;br /&gt;
 (UNKNOWN)&lt;br /&gt;
Presumably the 0011 message is an ACK, and the first 16 bits of each message is the line number.&lt;br /&gt;
The format itself appears to be Motorola S-record (SREC).&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2031</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2031"/>
		<updated>2014-07-27T23:31:25Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Command ids */ Backplate firmware upload&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
* TSL2571 Light-to-Digital Converter&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded (half-duplex for now - only reads) in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 6 different firmwares in the file:&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Backplate firmware upload|0091 - Backplate firmware upload]]&lt;br /&gt;
 [[#Backplate firmware upload|0092 - Backplate firmware upload]]&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 [[#Backplate firmware upload|0011 - Backplate firmware upload]]&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2030</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2030"/>
		<updated>2014-07-27T22:07:09Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Backplate firmware */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
* TSL2571 Light-to-Digital Converter&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate communications ===&lt;br /&gt;
Backplate communications can be decoded from a (filtered) strace log using [http://luke.dashjr.org/programs/freeabode/kindling/NestDecode.pl NestDecode.pl], or decoded (half-duplex for now - only reads) in real time using [http://luke.dashjr.org/programs/freeabode/kindling/nest-intercept.c nest-intercept.c].&lt;br /&gt;
&lt;br /&gt;
nest-intercept.c requires one argument, the thread id reading from the backplate controller.&lt;br /&gt;
The easiest way to get this is to strace the nlclient process with -ff and look for a thread reading from fd 54.&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 6 different firmwares in the file:&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2029</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2029"/>
		<updated>2014-07-27T04:53:44Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: 00ff does a reset&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
* TSL2571 Light-to-Digital Converter&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 6 different firmwares in the file:&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 Send [[#Reset|00ff - Reset]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Reset|00ff - Reset]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Reset ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to reset.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2028</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2028"/>
		<updated>2014-07-27T04:50:11Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
* TSL2571 Light-to-Digital Converter&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 6 different firmwares in the file:&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 Send [[#Request info|00ff - Request info]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
   Recv 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
   Recv 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data; responds with 001c (constant?) data=&amp;quot;BSL&amp;quot;)&lt;br /&gt;
 009d - (no data; responds with 001d (constant?) data=bbbb)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Request info|00ff - Request info]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - Response to 009c; always(?) &amp;quot;BSL&amp;quot;&lt;br /&gt;
 001d - Response to 009d; always(?) bbbb&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Request info ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to request information.&lt;br /&gt;
This takes just under half a second, so it may trigger some initialisation as well.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2027</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2027"/>
		<updated>2014-07-27T04:46:31Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: Get BSL version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
* TSL2571 Light-to-Digital Converter&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 6 different firmwares in the file:&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 Send [[#Request info|00ff - Request info]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data)&lt;br /&gt;
   Recv 001d - (16-bit data)&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
   Recv [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data)&lt;br /&gt;
   Recv 001c - (24-bit data)&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 [[#Get BSL version|009b - Get BSL version]]&lt;br /&gt;
 009c - (no data)&lt;br /&gt;
 009d - (no data)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Request info|00ff - Request info]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 [[#Get BSL version|001b - Get BSL version (response)]]&lt;br /&gt;
 001c - (24-bit data)&lt;br /&gt;
 001d - (16-bit data)&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get BSL version ===&lt;br /&gt;
Message 009b (no data) requests the backplate report its BSL version number.&lt;br /&gt;
The response will be message 001b in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Request info ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to request information.&lt;br /&gt;
This takes just under half a second, so it may trigger some initialisation as well.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2026</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2026"/>
		<updated>2014-07-27T04:44:17Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: 0098 is TFE version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
* TSL2571 Light-to-Digital Converter&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 6 different firmwares in the file:&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 Send [[#Request info|00ff - Request info]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data)&lt;br /&gt;
   Recv 001d - (16-bit data)&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009b - (no data)&lt;br /&gt;
   Recv 001b - (24-bit data)&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data)&lt;br /&gt;
   Recv 001c - (24-bit data)&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Get TFE version|0098 - Get TFE version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 009b - (no data)&lt;br /&gt;
 009c - (no data)&lt;br /&gt;
 009d - (no data)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Request info|00ff - Request info]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get TFE version|0018 - Get TFE version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 001b - (24-bit data)&lt;br /&gt;
 001c - (24-bit data)&lt;br /&gt;
 001d - (16-bit data)&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get TFE version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its TFE version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Request info ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to request information.&lt;br /&gt;
This takes just under half a second, so it may trigger some initialisation as well.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2025</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2025"/>
		<updated>2014-07-27T04:32:26Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Backplate initialisation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
* TSL2571 Light-to-Digital Converter&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 6 different firmwares in the file:&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
=== Backplate initialisation ===&lt;br /&gt;
When the backplate is first connected, the following sequence occurs:&lt;br /&gt;
 Send [[#Request info|00ff - Request info]]&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 Recv [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 Send [[#FET presence|008f - FET presence]]&lt;br /&gt;
 Send 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 Send 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0001 - (message from backplate; ASCII)&lt;br /&gt;
 Recv 0010 - (24-bit data)&lt;br /&gt;
 Send [[#Get version|0098 - Get version]]&lt;br /&gt;
 Recv 000a - (every second; 16-bit data)&lt;br /&gt;
 Recv 0007 - (every second; 16-bit data)&lt;br /&gt;
 Recv [[#Get version|0018 - Get version (response)]]&lt;br /&gt;
 Send [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 Recv [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009d - (no data)&lt;br /&gt;
   Recv 001d - (16-bit data)&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009b - (no data)&lt;br /&gt;
   Recv 001b - (24-bit data)&lt;br /&gt;
 Sometimes:&lt;br /&gt;
   Send 009c - (no data)&lt;br /&gt;
   Recv 001c - (24-bit data)&lt;br /&gt;
 Send [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 Recv [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 Send [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 Recv [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Get version|0098 - Get version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 009b - (no data)&lt;br /&gt;
 009c - (no data)&lt;br /&gt;
 009d - (no data)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Request info|00ff - Request info]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get version|0018 - Get version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 001b - (24-bit data)&lt;br /&gt;
 001c - (24-bit data)&lt;br /&gt;
 001d - (16-bit data)&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Request info ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to request information.&lt;br /&gt;
This takes just under half a second, so it may trigger some initialisation as well.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2024</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2024"/>
		<updated>2014-07-27T04:21:22Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Get hardware version? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
* TSL2571 Light-to-Digital Converter&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 6 different firmwares in the file:&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Get version|0098 - Get version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 009b - (no data)&lt;br /&gt;
 009c - (no data)&lt;br /&gt;
 009d - (no data)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Request info|00ff - Request info]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get version|0018 - Get version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 001b - (24-bit data)&lt;br /&gt;
 001c - (24-bit data)&lt;br /&gt;
 001d - (16-bit data)&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get hardware version? ===&lt;br /&gt;
Message 009e (no data) requests the backplate report a &amp;quot;Backplate-&amp;quot;X.Y version string.&lt;br /&gt;
Since the firmware file on the display CPU uses these strings as &amp;quot;MinApplicability&amp;quot; and &amp;quot;MaxApplicability&amp;quot; ranges, it is probable they refer to the hardware.&lt;br /&gt;
&lt;br /&gt;
Witnessed versions:&lt;br /&gt;
 &amp;quot;Backplate-2.8&amp;quot; - Florida Lowes&lt;br /&gt;
&lt;br /&gt;
=== Get version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Request info ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to request information.&lt;br /&gt;
This takes just under half a second, so it may trigger some initialisation as well.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2023</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2023"/>
		<updated>2014-07-27T04:19:21Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Command ids */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
* TSL2571 Light-to-Digital Converter&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 6 different firmwares in the file:&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Get version|0098 - Get version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 009b - (no data)&lt;br /&gt;
 009c - (no data)&lt;br /&gt;
 009d - (no data)&lt;br /&gt;
 [[#Get hardware version?|009e - Get hardware version?]]&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Request info|00ff - Request info]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get version|0018 - Get version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 001b - (24-bit data)&lt;br /&gt;
 001c - (24-bit data)&lt;br /&gt;
 001d - (16-bit data)&lt;br /&gt;
 [[#Get hardware version?|001e - Get hardware version? (response)]]&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Request info ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to request information.&lt;br /&gt;
This takes just under half a second, so it may trigger some initialisation as well.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
	<entry>
		<id>https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2022</id>
		<title>Nest Hacking</title>
		<link rel="alternate" type="text/html" href="https://wiki.exploitee.rs/index.php?title=Nest_Hacking&amp;diff=2022"/>
		<updated>2014-07-27T04:15:55Z</updated>

		<summary type="html">&lt;p&gt;Luke-Jr: /* Get firmware hash? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware ==&lt;br /&gt;
* TSL2571 Light-to-Digital Converter&lt;br /&gt;
&lt;br /&gt;
== Info ==&lt;br /&gt;
* /dev/event1 is the knob; /dev/event2 is the button&lt;br /&gt;
&lt;br /&gt;
== Nest software ==&lt;br /&gt;
 /nestlabs/sbin/nlclient -config /nestlabs/etc/client.config -config /nestlabs/etc/Display/Display-2/client.config&lt;br /&gt;
&lt;br /&gt;
=== Backplate firmware ===&lt;br /&gt;
Found in /nestlabs/share/bp/data/firmware/nlbpfirmware.plist&lt;br /&gt;
&lt;br /&gt;
There are 6 different firmwares in the file:&lt;br /&gt;
* Backplate 2 vs Backplate 3&lt;br /&gt;
* TFE (BP_D2 for Bp2, AMBER_BP for Bp3) vs BSL&lt;br /&gt;
* For TFE firmwares, hex vs srec (which for some reason DO differ!)&lt;br /&gt;
&lt;br /&gt;
== Nest backplate interface ==&lt;br /&gt;
* Connected on /dev/ttyO2&lt;br /&gt;
* All communications with backplate begin with (d5)d5aa96 (d5 is doubled only for data FROM backplate)&lt;br /&gt;
* Everything is little endian&lt;br /&gt;
* 16-bit command&lt;br /&gt;
* 16-bit data length&lt;br /&gt;
* &amp;lt;data&amp;gt;&lt;br /&gt;
* 16-bit checksum&lt;br /&gt;
&lt;br /&gt;
Monitor:&lt;br /&gt;
 strace -ff -p $(pidof nlclient) -x -s9999 -e read,write 2&amp;gt;&amp;amp;1 | grep &#039;(54&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checksum ===&lt;br /&gt;
&amp;lt;Bytes-from-end&amp;gt;.&amp;lt;bit-value&amp;gt;  &amp;lt;xor-with&amp;gt;&lt;br /&gt;
 00.01  2110 (1021)&lt;br /&gt;
 00.02  4220 (2042: 1021&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.04  8440 (4084: 2048&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.08  0881 (8108: 4084&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.10  3112 (1231: 8108&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 00.20  6224 (2462: 1231&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.40  c448 (48c4: 2462&amp;lt;&amp;lt;1)&lt;br /&gt;
 00.80  8891 (9188: 48c4&amp;lt;&amp;lt;1)&lt;br /&gt;
 01.01  3133 (3313: 9188&amp;lt;&amp;lt;1^1021)&lt;br /&gt;
 01.02  6266&lt;br /&gt;
 01.04  c4cc&lt;br /&gt;
 01.08  a989&lt;br /&gt;
 01.10  7303&lt;br /&gt;
 01.20  e606&lt;br /&gt;
 01.40  cc0d&lt;br /&gt;
 01.80  981b&lt;br /&gt;
 02.01  3037&lt;br /&gt;
 02.02  606e&lt;br /&gt;
 ...&lt;br /&gt;
 03.01  b476&lt;br /&gt;
 03.02  68ed&lt;br /&gt;
 03.04  f1ca&lt;br /&gt;
 03.08  c385&lt;br /&gt;
 03.10  a71b&lt;br /&gt;
 03.20  4e37&lt;br /&gt;
 03.40  9c6e&lt;br /&gt;
 03.80  38dd&lt;br /&gt;
 ...&lt;br /&gt;
 07.20  687b&lt;br /&gt;
&lt;br /&gt;
If you compute the contribution of the individual bit changes in the data you end up with the xor table above; byte offset from the end of the data, bit pattern, xor value. Correcting for little endianess in the output you end up with the hex values in parenthesis. The least significant bit is 0x1021 and each subsequent bit is a shift left, if the XOR value has the 0x8000 bit set then it is XORed with 0x1021. This is the CRC-CCITT polynomial.&lt;br /&gt;
&lt;br /&gt;
  8  7  6  5  4  3  2  1  0&lt;br /&gt;
 d5 aa 96 82 00 02 00 00 00: 08b2&lt;br /&gt;
          ||     |&lt;br /&gt;
          ||     68ed&lt;br /&gt;
          |408b&lt;br /&gt;
          20d4&lt;br /&gt;
  &lt;br /&gt;
 08b2: 68ed ^ 408b ^ 20d4&lt;br /&gt;
&lt;br /&gt;
Starting at the least significant bit and filling in the XOR values for each bit gives the above diagram; the diagram stops at the 20d4 XOR value because at that point it matches the final CRC. This tells us that the CRC covers the 6 bytes prior.&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env perl&lt;br /&gt;
 use Digest::CRC qw(crc);&lt;br /&gt;
 my $data = pack(&amp;quot;H*&amp;quot;, &amp;quot;820002000000&amp;quot;);&lt;br /&gt;
 printf(&amp;quot;%04x\n&amp;quot;, crc($data,16,0,0,0,0x1021,0,0));&lt;br /&gt;
&lt;br /&gt;
We can also compute the same CRC in Perl; note the result will be byte swapped since the data encodes the number as little endian.&lt;br /&gt;
&lt;br /&gt;
=== Command ids ===&lt;br /&gt;
&lt;br /&gt;
==== Display to backplate ====&lt;br /&gt;
 [[#FET control|0082 - FET control]]&lt;br /&gt;
 0083 - (every 30 seconds; no data; triggers periodic messages 0002, 0007, and 000a; also triggers 0005 to some extent?)&lt;br /&gt;
 [[#FET presence|008f - FET presence]]&lt;br /&gt;
 0090 - (no data; response 0010 with constant(?) 3 bytes a77948)&lt;br /&gt;
 [[#Get version|0098 - Get version]]&lt;br /&gt;
 [[#Get build info|0099 - Get build info]]&lt;br /&gt;
 009b - (no data)&lt;br /&gt;
 009c - (no data)&lt;br /&gt;
 009d - (no data)&lt;br /&gt;
 009e - (no data)&lt;br /&gt;
 [[#Get firmware hash?|009f - Get firmware hash?]]&lt;br /&gt;
 00a1 - (16-bit data)&lt;br /&gt;
 00a2 - (every 30 seconds; no data)&lt;br /&gt;
 00a3 - (every 30 seconds; no data)&lt;br /&gt;
 00a4 - (16-bit data)&lt;br /&gt;
 00b1 - button pressed/unpressed (no data)&lt;br /&gt;
 00b3 - (32-bit data; always ffffffff?)&lt;br /&gt;
 00b5 - (16-bit data; always 0f00?)&lt;br /&gt;
 00b9 - (32-bit data; always 0000ffff?)&lt;br /&gt;
 00ba - (48-bit data; always 000000000000?)&lt;br /&gt;
 00c2 - (48-bit data)&lt;br /&gt;
 [[#Request info|00ff - Request info]]&lt;br /&gt;
&lt;br /&gt;
==== Backplate to display ====&lt;br /&gt;
 0001 - (message from backplate; ASCII)&lt;br /&gt;
 [[#Temperature reading|0002 - Temperature reading (twice every 30 seconds; 32-bit data)]]&lt;br /&gt;
 [[#FET presence|0004 - FET presence]]&lt;br /&gt;
 0005 - (32-bit data)&lt;br /&gt;
 0007 - (every second; 16-bit data)&lt;br /&gt;
 [[#FET presence|0009 - FET presence]]&lt;br /&gt;
 000a - (every second; 16-bit data)&lt;br /&gt;
 [[#Backplate state|000b - Backplate state]]&lt;br /&gt;
 000c - (16-bit values: pir, px1, px1 divisor, px2, px2 divisor, alir, av)&lt;br /&gt;
 0010 - (24-bit data)&lt;br /&gt;
 0014 - (16-bit data)&lt;br /&gt;
 [[#Get version|0018 - Get version (response)]]&lt;br /&gt;
 [[#Get build info|0019 - Get build info (response)]]&lt;br /&gt;
 001b - (24-bit data)&lt;br /&gt;
 001c - (24-bit data)&lt;br /&gt;
 001d - (16-bit data)&lt;br /&gt;
 001e - (13-BYTE data)&lt;br /&gt;
 [[#Get firmware hash?|001f - Get firmware hash? (response)]]&lt;br /&gt;
 0022 - (every 30 seconds; 4, 8, 20, 28, 36, 56, 60, 54, 68, 72, or 176 byte data)&lt;br /&gt;
 0023 - (6, 12, 30, 42, 54, 78, 84, 90, 96, 102, 108, 144, or 150 byte data)&lt;br /&gt;
 0025 - (2, 4, 12, 14, 20, or 24 byte data)&lt;br /&gt;
 0027 - (8, 16, 48, 56, 80, or 96 byte data)&lt;br /&gt;
 0029 - (6, 12, 36, 42, 60, or 72 byte data)&lt;br /&gt;
 002b - (8, 16, 24, 32, 40, 128, or 152 byte data)&lt;br /&gt;
 002f - (every 30 seconds; 16-bit data; &amp;quot;end of buffers ACK&amp;quot; log msg)&lt;br /&gt;
&lt;br /&gt;
=== Backplate state ===&lt;br /&gt;
Data:&lt;br /&gt;
* 8-bit &amp;quot;state&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;flags&amp;quot;&lt;br /&gt;
* 8-bit &amp;quot;px0&amp;quot; (may be wider?)&lt;br /&gt;
* 40-bit UNKNOWN (includes at least &amp;quot;p2&amp;quot; and &amp;quot;voc&amp;quot;)&lt;br /&gt;
* 16-bit centi-volts &amp;quot;vi&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vo&amp;quot;&lt;br /&gt;
* 16-bit milli-volts &amp;quot;vb&amp;quot;&lt;br /&gt;
* 8-bit (&amp;quot;pins&amp;quot; or &amp;quot;wires&amp;quot;)&lt;br /&gt;
* 8-bit (&amp;quot;wires&amp;quot; or &amp;quot;pins&amp;quot;)&lt;br /&gt;
* 16-bit UNKNOWN&lt;br /&gt;
&lt;br /&gt;
=== FET control ===&lt;br /&gt;
 Turn on  W1: d5aa96 8200 0200 00 01 29a2&lt;br /&gt;
 Turn off W1: d5aa96 8200 0200 00 00 08b2&lt;br /&gt;
 Turn on  Y1: d5aa96 8200 0200 01 01 1891&lt;br /&gt;
 Turn off Y1: d5aa96 8200 0200 01 00 3981&lt;br /&gt;
 Turn on  G : d5aa96 8200 0200 02 01 4bc4&lt;br /&gt;
 Turn off G : d5aa96 8200 0200 02 00 6ad4&lt;br /&gt;
 Turn on  OB: d5aa96 8200 0200 03 01 7af7&lt;br /&gt;
 Turn off OB: d5aa96 8200 0200 03 00 5be7&lt;br /&gt;
 Turn on  W2: d5aa96 8200 0200 04 01 ed6e&lt;br /&gt;
 Turn off W2: d5aa96 8200 0200 04 00 cc7e&lt;br /&gt;
 Turn on  Y2: d5aa96 8200 0200 07 01 be3b&lt;br /&gt;
 Turn off Y2: d5aa96 8200 0200 07 00 9f2b&lt;br /&gt;
 Turn on  * : d5aa96 8200 0200 0b 01 d37e&lt;br /&gt;
 Turn off * : d5aa96 8200 0200 0b 00 f26e&lt;br /&gt;
&lt;br /&gt;
For the sake of documentation, we will refer to the unique id numbers for each wire as &amp;quot;wire id numbers&amp;quot;.&lt;br /&gt;
So wire id 0 is W1, wire id 1 is Y1, wire id B is *, etc.&lt;br /&gt;
&lt;br /&gt;
=== FET presence ===&lt;br /&gt;
The backplate will, at least upon connection, send information about which FETs have a wire present.&lt;br /&gt;
This data is received with command ids 0004 and 0009, in that order.&lt;br /&gt;
Each sensor is represented by one byte which is either 00 (not present) or 01 (present).&lt;br /&gt;
&lt;br /&gt;
The content of 0004 is in order of the &amp;quot;wire id numbers&amp;quot; used for control:&lt;br /&gt;
W1, Y1, G, OB, W2, ?0, ?0, Y2, ?1, ?1, ?0, *, ?0&lt;br /&gt;
&lt;br /&gt;
The content of 0009 is arranged differently and has 2 more values:&lt;br /&gt;
W1, Y1, ?1, ?1, ?0, G, OB, W2, ?0, Y2, ?0, *, ?0, ?0, ?0&lt;br /&gt;
&lt;br /&gt;
After these are received, the display sends back command 008f with the exact data from message 0004.&lt;br /&gt;
Message 008f does not itself receive any response.&lt;br /&gt;
&lt;br /&gt;
=== Get build info ===&lt;br /&gt;
Message 0099 (no data) requests the backplate report information about its build.&lt;br /&gt;
The response will be message 0019 in ASCII (one line, no trailing newline).&lt;br /&gt;
&lt;br /&gt;
=== Get firmware hash? ===&lt;br /&gt;
Message 009f (no data) requests the backplate report a 64-bit hexadecimal value, probably a hash of the firmware (since Nest&#039;s software requests it at the same time as version and build info).&lt;br /&gt;
The response will be message 001f in uppercase ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Get version ===&lt;br /&gt;
Message 0098 (no data) requests the backplate report its version number.&lt;br /&gt;
The response will be message 0018 in ASCII.&lt;br /&gt;
&lt;br /&gt;
=== Temperature reading ===&lt;br /&gt;
The backplate will send message 0002 every 30 seconds.&lt;br /&gt;
The data contains two 16-bit numbers, which nlclient logs in decimal.&lt;br /&gt;
The first number is the temperature in centi-celcius.&lt;br /&gt;
The second number is the humidity in per-millis.&lt;br /&gt;
&lt;br /&gt;
=== Request info ===&lt;br /&gt;
At least upon connection, the display sends message 00ff to the backplate to request information.&lt;br /&gt;
This takes just under half a second, so it may trigger some initialisation as well.&lt;br /&gt;
&lt;br /&gt;
The backplate answers with:&lt;br /&gt;
 0001 msg &amp;quot;&amp;lt;version&amp;gt; &amp;lt;build timestamp &amp;quot;YYYY-MM-DD HH:MM:SS&amp;quot;&amp;gt; K&amp;quot;&lt;br /&gt;
 [[#FET presence|0004 FET presence]]&lt;br /&gt;
 [[#FET presence|0009 FET presence]]&lt;br /&gt;
 0001 msg &amp;quot;*sense 06d1 06d0 0001 0001 0000 0000 0000 0001 06d9 06d8 06d8; detect 09d3 065c&amp;quot;&lt;br /&gt;
 0001 msg &amp;quot;BRK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Run BeagleBone/Debian programs ==&lt;br /&gt;
 ln -s . /lib/arm-linux-gnueabihf&lt;br /&gt;
 ln -s ld-2.11.1.so /lib/ld-linux-armhf.so.3&lt;/div&gt;</summary>
		<author><name>Luke-Jr</name></author>
	</entry>
</feed>