/** * Add a TLV to a DLEP writer buffer * @param writer dlep writer * @param type TLV type * @param data pointer to TLV value * @param len length of value, can be 0 */ void dlep_writer_add_tlv(struct dlep_writer *writer, uint16_t type, const void *data, uint16_t len) { abuf_append_uint16(writer->out, htons(type)); abuf_append_uint16(writer->out, htons(len)); abuf_memcpy(writer->out, data, len); }
/** * Add a TLV to a DLEP writer buffer * @param writer dlep writer * @param type TLV type * @param data1 first part of TLV value * @param len1 length of first value * @param data2 second part of TLV value * @param len2 length of second value */ void dlep_writer_add_tlv2( struct dlep_writer *writer, uint16_t type, const void *data1, uint16_t len1, const void *data2, uint16_t len2) { abuf_append_uint16(writer->out, htons(type)); abuf_append_uint16(writer->out, htons(len1 + len2)); abuf_memcpy(writer->out, data1, len1); abuf_memcpy(writer->out, data2, len2); }
/** * Start to write a new DLEP signal/message into a buffer * @param writer dlep writer * @param signal_type signal/message type */ void dlep_writer_start_signal(struct dlep_writer *writer, uint16_t signal_type) { writer->signal_type = signal_type; writer->signal_start = abuf_getlen(writer->out); abuf_append_uint16(writer->out, htons(signal_type)); abuf_append_uint16(writer->out, 0); }
/** * Send a data packet through a packet socket. The transmission might not * be happen synchronously if the socket would block. * @param pktsocket pointer to packet socket * @param remote ip/address to send packet to * @param data pointer to data to be sent * @param length length of data * @return -1 if an error happened, 0 otherwise */ int oonf_packet_send(struct oonf_packet_socket *pktsocket, union netaddr_socket *remote, const void *data, size_t length) { int result; struct netaddr_str buf; if (abuf_getlen(&pktsocket->out) == 0) { /* no backlog of outgoing packets, try to send directly */ result = os_fd_sendto(&pktsocket->scheduler_entry.fd, data, length, remote, pktsocket->config.dont_route); if (result > 0) { /* successful */ OONF_DEBUG(LOG_PACKET, "Sent %d bytes to %s %s", result, netaddr_socket_to_string(&buf, remote), pktsocket->os_if != NULL ? pktsocket->os_if->name : ""); return 0; } if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK) { OONF_WARN(LOG_PACKET, "Cannot send UDP packet to %s: %s (%d)", netaddr_socket_to_string(&buf, remote), strerror(errno), errno); return -1; } } /* append destination */ abuf_memcpy(&pktsocket->out, remote, sizeof(*remote)); /* append data length */ abuf_append_uint16(&pktsocket->out, length); /* append data */ abuf_memcpy(&pktsocket->out, data, length); /* activate outgoing socket scheduler */ oonf_socket_set_write(&pktsocket->scheduler_entry, true); return 0; }