Rime协议栈数据发送runicast_send
。
1. runicast_send
/* runicast_send(&c->c, receiver, MAX_TRANSMISSIONS); */
int runicast_send(struct runicast_conn *c, const rimeaddr_t *receiver, uint8_t max_retransmissions)
{
int ret; if (runicast_is_transmitting(c))
{
PRINTF( "%d.%d: runicast: already transmitting\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1] ); return(0);
}
packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 1);
packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, PACKETBUF_ATTR_PACKET_TYPE_DATA);
packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, c->sndnxt);
packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, 3);
c->max_rxmit = max_retransmissions;
c->rxmit = 0;
c->is_tx = 1;
RIMESTATS_ADD(reliabletx);
PRINTF("%d.%d: runicast: sending packet %d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], c->sndnxt);
ret = stunicast_send_stubborn(&c->c, receiver, REXMIT_TIME);
if (!ret)
{
c->is_tx = 0;
}
return(ret);
}
2. stunicast_send_stubborn
/* stunicast_send_stubborn(&c->c, receiver, REXMIT_TIME) */
int stunicast_send_stubborn(struct stunicast_conn *c, const rimeaddr_t *receiver, clock_time_t rxmittime)
{
if (c->buf != NULL)
{
queuebuf_free(c->buf);
}
c->buf = queuebuf_new_from_packetbuf(); if (c->buf == NULL)
{
return(0);
}
rimeaddr_copy(&c->receiver, receiver);
ctimer_set(&c->t, rxmittime, send, c);
PRINTF( "%d.%d: stunicast_send_stubborn to %d.%d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], c->receiver.u8[0], c->receiver.u8[1]);
unicast_send(&c->c, &c->receiver); /* if(c->u->sent != NULL) { c->u->sent(c); }*/
return(1);
}
3. unicast_send
int unicast_send(struct unicast_conn *c, const rimeaddr_t *receiver)
{
PRINTF("%d.%d: unicast_send to %d.%d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], receiver->u8[0], receiver->u8[1]);
packetbuf_set_addr( PACKETBUF_ADDR_RECEIVER, receiver);
return(broadcast_send(&c->c));
}
4. broadcast_send
4.1 broadcast_send
int broadcast_send(struct broadcast_conn *c)
{
PRINTF( "%d.%d: broadcast_send\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &rimeaddr_node_addr);
return(abc_send(&c->c));
}
4.2 abc_send
int abc_send( struct abc_conn *c )
{
PRINTF("%d.%d: abc: abc_send on channel %d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], c->channel.channelno);
return(rime_output(&c->channel));
}
4.3 rime_output
int rime_output(struct channel *c)
{
RIMESTATS_ADD(tx); if ( chameleon_create(c) )
{
packetbuf_compact();
NETSTACK_MAC.send(packet_sent, c); return(1);
}
return(0);
}
4.4 NETSTACK_MAC.send
#ifndef NETSTACK_MAC
#ifdef NETSTACK_CONF_MAC
#define NETSTACK_MAC NETSTACK_CONF_MAC
#else
#define NETSTACK_MACnullmac_driver
#endif
#endif
#ifndef NETSTACK_CONF_MAC
#define NETSTACK_CONF_MAC csma_driver
#endif
const struct mac_driver csma_driver = { "CSMA", init, send_packet, input_packet, on, off, channel_check_interval, };
/** * The structure of a MAC protocol driver in Contiki. */
struct mac_driver {
char *name;
/** Initialize the MAC driver */
void (* init)( void );
/** Send a packet from the Rime buffer */
void (* send)( mac_callback_t sent_callback, void *ptr );
/** Callback for getting notified of incoming packet. */
void (* input)( void );
/** Turn the MAC layer on. */
int (* on)( void );
/** Turn the MAC layer off. */
int (* off)( int keep_radio_on );
/** Returns the channel check interval, expressed in clock_time_t ticks. */
unsigned short (* channel_check_interval)( void );
};