Fork of my MQTTGateway
Diff: XbeeMonitor/XBeeLib/FrameBuffer/FrameBuffer.cpp
- Revision:
- 0:f1d3878b8dd9
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/XbeeMonitor/XBeeLib/FrameBuffer/FrameBuffer.cpp Sat Apr 08 14:45:51 2017 +0000
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2015 Digi International Inc.,
+ * All rights not expressly granted are reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
+ * =======================================================================
+ */
+
+#include "FrameBuffer.h"
+#include "Utils/Debug.h"
+
+#if !(defined AVOID_DISABLE_IRQS)
+#define disable_irq() __disable_irq()
+#define enable_irq() __enable_irq()
+#else
+#define disable_irq()
+#define enable_irq()
+#endif
+
+FrameBuffer::FrameBuffer(uint8_t size, uint16_t max_payload_len) : _size(size), _head(0), _tail(0), _dropped_frames(0)
+{
+ _frm_buf = new buf_element_t[_size];
+
+ assert(_frm_buf != NULL);
+
+ for (int i = 0; i < _size; i++) {
+ _frm_buf[i].frame = new ApiFrame(max_payload_len - 1);
+ _frm_buf[i].status = FrameStatusFree;
+ }
+}
+
+FrameBuffer::~FrameBuffer()
+{
+ for (int i = 0; i < _size; i++) {
+ delete _frm_buf[i].frame;
+ }
+
+ delete _frm_buf;
+}
+
+ApiFrame *FrameBuffer::get_next_free_frame(void)
+{
+ uint8_t i = _head;
+ ApiFrame *ret = NULL;
+
+ do {
+ if (_frm_buf[i].status == FrameStatusFree || _frm_buf[i].status == FrameStatusComplete) {
+ if (_frm_buf[i].status == FrameStatusComplete) {
+ _dropped_frames++;
+ }
+ _frm_buf[i].status = FrameStatusAssigned;
+ ret = _frm_buf[i].frame;
+ _head = ++i % _size;
+ break;
+ }
+ i++;
+ i = i % _size;
+ } while (i != _head);
+
+ return ret;
+}
+
+bool FrameBuffer::complete_frame(ApiFrame *frame)
+{
+ bool ret = false;
+
+ for (int i = 0; i < _size; i++) {
+ if (_frm_buf[i].frame == frame) {
+ _frm_buf[i].status = FrameStatusComplete;
+ ret = true;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+ApiFrame *FrameBuffer::get_next_complete_frame(void)
+{
+ uint8_t i = _tail;
+ ApiFrame *ret = NULL;
+
+ do {
+ disable_irq();
+ if (_frm_buf[i].status == FrameStatusComplete) {
+ _frm_buf[i].status = FrameStatusAssigned;
+ enable_irq();
+ ret = _frm_buf[i].frame;
+ _tail = ++i % _size;
+ break;
+ }
+ enable_irq();
+ i++;
+ i = i % _size;
+ } while (i != _tail);
+
+ return ret;
+}
+
+bool FrameBuffer::free_frame(ApiFrame *frame)
+{
+ bool ret = false;
+
+ for (int i = 0; i < _size; i++) {
+ if (_frm_buf[i].frame == frame) {
+ _frm_buf[i].status = FrameStatusFree;
+ ret = true;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+uint32_t FrameBuffer::get_dropped_frames_count(void)
+{
+ const uint32_t dropped_frames = _dropped_frames;
+
+ _dropped_frames = 0;
+
+ return dropped_frames;
+}