/ src / libserver / groupcacheclient.cpp
groupcacheclient.cpp
  1  /*
  2      EIBD eib bus access and management daemon
  3      Copyright (C) 2005-2011 Martin Koegler <mkoegler@auto.tuwien.ac.at>
  4  
  5      This program is free software; you can redistribute it and/or modify
  6      it under the terms of the GNU General Public License as published by
  7      the Free Software Foundation; either version 2 of the License, or
  8      (at your option) any later version.
  9  
 10      This program is distributed in the hope that it will be useful,
 11      but WITHOUT ANY WARRANTY; without even the implied warranty of
 12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13      GNU General Public License for more details.
 14  
 15      You should have received a copy of the GNU General Public License
 16      along with this program; if not, write to the Free Software
 17      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 18  */
 19  
 20  #include "groupcacheclient.h"
 21  
 22  #include "client.h"
 23  #include "groupcache.h"
 24  
 25  bool
 26  CreateGroupCache (Router& r, IniSectionPtr& s)
 27  {
 28    LinkConnectPtr c = LinkConnectPtr(new LinkConnect(r,s,r.t));
 29    GroupCachePtr cache;
 30    if (r.getCache())
 31      return false;
 32    cache = GroupCachePtr(new GroupCache (c,s));
 33    c->set_driver(cache);
 34    if (!c->setup())
 35      return false;
 36  
 37    if (!r.registerLink(c))
 38      return false;
 39    r.setCache(cache);
 40    return true;
 41  }
 42  
 43  void
 44  ReadCallback(const GroupCacheEntry &gce, bool nowait, ClientConnPtr c)
 45  {
 46    CArray erg;
 47  
 48    erg.resize (6 + gce.data.size());
 49    EIBSETTYPE (erg, nowait ? EIB_CACHE_READ_NOWAIT : EIB_CACHE_READ);
 50    erg[2] = (gce.src >> 8) & 0xff;
 51    erg[3] = (gce.src >> 0) & 0xff;
 52    erg[4] = (gce.dst >> 8) & 0xff;
 53    erg[5] = (gce.dst >> 0) & 0xff;
 54    erg.setpart (gce.data, 6);
 55    c->sendmessage (erg.size(), erg.data());
 56  }
 57  
 58  void
 59  LastUpdatesCallback(const std::vector<eibaddr_t> &addrs, uint32_t end, ClientConnPtr c)
 60  {
 61    CArray erg;
 62  
 63    erg.resize (addrs.size() * 2 + 4);
 64    EIBSETTYPE (erg, EIB_CACHE_LAST_UPDATES);
 65    erg[2] = (end >> 8) & 0xff;
 66    erg[3] = (end >> 0) & 0xff;
 67    for (unsigned int i = 0; i < addrs.size(); i++)
 68      {
 69        erg[4 + i * 2] = (addrs[i] >> 8) & 0xff;
 70        erg[4 + i * 2 + 1] = (addrs[i]) & 0xff;
 71      }
 72    c->sendmessage (erg.size(), erg.data());
 73  }
 74  
 75  void
 76  LastUpdates2Callback(const std::vector<eibaddr_t> &addrs, uint32_t end, ClientConnPtr c)
 77  {
 78    CArray erg;
 79  
 80    erg.resize (addrs.size() * 2 + 6);
 81    EIBSETTYPE (erg, EIB_CACHE_LAST_UPDATES_2);
 82    erg[2] = (end >> 24) & 0xff;
 83    erg[3] = (end >> 16) & 0xff;
 84    erg[4] = (end >> 8) & 0xff;
 85    erg[5] = (end >> 0) & 0xff;
 86    for (unsigned int i = 0; i < addrs.size(); i++)
 87      {
 88        erg[6 + i * 2] = (addrs[i] >> 8) & 0xff;
 89        erg[6 + i * 2 + 1] = (addrs[i]) & 0xff;
 90      }
 91    c->sendmessage (erg.size(), erg.data());
 92  }
 93  
 94  void
 95  GroupCacheRequest (ClientConnPtr c, uint8_t *buf, size_t len)
 96  {
 97    eibaddr_t dst;
 98    uint16_t age = 0;
 99    Router& r = c->router;
100    GroupCachePtr cache = r.getCache();
101  
102    if (!cache)
103      {
104        c->sendreject ();
105        return;
106      }
107    switch (EIBTYPE (buf))
108      {
109      case EIB_CACHE_ENABLE:
110        if (cache->Start ())
111          c->sendreject (EIB_CACHE_ENABLE);
112        else
113          c->sendreject (EIB_CONNECTION_INUSE);
114        break;
115      case EIB_CACHE_DISABLE:
116        cache->Stop ();
117        c->sendreject (EIB_CACHE_DISABLE);
118        break;
119      case EIB_CACHE_CLEAR:
120        cache->Clear ();
121        c->sendreject (EIB_CACHE_CLEAR);
122        break;
123      case EIB_CACHE_REMOVE:
124        if (len < 4)
125          {
126            c->sendreject ();
127            return;
128          }
129        dst = (buf[2] << 8) | (buf[3]);
130        cache->remove (dst);
131        c->sendreject (EIB_CACHE_REMOVE);
132        break;
133  
134      case EIB_CACHE_READ:
135      case EIB_CACHE_READ_NOWAIT:
136        if (len < 4)
137          {
138            c->sendreject ();
139            return;
140          }
141        dst = (buf[2] << 8) | (buf[3]);
142        if (EIBTYPE (buf) == EIB_CACHE_READ)
143          {
144            if (len < 6)
145              {
146                c->sendreject ();
147                return;
148              }
149            age = (buf[4] << 8) | (buf[5]);
150          }
151        cache->Read (dst, EIBTYPE (buf) == EIB_CACHE_READ_NOWAIT ? 0 : 75,
152                     age, ReadCallback, c);
153        break;
154  
155      case EIB_CACHE_LAST_UPDATES:
156      {
157        if (len < 5)
158          {
159            c->sendreject ();
160            return;
161          }
162        uint16_t start = (buf[2] << 8) | buf[3];
163        uint8_t timeout = buf[4];
164        cache->LastUpdates (start, timeout, &LastUpdatesCallback, c);
165        break;
166      }
167  
168      case EIB_CACHE_LAST_UPDATES_2:
169      {
170        if (len < 7)
171          {
172            c->sendreject ();
173            return;
174          }
175        uint32_t start = (buf[2] << 24) | (buf[3] << 16) | (buf[4] << 8) | buf[5];
176        uint8_t timeout = buf[6];
177        cache->LastUpdates2 (start, timeout, &LastUpdates2Callback, c);
178        break;
179      }
180  
181      default:
182        c->sendreject ();
183      }
184  }
185