ttcp.c File Reference

#include "lwip/opt.h"
#include "lwip/mem.h"
#include "lwip/raw.h"
#include "lwip/icmp.h"
#include "lwip/netif.h"
#include "lwip/sys.h"
#include "lwip/sockets.h"
#include "lwip/inet.h"
#include "lwip/inet_chksum.h"
#include "lwip/tcp.h"
#include "lwip/udp.h"
#include "ttcp.h"
#include "timer.h"
#include "util.h"
#include "getopt.h"

Go to the source code of this file.

Data Structures

struct  ttcp

Defines

#define TTCP_MODE_RECEIVE   1
#define TTCP_MODE_TRANSMIT   0

Typedefs

typedef void( ttcp_done_cb_t )(void *opaque, int result)

Functions

cmd_state_t cmd_ttcp (int argc, char *argv[], void *ctx)
static err_t tcp_accept_cb (void *arg, struct tcp_pcb *newpcb, err_t err)
 Only used in TCP mode.
static void tcp_conn_err_cb (void *arg, err_t err)
 Only used in TCP mode.
static err_t tcp_connect_cb (void *arg, struct tcp_pcb *tpcb, err_t err)
 Only used in TCP mode.
static err_t tcp_recv_cb (void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
 Only used in TCP mode.
static void tcp_send_data (struct ttcp *ttcp)
 Only used in TCP mode.
static int tcp_start (struct ttcp *ttcp)
 Start TCP transfer.
static void tcp_timeout_cb (void *ctx)
 Only used in TCP mode.
static void ttcp_destroy (struct ttcp *ttcp)
 Clean up and free the ttcp structure.
static void ttcp_done (struct ttcp *ttcp, int result)
 Invoked when transfer is done or aborted (non-zero result).
static void ttcp_print_stats (struct ttcp *ttcp)
 Calculate bitrate based on number of bytes transmitted and elapsed time.
int ttcp_start (struct ip_addr addr, uint16_t port, void *opaque, ttcp_done_cb_t *done_cb, int mode, uint16_t nbuf, uint16_t buflen, int udp, int verbose)
 Start a new ttcp transfer.
static void udp_recv_cb (void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port)
 Only used in UDP mode.
static int udp_send_bytes (struct ttcp *ttcp, uint32_t len)
static void udp_send_data (struct ttcp *ttcp)
 Only used in UDP mode.
static int udp_start (struct ttcp *ttcp)
 Start UDP transfer.
static void udp_timeout_cb (void *ctx)
 Only used in UDP mode.

Variables

char usage []


Define Documentation

#define TTCP_MODE_RECEIVE   1

Definition at line 52 of file ttcp.c.

Referenced by cmd_ttcp(), and ttcp_start().

#define TTCP_MODE_TRANSMIT   0

Definition at line 51 of file ttcp.c.

Referenced by cmd_ttcp(), tcp_start(), ttcp_print_stats(), ttcp_start(), and udp_start().


Typedef Documentation

typedef void( ttcp_done_cb_t)(void *opaque, int result)

Definition at line 54 of file ttcp.c.


Function Documentation

cmd_state_t cmd_ttcp ( int  argc,
char *  argv[],
void *  ctx 
)

Definition at line 599 of file ttcp.c.

References ttcp::buflen, CMD_DONE, ttcp::mode, ttcp::nbuf, ttcp::port, printk(), str2ip(), TTCP_MODE_RECEIVE, TTCP_MODE_TRANSMIT, ttcp_start(), ttcp::udp, and ttcp::verbose.

Referenced by wl_init_complete_cb().

00600 {       
00601         
00602         int c;
00603         int mode = TTCP_MODE_TRANSMIT;
00604         int verbose = 0;
00605         uint16_t buflen = 1024;
00606         uint16_t nbuf = 1024;
00607         uint16_t port = 2000;
00608         int udp = 0;
00609         struct ip_addr addr = { 0 };
00610 
00611         optind = 1;
00612         while ((c = getopt(argc, argv, "utrl:n:p:v")) != -1) {
00613                 switch (c) {
00614                 case 't':
00615                         mode = TTCP_MODE_TRANSMIT;
00616                         break;
00617                 case 'r':
00618                         mode = TTCP_MODE_RECEIVE;
00619                         break;
00620                 case 'l':
00621                         buflen = atoi(optarg);
00622                         break;
00623                 case 'v':
00624                         verbose = 1;
00625                         break;
00626                 case 'n':
00627                         nbuf = atoi(optarg);
00628                         break;
00629                 case 'u':
00630                         udp = 1;
00631                         break;
00632                 case 'p':
00633                         port = atoi(optarg);
00634                         break;
00635                 }
00636         }
00637 
00638         if (mode == TTCP_MODE_TRANSMIT) {
00639                 if (optind >= argc) {
00640                         printk("%s", usage);
00641                         return CMD_DONE;
00642                 }
00643 
00644                 addr = str2ip(argv[optind]);
00645                 if (!addr.addr) {
00646                         printk("%s", usage);
00647                         return CMD_DONE;
00648                 }
00649         }
00650          
00651         if (ttcp_start(addr, port, NULL, NULL, mode, nbuf, buflen, udp,
00652                        verbose))
00653                 return CMD_DONE;
00654          
00655         return CMD_DONE;
00656 }

static err_t tcp_accept_cb ( void *  arg,
struct tcp_pcb *  newpcb,
err_t  err 
) [static]

Only used in TCP mode.

Definition at line 321 of file ttcp.c.

References printk(), ttcp::start_time, tcp_conn_err_cb(), tcp_recv_cb(), timer_get_ms(), and ttcp::tpcb.

Referenced by tcp_start().

00322 {
00323         struct ttcp* ttcp = arg;
00324 
00325         ttcp->tpcb = newpcb;
00326         tcp_recv(ttcp->tpcb, tcp_recv_cb);
00327         tcp_err(ttcp->tpcb, tcp_conn_err_cb);
00328   
00329         printk("TTCP [%p]: accept\n", ttcp);                
00330         ttcp->start_time = timer_get_ms();
00331         return ERR_OK;
00332 }

static void tcp_conn_err_cb ( void *  arg,
err_t  err 
) [static]

Only used in TCP mode.

Definition at line 277 of file ttcp.c.

References printk(), ttcp::tpcb, and ttcp_done().

Referenced by tcp_accept_cb(), and tcp_start().

00278 {
00279         struct ttcp* ttcp = arg;
00280 
00281         printk("TTCP [%p]: connection error\n", ttcp);
00282         
00283         ttcp->tpcb = NULL; /* free'd by lwip upon return */
00284         ttcp_done(ttcp, err);
00285 }

static err_t tcp_connect_cb ( void *  arg,
struct tcp_pcb *  tpcb,
err_t  err 
) [static]

Only used in TCP mode.

Definition at line 258 of file ttcp.c.

References printk(), ttcp::start_time, tcp_send_data(), and timer_get_ms().

Referenced by tcp_start().

00259 {
00260         struct ttcp* ttcp = arg;
00261 
00262         printk("TTCP [%p]: connect\n", ttcp);
00263 
00264         ttcp->start_time = timer_get_ms();
00265 #if 0
00266         tcp_sent(tpcb, tcp_sent_cb);
00267 #endif
00268         tcp_send_data(ttcp);
00269         return ERR_OK;
00270 }

static err_t tcp_recv_cb ( void *  arg,
struct tcp_pcb *  pcb,
struct pbuf *  p,
err_t  err 
) [static]

Only used in TCP mode.

Definition at line 292 of file ttcp.c.

References ttcp::print_cnt, printk(), ttcp::recved, ttcp_done(), and ttcp::verbose.

Referenced by tcp_accept_cb(), and tcp_start().

00293 {
00294         struct ttcp* ttcp = arg;
00295         
00296         /* p will be NULL when remote end is done */
00297         if (p == NULL) {
00298                 ttcp_done(ttcp, 0);
00299                 return ERR_OK;
00300         }
00301 
00302         /* for print_stats() */
00303         ttcp->recved += p->tot_len;
00304         if (ttcp->verbose) {
00305                 printk(".");
00306                 if (ttcp->print_cnt % 80 == 0)
00307                         printk("\n");
00308                 ttcp->print_cnt++;
00309         }
00310         
00311         tcp_recved(pcb, p->tot_len);
00312         pbuf_free(p);
00313         return ERR_OK;
00314 }

static void tcp_send_data ( struct ttcp ttcp  )  [static]

Only used in TCP mode.

Will transmit a maximum of pbuf->tot_len bytes. Called upon connect and when there's space available in the TCP send window

Definition at line 165 of file ttcp.c.

References ttcp::buflen, ttcp::left, ttcp::payload, printk(), tcp_timeout_cb(), ttcp::tid, TIMEOUT_ONESHOT, timer_sched_timeout_cb(), and ttcp::tpcb.

Referenced by tcp_connect_cb(), and tcp_timeout_cb().

00166 {
00167         err_t err;
00168         uint32_t len;
00169         
00170     len = ttcp->left;
00171 
00172         /* don't send more than we have in the payload */
00173         if (len > ttcp->buflen)
00174                 len = ttcp->buflen;
00175 
00176         /* We cannot send more data than space available in the send
00177            buffer. */
00178         if (len > tcp_sndbuf(ttcp->tpcb))
00179                 len = tcp_sndbuf(ttcp->tpcb);
00180 
00181         do {
00182                 err = tcp_write(ttcp->tpcb, ttcp->payload, len, 0);
00183                 if (err == ERR_MEM)
00184                         len /= 2;
00185          } while (err == ERR_MEM && len > 1);  
00186 
00187         
00188         if (err == ERR_OK)
00189                 ttcp->left -= len;
00190         else
00191                 printk("TTCP [%p]: tcp_write failed\n", ttcp);
00192 
00193         ttcp->tid = timer_sched_timeout_cb(0, TIMEOUT_ONESHOT,
00194                                            tcp_timeout_cb, ttcp);
00195 }

static int tcp_start ( struct ttcp ttcp  )  [static]

Start TCP transfer.

Definition at line 341 of file ttcp.c.

References ttcp::addr, ttcp::buflen, ttcp::lpcb, ttcp::mode, ttcp::payload, ttcp::port, printk(), tcp_accept_cb(), tcp_conn_err_cb(), tcp_connect_cb(), tcp_recv_cb(), ttcp::tpcb, and TTCP_MODE_TRANSMIT.

Referenced by ttcp_start().

00342 {
00343         ttcp->tpcb = tcp_new();
00344         if (ttcp->tpcb == NULL) {
00345                 printk("TTCP [%p]: could not allocate pcb\n", ttcp);
00346                 return -1;
00347         }
00348 
00349         ttcp->payload = malloc(ttcp->buflen);
00350         if (ttcp->payload == NULL) {
00351                 printk("TTCP [%p]: could not allocate payload\n", ttcp);
00352                 return -1;
00353         }
00354         
00355         tcp_arg(ttcp->tpcb,  ttcp);
00356 
00357         if (ttcp->mode == TTCP_MODE_TRANSMIT) {
00358                 tcp_err(ttcp->tpcb,  tcp_conn_err_cb);
00359                 tcp_recv(ttcp->tpcb, tcp_recv_cb);
00360                 if (tcp_connect(ttcp->tpcb, &ttcp->addr, ttcp->port, 
00361                                 tcp_connect_cb) != ERR_OK) {
00362                         printk("TTCP [%p]: tcp connect failed\n", ttcp);
00363                         return -1;
00364                 }
00365 
00366         } else {
00367                 tcp_bind(ttcp->tpcb, IP_ADDR_ANY, ttcp->port);
00368                 ttcp->lpcb = tcp_listen(ttcp->tpcb);
00369                 if (ttcp->lpcb == NULL) {
00370                         printk("TTCP [%p]: listen failed\n", ttcp);
00371                         return -1;
00372                 }
00373                 tcp_accept(ttcp->lpcb, tcp_accept_cb);
00374         }
00375         
00376         return 0;
00377 }

static void tcp_timeout_cb ( void *  ctx  )  [static]

Only used in TCP mode.

Scheduled by tcp_send_data(). tcp_sent() is not used for performance reasons.

Definition at line 203 of file ttcp.c.

References ttcp::left, ttcp::print_cnt, printk(), tcp_send_data(), ttcp::tid, TIMEOUT_ONESHOT, timer_sched_timeout_cb(), ttcp::tpcb, ttcp_done(), and ttcp::verbose.

Referenced by tcp_send_data().

00204 {
00205         struct ttcp *ttcp = ctx;
00206 
00207         if (ttcp->left > 0) {
00208                 tcp_send_data(ttcp);
00209                 if (ttcp->verbose) {
00210                         printk(".");
00211                         if (ttcp->print_cnt % 80 == 0)
00212                                 printk("\n");
00213                         ttcp->print_cnt++;
00214                 }
00215                 return;
00216         }
00217 
00218         /* all sent - empty queue */
00219         if (ttcp->tpcb->snd_queuelen)
00220                 ttcp->tid = timer_sched_timeout_cb(0, TIMEOUT_ONESHOT,
00221                                                    tcp_timeout_cb, ttcp);
00222         else
00223                 ttcp_done(ttcp, 0);        
00224 }

static void ttcp_destroy ( struct ttcp ttcp  )  [static]

Clean up and free the ttcp structure.

Definition at line 112 of file ttcp.c.

References ttcp::lpcb, ttcp::payload, ttcp::tpcb, and ttcp::upcb.

Referenced by ttcp_done(), and ttcp_start().

00113 {
00114         if (ttcp->tpcb) {
00115                 tcp_arg(ttcp->tpcb, NULL);
00116                 tcp_sent(ttcp->tpcb, NULL);
00117                 tcp_recv(ttcp->tpcb, NULL);
00118                 tcp_err(ttcp->tpcb, NULL);
00119                 tcp_close(ttcp->tpcb);
00120         }
00121 
00122         if (ttcp->lpcb) {
00123                 tcp_arg(ttcp->lpcb, NULL);
00124                 tcp_accept(ttcp->lpcb, NULL);
00125                 tcp_close(ttcp->lpcb);
00126         }
00127 
00128         if (ttcp->upcb) {
00129                 udp_disconnect(ttcp->upcb);
00130                 udp_remove(ttcp->upcb);
00131         }
00132 
00133         if (ttcp->payload)
00134                 free(ttcp->payload);
00135         
00136         free(ttcp);
00137 }

static void ttcp_done ( struct ttcp ttcp,
int  result 
) [static]

Invoked when transfer is done or aborted (non-zero result).

Definition at line 144 of file ttcp.c.

References ttcp::done_cb, ttcp::opaque, ttcp_destroy(), and ttcp_print_stats().

Referenced by tcp_conn_err_cb(), tcp_recv_cb(), tcp_timeout_cb(), udp_recv_cb(), and udp_send_data().

00145 {
00146         if (result == 0)
00147                 ttcp_print_stats(ttcp);
00148 
00149         if (ttcp->done_cb)
00150                 ttcp->done_cb(ttcp->opaque, result);
00151 
00152         ttcp_destroy(ttcp);
00153 }

static void ttcp_print_stats ( struct ttcp ttcp  )  [static]

Calculate bitrate based on number of bytes transmitted and elapsed time.

Definition at line 93 of file ttcp.c.

References ttcp::buflen, ttcp::mode, ttcp::nbuf, printk(), ttcp::recved, ttcp::start_time, timer_get_ms(), TTCP_MODE_TRANSMIT, ttcp::udp, and ttcp::verbose.

Referenced by ttcp_done().

00094 {
00095         uint32_t ms = timer_get_ms() - ttcp->start_time;
00096         uint32_t bytes = ttcp->mode == TTCP_MODE_TRANSMIT ? 
00097                 ttcp->nbuf * ttcp->buflen : ttcp->recved;
00098 
00099         if (ttcp->verbose)
00100                 printk("\n");
00101         
00102         printk("TTCP [%p]: %d bytes processed, %d.%d KB/s (%s/%s)\n",
00103                ttcp, bytes, bytes / ms, bytes % ms, ttcp->udp ? "udp" : "tcp",
00104                ttcp->mode == TTCP_MODE_TRANSMIT ? "tx" : "rx");
00105 }

int ttcp_start ( struct ip_addr  addr,
uint16_t  port,
void *  opaque,
ttcp_done_cb_t done_cb,
int  mode,
uint16_t  nbuf,
uint16_t  buflen,
int  udp,
int  verbose 
)

Start a new ttcp transfer.

It should be possible to call this function multiple times in order to get multiple ttcp streams. done_cb() will be invoked upon completion.

Definition at line 529 of file ttcp.c.

References ttcp::addr, ttcp::buflen, ttcp::done_cb, ttcp::left, ttcp::mode, ttcp::nbuf, ttcp::opaque, ttcp::port, printk(), tcp_start(), ttcp_destroy(), TTCP_MODE_RECEIVE, TTCP_MODE_TRANSMIT, ttcp::udp, udp_start(), and ttcp::verbose.

Referenced by cmd_ttcp().

00532 {
00533         struct ttcp* ttcp;
00534         int status;
00535         
00536         if (mode != TTCP_MODE_TRANSMIT && mode != TTCP_MODE_RECEIVE) {
00537                 printk("TTCP [-]: invalid mode\n");
00538                 return -1;
00539         }
00540 
00541         if (nbuf == 0) {
00542                 printk("TTCP [-]: invalid nbuf\n");
00543                 return -1;
00544         }
00545         
00546         if (buflen == 0) {
00547                 printk("TTCP [-]: invalid buflen\n");
00548                 return -1;
00549         }
00550 
00551         ttcp = calloc(1, sizeof(struct ttcp));
00552         if (ttcp == NULL) {
00553                 printk("TTCP [-]: could not allocate memory for ttcp\n");
00554                 return -1;
00555         }
00556 
00557         ttcp->addr = addr;
00558         ttcp->port = port;
00559         ttcp->nbuf = nbuf;
00560         ttcp->mode = mode;
00561         ttcp->left = nbuf * buflen;
00562         ttcp->done_cb = done_cb;
00563         ttcp->opaque = opaque;
00564         ttcp->udp = udp;
00565         ttcp->verbose = verbose;
00566         ttcp->buflen = buflen;
00567         
00568         printk("TTCP [%p]: nbuf=%d, buflen=%d, port=%d (%s/%s)\n",
00569                ttcp, ttcp->nbuf, ttcp->buflen, ttcp->port,
00570                ttcp->udp ? "udp" : "tcp",
00571                ttcp->mode == TTCP_MODE_TRANSMIT ? "tx" : "rx");
00572 
00573         if (ttcp->udp)
00574                 status = udp_start(ttcp);
00575         else
00576                 status = tcp_start(ttcp);
00577 
00578         if (status)
00579                 goto fail;
00580 
00581         return 0;
00582 
00583 fail:
00584         ttcp_destroy(ttcp);
00585         return -1;
00586 }

static void udp_recv_cb ( void *  arg,
struct udp_pcb *  upcb,
struct pbuf *  p,
struct ip_addr *  addr,
u16_t  port 
) [static]

Only used in UDP mode.

Will finalize the ttcp process when an end marker is seen.

Definition at line 458 of file ttcp.c.

References ttcp::print_cnt, printk(), ttcp::recved, ttcp::start_time, timer_get_ms(), ttcp_done(), ttcp::udp_started, and ttcp::verbose.

Referenced by udp_start().

00460 {
00461         struct ttcp* ttcp = arg;
00462 
00463         /* got start marker? we might lose this so if we get it just reset
00464      * the timer
00465      */
00466         if (!ttcp->udp_started && p->tot_len <= 4) {
00467                 ttcp->start_time = timer_get_ms();
00468         ttcp->udp_started = 1;
00469         goto out;
00470     }
00471 
00472         /* after receiving at least 1 byte, check end marker 
00473      * don't check udp_started since we might have lost the start marker
00474      */
00475         if (ttcp->recved && p->tot_len <= 4) {
00476                 ttcp_done(ttcp, 0);
00477                 goto out;
00478         }
00479 
00480         /* for print_stats() */
00481         ttcp->recved += p->tot_len;
00482         if (ttcp->verbose) {
00483                 printk(".");
00484                 if (ttcp->print_cnt % 80 == 0)
00485                         printk("\n");
00486                 ttcp->print_cnt++;
00487         }
00488 
00489 out:        
00490         pbuf_free(p);
00491 }

static int udp_send_bytes ( struct ttcp ttcp,
uint32_t  len 
) [static]

Definition at line 395 of file ttcp.c.

References printk(), and ttcp::upcb.

Referenced by udp_send_data().

00396 {
00397         struct pbuf* p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
00398         if (p == NULL) {
00399                 printk("TTCP [%p]: could not allocate pbuf\n", ttcp);
00400                 return -1;
00401         }
00402 
00403         if (udp_send(ttcp->upcb, p) != ERR_OK) {
00404                 printk("TTCP [%p]: udp_send() failed\n", ttcp);
00405                 pbuf_free(p);
00406                 return -1;
00407         }
00408 
00409         pbuf_free(p);        
00410         return 0;
00411 }

static void udp_send_data ( struct ttcp ttcp  )  [static]

Only used in UDP mode.

First call will send the start marker. When all ttcp data has been sent, a number of end markers will be sent. After end marker transmission, this function will complete the ttcp process.

Definition at line 419 of file ttcp.c.

References ttcp::buflen, ttcp::left, ttcp::start_time, ttcp::tid, TIMEOUT_ONESHOT, timer_get_ms(), timer_sched_timeout_cb(), ttcp_done(), ttcp::udp_end_marker_left, udp_send_bytes(), ttcp::udp_started, and udp_timeout_cb().

Referenced by udp_start(), and udp_timeout_cb().

00420 {
00421         /* send start marker first time */
00422         if (!ttcp->udp_started) {
00423                 if (udp_send_bytes(ttcp, 4) == 0) {
00424                         ttcp->udp_started = 1;
00425                         ttcp->start_time = timer_get_ms();
00426                 }
00427         } 
00428 
00429         /* normal case */
00430         else if (ttcp->left) {
00431                 /* send data */
00432                 if (udp_send_bytes(ttcp, ttcp->buflen) == 0)
00433                         ttcp->left -= ttcp->buflen;
00434         }
00435 
00436         /* end marker? */
00437         else if (ttcp->left == 0 && ttcp->udp_end_marker_left) {
00438                 if (udp_send_bytes(ttcp, 4) == 0)
00439                         ttcp->udp_end_marker_left--;
00440         }
00441 
00442         /* all end markers sent */
00443         else if (ttcp->left == 0) {
00444                 ttcp_done(ttcp, 0);
00445                 return;
00446         }
00447 
00448         ttcp->tid = timer_sched_timeout_cb(0, TIMEOUT_ONESHOT,
00449                                            udp_timeout_cb, ttcp);
00450 }

static int udp_start ( struct ttcp ttcp  )  [static]

Start UDP transfer.

Definition at line 498 of file ttcp.c.

References ttcp::addr, ttcp::mode, ttcp::port, printk(), TTCP_MODE_TRANSMIT, ttcp::udp_end_marker_left, udp_recv_cb(), udp_send_data(), and ttcp::upcb.

Referenced by ttcp_start().

00499 {
00500     ttcp->udp_end_marker_left = 5;
00501         ttcp->upcb = udp_new();
00502         if (ttcp->upcb == NULL) {
00503                 printk("TTCP [%p]: could not allocate pcb\n", ttcp);
00504                 return -1;
00505         }
00506 
00507         if (ttcp->mode == TTCP_MODE_TRANSMIT) {
00508                 if (udp_connect(ttcp->upcb, &ttcp->addr, ttcp->port) != 
00509                     ERR_OK) {
00510                         printk("TTCP [%p]: udp connect failed\n", ttcp);
00511                         return -1;
00512                 }
00513                 udp_send_data(ttcp);
00514         } else {
00515                 udp_recv(ttcp->upcb, udp_recv_cb, ttcp);
00516         }
00517 
00518         return 0;
00519 }

static void udp_timeout_cb ( void *  ctx  )  [static]

Only used in UDP mode.

Scheduled after data has been sent in udp_send_data() if we have more data to send.

Definition at line 387 of file ttcp.c.

References udp_send_data().

Referenced by udp_send_data().

00388 {
00389         struct ttcp* ttcp = ctx;
00390         udp_send_data(ttcp);
00391 }


Variable Documentation

char usage[]

Initial value:

 "Usage: ttcp -t/-r [-options] host\n\
        -l      length of bufs written to network (default 1024)\n\
        -n      number of bufs written to network (default 1024)\n\
        -p      port number to send to (default 2000)\n\
        -u      udp\n\
        -v      verbose\n"

Definition at line 588 of file ttcp.c.


Generated on Fri Feb 19 02:24:09 2010 for AVR32 - H&D by  doxygen 1.5.5