neighbor-info.c
Go to the documentation of this file.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 #include "net/neighbor-info.h"
00041 #include "net/neighbor-attr.h"
00042
00043 #define DEBUG DEBUG_NONE
00044 #include "net/uip-debug.h"
00045
00046 #define ETX_LIMIT 15
00047 #define ETX_SCALE 100
00048 #define ETX_ALPHA 90
00049 #define ETX_NOACK_PENALTY ETX_LIMIT
00050
00051 NEIGHBOR_ATTRIBUTE(link_metric_t, etx, NULL);
00052
00053 static neighbor_info_subscriber_t subscriber_callback;
00054
00055 static void
00056 update_metric(const rimeaddr_t *dest, int packet_metric)
00057 {
00058 link_metric_t *metricp;
00059 link_metric_t recorded_metric, new_metric;
00060
00061 metricp = (link_metric_t *)neighbor_attr_get_data(&etx, dest);
00062 packet_metric = NEIGHBOR_INFO_ETX2FIX(packet_metric);
00063 if(metricp == NULL || *metricp == 0) {
00064 recorded_metric = NEIGHBOR_INFO_ETX2FIX(ETX_LIMIT);
00065 new_metric = packet_metric;
00066 } else {
00067 recorded_metric = *metricp;
00068
00069 new_metric = ((uint16_t)recorded_metric * ETX_ALPHA +
00070 (uint16_t)packet_metric * (ETX_SCALE - ETX_ALPHA)) / ETX_SCALE;
00071 }
00072
00073 PRINTF("neighbor-info: ETX changed from %d to %d (packet ETX = %d) %d\n",
00074 NEIGHBOR_INFO_FIX2ETX(recorded_metric),
00075 NEIGHBOR_INFO_FIX2ETX(new_metric),
00076 NEIGHBOR_INFO_FIX2ETX(packet_metric),
00077 dest->u8[7]);
00078
00079 if(neighbor_attr_has_neighbor(dest)) {
00080 neighbor_attr_set_data(&etx, dest, &new_metric);
00081 if(new_metric != recorded_metric && subscriber_callback != NULL) {
00082 subscriber_callback(dest, 1, new_metric);
00083 }
00084 }
00085 }
00086
00087 static void
00088 add_neighbor(const rimeaddr_t *addr)
00089 {
00090 switch(neighbor_attr_add_neighbor(addr)) {
00091 case -1:
00092 PRINTF("neighbor-info: failed to add a node.\n");
00093 break;
00094 case 0:
00095 PRINTF("neighbor-info: The neighbor is already known\n");
00096 break;
00097 default:
00098 break;
00099 }
00100 }
00101
00102 void
00103 neighbor_info_packet_sent(int status, int numtx)
00104 {
00105 const rimeaddr_t *dest;
00106 link_metric_t packet_metric;
00107
00108 dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
00109 if(rimeaddr_cmp(dest, &rimeaddr_null)) {
00110 return;
00111 }
00112
00113 PRINTF("neighbor-info: packet sent to %d.%d, status=%d, numtx=%d\n",
00114 dest->u8[sizeof(*dest) - 2], dest->u8[sizeof(*dest) - 1],
00115 status, numtx);
00116
00117 switch(status) {
00118 case MAC_TX_OK:
00119 packet_metric = numtx;
00120 add_neighbor(dest);
00121 break;
00122 case MAC_TX_COLLISION:
00123 packet_metric = numtx;
00124 break;
00125 case MAC_TX_NOACK:
00126 packet_metric = ETX_NOACK_PENALTY;
00127 break;
00128 default:
00129
00130
00131 return;
00132 }
00133
00134 update_metric(dest, packet_metric);
00135 }
00136
00137 void
00138 neighbor_info_packet_received(void)
00139 {
00140 const rimeaddr_t *src;
00141
00142 src = packetbuf_addr(PACKETBUF_ADDR_SENDER);
00143 if(rimeaddr_cmp(src, &rimeaddr_null)) {
00144 return;
00145 }
00146
00147 PRINTF("neighbor-info: packet received from %d.%d\n",
00148 src->u8[sizeof(*src) - 2], src->u8[sizeof(*src) - 1]);
00149
00150 add_neighbor(src);
00151 }
00152
00153 int
00154 neighbor_info_subscribe(neighbor_info_subscriber_t s)
00155 {
00156 if(subscriber_callback == NULL) {
00157 neighbor_attr_register(&etx);
00158 subscriber_callback = s;
00159 return 1;
00160 }
00161
00162 return 0;
00163 }
00164
00165 link_metric_t
00166 neighbor_info_get_metric(const rimeaddr_t *addr)
00167 {
00168 link_metric_t *metricp;
00169
00170 metricp = (link_metric_t *)neighbor_attr_get_data(&etx, addr);
00171 return metricp == NULL ? ETX_LIMIT : *metricp;
00172 }
00173