Client for the DeviceHubNet gateway. (You need the gateway SW as well!)
DeviceHubNet.cpp
- Committer:
- gume
- Date:
- 2017-03-28
- Revision:
- 0:093f1cb20c52
File content as of revision 0:093f1cb20c52:
#include <DeviceHubNet.h> int DeviceHubNet::readHex(char *hexStr, uint8_t* hex) { int j = 0; for (int i = 0; i < strlen(hexStr); i++) { char c = hexStr[i]; uint8_t n; if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { if (c <= '9') n = c - '0'; else if (c <= 'f') n = 10 + c - 'a'; else if (c <= 'F') n = 10 + c - 'A'; if (j % 2 == 0) hex[j/2] = n << 4; else hex[j/2] = hex[j/2] + n; j++; } } return (j+1)/2; } uint64_t DeviceHubNet::getFullAddress() { uint64_t full = 0; uint32_t netprefix = NETWORK_PREFIX; memcpy(((char*) &full)+2, (void*) &netprefix, 4); memcpy(((char*) &full)+0, (void*) &nodeAddress, 2); return full; } uint64_t DeviceHubNet::getGWAddress() { uint64_t full = 0; uint32_t netprefix = NETWORK_PREFIX; memcpy(((char*) &full)+2, (void*) &netprefix, 4); return full; } void DeviceHubNet::registerProject() { struct MsgRegister msgRegister; msgRegister.rType = 1; // Project memcpy((uint8_t*) msgRegister.id, &projectId, 4); memcpy((uint8_t*) msgRegister.id + 4, &apiKey, 16); sendData(PACKET_REGISTER, (uint8_t*) &msgRegister, 21); } void DeviceHubNet::registerDevice() { struct MsgRegister msgRegister; msgRegister.rType = 2; // Device memcpy((uint8_t*) msgRegister.id, &deviceId, 16); sendData(PACKET_REGISTER, (uint8_t*) &msgRegister, 17); } bool DeviceHubNet::sendData(uint8_t type, uint8_t *data, uint8_t len) { uint8_t msg[32]; msg[0] = nodeAddress & 0xff; msg[1] = nodeAddress >> 8; msg[2] = type; msg[3] = msgCounter++; memcpy(msg + 4, data, len); int w = 0; if (w < 5 && radio->testCarrier()) { w++; wait_ms(2); } // Stop listening, send radio->stopListening(); radio->setRetries(0, 3); radio->openWritingPipe(getGWAddress()); bool ok = radio->write(msg, len +4); radio->startListening(); return ok; } // public functions DeviceHubNet::DeviceHubNet(uint32_t projectId, uint8_t *apiKey, uint8_t *deviceId) { this->projectId = projectId; memcpy(this->apiKey, apiKey, 16); memcpy(this->deviceId, deviceId, 16); nextSId = 1; } DeviceHubNet::DeviceHubNet(uint32_t projectId, char *apiKeyStr, char *deviceIdStr) { this->projectId = projectId; memset(apiKey, 0, 16); readHex(apiKeyStr, apiKey); readHex(deviceIdStr, deviceId); nextSId = 1; } bool DeviceHubNet::radioPinConfig(PinName mosi, PinName miso, PinName sck, PinName cs, PinName ce) { radio = new RF24(mosi, miso, sck, cs, ce); return true; } bool DeviceHubNet::radioConfig(uint16_t address, uint8_t channel) { nodeAddress = address; if (!radio) return false; radio->begin(); radio->enableDynamicAck(); radio->enableDynamicPayloads(); //radio->openReadingPipe(0, BROADCAST_ADDRESS_LL); radio->openReadingPipe(1, getFullAddress()); //radio->setAutoAck(0, false); // Disable autoACK on broadcast radio->setAutoAck(1, true); // Ensure autoACK is enabled on data/control radio->setChannel(channel); radio->setDataRate(RF24_2MBPS); radio->setPALevel(RF24_PA_MAX); registerProject(); registerDevice(); radio->startListening(); // Start listening return true; } void DeviceHubNet::radioDump() { radio->printDetails(); } void DeviceHubNet::processMsgs() { uint8_t packet[32]; while (radio->available()) { uint8_t plen = radio->getDynamicPayloadSize(); radio->read(packet, plen); if (plen < 4) continue; //printf("New message received. Length: %d\n\r", plen); //for (int i = 0; i < plen; i++) printf("%02X:", packet[i]); //printf("\n\r"); if (packet[2] == 6) { // Registration error. Try to re-register everything registerProject(); registerDevice(); map<uint16_t, string>::iterator it; for (it = sensors.begin(); it != sensors.end(); ++it) { reRegisterSensor(it->first); } for (it = actuators.begin(); it != actuators.end(); ++it) { reRegisterActuator(it->first); } } else if (packet[2] == 3) { // Data message uint16_t sid = packet[4] + packet[5] * 256; uint8_t type = packet[6]; void (*cb)(uint8_t, uint8_t, float) = (void (*)(uint8_t, uint8_t, float)) actuator_cbs[sid]; if (type == 0) { // Digital data cb(type, packet[7], 0.0); } else { // Analog data float f; memcpy(&f, packet + 7, 4); cb(type, 0, f); } } } } uint16_t DeviceHubNet::registerSensor(char *sensorName) { uint16_t sensorId = nextSId++; sensors[sensorId] = string(sensorName); reRegisterSensor(sensorId); return sensorId; } uint16_t DeviceHubNet::registerActuator(char *actuatorName, uint8_t type, void (*onReceive)(uint8_t, uint8_t, float)) { uint16_t actuatorId = nextSId++; actuators[actuatorId] = string(actuatorName); actuator_cbs[actuatorId] = (void*) onReceive; actuator_types[actuatorId] = type; reRegisterActuator(actuatorId); return actuatorId; } void DeviceHubNet::reRegisterSensor(uint16_t sensorId) { char *sensorNameStr = (char*) sensors[sensorId].c_str(); struct MsgRegister msgRegister; msgRegister.rType = 3; // Sensor msgRegister.id[0] = sensorId & 0xff; msgRegister.id[1] = sensorId >> 8; strncpy((char*) msgRegister.id + 2, sensorNameStr, 24); int l = strlen(sensorNameStr); if (l > 24) l = 24; sendData(PACKET_REGISTER, (uint8_t*) &msgRegister, l + 3); } void DeviceHubNet::reRegisterActuator(uint16_t actuatorId) { char *actuatorNameStr = (char*) actuators[actuatorId].c_str(); struct MsgRegister msgRegister; msgRegister.rType = 4; // Actuator msgRegister.id[0] = actuatorId & 0xff; msgRegister.id[1] = actuatorId >> 8; msgRegister.id[2] = actuator_types[actuatorId]; strncpy((char*) msgRegister.id + 3, actuatorNameStr, 24); int l = strlen(actuatorNameStr); if (l > 24) l = 24; sendData(PACKET_REGISTER, (uint8_t*) &msgRegister, l + 4); } bool DeviceHubNet::sendDigitalData(uint16_t sensorId, uint8_t data) { struct MsgData msgData; msgData.sensorId = sensorId; msgData.dType = 0; msgData.data.ddata = data; return sendData(PACKET_DATA, (uint8_t*) &msgData, 4); } bool DeviceHubNet::sendAnalogData(uint16_t sensorId, float data) { struct MsgData msgData; msgData.sensorId = sensorId; msgData.dType = 1; msgData.data.adata = data; return sendData(PACKET_DATA, (uint8_t*) &msgData, 7); }