Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: MaximInterface
SensorNode.cpp@12:46c5974a565f, 2017-06-01 (annotated)
- Committer:
- IanBenzMaxim
- Date:
- Thu Jun 01 14:21:58 2017 -0500
- Revision:
- 12:46c5974a565f
- Parent:
- 0:33d4e66780c0
- Child:
- 13:6a6225690c2e
Added bidirectional challenge support.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| IanBenzMaxim | 0:33d4e66780c0 | 1 | /******************************************************************************* |
| IanBenzMaxim | 0:33d4e66780c0 | 2 | * Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved. |
| IanBenzMaxim | 0:33d4e66780c0 | 3 | * |
| IanBenzMaxim | 0:33d4e66780c0 | 4 | * Permission is hereby granted, free of charge, to any person obtaining a |
| IanBenzMaxim | 0:33d4e66780c0 | 5 | * copy of this software and associated documentation files (the "Software"), |
| IanBenzMaxim | 0:33d4e66780c0 | 6 | * to deal in the Software without restriction, including without limitation |
| IanBenzMaxim | 0:33d4e66780c0 | 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| IanBenzMaxim | 0:33d4e66780c0 | 8 | * and/or sell copies of the Software, and to permit persons to whom the |
| IanBenzMaxim | 0:33d4e66780c0 | 9 | * Software is furnished to do so, subject to the following conditions: |
| IanBenzMaxim | 0:33d4e66780c0 | 10 | * |
| IanBenzMaxim | 0:33d4e66780c0 | 11 | * The above copyright notice and this permission notice shall be included |
| IanBenzMaxim | 0:33d4e66780c0 | 12 | * in all copies or substantial portions of the Software. |
| IanBenzMaxim | 0:33d4e66780c0 | 13 | * |
| IanBenzMaxim | 0:33d4e66780c0 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| IanBenzMaxim | 0:33d4e66780c0 | 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| IanBenzMaxim | 0:33d4e66780c0 | 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| IanBenzMaxim | 0:33d4e66780c0 | 17 | * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES |
| IanBenzMaxim | 0:33d4e66780c0 | 18 | * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
| IanBenzMaxim | 0:33d4e66780c0 | 19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| IanBenzMaxim | 0:33d4e66780c0 | 20 | * OTHER DEALINGS IN THE SOFTWARE. |
| IanBenzMaxim | 0:33d4e66780c0 | 21 | * |
| IanBenzMaxim | 0:33d4e66780c0 | 22 | * Except as contained in this notice, the name of Maxim Integrated |
| IanBenzMaxim | 0:33d4e66780c0 | 23 | * Products, Inc. shall not be used except as stated in the Maxim Integrated |
| IanBenzMaxim | 0:33d4e66780c0 | 24 | * Products, Inc. Branding Policy. |
| IanBenzMaxim | 0:33d4e66780c0 | 25 | * |
| IanBenzMaxim | 0:33d4e66780c0 | 26 | * The mere transfer of this software does not imply any licenses |
| IanBenzMaxim | 0:33d4e66780c0 | 27 | * of trade secrets, proprietary technology, copyrights, patents, |
| IanBenzMaxim | 0:33d4e66780c0 | 28 | * trademarks, maskwork rights, or any other form of intellectual |
| IanBenzMaxim | 0:33d4e66780c0 | 29 | * property whatsoever. Maxim Integrated Products, Inc. retains all |
| IanBenzMaxim | 0:33d4e66780c0 | 30 | * ownership rights. |
| IanBenzMaxim | 0:33d4e66780c0 | 31 | *******************************************************************************/ |
| IanBenzMaxim | 0:33d4e66780c0 | 32 | |
| IanBenzMaxim | 0:33d4e66780c0 | 33 | #include <string> |
| IanBenzMaxim | 0:33d4e66780c0 | 34 | #include <I2C.h> |
| IanBenzMaxim | 0:33d4e66780c0 | 35 | #include "RomId.h" |
| IanBenzMaxim | 0:33d4e66780c0 | 36 | #include "HexConversions.hpp" |
| IanBenzMaxim | 0:33d4e66780c0 | 37 | #include "DS2476.hpp" |
| IanBenzMaxim | 0:33d4e66780c0 | 38 | #include "Factory.hpp" |
| IanBenzMaxim | 0:33d4e66780c0 | 39 | #include "SensorNode.hpp" |
| IanBenzMaxim | 0:33d4e66780c0 | 40 | |
| IanBenzMaxim | 0:33d4e66780c0 | 41 | // I2C address of the MLX90614. |
| IanBenzMaxim | 0:33d4e66780c0 | 42 | static const uint8_t mlx90614Addr = 0xB4; |
| IanBenzMaxim | 0:33d4e66780c0 | 43 | |
| IanBenzMaxim | 0:33d4e66780c0 | 44 | /// DS2476 derives the slave secret for a certain DS28C36 from the master secret. |
| IanBenzMaxim | 0:33d4e66780c0 | 45 | /// @param ds2476 DS2476 that will compute slave secret. |
| IanBenzMaxim | 0:33d4e66780c0 | 46 | /// @param ds28c36 DS28C36 containing the slave secret of interest. |
| IanBenzMaxim | 0:33d4e66780c0 | 47 | /// @param[out] message Contains the HMAC input used when computing the slave secret. Output to |
| IanBenzMaxim | 0:33d4e66780c0 | 48 | /// prevent redundant page reads. |
| IanBenzMaxim | 0:33d4e66780c0 | 49 | /// @param print Optional callback for displaying informational messages to the user. |
| IanBenzMaxim | 0:33d4e66780c0 | 50 | /// @returns True if the operation was successful. |
| IanBenzMaxim | 0:33d4e66780c0 | 51 | static bool setSlaveSecret(DS2476 & ds2476, DS28C36 & ds28c36, DS2476::Buffer & message, |
| IanBenzMaxim | 0:33d4e66780c0 | 52 | const SensorNode::PrintHandler & print = SensorNode::PrintHandler()) |
| IanBenzMaxim | 0:33d4e66780c0 | 53 | { |
| IanBenzMaxim | 0:33d4e66780c0 | 54 | if (print) |
| IanBenzMaxim | 0:33d4e66780c0 | 55 | { |
| IanBenzMaxim | 0:33d4e66780c0 | 56 | print("Computing slave secret"); |
| IanBenzMaxim | 0:33d4e66780c0 | 57 | print("Reading DS28C36 ROM Options page for ROM ID and MAN ID"); |
| IanBenzMaxim | 0:33d4e66780c0 | 58 | } |
| IanBenzMaxim | 0:33d4e66780c0 | 59 | DS28C36::Page page; |
| IanBenzMaxim | 0:33d4e66780c0 | 60 | DS28C36::CmdResult result = ds28c36.readMemory(DS28C36::RomOptions, page); |
| IanBenzMaxim | 0:33d4e66780c0 | 61 | if (result != DS28C36::Success) |
| IanBenzMaxim | 0:33d4e66780c0 | 62 | return false; |
| IanBenzMaxim | 0:33d4e66780c0 | 63 | message.clear(); |
| IanBenzMaxim | 0:33d4e66780c0 | 64 | message.reserve(75); |
| IanBenzMaxim | 0:33d4e66780c0 | 65 | message.assign(page.begin() + 24, page.end()); |
| IanBenzMaxim | 0:33d4e66780c0 | 66 | OneWire::array<uint8_t, 2> manId = { page[22], page[23] }; |
| IanBenzMaxim | 0:33d4e66780c0 | 67 | if (print) |
| IanBenzMaxim | 0:33d4e66780c0 | 68 | { |
| IanBenzMaxim | 0:33d4e66780c0 | 69 | print("Reading User Data 0 page"); |
| IanBenzMaxim | 0:33d4e66780c0 | 70 | } |
| IanBenzMaxim | 0:33d4e66780c0 | 71 | result = ds28c36.readMemory(DS28C36::UserData0, page); |
| IanBenzMaxim | 0:33d4e66780c0 | 72 | if (result != DS28C36::Success) |
| IanBenzMaxim | 0:33d4e66780c0 | 73 | return false; |
| IanBenzMaxim | 0:33d4e66780c0 | 74 | message.insert(message.end(), page.begin(), page.end()); |
| IanBenzMaxim | 0:33d4e66780c0 | 75 | message.insert(message.end(), 32, 0x00); |
| IanBenzMaxim | 0:33d4e66780c0 | 76 | message.insert(message.end(), DS28C36::UserData0); |
| IanBenzMaxim | 0:33d4e66780c0 | 77 | message.insert(message.end(), manId.begin(), manId.end()); |
| IanBenzMaxim | 0:33d4e66780c0 | 78 | if (print) |
| IanBenzMaxim | 0:33d4e66780c0 | 79 | { |
| IanBenzMaxim | 0:33d4e66780c0 | 80 | print(("Creating HMAC message (ROM ID | Binding Data (Page Data) | Partial Secret (Buffer) | Page # | MAN ID): " + |
| IanBenzMaxim | 0:33d4e66780c0 | 81 | byteArrayToHexString(&message[0], message.size())).c_str()); |
| IanBenzMaxim | 0:33d4e66780c0 | 82 | print("Writing HMAC message to DS2476 buffer"); |
| IanBenzMaxim | 0:33d4e66780c0 | 83 | } |
| IanBenzMaxim | 0:33d4e66780c0 | 84 | result = ds2476.writeBuffer(message); |
| IanBenzMaxim | 0:33d4e66780c0 | 85 | if (result != DS2476::Success) |
| IanBenzMaxim | 0:33d4e66780c0 | 86 | return false; |
| IanBenzMaxim | 0:33d4e66780c0 | 87 | if (print) |
| IanBenzMaxim | 0:33d4e66780c0 | 88 | { |
| IanBenzMaxim | 0:33d4e66780c0 | 89 | print("DS2476 computes slave secret from master secret (Secret A) and message in buffer"); |
| IanBenzMaxim | 0:33d4e66780c0 | 90 | } |
| IanBenzMaxim | 0:33d4e66780c0 | 91 | result = ds2476.computeSha2UniqueSecret(DS2476::SecretNumA); |
| IanBenzMaxim | 0:33d4e66780c0 | 92 | if (result != DS2476::Success) |
| IanBenzMaxim | 0:33d4e66780c0 | 93 | return false; |
| IanBenzMaxim | 0:33d4e66780c0 | 94 | return true; |
| IanBenzMaxim | 0:33d4e66780c0 | 95 | } |
| IanBenzMaxim | 0:33d4e66780c0 | 96 | |
| IanBenzMaxim | 0:33d4e66780c0 | 97 | SensorNode::SensorNode(mbed::I2C & i2c, DS2476 & ds2476) : i2c(i2c), ds28c36(i2c), ds2476(ds2476) { } |
| IanBenzMaxim | 0:33d4e66780c0 | 98 | |
| IanBenzMaxim | 0:33d4e66780c0 | 99 | bool SensorNode::detect() |
| IanBenzMaxim | 0:33d4e66780c0 | 100 | { |
| IanBenzMaxim | 0:33d4e66780c0 | 101 | // Read ROM ID |
| IanBenzMaxim | 0:33d4e66780c0 | 102 | OneWire::RomId romId; |
| IanBenzMaxim | 0:33d4e66780c0 | 103 | return (DS28C36::readRomId(ds28c36, romId) == DS28C36::Success) && romId.valid(); |
| IanBenzMaxim | 0:33d4e66780c0 | 104 | } |
| IanBenzMaxim | 0:33d4e66780c0 | 105 | |
| IanBenzMaxim | 0:33d4e66780c0 | 106 | bool SensorNode::readTemp(TempStyle style, double & temp) |
| IanBenzMaxim | 0:33d4e66780c0 | 107 | { |
| IanBenzMaxim | 0:33d4e66780c0 | 108 | uint8_t data[2]; |
| IanBenzMaxim | 0:33d4e66780c0 | 109 | switch (style) |
| IanBenzMaxim | 0:33d4e66780c0 | 110 | { |
| IanBenzMaxim | 0:33d4e66780c0 | 111 | case ObjectTemp: |
| IanBenzMaxim | 0:33d4e66780c0 | 112 | default: |
| IanBenzMaxim | 0:33d4e66780c0 | 113 | data[0] = 0x07; |
| IanBenzMaxim | 0:33d4e66780c0 | 114 | break; |
| IanBenzMaxim | 0:33d4e66780c0 | 115 | |
| IanBenzMaxim | 0:33d4e66780c0 | 116 | case AmbientTemp: |
| IanBenzMaxim | 0:33d4e66780c0 | 117 | data[0] = 0x06; |
| IanBenzMaxim | 0:33d4e66780c0 | 118 | break; |
| IanBenzMaxim | 0:33d4e66780c0 | 119 | } |
| IanBenzMaxim | 0:33d4e66780c0 | 120 | int result = i2c.write(mlx90614Addr, reinterpret_cast<const char *>(data), 1, true); |
| IanBenzMaxim | 0:33d4e66780c0 | 121 | if (result != 0) |
| IanBenzMaxim | 0:33d4e66780c0 | 122 | { |
| IanBenzMaxim | 0:33d4e66780c0 | 123 | i2c.stop(); |
| IanBenzMaxim | 0:33d4e66780c0 | 124 | return false; |
| IanBenzMaxim | 0:33d4e66780c0 | 125 | } |
| IanBenzMaxim | 0:33d4e66780c0 | 126 | result = i2c.read(mlx90614Addr, reinterpret_cast<char *>(data), 2, false); |
| IanBenzMaxim | 0:33d4e66780c0 | 127 | if (result != 0) |
| IanBenzMaxim | 0:33d4e66780c0 | 128 | { |
| IanBenzMaxim | 0:33d4e66780c0 | 129 | i2c.stop(); |
| IanBenzMaxim | 0:33d4e66780c0 | 130 | return false; |
| IanBenzMaxim | 0:33d4e66780c0 | 131 | } |
| IanBenzMaxim | 0:33d4e66780c0 | 132 | temp = ((static_cast<uint_fast16_t>(data[1]) << 8) | data[0]) * 0.02 - 273.15; |
| IanBenzMaxim | 0:33d4e66780c0 | 133 | return true; |
| IanBenzMaxim | 0:33d4e66780c0 | 134 | } |
| IanBenzMaxim | 0:33d4e66780c0 | 135 | |
| IanBenzMaxim | 0:33d4e66780c0 | 136 | bool SensorNode::getProvisioned(bool & provisioned) |
| IanBenzMaxim | 0:33d4e66780c0 | 137 | { |
| IanBenzMaxim | 0:33d4e66780c0 | 138 | return checkAuthenticatorProvisioned(ds28c36, provisioned); |
| IanBenzMaxim | 0:33d4e66780c0 | 139 | } |
| IanBenzMaxim | 0:33d4e66780c0 | 140 | |
| IanBenzMaxim | 0:33d4e66780c0 | 141 | bool SensorNode::provision() |
| IanBenzMaxim | 0:33d4e66780c0 | 142 | { |
| IanBenzMaxim | 0:33d4e66780c0 | 143 | return provisionAuthenticator(ds28c36); |
| IanBenzMaxim | 0:33d4e66780c0 | 144 | } |
| IanBenzMaxim | 0:33d4e66780c0 | 145 | |
| IanBenzMaxim | 0:33d4e66780c0 | 146 | bool SensorNode::authenticate() |
| IanBenzMaxim | 0:33d4e66780c0 | 147 | { |
| IanBenzMaxim | 0:33d4e66780c0 | 148 | // Compute slave secret on coprocessor. |
| IanBenzMaxim | 0:33d4e66780c0 | 149 | DS2476::Buffer message; |
| IanBenzMaxim | 0:33d4e66780c0 | 150 | if (!setSlaveSecret(ds2476, ds28c36, message)) |
| IanBenzMaxim | 0:33d4e66780c0 | 151 | return false; |
| IanBenzMaxim | 0:33d4e66780c0 | 152 | |
| IanBenzMaxim | 0:33d4e66780c0 | 153 | // Compute HMAC on coprocessor. |
| IanBenzMaxim | 0:33d4e66780c0 | 154 | // ROM ID, Page 0, and MAN ID are already in message. |
| IanBenzMaxim | 0:33d4e66780c0 | 155 | DS2476::Buffer challenge; |
| IanBenzMaxim | 0:33d4e66780c0 | 156 | DS2476::CmdResult result = ds2476.readRng(32, challenge); |
| IanBenzMaxim | 0:33d4e66780c0 | 157 | if (result != DS2476::Success) |
| IanBenzMaxim | 0:33d4e66780c0 | 158 | return false; |
| IanBenzMaxim | 0:33d4e66780c0 | 159 | std::copy(challenge.begin(), challenge.end(), message.begin() + 40); |
| IanBenzMaxim | 0:33d4e66780c0 | 160 | result = ds2476.writeBuffer(message); |
| IanBenzMaxim | 0:33d4e66780c0 | 161 | if (result != DS2476::Success) |
| IanBenzMaxim | 0:33d4e66780c0 | 162 | return false; |
| IanBenzMaxim | 0:33d4e66780c0 | 163 | DS2476::HMAC computedHmac; |
| IanBenzMaxim | 0:33d4e66780c0 | 164 | result = ds2476.computeSha2Hmac(computedHmac); |
| IanBenzMaxim | 0:33d4e66780c0 | 165 | if (result != DS2476::Success) |
| IanBenzMaxim | 0:33d4e66780c0 | 166 | return false; |
| IanBenzMaxim | 0:33d4e66780c0 | 167 | |
| IanBenzMaxim | 0:33d4e66780c0 | 168 | // Compute HMAC on device. |
| IanBenzMaxim | 0:33d4e66780c0 | 169 | result = ds28c36.writeBuffer(challenge); |
| IanBenzMaxim | 0:33d4e66780c0 | 170 | if (result != DS28C36::Success) |
| IanBenzMaxim | 0:33d4e66780c0 | 171 | return false; |
| IanBenzMaxim | 0:33d4e66780c0 | 172 | DS28C36::HMAC deviceHmac; |
| IanBenzMaxim | 0:33d4e66780c0 | 173 | result = ds28c36.computeAndReadHmacPageAuthentication(DS28C36::UserData0, DS28C36::SecretNumA, deviceHmac); |
| IanBenzMaxim | 0:33d4e66780c0 | 174 | if (result != DS28C36::Success) |
| IanBenzMaxim | 0:33d4e66780c0 | 175 | return false; |
| IanBenzMaxim | 0:33d4e66780c0 | 176 | |
| IanBenzMaxim | 0:33d4e66780c0 | 177 | return computedHmac == deviceHmac; |
| IanBenzMaxim | 0:33d4e66780c0 | 178 | } |
| IanBenzMaxim | 0:33d4e66780c0 | 179 | |
| IanBenzMaxim | 0:33d4e66780c0 | 180 | bool SensorNode::setLaserEnabled(bool enabled, const PrintHandler & print) |
| IanBenzMaxim | 0:33d4e66780c0 | 181 | { |
| IanBenzMaxim | 0:33d4e66780c0 | 182 | if (print) |
| IanBenzMaxim | 0:33d4e66780c0 | 183 | { |
| IanBenzMaxim | 0:33d4e66780c0 | 184 | print((std::string(enabled ? "Enabling" : "Disabling") + " laser").c_str()); |
| IanBenzMaxim | 0:33d4e66780c0 | 185 | } |
| IanBenzMaxim | 0:33d4e66780c0 | 186 | |
| IanBenzMaxim | 0:33d4e66780c0 | 187 | // Compute slave secret on coprocessor. |
| IanBenzMaxim | 0:33d4e66780c0 | 188 | DS2476::Buffer message; |
| IanBenzMaxim | 0:33d4e66780c0 | 189 | if (!setSlaveSecret(ds2476, ds28c36, message, print)) |
| IanBenzMaxim | 0:33d4e66780c0 | 190 | return false; |
| IanBenzMaxim | 0:33d4e66780c0 | 191 | |
| IanBenzMaxim | 0:33d4e66780c0 | 192 | // Compute write HMAC. |
| IanBenzMaxim | 0:33d4e66780c0 | 193 | // ROM ID and MAN ID are already in message. |
| IanBenzMaxim | 0:33d4e66780c0 | 194 | if (print) |
| IanBenzMaxim | 0:33d4e66780c0 | 195 | { |
| IanBenzMaxim | 0:33d4e66780c0 | 196 | print("Reading GPIO Control page"); |
| IanBenzMaxim | 0:33d4e66780c0 | 197 | print((std::string("Modify copy of GPIO Control page to set GPIO B state to ") + |
| IanBenzMaxim | 0:33d4e66780c0 | 198 | (enabled ? "conducting" : "high-impedance")).c_str()); |
| IanBenzMaxim | 0:33d4e66780c0 | 199 | } |
| IanBenzMaxim | 0:33d4e66780c0 | 200 | DS28C36::Page page; |
| IanBenzMaxim | 0:33d4e66780c0 | 201 | DS28C36::CmdResult result = ds28c36.readMemory(DS28C36::GpioControl, page); |
| IanBenzMaxim | 0:33d4e66780c0 | 202 | if (result != DS28C36::Success) |
| IanBenzMaxim | 0:33d4e66780c0 | 203 | return false; |
| IanBenzMaxim | 0:33d4e66780c0 | 204 | std::copy(page.begin(), page.end(), message.begin() + 8); |
| IanBenzMaxim | 0:33d4e66780c0 | 205 | page[1] = (enabled ? 0xAA : 0x55); |
| IanBenzMaxim | 0:33d4e66780c0 | 206 | std::copy(page.begin(), page.end(), message.begin() + 40); |
| IanBenzMaxim | 0:33d4e66780c0 | 207 | message[72] = DS28C36::GpioControl; |
| IanBenzMaxim | 0:33d4e66780c0 | 208 | if (print) |
| IanBenzMaxim | 0:33d4e66780c0 | 209 | { |
| IanBenzMaxim | 0:33d4e66780c0 | 210 | print(("Creating HMAC message (ROM ID | Old Page Data | New Page Data | Page # | MAN ID): " + |
| IanBenzMaxim | 0:33d4e66780c0 | 211 | byteArrayToHexString(&message[0], message.size())).c_str()); |
| IanBenzMaxim | 0:33d4e66780c0 | 212 | print("Writing HMAC message to DS2476 buffer"); |
| IanBenzMaxim | 0:33d4e66780c0 | 213 | } |
| IanBenzMaxim | 0:33d4e66780c0 | 214 | result = ds2476.writeBuffer(message); |
| IanBenzMaxim | 0:33d4e66780c0 | 215 | if (result != DS2476::Success) |
| IanBenzMaxim | 0:33d4e66780c0 | 216 | return false; |
| IanBenzMaxim | 0:33d4e66780c0 | 217 | DS2476::HMAC hmac; |
| IanBenzMaxim | 0:33d4e66780c0 | 218 | result = ds2476.computeSha2Hmac(hmac); |
| IanBenzMaxim | 0:33d4e66780c0 | 219 | if (result != DS2476::Success) |
| IanBenzMaxim | 0:33d4e66780c0 | 220 | return false; |
| IanBenzMaxim | 0:33d4e66780c0 | 221 | |
| IanBenzMaxim | 0:33d4e66780c0 | 222 | if (print) |
| IanBenzMaxim | 0:33d4e66780c0 | 223 | { |
| IanBenzMaxim | 0:33d4e66780c0 | 224 | print(("DS2476 computes write authentication HMAC from slave secret (Secret S) and message in buffer: " + |
| IanBenzMaxim | 0:33d4e66780c0 | 225 | byteArrayToHexString(hmac.data(), hmac.size())).c_str()); |
| IanBenzMaxim | 0:33d4e66780c0 | 226 | print("Write authentication HMAC is written to DS28C36 buffer"); |
| IanBenzMaxim | 0:33d4e66780c0 | 227 | print("DS28C36 computes an HMAC to compare to the write authentication HMAC after receiving Page # and New Page Data"); |
| IanBenzMaxim | 0:33d4e66780c0 | 228 | } |
| IanBenzMaxim | 0:33d4e66780c0 | 229 | |
| IanBenzMaxim | 0:33d4e66780c0 | 230 | // Write page data. |
| IanBenzMaxim | 0:33d4e66780c0 | 231 | result = ds28c36.writeBuffer(DS28C36::Buffer(hmac.begin(), hmac.end())); |
| IanBenzMaxim | 0:33d4e66780c0 | 232 | if (result != DS28C36::Success) |
| IanBenzMaxim | 0:33d4e66780c0 | 233 | return false; |
| IanBenzMaxim | 0:33d4e66780c0 | 234 | result = ds28c36.authenticatedSha2WriteMemory(DS28C36::GpioControl, DS28C36::SecretNumA, page); |
| IanBenzMaxim | 0:33d4e66780c0 | 235 | if (result != DS28C36::Success) |
| IanBenzMaxim | 0:33d4e66780c0 | 236 | return false; |
| IanBenzMaxim | 0:33d4e66780c0 | 237 | if (print) |
| IanBenzMaxim | 0:33d4e66780c0 | 238 | { |
| IanBenzMaxim | 0:33d4e66780c0 | 239 | print("DS28C36 updates page data which changes GPIO B state"); |
| IanBenzMaxim | 0:33d4e66780c0 | 240 | print((std::string("Laser is now ") + (enabled ? "enabled" : "disabled")).c_str()); |
| IanBenzMaxim | 0:33d4e66780c0 | 241 | } |
| IanBenzMaxim | 0:33d4e66780c0 | 242 | return true; |
| IanBenzMaxim | 0:33d4e66780c0 | 243 | } |
| IanBenzMaxim | 0:33d4e66780c0 | 244 | |
| IanBenzMaxim | 0:33d4e66780c0 | 245 | bool SensorNode::getLaserEnabled(bool & enabled) |
| IanBenzMaxim | 0:33d4e66780c0 | 246 | { |
| IanBenzMaxim | 0:33d4e66780c0 | 247 | DS28C36::Page page; |
| IanBenzMaxim | 0:33d4e66780c0 | 248 | DS28C36::CmdResult result = ds28c36.readMemory(DS28C36::GpioControl, page); |
| IanBenzMaxim | 0:33d4e66780c0 | 249 | if (result != DS28C36::Success) |
| IanBenzMaxim | 0:33d4e66780c0 | 250 | return false; |
| IanBenzMaxim | 0:33d4e66780c0 | 251 | enabled = (page[1] == 0xAA); |
| IanBenzMaxim | 0:33d4e66780c0 | 252 | return true; |
| IanBenzMaxim | 0:33d4e66780c0 | 253 | } |