📄 prism2dl.c
字号:
*(dest+1) = 0xc0; } return result;}/*----------------------------------------------------------------* 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(APPNAME); } else { req.len = msg->msglen; req.data = (caddr_t) 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;}/*----------------------------------------------------------------* free_chunks** Clears the chunklist data structures in preparation for a new file.** Arguments:* none** Returns: * nothing----------------------------------------------------------------*/void free_chunks(imgchunk_t *fchunk, UINT* nfchunks){ int i; for ( i = 0; i < *nfchunks; i++) { if ( fchunk[i].data != NULL ) { free(fchunk[i].data); } } *nfchunks = 0; memset( fchunk, 0, sizeof(fchunk));}/*----------------------------------------------------------------* free_srecs** Clears the srec data structures in preparation for a new file.** Arguments:* none** Returns: * nothing----------------------------------------------------------------*/void free_srecs(void){ int i; for ( i = 0; i < ns3data; i++) { free(s3data[i].data); } ns3data = 0; memset(s3data, 0, sizeof(s3data)); ns3plug = 0; memset(s3plug, 0, sizeof(s3plug)); ns3crc = 0; memset(s3crc, 0, sizeof(s3crc)); ns3info = 0; memset(s3info, 0, sizeof(s3info)); startaddr = 0;}/*----------------------------------------------------------------* 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 = 0; 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) { 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("%s: pdacrc=0x%04x\n", __FUNCTION__, crc); } return result;}/*----------------------------------------------------------------* mkpdrlist** Reads a raw PDA and builds an array of pdrec_t structures.** 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]); if (hfa384x2host_16(pda->rec[pda->nrec]->code) == HFA384x_PDR_NICID) { memcpy(&nicid, &pda->rec[pda->nrec]->data.nicid, sizeof(nicid)); nicid.id = hfa384x2host_16(nicid.id); nicid.variant = hfa384x2host_16(nicid.variant); nicid.major = hfa384x2host_16(nicid.major); nicid.minor = hfa384x2host_16(nicid.minor); } if (hfa384x2host_16(pda->rec[pda->nrec]->code) == HFA384x_PDR_MFISUPRANGE) { memcpy(&rfid, &pda->rec[pda->nrec]->data.mfisuprange, sizeof(rfid)); rfid.id = hfa384x2host_16(rfid.id); rfid.variant = hfa384x2host_16(rfid.variant); rfid.bottom = hfa384x2host_16(rfid.bottom); rfid.top = hfa384x2host_16(rfid.top); } if (hfa384x2host_16(pda->rec[pda->nrec]->code) == HFA384x_PDR_CFISUPRANGE) { memcpy(&macid, &pda->rec[pda->nrec]->data.cfisuprange, sizeof(macid)); macid.id = hfa384x2host_16(macid.id); macid.variant = hfa384x2host_16(macid.variant); macid.bottom = hfa384x2host_16(macid.bottom); macid.top = hfa384x2host_16(macid.top); } (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. %x %d\n", curroff, pda->nrec); 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;}/*----------------------------------------------------------------* pda_write** Builds a message containing the PDA in the given pda structure* and sends it to the device driver. The driver will (hopefully)* write the pda to the card flash.** Arguments:* pda structure containing the PDA we wish to write to* the card.** Returns: * 0 success* ~0 failure----------------------------------------------------------------*/int pda_write(pda_t *pda){ int result = 0; p80211msg_p2req_flashdl_state_t statemsg; p80211msg_p2req_flashdl_write_t writemsg; /* Initialize the messages */ memset(&statemsg, 0, sizeof(statemsg)); strcpy(statemsg.devname, devname); statemsg.msgcode = DIDmsg_p2req_flashdl_state; statemsg.msglen = sizeof(statemsg); statemsg.enable.did = DIDmsg_p2req_flashdl_state_enable; statemsg.resultcode.did = DIDmsg_p2req_flashdl_state_resultcode; statemsg.enable.status = P80211ENUM_msgitem_status_data_ok; statemsg.resultcode.status = P80211ENUM_msgitem_status_no_value; statemsg.enable.len = sizeof(UINT32); statemsg.resultcode.len = sizeof(UINT32); memset(&writemsg, 0, sizeof(writemsg)); strcpy(writemsg.devname, devname); writemsg.msgcode = DIDmsg_p2req_flashdl_write; writemsg.msglen = sizeof(writemsg); writemsg.addr.did = DIDmsg_p2req_flashdl_write_addr; writemsg.len.did = DIDmsg_p2req_flashdl_write_len; writemsg.data.did = DIDmsg_p2req_flashdl_write_data; writemsg.resultcode.did = DIDmsg_p2req_flashdl_write_resultcode; writemsg.addr.status = P80211ENUM_msgitem_status_data_ok; writemsg.len.status = P80211ENUM_msgitem_status_data_ok; writemsg.data.status = P80211ENUM_msgitem_status_data_ok; writemsg.resultcode.status = P80211ENUM_msgitem_status_no_value; writemsg.addr.len = sizeof(UINT32); writemsg.len.len = sizeof(UINT32); writemsg.data.len = WRITESIZE_MAX; writemsg.resultcode.len = sizeof(UINT32); /* Send flashdl_state(enable) */ if (opt_verbose) printf("Sending dlflash_state(enable) message.\n"); statemsg.enable.data = P80211ENUM_truth_true; if ( !opt_debug ) { result = do_ioctl((p80211msg_t*)&statemsg); if ( result ) { fprintf(stderr,APPNAME ": pda_write()->do_ioctl() failed w/ result=%d, " "aborting pda download\n", result); return result; } if ( statemsg.resultcode.data != P80211ENUM_resultcode_success ) { fprintf(stderr,APPNAME ": pda_write()->flashdl_state msg indicates failure, " "w/ resultcode=%ld, aborting pda download.\n", statemsg.resultcode.data); return 1; } } /* Send flashdl_write(pda) */ writemsg.addr.data = opt_pdaloc; writemsg.len.data = (((UINT8*)(pda->rec[pda->nrec - 1])) - pda->buf + 6); memcpy(writemsg.data.data, pda->buf, writemsg.len.data); if (opt_verbose) { printf("Sending dlflash_write, addr=%06lx len=%ld \n", writemsg.addr.data, writemsg.len.data); } if ( !opt_debug ) { result = do_ioctl((p80211msg_t*)&writemsg); if ( result ) { fprintf(stderr,APPNAME ": pda_write()->do_ioctl() failed w/ result=%d, " "aborting pda download\n", result); return result; } if ( writemsg.resultcode.data != P80211ENUM_resultcode_success ) { fprintf(stderr,APPNAME ": pda_write()->flashdl_write msg indicates failure, " "w/ resultcode=%ld, aborting pda download.\n", writemsg.resultcode.data); return 1; } } /* Send flashdl_state(disable) */ if (opt_verbose) printf("Sending dlflash_state(disable) message.\n"); statemsg.enable.data = P80211ENUM_truth_false; if ( !opt_debug ) { result = do_ioctl((p80211msg_t*)&statemsg); if ( result ) { fprintf(stderr,APPNAME ": pda_write()->do_ioctl() failed w/ result=%d, " "aborting pda download\n", result); return result; } if ( statemsg.resultcode.data != P80211ENUM_resultcode_success ) { fprintf(stderr,APPNAME ": pda_write()->flashdl_state msg indicates failure, " "w/ resultcode=%ld, aborting pda download.\n", statemsg.resultcode.data); return 1; } } return result;}/*----------------------------------------------------------------* plugimage** Plugs the given image using the given plug records from the given * PDA and filename.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -