Added image construction and PDA crc.
This commit is contained in:
parent
8fd24ebeee
commit
7d27d17666
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue