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