Added image construction and PDA crc.

This commit is contained in:
mark 2000-01-29 22:15:18 +00:00
parent 8fd24ebeee
commit 7d27d17666
1 changed files with 472 additions and 191 deletions

View File

@ -111,6 +111,8 @@
#define PDAFILE_LINE_MAX 1024
#define CHUNKS_MAX 100
/*================================================================*/
/* Local Macros */
@ -120,8 +122,8 @@
typedef struct s3datarec
{
UINT32 datalen;
UINT32 address;
UINT32 len;
UINT32 addr;
UINT8 checksum;
UINT8 *data;
} s3datarec_t;
@ -129,13 +131,13 @@ typedef struct s3datarec
typedef struct s3plugrec
{
UINT32 itemcode;
UINT32 address;
UINT32 addr;
UINT32 len;
} s3plugrec_t;
typedef struct s3crcrec
{
UINT32 address;
UINT32 addr;
UINT32 len;
UINT dowrite;
} s3crcrec_t;
@ -159,6 +161,14 @@ typedef struct pda
UINT nrec;
} pda_t;
typedef struct imgchunk
{
UINT32 addr; /* start address */
UINT32 len; /* in bytes */
UINT16 crc; /* CRC value (if it falls at a chunk boundary) */
UINT8 *data;
} imgchunk_t;
/*================================================================*/
/* Local Static Definitions */
@ -175,6 +185,7 @@ int opt_status = 0; /* -s => show status and exit */
int opt_verbose = 0; /* -v => boolean, verbose operation */
int opt_nowrite = 0; /* -n => boolean, process all data-but don't download */
int opt_debug = 0; /* -d => boolean, process all data-but don't download */
int opt_generate = 0; /* -g => boolean, if -s or -d output is in pdr and srec file format */
/* IMAGEFILE options */
@ -197,7 +208,7 @@ UINT8 macaddr[WLAN_ADDR_LEN]; /* -m mac address */
int opt_sernum = 0; /* -S => boolean for cmdline serial # */
char sernum[SERNUM_LEN_MAX+1]; /* -S serial # string */
char opts[] = "svVndr:f:a:p:m:S:";
char opts[] = "svVndgr:f:a:p:m:S:";
/*----------------------------------------------------------------*/
/* s-record image processing */
@ -221,26 +232,72 @@ s3inforec_t s3info[50];
/* S7 record (there _better_ be only one) */
UINT32 startaddr;
/* Load image chunks */
UINT nfchunks;
imgchunk_t fchunk[CHUNKS_MAX]; /* address of 0xffffffff indicates */
UINT nrchunks;
imgchunk_t rchunk[CHUNKS_MAX]; /* entry unused. */
/* Note that for the following pdrec_t arrays, the len and code */
/* fields are stored in HOST byte order. The makepdrlist() function */
/* fields are stored in HOST byte order. The mkpdrlist() function */
/* does the conversion. */
/*----------------------------------------------------------------*/
/* PDA, built from [card|newfile]+[addfile1+addfile2...] */
pda_t pda;
const UINT16 crc16tab[256] =
{
0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
};
/*================================================================*/
/* Local Function Declarations */
void usage(void);
int read_srecfile(char *fname);
int mkimage(imgchunk_t *clist, UINT *ccnt);
int read_pdrfile( char *fname, int isnew);
int read_cardpda(pda_t *pda, char *dev);
int read_filepda(pda_t *pda, char *pdrfname);
int makepdrlist( pda_t *pda);
int mkpdrlist( pda_t *pda);
int do_ioctl( p80211msg_t *msg );
void print_all_pdrs(pda_t *pda);
int str2macaddr( UINT8 *a, char *s );
int s3datarec_compare(const void *p1, const void *p2);
int mkpda_crc( pda_t *pda);
/*================================================================*/
/* Function Definitions */
@ -288,6 +345,11 @@ int main ( int argc, char **argv )
memset(s3info, 0, sizeof(s3info));
startaddr = 0;
nfchunks = 0;
memset( fchunk, sizeof(fchunk), 0);
nrchunks = 0;
memset( rchunk, sizeof(rchunk), 0);
/* clear the pda and add an initial END record */
memset(&pda, 0, sizeof(pda));
pda.rec[0] = (hfa384x_pdrec_t*)pda.buf;
@ -321,11 +383,17 @@ int main ( int argc, char **argv )
case 'd':
/* Process files, no card PDA, no download */
opt_debug = 1;
opt_verbose = 1;
break;
case 's':
/* Show status */
opt_status = 1;
break;
case 'g':
/* File generate */
opt_generate = 1;
break;
case 'r':
/* Ram image filename, add to list */
if ( opt_ramloadcnt >= RAMFILES_MAX ) {
@ -405,7 +473,7 @@ int main ( int argc, char **argv )
fprintf(stderr, APPNAME": missing argument - devname\n");
usage();
return -1;
} else {
} else if (!opt_debug) {
/* save the interface name */
strncpy( devname, argv[optind], sizeof(devname) );
}
@ -443,8 +511,13 @@ int main ( int argc, char **argv )
}
}
if ( opt_status && opt_addpdrcnt ) {
printf("PDA after \"-a\" file generated modifications:\n");
if ( pda_changed ) { /* calculate the CRC for the new PDA */
mkpda_crc(&pda);
}
if ( opt_status && pda_changed ) {
printf("PDA after crc calc and/or \"-a\" file "
"generated modifications:\n");
print_all_pdrs(&pda);
/* Read and print the CIS? */
exit(0);
@ -452,12 +525,15 @@ int main ( int argc, char **argv )
exit(0);
}
#if 0
if ( !opt_debug && !opt_nowrite && pda_changed) { /* write the PDA */
pda_write(&pda);
}
#endif
/*-----------------------------------------------------*/
/* Read the flash files */
if ( opt_flashloadcnt ) {
/* For each file */
for ( i = 0; i < opt_flashloadcnt; i++) {
for ( i = 0; i < opt_flashloadcnt; i++) { /* For each file */
/* Read the S3 file */
result = read_srecfile(ffname[i]);
if ( result ) {
@ -466,20 +542,38 @@ int main ( int argc, char **argv )
ffname[i]);
exit(1);
}
/* Sort the S3 data records */
qsort( s3data,
ns3data,
sizeof(s3datarec_t),
s3datarec_compare);
/* TODO: Validate the identity and compat ranges */
/* Make the image chunks */
/* result = mkchunks(flash_chunks); */
result = mkimage(fchunk, &nfchunks);
#if 0
/* Do any plugging */
for ( i = 0; i < ns3plug; i++) {
plugimage(fchunk, &da, s3plug[i]);
}
#endif
/* Write the image */
if ( opt_debug || !opt_nowrite ) continue;
/* do the write */
}
}
/* Read the ram files */
if ( opt_ramloadcnt ) {
/* For each file */
/* Validate the identity and compat ranges */
/* Make the image chunks */
/* Do any plugging */
for ( i = 0; i < opt_ramloadcnt; i++) { /* For each file */
/* Validate the identity and compat ranges */
/* Make the image chunks */
/* Do any plugging */
/* Write the image */
if ( opt_debug || !opt_nowrite ) continue;
/* do the write */
}
}
/*-----------------------------------------------------*/
@ -506,11 +600,245 @@ int main ( int argc, char **argv )
}
/*----------------------------------------------------------------
* do_ioctl
*
* Performs the ioctl call to send a message down to an 802.11
* device.
*
* Arguments:
* msg the message to send
*
* Returns:
* 0 success
* ~0 failure
----------------------------------------------------------------*/
int do_ioctl( p80211msg_t *msg )
{
int result = 0;
int fd;
p80211ioctl_req_t req;
/* set the magic */
req.magic = P80211_IOCTL_MAGIC;
/* get a socket */
fd = socket(AF_INET, SOCK_STREAM, 0);
if ( fd == -1 ) {
result = errno;
perror("wlanctl");
} else {
req.len = msg->msglen;
req.data = msg;
strcpy( req.name, msg->devname);
req.result = 0;
result = ioctl( fd, P80211_IFREQ, &req);
if ( result == -1 ) {
result = errno;
perror(APPNAME);
}
close(fd);
}
return result;
}
/*----------------------------------------------------------------
* mkimage
*
* Scans the currently loaded set of S records for data residing
* in contiguous memory regions. Each contiguous region is then
* made into a 'chunk'. This function assumes that we're building
* a new chunk list. Assumes the s3data items are in sorted order.
*
* Arguments: none
*
* Returns:
* 0 - success
* ~0 - failure (probably an errno)
----------------------------------------------------------------*/
int mkimage(imgchunk_t *clist, UINT *ccnt)
{
int result = 0;
int i;
int j;
int currchunk = 0;
UINT32 nextaddr = 0;
UINT32 s3start;
UINT32 s3end;
UINT32 cstart;
UINT32 cend;
UINT32 coffset;
/* There may already be data in the chunklist */
*ccnt = 0;
/* Establish the location and size of each chunk */
for ( i = 0; i < ns3data; i++) {
if ( s3data[i].addr == nextaddr ) {
/* existing chunk, grow it */
clist[currchunk].len += s3data[i].len;
nextaddr += s3data[i].len;
} else {
/* New chunk */
(*ccnt)++;
currchunk = *ccnt - 1;
clist[currchunk].addr = s3data[i].addr;
clist[currchunk].len = s3data[i].len;
nextaddr = s3data[i].addr + s3data[i].len;
/* Expand the chunk if there is a CRC record at */
/* their beginning bound */
for ( j = 0; j < ns3crc; j++) {
if ( s3crc[j].dowrite &&
s3crc[j].addr == clist[currchunk].addr ) {
clist[currchunk].addr -= 2;
clist[currchunk].len += 2;
}
}
}
}
/* We're currently assuming there aren't any overlapping chunks */
/* if this proves false, we'll need to add code to coalesce. */
/* Allocate buffer space for chunks */
for ( i = 0; i < *ccnt; i++) {
clist[i].data = malloc(clist[i].len);
if ( clist[i].data == NULL ) {
fprintf(stderr, APPNAME": failed to allocate image space, exitting.\n");
exit(1);
}
memset(clist[i].data, 0, clist[i].len);
}
/* Display chunks */
if ( opt_verbose ) {
for ( i = 0; i < *ccnt; i++) {
printf("chunk[%d]: addr=0x%06lx len=%ld\n",
i, clist[i].addr, clist[i].len);
}
}
/* Copy srec data to chunks */
for ( i = 0; i < ns3data; i++) {
s3start = s3data[i].addr;
s3end = s3start + s3data[i].len - 1;
for ( j = 0; j < *ccnt; j++) {
cstart = clist[j].addr;
cend = cstart + clist[j].len - 1;
if ( s3start >= cstart && s3end <= cend ) {
break;
}
}
if ( ((UINT)j) >= (*ccnt) ) {
fprintf(stderr,APPNAME
":s3rec(a=0x%06lx,l=%ld), no chunk match, exiting.\n",
s3start, s3data[i].len);
exit(1);
}
coffset = s3start - cstart;
memcpy( clist[j].data + coffset, s3data[i].data, s3data[i].len);
}
return result;
}
/*----------------------------------------------------------------
* mkpda_crc
*
* Calculates the CRC16 for the given PDA and inserts the value
* into the end record.
*
* Arguments:
* pda ptr to the PDA data structure.
*
* Returns:
* 0 - success
* ~0 - failure (probably an errno)
----------------------------------------------------------------*/
int mkpda_crc( pda_t *pda)
{
int result = 0;
UINT8 *p;
UINT8 *lim;
UINT16 crc = 0;
p = pda->buf;
/* pda->nrec-1 _better_ be the end record */
/* get ptr to last rec */
lim = (UINT8*)(pda->rec[pda->nrec - 1]);
lim += sizeof(UINT16) * 2; /* increase to include len&code fields */
while (p < lim) {
printf("%02x ", *p);
crc = (crc >> 8 ) ^ crc16tab[(crc & 0xff) ^ *p++];
}
/* assign to endrec field */
pda->rec[pda->nrec - 1]->data.end_of_pda.crc = host2hfa384x_16(crc);
if (opt_debug) {
printf(__FUNCTION__": pdacrc=0x%04x\n", crc);
}
return result;
}
/*----------------------------------------------------------------
* mkpdrlist
*
* Reads a raw PDA and builds an array of pdrec_t structures.
* NOTE: the len and code fields of the pdrrec_t's in the array
* will contain their values in HOST byte order following the
* execution of this function. The data field is NOT converted.
* If you use one of the data field elements don't forget to
* convert it first.
*
* Arguments:
* pda buffer containing raw PDA bytes
* pdrec ptr to an array of pdrec_t's. Will be filled on exit.
* nrec ptr to a variable that will contain the count of PDRs
*
* Returns:
* 0 - success
* ~0 - failure (probably an errno)
----------------------------------------------------------------*/
int mkpdrlist( pda_t *pda)
{
int result = 0;
UINT16 *pda16 = (UINT16*)pda->buf;
int curroff; /* in 'words' */
pda->nrec = 0;
curroff = 0;
while ( curroff < (HFA384x_PDA_LEN_MAX / 2) &&
hfa384x2host_16(pda16[curroff + 1]) != HFA384x_PDR_END_OF_PDA ) {
pda->rec[pda->nrec] = (hfa384x_pdrec_t*)&(pda16[curroff]);
(pda->nrec)++;
curroff += hfa384x2host_16(pda16[curroff]) + 1;
}
if ( curroff >= (HFA384x_PDA_LEN_MAX / 2) ) {
fprintf(stderr, APPNAME
": no end record found or invalid lengths in PDR data, exiting.\n");
exit(1);
}
if (hfa384x2host_16(pda16[curroff + 1]) == HFA384x_PDR_END_OF_PDA ) {
pda->rec[pda->nrec] = (hfa384x_pdrec_t*)&(pda16[curroff]);
(pda->nrec)++;
}
return result;
}
/*----------------------------------------------------------------
* print_all_pdrs
*
* Dumps the contents of all the pdr lists to stdout. Assumes that
* the pdrlists have 'been made'. See makepdrlist().
* the pdrlists have 'been made'. See mkpdrlist().
*
* Arguments: none
*
@ -527,6 +855,18 @@ void print_all_pdrs(pda_t *pda)
int end;
int nwords;
if ( opt_generate ) {
for ( i = 0; i < pda->nrec; i++) {
datap = (UINT16*)(pda->rec[i]);
nwords = hfa384x2host_16(pda->rec[i]->len) +1;
for ( j = 0; j < nwords; j++) {
printf("0x%04x, ", hfa384x2host_16(datap[j]));
}
printf("\n");
}
return;
}
printf("Current PDA:\n");
printf( " offset len code data\n"
" ---------------------------------------------------\n");
@ -565,6 +905,50 @@ void print_all_pdrs(pda_t *pda)
}
/*----------------------------------------------------------------
* read_cardpda
*
* Sends the command for the driver to read the pda from the card
* named in the device variable. Upon success, the card pda is
* stored in the "cardpda" variables. Note that the pda structure
* is considered 'well formed' after this function. That means
* that the nrecs is valid, the rec array has been set up, and there's
* a valid PDAEND record in the raw PDA data.
*
* Arguments: none
*
* Returns:
* 0 - success
* ~0 - failure (probably an errno)
----------------------------------------------------------------*/
int read_cardpda(pda_t *pda, char *dev)
{
int result = 0;
p80211msg_p2req_readpda_t msg;
/* set up the msg */
msg.msgcode = DIDmsg_p2req_readpda;
msg.msglen = sizeof(msg);
strcpy(msg.devname, dev);
msg.pda.did = DIDmsg_p2req_readpda_pda;
msg.pda.len = HFA384x_PDA_LEN_MAX;
msg.pda.status = P80211ENUM_msgitem_status_no_value;
msg.resultcode.did = DIDmsg_p2req_readpda_resultcode;
msg.resultcode.len = sizeof(UINT32);
msg.resultcode.status = P80211ENUM_msgitem_status_no_value;
if ( do_ioctl((p80211msg_t*)&msg) != 0 ) {
/* do_ioctl prints an errno if appropriate */
result = -1;
} else if ( msg.resultcode.data == P80211ENUM_resultcode_success ) {
memcpy(pda->buf, msg.pda.data, HFA384x_PDA_LEN_MAX);
result = mkpdrlist(pda);
}
return result;
}
/*----------------------------------------------------------------
* read_filepda
*
@ -664,6 +1048,11 @@ int read_filepda(pda_t *pda, char *pdrfname)
pdrlen = hfa384x2host_16(pdword[i]); /* in words */
pdrcode = hfa384x2host_16(pdword[i+1]);
if ( pdrlen > (HFA384x_PDR_LEN_MAX / 2) ) {
fprintf(stderr,APPNAME": invalid pdr length encountered, exiting.\n");
exit(1);
}
for ( j = 0; j < pda->nrec; j++) { /* Find matching code in PDA */
if ( pdrcode == hfa384x2host_16(pda->rec[j]->code) ) {
break;
@ -682,7 +1071,7 @@ int read_filepda(pda_t *pda, char *pdrfname)
mvlen = HFA384x_PDA_LEN_MAX - (mvpdastart - pda->buf);
memmove( delpdastart, mvpdastart, mvlen);
pda->nrec = 0;
makepdrlist(pda);
mkpdrlist(pda);
} else if ( j < pda->nrec ) { /* Replace the pdr in the PDA */
if (opt_verbose) {
printf(" Replacing PDR: code=%04x, len=%d\n",
@ -721,95 +1110,6 @@ int read_filepda(pda_t *pda, char *pdrfname)
}
/*----------------------------------------------------------------
* read_cardpda
*
* Sends the command for the driver to read the pda from the card
* named in the device variable. Upon success, the card pda is
* stored in the "cardpda" variables. Note that the pda structure
* is considered 'well formed' after this function. That means
* that the nrecs is valid, the rec array has been set up, and there's
* a valid PDAEND record in the raw PDA data.
*
* Arguments: none
*
* Returns:
* 0 - success
* ~0 - failure (probably an errno)
----------------------------------------------------------------*/
int read_cardpda(pda_t *pda, char *dev)
{
int result = 0;
p80211msg_p2req_readpda_t msg;
/* set up the msg */
msg.msgcode = DIDmsg_p2req_readpda;
msg.msglen = sizeof(msg);
strcpy(msg.devname, dev);
msg.pda.did = DIDmsg_p2req_readpda_pda;
msg.pda.len = HFA384x_PDA_LEN_MAX;
msg.pda.status = P80211ENUM_msgitem_status_no_value;
msg.resultcode.did = DIDmsg_p2req_readpda_resultcode;
msg.resultcode.len = sizeof(UINT32);
msg.resultcode.status = P80211ENUM_msgitem_status_no_value;
if ( do_ioctl((p80211msg_t*)&msg) != 0 ) {
/* do_ioctl prints an errno if appropriate */
result = -1;
} else if ( msg.resultcode.data == P80211ENUM_resultcode_success ) {
memcpy(pda->buf, msg.pda.data, HFA384x_PDA_LEN_MAX);
result = makepdrlist(pda);
}
return result;
}
/*----------------------------------------------------------------
* makepdrlist
*
* Reads a raw PDA and builds an array of pdrec_t structures.
* NOTE: the len and code fields of the pdrrec_t's in the array
* will contain their values in HOST byte order following the
* execution of this function. The data field is NOT converted.
* If you use one of the data field elements don't forget to
* convert it first.
*
* Arguments:
* pda buffer containing raw PDA bytes
* pdrec ptr to an array of pdrec_t's. Will be filled on exit.
* nrec ptr to a variable that will contain the count of PDRs
*
* Returns:
* 0 - success
* ~0 - failure (probably an errno)
----------------------------------------------------------------*/
int makepdrlist( pda_t *pda)
{
int result = 0;
UINT16 *pda16 = (UINT16*)pda->buf;
int curroff; /* in 'words' */
pda->nrec = 0;
curroff = 0;
while ( curroff < (HFA384x_PDA_LEN_MAX / 2) &&
hfa384x2host_16(pda16[curroff + 1]) != HFA384x_PDR_END_OF_PDA ) {
pda->rec[pda->nrec] = (hfa384x_pdrec_t*)&(pda16[curroff]);
(pda->nrec)++;
curroff += hfa384x2host_16(pda16[curroff]) + 1;
}
if ( curroff >= (HFA384x_PDA_LEN_MAX / 2) ) {
fprintf(stderr, APPNAME
": no end record found in PDR data, exiting.\n");
exit(1);
}
if (hfa384x2host_16(pda16[curroff + 1]) == HFA384x_PDR_END_OF_PDA ) {
pda->rec[pda->nrec] = (hfa384x_pdrec_t*)&(pda16[curroff]);
(pda->nrec)++;
}
return result;
}
/*----------------------------------------------------------------
* read_srecfile
*
@ -907,15 +1207,15 @@ int read_srecfile(char *fname)
/* Record Length field (we only want datalen) */
memcpy(tmpbuf, buf+S3LEN_TXTOFFSET, S3LEN_TXTLEN);
tmpbuf[S3LEN_TXTLEN] = '\0';
tmprec.datalen = strtoul( tmpbuf, NULL, 16) - 4 - 1; /* 4=addr, 1=cksum */
tmprec.len = strtoul( tmpbuf, NULL, 16) - 4 - 1; /* 4=addr, 1=cksum */
/* Address field */
memcpy(tmpbuf, buf+S3ADDR_TXTOFFSET, S3ADDR_TXTLEN);
tmpbuf[S3ADDR_TXTLEN] = '\0';
tmprec.address = strtoul( tmpbuf, NULL, 16);
tmprec.addr = strtoul( tmpbuf, NULL, 16);
/* Checksum field */
tmprec.checksum = strtoul( buf+strlen(buf)-2, NULL, 16);
switch( tmprec.address )
switch( tmprec.addr )
{
case S3ADDR_PLUG:
memcpy(tmpbuf, buf+S3PLUG_ITEMCODE_TXTOFFSET, S3PLUG_ITEMCODE_TXTLEN);
@ -925,8 +1225,8 @@ int read_srecfile(char *fname)
memcpy(tmpbuf, buf+S3PLUG_ADDR_TXTOFFSET, S3PLUG_ADDR_TXTLEN);
tmpbuf[S3PLUG_ADDR_TXTLEN] = '\0';
s3plug[ns3plug].address = strtoul(tmpbuf,NULL,16);
s3plug[ns3plug].address = __swab32(s3plug[ns3plug].address);
s3plug[ns3plug].addr = strtoul(tmpbuf,NULL,16);
s3plug[ns3plug].addr = __swab32(s3plug[ns3plug].addr);
memcpy(tmpbuf, buf+S3PLUG_LEN_TXTOFFSET, S3PLUG_LEN_TXTLEN);
tmpbuf[S3PLUG_LEN_TXTLEN] = '\0';
@ -938,7 +1238,7 @@ int read_srecfile(char *fname)
"itemcode=0x%04lx addr=0x%08lx len=%ld\n",
line,
s3plug[ns3plug].itemcode,
s3plug[ns3plug].address,
s3plug[ns3plug].addr,
s3plug[ns3plug].len);
}
@ -947,8 +1247,8 @@ int read_srecfile(char *fname)
case S3ADDR_CRC:
memcpy(tmpbuf, buf+S3CRC_ADDR_TXTOFFSET, S3CRC_ADDR_TXTLEN);
tmpbuf[S3CRC_ADDR_TXTLEN] = '\0';
s3crc[ns3crc].address = strtoul(tmpbuf,NULL,16);
s3crc[ns3crc].address =__swab32(s3crc[ns3crc].address);
s3crc[ns3crc].addr = strtoul(tmpbuf,NULL,16);
s3crc[ns3crc].addr =__swab32(s3crc[ns3crc].addr);
memcpy(tmpbuf, buf+S3CRC_LEN_TXTOFFSET, S3CRC_LEN_TXTLEN);
tmpbuf[S3CRC_LEN_TXTLEN] = '\0';
@ -964,7 +1264,7 @@ int read_srecfile(char *fname)
printf( " S3 crcrec, line=%d "
"addr=0x%08lx len=%ld write=0x%08x\n",
line,
s3crc[ns3crc].address,
s3crc[ns3crc].addr,
s3crc[ns3crc].len,
s3crc[ns3crc].dowrite);
}
@ -1005,19 +1305,20 @@ int read_srecfile(char *fname)
break;
default: /* Data record */
if (opt_verbose) {
printf(" S3 datarec, line=%04d addr=0x%08lx datalen=%03ld\n",
line, tmprec.address, tmprec.datalen);
printf(" S3 datarec, line=%04d addr=0x%08lx len=%03ld\n",
line, tmprec.addr, tmprec.len);
}
s3data[ns3data].address = tmprec.address;
s3data[ns3data].datalen = tmprec.datalen;
s3data[ns3data].addr = tmprec.addr;
s3data[ns3data].len = tmprec.len;
s3data[ns3data].checksum = tmprec.checksum;
s3data[ns3data].data = malloc(tmprec.datalen);
for ( i = 0; i < tmprec.datalen; i++) {
s3data[ns3data].data = malloc(tmprec.len);
for ( i = 0; i < tmprec.len; i++) {
memcpy(tmpbuf, buf+S3DATA_TXTOFFSET+(i*2), 2);
tmpbuf[3] = '\0';
s3data[ns3data].data[i] = strtoul(tmpbuf, NULL, 16);
}
ns3data++;
break;
}
}
return result;
@ -1025,49 +1326,64 @@ int read_srecfile(char *fname)
/*----------------------------------------------------------------
* do_ioctl
*
* Performs the ioctl call to send a message down to an 802.11
* device.
* str2macaddr
* This function converts a character string that represents an
* a 6 byte hex string to a 6 byte array.
* The string format is: "xx:xx:xx:xx:xx:xx"
*
* Arguments:
* msg the message to send
*
* a - a six byte array
* s - character string representing a mac address
* Returns:
* 0 success
* ~0 failure
* ~0 detected a format error
----------------------------------------------------------------*/
int do_ioctl( p80211msg_t *msg )
int str2macaddr( UINT8 *a, char *s )
{
int result = 0;
int fd;
p80211ioctl_req_t req;
char *p;
int i;
UINT val;
/* set the magic */
req.magic = P80211_IOCTL_MAGIC;
/* get a socket */
fd = socket(AF_INET, SOCK_STREAM, 0);
if ( fd == -1 ) {
result = errno;
perror("wlanctl");
} else {
req.len = msg->msglen;
req.data = msg;
strcpy( req.name, msg->devname);
req.result = 0;
result = ioctl( fd, P80211_IFREQ, &req);
if ( result == -1 ) {
result = errno;
perror(APPNAME);
for ( i = 0; i < 5; i++) { /* loop over the number of :'s */
p = strchr( s, ':');
if ( p == NULL ) {
return 1;
} else {
*p = '\0';
sscanf( s, "%x", &val);
a[i] = (UINT8)val;
s = p+1;
}
close(fd);
}
return result;
sscanf( s, "%x", &val);
a[i] = (UINT8)val;
return 0;
}
/*----------------------------------------------------------------
* s3datarec_compare
*
* Comparison function for qsort().
*
* Arguments:
* p1 ptr to the first item
* p2 ptr to the second item
* Returns:
* 0 items are equal
* <0 p1 < p2
* >0 p1 > p2
----------------------------------------------------------------*/
int s3datarec_compare(const void *p1, const void *p2)
{
const s3datarec_t *s1 = p1;
const s3datarec_t *s2 = p2;
if ( s1->addr == s2->addr ) return 0;
if ( s1->addr < s2->addr ) return -1;
return 1;
}
/*----------------------------------------------------------------
* usage
*
@ -1146,39 +1462,4 @@ void usage(void)
}
/*----------------------------------------------------------------
* str2macaddr
* This function converts a character string that represents an
* a 6 byte hex string to a 6 byte array.
* The string format is: "xx:xx:xx:xx:xx:xx"
*
* Arguments:
* a - a six byte array
* s - character string representing a mac address
* Returns:
* 0 success
* ~0 detected a format error
----------------------------------------------------------------*/
int str2macaddr( UINT8 *a, char *s )
{
char *p;
int i;
UINT val;
for ( i = 0; i < 5; i++) { /* loop over the number of :'s */
p = strchr( s, ':');
if ( p == NULL ) {
return 1;
} else {
*p = '\0';
sscanf( s, "%x", &val);
a[i] = (UINT8)val;
s = p+1;
}
}
sscanf( s, "%x", &val);
a[i] = (UINT8)val;
return 0;
}