Dependencies: AccelSensor BLE_API mbed nRF51822
ImobStateService.h@0:027b7829b46a, 2018-01-19 (annotated)
- Committer:
- fjaviercifuentes
- Date:
- Fri Jan 19 02:38:38 2018 +0000
- Revision:
- 0:027b7829b46a
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
fjaviercifuentes | 0:027b7829b46a | 1 | #ifndef __BLE_IMOB_STATE_SERVICE_H__ |
fjaviercifuentes | 0:027b7829b46a | 2 | #define __BLE_IMOB_STATE_SERVICE_H__ |
fjaviercifuentes | 0:027b7829b46a | 3 | |
fjaviercifuentes | 0:027b7829b46a | 4 | #include "mbed.h" |
fjaviercifuentes | 0:027b7829b46a | 5 | #include "ble/BLE.h" |
fjaviercifuentes | 0:027b7829b46a | 6 | #include "ble/Gap.h" |
fjaviercifuentes | 0:027b7829b46a | 7 | #include "crypt.h" |
fjaviercifuentes | 0:027b7829b46a | 8 | |
fjaviercifuentes | 0:027b7829b46a | 9 | #include "softdevice_handler.h" |
fjaviercifuentes | 0:027b7829b46a | 10 | |
fjaviercifuentes | 0:027b7829b46a | 11 | #define PASSLEN 16 |
fjaviercifuentes | 0:027b7829b46a | 12 | #define KEYLEN 16 |
fjaviercifuentes | 0:027b7829b46a | 13 | #define MACLEN 6 |
fjaviercifuentes | 0:027b7829b46a | 14 | |
fjaviercifuentes | 0:027b7829b46a | 15 | static bool authenticated = false; |
fjaviercifuentes | 0:027b7829b46a | 16 | static bool activated = false; |
fjaviercifuentes | 0:027b7829b46a | 17 | static bool userIsConnected = false; |
fjaviercifuentes | 0:027b7829b46a | 18 | static bool initial_activation = false; |
fjaviercifuentes | 0:027b7829b46a | 19 | |
fjaviercifuentes | 0:027b7829b46a | 20 | uint8_t defaultPass[PASSLEN] = {0}; |
fjaviercifuentes | 0:027b7829b46a | 21 | uint8_t defaultMac[MACLEN] = {0}; |
fjaviercifuentes | 0:027b7829b46a | 22 | |
fjaviercifuentes | 0:027b7829b46a | 23 | bool equal_arrays(uint8_t a1 [], const uint8_t a2 [], uint8_t n) |
fjaviercifuentes | 0:027b7829b46a | 24 | { |
fjaviercifuentes | 0:027b7829b46a | 25 | for (uint8_t i = 0; i < n; ++i) |
fjaviercifuentes | 0:027b7829b46a | 26 | if (a1[i] != a2[i]) |
fjaviercifuentes | 0:027b7829b46a | 27 | return false; |
fjaviercifuentes | 0:027b7829b46a | 28 | return (true); |
fjaviercifuentes | 0:027b7829b46a | 29 | } |
fjaviercifuentes | 0:027b7829b46a | 30 | |
fjaviercifuentes | 0:027b7829b46a | 31 | class ImobStateService { |
fjaviercifuentes | 0:027b7829b46a | 32 | public: |
fjaviercifuentes | 0:027b7829b46a | 33 | const static uint16_t IMOB_STATE_SERVICE_UUID = 0xA000; |
fjaviercifuentes | 0:027b7829b46a | 34 | const static uint16_t IMOB_STATE_PASS_CHARACTERISTIC_UUID = 0xA001; |
fjaviercifuentes | 0:027b7829b46a | 35 | const static uint16_t IMOB_STATE_NONCE_CHARACTERISTIC_UUID = 0xA002; |
fjaviercifuentes | 0:027b7829b46a | 36 | const static uint16_t IMOB_STATE_NONCE_UPDATED_CHARACTERISTIC_UUID = 0xA003; |
fjaviercifuentes | 0:027b7829b46a | 37 | const static uint16_t IMOB_STATE_AUTHENTICATION_CHARACTERISTIC_UUID = 0xA004; |
fjaviercifuentes | 0:027b7829b46a | 38 | const static uint16_t IMOB_STATE_ACTIVATION_CHARACTERISTIC_UUID = 0xA005; |
fjaviercifuentes | 0:027b7829b46a | 39 | |
fjaviercifuentes | 0:027b7829b46a | 40 | ImobStateService(BLEDevice &_ble) : |
fjaviercifuentes | 0:027b7829b46a | 41 | ble(_ble), |
fjaviercifuentes | 0:027b7829b46a | 42 | passUpdated(false), |
fjaviercifuentes | 0:027b7829b46a | 43 | nonceUpdated(false), |
fjaviercifuentes | 0:027b7829b46a | 44 | activation(0), |
fjaviercifuentes | 0:027b7829b46a | 45 | authentication(0), |
fjaviercifuentes | 0:027b7829b46a | 46 | passCharacteristic(IMOB_STATE_PASS_CHARACTERISTIC_UUID, defaultPass), |
fjaviercifuentes | 0:027b7829b46a | 47 | nonceCharacteristic(IMOB_STATE_NONCE_CHARACTERISTIC_UUID, defaultPass), |
fjaviercifuentes | 0:027b7829b46a | 48 | nonceUpdatedCharacteristic(IMOB_STATE_NONCE_UPDATED_CHARACTERISTIC_UUID, (uint8_t*)&nonceUpdated), |
fjaviercifuentes | 0:027b7829b46a | 49 | activationCharacteristic(IMOB_STATE_ACTIVATION_CHARACTERISTIC_UUID, &activation), |
fjaviercifuentes | 0:027b7829b46a | 50 | authenticationCharacteristic(IMOB_STATE_AUTHENTICATION_CHARACTERISTIC_UUID, &authentication) |
fjaviercifuentes | 0:027b7829b46a | 51 | |
fjaviercifuentes | 0:027b7829b46a | 52 | { |
fjaviercifuentes | 0:027b7829b46a | 53 | GattCharacteristic *charTable[] = {&passCharacteristic, &nonceCharacteristic, &nonceUpdatedCharacteristic, &activationCharacteristic, &authenticationCharacteristic}; |
fjaviercifuentes | 0:027b7829b46a | 54 | GattService imobStateService(IMOB_STATE_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); |
fjaviercifuentes | 0:027b7829b46a | 55 | |
fjaviercifuentes | 0:027b7829b46a | 56 | ble.addService(imobStateService); |
fjaviercifuentes | 0:027b7829b46a | 57 | |
fjaviercifuentes | 0:027b7829b46a | 58 | ble.gap().onDisconnection(this, &ImobStateService::onDisconnectionFilter); |
fjaviercifuentes | 0:027b7829b46a | 59 | ble.gap().onConnection(this, &ImobStateService::onConnectionFilter); |
fjaviercifuentes | 0:027b7829b46a | 60 | ble.gattServer().onDataWritten(this, &ImobStateService::onDataWritten); |
fjaviercifuentes | 0:027b7829b46a | 61 | |
fjaviercifuentes | 0:027b7829b46a | 62 | resetAuthenticationValues(); |
fjaviercifuentes | 0:027b7829b46a | 63 | |
fjaviercifuentes | 0:027b7829b46a | 64 | for(uint8_t i = 0; i < PASSLEN;i++) |
fjaviercifuentes | 0:027b7829b46a | 65 | correctPass[i] = defaultPass[i]; |
fjaviercifuentes | 0:027b7829b46a | 66 | |
fjaviercifuentes | 0:027b7829b46a | 67 | for(uint8_t i = 0; i < KEYLEN;i++) |
fjaviercifuentes | 0:027b7829b46a | 68 | p_ecb_key[i] = defaultPass[i]; |
fjaviercifuentes | 0:027b7829b46a | 69 | |
fjaviercifuentes | 0:027b7829b46a | 70 | for(uint8_t i = 0; i < MACLEN;i++) |
fjaviercifuentes | 0:027b7829b46a | 71 | recentMac[i] = defaultMac[i]; |
fjaviercifuentes | 0:027b7829b46a | 72 | |
fjaviercifuentes | 0:027b7829b46a | 73 | } |
fjaviercifuentes | 0:027b7829b46a | 74 | |
fjaviercifuentes | 0:027b7829b46a | 75 | void resetAuthenticationValues() |
fjaviercifuentes | 0:027b7829b46a | 76 | { |
fjaviercifuentes | 0:027b7829b46a | 77 | updateAuthenticationValue(false); |
fjaviercifuentes | 0:027b7829b46a | 78 | |
fjaviercifuentes | 0:027b7829b46a | 79 | passUpdated = false; |
fjaviercifuentes | 0:027b7829b46a | 80 | |
fjaviercifuentes | 0:027b7829b46a | 81 | for(uint8_t i = 0; i < PASSLEN; i++) |
fjaviercifuentes | 0:027b7829b46a | 82 | pass[i] = defaultPass[i]; |
fjaviercifuentes | 0:027b7829b46a | 83 | |
fjaviercifuentes | 0:027b7829b46a | 84 | ble.updateCharacteristicValue(passCharacteristic.getValueHandle(), pass, PASSLEN); |
fjaviercifuentes | 0:027b7829b46a | 85 | } |
fjaviercifuentes | 0:027b7829b46a | 86 | |
fjaviercifuentes | 0:027b7829b46a | 87 | void updateAuthenticationPassValues(const uint8_t newpass[PASSLEN]) |
fjaviercifuentes | 0:027b7829b46a | 88 | { |
fjaviercifuentes | 0:027b7829b46a | 89 | passUpdated = true; |
fjaviercifuentes | 0:027b7829b46a | 90 | |
fjaviercifuentes | 0:027b7829b46a | 91 | for(uint8_t i = 0; i < PASSLEN;i++) |
fjaviercifuentes | 0:027b7829b46a | 92 | pass[i] = newpass[i]; |
fjaviercifuentes | 0:027b7829b46a | 93 | |
fjaviercifuentes | 0:027b7829b46a | 94 | ctr_decrypt(pass); |
fjaviercifuentes | 0:027b7829b46a | 95 | } |
fjaviercifuentes | 0:027b7829b46a | 96 | |
fjaviercifuentes | 0:027b7829b46a | 97 | void updateAuthenticationNonceValues(const uint8_t newnonce[PASSLEN]) |
fjaviercifuentes | 0:027b7829b46a | 98 | { |
fjaviercifuentes | 0:027b7829b46a | 99 | updateNonceUpdatedValue(true); |
fjaviercifuentes | 0:027b7829b46a | 100 | |
fjaviercifuentes | 0:027b7829b46a | 101 | for(uint8_t i = 0; i < PASSLEN;i++) |
fjaviercifuentes | 0:027b7829b46a | 102 | nonce[i] = newnonce[i]; |
fjaviercifuentes | 0:027b7829b46a | 103 | |
fjaviercifuentes | 0:027b7829b46a | 104 | ble.updateCharacteristicValue(nonceCharacteristic.getValueHandle(),nonce,PASSLEN); |
fjaviercifuentes | 0:027b7829b46a | 105 | ctr_init(nonce, p_ecb_key); |
fjaviercifuentes | 0:027b7829b46a | 106 | } |
fjaviercifuentes | 0:027b7829b46a | 107 | |
fjaviercifuentes | 0:027b7829b46a | 108 | void updateNonceUpdatedValue(bool value) |
fjaviercifuentes | 0:027b7829b46a | 109 | { |
fjaviercifuentes | 0:027b7829b46a | 110 | nonceUpdated = value; |
fjaviercifuentes | 0:027b7829b46a | 111 | uint8_t aux_nonceUpdated = (nonceUpdated) ? 1: 0; |
fjaviercifuentes | 0:027b7829b46a | 112 | ble.gattServer().write(nonceUpdatedCharacteristic.getValueHandle(), &aux_nonceUpdated, 1); |
fjaviercifuentes | 0:027b7829b46a | 113 | |
fjaviercifuentes | 0:027b7829b46a | 114 | } |
fjaviercifuentes | 0:027b7829b46a | 115 | |
fjaviercifuentes | 0:027b7829b46a | 116 | void updateAuthenticationValue(bool value) |
fjaviercifuentes | 0:027b7829b46a | 117 | { |
fjaviercifuentes | 0:027b7829b46a | 118 | authenticated = value; |
fjaviercifuentes | 0:027b7829b46a | 119 | authentication = (authenticated) ? 1: 0; |
fjaviercifuentes | 0:027b7829b46a | 120 | ble.gattServer().write(authenticationCharacteristic.getValueHandle(), &authentication, 1); |
fjaviercifuentes | 0:027b7829b46a | 121 | } |
fjaviercifuentes | 0:027b7829b46a | 122 | |
fjaviercifuentes | 0:027b7829b46a | 123 | void updateActivationValue(const uint8_t value) |
fjaviercifuentes | 0:027b7829b46a | 124 | { |
fjaviercifuentes | 0:027b7829b46a | 125 | activated = (value == 1) ? true: false; |
fjaviercifuentes | 0:027b7829b46a | 126 | activation = (activated) ? 1: 0; |
fjaviercifuentes | 0:027b7829b46a | 127 | ble.gattServer().write(activationCharacteristic.getValueHandle(), &activation, 1); |
fjaviercifuentes | 0:027b7829b46a | 128 | } |
fjaviercifuentes | 0:027b7829b46a | 129 | |
fjaviercifuentes | 0:027b7829b46a | 130 | void setCorrectPass(const uint8_t * newCorrectPass) |
fjaviercifuentes | 0:027b7829b46a | 131 | { |
fjaviercifuentes | 0:027b7829b46a | 132 | for(uint8_t i = 0; i < PASSLEN;i++) |
fjaviercifuentes | 0:027b7829b46a | 133 | correctPass[i] = newCorrectPass[i]; |
fjaviercifuentes | 0:027b7829b46a | 134 | } |
fjaviercifuentes | 0:027b7829b46a | 135 | |
fjaviercifuentes | 0:027b7829b46a | 136 | void setCryptKey(const uint8_t * newCryptKey) |
fjaviercifuentes | 0:027b7829b46a | 137 | { |
fjaviercifuentes | 0:027b7829b46a | 138 | for(uint8_t i = 0; i < PASSLEN;i++) |
fjaviercifuentes | 0:027b7829b46a | 139 | p_ecb_key[i] = newCryptKey[i]; |
fjaviercifuentes | 0:027b7829b46a | 140 | } |
fjaviercifuentes | 0:027b7829b46a | 141 | |
fjaviercifuentes | 0:027b7829b46a | 142 | protected: |
fjaviercifuentes | 0:027b7829b46a | 143 | virtual void onDataWritten(const GattWriteCallbackParams *params) |
fjaviercifuentes | 0:027b7829b46a | 144 | { |
fjaviercifuentes | 0:027b7829b46a | 145 | if ((params->handle == passCharacteristic.getValueHandle()) && (params->len == PASSLEN) && (nonceUpdated)) |
fjaviercifuentes | 0:027b7829b46a | 146 | { |
fjaviercifuentes | 0:027b7829b46a | 147 | updateAuthenticationPassValues((params->data)); |
fjaviercifuentes | 0:027b7829b46a | 148 | } |
fjaviercifuentes | 0:027b7829b46a | 149 | else if ((params->handle == nonceCharacteristic.getValueHandle()) && (params->len == PASSLEN)) |
fjaviercifuentes | 0:027b7829b46a | 150 | { |
fjaviercifuentes | 0:027b7829b46a | 151 | updateAuthenticationNonceValues((params->data)); |
fjaviercifuentes | 0:027b7829b46a | 152 | } |
fjaviercifuentes | 0:027b7829b46a | 153 | else if ((params->handle == activationCharacteristic.getValueHandle()) && (params->len == 1) && authenticated) |
fjaviercifuentes | 0:027b7829b46a | 154 | { |
fjaviercifuentes | 0:027b7829b46a | 155 | updateActivationValue(*(params->data)); |
fjaviercifuentes | 0:027b7829b46a | 156 | } |
fjaviercifuentes | 0:027b7829b46a | 157 | |
fjaviercifuentes | 0:027b7829b46a | 158 | if(passUpdated) |
fjaviercifuentes | 0:027b7829b46a | 159 | { |
fjaviercifuentes | 0:027b7829b46a | 160 | if(equal_arrays(pass, correctPass, PASSLEN)) |
fjaviercifuentes | 0:027b7829b46a | 161 | { |
fjaviercifuentes | 0:027b7829b46a | 162 | updateAuthenticationValue(true); |
fjaviercifuentes | 0:027b7829b46a | 163 | initial_activation = true; |
fjaviercifuentes | 0:027b7829b46a | 164 | } |
fjaviercifuentes | 0:027b7829b46a | 165 | else |
fjaviercifuentes | 0:027b7829b46a | 166 | { |
fjaviercifuentes | 0:027b7829b46a | 167 | resetAuthenticationValues(); |
fjaviercifuentes | 0:027b7829b46a | 168 | } |
fjaviercifuentes | 0:027b7829b46a | 169 | } |
fjaviercifuentes | 0:027b7829b46a | 170 | } |
fjaviercifuentes | 0:027b7829b46a | 171 | |
fjaviercifuentes | 0:027b7829b46a | 172 | void onDisconnectionFilter(const Gap::DisconnectionCallbackParams_t *params) |
fjaviercifuentes | 0:027b7829b46a | 173 | { |
fjaviercifuentes | 0:027b7829b46a | 174 | resetAuthenticationValues(); |
fjaviercifuentes | 0:027b7829b46a | 175 | userIsConnected = false; |
fjaviercifuentes | 0:027b7829b46a | 176 | } |
fjaviercifuentes | 0:027b7829b46a | 177 | |
fjaviercifuentes | 0:027b7829b46a | 178 | void onConnectionFilter(const Gap::ConnectionCallbackParams_t* params) |
fjaviercifuentes | 0:027b7829b46a | 179 | { |
fjaviercifuentes | 0:027b7829b46a | 180 | uint8_t newMac[MACLEN]; |
fjaviercifuentes | 0:027b7829b46a | 181 | for(uint8_t i = 0; i < 6; i++) |
fjaviercifuentes | 0:027b7829b46a | 182 | newMac[i] = params->peerAddr[i]; |
fjaviercifuentes | 0:027b7829b46a | 183 | |
fjaviercifuentes | 0:027b7829b46a | 184 | if(!equal_arrays(recentMac, newMac, MACLEN)) |
fjaviercifuentes | 0:027b7829b46a | 185 | { |
fjaviercifuentes | 0:027b7829b46a | 186 | for(uint8_t i = 0; i < 6; i++) |
fjaviercifuentes | 0:027b7829b46a | 187 | recentMac[i] = newMac[i]; |
fjaviercifuentes | 0:027b7829b46a | 188 | |
fjaviercifuentes | 0:027b7829b46a | 189 | updateNonceUpdatedValue(false); |
fjaviercifuentes | 0:027b7829b46a | 190 | |
fjaviercifuentes | 0:027b7829b46a | 191 | for(uint8_t i = 0; i < PASSLEN; i++) |
fjaviercifuentes | 0:027b7829b46a | 192 | nonce[i] = defaultPass[i]; |
fjaviercifuentes | 0:027b7829b46a | 193 | |
fjaviercifuentes | 0:027b7829b46a | 194 | ble.updateCharacteristicValue(nonceCharacteristic.getValueHandle(), nonce, PASSLEN); |
fjaviercifuentes | 0:027b7829b46a | 195 | } |
fjaviercifuentes | 0:027b7829b46a | 196 | |
fjaviercifuentes | 0:027b7829b46a | 197 | userIsConnected = true; |
fjaviercifuentes | 0:027b7829b46a | 198 | } |
fjaviercifuentes | 0:027b7829b46a | 199 | |
fjaviercifuentes | 0:027b7829b46a | 200 | private: |
fjaviercifuentes | 0:027b7829b46a | 201 | BLEDevice &ble; |
fjaviercifuentes | 0:027b7829b46a | 202 | bool passUpdated; |
fjaviercifuentes | 0:027b7829b46a | 203 | bool nonceUpdated; |
fjaviercifuentes | 0:027b7829b46a | 204 | |
fjaviercifuentes | 0:027b7829b46a | 205 | uint8_t pass[PASSLEN]; |
fjaviercifuentes | 0:027b7829b46a | 206 | uint8_t nonce[PASSLEN]; |
fjaviercifuentes | 0:027b7829b46a | 207 | uint8_t correctPass[PASSLEN]; |
fjaviercifuentes | 0:027b7829b46a | 208 | uint8_t p_ecb_key[KEYLEN]; |
fjaviercifuentes | 0:027b7829b46a | 209 | |
fjaviercifuentes | 0:027b7829b46a | 210 | uint8_t recentMac[MACLEN]; |
fjaviercifuentes | 0:027b7829b46a | 211 | |
fjaviercifuentes | 0:027b7829b46a | 212 | uint8_t activation; |
fjaviercifuentes | 0:027b7829b46a | 213 | uint8_t authentication; |
fjaviercifuentes | 0:027b7829b46a | 214 | |
fjaviercifuentes | 0:027b7829b46a | 215 | WriteOnlyArrayGattCharacteristic <uint8_t, sizeof(pass)> passCharacteristic; |
fjaviercifuentes | 0:027b7829b46a | 216 | WriteOnlyArrayGattCharacteristic <uint8_t, sizeof(pass)> nonceCharacteristic; |
fjaviercifuentes | 0:027b7829b46a | 217 | |
fjaviercifuentes | 0:027b7829b46a | 218 | ReadOnlyGattCharacteristic < uint8_t > nonceUpdatedCharacteristic; |
fjaviercifuentes | 0:027b7829b46a | 219 | ReadWriteGattCharacteristic < uint8_t > activationCharacteristic; |
fjaviercifuentes | 0:027b7829b46a | 220 | ReadOnlyGattCharacteristic < uint8_t > authenticationCharacteristic; |
fjaviercifuentes | 0:027b7829b46a | 221 | |
fjaviercifuentes | 0:027b7829b46a | 222 | |
fjaviercifuentes | 0:027b7829b46a | 223 | }; |
fjaviercifuentes | 0:027b7829b46a | 224 | |
fjaviercifuentes | 0:027b7829b46a | 225 | #endif /* #ifndef __BLE_IMOB_STATE_SERVICE_H__ */ |