@@ -286,7 +286,28 @@ struct sicslowpan_frag_buf {
286
286
};
287
287
288
288
static struct sicslowpan_frag_buf frag_buf [SICSLOWPAN_FRAGMENT_BUFFERS ];
289
-
289
+ /*---------------------------------------------------------------------------*/
290
+ static void track_frag_start (struct tcpip_track * track )
291
+ {
292
+ if (track ) {
293
+ track -> frag_track = FRAG_TRACK_UNQUEUED ;
294
+ track -> frag_count_queued = 0 ;
295
+ }
296
+ }
297
+ /*---------------------------------------------------------------------------*/
298
+ static void track_frag_queued (struct tcpip_track * track )
299
+ {
300
+ if (track ) {
301
+ track -> frag_count_queued += 1 ;
302
+ }
303
+ }
304
+ /*---------------------------------------------------------------------------*/
305
+ static void track_frag_done (struct tcpip_track * track )
306
+ {
307
+ if (track && (track -> frag_track != FRAG_TRACK_ERROR )) {
308
+ track -> frag_track = FRAG_TRACK_ALL_QUEUED ;
309
+ }
310
+ }
290
311
/*---------------------------------------------------------------------------*/
291
312
static int
292
313
clear_fragments (uint8_t frag_info_index )
@@ -1231,16 +1252,50 @@ packet_sent(void *ptr, int status, int transmissions)
1231
1252
if (callback != NULL ) {
1232
1253
callback -> output_callback (status );
1233
1254
}
1255
+
1256
+ if (ptr ) {
1257
+ struct tcpip_track * track = ptr ;
1258
+
1259
+ switch (track -> frag_track )
1260
+ {
1261
+ case FRAG_TRACK_NONE :
1262
+ track -> callback (track , status );
1263
+ break ;
1264
+ case FRAG_TRACK_UNQUEUED :
1265
+ track -> frag_count_queued -= 1 ;
1266
+ if (status != MAC_TX_OK ) {
1267
+ track -> frag_track = FRAG_TRACK_ERROR ;
1268
+ }
1269
+ break ;
1270
+ case FRAG_TRACK_ALL_QUEUED :
1271
+ track -> frag_count_queued -= 1 ;
1272
+ if (status != MAC_TX_OK ) {
1273
+ track -> frag_track = FRAG_TRACK_ERROR ;
1274
+ track -> first_fail_status = status ;
1275
+ } else if (track -> frag_count_queued == 0 ) {
1276
+ track -> callback (track , status );
1277
+ }
1278
+ break ;
1279
+ case FRAG_TRACK_ERROR :
1280
+ track -> frag_count_queued -= 1 ;
1281
+ if (track -> frag_count_queued == 0 ) {
1282
+ track -> callback (track , track -> first_fail_status );
1283
+ }
1284
+ break ;
1285
+ }
1286
+ }
1287
+
1234
1288
last_tx_status = status ;
1235
1289
}
1236
1290
/*--------------------------------------------------------------------*/
1237
1291
/**
1238
1292
* \brief This function is called by the 6lowpan code to send out a
1239
1293
* packet.
1240
1294
* \param dest the link layer destination address of the packet
1295
+ * \param track data used for calling back into the application on tx done
1241
1296
*/
1242
1297
static void
1243
- send_packet (linkaddr_t * dest )
1298
+ send_packet (linkaddr_t * dest , struct tcpip_track * track )
1244
1299
{
1245
1300
/* Set the link layer destination address for the packet as a
1246
1301
* packetbuf attribute. The MAC layer can access the destination
@@ -1255,7 +1310,7 @@ send_packet(linkaddr_t *dest)
1255
1310
1256
1311
/* Provide a callback function to receive the result of
1257
1312
a packet transmission. */
1258
- NETSTACK_LLSEC .send (& packet_sent , NULL );
1313
+ NETSTACK_LLSEC .send (& packet_sent , track );
1259
1314
1260
1315
/* If we are sending multiple packets in a row, we need to let the
1261
1316
watchdog know that we are still alive. */
@@ -1265,14 +1320,15 @@ send_packet(linkaddr_t *dest)
1265
1320
/** \brief Take an IP packet and format it to be sent on an 802.15.4
1266
1321
* network using 6lowpan.
1267
1322
* \param localdest The MAC address of the destination
1323
+ * \param track data used for calling back into the application on tx done
1268
1324
*
1269
1325
* The IP packet is initially in uip_buf. Its header is compressed
1270
1326
* and if necessary it is fragmented. The resulting
1271
1327
* packet/fragments are put in packetbuf and delivered to the 802.15.4
1272
1328
* MAC.
1273
1329
*/
1274
1330
static uint8_t
1275
- output (const uip_lladdr_t * localdest )
1331
+ output (const uip_lladdr_t * localdest , struct tcpip_track * track )
1276
1332
{
1277
1333
int framer_hdrlen ;
1278
1334
int max_payload ;
@@ -1409,7 +1465,9 @@ output(const uip_lladdr_t *localdest)
1409
1465
PRINTFO ("could not allocate queuebuf for first fragment, dropping packet\n" );
1410
1466
return 0 ;
1411
1467
}
1412
- send_packet (& dest );
1468
+ track_frag_start (track );
1469
+ track_frag_queued (track );
1470
+ send_packet (& dest , track );
1413
1471
queuebuf_to_packetbuf (q );
1414
1472
queuebuf_free (q );
1415
1473
q = NULL ;
@@ -1455,7 +1513,11 @@ output(const uip_lladdr_t *localdest)
1455
1513
PRINTFO ("could not allocate queuebuf, dropping fragment\n" );
1456
1514
return 0 ;
1457
1515
}
1458
- send_packet (& dest );
1516
+ track_frag_queued (track );
1517
+ if ((processed_ip_out_len + packetbuf_payload_len ) >= uip_len ) {
1518
+ track_frag_done (track );
1519
+ }
1520
+ send_packet (& dest , track );
1459
1521
queuebuf_to_packetbuf (q );
1460
1522
queuebuf_free (q );
1461
1523
q = NULL ;
@@ -1482,7 +1544,7 @@ output(const uip_lladdr_t *localdest)
1482
1544
memcpy (packetbuf_ptr + packetbuf_hdr_len , (uint8_t * )UIP_IP_BUF + uncomp_hdr_len ,
1483
1545
uip_len - uncomp_hdr_len );
1484
1546
packetbuf_set_datalen (uip_len - uncomp_hdr_len + packetbuf_hdr_len );
1485
- send_packet (& dest );
1547
+ send_packet (& dest , track );
1486
1548
}
1487
1549
return 1 ;
1488
1550
}
0 commit comments