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.
Dependents: LittleCounter-Example
Revision 6:79100379d4b4, committed 2014-04-16
- Comitter:
- nickludlam
- Date:
- Wed Apr 16 14:38:12 2014 +0000
- Parent:
- 5:2e04a8b3fc25
- Commit message:
- Updated to support the Berg V2 API. Please see http://bergcloud.com/devcenter/api/v2/device-v2 for more details.
Changed in this revision
diff -r 2e04a8b3fc25 -r 79100379d4b4 BERGCloud.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BERGCloud.h Wed Apr 16 14:38:12 2014 +0000 @@ -0,0 +1,37 @@ +/* + +BERGCloud library + +Copyright (c) 2013 BERG Ltd. http://bergcloud.com/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +#ifndef BERGCLOUD_H +#define BERGCLOUD_H + +#ifdef ARDUINO +#include "BERGCloudArduino.h" +#else +#error Please #include "BERGCloudMbed.h" or "BERGCloudLinux.h" instead. +#endif + +#endif // #ifndef BERGCLOUD_H +
diff -r 2e04a8b3fc25 -r 79100379d4b4 BERGCloudBase.cpp
--- a/BERGCloudBase.cpp Tue Nov 26 17:45:12 2013 +0000
+++ b/BERGCloudBase.cpp Wed Apr 16 14:38:12 2014 +0000
@@ -28,7 +28,7 @@
#define __STDC_LIMIT_MACROS /* Include C99 stdint defines in C++ code */
#include <stdint.h>
#include <stddef.h>
-#include <string.h> /* For memcpy() */
+#include <string.h> /* For memset() */
#include "BERGCloudBase.h"
@@ -37,6 +37,11 @@
#define CONNECT_POLL_RATE_MS 250
+/* MessagePack for named commands and events */
+#define _MP_FIXRAW_MIN 0xa0
+#define _MP_FIXRAW_MAX 0xbf
+#define _MAX_FIXRAW (_MP_FIXRAW_MAX - _MP_FIXRAW_MIN)
+
uint8_t BERGCloudBase::nullKey[BC_KEY_SIZE_BYTES] = {0};
bool BERGCloudBase::_transaction(_BC_SPI_TRANSACTION *tr)
@@ -276,6 +281,8 @@
{
/* Returns TRUE if a valid command has been received */
+ _LOG("pollForCommand() methods returning a command ID number have been deprecated.\r\n");
+
_BC_SPI_TRANSACTION tr;
uint8_t cmdID[2] = {0};
uint16_t cmdIDSize = 0;
@@ -303,11 +310,80 @@
return false;
}
+bool BERGCloudBase::pollForCommand(uint8_t *commandBuffer, uint16_t commandBufferSize, uint16_t& commandSize, char *commandName, uint8_t commandNameMaxSize)
+{
+ /* Returns TRUE if a valid command has been received */
+
+ _BC_SPI_TRANSACTION tr;
+ uint8_t cmdID[2] = {0};
+ uint16_t cmdIDSize = 0;
+ uint8_t commandNameSize;
+ uint8_t originalCommandNameSize;
+ uint8_t msgPackByte;
+ uint16_t command;
+
+ if ((commandName == NULL) || (commandNameMaxSize < 2))
+ {
+ return false;
+ }
+
+ initTransaction(&tr);
+
+ tr.command = SPI_CMD_POLL_FOR_COMMAND;
+
+ tr.rx[0].buffer = cmdID;
+ tr.rx[0].bufferSize = sizeof(cmdID);
+ tr.rx[0].dataSize = &cmdIDSize;
+
+ tr.rx[1].buffer = commandBuffer;
+ tr.rx[1].bufferSize = commandBufferSize;
+ tr.rx[1].dataSize = &commandSize;
+
+ if (transaction(&tr))
+ {
+ command = (cmdID[0] << 8) | cmdID[1];
+ if (command == BC_COMMAND_NAMED_PACKED)
+ {
+ /* Get command name string size */
+ msgPackByte = *commandBuffer;
+
+ if ((msgPackByte <_MP_FIXRAW_MIN) || (msgPackByte > _MP_FIXRAW_MAX))
+ {
+ /* Invalid */
+ return false;
+ }
+
+ commandNameSize = originalCommandNameSize = msgPackByte - _MP_FIXRAW_MIN;
+
+ /* Limit to the size of the buffer provided */
+ if (commandNameSize > (commandNameMaxSize-1)) /* -1 for null terminator */
+ {
+ commandNameSize = (commandNameMaxSize-1);
+ }
+
+ /* Copy command name string as a null-terminated C string */
+ bytecpy((uint8_t *)commandName, (commandBuffer+1), commandNameSize); /* +1 for messagePack fixraw byte */
+ commandName[commandNameSize] = '\0';
+
+ /* Move up remaining packed data, update size */
+ commandSize -= (originalCommandNameSize + 1); /* +1 for messagePack fixraw byte */
+ bytecpy(commandBuffer, commandBuffer + (originalCommandNameSize + 1), commandSize);
+ return true;
+ }
+ }
+
+ *commandName = '\0';
+ commandSize = 0;
+ return false;
+}
+
#ifdef BERGCLOUD_PACK_UNPACK
bool BERGCloudBase::pollForCommand(BERGCloudMessageBuffer& buffer, uint8_t& commandID)
{
/* Returns TRUE if a valid command has been received */
+ _LOG("pollForCommand() methods returning a command ID number have been deprecated.\r\n");
+
_BC_SPI_TRANSACTION tr;
uint8_t cmdID[2] = {0};
uint16_t cmdIDSize = 0;
@@ -337,12 +413,85 @@
buffer.used(0);
return false;
}
+
+bool BERGCloudBase::pollForCommand(BERGCloudMessageBuffer& buffer, char *commandName, uint8_t commandNameMaxSize)
+{
+ /* Returns TRUE if a valid command has been received */
+
+ _BC_SPI_TRANSACTION tr;
+ uint8_t cmdID[2] = {0};
+ uint16_t cmdIDSize = 0;
+ uint16_t dataSize = 0;
+ uint8_t commandNameSize;
+ uint8_t originalCommandNameSize;
+ uint8_t msgPackByte;
+ uint16_t command;
+
+ if ((commandName == NULL) || (commandNameMaxSize < 2))
+ {
+ return false;
+ }
+
+ initTransaction(&tr);
+ buffer.clear();
+
+ tr.command = SPI_CMD_POLL_FOR_COMMAND;
+
+ tr.rx[0].buffer = cmdID;
+ tr.rx[0].bufferSize = sizeof(cmdID);
+ tr.rx[0].dataSize = &cmdIDSize;
+
+ tr.rx[1].buffer = buffer.ptr();
+ tr.rx[1].bufferSize = buffer.size();
+ tr.rx[1].dataSize = &dataSize;
+
+ if (transaction(&tr))
+ {
+ command = (cmdID[0] << 8) | cmdID[1];
+ if (command == BC_COMMAND_NAMED_PACKED)
+ {
+ /* Get command name string size */
+ msgPackByte = *buffer.ptr();
+
+ if ((msgPackByte <_MP_FIXRAW_MIN) || (msgPackByte > _MP_FIXRAW_MAX))
+ {
+ /* Invalid */
+ return false;
+ }
+
+ commandNameSize = originalCommandNameSize = msgPackByte - _MP_FIXRAW_MIN;
+
+ /* Limit to the size of the buffer provided */
+ if (commandNameSize > (commandNameMaxSize-1)) /* -1 for null terminator */
+ {
+ commandNameSize = (commandNameMaxSize-1);
+ }
+
+ /* Copy command name string as a null-terminated C string */
+ bytecpy((uint8_t *)commandName, (buffer.ptr()+1), commandNameSize); /* +1 for messagePack fixraw byte */
+ commandName[commandNameSize] = '\0';
+
+ /* Move up remaining packed data, update size */
+ dataSize -= (originalCommandNameSize + 1); /* +1 for messagePack fixraw byte */
+ bytecpy(buffer.ptr(), buffer.ptr() + (originalCommandNameSize + 1), dataSize);
+
+ buffer.used(dataSize);
+ return true;
+ }
+ }
+
+ buffer.used(0);
+ *commandName = '\0';
+ return false;
+}
#endif
bool BERGCloudBase::_sendEvent(uint8_t eventCode, uint8_t *eventBuffer, uint16_t eventSize, uint8_t command)
{
/* Returns TRUE if the event is sent successfully */
+ _LOG("sendEvent() methods using an eventCode number have been deprecated.\r\n");
+
_BC_SPI_TRANSACTION tr;
uint8_t header[4] = {0};
@@ -367,9 +516,62 @@
bool BERGCloudBase::sendEvent(uint8_t eventCode, uint8_t *eventBuffer, uint16_t eventSize, bool packed)
{
+
return _sendEvent(eventCode, eventBuffer, eventSize, packed ? SPI_CMD_SEND_EVENT_PACKED : SPI_CMD_SEND_EVENT_RAW);
}
+bool BERGCloudBase::sendEvent(const char *eventName, uint8_t *eventBuffer, uint16_t eventSize, bool packed)
+{
+ /* Returns TRUE if the event is sent successfully */
+
+ _BC_SPI_TRANSACTION tr;
+ uint8_t headerSize = 5; /* Four bytes of SPI header, one byte of messagePack type */
+ uint8_t header[5 + _MAX_FIXRAW] = {0}; /* Header size plus maximum name string size */
+
+ if (!packed)
+ {
+ /* We only support packed data now */
+ return false;
+ }
+
+ if ((eventName == NULL) || (eventName[0] == '\0'))
+ {
+ _LOG("Event name must be at least one character.\r\n");
+ return false;
+ }
+
+ /* Create SPI header */
+ header[0] = BC_EVENT_NAMED_PACKED & BC_EVENT_ID_MASK;
+ header[1] = 0;
+ header[2] = 0;
+ header[3] = 0;
+
+ /* Create string header in messagePack format */
+ header[4] = _MP_FIXRAW_MIN;
+ while ((*eventName != '\0') && (headerSize < sizeof(header)))
+ {
+ /* Copy string, update messagePack byte */
+ header[4]++;
+ header[headerSize++] = *eventName++;
+ }
+
+ if (eventSize > ((uint16_t)SPI_MAX_PAYLOAD_SIZE_BYTES - headerSize))
+ {
+ _LOG("Event is too big.\r\n");
+ return false;
+ }
+
+ initTransaction(&tr);
+
+ tr.command = SPI_CMD_SEND_EVENT_PACKED;
+ tr.tx[0].buffer = (uint8_t *)header;
+ tr.tx[0].dataSize = headerSize;
+ tr.tx[1].buffer = eventBuffer;
+ tr.tx[1].dataSize = eventSize;
+
+ return transaction(&tr);
+}
+
#ifdef BERGCLOUD_PACK_UNPACK
bool BERGCloudBase::sendEvent(uint8_t eventCode, BERGCloudMessageBuffer& buffer)
{
@@ -380,6 +582,52 @@
buffer.clear();
return result;
}
+
+bool BERGCloudBase::sendEvent(const char *eventName, BERGCloudMessageBuffer& buffer)
+{
+ /* Returns TRUE if the event is sent successfully */
+
+ _BC_SPI_TRANSACTION tr;
+ uint8_t headerSize = 5; /* Four bytes of SPI header, one byte of messagePack type */
+ uint8_t header[5 + _MAX_FIXRAW] = {0}; /* Header size plus maximum name string size */
+
+ if ((eventName == NULL) || (eventName[0] == '\0'))
+ {
+ _LOG("Event name must be at least one character.\r\n");
+ return false;
+ }
+
+ /* Create SPI header */
+ header[0] = BC_EVENT_NAMED_PACKED & BC_EVENT_ID_MASK;
+ header[1] = 0;
+ header[2] = 0;
+ header[3] = 0;
+
+ /* Create string header in messagePack format */
+ header[4] = _MP_FIXRAW_MIN;
+ while ((*eventName != '\0') && (headerSize < sizeof(header)))
+ {
+ /* Copy string, update messagePack byte */
+ header[4]++;
+ header[headerSize++] = *eventName++;
+ }
+
+ if (buffer.used() > ((uint16_t)SPI_MAX_PAYLOAD_SIZE_BYTES - headerSize))
+ {
+ _LOG("Event is too big.\r\n");
+ return false;
+ }
+
+ initTransaction(&tr);
+
+ tr.command = SPI_CMD_SEND_EVENT_PACKED;
+ tr.tx[0].buffer = (uint8_t *)header;
+ tr.tx[0].dataSize = headerSize;
+ tr.tx[1].buffer = buffer.ptr();
+ tr.tx[1].dataSize = buffer.used();
+
+ return transaction(&tr);
+}
#endif
bool BERGCloudBase::getConnectionState(uint8_t& state)
@@ -479,6 +727,31 @@
return true;
}
+bool BERGCloudBase::connect(const char *key, uint16_t version, bool waitForConnected)
+{
+ unsigned int tmp_key[BC_KEY_SIZE_BYTES] = {0};
+ uint8_t _key[BC_KEY_SIZE_BYTES] = {0};
+ uint8_t i;
+
+ /* Convert key from ASCII */
+ if (key != NULL)
+ {
+ if (sscanf(key, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
+ &tmp_key[0], &tmp_key[1], &tmp_key[2], &tmp_key[3],
+ &tmp_key[4], &tmp_key[5], &tmp_key[6], &tmp_key[7],
+ &tmp_key[8], &tmp_key[9], &tmp_key[10], &tmp_key[11],
+ &tmp_key[12], &tmp_key[13], &tmp_key[14], &tmp_key[15]) == 16)
+ {
+ for (i=0; i<sizeof(_key); i++)
+ {
+ _key[i] = (uint8_t)tmp_key[i];
+ }
+ }
+ }
+
+ return connect(_key, version, waitForConnected);
+}
+
bool BERGCloudBase::getClaimingState(uint8_t& state)
{
_BC_SPI_TRANSACTION tr;
@@ -610,9 +883,25 @@
{
synced = false;
lastResponse = SPI_RSP_SUCCESS;
+
+ /* Print library version */
+ _LOG("\r\nBERGCloud library version ");
+ _LOG_HEX(BERGCLOUD_LIB_VERSION >> 8);
+ _LOG(".");
+ _LOG_HEX(BERGCLOUD_LIB_VERSION & 0xff);
+ _LOG("\r\n");
}
void BERGCloudBase::end(void)
{
}
+
+void BERGCloudBase::bytecpy(uint8_t *dst, uint8_t *src, uint16_t size)
+{
+ /* memcpy() cannot be used when buffers overlap */
+ while (size-- > 0)
+ {
+ *dst++ = *src++;
+ }
+}
diff -r 2e04a8b3fc25 -r 79100379d4b4 BERGCloudBase.h --- a/BERGCloudBase.h Tue Nov 26 17:45:12 2013 +0000 +++ b/BERGCloudBase.h Wed Apr 16 14:38:12 2014 +0000 @@ -36,7 +36,7 @@ #include "BERGCloudMessageBuffer.h" #endif -#define BERGCLOUD_LIB_VERSION (0x0100) +#define BERGCLOUD_LIB_VERSION (0x0200) #define _TX_GROUPS (2) #define _RX_GROUPS (2) @@ -63,13 +63,17 @@ public: /* Check for a command */ bool pollForCommand(uint8_t *commandBuffer, uint16_t commandBufferSize, uint16_t& commandSize, uint8_t& commandID); + bool pollForCommand(uint8_t *commandBuffer, uint16_t commandBufferSize, uint16_t& commandSize, char *commandName, uint8_t commandNameMaxSize); #ifdef BERGCLOUD_PACK_UNPACK bool pollForCommand(BERGCloudMessageBuffer& buffer, uint8_t& commandID); + bool pollForCommand(BERGCloudMessageBuffer& buffer, char *commandName, uint8_t commandNameMaxSize); #endif /* Send an event */ - bool sendEvent(uint8_t eventCode, uint8_t *eventBuffer, uint16_t eventSize, bool packed = false); + bool sendEvent(uint8_t eventCode, uint8_t *eventBuffer, uint16_t eventSize, bool packed = true); + bool sendEvent(const char *eventName, uint8_t *eventBuffer, uint16_t eventSize, bool packed = true); #ifdef BERGCLOUD_PACK_UNPACK bool sendEvent(uint8_t eventCode, BERGCloudMessageBuffer& buffer); + bool sendEvent(const char *eventName, BERGCloudMessageBuffer& buffer); #endif /* Get the connection state */ bool getConnectionState(uint8_t& state); @@ -77,6 +81,7 @@ bool getSignalQuality(int8_t& rssi, uint8_t& lqi); /* Connect */ virtual bool connect(const uint8_t (&key)[BC_KEY_SIZE_BYTES] = nullKey, uint16_t version = 0, bool waitForConnected = false); + virtual bool connect(const char *key = NULL, uint16_t version = 0, bool waitForConnected = false); /* Check if the device has been claimed */ bool getClaimingState(uint8_t& state); /* Get the current claimcode */ @@ -110,6 +115,7 @@ bool _transaction(_BC_SPI_TRANSACTION *tr); bool transaction(_BC_SPI_TRANSACTION *tr); bool _sendEvent(uint8_t eventCode, uint8_t *eventBuffer, uint16_t eventSize, uint8_t command); + void bytecpy(uint8_t *dst, uint8_t *src, uint16_t size); void lockTake(void); void lockRelease(void); bool synced;
diff -r 2e04a8b3fc25 -r 79100379d4b4 BERGCloudConst.h --- a/BERGCloudConst.h Tue Nov 26 17:45:12 2013 +0000 +++ b/BERGCloudConst.h Wed Apr 16 14:38:12 2014 +0000 @@ -43,6 +43,7 @@ #define BC_COMMAND_START_RAW 0xC000 #define BC_COMMAND_START_PACKED 0xC100 +#define BC_COMMAND_NAMED_PACKED 0xC17F #define BC_COMMAND_ID_MASK 0x00FF #define BC_COMMAND_FORMAT_MASK 0xFF00 @@ -51,6 +52,7 @@ #define BC_EVENT_START_RAW 0xE000 #define BC_EVENT_START_PACKED 0xE100 +#define BC_EVENT_NAMED_PACKED 0xE17F #define BC_EVENT_ID_MASK 0x00FF #define BC_EVENT_FORMAT_MASK 0xFF00
diff -r 2e04a8b3fc25 -r 79100379d4b4 BERGCloudMbed.cpp
--- a/BERGCloudMbed.cpp Tue Nov 26 17:45:12 2013 +0000
+++ b/BERGCloudMbed.cpp Wed Apr 16 14:38:12 2014 +0000
@@ -168,5 +168,21 @@
return true;
}
+bool BERGCloudMbed::pollForCommand(BERGCloudMessageBuffer& buffer, string &commandName)
+{
+ bool result = false;
+ char tmp[31 + 1]; /* +1 for null terminator */
+
+ commandName = ""; /* Empty string */
+ result = pollForCommand(buffer, tmp, sizeof(tmp));
+
+ if (result)
+ {
+ commandName = string(tmp);
+ }
+
+ return result;
+}
+
#endif // #ifdef BERGCLOUD_PACK_UNPACK
diff -r 2e04a8b3fc25 -r 79100379d4b4 BERGCloudMbed.h --- a/BERGCloudMbed.h Tue Nov 26 17:45:12 2013 +0000 +++ b/BERGCloudMbed.h Wed Apr 16 14:38:12 2014 +0000 @@ -40,9 +40,11 @@ public: void begin(PinName _MOSIPin, PinName _MISOPin, PinName _SCLKPin, PinName _nSSELPin); void end(); + /* Methods using std::string class */ using BERGCloudBase::display; - /* Methods using std::string class */ bool display(std::string& s); + using BERGCloudBase::pollForCommand; + bool pollForCommand(BERGCloudMessageBuffer& buffer, string &commandName); private: virtual uint16_t SPITransaction(uint8_t *dataOut, uint8_t *dataIn, uint16_t dataSize, bool finalCS); virtual void timerReset(void);

