LQ messages are now processed. MPRs are selected based on the link
authorThomas Lopatic <thomas@lopatic.de>
Fri, 5 Nov 2004 20:58:10 +0000 (20:58 +0000)
committerThomas Lopatic <thomas@lopatic.de>
Fri, 5 Nov 2004 20:58:10 +0000 (20:58 +0000)
quality. Not tested at all, yet. Well, at least we now *have* something
to test. :-)

13 files changed:
Makefile
src/link_set.c
src/link_set.h
src/lq_mpr.c [new file with mode: 0644]
src/lq_mpr.h [new file with mode: 0644]
src/lq_packet.c
src/lq_packet.h
src/mpr.c
src/olsr.c
src/packet.h
src/process_package.c
src/process_package.h
src/two_hop_neighbor_table.h

index 7f8b913..8633b83 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -19,7 +19,7 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #
 #
-# $Id: Makefile,v 1.17 2004/11/05 18:48:25 kattemat Exp $
+# $Id: Makefile,v 1.18 2004/11/05 20:58:09 tlopatic Exp $
 #
 
 #OS ?=         linux
@@ -66,7 +66,7 @@ CFLAGS ?=     -Isrc -Wall -Wmissing-prototypes -Wstrict-prototypes \
 
 LIBS =         -lpthread -lm -ldl
 
-$(DEPFILE):
+$(DEPFILE):    $(SRCS) $(HDRS)
                @echo '# olsrd dependency file. AUTOGENERATED' > $(DEPFILE)
                $(DEPEND) -Y $(CFLAGS) $(SRCS) >/dev/null 2>&1
 
@@ -88,7 +88,7 @@ CFLAGS ?=     -Isrc -Wall -Wmissing-prototypes -Wstrict-prototypes \
 
 LIBS =         -pthread -lm
 
-$(DEPFILE):
+$(DEPFILE):    $(SRCS) $(HDRS)
                @echo '# olsrd dependency file. AUTOGENERATED' > $(DEPFILE)
                $(DEPEND) $(CFLAGS) $(SRCS)
 
@@ -109,7 +109,7 @@ CFLAGS ?=   -Isrc -Isrc/win32 -Wall -Wmissing-prototypes \
 
 LIBS =         -mno-cygwin -lws2_32 -liphlpapi
 
-$(DEPFILE):
+$(DEPFILE):    $(SRCS) $(HDRS)
                @echo '# olsrd dependency file. AUTOGENERATED' > $(DEPFILE)
                $(DEPEND) $(CFLAGS) $(SRCS)
 
@@ -130,8 +130,8 @@ CFLAGS ?=   -D__MacOSX__ -Isrc -Wall -Wmissing-prototypes \
                -Wstrict-prototypes -O2 -g 
 
 LIBS =         -lm -ldl
-$(DEPFILE):
+
+$(DEPFILE):    $(SRCS) $(HDRS)
                @echo '# olsrd dependency file. AUTOGENERATED' > $(DEPFILE)
                $(DEPEND) $(CFLAGS) $(SRCS)
 
index fdc93bd..1a6f24d 100644 (file)
@@ -19,7 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * 
  * 
- * $Id: link_set.c,v 1.16 2004/11/05 14:33:31 tlopatic Exp $
+ * $Id: link_set.c,v 1.17 2004/11/05 20:58:09 tlopatic Exp $
  *
  */
 
@@ -446,9 +446,10 @@ add_new_entry(union olsr_ip_addr *local, union olsr_ip_addr *remote, union olsr_
       olsr_get_timestamp((olsr_u32_t) htime*1500, &new_link->hello_timeout);
       new_link->last_htime = htime;
       new_link->olsr_seqno = 0;
-      new_link->L_link_quality = 0;
     }
 
+  new_link->L_link_quality = 0.0;
+
 #if defined USE_LINK_QUALITY
   if (1)
     {
@@ -464,13 +465,14 @@ add_new_entry(union olsr_ip_addr *local, union olsr_ip_addr *remote, union olsr_
       new_link->lost_packets = 0;
       new_link->total_packets = 0;
 
-      new_link->loss_link_quality = 0.0;
-
       new_link->loss_window_size = 10;
       new_link->loss_index = 0;
 
       memset(new_link->loss_bitmap, 0, sizeof (new_link->loss_bitmap));
     }
+
+  new_link->loss_link_quality = 0.0;
+  new_link->neigh_link_quality = 0.0;
 #endif
 
   /* Add to queue */
@@ -894,15 +896,15 @@ void olsr_print_link_set(void)
 {
   struct link_entry *walker;
 
-  olsr_printf(1, "CURRENT LINK SET ------------------------------\n");
+  olsr_printf(1, "LINK SET --------------------------------------\n");
+  olsr_printf(1, "IP address      hyst  LQ    lost  total  NLQ\n");
 
   for (walker = link_set; walker != NULL; walker = walker->next)
-    olsr_printf(1, "%15s %5.3f %5.3f %d/%d\n",
+    olsr_printf(1, "%15s %5.3f %5.3f %3d   %3d    %5.3f\n",
                 olsr_ip_to_string(&walker->neighbor_iface_addr),
                 walker->L_link_quality, walker->loss_link_quality,
                 walker->lost_packets, walker->total_packets);
-
-  olsr_printf(1, "CURRENT LINK SET (END) ------------------------\n");
+  olsr_printf(1, "-----------------------------------------------\n");
 }
 
 static void update_packet_loss_worker(struct link_entry *entry, int lost)
@@ -912,8 +914,13 @@ static void update_packet_loss_worker(struct link_entry *entry, int lost)
 
   if (lost == 0)
     {
+      // packet not lost
+
       if ((entry->loss_bitmap[index] & mask) != 0)
         {
+          // but the packet that we replace was lost
+          // => decrement packet loss
+
           entry->loss_bitmap[index] &= ~mask;
           entry->lost_packets--;
         }
@@ -921,21 +928,34 @@ static void update_packet_loss_worker(struct link_entry *entry, int lost)
 
   else
     {
+      // packet lost
+
       if ((entry->loss_bitmap[index] & mask) == 0)
         {
+          // but the packet that we replace was not lost
+          // => increment packet loss
+
           entry->loss_bitmap[index] |= mask;
           entry->lost_packets++;
         }
     }
 
+  // move to the next packet
+
   entry->loss_index++;
 
+  // wrap around at the end of the packet loss window
+
   if (entry->loss_index >= entry->loss_window_size)
     entry->loss_index = 0;
 
+  // count the total number of handled packets up to the window size
+
   if (entry->total_packets < entry->loss_window_size)
     entry->total_packets++;
 
+  // calculate the link quality
+
   entry->loss_link_quality = 1.0 - (float)entry->lost_packets /
     (float)entry->total_packets;
 }
@@ -943,6 +963,9 @@ static void update_packet_loss_worker(struct link_entry *entry, int lost)
 void olsr_update_packet_loss_hello_int(struct link_entry *entry,
                                        double loss_hello_int)
 {
+  // called for every LQ HELLO message - update the timeout
+  // with the htime value from the message
+
   entry->loss_hello_int = loss_hello_int;
 }
 
@@ -951,19 +974,34 @@ void olsr_update_packet_loss(union olsr_ip_addr *rem, union olsr_ip_addr *loc,
 {
   struct link_entry *entry;
 
+  // called for every OLSR packet
+
   entry = lookup_link_entry(rem, loc);
 
+  // it's the very first LQ HELLO message - we do not yet have a link
+
   if (entry == NULL)
     return;
     
+  // a) have we seen a packet before, i.e. is the sequence number valid?
+
+  // b) heuristically detect a restart (= sequence number reset)
+  //    of our neighbor
+
   if (entry->loss_seqno_valid != 0 && 
       (unsigned short)(seqno - entry->loss_seqno) < 100)
     {
+      // loop through all lost packets
+
       while (entry->loss_seqno != seqno)
         {
+          // have we already considered all lost LQ HELLO messages?
+
           if (entry->loss_missed_hellos == 0)
             update_packet_loss_worker(entry, 1);
 
+          // if not, then decrement the number of lost LQ HELLOs
+
           else
             entry->loss_missed_hellos--;
 
@@ -971,12 +1009,22 @@ void olsr_update_packet_loss(union olsr_ip_addr *rem, union olsr_ip_addr *loc,
         }
     }
 
+  // we have received a packet, otherwise this function would not
+  // have been called
+
   update_packet_loss_worker(entry, 0);
 
+  // (re-)initialize
+
   entry->loss_missed_hellos = 0;
   entry->loss_seqno = seqno + 1;
+
+  // we now have a valid serial number for sure
+
   entry->loss_seqno_valid = 1;
 
+  // timeout for the first lost packet is 1.5 x htime
+
   olsr_get_timestamp((olsr_u32_t)(entry->loss_hello_int * 1500.0),
                      &entry->loss_timeout);
 }
@@ -985,15 +1033,27 @@ static void olsr_time_out_packet_loss()
 {
   struct link_entry *walker;
 
+  // loop through all links
+
   for (walker = link_set; walker != NULL; walker = walker->next)
     {
+      // find a link that has not seen any packets for a very long
+      // time (first time: 1.5 x htime, subsequently: 1.0 x htime)
+
       if (!TIMED_OUT(&walker->loss_timeout))
         continue;
       
+      // count the lost packet
+
       update_packet_loss_worker(walker, 1);
 
+      // memorize that we've counted the packet, so that we do not
+      // count it a second time later
+
       walker->loss_missed_hellos++;
 
+      // next timeout in 1.0 x htime
+
       olsr_get_timestamp((olsr_u32_t)(walker->loss_hello_int * 1000.0),
                          &walker->loss_timeout);
     }
@@ -1004,62 +1064,19 @@ float olsr_neighbor_best_link_quality(union olsr_ip_addr *main)
   struct link_entry *walker;
   float res = 0.0;
 
+  // loop through all links
+
   for (walker = link_set; walker != NULL; walker = walker->next)
     {
+      // check whether it's a link to the requested neighbor and
+      // whether the link's (bidirectional = forth x back) quality
+      // is better than what we have
+
       if(COMP_IP(&main, &walker->neighbor->neighbor_main_addr) &&
-         walker->loss_link_quality > res)
+         walker->loss_link_quality * walker->neigh_link_quality > res)
         res = walker->loss_link_quality;
     }
 
   return res;
 }
-
-struct link_entry *update_lq_link_entry(union olsr_ip_addr *local,
-                                        union olsr_ip_addr *remote,
-                                        struct lq_hello_message *lq_hello,
-                                        struct interface *inif)
-{
-  struct lq_hello_neighbor *neigh;
-  int stat;
-  struct link_entry *link;
-  struct interface *inter;
-
-  link = add_new_entry(local, remote, &lq_hello->comm.orig,
-                       lq_hello->comm.vtime, lq_hello->htime);
-
-  olsr_get_timestamp((olsr_u32_t)(lq_hello->comm.vtime * 1000),
-                     &link->ASYM_time);
-
-  for (neigh = lq_hello->neigh; neigh != NULL; neigh = neigh->next)
-      for (inter = ifnet; inter != NULL; inter = inter->int_next) 
-        if(COMP_IP(&neigh->addr, &inter->ip_addr))
-          break;
-
-  stat = (neigh != NULL) ? neigh->link_type : UNSPEC_LINK;
-
-  if (stat == LOST_LINK)
-    {
-      link->SYM_time = now;
-      link->SYM_time.tv_sec -= 1;
-    }
-
-  else if (stat == SYM_LINK || stat == ASYM_LINK)
-    {
-      olsr_get_timestamp((olsr_u32_t)(lq_hello->comm.vtime * 1000),
-                         &link->SYM_time);
-      timeradd(&link->SYM_time, &hold_time_neighbor, &link->time);
-    }
-
-  if(timercmp(&link->time, &link->ASYM_time, <))
-    link->time = link->ASYM_time;
-
-  if(olsr_cnf->use_hysteresis)
-    olsr_process_hysteresis(link);
-
-  stat = get_neighbor_status(remote);
-
-  update_neighbor_status(link->neighbor, stat);
-
-  return link;
-}
 #endif
index 0baaa32..fa9cefd 100644 (file)
@@ -19,7 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * 
  * 
- * $Id: link_set.h,v 1.11 2004/11/03 18:19:54 tlopatic Exp $
+ * $Id: link_set.h,v 1.12 2004/11/05 20:58:09 tlopatic Exp $
  *
  */
 
@@ -68,12 +68,14 @@ struct link_entry
   int lost_packets;
   int total_packets;
 
-  float loss_link_quality;
+  double loss_link_quality;
 
   int loss_window_size;
   int loss_index;
 
   unsigned char loss_bitmap[16];
+
+  double neigh_link_quality;
 #endif
 
   /*
@@ -126,10 +128,6 @@ void olsr_update_packet_loss(union olsr_ip_addr *rem, union olsr_ip_addr *loc,
                         olsr_u16_t seqno);
 void olsr_print_link_set(void);
 float olsr_neighbor_best_link_quality(union olsr_ip_addr *main);
-struct link_entry *update_lq_link_entry(union olsr_ip_addr *local,
-                                        union olsr_ip_addr *remote,
-                                        struct lq_hello_message *lq_hello,
-                                        struct interface *inif);
 #endif
 
 #endif
diff --git a/src/lq_mpr.c b/src/lq_mpr.c
new file mode 100644 (file)
index 0000000..b2052e2
--- /dev/null
@@ -0,0 +1,96 @@
+/* 
+ * OLSR ad-hoc routing table management protocol
+ * Copyright (C) 2004 Thomas Lopatic (thomas@lopatic.de)
+ *
+ * This file is part of the olsr.org OLSR daemon.
+ *
+ * olsr.org is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * olsr.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with olsr.org; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: lq_mpr.c,v 1.1 2004/11/05 20:58:10 tlopatic Exp $
+ *
+ */
+
+#if defined USE_LINK_QUALITY
+#include "defs.h"
+#include "neighbor_table.h"
+#include "two_hop_neighbor_table.h"
+#include "lq_mpr.h"
+
+void olsr_calculate_lq_mpr(void)
+{
+  struct neighbor_2_entry *neigh2;
+  struct neighbor_list_entry *walker;
+  int i;
+  struct neighbor_entry *neigh;
+  double best;
+
+  for(i = 0; i < HASHSIZE; i++)
+    {
+      for (neigh = neighbortable[i].next;
+           neigh != &neighbortable[i];
+           neigh = neigh->next)
+        { 
+          // memorize previous MPR status
+
+          neigh->was_mpr = neigh->is_mpr;
+
+          // clear current MPR status
+
+          neigh->is_mpr = OLSR_FALSE;
+
+          // in this pass we are only interested in WILL_ALWAYS neighbours
+
+          if(neigh->status == NOT_SYM ||
+             neigh->willingness != WILL_ALWAYS)
+            continue;
+
+          neigh->is_mpr = OLSR_TRUE;
+
+          if (neigh->is_mpr != neigh->was_mpr)
+            changes = OLSR_TRUE;
+        }
+    }
+
+  for(i = 0; i < HASHSIZE; i++)
+    {
+      // loop through all 2-hop neighbours
+
+      for (neigh2 = two_hop_neighbortable[i].next;
+           neigh2 != &two_hop_neighbortable[i];
+           neigh2 = neigh2->next)
+        {
+          // find the connecting 1-hop neighbour with the
+          // best total link quality
+
+          neigh = NULL;
+          best = 0.0;
+
+          for (walker = neigh2->neighbor_2_nblist.next;
+               walker != &neigh2->neighbor_2_nblist;
+               walker = walker->next)
+            if (walker->full_link_quality >= best)
+              {
+                neigh = walker->neighbor;
+                best = walker->full_link_quality;
+              }
+
+          neigh->is_mpr = OLSR_TRUE;
+
+          if (neigh->is_mpr != neigh->was_mpr)
+            changes = OLSR_TRUE;
+        }
+    }
+}
+#endif
diff --git a/src/lq_mpr.h b/src/lq_mpr.h
new file mode 100644 (file)
index 0000000..9140635
--- /dev/null
@@ -0,0 +1,30 @@
+/* 
+ * OLSR ad-hoc routing table management protocol
+ * Copyright (C) 2004 Thomas Lopatic (thomas@lopatic.de)
+ *
+ * This file is part of the olsr.org OLSR daemon.
+ *
+ * olsr.org is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * olsr.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with olsr.org; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: lq_mpr.h,v 1.1 2004/11/05 20:58:10 tlopatic Exp $
+ *
+ */
+
+#ifndef _OLSR_LQ_MPR
+#define _OLSR_LQ_MPR
+
+void olsr_calculate_lq_mpr(void);
+
+#endif
index 7afd6d9..e909c05 100644 (file)
@@ -20,7 +20,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * 
  * 
- * $Id: lq_packet.c,v 1.2 2004/11/05 11:52:55 kattemat Exp $
+ * $Id: lq_packet.c,v 1.3 2004/11/05 20:58:10 tlopatic Exp $
  *
  */
 
@@ -45,6 +45,8 @@ create_lq_hello(struct lq_hello_message *lq_hello, struct interface *outif)
   struct lq_hello_neighbor *neigh;
   struct link_entry *walker;
 
+  // initialize the static fields
+
   lq_hello->comm.type = LQ_HELLO_MESSAGE;
   lq_hello->comm.vtime = me_to_double(outif->valtimes.hello);
   lq_hello->comm.size = 0;
@@ -60,17 +62,30 @@ create_lq_hello(struct lq_hello_message *lq_hello, struct interface *outif)
 
   lq_hello->neigh = NULL;
   
+  // loop through the link set
+
   for (walker = link_set; walker != NULL; walker = walker->next)
     {
+      // allocate a neighbour entry
+
       neigh = olsr_malloc(sizeof (struct lq_hello_neighbor), "Build LQ_HELLO");
       
+      // a) this neighbor interface IS NOT visible via the output interface
+
       if(!COMP_IP(&walker->local_iface_addr, &outif->ip_addr))
         neigh->link_type = UNSPEC_LINK;
       
+      // b) this neighbor interface IS visible via the output interface
+
       else
         neigh->link_type = lookup_link_status(walker);
 
+      // set the entry's link quality
+
       neigh->link_quality = walker->loss_link_quality;
+      neigh->neigh_link_quality = walker->neigh_link_quality;
+
+      // set the entry's neighbour type
 
       if(walker->neighbor->is_mpr)
         neigh->neigh_type = MPR_NEIGH;
@@ -81,8 +96,12 @@ create_lq_hello(struct lq_hello_message *lq_hello, struct interface *outif)
       else if (walker->neighbor->status == NOT_SYM)
         neigh->neigh_type = NOT_NEIGH;
   
+      // set the entry's neighbour interface address
+
       COPY_IP(&neigh->addr, &walker->neighbor_iface_addr);
       
+      // queue the neighbour entry
+
       neigh->next = lq_hello->neigh;
       lq_hello->neigh = neigh;
     }
@@ -93,11 +112,15 @@ destroy_lq_hello(struct lq_hello_message *lq_hello)
 {
   struct lq_hello_neighbor *walker, *aux;
 
+  // loop through the queued neighbour entries and free them
+
   for (walker = lq_hello->neigh; walker != NULL; walker = aux)
     {
       aux = walker->next;
       free(walker);
     }
+
+  lq_hello->neigh = NULL;
 }
 
 static void
@@ -107,6 +130,8 @@ create_lq_tc(struct lq_tc_message *lq_tc, struct interface *outif)
   int i;
   struct neighbor_entry *walker;
 
+  // initialize the static fields
+
   lq_tc->comm.type = LQ_TC_MESSAGE;
   lq_tc->comm.vtime = me_to_double(outif->valtimes.tc);
   lq_tc->comm.size = 0;
@@ -123,29 +148,45 @@ create_lq_tc(struct lq_tc_message *lq_tc, struct interface *outif)
 
   lq_tc->neigh = NULL;
  
+  // loop through all neighbours
+  
   for(i = 0; i < HASHSIZE; i++)
     {
       for(walker = neighbortable[i].next; walker != &neighbortable[i];
           walker = walker->next)
         {
+          // only consider symmetric neighbours
+
           if(walker->status != SYM)
             continue;
 
+          // TC redundancy == 1: only consider MPRs and MPR selectors
+
           if (olsr_cnf->tc_redundancy == 1 && !walker->is_mpr &&
               olsr_lookup_mprs_set(&walker->neighbor_main_addr) == NULL)
             continue;
 
+          // TC redundancy == 0: only consider MPR selectors
+
           else if (olsr_cnf->tc_redundancy == 0 &&
                    olsr_lookup_mprs_set(&walker->neighbor_main_addr) == NULL)
             continue;
 
+          // allocate a neighbour entry
+          
           neigh = olsr_malloc(sizeof (struct lq_tc_neighbor), "Build LQ_TC");
                
+          // set the entry's main address
+
           COPY_IP(&neigh->main, &walker->neighbor_main_addr);
 
+          // set the entry's link quality
+
           neigh->link_quality =
             olsr_neighbor_best_link_quality(&neigh->main);
 
+          // queue the neighbour entry
+
           neigh->next = lq_tc->neigh;
           lq_tc->neigh = neigh;
         }
@@ -157,6 +198,8 @@ destroy_lq_tc(struct lq_tc_message *lq_tc)
 {
   struct lq_tc_neighbor *walker, *aux;
 
+  // loop through the queued neighbour entries and free them
+
   for (walker = lq_tc->neigh; walker != NULL; walker = aux)
     {
       aux = walker->next;
@@ -166,6 +209,8 @@ destroy_lq_tc(struct lq_tc_message *lq_tc)
 
 static int common_size(void)
 {
+  // return the size of the header shared by all OLSR messages
+
   return (olsr_cnf->ip_version == AF_INET) ?
     sizeof (struct olsr_header_v4) : sizeof (struct olsr_header_v6);
 }
@@ -175,6 +220,8 @@ static void serialize_common(struct olsr_common *comm)
   struct olsr_header_v4 *olsr_head_v4;
   struct olsr_header_v6 *olsr_head_v6;
 
+  // serialize an IPv4 OLSR message header
+
   if (olsr_cnf->ip_version == AF_INET)
     {
       olsr_head_v4 = (struct olsr_header_v4 *)msg_buffer;
@@ -190,6 +237,8 @@ static void serialize_common(struct olsr_common *comm)
       olsr_head_v4->seqno = htons(comm->seqno);
     }
 
+  // serialize an IPv6 OLSR message header
+
   olsr_head_v6 = (struct olsr_header_v6 *)msg_buffer;
 
   olsr_head_v6->type = comm->type;
@@ -334,12 +383,12 @@ serialize_lq_hello(struct lq_hello_message *lq_hello, struct interface *outif)
               // add the corresponding link quality
 
               buff[size++] = (unsigned char)(neigh->link_quality * 256);
+              buff[size++] = (unsigned char)(neigh->neigh_link_quality * 256);
 
               // pad
 
               buff[size++] = 0;
               buff[size++] = 0;
-              buff[size++] = 0;
 
               is_first = 0;
             }
@@ -466,6 +515,8 @@ static void *deserialize_common(struct olsr_common *comm, void *ser)
   struct olsr_header_v4 *olsr_head_v4;
   struct olsr_header_v6 *olsr_head_v6;
 
+  // deserialize an IPv4 OLSR message header
+
   if (olsr_cnf->ip_version == AF_INET)
     {
       olsr_head_v4 = (struct olsr_header_v4 *)ser;
@@ -483,6 +534,8 @@ static void *deserialize_common(struct olsr_common *comm, void *ser)
       return (void *)(olsr_head_v4 + 1);
     }
 
+  // deserialize an IPv6 OLSR message header
+
   olsr_head_v6 = (struct olsr_header_v6 *)ser;
 
   comm->type = olsr_head_v6->type;
@@ -540,8 +593,10 @@ deserialize_lq_hello(struct lq_hello_message *lq_hello, void *ser)
           COPY_IP(&neigh->addr, curr);
           curr += ipsize;
 
-          neigh->link_quality = (double)*curr / 256.0;
-          curr += 4;
+          neigh->link_quality = (double)*curr++ / 256.0;
+          neigh->neigh_link_quality = (double)*curr++ / 256.0;
+
+          curr += 2;
 
           neigh->link_type = EXTRACT_LINK(info_head->link_code);
           neigh->neigh_type = EXTRACT_STATUS(info_head->link_code);
@@ -602,184 +657,172 @@ deserialize_lq_tc(struct lq_tc_message *lq_tc, void *ser,
     }
 }
 
-static void process_lq_hello(struct lq_hello_message *lq_hello,
-                             struct interface *inif,
-                             union olsr_ip_addr *from)
+void
+olsr_output_lq_hello(void *para)
 {
-  struct link_entry *link;
-  struct lq_hello_neighbor *neigh;
-  union olsr_ip_addr *addr;
-  struct neighbor_2_list_entry *n2le;
-  struct neighbor_2_entry *n2e;
-
-  // XXX - TODO: parse the link quality values
+  struct lq_hello_message lq_hello;
+  struct interface *outif = (struct interface *)para;
 
-  // create or update the link and neighbor entries
+  // create LQ_HELLO in internal format
 
-  link = update_lq_link_entry(&inif->ip_addr, from, lq_hello, inif);
+  create_lq_hello(&lq_hello, outif);
 
-  // pass the hello interval to the packet loss detector
+  // convert internal format into transmission format, send it
 
-  olsr_update_packet_loss_hello_int(link, lq_hello->htime);
+  serialize_lq_hello(&lq_hello, outif);
 
-  // pass the hello interval to hysteresis
+  // destroy internal format
 
-  if (olsr_cnf->use_hysteresis != 0)
-    olsr_update_hysteresis_hello(link, lq_hello->htime);
+  destroy_lq_hello(&lq_hello);
 
-  // have we been selected as an MPR?
+  if(net_output_pending(outif))
+    net_output(outif);
+}
 
-  for (neigh = lq_hello->neigh; neigh != NULL; neigh = neigh->next)
-    if (neigh->link_type == SYM_LINK && neigh->neigh_type == MPR_NEIGH &&
-        COMP_IP(&neigh->addr, &inif->ip_addr))
-      break;
+void
+olsr_output_lq_tc(void *para)
+{
+  static int prev_empty = 1;
+  struct lq_tc_message lq_tc;
+  struct interface *outif = (struct interface *)para;
+  struct timeval timer;
 
-  // yes, we have
+  // create LQ_TC in internal format
 
-  if (neigh != NULL)
-    olsr_update_mprs_set(&lq_hello->comm.orig, lq_hello->comm.vtime);
+  create_lq_tc(&lq_tc, outif);
 
-  // our neighbor's willingness has changed
+  // a) the message is not empty
 
-  if(link->neighbor->willingness != lq_hello->will)
+  if (lq_tc.neigh != NULL)
     {
-      link->neighbor->willingness = lq_hello->will;
+      prev_empty = 0;
+
+      // convert internal format into transmission format, send it
 
-      changes_neighborhood = OLSR_TRUE;
-      changes_topology = OLSR_TRUE;
+      serialize_lq_tc(&lq_tc, outif);
     }
 
-  // we'll never be able to reach a two-hop neighbor via this neighbor,
-  // so there's nothing left to do
+  // b) this is the first empty message
 
-  if(link->neighbor->willingness == WILL_NEVER)
+  else if (prev_empty == 0)
     {
-      olsr_process_changes();
-      return;
+      // initialize timer
+
+      olsr_init_timer((olsr_u32_t)(max_tc_vtime * 3) * 1000, &timer);
+      timeradd(&now, &timer, &send_empty_tc);
+
+      prev_empty = 1;
+
+      // convert internal format into transmission format, send it
+
+      serialize_lq_tc(&lq_tc, outif);
     }
-  
-  // go through all neighbor entries in the LQ HELLO message
 
-  for (neigh = lq_hello->neigh; neigh != NULL; neigh = neigh->next)
-    {
-      // we cannot be our own two-hop neighbor
+  // c) this is not the first empty message, send if timer hasn't fired
 
-      if (if_ifwithaddr(&neigh->addr) != NULL)
-        continue;
+  else if (!TIMED_OUT(&send_empty_tc))
+    serialize_lq_tc(&lq_tc, outif);
 
-      // find the the two-hop neighbor's main address
+  // destroy internal format
 
-      addr = mid_lookup_main_addr(&neigh->addr);
+  destroy_lq_tc(&lq_tc);
 
-      if (addr == NULL)
-        addr = &neigh->addr;
+  if(net_output_pending(outif) && TIMED_OUT(&fwdtimer[outif->if_nr]))
+    set_buffer_timer(outif);
+}
 
-      // our neighbor has a symmetric link to the two-hop neighbor
+static void
+process_lq_hello(struct lq_hello_message *lq_hello, struct interface *inif,
+                 union olsr_ip_addr *from)
+{
+  struct hello_message hello;
+  struct lq_hello_neighbor *neigh;
+  struct hello_neighbor *new_neigh;
 
-      if(neigh->neigh_type == SYM_NEIGH || neigh->neigh_type == MPR_NEIGH)
-        {
-          // do we already know what we can reach this two-hop neighbor
-          // via the current neighbor?
+  // XXX - translation is ugly; everybody should use lq_hello_message :-)
 
-          n2le = olsr_lookup_my_neighbors(link->neighbor, addr);
+  // move the static fields from LQ_HELLO to HELLO
 
-          // yes, we already know -> only update the timeout value
+  hello.vtime = lq_hello->comm.vtime;
+  hello.htime = lq_hello->htime;
 
-          if (n2le != NULL)
-            olsr_get_timestamp((olsr_u32_t)lq_hello->comm.vtime * 1000,
-                               &n2le->neighbor_2_timer);
+  COPY_IP(&hello.source_addr, &lq_hello->comm.orig);
 
-          else
-            {
-              // do we already know this two-hop neighbor?
-              
-              n2e = olsr_lookup_two_hop_neighbor_table(addr);
+  hello.packet_seq_number = lq_hello->comm.seqno;
+  hello.hop_count = lq_hello->comm.hops;
+  hello.ttl = lq_hello->comm.ttl;
+  hello.willingness = lq_hello->will;
 
-              // no, we don't -> create a new two-hop neighbor entry
+  // move all LQ_HELLO neighbours to HELLO
 
-              if (n2e == NULL)
-                {
-                  n2e = olsr_malloc(sizeof(struct neighbor_2_entry),
-                                    "Process LQ_HELLO");
-                 
-                  n2e->neighbor_2_nblist.next = &n2e->neighbor_2_nblist;
+  for (neigh = lq_hello->neigh; neigh != NULL; neigh = neigh->next)
+    {
+      // allocate HELLO neighbour
 
-                  n2e->neighbor_2_nblist.prev = &n2e->neighbor_2_nblist;
+      new_neigh = olsr_malloc(sizeof (struct hello_neighbor),
+                              "LQ_HELLO translation");
 
-                  n2e->neighbor_2_pointer = 0;
-                  
-                  COPY_IP(&n2e->neighbor_2_addr, addr);
+      // copy fields
 
-                  olsr_insert_two_hop_neighbor_table(n2e);
-                }
+      new_neigh->status = neigh->neigh_type;
+      new_neigh->link = neigh->link_type;
+      new_neigh->link_quality = neigh->link_quality;
 
-              // memorize that we can reach this two-hop neighbor via the
-              // current neighbor
+      COPY_IP(&new_neigh->address, &neigh->addr);
 
-              olsr_linking_this_2_entries(link->neighbor, n2e,
-                                          (float)lq_hello->comm.vtime);
+      // queue HELLO neighbour
 
-              changes_neighborhood = OLSR_TRUE;
-              changes_topology = OLSR_TRUE;
-            }
-        }
+      new_neigh->next = hello.neighbors;
+      hello.neighbors = new_neigh;
     }
 
-  olsr_process_changes();
+  olsr_hello_tap(&hello, inif, from);
 }
 
-static void process_lq_tc(struct lq_tc_message *lq_tc)
+static void
+process_lq_tc(struct lq_tc_message *lq_tc, struct interface *inif,
+              union olsr_ip_addr *from, union olsr_message *ser)
 {
-}
+  struct tc_message tc;
+  struct lq_tc_neighbor *neigh;
+  struct tc_mpr_addr *new_neigh;
 
-void
-olsr_output_lq_hello(void *para)
-{
-  struct lq_hello_message lq_hello;
-  struct interface *outif = (struct interface *)para;
+  // XXX - translation is ugly; everybody should use lq_tc_message :-)
 
-  create_lq_hello(&lq_hello, outif);
-  serialize_lq_hello(&lq_hello, outif);
-  destroy_lq_hello(&lq_hello);
+  // move the static fields from LQ_TC to TC
 
-  if(net_output_pending(outif))
-    net_output(outif);
-}
+  tc.vtime = lq_tc->comm.vtime;
 
-void
-olsr_output_lq_tc(void *para)
-{
-  static int prev_empty = 1;
-  struct lq_tc_message lq_tc;
-  struct interface *outif = (struct interface *)para;
-  struct timeval timer;
+  COPY_IP(&tc.source_addr, &lq_tc->from);
+  COPY_IP(&tc.originator, &lq_tc->comm.orig);
 
-  create_lq_tc(&lq_tc, outif);
+  tc.packet_seq_number = lq_tc->comm.seqno;
+  tc.hop_count = lq_tc->comm.hops;
+  tc.ttl = lq_tc->comm.ttl;
+  tc.ansn = lq_tc->ansn;
 
-  if (lq_tc.neigh != NULL)
+  // move all LQ_TC neighbours to TC
+
+  for (neigh = lq_tc->neigh; neigh != NULL; neigh = neigh->next)
     {
-      prev_empty = 0;
+      // allocate TC neighbour
 
-      serialize_lq_tc(&lq_tc, outif);
-    }
+      new_neigh = olsr_malloc(sizeof (struct tc_mpr_addr),
+                              "LQ_TC translation");
 
-  else if (prev_empty == 0)
-    {
-      olsr_init_timer((olsr_u32_t)(max_tc_vtime * 3) * 1000, &timer);
-      timeradd(&now, &timer, &send_empty_tc);
+      // copy fields
 
-      prev_empty = 1;
+      new_neigh->link_quality = neigh->link_quality;
 
-      serialize_lq_tc(&lq_tc, outif);
-    }
+      COPY_IP(&new_neigh->address, &neigh->main);
 
-  else if (!TIMED_OUT(&send_empty_tc))
-    serialize_lq_tc(&lq_tc, outif);
+      // queue TC neighbour
 
-  destroy_lq_tc(&lq_tc);
+      new_neigh->next = tc.multipoint_relay_selector_address;
+      tc.multipoint_relay_selector_address = new_neigh;
+    }
 
-  if(net_output_pending(outif) && TIMED_OUT(&fwdtimer[outif->if_nr]))
-    set_buffer_timer(outif);
+  olsr_tc_tap(&tc, inif, from, ser);
 }
 
 void
@@ -789,8 +832,16 @@ olsr_input_lq_hello(union olsr_message *ser,
 {
   struct lq_hello_message lq_hello;
 
+  // convert received packet from transmission format into internal format
+
   deserialize_lq_hello(&lq_hello, ser);
+
+  // process internal format
+
   process_lq_hello(&lq_hello, inif, from);
+
+  // destroy internal format
+
   destroy_lq_hello(&lq_hello);
 }
 
@@ -799,9 +850,17 @@ olsr_input_lq_tc(union olsr_message *ser, struct interface *inif,
                  union olsr_ip_addr *from)
 {
   struct lq_tc_message lq_tc;
+  
+  // convert received packet from transmission format into internal format
 
   deserialize_lq_tc(&lq_tc, ser, from);
-  process_lq_tc(&lq_tc);
+
+  // process internal format
+
+  process_lq_tc(&lq_tc, inif, from, ser);
+
+  // destroy internal format
+
   destroy_lq_tc(&lq_tc);
 }
 #endif
index 4f4700d..6856da2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * OLSR ad-hoc routing table management protocol
- * Copyright (C) 2003 Andreas T√łnnesen (andreto@ifi.uio.no)
+ * Copyright (C) 2004 Thomas Lopatic (thomas@lopatic.de)
  *
  * This file is part of the olsr.org OLSR daemon.
  *
@@ -19,7 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * 
  * 
- * $Id: lq_packet.h,v 1.1 2004/11/03 18:19:54 tlopatic Exp $
+ * $Id: lq_packet.h,v 1.2 2004/11/05 20:58:10 tlopatic Exp $
  *
  */
 
@@ -72,6 +72,7 @@ struct lq_hello_neighbor
   olsr_u8_t                link_type;
   olsr_u8_t                neigh_type;
   double                   link_quality;
+  double                   neigh_link_quality;
   union olsr_ip_addr       addr;
   struct lq_hello_neighbor *next;
 };
index 49560a8..f3e0872 100644 (file)
--- a/src/mpr.c
+++ b/src/mpr.c
@@ -19,7 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * 
  * 
- * $Id: mpr.c,v 1.10 2004/11/05 11:52:55 kattemat Exp $
+ * $Id: mpr.c,v 1.11 2004/11/05 20:58:10 tlopatic Exp $
  *
  */
 
@@ -449,7 +449,6 @@ add_will_always_nodes()
   return count;
 }
 
-
 /**
  *This function calculates the mpr neighbors
  *@return nada
@@ -530,9 +529,6 @@ olsr_calculate_mpr()
 
 }
 
-
-
-
 /**
  *Optimize MPR set by removing all entries
  *where all 2 hop neighbors actually is
index 6076e45..3d54d0d 100644 (file)
@@ -19,7 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * 
  * 
- * $Id: olsr.c,v 1.16 2004/11/05 11:52:56 kattemat Exp $
+ * $Id: olsr.c,v 1.17 2004/11/05 20:58:10 tlopatic Exp $
  *
  */
 
@@ -36,6 +36,9 @@
 #include "mpr_selector_set.h"
 #include "mid_set.h"
 #include "mpr.h"
+#if defined USE_LINK_QUALITY
+#include "lq_mpr.h"
+#endif
 #include "scheduler.h"
 #include "generate_msg.h"
 #include "apm.h"
@@ -163,7 +166,11 @@ olsr_process_changes()
   if(changes_neighborhood)
     {
       /* Calculate new mprs, HNA and routing table */
+#if !defined USE_LINK_QUALITY
       olsr_calculate_mpr();
+#else
+      olsr_calculate_lq_mpr();
+#endif
       olsr_calculate_routing_table();
       olsr_calculate_hna_routes();
 
index 09f1f08..13334a0 100644 (file)
@@ -19,7 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * 
  * 
- * $Id: packet.h,v 1.8 2004/11/03 18:19:54 tlopatic Exp $
+ * $Id: packet.h,v 1.9 2004/11/05 20:58:10 tlopatic Exp $
  *
  */
 
@@ -43,6 +43,10 @@ struct hello_neighbor
 {
   olsr_u8_t             status;
   olsr_u8_t             link;
+#if defined USE_LINK_QUALITY
+  double                link_quality;
+  double                neigh_link_quality;
+#endif
   union olsr_ip_addr    main_address;
   union olsr_ip_addr    address;
   struct hello_neighbor *next;
@@ -63,7 +67,9 @@ struct hello_message
 
 struct tc_mpr_addr
 {
-
+#if defined USE_LINK_QUALITY
+  double             link_quality;
+#endif
   union olsr_ip_addr address;
   struct tc_mpr_addr *next;
 };
index aaa71e9..5f7de65 100644 (file)
@@ -19,7 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * 
  * 
- * $Id: process_package.c,v 1.13 2004/11/05 14:33:31 tlopatic Exp $
+ * $Id: process_package.c,v 1.14 2004/11/05 20:58:10 tlopatic Exp $
  *
  */
 
@@ -58,35 +58,40 @@ olsr_init_package_process()
   olsr_parser_add_function(&olsr_process_received_hna, HNA_MESSAGE, 1);
 }
 
-/**
- *Processes a received HELLO message. 
- *
- *@param m the incoming OLSR message
- *@return 0 on sucess
- */
-
 void
-olsr_process_received_hello(union olsr_message *m, struct interface *in_if, union olsr_ip_addr *from_addr)
+olsr_hello_tap(struct hello_message *message, struct interface *in_if,
+               union olsr_ip_addr *from_addr)
 {
   struct link_entry         *link;
   struct neighbor_entry     *neighbor;
-  struct hello_message      message;
-
-  hello_chgestruct(&message, m);
-
-  /*
-  if(COMP_IP(&message.source_addr, &main_addr))
-    {
-      olsr_destroy_hello_message(&message);
-      return;
-    }
-  */
+  struct hello_neighbor *walker;
 
   /*
    * Update link status
    */
-  link = update_link_entry(&in_if->ip_addr, from_addr, &message, in_if);
+  link = update_link_entry(&in_if->ip_addr, from_addr, message, in_if);
+
+#if defined USE_LINK_QUALITY
+  // just in case our neighbor has changed its HELLO interval
+
+  olsr_update_packet_loss_hello_int(link, message->htime);
+
+  // find the input interface in the list of neighbor interfaces
+
+  for (walker = message->neighbors; walker != NULL; walker = walker->next)
+    if (COMP_IP(&walker->address, &in_if->ip_addr))
+      break;
+
+  // memorize our neighbour's idea of the link quality, so that we
+  // know the link quality in both directions
+
+  if (walker != NULL)
+    link->neigh_link_quality = walker->link_quality;
 
+  else
+    link->neigh_link_quality = 0.0;
+#endif
+  
   neighbor = link->neighbor;
 
   /*
@@ -95,28 +100,28 @@ olsr_process_received_hello(union olsr_message *m, struct interface *in_if, unio
   if(olsr_cnf->use_hysteresis)
     {
       /* Update HELLO timeout */
-      //printf("MESSAGE HTIME: %f\n", message.htime);
-      olsr_update_hysteresis_hello(link, message.htime);
+      //printf("MESSAGE HTIME: %f\n", message->htime);
+      olsr_update_hysteresis_hello(link, message->htime);
     }
 
   /* Check if we are chosen as MPR */
-  if(olsr_lookup_mpr_status(&message, in_if))
+  if(olsr_lookup_mpr_status(message, in_if))
     /* source_addr is always the main addr of a node! */
-    olsr_update_mprs_set(&message.source_addr, (float)message.vtime);
+    olsr_update_mprs_set(&message->source_addr, (float)message->vtime);
 
 
 
   /* Check willingness */
-  if(neighbor->willingness != message.willingness)
+  if(neighbor->willingness != message->willingness)
     {
       olsr_printf(1, "Willingness for %s changed from %d to %d - UPDATING\n", 
                  olsr_ip_to_string(&neighbor->neighbor_main_addr),
                  neighbor->willingness,
-                 message.willingness);
+                 message->willingness);
       /*
        *If willingness changed - recalculate
        */
-      neighbor->willingness = message.willingness;
+      neighbor->willingness = message->willingness;
       changes_neighborhood = OLSR_TRUE;
       changes_topology = OLSR_TRUE;
     }
@@ -124,54 +129,48 @@ olsr_process_received_hello(union olsr_message *m, struct interface *in_if, unio
 
   /* Don't register neighbors of neighbors that announces WILL_NEVER */
   if(neighbor->willingness != WILL_NEVER)
-    olsr_process_message_neighbors(neighbor, &message);
+    olsr_process_message_neighbors(neighbor, message);
 
   /* Process changes immedeatly in case of MPR updates */
   olsr_process_changes();
 
-  olsr_destroy_hello_message(&message);
+  olsr_destroy_hello_message(message);
 
   return;
 }
 
-
-
-
-
 /**
- *Process a received TopologyControl message
- *
+ *Processes a received HELLO message. 
  *
  *@param m the incoming OLSR message
- *@return 0 on success
+ *@return 0 on sucess
  */
+
 void
-olsr_process_received_tc(union olsr_message *m, struct interface *in_if, union olsr_ip_addr *from_addr)
-{ 
-  struct tc_mpr_addr              *mpr;
-  struct tc_entry                 *tc_last;
-  struct tc_message               message;
+olsr_process_received_hello(union olsr_message *m, struct interface *in_if, union olsr_ip_addr *from_addr)
+{
+  struct hello_message      message;
 
-  tc_chgestruct(&message, m, from_addr);
+  hello_chgestruct(&message, m);
 
-  /*    
-  if(COMP_IP(&message.originator, &main_addr))
-    { 
-      goto forward;
-    }
-  */
+  olsr_hello_tap(&message, in_if, from_addr);
+}
 
-  if(!olsr_check_dup_table_proc(&message.originator, 
-                               message.packet_seq_number))
+void
+olsr_tc_tap(struct tc_message *message, struct interface *in_if,
+            union olsr_ip_addr *from_addr, union olsr_message *m)
+{
+  struct tc_mpr_addr              *mpr;
+  struct tc_entry                 *tc_last;
+
+  if(!olsr_check_dup_table_proc(&message->originator, 
+                                message->packet_seq_number))
     {
       goto forward;
     }
 
-  olsr_printf(3, "Processing TC from %s\n", olsr_ip_to_string(&message.originator));
-
-
-
-
+  olsr_printf(3, "Processing TC from %s\n",
+              olsr_ip_to_string(&message->originator));
 
   /*
    *      If the sender interface (NB: not originator) of this message
@@ -181,63 +180,63 @@ olsr_process_received_tc(union olsr_message *m, struct interface *in_if, union o
 
   if(check_neighbor_link(from_addr) != SYM_LINK)
     {
-      olsr_printf(2, "Received TC from NON SYM neighbor %s\n", olsr_ip_to_string(from_addr));
-      olsr_destroy_tc_message(&message);
+      olsr_printf(2, "Received TC from NON SYM neighbor %s\n",
+                  olsr_ip_to_string(from_addr));
+      olsr_destroy_tc_message(message);
       return;
     }
 
-
   if(olsr_cnf->debug_level > 2)
     {
-      mpr = message.multipoint_relay_selector_address;
-      olsr_printf(3, "mpr_selector_list:[");      
+      mpr = message->multipoint_relay_selector_address;
+      olsr_printf(3, "mpr_selector_list:[");
+
       while(mpr!=NULL)
-       {
-         olsr_printf(3, "%s:", olsr_ip_to_string(&mpr->address));
-         mpr=mpr->next;
-       }
+        {
+          olsr_printf(3, "%s:", olsr_ip_to_string(&mpr->address));
+          mpr=mpr->next;
+        }
+
       olsr_printf(3, "]\n");
     }
 
-
-
-  tc_last = olsr_lookup_tc_entry(&message.originator);
-  
+  tc_last = olsr_lookup_tc_entry(&message->originator);
+   
   if(tc_last != NULL)
     {
       /* Update entry */
 
       /* Delete destinations with lower ANSN */
-      if(olsr_tc_delete_mprs(tc_last, &message))
-       changes_topology = OLSR_TRUE; 
+      if(olsr_tc_delete_mprs(tc_last, message))
+        changes_topology = OLSR_TRUE; 
 
       /* Update destinations */
-      if(olsr_tc_update_mprs(tc_last, &message))
-       changes_topology = OLSR_TRUE;
+      if(olsr_tc_update_mprs(tc_last, message))
+        changes_topology = OLSR_TRUE;
 
       /* Delete possible empty TC entry */
       if(changes_topology)
-       olsr_tc_delete_entry_if_empty(tc_last);
-
+        olsr_tc_delete_entry_if_empty(tc_last);
     }
+
   else
     {
       /*if message is empty then skip it */
-      if(message.multipoint_relay_selector_address != NULL)
-       {
-         /* New entry */
-         tc_last = olsr_add_tc_entry(&message.originator);      
+      if(message->multipoint_relay_selector_address != NULL)
+        {
+          /* New entry */
+          tc_last = olsr_add_tc_entry(&message->originator);      
          
-         /* Update destinations */
-         olsr_tc_update_mprs(tc_last, &message);
+          /* Update destinations */
+          olsr_tc_update_mprs(tc_last, message);
          
-         changes_topology = OLSR_TRUE;
-       }
+          changes_topology = OLSR_TRUE;
+        }
       else
-       {
-         olsr_printf(3, "Dropping empty TC from %s\n", olsr_ip_to_string(&message.originator)); 
-       }
+        {
+          olsr_printf(3, "Dropping empty TC from %s\n",
+                      olsr_ip_to_string(&message->originator)); 
+        }
     }
 
   /* Process changes */
@@ -246,15 +245,33 @@ olsr_process_received_tc(union olsr_message *m, struct interface *in_if, union o
  forward:
 
   olsr_forward_message(m, 
-                      &message.originator, 
-                      message.packet_seq_number, 
-                      in_if,
-                      from_addr);
-  olsr_destroy_tc_message(&message);
+                       &message->originator, 
+                       message->packet_seq_number, 
+                       in_if,
+                       from_addr);
+
+  olsr_destroy_tc_message(message);
 
   return;
 }
 
+/**
+ *Process a received TopologyControl message
+ *
+ *
+ *@param m the incoming OLSR message
+ *@return 0 on success
+ */
+void
+olsr_process_received_tc(union olsr_message *m, struct interface *in_if, union olsr_ip_addr *from_addr)
+{ 
+  struct tc_message               message;
+
+  tc_chgestruct(&message, m, from_addr);
+
+  olsr_tc_tap(&message, in_if, from_addr, m);
+}
+
 
 
 
@@ -456,19 +473,24 @@ olsr_process_received_hna(union olsr_message *m, struct interface *in_if, union
  *@return nada
  */
 void
-olsr_process_message_neighbors(struct neighbor_entry *neighbor,struct hello_message *message)
+olsr_process_message_neighbors(struct neighbor_entry *neighbor,
+                               struct hello_message *message)
 {
   struct hello_neighbor        *message_neighbors;
   struct neighbor_2_list_entry *two_hop_neighbor_yet;
   struct neighbor_2_entry      *two_hop_neighbor;
   union olsr_ip_addr           *neigh_addr;
-  
 
-  for(message_neighbors=message->neighbors;
-      message_neighbors!=NULL;
-      message_neighbors=message_neighbors->next)
+#if defined USE_LINK_QUALITY
+  struct neighbor_list_entry *walker;
+  double link_quality =
+    olsr_neighbor_best_link_quality(&neighbor->neighbor_main_addr);
+#endif
+
+  for(message_neighbors = message->neighbors;
+      message_neighbors != NULL;
+      message_neighbors = message_neighbors->next)
     {
-      
       /*
        *check all interfaces
        *so that we don't add ourselves to the
@@ -476,61 +498,102 @@ olsr_process_message_neighbors(struct neighbor_entry *neighbor,struct hello_mess
        *IMPORTANT!
        */
       if(if_ifwithaddr(&message_neighbors->address) != NULL)
-        continue;
+        continue;
 
       /* Get the main address */
-      if((neigh_addr = mid_lookup_main_addr(&message_neighbors->address)) != NULL)
-       COPY_IP(&message_neighbors->address, neigh_addr);
-      
 
-      if(((message_neighbors->status==SYM_NEIGH) || (message_neighbors->status==MPR_NEIGH)))
-       {
-         //printf("\tProcessing %s\n", olsr_ip_to_string(&message_neighbors->address));
-         
-         //printf("\tMain addr: %s\n", olsr_ip_to_string(neigh_addr));
-         
-         if((two_hop_neighbor_yet = olsr_lookup_my_neighbors(neighbor, &message_neighbors->address))!=NULL)
-           {
-             
-             /* Updating the holding time for this neighbor */
-             olsr_get_timestamp((olsr_u32_t) message->vtime*1000, &two_hop_neighbor_yet->neighbor_2_timer);
+      neigh_addr = mid_lookup_main_addr(&message_neighbors->address);
 
-           }
-         else
-           {
-             
-             if((two_hop_neighbor = olsr_lookup_two_hop_neighbor_table(&message_neighbors->address)) == NULL)
-               {
-                
-                 //printf("Adding 2 hop neighbor %s\n\n", olsr_ip_to_string(&message_neighbors->address)); 
-                 changes_neighborhood = OLSR_TRUE;
-                 changes_topology = OLSR_TRUE;
-                 two_hop_neighbor = olsr_malloc(sizeof(struct neighbor_2_entry), "Process HELLO");
-                 
-                 two_hop_neighbor->neighbor_2_nblist.next = &two_hop_neighbor->neighbor_2_nblist;
-                 two_hop_neighbor->neighbor_2_nblist.prev = &two_hop_neighbor->neighbor_2_nblist;
-                 two_hop_neighbor->neighbor_2_pointer=0;
+      if (neigh_addr != NULL)
+        COPY_IP(&message_neighbors->address, neigh_addr);
+      
+      if(((message_neighbors->status == SYM_NEIGH) ||
+          (message_neighbors->status == MPR_NEIGH)))
+        {
+          //printf("\tProcessing %s\n", olsr_ip_to_string(&message_neighbors->address));
+          //printf("\tMain addr: %s\n", olsr_ip_to_string(neigh_addr));
+         
+          two_hop_neighbor_yet =
+            olsr_lookup_my_neighbors(neighbor,
+                                     &message_neighbors->address);
+
+          if (two_hop_neighbor_yet != NULL)
+            {
+              /* Updating the holding time for this neighbor */
+              olsr_get_timestamp((olsr_u32_t)message->vtime * 1000,
+                                 &two_hop_neighbor_yet->neighbor_2_timer);
+
+              two_hop_neighbor = two_hop_neighbor_yet->neighbor_2;
+            }
+          else
+            {
+              two_hop_neighbor =
+                olsr_lookup_two_hop_neighbor_table(&message_neighbors->address);
+              if (two_hop_neighbor == NULL)
+                {
+                  //printf("Adding 2 hop neighbor %s\n\n", olsr_ip_to_string(&message_neighbors->address)); 
+
+                  changes_neighborhood = OLSR_TRUE;
+                  changes_topology = OLSR_TRUE;
+
+                  two_hop_neighbor =
+                    olsr_malloc(sizeof(struct neighbor_2_entry),
+                                "Process HELLO");
                  
-                 COPY_IP(&two_hop_neighbor->neighbor_2_addr,&message_neighbors->address);
-                 olsr_insert_two_hop_neighbor_table(two_hop_neighbor);
-                 olsr_linking_this_2_entries(neighbor, two_hop_neighbor, (float)message->vtime);
-               }
-             else
-               {
+                  two_hop_neighbor->neighbor_2_nblist.next =
+                    &two_hop_neighbor->neighbor_2_nblist;
+
+                  two_hop_neighbor->neighbor_2_nblist.prev =
+                    &two_hop_neighbor->neighbor_2_nblist;
+
+                  two_hop_neighbor->neighbor_2_pointer = 0;
                  
-                 /*
-                   linking to this two_hop_neighbor entry
-                 */    
-                 changes_neighborhood = OLSR_TRUE;
-                 changes_topology = OLSR_TRUE;
+                  COPY_IP(&two_hop_neighbor->neighbor_2_addr,
+                          &message_neighbors->address);
+
+                  olsr_insert_two_hop_neighbor_table(two_hop_neighbor);
+
+                  olsr_linking_this_2_entries(neighbor, two_hop_neighbor,
+                                              (float)message->vtime);
+                }
+              else
+                {
+                  /*
+                    linking to this two_hop_neighbor entry
+                  */   
+                  changes_neighborhood = OLSR_TRUE;
+                  changes_topology = OLSR_TRUE;
                  
-                 olsr_linking_this_2_entries(neighbor, two_hop_neighbor, (float)message->vtime); 
-               }
-           }
-       }
-      
+                  olsr_linking_this_2_entries(neighbor, two_hop_neighbor,
+                                              (float)message->vtime); 
+                }
+            }
+#if defined USE_LINK_QUALITY
+          // loop through the one-hop neighbors that see this
+          // two hop neighbour
+
+          for (walker = two_hop_neighbor->neighbor_2_nblist.next;
+               walker != &two_hop_neighbor->neighbor_2_nblist;
+               walker = walker->next)
+            {
+              // have we found the one-hop neighbor that sent the
+              // HELLO message that we're current processing?
+
+              if (walker->neighbor == neighbor)
+                {
+                  // total link quality = link quality between us
+                  // and our one-hop neighbor x link quality between
+                  // our one-hop neighbor and the two-hop neighbor
+
+                  walker->full_link_quality =
+                    link_quality *
+                    message_neighbors->link_quality *
+                    message_neighbors->neigh_link_quality;
+                }
+            }
+#endif
+        }
     }
-
 }
 
 
@@ -559,6 +622,10 @@ olsr_linking_this_2_entries(struct neighbor_entry *neighbor,struct neighbor_2_en
 
   list_of_1_neighbors->neighbor = neighbor;
 
+#if defined USE_LINK_QUALITY
+  list_of_1_neighbors->full_link_quality = 0.0;
+#endif
+
   /* Queue */
   two_hop_neighbor->neighbor_2_nblist.next->prev = list_of_1_neighbors;
   list_of_1_neighbors->next = two_hop_neighbor->neighbor_2_nblist.next;
index 155d955..5467fcb 100644 (file)
@@ -19,7 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * 
  * 
- * $Id: process_package.h,v 1.8 2004/11/03 18:19:54 tlopatic Exp $
+ * $Id: process_package.h,v 1.9 2004/11/05 20:58:10 tlopatic Exp $
  *
  */
 
@@ -34,9 +34,17 @@ void
 olsr_init_package_process(void);
 
 void
+olsr_hello_tap(struct hello_message *message, struct interface *in_if,
+               union olsr_ip_addr *from_addr);
+
+void
 olsr_process_received_hello(union olsr_message *, struct interface *, union olsr_ip_addr *);
 
 void
+olsr_tc_tap(struct tc_message *message, struct interface *in_if,
+            union olsr_ip_addr *from_addr, union olsr_message *m);
+
+void
 olsr_process_received_tc(union olsr_message *, struct interface *, union olsr_ip_addr *);
 
 void
index 158b0c7..ba08ce1 100644 (file)
@@ -19,7 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * 
  * 
- * $Id: two_hop_neighbor_table.h,v 1.6 2004/10/09 22:32:47 kattemat Exp $
+ * $Id: two_hop_neighbor_table.h,v 1.7 2004/11/05 20:58:10 tlopatic Exp $
  *
  */
 
@@ -35,6 +35,9 @@
 struct neighbor_list_entry 
 {
   struct       neighbor_entry *neighbor;
+#if defined USE_LINK_QUALITY
+  double full_link_quality;
+#endif
   struct       neighbor_list_entry *next;
   struct       neighbor_list_entry *prev;
 };