Define internal port bindings with section linking tricks

This commit is contained in:
Jeremy Lakeman 2016-03-07 15:48:23 +10:30
parent 3cacf63eaa
commit 231ab257e4
13 changed files with 56 additions and 110 deletions

View File

@ -1787,7 +1787,8 @@ static int keyring_process_challenge(keyring_file *k, struct subscriber *subscri
return 0; return 0;
} }
int keyring_mapping_request(struct internal_mdp_header *header, struct overlay_buffer *payload) DEFINE_BINDING(MDP_PORT_KEYMAPREQUEST, keyring_mapping_request);
static int keyring_mapping_request(struct internal_mdp_header *header, struct overlay_buffer *payload)
{ {
/* The authcryption of the MDP frame proves that the SAS key is owned by the /* The authcryption of the MDP frame proves that the SAS key is owned by the

View File

@ -119,7 +119,6 @@ unsigned char *keyring_get_nm_bytes(const sid_t *known_sidp, const sid_t *unknow
struct internal_mdp_header; struct internal_mdp_header;
struct overlay_buffer; struct overlay_buffer;
int keyring_mapping_request(struct internal_mdp_header *header, struct overlay_buffer *payload);
int keyring_send_unlock(struct subscriber *subscriber); int keyring_send_unlock(struct subscriber *subscriber);
int keyring_release_subscriber(keyring_file *k, const sid_t *sid); int keyring_release_subscriber(keyring_file *k, const sid_t *sid);

View File

@ -147,8 +147,8 @@ struct network_destination *load_subscriber_address(struct subscriber *subscribe
} }
/* Collection of unicast echo responses to detect working links */ /* Collection of unicast echo responses to detect working links */
int DEFINE_BINDING(MDP_PORT_PROBE, overlay_mdp_service_probe);
overlay_mdp_service_probe(struct internal_mdp_header *header, struct overlay_buffer *payload) static int overlay_mdp_service_probe(struct internal_mdp_header *header, struct overlay_buffer *payload)
{ {
IN(); IN();
if (header->source_port!=MDP_PORT_ECHO){ if (header->source_port!=MDP_PORT_ECHO){
@ -230,7 +230,8 @@ static void overlay_append_unicast_address(struct subscriber *subscriber, struct
} }
} }
int overlay_mdp_service_stun_req(struct internal_mdp_header *header, struct overlay_buffer *payload) DEFINE_BINDING(MDP_PORT_STUNREQ, overlay_mdp_service_stun_req);
static int overlay_mdp_service_stun_req(struct internal_mdp_header *header, struct overlay_buffer *payload)
{ {
DEBUGF(overlayrouting, "Processing STUN request from %s", alloca_tohex_sid_t(header->source->sid)); DEBUGF(overlayrouting, "Processing STUN request from %s", alloca_tohex_sid_t(header->source->sid));
@ -268,7 +269,8 @@ int overlay_mdp_service_stun_req(struct internal_mdp_header *header, struct over
return 0; return 0;
} }
int overlay_mdp_service_stun(struct internal_mdp_header *header, struct overlay_buffer *payload) DEFINE_BINDING(MDP_PORT_STUN, overlay_mdp_service_stun);
static int overlay_mdp_service_stun(struct internal_mdp_header *header, struct overlay_buffer *payload)
{ {
DEBUGF(overlayrouting, "Processing STUN info from %s", alloca_tohex_sid_t(header->source->sid)); DEBUGF(overlayrouting, "Processing STUN info from %s", alloca_tohex_sid_t(header->source->sid));

View File

@ -239,7 +239,6 @@ struct mdp_binding{
struct subscriber *subscriber; struct subscriber *subscriber;
mdp_port_t port; mdp_port_t port;
int version; int version;
int (*internal)(struct internal_mdp_header *header, struct overlay_buffer *payload);
struct socket_address client; struct socket_address client;
time_ms_t binding_time; time_ms_t binding_time;
}; };
@ -376,57 +375,6 @@ static int overlay_mdp_process_bind_request(struct subscriber *subscriber, mdp_p
return 0; return 0;
} }
int mdp_bind_internal(struct subscriber *subscriber, mdp_port_t port,
int (*internal)(struct internal_mdp_header *header, struct overlay_buffer *payload))
{
int i;
struct mdp_binding *free_slot=NULL;
if (!mdp_bindings_initialised) {
/* Mark all slots as unused */
int i;
for(i=0;i<MDP_MAX_BINDINGS;i++)
mdp_bindings[i].port=0;
mdp_bindings_initialised=1;
}
for(i=0;i<MDP_MAX_BINDINGS;i++) {
if ((!free_slot) && mdp_bindings[i].port==0)
free_slot=&mdp_bindings[i];
if (mdp_bindings[i].port == port
&& mdp_bindings[i].subscriber == subscriber)
return WHYF("Internal binding for port %d failed, port already in use", port);
}
if (!free_slot)
return WHYF("Internal binding for port %d failed, no free slots", port);
free_slot->subscriber=subscriber;
free_slot->port=port;
free_slot->version=1;
free_slot->internal=internal;
free_slot->binding_time=gettime_ms();
return 0;
}
int mdp_unbind_internal(struct subscriber *subscriber, mdp_port_t port,
int (*internal)(struct internal_mdp_header *header, struct overlay_buffer *payload))
{
int i;
for(i=0;i<MDP_MAX_BINDINGS;i++) {
if (mdp_bindings[i].port == port
&& mdp_bindings[i].subscriber == subscriber
&& mdp_bindings[i].internal == internal){
mdp_bindings[i].port=0;
mdp_bindings[i].subscriber=NULL;
mdp_bindings[i].internal=NULL;
}
}
return 0;
}
static void overlay_mdp_decode_header(struct internal_mdp_header *header, struct overlay_buffer *buff) static void overlay_mdp_decode_header(struct internal_mdp_header *header, struct overlay_buffer *buff)
{ {
/* extract MDP port numbers */ /* extract MDP port numbers */
@ -646,9 +594,6 @@ static int overlay_saw_mdp_frame(
} }
case 1: case 1:
{ {
if (mdp_bindings[match].internal)
RETURN(mdp_bindings[match].internal(header, payload));
struct socket_address *client = &mdp_bindings[match].client; struct socket_address *client = &mdp_bindings[match].client;
struct mdp_header client_header; struct mdp_header client_header;
client_header.local.sid=header->destination?header->destination->sid:SID_BROADCAST; client_header.local.sid=header->destination?header->destination->sid:SID_BROADCAST;
@ -668,6 +613,14 @@ static int overlay_saw_mdp_frame(
} }
} }
} else { } else {
// look for a compile time defined internal binding
struct internal_binding *binding;
for (binding = SECTION_START(bindings); binding < SECTION_END(bindings); ++binding) {
if (binding->port == header->destination_port)
RETURN(binding->function(header, payload));
}
/* Unbound socket. We won't be sending ICMP style connection refused /* Unbound socket. We won't be sending ICMP style connection refused
messages, partly because they are a waste of bandwidth. */ messages, partly because they are a waste of bandwidth. */
RETURN(WHYF("Received packet for which no listening process exists (MDP ports: src=%d, dst=%d", RETURN(WHYF("Received packet for which no listening process exists (MDP ports: src=%d, dst=%d",
@ -1555,7 +1508,6 @@ static void mdp_process_packet(struct socket_address *client, struct mdp_header
case MDP_LISTEN: case MDP_LISTEN:
// double check that this binding belongs to this connection // double check that this binding belongs to this connection
if (!binding if (!binding
|| binding->internal
|| cmp_sockaddr(&binding->client, client)!=0){ || cmp_sockaddr(&binding->client, client)!=0){
WHYF("That port is not bound by you %s vs %s", WHYF("That port is not bound by you %s vs %s",
binding?alloca_socket_address(&binding->client):"(none)", binding?alloca_socket_address(&binding->client):"(none)",
@ -1590,7 +1542,6 @@ static void mdp_process_packet(struct socket_address *client, struct mdp_header
}else{ }else{
// double check that this binding belongs to this connection // double check that this binding belongs to this connection
if (!binding if (!binding
|| binding->internal
|| !internal_header.source || !internal_header.source
|| header->local.port == 0 || header->local.port == 0
|| cmp_sockaddr(&binding->client, client)!=0){ || cmp_sockaddr(&binding->client, client)!=0){
@ -1617,7 +1568,6 @@ static void mdp_process_packet(struct socket_address *client, struct mdp_header
// remove binding // remove binding
if (binding if (binding
&& !binding->internal
&& header->flags & MDP_FLAG_CLOSE && header->flags & MDP_FLAG_CLOSE
&& cmp_sockaddr(&binding->client, client)==0){ && cmp_sockaddr(&binding->client, client)==0){
DEBUGF(mdprequests, "Unbind MDP %s:%d from %s", DEBUGF(mdprequests, "Unbind MDP %s:%d from %s",

View File

@ -34,7 +34,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "dataformats.h" #include "dataformats.h"
#include "route_link.h" #include "route_link.h"
int rhizome_mdp_send_block(struct subscriber *dest, const rhizome_bid_t *bid, uint64_t version, uint64_t fileOffset, uint32_t bitmap, uint16_t blockLength) static int rhizome_mdp_send_block(struct subscriber *dest, const rhizome_bid_t *bid, uint64_t version, uint64_t fileOffset, uint32_t bitmap, uint16_t blockLength)
{ {
IN(); IN();
if (!is_rhizome_mdp_server_running()) if (!is_rhizome_mdp_server_running())
@ -116,7 +116,8 @@ int rhizome_mdp_send_block(struct subscriber *dest, const rhizome_bid_t *bid, ui
OUT(); OUT();
} }
int overlay_mdp_service_rhizomerequest(struct internal_mdp_header *header, struct overlay_buffer *payload) DEFINE_BINDING(MDP_PORT_RHIZOME_REQUEST, overlay_mdp_service_rhizomerequest);
static int overlay_mdp_service_rhizomerequest(struct internal_mdp_header *header, struct overlay_buffer *payload)
{ {
const rhizome_bid_t *bidp = (const rhizome_bid_t *) ob_get_bytes_ptr(payload, sizeof bidp->binary); const rhizome_bid_t *bidp = (const rhizome_bid_t *) ob_get_bytes_ptr(payload, sizeof bidp->binary);
// Note, was originally built using read_uint64 which has reverse byte order of ob_get_ui64 // Note, was originally built using read_uint64 which has reverse byte order of ob_get_ui64
@ -129,7 +130,8 @@ int overlay_mdp_service_rhizomerequest(struct internal_mdp_header *header, struc
return rhizome_mdp_send_block(header->source, bidp, version, fileOffset, bitmap, blockLength); return rhizome_mdp_send_block(header->source, bidp, version, fileOffset, bitmap, blockLength);
} }
int overlay_mdp_service_rhizomeresponse(struct internal_mdp_header *UNUSED(header), struct overlay_buffer *payload) DEFINE_BINDING(MDP_PORT_RHIZOME_RESPONSE, overlay_mdp_service_rhizomeresponse);
static int overlay_mdp_service_rhizomeresponse(struct internal_mdp_header *UNUSED(header), struct overlay_buffer *payload)
{ {
IN(); IN();
@ -170,7 +172,8 @@ int overlay_mdp_service_rhizomeresponse(struct internal_mdp_header *UNUSED(heade
OUT(); OUT();
} }
int overlay_mdp_service_dnalookup(struct internal_mdp_header *header, struct overlay_buffer *payload) DEFINE_BINDING(MDP_PORT_DNALOOKUP, overlay_mdp_service_dnalookup);
static int overlay_mdp_service_dnalookup(struct internal_mdp_header *header, struct overlay_buffer *payload)
{ {
IN(); IN();
keyring_iterator it; keyring_iterator it;
@ -230,7 +233,8 @@ int overlay_mdp_service_dnalookup(struct internal_mdp_header *header, struct ove
RETURN(0); RETURN(0);
} }
int overlay_mdp_service_echo(struct internal_mdp_header *header, struct overlay_buffer *payload) DEFINE_BINDING(MDP_PORT_ECHO, overlay_mdp_service_echo);
static int overlay_mdp_service_echo(struct internal_mdp_header *header, struct overlay_buffer *payload)
{ {
IN(); IN();
@ -265,6 +269,7 @@ int overlay_mdp_service_echo(struct internal_mdp_header *header, struct overlay_
* in situations where a routing protocol is in development. * in situations where a routing protocol is in development.
*/ */
DEFINE_BINDING(MDP_PORT_TRACE, overlay_mdp_service_trace);
static int overlay_mdp_service_trace(struct internal_mdp_header *header, struct overlay_buffer *payload){ static int overlay_mdp_service_trace(struct internal_mdp_header *header, struct overlay_buffer *payload){
IN(); IN();
struct overlay_buffer *next_payload = ob_new(); struct overlay_buffer *next_payload = ob_new();
@ -355,6 +360,7 @@ end:
RETURN(ret); RETURN(ret);
} }
DEFINE_BINDING(MDP_PORT_RHIZOME_MANIFEST_REQUEST, overlay_mdp_service_manifest_requests);
static int overlay_mdp_service_manifest_requests(struct internal_mdp_header *header, struct overlay_buffer *payload) static int overlay_mdp_service_manifest_requests(struct internal_mdp_header *header, struct overlay_buffer *payload)
{ {
while (ob_remaining(payload)) { while (ob_remaining(payload)) {
@ -375,19 +381,3 @@ static int overlay_mdp_service_manifest_requests(struct internal_mdp_header *hea
return 0; return 0;
} }
void overlay_mdp_bind_internal_services()
{
mdp_bind_internal(NULL, MDP_PORT_LINKSTATE, link_receive);
mdp_bind_internal(NULL, MDP_PORT_ECHO, overlay_mdp_service_echo);
mdp_bind_internal(NULL, MDP_PORT_RHIZOME_REQUEST, overlay_mdp_service_rhizomerequest);
mdp_bind_internal(NULL, MDP_PORT_RHIZOME_MANIFEST_REQUEST, overlay_mdp_service_manifest_requests);
mdp_bind_internal(NULL, MDP_PORT_RHIZOME_SYNC, overlay_mdp_service_rhizome_sync);
mdp_bind_internal(NULL, MDP_PORT_RHIZOME_RESPONSE, overlay_mdp_service_rhizomeresponse);
mdp_bind_internal(NULL, MDP_PORT_PROBE, overlay_mdp_service_probe);
mdp_bind_internal(NULL, MDP_PORT_STUNREQ, overlay_mdp_service_stun_req);
mdp_bind_internal(NULL, MDP_PORT_STUN, overlay_mdp_service_stun);
mdp_bind_internal(NULL, MDP_PORT_DNALOOKUP, overlay_mdp_service_dnalookup);
mdp_bind_internal(NULL, MDP_PORT_VOMP, vomp_mdp_received);
mdp_bind_internal(NULL, MDP_PORT_TRACE, overlay_mdp_service_trace);
mdp_bind_internal(NULL, MDP_PORT_KEYMAPREQUEST, keyring_mapping_request);
}

View File

@ -22,6 +22,7 @@
#include "overlay_address.h" #include "overlay_address.h"
#include "serval_types.h" #include "serval_types.h"
#include "section.h"
#define FRAME_NOT_SENT -1 #define FRAME_NOT_SENT -1
#define FRAME_DONT_SEND -2 #define FRAME_DONT_SEND -2
@ -126,4 +127,26 @@ int reload_mdp_packet_rules(void);
void frame_remove_destination(struct overlay_frame *frame, int i); void frame_remove_destination(struct overlay_frame *frame, int i);
void frame_add_destination(struct overlay_frame *frame, struct subscriber *next_hop, struct network_destination *dest); void frame_add_destination(struct overlay_frame *frame, struct subscriber *next_hop, struct network_destination *dest);
void mdp_init_response(const struct internal_mdp_header *in, struct internal_mdp_header *out);
void overlay_mdp_encode_ports(struct overlay_buffer *plaintext, mdp_port_t dst_port, mdp_port_t src_port);
int overlay_mdp_dnalookup_reply(struct subscriber *dest, mdp_port_t dest_port,
struct subscriber *resolved_sid, const char *uri, const char *did, const char *name);
int _overlay_send_frame(struct __sourceloc whence, struct internal_mdp_header *header, struct overlay_buffer *payload);
#define overlay_send_frame(H, P) _overlay_send_frame(__WHENCE__, H, P)
struct internal_binding{
mdp_port_t port;
int (*function)(struct internal_mdp_header *header, struct overlay_buffer *payload);
};
DECLARE_SECTION(struct internal_binding, bindings);
#define DEFINE_BINDING(PORT, FUNC) \
static int FUNC(struct internal_mdp_header *, struct overlay_buffer *);\
static struct internal_binding BIND ## FUNC IN_SECTION(bindings) = { \
.port = PORT, \
.function = FUNC, \
}
#endif //__SERVAL_DNA__OVERLAY_PACKET_H #endif //__SERVAL_DNA__OVERLAY_PACKET_H

View File

@ -945,7 +945,6 @@ int rhizome_cache_close();
int rhizome_database_filehash_from_id(const rhizome_bid_t *bidp, uint64_t version, rhizome_filehash_t *hashp); int rhizome_database_filehash_from_id(const rhizome_bid_t *bidp, uint64_t version, rhizome_filehash_t *hashp);
int overlay_mdp_service_rhizome_sync(struct internal_mdp_header *header, struct overlay_buffer *payload);
void rhizome_sync_status(); void rhizome_sync_status();
DECLARE_ALARM(rhizome_fetch_status); DECLARE_ALARM(rhizome_fetch_status);

View File

@ -515,7 +515,8 @@ void rhizome_sync_announce(struct sched_ent *alarm)
schedule(alarm); schedule(alarm);
} }
int overlay_mdp_service_rhizome_sync(struct internal_mdp_header *header, struct overlay_buffer *payload) DEFINE_BINDING(MDP_PORT_RHIZOME_SYNC, overlay_mdp_service_rhizome_sync);
static int overlay_mdp_service_rhizome_sync(struct internal_mdp_header *header, struct overlay_buffer *payload)
{ {
if (!config.rhizome.enable || !rhizome_db) if (!config.rhizome.enable || !rhizome_db)
return 0; return 0;

View File

@ -1339,7 +1339,8 @@ int link_received_packet(struct decode_context *context, int sender_seq, uint8_t
} }
// parse incoming link details // parse incoming link details
int link_receive(struct internal_mdp_header *header, struct overlay_buffer *payload) DEFINE_BINDING(MDP_PORT_LINKSTATE, link_receive);
static int link_receive(struct internal_mdp_header *header, struct overlay_buffer *payload)
{ {
IN(); IN();

View File

@ -41,7 +41,6 @@ int link_state_ack_soon(struct subscriber *subscriber);
int link_received_duplicate(struct decode_context *context, int payload_seq); int link_received_duplicate(struct decode_context *context, int payload_seq);
int link_received_packet(struct decode_context *context, int sender_seq, uint8_t unicast); int link_received_packet(struct decode_context *context, int sender_seq, uint8_t unicast);
int link_unicast_ack(struct subscriber *subscriber, struct overlay_interface *interface, struct socket_address *addr); int link_unicast_ack(struct subscriber *subscriber, struct overlay_interface *interface, struct socket_address *addr);
int link_receive(struct internal_mdp_header *header, struct overlay_buffer *payload);
void link_explained(struct subscriber *subscriber); void link_explained(struct subscriber *subscriber);
void link_interface_down(struct overlay_interface *interface); void link_interface_down(struct overlay_interface *interface);
int link_state_legacy_ack(struct overlay_frame *frame, time_ms_t now); int link_state_legacy_ack(struct overlay_frame *frame, time_ms_t now);

View File

@ -218,18 +218,6 @@ int rhizome_opendb();
int parseCommandLine(struct cli_context *context, const char *argv0, int argc, const char *const *argv); int parseCommandLine(struct cli_context *context, const char *argv0, int argc, const char *const *argv);
/* Server-side MDP functions */
void mdp_init_response(const struct internal_mdp_header *in, struct internal_mdp_header *out);
void overlay_mdp_encode_ports(struct overlay_buffer *plaintext, mdp_port_t dst_port, mdp_port_t src_port);
int overlay_mdp_dnalookup_reply(struct subscriber *dest, mdp_port_t dest_port,
struct subscriber *resolved_sid, const char *uri, const char *did, const char *name);
int _overlay_send_frame(struct __sourceloc whence, struct internal_mdp_header *header, struct overlay_buffer *payload);
#define overlay_send_frame(H, P) _overlay_send_frame(__WHENCE__, H, P)
int mdp_bind_internal(struct subscriber *subscriber, mdp_port_t port,
int (*internal)(struct internal_mdp_header *header, struct overlay_buffer *payload));
int mdp_unbind_internal(struct subscriber *subscriber, mdp_port_t port,
int (*internal)(struct internal_mdp_header *header, struct overlay_buffer *payload));
int allow_inbound_packet(const struct internal_mdp_header *header); int allow_inbound_packet(const struct internal_mdp_header *header);
int allow_outbound_packet(const struct internal_mdp_header *header); int allow_outbound_packet(const struct internal_mdp_header *header);
void load_mdp_packet_rules(const char *filename); void load_mdp_packet_rules(const char *filename);
@ -239,7 +227,6 @@ struct vomp_call_state;
void set_codec_flag(int codec, unsigned char *flags); void set_codec_flag(int codec, unsigned char *flags);
struct vomp_call_state *vomp_find_call_by_session(unsigned int session_token); struct vomp_call_state *vomp_find_call_by_session(unsigned int session_token);
int vomp_mdp_received(struct internal_mdp_header *header, struct overlay_buffer *payload);
int vomp_parse_dtmf_digit(char c); int vomp_parse_dtmf_digit(char c);
int vomp_dial(struct subscriber *local, struct subscriber *remote, const char *local_did, const char *remote_did); int vomp_dial(struct subscriber *local, struct subscriber *remote, const char *local_did, const char *remote_did);
int vomp_pickup(struct vomp_call_state *call); int vomp_pickup(struct vomp_call_state *call);
@ -276,7 +263,6 @@ extern uint16_t mdp_loopback_port;
int overlay_mdp_setup_sockets(); int overlay_mdp_setup_sockets();
int overlay_packetradio_setup_port(struct overlay_interface *interface); int overlay_packetradio_setup_port(struct overlay_interface *interface);
void overlay_mdp_bind_internal_services();
int overlay_send_probe(struct subscriber *peer, struct network_destination *destination, int queue); int overlay_send_probe(struct subscriber *peer, struct network_destination *destination, int queue);
int overlay_send_stun_request(struct subscriber *server, struct subscriber *request); int overlay_send_stun_request(struct subscriber *server, struct subscriber *request);
void rhizome_check_connections(struct sched_ent *alarm); void rhizome_check_connections(struct sched_ent *alarm);
@ -288,10 +274,6 @@ void monitor_poll(struct sched_ent *alarm);
void rhizome_fetch_poll(struct sched_ent *alarm); void rhizome_fetch_poll(struct sched_ent *alarm);
void rhizome_server_poll(struct sched_ent *alarm); void rhizome_server_poll(struct sched_ent *alarm);
int overlay_mdp_service_stun_req(struct internal_mdp_header *header, struct overlay_buffer *payload);
int overlay_mdp_service_stun(struct internal_mdp_header *header, struct overlay_buffer *payload);
int overlay_mdp_service_probe(struct internal_mdp_header *header, struct overlay_buffer *payload);
int olsr_init_socket(void); int olsr_init_socket(void);
int olsr_send(struct overlay_frame *frame); int olsr_send(struct overlay_frame *frame);

View File

@ -338,8 +338,6 @@ static int server_bind()
// Periodically check for server shut down // Periodically check for server shut down
RESCHEDULE(&ALARM_STRUCT(server_shutdown_check), now, TIME_MS_NEVER_WILL, now); RESCHEDULE(&ALARM_STRUCT(server_shutdown_check), now, TIME_MS_NEVER_WILL, now);
overlay_mdp_bind_internal_services();
olsr_init_socket(); olsr_init_socket();
/* Calculate (and possibly show) CPU usage stats periodically */ /* Calculate (and possibly show) CPU usage stats periodically */

3
vomp.c
View File

@ -865,7 +865,8 @@ static int vomp_extract_remote_codec_list(struct vomp_call_state *call, struct o
/* At this point we know the MDP frame is addressed to the VoMP port, but /* At this point we know the MDP frame is addressed to the VoMP port, but
we have not inspected the contents. As these frames are wire-format, we we have not inspected the contents. As these frames are wire-format, we
must pay attention to endianness. */ must pay attention to endianness. */
int vomp_mdp_received(struct internal_mdp_header *header, struct overlay_buffer *payload) DEFINE_BINDING(MDP_PORT_VOMP, vomp_mdp_received);
static int vomp_mdp_received(struct internal_mdp_header *header, struct overlay_buffer *payload)
{ {
time_ms_t now = gettime_ms(); time_ms_t now = gettime_ms();