199 lines
7.7 KiB
C++
199 lines
7.7 KiB
C++
/*
|
|
* Copyright (c) 2015 SODAQ. All rights reserved.
|
|
*
|
|
* This file is part of Sodaq_RN2483.
|
|
*
|
|
* Sodaq_RN2483 is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as
|
|
* published by the Free Software Foundation, either version 3 of
|
|
* the License, or(at your option) any later version.
|
|
*
|
|
* Sodaq_RN2483 is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with Sodaq_RN2483. If not, see
|
|
* <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef _Sodaq_RN2483_h
|
|
#define _Sodaq_RN2483_h
|
|
|
|
#include <Arduino.h>
|
|
|
|
#include <stdint.h>
|
|
#include <Stream.h>
|
|
#include "Switchable_Device.h"
|
|
|
|
/**
|
|
|
|
Notes:
|
|
|
|
- uint16_t is preferred over size_t because long is never needed by the
|
|
size of the packets or the buffers of this application.
|
|
(Kees Bakker does not agree with this. size_t is not the same as long.
|
|
On AVR a size_t is uint16_t. On SAMD we don't care too much about the
|
|
data size, a long is fine.)
|
|
- Currently, only one received packet is supported. Every time a packet is
|
|
received, the previous one is overwritten.
|
|
- Also multiple responses from the server (with Frame Pending Bit set) are
|
|
not supported.
|
|
- The port of the received packet is not returned.
|
|
|
|
*/
|
|
|
|
//#define USE_DYNAMIC_BUFFER
|
|
//#define DEBUG
|
|
|
|
#define DEFAULT_INPUT_BUFFER_SIZE 64
|
|
#define DEFAULT_RECEIVED_PAYLOAD_BUFFER_SIZE 32
|
|
#define DEFAULT_TIMEOUT 120
|
|
#define RECEIVE_TIMEOUT 60000
|
|
|
|
// Available error codes.
|
|
enum MacTransmitErrorCodes
|
|
{
|
|
NoError = 0,
|
|
NoResponse = 1,
|
|
Timeout = 2,
|
|
PayloadSizeError = 3,
|
|
InternalError = 4,
|
|
Busy = 5,
|
|
NetworkFatalError = 6,
|
|
NotConnected = 7,
|
|
NoAcknowledgment = 8,
|
|
};
|
|
|
|
// Provides a simple, abstracted interface to Microchip's RN2483 LoRaWAN module.
|
|
// Implements SwitchableDevice for turning the device On/Off on supported boards.
|
|
//
|
|
// It is strongly suggested to use the static instance that is included with the library (LoRaBee)
|
|
// and not to create a new instance.
|
|
class Sodaq_RN2483 : public SwitchableDevice
|
|
{
|
|
public:
|
|
// Creates a new Sodaq_RN2483 instance.
|
|
Sodaq_RN2483();
|
|
|
|
// Returns the correct baudrate for the serial port that connects to the device.
|
|
uint32_t getDefaultBaudRate() { return 57600; };
|
|
|
|
// Initializes the device and connects to the network using Over-The-Air Activation.
|
|
// Returns true on successful connection.
|
|
bool initOTA(Stream& stream, const uint8_t devEUI[8], const uint8_t appEUI[8], const uint8_t appKey[16], bool adr = true);
|
|
|
|
// Initializes the device and connects to the network using Activation By Personalization.
|
|
// Returns true on successful connection.
|
|
bool initABP(Stream& stream, const uint8_t devAddr[4], const uint8_t appSKey[16], const uint8_t nwkSKey[16], bool adr = true);
|
|
|
|
// Sets the optional "Diagnostics and Debug" stream.
|
|
void setDiag(Stream& stream) { diagStream = &stream; };
|
|
|
|
// Sends the given payload without acknowledgement.
|
|
// Returns 0 (NoError) when transmission is successful or one of the MacTransmitErrorCodes otherwise.
|
|
uint8_t send(uint8_t port, const uint8_t* payload, uint8_t size);
|
|
|
|
// Sends the given payload with acknowledgement.
|
|
// Returns 0 (NoError) when transmission is successful or one of the MacTransmitErrorCodes otherwise.
|
|
uint8_t sendReqAck(uint8_t port, const uint8_t* payload, uint8_t size, uint8_t maxRetries);
|
|
|
|
// Copies the latest received packet (optionally starting from the "payloadStartPosition"
|
|
// position of the payload) into the given "buffer", up to "size" number of bytes.
|
|
// Returns the number of bytes written or 0 if no packet is received since last transmission.
|
|
uint16_t receive(uint8_t* buffer, uint16_t size, uint16_t payloadStartPosition = 0);
|
|
|
|
#ifdef USE_DYNAMIC_BUFFER
|
|
// Sets the size of the input buffer.
|
|
// Needs to be called before initOTA()/initABP().
|
|
void setInputBufferSize(uint16_t value) { this->inputBufferSize = value; };
|
|
|
|
// Sets the size of the "Received Payload" buffer.
|
|
// Needs to be called before initOTA()/initABP().
|
|
void setReceivedPayloadBufferSize(uint16_t value) { this->receivedPayloadBufferSize = value; };
|
|
#endif
|
|
|
|
#ifdef DEBUG
|
|
// Provides a quick test of several methods as a pseudo-unit test.
|
|
void runTestSequence(Stream& stream);
|
|
int freeRam();
|
|
#endif
|
|
|
|
private:
|
|
// The stream that communicates with the device.
|
|
Stream* loraStream;
|
|
|
|
// The (optional) stream to show debug information.
|
|
Stream* diagStream;
|
|
|
|
// The size of the input buffer. Equals DEFAULT_INPUT_BUFFER_SIZE
|
|
// by default or (optionally) a user-defined value when using USE_DYNAMIC_BUFFER.
|
|
uint16_t inputBufferSize;
|
|
|
|
// The size of the received payload buffer. Equals DEFAULT_RECEIVED_PAYLOAD_BUFFER_SIZE
|
|
// by default or (optionally) a user-defined value when using USE_DYNAMIC_BUFFER.
|
|
uint16_t receivedPayloadBufferSize;
|
|
|
|
// Flag used to make sure the received payload buffer is
|
|
// current with the latest transmission.
|
|
bool packetReceived;
|
|
|
|
#ifdef USE_DYNAMIC_BUFFER
|
|
// Flag to make sure the buffers are not allocated more than once.
|
|
bool isBufferInitialized;
|
|
|
|
char* inputBuffer;
|
|
char* receivedPayloadBuffer;
|
|
#else
|
|
char inputBuffer[DEFAULT_INPUT_BUFFER_SIZE];
|
|
char receivedPayloadBuffer[DEFAULT_RECEIVED_PAYLOAD_BUFFER_SIZE];
|
|
#endif
|
|
// Takes care of the init tasks common to both initOTA() and initABP.
|
|
inline void init(Stream& stream);
|
|
|
|
// Reads a line from the device stream into the "buffer" starting at the "start" position of the buffer.
|
|
// Returns the number of bytes read.
|
|
uint16_t readLn(char* buffer, uint16_t size, uint16_t start = 0);
|
|
|
|
// Reads a line from the device stream into the input buffer.
|
|
// Returns the number of bytes read.
|
|
uint16_t readLn() { return readLn(this->inputBuffer, this->inputBufferSize); };
|
|
|
|
// Waits for the given string. Returns true if the string is received before a timeout.
|
|
// Returns false if a timeout occurs or if another string is received.
|
|
bool expectString(const char* str, uint16_t timeout = DEFAULT_TIMEOUT);
|
|
bool expectOK();
|
|
|
|
// Sends a reset command to the module and waits for the success response (or timeout).
|
|
// Returns true on success.
|
|
bool resetDevice();
|
|
|
|
// Sends a join network command to the device and waits for the response (or timeout).
|
|
// Returns true on success.
|
|
bool joinNetwork(const char* type);
|
|
|
|
// Sends the given mac command together with the given paramValue
|
|
// to the device and awaits for the response.
|
|
// Returns true on success.
|
|
// NOTE: paramName should include a trailing space
|
|
bool setMacParam(const char* paramName, const uint8_t* paramValue, uint16_t size);
|
|
bool setMacParam(const char* paramName, uint8_t paramValue);
|
|
bool setMacParam(const char* paramName, const char* paramValue);
|
|
|
|
// Returns the enum that is mapped to the given "error" message.
|
|
uint8_t lookupMacTransmitError(const char* error);
|
|
|
|
// Sends a a payload and blocks until there is a response back, or the receive windows have closed,
|
|
// or the hard timeout has passed.
|
|
uint8_t macTransmit(const char* type, uint8_t port, const uint8_t* payload, uint8_t size);
|
|
|
|
// Parses the input buffer and copies the received payload into the "received payload" buffer
|
|
// when a "mac rx" message has been received. It is called internally by macTransmit().
|
|
// Returns 0 (NoError) or otherwise one of the MacTransmitErrorCodes.
|
|
uint8_t onMacRX();
|
|
};
|
|
|
|
extern Sodaq_RN2483 LoRaBee;
|
|
|
|
#endif // Sodaq_RN2483
|