olsr_reltime reltime_minimum_interval(void) { if (minimum_interval == UINT32_MAX) { minimum_interval = me_to_reltime(reltime_to_me(0)); } return minimum_interval; }
static bool serialize_hello6(struct hello_message *message, struct interface *ifp) { uint16_t remainsize, curr_size; struct hello_neighbor *nb; union olsr_message *m; struct hellomsg6 *h6; struct hellinfo6 *hinfo6; union olsr_ip_addr *haddr; int i, j; bool first_entry; if ((!message) || (!ifp) || (olsr_cnf->ip_version != AF_INET6)) return false; remainsize = net_outbuffer_bytes_left(ifp); m = (union olsr_message *)msg_buffer; curr_size = OLSR_HELLO_IPV6_HDRSIZE; /* OLSR message header */ /* Send pending packet if not room in buffer */ if (curr_size > remainsize) { net_output(ifp); remainsize = net_outbuffer_bytes_left(ifp); } check_buffspace(curr_size + olsr_cnf->ipsize + 4, remainsize, "HELLO"); h6 = &m->v6.message.hello; hinfo6 = h6->hell_info; haddr = (union olsr_ip_addr *)hinfo6->neigh_addr; /* Fill message header */ m->v6.ttl = message->ttl; m->v6.hopcnt = 0; /* Set source(main) addr */ m->v6.originator = olsr_cnf->main_addr.v6; m->v6.olsr_msgtype = HELLO_MESSAGE; m->v6.olsr_vtime = ifp->valtimes.hello; /* Fill packet header */ h6->willingness = message->willingness; h6->htime = reltime_to_me(ifp->hello_etime); memset(&h6->reserved, 0, sizeof(uint16_t)); /* *Loops trough all possible neighbor statuses *The negbor list is grouped by status */ for (i = 0; i <= MAX_NEIGH; i++) { for (j = 0; j <= MAX_LINK; j++) { #ifdef DEBUG struct ipaddr_str buf; #endif first_entry = true; /* *Looping trough neighbors */ for (nb = message->neighbors; nb != NULL; nb = nb->next) { if ((nb->status != i) || (nb->link != j)) continue; #ifdef DEBUG OLSR_PRINTF(BMSG_DBGLVL, "\t%s - ", olsr_ip_to_string(&buf, &nb->address)); OLSR_PRINTF(BMSG_DBGLVL, "L:%d N:%d\n", j, i); #endif /* * If there is not enough room left * for the data in the outputbuffer * we must send a partial HELLO and * continue building the rest of the * data in a new HELLO message * * If this is the first neighbor in * a group, we must check for an extra * 4 bytes */ if ((curr_size + olsr_cnf->ipsize + (first_entry ? 4 : 0)) > remainsize) { /* Only send partial HELLO if it contains data */ if (curr_size > OLSR_HELLO_IPV6_HDRSIZE) { #ifdef DEBUG OLSR_PRINTF(BMSG_DBGLVL, "Sending partial(size: %d, buff left:%d)\n", curr_size, remainsize); #endif /* Complete the headers */ m->v6.seqno = htons(get_msg_seqno()); m->v6.olsr_msgsize = htons(curr_size); hinfo6->size = (char *)haddr - (char *)hinfo6; hinfo6->size = htons(hinfo6->size); /* Send partial packet */ net_outbuffer_push(ifp, msg_buffer, curr_size); curr_size = OLSR_HELLO_IPV6_HDRSIZE; h6 = &m->v6.message.hello; hinfo6 = h6->hell_info; haddr = (union olsr_ip_addr *)hinfo6->neigh_addr; /* Make sure typeheader is added */ first_entry = true; } net_output(ifp); /* Reset size and pointers */ remainsize = net_outbuffer_bytes_left(ifp); check_buffspace(curr_size + olsr_cnf->ipsize + 4, remainsize, "HELLO2"); } if (first_entry) { memset(&hinfo6->reserved, 0, sizeof(uint8_t)); /* Set link and status for this group of neighbors (this is the first) */ hinfo6->link_code = CREATE_LINK_CODE(i, j); curr_size += 4; /* HELLO type section header */ } *haddr = nb->address; /* Point to next address */ haddr++; curr_size += olsr_cnf->ipsize; /* IP address added */ first_entry = false; } /* looping trough neighbors */ if (!first_entry) { hinfo6->size = htons((char *)haddr - (char *)hinfo6); hinfo6 = (struct hellinfo6 *)((char *)haddr); haddr = (union olsr_ip_addr *)&hinfo6->neigh_addr; } } /* for j */ } /* for i */ m->v6.seqno = htons(get_msg_seqno()); m->v6.olsr_msgsize = htons(curr_size); net_outbuffer_push(ifp, msg_buffer, curr_size); /* HELLO is always buildt */ return true; }
/** Convert a nmeaINFO structure into an OLSR message. @param nmeaInfo A pointer to a nmeaINFO structure @param olsrMessage A pointer to an OLSR message in which to place the converted information @param olsrMessageSize The maximum number of bytes available for the olsrMessage @param validityTime the validity time of the message in seconds @return - the aligned size of the converted information - 0 (zero) in case of an error */ unsigned int gpsToOlsr(nmeaINFO *nmeaInfo, union olsr_message *olsrMessage, unsigned int olsrMessageSize, unsigned long long validityTime) { unsigned int aligned_size; unsigned int aligned_size_remainder; size_t nodeLength; nodeIdBinaryType * nodeIdBinary = NULL; PudOlsrPositionUpdate * olsrGpsMessage = getOlsrMessagePayload(olsr_cnf->ip_version, olsrMessage); /* * Compose message contents */ memset(olsrGpsMessage, 0, sizeof (PudOlsrPositionUpdate)); setPositionUpdateVersion(olsrGpsMessage, PUD_WIRE_FORMAT_VERSION); setValidityTime(&olsrGpsMessage->validityTime, validityTime); setPositionUpdatePresent(olsrGpsMessage, nmeaInfo->present & ~PUD_PRESENT_GATEWAY); /* utc is always present, we make sure of that elsewhere, so just use it */ setPositionUpdateTime(olsrGpsMessage, nmeaInfo->utc.hour, nmeaInfo->utc.min, nmeaInfo->utc.sec); if (likely(nmea_INFO_is_present(nmeaInfo->present, LAT))) { setPositionUpdateLatitude(olsrGpsMessage, nmeaInfo->lat); } else { setPositionUpdateLatitude(olsrGpsMessage, 0.0); } if (likely(nmea_INFO_is_present(nmeaInfo->present, LON))) { setPositionUpdateLongitude(olsrGpsMessage, nmeaInfo->lon); } else { setPositionUpdateLongitude(olsrGpsMessage, 0.0); } if (likely(nmea_INFO_is_present(nmeaInfo->present, ELV))) { setPositionUpdateAltitude(olsrGpsMessage, nmeaInfo->elv); } else { setPositionUpdateAltitude(olsrGpsMessage, 0.0); } if (likely(nmea_INFO_is_present(nmeaInfo->present, SPEED))) { setPositionUpdateSpeed(olsrGpsMessage, nmeaInfo->speed); } else { setPositionUpdateSpeed(olsrGpsMessage, 0.0); } if (likely(nmea_INFO_is_present(nmeaInfo->present, TRACK))) { setPositionUpdateTrack(olsrGpsMessage, nmeaInfo->track); } else { setPositionUpdateTrack(olsrGpsMessage, 0); } if (likely(nmea_INFO_is_present(nmeaInfo->present, HDOP))) { setPositionUpdateHdop(olsrGpsMessage, nmeaInfo->HDOP); } else { setPositionUpdateHdop(olsrGpsMessage, PUD_HDOP_MAX); } nodeIdBinary = getNodeIdBinary(); nodeLength = setPositionUpdateNodeInfo(olsr_cnf->ip_version, olsrGpsMessage, olsrMessageSize, getNodeIdTypeNumber(), (unsigned char *) &nodeIdBinary->buffer, nodeIdBinary->length); /* * Messages in OLSR are 4-byte aligned: align */ /* size = type, string, string terminator */ aligned_size = PUD_OLSRWIREFORMATSIZE + nodeLength; aligned_size_remainder = (aligned_size % 4); if (aligned_size_remainder != 0) { aligned_size += (4 - aligned_size_remainder); } /* * Fill message headers (fill ALL fields, except message) * Note: olsr_vtime is currently unused, we use it for our validity time. */ if (olsr_cnf->ip_version == AF_INET) { /* IPv4 */ olsrMessage->v4.olsr_msgtype = PUD_OLSR_MSG_TYPE; olsrMessage->v4.olsr_vtime = reltime_to_me(validityTime * 1000); /* message->v4.olsr_msgsize at the end */ olsrMessage->v4.originator = olsr_cnf->main_addr.v4.s_addr; olsrMessage->v4.ttl = getOlsrTtl(); olsrMessage->v4.hopcnt = 0; olsrMessage->v4.seqno = htons(get_msg_seqno()); /* add length of message->v4 fields */ aligned_size += (sizeof(olsrMessage->v4) - sizeof(olsrMessage->v4.message)); olsrMessage->v4.olsr_msgsize = htons(aligned_size); } else { /* IPv6 */ olsrMessage->v6.olsr_msgtype = PUD_OLSR_MSG_TYPE; olsrMessage->v6.olsr_vtime = reltime_to_me(validityTime * 1000); /* message->v6.olsr_msgsize at the end */ olsrMessage->v6.originator = olsr_cnf->main_addr.v6; olsrMessage->v6.ttl = getOlsrTtl(); olsrMessage->v6.hopcnt = 0; olsrMessage->v6.seqno = htons(get_msg_seqno()); /* add length of message->v6 fields */ aligned_size += (sizeof(olsrMessage->v6) - sizeof(olsrMessage->v6.message)); olsrMessage->v6.olsr_msgsize = htons(aligned_size); } /* pad with zeroes */ if (aligned_size_remainder != 0) { memset(&(((char *) &olsrGpsMessage->nodeInfo.nodeIdType)[nodeLength]), 0, (4 - aligned_size_remainder)); } return aligned_size; }