diff --git a/examples/nsh/nsh_fscmds.c b/examples/nsh/nsh_fscmds.c index f6049e67e0..43ef483a6f 100644 --- a/examples/nsh/nsh_fscmds.c +++ b/examples/nsh/nsh_fscmds.c @@ -852,6 +852,10 @@ int cmd_mkrd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) fmt = g_fmtcmdoutofmemory; goto errout_with_fmt; } + +#ifdef CONFIG_DEBUG_VERBOSE + memset(buffer, 0, sectsize * nsectors); +#endif dbg("RAMDISK at %p\n", buffer); /* Then register the ramdisk */ diff --git a/fs/fat/fs_fat32.c b/fs/fat/fs_fat32.c index f7942e548f..6c4f667431 100644 --- a/fs/fat/fs_fat32.c +++ b/fs/fat/fs_fat32.c @@ -289,7 +289,7 @@ static int fat_open(FAR struct file *filep, const char *relpath, ret = -ENOMEM; goto errout_with_semaphore; } - + /* Create a file buffer to support partial sector accesses */ ff->ff_buffer = (ubyte*)malloc(fs->fs_hwsectorsize); @@ -316,6 +316,8 @@ static int fat_open(FAR struct file *filep, const char *relpath, ((uint32)DIR_GETFSTCLUSTHI(dirinfo.fd_entry) << 16) | DIR_GETFSTCLUSTLO(dirinfo.fd_entry); + ff->ff_currentcluster = ff->ff_startcluster; + ff->ff_sectorsincluster = fs->fs_fatsecperclus; ff->ff_size = DIR_GETFILESIZE(dirinfo.fd_entry); /* Attach the private date to the struct file instance */ @@ -417,13 +419,13 @@ static ssize_t fat_read(FAR struct file *filep, char *buffer, size_t buflen) struct inode *inode; struct fat_mountpt_s *fs; struct fat_file_s *ff; - uint32 cluster; unsigned int bytesread; unsigned int readsize; unsigned int nsectors; - size_t readsector; size_t bytesleft; + sint32 cluster; ubyte *userbuffer = (ubyte*)buffer; + int sectorindex; int ret; /* Sanity checks */ @@ -468,81 +470,38 @@ static ssize_t fat_read(FAR struct file *filep, char *buffer, size_t buflen) buflen = bytesleft; } - /* Loop until either (1) all data has been transferred, or (2) an - * error occurs. - */ + /* Get the first sector to read from. */ - readsize = 0; - readsector = ff->ff_currentsector; - while (buflen > 0) + if (!ff->ff_currentsector) { - /* Get offset into the sector where we begin the read */ - - int sectorindex = filep->f_pos & SEC_NDXMASK(fs); - bytesread = 0; - - /* Check if the current read stream happens to lie on a - * sector boundary. + /* The current sector can be determined from the current cluster + * and the file offset. */ - if (sectorindex == 0) - { - /* Try to read another contiguous sector from the cluster */ + ff->ff_currentsector = fat_cluster2sector(fs, ff->ff_currentcluster) + + (SEC_NSECTORS(fs, filep->f_pos) & CLUS_NDXMASK(fs)); + fdbg("Start with sector: %d\n", ff->ff_currentsector); + } - ff->ff_sectorsincluster--; + /* Loop until either (1) all data has been transferred, or (2) an + * error occurs. We assume we start with the current sector + * (ff_currentsector) which may be uninitialized. + */ - /* Are there unread sectors remaining in the cluster? */ + readsize = 0; + sectorindex = filep->f_pos & SEC_NDXMASK(fs); - if (ff->ff_sectorsincluster > 0) - { - /* Yes.. There are more sectors in this cluster to be read - * just increment the current sector number and read. - */ - - readsector = ff->ff_currentsector + 1; - } - else - { - /* No.. Handle the case of the first sector of the file */ - - if (filep->f_pos == 0) - { - /* Get the first cluster of the file */ - - cluster = ff->ff_startcluster; - } - - /* But in the general case, we have to find the next cluster - * in the FAT. - */ - - else - { - cluster = fat_getcluster(fs, ff->ff_currentcluster); - } - - /* Verify the cluster number */ - - if (cluster < 2 || cluster >= fs->fs_nclusters) - { - ret = -EINVAL; /* Not the right error */ - goto errout_with_semaphore; - } - - /* Setup to read the first sector from the new cluster */ - - ff->ff_currentcluster = cluster; - ff->ff_sectorsincluster = fs->fs_fatsecperclus; - readsector = fat_cluster2sector(fs, cluster); - } - } + while (buflen > 0) + { + bytesread = 0; /* Check if the user has provided a buffer large enough to - * hold one or more complete sectors. + * hold one or more complete sectors -AND- the read is + * aligned to a sector boundary. */ nsectors = buflen / fs->fs_hwsectorsize; - if (nsectors > 0) + if (nsectors > 0 && sectorindex == 0) { /* Read maximum contiguous sectors directly to the user's * buffer without using our tiny read buffer. @@ -563,16 +522,16 @@ static ssize_t fat_read(FAR struct file *filep, char *buffer, size_t buflen) (void)fat_ffcacheinvalidate(fs, ff); - /* Read all of the sectors directory into user memory */ + /* Read all of the sectors directly into user memory */ - ret = fat_hwread(fs, userbuffer, readsector, nsectors); + ret = fat_hwread(fs, userbuffer, ff->ff_currentsector, nsectors); if (ret < 0) { goto errout_with_semaphore; } - ff->ff_sectorsincluster -= nsectors - 1; - ff->ff_currentsector = readsector + nsectors - 1; + ff->ff_sectorsincluster -= nsectors; + ff->ff_currentsector += nsectors; bytesread = nsectors * fs->fs_hwsectorsize; } else @@ -582,7 +541,7 @@ static ssize_t fat_read(FAR struct file *filep, char *buffer, size_t buflen) * it is already there then all is well. */ - ret = fat_ffcacheread(fs, ff, readsector); + ret = fat_ffcacheread(fs, ff, ff->ff_currentsector); if (ret < 0) { goto errout_with_semaphore; @@ -595,9 +554,13 @@ static ssize_t fat_read(FAR struct file *filep, char *buffer, size_t buflen) { bytesread = buflen; } + else + { + ff->ff_sectorsincluster--; + ff->ff_currentsector++; + } memcpy(userbuffer, &ff->ff_buffer[sectorindex], bytesread); - ff->ff_currentsector = readsector; } /* Set up for the next sector read */ @@ -606,6 +569,29 @@ static ssize_t fat_read(FAR struct file *filep, char *buffer, size_t buflen) filep->f_pos += bytesread; readsize += bytesread; buflen -= bytesread; + sectorindex = filep->f_pos & SEC_NDXMASK(fs); + + /* Check if the current read stream has incremented to the next + * cluster boundary + */ + + if (ff->ff_sectorsincluster < 1) + { + /* Find the next cluster in the FAT. */ + + cluster = fat_getcluster(fs, cluster); + if (cluster < 2 || cluster >= fs->fs_nclusters) + { + ret = -EINVAL; /* Not the right error */ + goto errout_with_semaphore; + } + + /* Setup to read the first sector from the new cluster */ + + ff->ff_currentcluster = cluster; + ff->ff_currentsector = fat_cluster2sector(fs, cluster); + ff->ff_sectorsincluster = fs->fs_fatsecperclus; + } } fat_semgive(fs); @@ -627,11 +613,11 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer, struct fat_mountpt_s *fs; struct fat_file_s *ff; sint32 cluster; - size_t writesector; unsigned int byteswritten; unsigned int writesize; unsigned int nsectors; ubyte *userbuffer = (ubyte*)buffer; + int sectorindex; int ret; /* Sanity checks */ @@ -671,96 +657,39 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer, goto errout_with_semaphore; } + /* Get the first sector to write to. */ + + if (!ff->ff_currentsector) + { + /* Has the starting cluster been defined? */ + + if (ff->ff_startcluster == 0) + { + /* No.. we have to create a new cluster chain */ + + ff->ff_startcluster = fat_createchain(fs); + ff->ff_currentcluster = ff->ff_startcluster; + ff->ff_sectorsincluster = fs->fs_fatsecperclus; + } + + /* The current sector can then be determined from the currentcluster + * and the file offset. + */ + + ff->ff_currentsector = fat_cluster2sector(fs, ff->ff_currentcluster) + + (SEC_NSECTORS(fs, filep->f_pos) & CLUS_NDXMASK(fs)); + } + /* Loop until either (1) all data has been transferred, or (2) an - * error occurs. + * error occurs. We assume we start with the current sector in + * cache (ff_currentsector) */ byteswritten = 0; - writesector = ff->ff_currentsector; + sectorindex = filep->f_pos & SEC_NDXMASK(fs); + while (buflen > 0) { - /* Get offset into the sector where we begin the read */ - - int sectorindex = filep->f_pos & SEC_NDXMASK(fs); - - /* Check if the current read stream happens to lie on a - * sector boundary. - */ - - if (sectorindex == 0) - { - /* Decrement the number of sectors left in this cluster */ - - ff->ff_sectorsincluster--; - - /* Are there unwritten sectors remaining in this cluster */ - - if (ff->ff_sectorsincluster > 0) - { - /* Yes.. There are more sectors in this cluster to be written. - * just increment the current sector number and write. - */ - - writesector = ff->ff_currentsector + 1; - } - else - { - /* No.. Handle the case of the first sector of the file */ - - if (filep->f_pos == 0) - { - /* Check the first cluster of the file. Zero means that - * the file is empty -- perhaps the file was truncated or - * created when it was opened - */ - - if (ff->ff_startcluster == 0) - { - /* In this case, we have to create a new cluster chain */ - - ff->ff_startcluster = fat_createchain(fs); - } - - /* Start writing at the first cluster of the file */ - - cluster = ff->ff_startcluster; - } - - /* But in the general case, we have to extend the current - * cluster by one (unless lseek was used to move the file - * position back from the end of the file) - */ - - else - { - /* Extend the chain by adding a new cluster after - * the last one - */ - - cluster = fat_extendchain(fs, ff->ff_currentcluster); - } - - /* Verify the cluster number */ - - if (cluster < 0) - { - ret = cluster; - goto errout_with_semaphore; - } - else if (cluster < 2 || cluster >= fs->fs_nclusters) - { - ret = -ENOSPC; - goto errout_with_semaphore; - } - - /* Setup to write the first sector from the new cluster */ - - ff->ff_currentcluster = cluster; - ff->ff_sectorsincluster = fs->fs_fatsecperclus; - writesector = fat_cluster2sector(fs, cluster); - } - } - /* Check if there is unwritten data in the file buffer */ ret = fat_ffcacheflush(fs, ff); @@ -795,16 +724,16 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer, (void)fat_ffcacheinvalidate(fs, ff); - /* Write all of the sectors directory from user memory */ + /* Write all of the sectors directly from user memory */ - ret = fat_hwwrite(fs, userbuffer, writesector, nsectors); + ret = fat_hwwrite(fs, userbuffer, ff->ff_currentsector, nsectors); if (ret < 0) { goto errout_with_semaphore; } - ff->ff_sectorsincluster -= nsectors - 1; - ff->ff_currentsector = writesector + nsectors - 1; + ff->ff_sectorsincluster -= nsectors; + ff->ff_currentsector += nsectors; writesize = nsectors * fs->fs_hwsectorsize; ff->ff_bflags |= FFBUFF_MODIFIED; } @@ -823,8 +752,7 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer, if (filep->f_pos < ff->ff_size || sectorindex != 0) { - ff->ff_currentsector = writesector; - ret = fat_ffcacheread(fs, ff, writesector); + ret = fat_ffcacheread(fs, ff, ff->ff_currentsector); if (ret < 0) { goto errout_with_semaphore; @@ -838,9 +766,13 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer, { writesize = buflen; } + else + { + ff->ff_sectorsincluster--; + ff->ff_currentsector++; + } memcpy(&ff->ff_buffer[sectorindex], userbuffer, writesize); - ff->ff_currentsector = writesector; ff->ff_bflags |= (FFBUFF_DIRTY|FFBUFF_VALID|FFBUFF_MODIFIED); } @@ -850,7 +782,40 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer, filep->f_pos += writesize; byteswritten += writesize; buflen -= writesize; - } + sectorindex = filep->f_pos & SEC_NDXMASK(fs); + + /* Check if the current read stream has incremented to the next + * cluster boundary + */ + + if (ff->ff_sectorsincluster < 1) + { + /* Extend the current cluster by one (unless lseek was used to + * move the file position back from the end of the file) + */ + + cluster = fat_extendchain(fs, ff->ff_currentcluster); + + /* Verify the cluster number */ + + if (cluster < 0) + { + ret = cluster; + goto errout_with_semaphore; + } + else if (cluster < 2 || cluster >= fs->fs_nclusters) + { + ret = -ENOSPC; + goto errout_with_semaphore; + } + + /* Setup to write the first sector from the new cluster */ + + ff->ff_currentcluster = cluster; + ff->ff_sectorsincluster = fs->fs_fatsecperclus; + ff->ff_currentsector = fat_cluster2sector(fs, cluster); + } + } /* The transfer has completed without error. Update the file size */ diff --git a/fs/fat/fs_fat32.h b/fs/fat/fs_fat32.h index 9cad293bb0..576e7ea84a 100644 --- a/fs/fat/fs_fat32.h +++ b/fs/fat/fs_fat32.h @@ -162,6 +162,8 @@ #define SEC_NDXMASK(f) ((f)->fs_hwsectorsize - 1) #define SEC_NSECTORS(f,n) ((n) / (f)->fs_hwsectorsize) +#define CLUS_NDXMASK(f) ((f)->fs_fatsecperclus -1) + /**************************************************************************** * File system types */ @@ -515,7 +517,8 @@ struct fat_file_s size_t ff_dirsector; /* Sector containing the directory entry */ off_t ff_size; /* Size of the file in bytes */ size_t ff_startcluster; /* Start cluster of file on media */ - size_t ff_currentsector; /* Current sector in the file buffer */ + size_t ff_currentsector; /* Current sector being operated on */ + size_t ff_cachesector; /* Current sector in the file buffer */ ubyte *ff_buffer; /* File buffer (for partial sector accesses) */ }; @@ -578,7 +581,7 @@ EXTERN int fat_hwwrite(struct fat_mountpt_s *fs, ubyte *buffer, /* Cluster / cluster chain access helpers */ -EXTERN ssize_t fat_cluster2sector(struct fat_mountpt_s *fs, uint32 cluster ); +EXTERN ssize_t fat_cluster2sector(struct fat_mountpt_s *fs, uint32 cluster); EXTERN ssize_t fat_getcluster(struct fat_mountpt_s *fs, uint32 clusterno); EXTERN int fat_putcluster(struct fat_mountpt_s *fs, uint32 clusterno, size_t startsector); diff --git a/fs/fat/fs_fat32util.c b/fs/fat/fs_fat32util.c index 637e4d1a3c..c70c4cb1e4 100644 --- a/fs/fat/fs_fat32util.c +++ b/fs/fat/fs_fat32util.c @@ -858,7 +858,7 @@ ssize_t fat_cluster2sector(struct fat_mountpt_s *fs, uint32 cluster ) /**************************************************************************** * Name: fat_getcluster * - * Desciption: Get the cluster start sector into the FAT. + * Desciption: Get the next cluster start from the FAT. * * Return: <0: error, 0:cluster unassigned, >=0: start sector of cluster * @@ -880,7 +880,7 @@ ssize_t fat_getcluster(struct fat_mountpt_s *fs, uint32 clusterno) { size_t fatsector; unsigned int fatoffset; - unsigned int startsector; + unsigned int cluster; unsigned int fatindex; /* FAT12 is more complex because it has 12-bits (1.5 bytes) @@ -895,13 +895,14 @@ ssize_t fat_getcluster(struct fat_mountpt_s *fs, uint32 clusterno) if (fat_fscacheread(fs, fatsector) < 0) { /* Read error */ + break; } /* Get the first, LS byte of the cluster from the FAT */ - fatindex = fatoffset & SEC_NDXMASK(fs); - startsector = fs->fs_buffer[fatindex]; + fatindex = fatoffset & SEC_NDXMASK(fs); + cluster = fs->fs_buffer[fatindex]; /* With FAT12, the second byte of the cluster number may lie in * a different sector than the first byte. @@ -916,6 +917,7 @@ ssize_t fat_getcluster(struct fat_mountpt_s *fs, uint32 clusterno) if (fat_fscacheread(fs, fatsector) < 0) { /* Read error */ + break; } } @@ -925,21 +927,23 @@ ssize_t fat_getcluster(struct fat_mountpt_s *fs, uint32 clusterno) * on the fact that the byte stream is little-endian. */ - startsector |= (unsigned int)fs->fs_buffer[fatindex] << 8; + cluster |= (unsigned int)fs->fs_buffer[fatindex] << 8; /* Now, pick out the correct 12 bit cluster start sector value */ if ((clusterno & 1) != 0) { /* Odd.. take the MS 12-bits */ - startsector >>= 4; + + cluster >>= 4; } else { /* Even.. take the LS 12-bits */ - startsector &= 0x0fff; + + cluster &= 0x0fff; } - return startsector; + return cluster; } case FSTYPE_FAT16 : @@ -967,7 +971,7 @@ ssize_t fat_getcluster(struct fat_mountpt_s *fs, uint32 clusterno) /* Read error */ break; } - return FAT_GETFAT16(fs->fs_buffer, fatindex) & 0x0fffffff; + return FAT_GETFAT32(fs->fs_buffer, fatindex) & 0x0fffffff; } default: break; @@ -2198,20 +2202,21 @@ int fat_ffcacheflush(struct fat_mountpt_s *fs, struct fat_file_s *ff) * contents of ff_buffer. */ - if (ff->ff_bflags && (FFBUFF_DIRTY|FFBUFF_VALID) == (FFBUFF_DIRTY|FFBUFF_VALID)) - { + if (ff->ff_cachesector && + ff->ff_bflags && (FFBUFF_DIRTY|FFBUFF_VALID) == (FFBUFF_DIRTY|FFBUFF_VALID)) + { /* Write the dirty sector */ - ret = fat_hwwrite(fs, ff->ff_buffer, ff->ff_currentsector, 1); + ret = fat_hwwrite(fs, ff->ff_buffer, ff->ff_cachesector, 1); if (ret < 0) - { + { return ret; - } + } - /* No longer dirty */ + /* No longer dirty, but still valid */ ff->ff_bflags &= ~FFBUFF_DIRTY; - } + } return OK; } @@ -2228,12 +2233,12 @@ int fat_ffcacheread(struct fat_mountpt_s *fs, struct fat_file_s *ff, size_t sect { int ret; - /* ff->ff_currentsector holds the current sector that is buffered in + /* ff->ff_cachesector holds the current sector that is buffered in * ff->ff_buffer. If the requested sector is the same as this sector, then * we do nothing. Otherwise, we will have to read the new sector. */ - if (ff->ff_currentsector != sector || (ff->ff_bflags & FFBUFF_VALID) == 0) + if (ff->ff_cachesector != sector || (ff->ff_bflags & FFBUFF_VALID) == 0) { /* We will need to read the new sector. First, flush the cached * sector if it is dirty. @@ -2255,7 +2260,7 @@ int fat_ffcacheread(struct fat_mountpt_s *fs, struct fat_file_s *ff, size_t sect /* Update the cached sector number */ - ff->ff_currentsector = sector; + ff->ff_cachesector = sector; ff->ff_bflags |= FFBUFF_VALID; } return OK; diff --git a/netutils/tftpc/tftpc_get.c b/netutils/tftpc/tftpc_get.c index 1471fb0a0a..abd34db21f 100644 --- a/netutils/tftpc/tftpc_get.c +++ b/netutils/tftpc/tftpc_get.c @@ -97,6 +97,7 @@ static inline ssize_t tftp_write(int fd, const ubyte *buf, size_t len) /* Handle partial writes */ + nvdbg("Wrote %d bytes to file\n", nbyteswritten); left -= nbyteswritten; buf += nbyteswritten; } @@ -186,22 +187,6 @@ int tftpget(const char *remote, const char *local, in_addr_t addr, boolean binar goto errout_with_fd; } - /* Send the read request using the well-known port number */ - - len = tftp_mkreqpacket(packet, TFTP_RRQ, remote, binary); - ret = tftp_sendto(sd, packet, len, &server); - if (ret != len) - { - goto errout_with_sd; - } - - /* Subsequent sendto will use the port number selected by the TFTP - * server. Setting the server port to zero indicates that we have - * not yet received the server port number. - */ - - server.sin_port = 0; - /* Then enter the transfer loop. Loop until the entire file has * been received or until an error occurs. */ @@ -219,6 +204,29 @@ int tftpget(const char *remote, const char *local, in_addr_t addr, boolean binar for (retry = 0; retry < TFTP_RETRIES; retry++) { + /* Send the read request using the well-known port number before + * receiving the first block. Each retry of the first block will + * re-send the request. + */ + + if (blockno == 1) + { + len = tftp_mkreqpacket(packet, TFTP_RRQ, remote, binary); + server.sin_port = HTONS(CONFIG_NETUTILS_TFTP_PORT); + ret = tftp_sendto(sd, packet, len, &server); + if (ret != len) + { + goto errout_with_sd; + } + + /* Subsequent sendto will use the port number selected by the TFTP + * server in the DATA packet. Setting the server port to zero + * here indicates that we have not yet received the server port number. + */ + + server.sin_port = 0; + } + /* Get the next packet from the server */ nbytesrecvd = tftp_recvfrom(sd, packet, TFTP_IOBUFSIZE, &from); @@ -284,6 +292,7 @@ int tftpget(const char *remote, const char *local, in_addr_t addr, boolean binar /* Write the received data chunk to the file */ ndatabytes = nbytesrecvd - TFTP_DATAHEADERSIZE; + tftp_dumpbuffer("Recvd DATA", packet + TFTP_DATAHEADERSIZE, ndatabytes); if (tftp_write(fd, packet + TFTP_DATAHEADERSIZE, ndatabytes) < 0) { goto errout_with_sd; diff --git a/netutils/tftpc/tftpc_internal.h b/netutils/tftpc/tftpc_internal.h index c7716f9036..57a0810225 100644 --- a/netutils/tftpc/tftpc_internal.h +++ b/netutils/tftpc/tftpc_internal.h @@ -69,6 +69,10 @@ # define CONFIG_NETUTILS_TFTP_TIMEOUT 10 /* One second */ #endif +/* Dump received buffers */ + +#undef CONFIG_NETUTILS_TFTP_DUMPBUFFERS + /* Sizes of TFTP messsage headers */ #define TFTP_ACKHEADERSIZE 4 @@ -153,4 +157,10 @@ extern int tftp_parseerrpacket(const ubyte *packet); extern ssize_t tftp_recvfrom(int sd, void *buf, size_t len, struct sockaddr_in *from); extern ssize_t tftp_sendto(int sd, const void *buf, size_t len, struct sockaddr_in *to); +#ifdef CONFIG_NETUTILS_TFTP_DUMPBUFFERS +extern void tftp_dumpbuffer(const char *msg, ubyte *buffer, int nbytes); +#else +# define tftp_dumpbuffer(msg, buffer, nbytes) +#endif + #endif /* __NETUTILS_TFTP_TFTPC_INTERNAL_H */ diff --git a/netutils/tftpc/tftpc_packets.c b/netutils/tftpc/tftpc_packets.c index 0e606da691..73e4bd1109 100644 --- a/netutils/tftpc/tftpc_packets.c +++ b/netutils/tftpc/tftpc_packets.c @@ -241,6 +241,12 @@ ssize_t tftp_recvfrom(int sd, void *buf, size_t len, struct sockaddr_in *from) for (;;) { + /* For debugging, it is helpful to start with a clean buffer */ + +#if defined(CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_NET) + memset(buf, 0, len); +#endif + /* Receive the packet */ addrlen = sizeof(struct sockaddr_in); @@ -320,4 +326,52 @@ ssize_t tftp_sendto(int sd, const void *buf, size_t len, struct sockaddr_in *to) } } +/**************************************************************************** + * Name: tftp_sendto + * + * Description: + * Dump a buffer of data + * + ****************************************************************************/ + +#ifdef CONFIG_NETUTILS_TFTP_DUMPBUFFERS +void tftp_dumpbuffer(const char *msg, ubyte *buffer, int nbytes) +{ +#ifdef CONFIG_DEBUG + char line[128]; + int ch; + int i; + int j; + + dbg("%s:\n", msg); + for (i = 0; i < nbytes; i += 16) + { + sprintf(line, "%04x: ", i); + + for ( j = 0; j < 16; j++) + { + if (i + j < nbytes) + { + sprintf(&line[strlen(line)], "%02x ", buffer[i+j] ); + } + else + { + strcpy(&line[strlen(line)], " "); + } + } + + for ( j = 0; j < 16; j++) + { + if (i + j < nbytes) + { + ch = buffer[i+j]; + sprintf(&line[strlen(line)], "%c", ch >= 0x20 && ch <= 0x7e ? ch : '.'); + } + } + dbg("%s\n", line); + } +#endif +} +#endif + #endif /* CONFIG_NET && CONFIG_NET_UDP && CONFIG_NFILE_DESCRIPTORS */