Client for the DeviceHubNet gateway. (You need the gateway SW as well!)

Dependents:   DeviceHubNet_DEMO

Committer:
gume
Date:
Tue Apr 04 02:21:56 2017 +0000
Revision:
1:5dca66437dd1
Parent:
0:093f1cb20c52
Add documentation to the class

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gume 0:093f1cb20c52 1 #include <DeviceHubNet.h>
gume 0:093f1cb20c52 2
gume 0:093f1cb20c52 3 int DeviceHubNet::readHex(char *hexStr, uint8_t* hex)
gume 0:093f1cb20c52 4 {
gume 0:093f1cb20c52 5
gume 0:093f1cb20c52 6 int j = 0;
gume 0:093f1cb20c52 7 for (int i = 0; i < strlen(hexStr); i++) {
gume 0:093f1cb20c52 8 char c = hexStr[i];
gume 0:093f1cb20c52 9 uint8_t n;
gume 0:093f1cb20c52 10 if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
gume 0:093f1cb20c52 11 if (c <= '9') n = c - '0';
gume 0:093f1cb20c52 12 else if (c <= 'f') n = 10 + c - 'a';
gume 0:093f1cb20c52 13 else if (c <= 'F') n = 10 + c - 'A';
gume 0:093f1cb20c52 14 if (j % 2 == 0)
gume 0:093f1cb20c52 15 hex[j/2] = n << 4;
gume 0:093f1cb20c52 16 else
gume 0:093f1cb20c52 17 hex[j/2] = hex[j/2] + n;
gume 0:093f1cb20c52 18 j++;
gume 0:093f1cb20c52 19 }
gume 0:093f1cb20c52 20 }
gume 0:093f1cb20c52 21
gume 0:093f1cb20c52 22 return (j+1)/2;
gume 0:093f1cb20c52 23 }
gume 0:093f1cb20c52 24
gume 0:093f1cb20c52 25 uint64_t DeviceHubNet::getFullAddress()
gume 0:093f1cb20c52 26 {
gume 0:093f1cb20c52 27 uint64_t full = 0;
gume 0:093f1cb20c52 28 uint32_t netprefix = NETWORK_PREFIX;
gume 0:093f1cb20c52 29 memcpy(((char*) &full)+2, (void*) &netprefix, 4);
gume 0:093f1cb20c52 30 memcpy(((char*) &full)+0, (void*) &nodeAddress, 2);
gume 0:093f1cb20c52 31 return full;
gume 0:093f1cb20c52 32 }
gume 0:093f1cb20c52 33
gume 0:093f1cb20c52 34 uint64_t DeviceHubNet::getGWAddress()
gume 0:093f1cb20c52 35 {
gume 0:093f1cb20c52 36 uint64_t full = 0;
gume 0:093f1cb20c52 37 uint32_t netprefix = NETWORK_PREFIX;
gume 0:093f1cb20c52 38 memcpy(((char*) &full)+2, (void*) &netprefix, 4);
gume 0:093f1cb20c52 39 return full;
gume 0:093f1cb20c52 40 }
gume 0:093f1cb20c52 41
gume 0:093f1cb20c52 42 void DeviceHubNet::registerProject()
gume 0:093f1cb20c52 43 {
gume 0:093f1cb20c52 44 struct MsgRegister msgRegister;
gume 0:093f1cb20c52 45 msgRegister.rType = 1; // Project
gume 0:093f1cb20c52 46 memcpy((uint8_t*) msgRegister.id, &projectId, 4);
gume 0:093f1cb20c52 47 memcpy((uint8_t*) msgRegister.id + 4, &apiKey, 16);
gume 0:093f1cb20c52 48
gume 0:093f1cb20c52 49 sendData(PACKET_REGISTER, (uint8_t*) &msgRegister, 21);
gume 0:093f1cb20c52 50 }
gume 0:093f1cb20c52 51
gume 0:093f1cb20c52 52
gume 0:093f1cb20c52 53 void DeviceHubNet::registerDevice()
gume 0:093f1cb20c52 54 {
gume 0:093f1cb20c52 55 struct MsgRegister msgRegister;
gume 0:093f1cb20c52 56 msgRegister.rType = 2; // Device
gume 0:093f1cb20c52 57 memcpy((uint8_t*) msgRegister.id, &deviceId, 16);
gume 0:093f1cb20c52 58
gume 0:093f1cb20c52 59 sendData(PACKET_REGISTER, (uint8_t*) &msgRegister, 17);
gume 0:093f1cb20c52 60 }
gume 0:093f1cb20c52 61
gume 0:093f1cb20c52 62
gume 0:093f1cb20c52 63 bool DeviceHubNet::sendData(uint8_t type, uint8_t *data, uint8_t len)
gume 0:093f1cb20c52 64 {
gume 0:093f1cb20c52 65 uint8_t msg[32];
gume 0:093f1cb20c52 66 msg[0] = nodeAddress & 0xff;
gume 0:093f1cb20c52 67 msg[1] = nodeAddress >> 8;
gume 0:093f1cb20c52 68 msg[2] = type;
gume 0:093f1cb20c52 69 msg[3] = msgCounter++;
gume 0:093f1cb20c52 70 memcpy(msg + 4, data, len);
gume 0:093f1cb20c52 71
gume 0:093f1cb20c52 72 int w = 0;
gume 0:093f1cb20c52 73 if (w < 5 && radio->testCarrier()) {
gume 0:093f1cb20c52 74 w++;
gume 0:093f1cb20c52 75 wait_ms(2);
gume 0:093f1cb20c52 76 }
gume 0:093f1cb20c52 77
gume 0:093f1cb20c52 78 // Stop listening, send
gume 0:093f1cb20c52 79 radio->stopListening();
gume 0:093f1cb20c52 80 radio->setRetries(0, 3);
gume 0:093f1cb20c52 81 radio->openWritingPipe(getGWAddress());
gume 0:093f1cb20c52 82 bool ok = radio->write(msg, len +4);
gume 0:093f1cb20c52 83
gume 0:093f1cb20c52 84 radio->startListening();
gume 0:093f1cb20c52 85 return ok;
gume 0:093f1cb20c52 86 }
gume 0:093f1cb20c52 87
gume 0:093f1cb20c52 88
gume 0:093f1cb20c52 89 // public functions
gume 0:093f1cb20c52 90
gume 0:093f1cb20c52 91 DeviceHubNet::DeviceHubNet(uint32_t projectId, uint8_t *apiKey, uint8_t *deviceId)
gume 0:093f1cb20c52 92 {
gume 0:093f1cb20c52 93 this->projectId = projectId;
gume 0:093f1cb20c52 94 memcpy(this->apiKey, apiKey, 16);
gume 0:093f1cb20c52 95 memcpy(this->deviceId, deviceId, 16);
gume 0:093f1cb20c52 96
gume 0:093f1cb20c52 97 nextSId = 1;
gume 0:093f1cb20c52 98 }
gume 0:093f1cb20c52 99
gume 0:093f1cb20c52 100 DeviceHubNet::DeviceHubNet(uint32_t projectId, char *apiKeyStr, char *deviceIdStr)
gume 0:093f1cb20c52 101 {
gume 0:093f1cb20c52 102 this->projectId = projectId;
gume 0:093f1cb20c52 103 memset(apiKey, 0, 16);
gume 0:093f1cb20c52 104 readHex(apiKeyStr, apiKey);
gume 0:093f1cb20c52 105 readHex(deviceIdStr, deviceId);
gume 0:093f1cb20c52 106
gume 0:093f1cb20c52 107 nextSId = 1;
gume 0:093f1cb20c52 108 }
gume 0:093f1cb20c52 109
gume 0:093f1cb20c52 110 bool DeviceHubNet::radioPinConfig(PinName mosi, PinName miso, PinName sck, PinName cs, PinName ce)
gume 0:093f1cb20c52 111 {
gume 0:093f1cb20c52 112
gume 0:093f1cb20c52 113 radio = new RF24(mosi, miso, sck, cs, ce);
gume 0:093f1cb20c52 114 return true;
gume 0:093f1cb20c52 115 }
gume 0:093f1cb20c52 116
gume 0:093f1cb20c52 117 bool DeviceHubNet::radioConfig(uint16_t address, uint8_t channel)
gume 0:093f1cb20c52 118 {
gume 0:093f1cb20c52 119 nodeAddress = address;
gume 0:093f1cb20c52 120 if (!radio) return false;
gume 0:093f1cb20c52 121
gume 0:093f1cb20c52 122 radio->begin();
gume 0:093f1cb20c52 123 radio->enableDynamicAck();
gume 0:093f1cb20c52 124 radio->enableDynamicPayloads();
gume 0:093f1cb20c52 125 //radio->openReadingPipe(0, BROADCAST_ADDRESS_LL);
gume 0:093f1cb20c52 126 radio->openReadingPipe(1, getFullAddress());
gume 0:093f1cb20c52 127 //radio->setAutoAck(0, false); // Disable autoACK on broadcast
gume 0:093f1cb20c52 128 radio->setAutoAck(1, true); // Ensure autoACK is enabled on data/control
gume 0:093f1cb20c52 129
gume 0:093f1cb20c52 130 radio->setChannel(channel);
gume 0:093f1cb20c52 131 radio->setDataRate(RF24_2MBPS);
gume 0:093f1cb20c52 132 radio->setPALevel(RF24_PA_MAX);
gume 0:093f1cb20c52 133
gume 0:093f1cb20c52 134 registerProject();
gume 0:093f1cb20c52 135 registerDevice();
gume 0:093f1cb20c52 136
gume 0:093f1cb20c52 137 radio->startListening(); // Start listening
gume 0:093f1cb20c52 138 return true;
gume 0:093f1cb20c52 139 }
gume 0:093f1cb20c52 140
gume 0:093f1cb20c52 141 void DeviceHubNet::radioDump()
gume 0:093f1cb20c52 142 {
gume 0:093f1cb20c52 143 radio->printDetails();
gume 0:093f1cb20c52 144 }
gume 0:093f1cb20c52 145
gume 0:093f1cb20c52 146 void DeviceHubNet::processMsgs()
gume 0:093f1cb20c52 147 {
gume 0:093f1cb20c52 148 uint8_t packet[32];
gume 0:093f1cb20c52 149
gume 0:093f1cb20c52 150 while (radio->available()) {
gume 0:093f1cb20c52 151 uint8_t plen = radio->getDynamicPayloadSize();
gume 0:093f1cb20c52 152 radio->read(packet, plen);
gume 0:093f1cb20c52 153
gume 0:093f1cb20c52 154 if (plen < 4) continue;
gume 0:093f1cb20c52 155 //printf("New message received. Length: %d\n\r", plen);
gume 0:093f1cb20c52 156 //for (int i = 0; i < plen; i++) printf("%02X:", packet[i]);
gume 0:093f1cb20c52 157 //printf("\n\r");
gume 0:093f1cb20c52 158
gume 0:093f1cb20c52 159 if (packet[2] == 6) {
gume 0:093f1cb20c52 160 // Registration error. Try to re-register everything
gume 0:093f1cb20c52 161 registerProject();
gume 0:093f1cb20c52 162 registerDevice();
gume 0:093f1cb20c52 163
gume 0:093f1cb20c52 164 map<uint16_t, string>::iterator it;
gume 0:093f1cb20c52 165 for (it = sensors.begin(); it != sensors.end(); ++it) {
gume 0:093f1cb20c52 166 reRegisterSensor(it->first);
gume 0:093f1cb20c52 167 }
gume 0:093f1cb20c52 168 for (it = actuators.begin(); it != actuators.end(); ++it) {
gume 0:093f1cb20c52 169 reRegisterActuator(it->first);
gume 0:093f1cb20c52 170 }
gume 0:093f1cb20c52 171 }
gume 0:093f1cb20c52 172
gume 0:093f1cb20c52 173 else if (packet[2] == 3) {
gume 0:093f1cb20c52 174 // Data message
gume 0:093f1cb20c52 175 uint16_t sid = packet[4] + packet[5] * 256;
gume 0:093f1cb20c52 176 uint8_t type = packet[6];
gume 0:093f1cb20c52 177 void (*cb)(uint8_t, uint8_t, float) = (void (*)(uint8_t, uint8_t, float)) actuator_cbs[sid];
gume 0:093f1cb20c52 178 if (type == 0) {
gume 0:093f1cb20c52 179 // Digital data
gume 0:093f1cb20c52 180 cb(type, packet[7], 0.0);
gume 0:093f1cb20c52 181 } else {
gume 0:093f1cb20c52 182 // Analog data
gume 0:093f1cb20c52 183 float f;
gume 0:093f1cb20c52 184 memcpy(&f, packet + 7, 4);
gume 0:093f1cb20c52 185 cb(type, 0, f);
gume 0:093f1cb20c52 186 }
gume 0:093f1cb20c52 187 }
gume 0:093f1cb20c52 188
gume 0:093f1cb20c52 189 }
gume 0:093f1cb20c52 190 }
gume 0:093f1cb20c52 191
gume 0:093f1cb20c52 192
gume 0:093f1cb20c52 193 uint16_t DeviceHubNet::registerSensor(char *sensorName)
gume 0:093f1cb20c52 194 {
gume 0:093f1cb20c52 195 uint16_t sensorId = nextSId++;
gume 0:093f1cb20c52 196 sensors[sensorId] = string(sensorName);
gume 0:093f1cb20c52 197 reRegisterSensor(sensorId);
gume 0:093f1cb20c52 198
gume 0:093f1cb20c52 199 return sensorId;
gume 0:093f1cb20c52 200 }
gume 0:093f1cb20c52 201
gume 0:093f1cb20c52 202 uint16_t DeviceHubNet::registerActuator(char *actuatorName, uint8_t type, void (*onReceive)(uint8_t, uint8_t, float))
gume 0:093f1cb20c52 203 {
gume 0:093f1cb20c52 204 uint16_t actuatorId = nextSId++;
gume 0:093f1cb20c52 205 actuators[actuatorId] = string(actuatorName);
gume 0:093f1cb20c52 206 actuator_cbs[actuatorId] = (void*) onReceive;
gume 0:093f1cb20c52 207 actuator_types[actuatorId] = type;
gume 0:093f1cb20c52 208 reRegisterActuator(actuatorId);
gume 0:093f1cb20c52 209
gume 0:093f1cb20c52 210 return actuatorId;
gume 0:093f1cb20c52 211 }
gume 0:093f1cb20c52 212
gume 0:093f1cb20c52 213 void DeviceHubNet::reRegisterSensor(uint16_t sensorId)
gume 0:093f1cb20c52 214 {
gume 0:093f1cb20c52 215 char *sensorNameStr = (char*) sensors[sensorId].c_str();
gume 0:093f1cb20c52 216
gume 0:093f1cb20c52 217 struct MsgRegister msgRegister;
gume 0:093f1cb20c52 218 msgRegister.rType = 3; // Sensor
gume 0:093f1cb20c52 219 msgRegister.id[0] = sensorId & 0xff;
gume 0:093f1cb20c52 220 msgRegister.id[1] = sensorId >> 8;
gume 0:093f1cb20c52 221 strncpy((char*) msgRegister.id + 2, sensorNameStr, 24);
gume 0:093f1cb20c52 222 int l = strlen(sensorNameStr);
gume 0:093f1cb20c52 223 if (l > 24) l = 24;
gume 0:093f1cb20c52 224 sendData(PACKET_REGISTER, (uint8_t*) &msgRegister, l + 3);
gume 0:093f1cb20c52 225 }
gume 0:093f1cb20c52 226
gume 0:093f1cb20c52 227 void DeviceHubNet::reRegisterActuator(uint16_t actuatorId)
gume 0:093f1cb20c52 228 {
gume 0:093f1cb20c52 229 char *actuatorNameStr = (char*) actuators[actuatorId].c_str();
gume 0:093f1cb20c52 230
gume 0:093f1cb20c52 231 struct MsgRegister msgRegister;
gume 0:093f1cb20c52 232 msgRegister.rType = 4; // Actuator
gume 0:093f1cb20c52 233 msgRegister.id[0] = actuatorId & 0xff;
gume 0:093f1cb20c52 234 msgRegister.id[1] = actuatorId >> 8;
gume 0:093f1cb20c52 235 msgRegister.id[2] = actuator_types[actuatorId];
gume 0:093f1cb20c52 236 strncpy((char*) msgRegister.id + 3, actuatorNameStr, 24);
gume 0:093f1cb20c52 237 int l = strlen(actuatorNameStr);
gume 0:093f1cb20c52 238 if (l > 24) l = 24;
gume 0:093f1cb20c52 239 sendData(PACKET_REGISTER, (uint8_t*) &msgRegister, l + 4);
gume 0:093f1cb20c52 240 }
gume 0:093f1cb20c52 241
gume 0:093f1cb20c52 242 bool DeviceHubNet::sendDigitalData(uint16_t sensorId, uint8_t data)
gume 0:093f1cb20c52 243 {
gume 0:093f1cb20c52 244 struct MsgData msgData;
gume 0:093f1cb20c52 245 msgData.sensorId = sensorId;
gume 0:093f1cb20c52 246 msgData.dType = 0;
gume 0:093f1cb20c52 247 msgData.data.ddata = data;
gume 0:093f1cb20c52 248
gume 0:093f1cb20c52 249 return sendData(PACKET_DATA, (uint8_t*) &msgData, 4);
gume 0:093f1cb20c52 250 }
gume 0:093f1cb20c52 251
gume 0:093f1cb20c52 252 bool DeviceHubNet::sendAnalogData(uint16_t sensorId, float data)
gume 0:093f1cb20c52 253 {
gume 0:093f1cb20c52 254 struct MsgData msgData;
gume 0:093f1cb20c52 255 msgData.sensorId = sensorId;
gume 0:093f1cb20c52 256 msgData.dType = 1;
gume 0:093f1cb20c52 257 msgData.data.adata = data;
gume 0:093f1cb20c52 258
gume 0:093f1cb20c52 259 return sendData(PACKET_DATA, (uint8_t*) &msgData, 7);
gume 0:093f1cb20c52 260 }