00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "lq_plugin.h"
00043 #include "tc_set.h"
00044 #include "link_set.h"
00045 #include "olsr_spf.h"
00046 #include "lq_packet.h"
00047 #include "olsr.h"
00048 #include "olsr_memcookie.h"
00049 #include "common/avl.h"
00050 #include "common/string.h"
00051 #include "olsr_logging.h"
00052 #include "neighbor_table.h"
00053
00054 #include "assert.h"
00055
00056 struct lq_handler *active_lq_handler = NULL;
00057
00058 static struct olsr_memcookie_info *tc_edge_mem_cookie = NULL;
00059 static struct olsr_memcookie_info *lq_hello_neighbor_mem_cookie = NULL;
00060 static struct olsr_memcookie_info *link_entry_mem_cookie = NULL;
00061
00062 void
00063 init_lq_handler(void)
00064 {
00065 if (NULL == active_lq_handler) {
00066 OLSR_ERROR(LOG_LQ_PLUGINS, "You removed the static linked LQ plugin and don't provide another one.\n");
00067 olsr_exit(1);
00068 }
00069
00070 OLSR_INFO(LOG_LQ_PLUGINS, "Initializing LQ handler %s...\n", active_lq_handler->name);
00071
00072 tc_edge_mem_cookie = olsr_memcookie_add("tc_edge", active_lq_handler->size_tc_edge);
00073
00074 lq_hello_neighbor_mem_cookie =
00075 olsr_memcookie_add("lq_hello_neighbor", active_lq_handler->size_lq_hello_neighbor);
00076
00077 link_entry_mem_cookie =
00078 olsr_memcookie_add("link_entry", active_lq_handler->size_link_entry);
00079
00080 if (active_lq_handler->initialize) {
00081 active_lq_handler->initialize();
00082 }
00083 }
00084
00085 void
00086 deinit_lq_handler(void)
00087 {
00088 if (NULL != active_lq_handler) {
00089 if (active_lq_handler->deinitialize) {
00090 active_lq_handler->deinitialize();
00091 }
00092 active_lq_handler = NULL;
00093 }
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 olsr_linkcost
00105 olsr_calc_tc_cost(struct tc_edge_entry *tc_edge)
00106 {
00107 return active_lq_handler->calc_tc_edge_entry_cost(tc_edge);
00108 }
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 void
00120 olsr_serialize_hello_lq_pair(uint8_t **buff, struct link_entry *link)
00121 {
00122 active_lq_handler->serialize_hello_lq(buff, link);
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 void
00135 olsr_deserialize_hello_lq_pair(const uint8_t ** curr, struct lq_hello_neighbor *neigh)
00136 {
00137 active_lq_handler->deserialize_hello_lq(curr, neigh);
00138 neigh->cost = active_lq_handler->calc_lq_hello_neighbor_cost(neigh);
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 void
00151 olsr_serialize_tc_lq(unsigned char **curr, struct link_entry *lnk)
00152 {
00153 active_lq_handler->serialize_tc_lq(curr, lnk);
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 void
00165 olsr_deserialize_tc_lq_pair(const uint8_t ** curr, struct tc_edge_entry *edge)
00166 {
00167 active_lq_handler->deserialize_tc_lq(curr, edge);
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 void
00181 olsr_lq_hello_handler(struct link_entry *entry, bool lost)
00182 {
00183 active_lq_handler->hello_handler(entry, lost);
00184 }
00185
00186 static void
00187 internal_clear_tc_edge_lq(struct tc_edge_entry *edge) {
00188
00189 if (active_lq_handler->clear_tc_edge_entry) {
00190 active_lq_handler->clear_tc_edge_entry(edge);
00191 }
00192 else {
00193 uint8_t *ptr = (uint8_t *) edge;
00194
00195 memset (ptr + sizeof(*edge), 0, active_lq_handler->size_tc_edge - sizeof(*edge));
00196 }
00197 }
00198
00199 void
00200 olsr_neighbor_cost_may_changed(struct nbr_entry *nbr) {
00201 struct link_entry *link;
00202 struct tc_edge_entry *edge;
00203 olsr_linkcost cost = LINK_COST_BROKEN;
00204
00205 link = get_best_link_to_neighbor(nbr);
00206 edge = nbr->tc_edge;
00207
00208 if (link) {
00209 cost = link->linkcost;
00210 active_lq_handler->copy_link_entry_lq_into_tc_edge_entry(edge, link);
00211 }
00212 else {
00213 internal_clear_tc_edge_lq(edge);
00214 }
00215
00216 if (edge->cost != cost) {
00217 edge->cost = cost;
00218
00219 changes_neighborhood = true;
00220 changes_topology = true;
00221 signal_link_changes(true);
00222 }
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 void
00236 olsr_memorize_foreign_hello_lq(struct link_entry *local, struct lq_hello_neighbor *foreign)
00237 {
00238 active_lq_handler->memorize_foreign_hello(local, foreign);
00239 }
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 const char *
00254 olsr_get_linkcost_text(olsr_linkcost cost, bool route, char *buffer, size_t bufsize)
00255 {
00256 static const char *infinite = "INF";
00257
00258 if (route) {
00259 if (cost == ROUTE_COST_BROKEN) {
00260 strscpy(buffer, infinite, bufsize);
00261 return buffer;
00262 }
00263 } else {
00264 if (cost >= LINK_COST_BROKEN) {
00265 strscpy(buffer, infinite, bufsize);
00266 return buffer;
00267 }
00268 }
00269 return active_lq_handler->print_cost(cost, buffer, bufsize);
00270 }
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 const char *
00284 olsr_get_linkdata_text(struct link_entry *entry, int idx, char *buffer, size_t bufsize)
00285 {
00286 if (idx == 0) {
00287 return olsr_get_linkcost_text(entry->linkcost, false, buffer, bufsize);
00288 }
00289 return active_lq_handler->print_link_entry_lq(entry, idx, buffer, bufsize);
00290 }
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 const char *
00301 olsr_get_linklabel (int idx) {
00302 assert (idx >= 0 && idx < active_lq_handler->linkdata_hello_count);
00303 return active_lq_handler->linkdata_hello[idx].name;
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 size_t
00316 olsr_get_linklabel_maxlength (int idx) {
00317 assert (idx >= 0 && idx < active_lq_handler->linkdata_hello_count);
00318 return active_lq_handler->linkdata_hello[idx].name_maxlen;
00319 }
00320
00321
00322
00323
00324
00325
00326 size_t olsr_get_linklabel_count (void) {
00327 return active_lq_handler->linkdata_hello_count;
00328 }
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 enum lq_linkdata_quality olsr_get_linkdata_quality (struct link_entry *link, int idx) {
00341 struct lq_linkdata_type *linkdata;
00342 int value;
00343
00344 assert (idx >= 0 && idx < active_lq_handler->linkdata_hello_count);
00345 linkdata = &active_lq_handler->linkdata_hello[idx];
00346 value = active_lq_handler->get_link_entry_data(link, idx);
00347
00348 if (value == linkdata->best) {
00349 return LQ_QUALITY_BEST;
00350 }
00351 if (value == linkdata->worst) {
00352 return LQ_QUALITY_WORST;
00353 }
00354
00355 if (linkdata->best < linkdata->worst) {
00356 if (value > linkdata->good) {
00357 return LQ_QUALITY_GOOD;
00358 }
00359 if (value > linkdata->average) {
00360 return LQ_QUALITY_AVERAGE;
00361 }
00362 }
00363 else {
00364 if (value < linkdata->good) {
00365 return LQ_QUALITY_GOOD;
00366 }
00367 if (value < linkdata->average) {
00368 return LQ_QUALITY_AVERAGE;
00369 }
00370 }
00371 return LQ_QUALITY_BAD;
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 struct tc_edge_entry *
00383 olsr_malloc_tc_edge_entry(void)
00384 {
00385 struct tc_edge_entry *t;
00386
00387 t = olsr_memcookie_malloc(tc_edge_mem_cookie);
00388 if (active_lq_handler->clear_tc_edge_entry)
00389 active_lq_handler->clear_tc_edge_entry(t);
00390 return t;
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 struct lq_hello_neighbor *
00402 olsr_malloc_lq_hello_neighbor(void)
00403 {
00404 struct lq_hello_neighbor *h;
00405
00406 h = olsr_memcookie_malloc(lq_hello_neighbor_mem_cookie);
00407 if (active_lq_handler->clear_lq_hello_neighbor)
00408 active_lq_handler->clear_lq_hello_neighbor(h);
00409 return h;
00410 }
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 struct link_entry *
00421 olsr_malloc_link_entry(void)
00422 {
00423 struct link_entry *h;
00424
00425 h = olsr_memcookie_malloc(link_entry_mem_cookie);
00426 if (active_lq_handler->clear_link_entry)
00427 active_lq_handler->clear_link_entry(h);
00428 return h;
00429 }
00430
00438 void
00439 olsr_free_link_entry(struct link_entry *link)
00440 {
00441 olsr_memcookie_free(link_entry_mem_cookie, link);
00442 }
00443
00451 void
00452 olsr_free_lq_hello_neighbor(struct lq_hello_neighbor *neigh)
00453 {
00454 olsr_memcookie_free(lq_hello_neighbor_mem_cookie, neigh);
00455 }
00456
00464 void
00465 olsr_free_tc_edge_entry(struct tc_edge_entry *edge)
00466 {
00467 olsr_memcookie_free(tc_edge_mem_cookie, edge);
00468 }
00469
00475 uint8_t
00476 olsr_get_Hello_MessageId(void)
00477 {
00478 return active_lq_handler->messageid_hello;
00479 }
00480
00486 uint8_t
00487 olsr_get_TC_MessageId(void)
00488 {
00489 return active_lq_handler->messageid_tc;
00490 }
00491
00497 size_t
00498 olsr_sizeof_HelloLQ(void) {
00499 return active_lq_handler->serialized_lqhello_size;
00500 }
00501
00507 size_t
00508 olsr_sizeof_TCLQ(void) {
00509 return active_lq_handler->serialized_lqtc_size;
00510 }
00511
00512
00513
00514
00515
00516
00517