Skip to content

Commit e89e04c

Browse files
The process is polled when a udp packet is sent
The application can now use the tcpip_udp_sent_event to know when a udp packet has finished sending. The data for the event also contains the status code from the MAC layer.
1 parent 7143814 commit e89e04c

File tree

11 files changed

+174
-37
lines changed

11 files changed

+174
-37
lines changed

core/net/ip/tcpip.c

+24-8
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ extern struct uip_fallback_interface UIP_FALLBACK_INTERFACE;
7272
#include "rpl/rpl.h"
7373
#endif
7474

75+
process_event_t tcpip_udp_sent_event;
7576
process_event_t tcpip_event;
7677
#if UIP_CONF_ICMP6
7778
process_event_t tcpip_icmp6_event;
@@ -116,22 +117,22 @@ setup_appstate(uip_tcp_appstate_t* as, void* state)
116117
/* Called on IP packet output. */
117118
#if NETSTACK_CONF_WITH_IPV6
118119

119-
static uint8_t (* outputfunc)(const uip_lladdr_t *a);
120+
static uint8_t (*outputfunc)(const uip_lladdr_t *a, struct tcpip_sent *sent);
120121

121122
uint8_t
122-
tcpip_output(const uip_lladdr_t *a)
123+
tcpip_output_sent(const uip_lladdr_t *a, struct tcpip_sent *sent)
123124
{
124125
int ret;
125126
if(outputfunc != NULL) {
126-
ret = outputfunc(a);
127+
ret = outputfunc(a, sent);
127128
return ret;
128129
}
129130
UIP_LOG("tcpip_output: Use tcpip_set_outputfunc() to set an output function");
130131
return 0;
131132
}
132133

133134
void
134-
tcpip_set_outputfunc(uint8_t (*f)(const uip_lladdr_t *))
135+
tcpip_set_outputfunc(uint8_t (*f)(const uip_lladdr_t *, struct tcpip_sent *))
135136
{
136137
outputfunc = f;
137138
}
@@ -154,7 +155,19 @@ tcpip_set_outputfunc(uint8_t (*f)(void))
154155
outputfunc = f;
155156
}
156157
#endif
158+
/*---------------------------------------------------------------------------*/
159+
void
160+
tcpip_udp_sent(struct tcpip_sent *sent, int status)
161+
{
162+
struct uip_udp_conn *conn = sent->ptr;
163+
struct tcpip_udp_sent_status data;
164+
165+
data.conn = conn;
166+
data.status = status;
157167

168+
process_post_synch(conn->appstate.p, tcpip_udp_sent_event, &data);
169+
}
170+
/*---------------------------------------------------------------------------*/
158171
#if UIP_CONF_IP_FORWARD
159172
unsigned char tcpip_is_forwarding; /* Forwarding right now? */
160173
#endif /* UIP_CONF_IP_FORWARD */
@@ -526,7 +539,7 @@ tcpip_input(void)
526539
/*---------------------------------------------------------------------------*/
527540
#if NETSTACK_CONF_WITH_IPV6
528541
void
529-
tcpip_ipv6_output(void)
542+
tcpip_ipv6_output_sent(struct tcpip_sent *sent)
530543
{
531544
uip_ds6_nbr_t *nbr = NULL;
532545
uip_ipaddr_t *nexthop;
@@ -704,7 +717,7 @@ tcpip_ipv6_output(void)
704717
}
705718
#endif /* UIP_ND6_SEND_NA */
706719

707-
tcpip_output(uip_ds6_nbr_get_ll(nbr));
720+
tcpip_output_sent(uip_ds6_nbr_get_ll(nbr), sent);
708721

709722
#if UIP_CONF_IPV6_QUEUE_PKT
710723
/*
@@ -717,7 +730,7 @@ tcpip_ipv6_output(void)
717730
uip_len = uip_packetqueue_buflen(&nbr->packethandle);
718731
memcpy(UIP_IP_BUF, uip_packetqueue_buf(&nbr->packethandle), uip_len);
719732
uip_packetqueue_free(&nbr->packethandle);
720-
tcpip_output(uip_ds6_nbr_get_ll(nbr));
733+
tcpip_output_sent(uip_ds6_nbr_get_ll(nbr), sent);
721734
}
722735
#endif /*UIP_CONF_IPV6_QUEUE_PKT*/
723736

@@ -726,7 +739,7 @@ tcpip_ipv6_output(void)
726739
}
727740
}
728741
/* Multicast IP destination address. */
729-
tcpip_output(NULL);
742+
tcpip_output_sent(NULL, sent);
730743
uip_clear_buf();
731744
}
732745
#endif /* NETSTACK_CONF_WITH_IPV6 */
@@ -802,6 +815,9 @@ PROCESS_THREAD(tcpip_process, ev, data)
802815
#endif
803816

804817
tcpip_event = process_alloc_event();
818+
819+
tcpip_udp_sent_event = process_alloc_event();
820+
805821
#if UIP_CONF_ICMP6
806822
tcpip_icmp6_event = process_alloc_event();
807823
#endif /* UIP_CONF_ICMP6 */

core/net/ip/tcpip.h

+40-4
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,24 @@
7070
#include "contiki.h"
7171

7272
struct uip_conn;
73+
struct tcpip_sent {
74+
void (*callback)(struct tcpip_sent *, int);
75+
void *ptr;
76+
77+
enum {
78+
FRAG_TRACK_NONE,
79+
FRAG_TRACK_UNQUEUED,
80+
FRAG_TRACK_ALL_QUEUED,
81+
FRAG_TRACK_ERROR
82+
} frag_track;
83+
int frag_count_queued;
84+
int first_fail_status;
85+
};
86+
87+
struct tcpip_udp_sent_status {
88+
struct uip_udp_conn *conn;
89+
int status;
90+
};
7391

7492
struct tcpip_uipstate {
7593
struct process *p;
@@ -275,7 +293,7 @@ struct uip_udp_conn *udp_broadcast_new(uint16_t port, void *appstate);
275293
CCIF void tcpip_poll_udp(struct uip_udp_conn *conn);
276294

277295
/** @} */
278-
296+
279297
/**
280298
* \name ICMPv6 functions
281299
* @{
@@ -319,6 +337,14 @@ void tcpip_icmp6_call(uint8_t type);
319337
* This event is posted to a process whenever a uIP event has occurred.
320338
*/
321339
CCIF extern process_event_t tcpip_event;
340+
/** @} */
341+
/**
342+
* The udp sent event
343+
*
344+
* This event is posted to a process whenever a udp packet has finished sending
345+
* (possibly as a result of error).
346+
*/
347+
CCIF extern process_event_t tcpip_udp_sent_event;
322348

323349
/**
324350
* \name TCP/IP packet processing
@@ -341,8 +367,12 @@ CCIF void tcpip_input(void);
341367
* The eventual parameter is the MAC address of the destination.
342368
*/
343369
#if NETSTACK_CONF_WITH_IPV6
344-
uint8_t tcpip_output(const uip_lladdr_t *);
345-
void tcpip_set_outputfunc(uint8_t (* f)(const uip_lladdr_t *));
370+
#define tcpip_output(addr) tcpip_output_sent(addr, NULL)
371+
372+
uint8_t tcpip_output_sent(const uip_lladdr_t *, struct tcpip_sent *ptr);
373+
void tcpip_set_outputfunc(
374+
uint8_t (*f)(const uip_lladdr_t *, struct tcpip_sent *)
375+
);
346376
#else
347377
uint8_t tcpip_output(void);
348378
void tcpip_set_outputfunc(uint8_t (* f)(void));
@@ -352,9 +382,15 @@ void tcpip_set_outputfunc(uint8_t (* f)(void));
352382
* \brief This function does address resolution and then calls tcpip_output
353383
*/
354384
#if NETSTACK_CONF_WITH_IPV6
355-
void tcpip_ipv6_output(void);
385+
#define tcpip_ipv6_output() tcpip_ipv6_output_sent(NULL)
386+
void tcpip_ipv6_output_sent(struct tcpip_sent* sent);
356387
#endif
357388

389+
/**
390+
* \brief call after sending a udp packet, informs the application
391+
*/
392+
void tcpip_udp_sent(struct tcpip_sent *sent, int status);
393+
358394
/**
359395
* \brief Is forwarding generally enabled?
360396
*/

core/net/ip/uip-udp-packet.c

+20-3
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ extern uint16_t uip_slen;
4747
#include <string.h>
4848

4949
/*---------------------------------------------------------------------------*/
50-
void
51-
uip_udp_packet_send(struct uip_udp_conn *c, const void *data, int len)
50+
static void
51+
send(struct uip_udp_conn *c, const void *data, int len,struct tcpip_sent* sent)
5252
{
5353
#if UIP_UDP
5454
if(data != NULL) {
@@ -67,7 +67,7 @@ uip_udp_packet_send(struct uip_udp_conn *c, const void *data, int len)
6767
#endif /* UIP_IPV6_MULTICAST */
6868

6969
#if NETSTACK_CONF_WITH_IPV6
70-
tcpip_ipv6_output();
70+
tcpip_ipv6_output_sent(sent);
7171
#else
7272
if(uip_len > 0) {
7373
tcpip_output();
@@ -79,6 +79,12 @@ uip_udp_packet_send(struct uip_udp_conn *c, const void *data, int len)
7979
}
8080
/*---------------------------------------------------------------------------*/
8181
void
82+
uip_udp_packet_send(struct uip_udp_conn *c, const void *data, int len)
83+
{
84+
send(c, data, len, NULL);
85+
}
86+
/*---------------------------------------------------------------------------*/
87+
void
8288
uip_udp_packet_sendto(struct uip_udp_conn *c, const void *data, int len,
8389
const uip_ipaddr_t *toaddr, uint16_t toport)
8490
{
@@ -102,3 +108,14 @@ uip_udp_packet_sendto(struct uip_udp_conn *c, const void *data, int len,
102108
}
103109
}
104110
/*---------------------------------------------------------------------------*/
111+
void
112+
uip_udp_packet_send2(struct uip_udp_conn *c, const void *data, int len,
113+
struct tcpip_sent* sent)
114+
{
115+
sent->ptr = c;
116+
sent->callback = tcpip_udp_sent;
117+
sent->frag_track = FRAG_TRACK_NONE;
118+
119+
send(c, data, len, sent);
120+
}
121+
/*---------------------------------------------------------------------------*/

core/net/ip/uip-udp-packet.h

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242

4343
#include "net/ip/uip.h"
4444

45+
void uip_udp_packet_send2(struct uip_udp_conn *c, const void *data, int len,
46+
struct tcpip_sent* sent);
4547
void uip_udp_packet_send(struct uip_udp_conn *c, const void *data, int len);
4648
void uip_udp_packet_sendto(struct uip_udp_conn *c, const void *data, int len,
4749
const uip_ipaddr_t *toaddr, uint16_t toport);

core/net/ipv6/sicslowpan.c

+69-7
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,28 @@ struct sicslowpan_frag_buf {
283283
};
284284

285285
static struct sicslowpan_frag_buf frag_buf[SICSLOWPAN_FRAGMENT_BUFFERS];
286-
286+
/*---------------------------------------------------------------------------*/
287+
static void track_frag_start(struct tcpip_sent *sent)
288+
{
289+
if(sent) {
290+
sent->frag_track = FRAG_TRACK_UNQUEUED;
291+
sent->frag_count_queued = 0;
292+
}
293+
}
294+
/*---------------------------------------------------------------------------*/
295+
static void track_frag_queued(struct tcpip_sent *sent)
296+
{
297+
if(sent) {
298+
sent->frag_count_queued += 1;
299+
}
300+
}
301+
/*---------------------------------------------------------------------------*/
302+
static void track_frag_done(struct tcpip_sent *sent)
303+
{
304+
if(sent && (sent->frag_track != FRAG_TRACK_ERROR)) {
305+
sent->frag_track = FRAG_TRACK_ALL_QUEUED;
306+
}
307+
}
287308
/*---------------------------------------------------------------------------*/
288309
static int
289310
clear_fragments(uint8_t frag_info_index)
@@ -1228,16 +1249,50 @@ packet_sent(void *ptr, int status, int transmissions)
12281249
if(callback != NULL) {
12291250
callback->output_callback(status);
12301251
}
1252+
1253+
if(ptr) {
1254+
struct tcpip_sent *sent = ptr;
1255+
1256+
switch(sent->frag_track)
1257+
{
1258+
case FRAG_TRACK_NONE:
1259+
sent->callback(sent, status);
1260+
break;
1261+
case FRAG_TRACK_UNQUEUED:
1262+
sent->frag_count_queued -= 1;
1263+
if(status != MAC_TX_OK) {
1264+
sent->frag_track = FRAG_TRACK_ERROR;
1265+
}
1266+
break;
1267+
case FRAG_TRACK_ALL_QUEUED:
1268+
sent->frag_count_queued -= 1;
1269+
if(status != MAC_TX_OK) {
1270+
sent->frag_track = FRAG_TRACK_ERROR;
1271+
sent->first_fail_status = status;
1272+
} else if(sent->frag_count_queued == 0) {
1273+
sent->callback(sent, status);
1274+
}
1275+
break;
1276+
case FRAG_TRACK_ERROR:
1277+
sent->frag_count_queued -= 1;
1278+
if(sent->frag_count_queued == 0) {
1279+
sent->callback(sent, sent->first_fail_status);
1280+
}
1281+
break;
1282+
}
1283+
}
1284+
12311285
last_tx_status = status;
12321286
}
12331287
/*--------------------------------------------------------------------*/
12341288
/**
12351289
* \brief This function is called by the 6lowpan code to send out a
12361290
* packet.
12371291
* \param dest the link layer destination address of the packet
1292+
* \param sent data used for calling back into the application on tx done
12381293
*/
12391294
static void
1240-
send_packet(linkaddr_t *dest)
1295+
send_packet(linkaddr_t *dest,struct tcpip_sent *sent)
12411296
{
12421297
/* Set the link layer destination address for the packet as a
12431298
* packetbuf attribute. The MAC layer can access the destination
@@ -1252,7 +1307,7 @@ send_packet(linkaddr_t *dest)
12521307

12531308
/* Provide a callback function to receive the result of
12541309
a packet transmission. */
1255-
NETSTACK_LLSEC.send(&packet_sent, NULL);
1310+
NETSTACK_LLSEC.send(&packet_sent, sent);
12561311

12571312
/* If we are sending multiple packets in a row, we need to let the
12581313
watchdog know that we are still alive. */
@@ -1262,14 +1317,15 @@ send_packet(linkaddr_t *dest)
12621317
/** \brief Take an IP packet and format it to be sent on an 802.15.4
12631318
* network using 6lowpan.
12641319
* \param localdest The MAC address of the destination
1320+
* \param sent data used for calling back into the application on tx done
12651321
*
12661322
* The IP packet is initially in uip_buf. Its header is compressed
12671323
* and if necessary it is fragmented. The resulting
12681324
* packet/fragments are put in packetbuf and delivered to the 802.15.4
12691325
* MAC.
12701326
*/
12711327
static uint8_t
1272-
output(const uip_lladdr_t *localdest)
1328+
output(const uip_lladdr_t *localdest, struct tcpip_sent* sent)
12731329
{
12741330
int framer_hdrlen;
12751331
int max_payload;
@@ -1412,7 +1468,9 @@ output(const uip_lladdr_t *localdest)
14121468
PRINTFO("could not allocate queuebuf for first fragment, dropping packet\n");
14131469
return 0;
14141470
}
1415-
send_packet(&dest);
1471+
track_frag_start(sent);
1472+
track_frag_queued(sent);
1473+
send_packet(&dest, sent);
14161474
queuebuf_to_packetbuf(q);
14171475
queuebuf_free(q);
14181476
q = NULL;
@@ -1458,7 +1516,11 @@ output(const uip_lladdr_t *localdest)
14581516
PRINTFO("could not allocate queuebuf, dropping fragment\n");
14591517
return 0;
14601518
}
1461-
send_packet(&dest);
1519+
track_frag_queued(sent);
1520+
if((processed_ip_out_len + packetbuf_payload_len) >= uip_len) {
1521+
track_frag_done(sent);
1522+
}
1523+
send_packet(&dest, sent);
14621524
queuebuf_to_packetbuf(q);
14631525
queuebuf_free(q);
14641526
q = NULL;
@@ -1485,7 +1547,7 @@ output(const uip_lladdr_t *localdest)
14851547
memcpy(packetbuf_ptr + packetbuf_hdr_len, (uint8_t *)UIP_IP_BUF + uncomp_hdr_len,
14861548
uip_len - uncomp_hdr_len);
14871549
packetbuf_set_datalen(uip_len - uncomp_hdr_len + packetbuf_hdr_len);
1488-
send_packet(&dest);
1550+
send_packet(&dest, sent);
14891551
}
14901552
return 1;
14911553
}

cpu/native/net/tapdev6.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ static unsigned long lasttime;
9898
#endif
9999

100100
static void do_send(void);
101-
uint8_t tapdev_send(const uip_lladdr_t *lladdr);
101+
uint8_t tapdev_send(const uip_lladdr_t *lladdr, struct tcpip_sent *sent);
102102

103103
/*---------------------------------------------------------------------------*/
104104
int
@@ -375,7 +375,7 @@ do_send(void)
375375
}
376376
/*---------------------------------------------------------------------------*/
377377
uint8_t
378-
tapdev_send(const uip_lladdr_t *lladdr)
378+
tapdev_send(const uip_lladdr_t *lladdr, struct tcpip_sent *sent)
379379
{
380380
/*
381381
* If L3 dest is multicast, build L2 multicast address

0 commit comments

Comments
 (0)