Jack Hansdampf / mbed-mqtt-GSOE1

Dependents:   ESP8266MQTT

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MQTTSNGWMessageIdTable.cpp Source File

MQTTSNGWMessageIdTable.cpp

00001 /**************************************************************************************
00002  * Copyright (c) 2018, Tomoaki Yamaguchi
00003  *
00004  * All rights reserved. This program and the accompanying materials
00005  * are made available under the terms of the Eclipse Public License v1.0
00006  * and Eclipse Distribution License v1.0 which accompany this distribution.
00007  *
00008  * The Eclipse Public License is available at
00009  *    http://www.eclipse.org/legal/epl-v10.html
00010  * and the Eclipse Distribution License is available at
00011  *   http://www.eclipse.org/org/documents/edl-v10.php.
00012  *
00013  * Contributors:
00014  *    Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
00015  **************************************************************************************/
00016 
00017 #include "MQTTSNGWMessageIdTable.h"
00018 #include "MQTTSNGWClient.h"
00019 
00020 using namespace MQTTSNGW;
00021 
00022 /*===============================
00023  * Class MessageIdTable
00024  ===============================*/
00025 MessageIdTable::MessageIdTable()
00026 {
00027 
00028 }
00029 
00030 MessageIdTable::~MessageIdTable()
00031 {
00032     _mutex.lock();
00033     if ( _head != nullptr )
00034     {
00035         MessageIdElement* p = _tail;
00036         while ( p )
00037         {
00038             MessageIdElement* pPrev = p;
00039             delete p;
00040             _cnt--;
00041             p = pPrev->_prev;
00042         }
00043         _head = _tail = nullptr;
00044     }
00045     _mutex.unlock();
00046 }
00047 
00048 MessageIdElement* MessageIdTable::add(Aggregater* aggregater, Client* client, uint16_t clientMsgId)
00049 {
00050     if ( _cnt > _maxSize )
00051     {
00052         return nullptr;
00053     }
00054 
00055     MessageIdElement* elm = new MessageIdElement(0, client, clientMsgId);
00056     if ( elm == nullptr )
00057     {
00058         return nullptr;
00059     }
00060     _mutex.lock();
00061     if ( _head == nullptr )
00062     {
00063         elm->_msgId = aggregater->msgId();
00064         _head = elm;
00065         _tail = elm;
00066         _cnt++;
00067     }
00068     else
00069     {
00070         MessageIdElement* p = find(client, clientMsgId);
00071         if ( p == nullptr )
00072         {
00073             elm->_msgId = aggregater->msgId();
00074              p = _tail;
00075             _tail = elm;
00076             elm->_prev = p;
00077             p->_next = elm;
00078             _cnt++;
00079         }
00080         else
00081         {
00082             delete elm;
00083             elm = nullptr;
00084         }
00085     }
00086     _mutex.unlock();
00087     return elm;
00088 }
00089 
00090 MessageIdElement* MessageIdTable::find(uint16_t msgId)
00091 {
00092     MessageIdElement* p = _head;
00093     while ( p )
00094     {
00095         if ( p->_msgId == msgId)
00096         {
00097             break;
00098         }
00099         p = p->_next;
00100     }
00101     return p;
00102 }
00103 
00104 MessageIdElement* MessageIdTable::find(Client* client, uint16_t clientMsgId)
00105 {
00106     MessageIdElement* p = _head;
00107     while ( p )
00108     {
00109         if ( p->_clientMsgId == clientMsgId && p->_client == client)
00110         {
00111             break;
00112         }
00113         p = p->_next;
00114     }
00115     return p;
00116 }
00117 
00118 
00119 Client* MessageIdTable::getClientMsgId(uint16_t msgId, uint16_t* clientMsgId)
00120 {
00121     Client* clt = nullptr;
00122     *clientMsgId = 0;
00123     _mutex.lock();
00124     MessageIdElement* p = find(msgId);
00125     if ( p != nullptr )
00126     {
00127         clt = p->_client;
00128         *clientMsgId = p->_clientMsgId;
00129         clear(p);
00130     }
00131     _mutex.unlock();
00132     return clt;
00133 }
00134 
00135 void MessageIdTable::erase(uint16_t msgId)
00136 {
00137     _mutex.lock();
00138     MessageIdElement* p = find(msgId);
00139     clear(p);
00140     _mutex.unlock();
00141 }
00142 
00143 void MessageIdTable::clear(MessageIdElement* elm)
00144 {
00145     if ( elm == nullptr )
00146     {
00147         return;
00148     }
00149 
00150     if ( elm->_prev == nullptr )
00151     {
00152         _head = elm->_next;
00153         if ( _head == nullptr)
00154         {
00155             _tail = nullptr;
00156         }
00157         else
00158         {
00159             _head->_prev = nullptr;
00160         }
00161         delete elm;
00162         _cnt--;
00163         return;
00164     }
00165     else
00166     {
00167         elm->_prev->_next = elm->_next;
00168         if ( elm->_next == nullptr )
00169         {
00170             _tail = elm->_prev;
00171         }
00172         else
00173         {
00174             elm->_next->_prev = elm->_prev;
00175         }
00176         delete elm;
00177         _cnt--;
00178         return;
00179     }
00180 }
00181 
00182 
00183 uint16_t MessageIdTable::getMsgId(Client* client, uint16_t clientMsgId)
00184 {
00185     uint16_t msgId = 0;
00186     MessageIdElement* p = find(client, clientMsgId);
00187     if ( p != nullptr )
00188     {
00189         msgId = p->_msgId;
00190     }
00191     return msgId;
00192 }
00193 
00194 /*===============================
00195  * Class MessageIdElement
00196  ===============================*/
00197 MessageIdElement::MessageIdElement(void)
00198     : _msgId{0}
00199     , _clientMsgId {0}
00200     , _client {nullptr}
00201     , _next {nullptr}
00202     , _prev {nullptr}
00203 {
00204 
00205 }
00206 
00207 MessageIdElement::MessageIdElement(uint16_t msgId, Client* client, uint16_t clientMsgId)
00208     : MessageIdElement()
00209 {
00210     _msgId = msgId;
00211     _client = client;
00212     _clientMsgId = clientMsgId;
00213 }
00214 
00215 MessageIdElement::~MessageIdElement(void)
00216 {
00217 
00218 }