BROADCAST DOWNLOAD TECHNIQUE

Abstract: In a wireless microcell distribution system, a multicast system is provided for broadcasting software updates, enable and disable capabilities, channel reassignments or other downloadable data simultaneously to a plurality of cable microcell integrators, thereby precluding the lengthy unicast process of updating cable microcell integrators manually or suffering prior unreliable message delivery in which each of the cable microcell integrators in individually addressed and the response tallied. In one embodiment, the request is transmitted simultaneously in a broadcast mode to multiple cable microcell integrators with no response required. Thereafter, each cable microcell integrator is queried on a unicast basis as to receipt of broadcast information and as to whether or not any portion must be re-broadcast. If so optionally the entire information set can be rebroadcast, with only affected cable microcell integrators downloading the broadcast information. The multicast broadcast technique thus provides rapid simultaneous updating of each of the cable microcell integrators from a central location.

Description: TTΓLB OF INVENTION BROADCAST DOWNLOAD TECHNIQUE HELD OF INVENTION This invention relates to wireless microcell distribution systems and more particularly to a technique for providing software updates and other information to a plurality of microcells for decreasing the amount of download time required. BACKGROUND OF THE INVENΗON In wireless mjcrocell distribution systems, a number of miciOcells are coupled to a cable for the transmission and receipt of wireless signals to and from wireless terminals. It will be appreciated that there may be as many as thirty six microcells coupled to a cable, and that each of these microcells on occasion must be provided with downloadable software updates. The type of information which is transmitted to each of the microcells is for instance, software to reconfigure each of the microcells, to reconfigure the enable and disable capabilities of each of the microcells, to change the channel assignments, or to provide other information to each of the microcells. In the past, this has been accomplished on a unicast basis in which messages from a head end control unit are transmitted one at a time to each of the microcells, with each of the microcells having a so-called cable microcell integrator thereat. The cable microcell integrator responds to a request message from the head end interface converter and reconfigures its own internal software to comply with the information transmitted to it. Upon the download, the cable microcell integrator transmits a response back to the head end control unit indicating the status of the downloaded information. It will be appreciated that this unicast technique requires considerable time. For instance, it may require as much as an hour to download 1,000 messages to a particular cable microcell integrator. This is multiplied by the number of cable microcell integrators communicating with the particular head end control unit, such that a software download can sometimes take up to a number of weeks to accomplish. While it will be appreciated that the prior techniques adequately permit downloading of information to each of the cable microcell integrators, it is preferable to be able to accomplish the process in a shorter period of time. SUMMARY OF THE INVENTION Rather than addressing each of the cable microcell integrators separately, in an improved process, a message is sent from the head end control unit to each of the cable microcell integrators to reconfigure each cable microcell integrator to go into the broadcast mode. This transmission is done on a unicast basis. Thereafter, the downloadable information is broadcast to all of the cable microcell integrators in a so-called broadcast mode in which the information is transmitted simultaneously to each of the cable microcell integrators. After the broadcast has been completed, an exit broadcast mode message is broadcast to each of the cable microcell integrators. Thereafter, in a unicast mode, each of the cable microcell integrators is queried as to the broadcast status. In one embodiment, what each of the cable microcell integrator computes is a check sum, indicative of the confirmed receipt of each of the downloads. Upon ascertaining at each of the cable microcell integrators the status of each broadcast, this information is transmitted back to the head end control unit on a unicast basis. If it appears that a large portion of the message has been lost or could have been misinterpreted by a number of cable microcell integrators, in one embodiment the head end control unit re-broadcasts either all or part of the download with those cable microcell integrators having confirmed receipt of the original message simply ignoring the additional broadcast or that portion of it that they have properly received. In this manner, the process which in some cases can take as much as several weeks, is completed in a matter of hours or even minutes. It is important to note that only that information which is required of each cable microcell integrator which it did not get, is required to be transmitted back to it. Thus, the subject system combines unicast and broadcast in an efficient manner to be able to provide detection and correction of erroneous messages at each cable microcell integrator. In summary, in a wireless microcell distribution system, a multicast system is provided for broadcasting software updates, enable and disable capabilities, channel reassignments or other downloadable data simultaneously to a plurality of cable microcell integrators, thereby precluding the lengthy unicast process of updating cable microcell integrators manually or suffering prior unreliable message delivery in which each of the cable microcell integrators is individually addressed and the response tallied. In one embodiment, the request is transmitted simultaneously in a broadcast mode to multiple cable microcell integrators with no response required. Thereafter, each cable microcell integrator is queried on a unicast basis as to receipt of broadcast information and as to whether or not any portion must be re-broadcast. If so optionally, all or portions of the information set can be re-broadcast, with only affected cable microcell integrators downloading the broadcast information. The multicast broadcast technique thus provides rapid simultaneous updating of each of the cable microcell integrators from a central location. BRIEF DESCRIPTION OF THE DRAWINGS These and other features of the Subject Invention will be better understood in connection with the Detailed Description in conjunction with the Drawings of which: Figure 1 is a block diagram of a prior art unicast system in which information is downloaded to each of the cable microcell integrators separately, with the response from each of the cable microcell integrators also being evaluated on an microcell-by-microcell basis; Figure 2 is a block diagram of the subject system in which software updates and other information are broadcast simultaneously to each of the cable microcell integrators with no response required; Figure 3 is a block diagram of the system in Figure 2 in which after the information has been broadcast to each of the cable microcell integrators, a query message is sent on a unicast basis to each of the cable microcell integrators and the response therefrom evaluated; and Figure 4 is a flow chart illustrating the sequence of events in the download of information to be broadcast to each of the cable microcell integrators. DETAILED DESCRIPTION Referring now to Figure 1, in a wireless microcell distribution system, a head end control unit 10 is coupled to a head end interface converter 12 which is serially connected to a number of cable microcell integrators 14, 16, 18 and 20 over a network which includes a cable television plant, be it fiber optic, cable or microcell. It will be appreciated that from time to time, each of the cable microcell integrators must be provided with software updates, channel reassignments or enable and disable capabilities which must be changed. Thus on occasion requirements include fixing, software bugs, enhancing capabilities or channel configurations. In the past, as mentioned before, these software updates have been accomplished by downloading to each of the cable microcell integrators, the required information on a separate basis. Thus for instance, each of the cable microcell integrators is addressed separately and is provided with the downloaded information at that time. Thereafter, validation of receipt of such information is transmitted back to the head end control unit over the network. Should some of the information not be properly downloaded, the proper information is resent to the particular cable microcell integrator requiring it. Referring now to Figure 2, in contradistinction to the above method of providing software updates to the cable microcell integrators, in the subject system the information is transmitted to each of the cable microcell integrators on a multicast basis in which the information to be downloaded is transmitted simultaneously to each of the cable microcell integrators. This is indicated by information on a request path here illustrated at 22. Referring now to Figure 3, while the broadcast of the downloadable information is accomplished in a multicast or simultaneous mode, after the information has been transmitted, the system is placed in a unicast query mode, as illustrated in Figure 3, in which a query message, as illustrated in line 24, is sent to a specific cable microcell integrator and the response therefrom evaluated, with the response being sent back as illustrated on path 26. In one embodiment, the query message requests a response from the addressed cable microcell integrator for a validation message, in one case a simple check sum. Other types of validation messages are possible, including those that indicate which portion of which message has not been properly downloaded or received. As is typical in such validation techniques, check sums are provided on sections of the downloaded information. Another technique for validation includes a cyclic redundancy check. Referring now to Figure 4, from the point of view of the flow of information, the head end control unit, as illustrated in box 30, transmits to each cable microcell integrator the need to place the cable microcell integrator in its broadcast mode. Thereafter, the downloadable information is broadcast, as illustrated at box 32, to send N broadcast messages, which in some cases can exceed 1,000 messages. These messages, as indicated above, are sent simultaneously to each of the cable microcell integrators from the particular head end control unit. As can be seen from box 34, after the broadcast of the information to each of the cable microcell integrators, an "exit" broadcast message is simultaneously multicast to each of the cable microcell integrators followed by a unicast "query" message as illustrated at box 36 as to the broadcast status. Thus in this task, each of the cable microcell integrators is serially queried by the head end control unit, with its broadcast status evaluated one at a time. Thereafter, assuming that there is a common transmission of any, all or a part of a broadcast message, the original information may be broadcast back to all of the cable microcell integrators as indicated by dotted line 38, with each of the cable microcell integrators responding only to that portion of the message that was not properly received. What follows is a program written in C, describing the combined umcast-broadcast system for one embodiment of the subject invention. Code Pertaining Co CD Extracted from HLROM.C ** TITLE: Proc Mess ** * DESCRIPTION: To process the messages received while in PROM and some of the messages ** received while m EEprom will call this procedure 1 ** INPUTS: none ** ** OUTPUTS: contιnue_Download Flag: True or False ** ** ASSUMPTIONS/LIMITATIONS: ** This routine handles broadcast messages ** This procedure does not handle every CMI message. ** This procedure will NACK messages and report a reason for the Nack Revision History: ** ** PCSC-122 3/15/98 * This procedure now sends the response sg to the appropriate source ** CMI Number of BROADCAST indicates that the message received was a ** broadcast ** message and therefore should not be ackknowledged by the CMI. ** dl_stat is now a local variable not a global. ** This procedure now processes new download messages. ** This procedure now checks for multiple faults, not 3 ust two. ** Removed the xdata declaration on local variable 3 . This routine can now receive broadcast messages: but this particular CMI may not want to be processing the broadcast message; check the global flag prior to processing. This procedure now checks the global flag download_mode prior to ** processing any download messages. This procedure now handles filling all/part of EEprom witn 1 msg This procedure now handles performing a checksum on any defined area 0 ** PCSC-161 Added the ACT_CMI message to ROM - note it does not perform some of ** the action if the CMI is in ROM waiting for download ** 4/24/98 Set EEP__ONLINE to false when CDL xsum is received. ** Nack the old 15.4 download messages. 15 ** 4/28/98 This procedure will handle a random delay to the response of a broad- ** cast RUA_LOST_CMI message. ** PCΞC-174 5/20/98 The flush routine must ensure download mode is active to process ' 0 ** PCSC-178 6/9/98 This routine now processes frecr_stat messages. ** This routine is set up to handle two future features on * the Rua_Lost CMI message. ** PCSC-213 7/17/98 Changed the freq_stat_msg to report back the RAM value of * fwd_channel and type (not what is in EEprom) 5 * On ACT_CMI, if sector changes, re-tune F D PLLs /* This is the Process Message Routine */ unsigned char Proc_Mess (void ) 0 unsigned char l, 3 ; unsigned mt ιnt_ι; unsigned char xdata *addr; unsigned mt s_addr; /* will contain a pointer */ unsigned at count; 5 unsigned char pattern; unsigned char load_stat; unsigned char contin; unsigned char ret_stat; unsigned long chksum; 0 unsigned char *x_addr; unsigned char cnt; unsigned char n,temp; 5 contin = TRUE; load_stat = TRUE; /* unless otherwise changed by any proc. called from this proc */ recvd_brdcst_msg = msg_in.dat .raw.dat.O] & BRCDΞT_MSK; /* DF# 1 contains num/sector OR brdcst */ / * == = = = = = = = = = = = = = = ==== = = = = = — = = = = = = = = = = = = = = = = = = = = = = = = = = = == = = = = = = = = = = = = - -.=-.= */ 50 /* Ensure that any broadcast message received is to be processed by this CMI */ * / * ========= = ======= ==== = ====== = ^=== == === = ========= = == = ==== == = == =^ == ^= === ^ * / if ( recvd_brdcst_msg == BROADCAST) /* was the msg received broadcast ? */ { /* yes -check to see that the process_broadcast_msg flag has been previously set */ 55 if ( process_broadcast_msgs '= TRUE ) /* are we currently accepting brdcast ? */ {/* NO - but, it may be a Broadcast call for Lost CMI ' check before ignoring */ if ( lost_cmι )/* are we a lost_cmι ? */ { /* yes - check to see if this is a lost inquerey */ if ( msg_ιn.number •= RUA_LOST_CMI ) 60 { if ( ' serιal_data_flag ) /* is it from the Neuorn ? */ { /* yes - */ contin = FALSE, /* do not process and do not ack ' */ t ,. Drop_It(); 65 } else /* it's from rs232 - we can process it */ contin = TRUE; ) else /* it is an RUA_LOST_CMI msg - process it */ 70 contin = TRUE; else /* not a lost CMI, and not processing Brdcst, drop it on the floor ' */ contin = FALSE; /* no, do not process and do not ack ' */ 75 Drop_It() ; } ) else { /* the message received was not broadcast, but should we process it ? */ 5 /* ========================================================================== */ /* Since we are in ROM, we need to have an established communications with our HIC in order to properly respond to any message received. Until we receive an RUA_LOΞT_CMI (or ACT_CMI), we will not process any messages ! */ /* ================================================== */ 10 if (( lost_cmι ) __& ( neuron_msg_ lag) ) /* are we a lost_cmι? AND receiving Neuron ? */ { /* yes - check to see if this is a lost inquerey OR an Activate CMI */ if (( msg_ιn.number == RUA_LOST_CMI ) || (msg_ιn.number == ACT_CMI_MSG )) contin = TRUE; /* process and do not ack ! */ else /* no, do not process the message */ 15 contin = FALSE; } else /* we are not lostlor we are but msg is from 232)- so process the message */ contin = TRUE; 0 } if ( contin == TRUE ) { /* this CMI is supposed to process the message */ 5 /* ========================================================================== */ switch! msg_m.number ) /* which message was received ? */ /« ========================================================================== */ { 30 /* ========================================================================== -/ /* improved download commands (post Version 4 EEprom code) */ / * * / case CMI_CDL_FILL_PATT :/* indicates a fill pattern */ 35 case CMI_CDL_NORM :/* all data in one record */ case CMI_CDL_START_CONT :/* start of a continuation load */ case CMI_CDL_CONT :/* a continuation load 0 */ case CMI_CDL_FUTURE : /* a future enhancement download */ if ( download_mode == TRUE ) /* are we supposed to be getting these ' */ 45 { /* yes - process the download message */ load_εtat = Improved_DL_Code ( ) ; /* process the download msg */ Return_Message ( ) ; /* acknowledge msg s processed*/ } else/* we are not in the correct mode to receive this message ' */ 50 { Send_Back_Nack ( /* Nack the msg is NOT processed */ CDL_WRONG_MODE, /* Reason code */ msg_ιn.number) ,- /* supporting data */ -5-5 break; ========================================================================== * case CMI_FREQ_STAT_MSG: /* $$$$$$$$ Read the Frequency status $$$$$$$$ */ ========================================================================== * / 60 msg_ιn.dat .send_freq_stat. rev_prι_freq * (char xdata > ) EEP_REV_PRI_FREQ; msg_ιn.dat .send_freq_stat.rev_dιv_ req * (char xdata > ) EEP_REV_DIV_FREQ; insg_in.dat . send_freq_stat. fwd_chn fwd_chan, msg_ιn.dat . send_freq_stat . fwd_chn_type fwd_type; msg_ιn.da . send_freq_stat .pcs_tx_freq_msb • (char xdata *) EEP_PCS_CHAN_MSB; 65 msg_ιn.dat .send_freq__stat .pcs_tx_freq_lsb char xdata *)EEP_PCS_CHAN_LSB; Return_Message ( ) ; /* acknowledge msg is processed break; 70 case CMI_CDL_CALC_SECT_XSU : /* CMI calculate sector xsum data Return_Message ( ) ; /* acknowledge msg is received prior : it takes 10 seconds ' */ Calc_sector_xsum( ) ; break; 75 case CMI_CDL_RPT_SCT_XSUM: /* CMI Report sector xsum data -nsg_ιn.dat.rpt_xsum. fld2 sector_xsum[0] ; msg_ιn .dat . rpt_xsum. fld3 sector_xsum[l] ; msg_ιn. dat . rpt_xsum. fld4 sector_xsum[2] , msg_m.dat .rpt_xsum. fld5 sector_xsum[3] ; msg_m.dat . rpt_xsuιn. fld6 sector_xsum[4] ; msg_ιn. dat . rpt_xsum. fld7 sector_xsum[5] ; 10 msg_ιn.dat.rpt_xsum. fld8 sector_xsum[6] msg_ιn.dat.rpt_xsum. fld9 sector_xsum[7] j msg_in.dat. rpt_xsum.fldlO = 0; /* clear for calc xsum for (ι=0; ι<8; ι++) /* now clac xsum of msg */ msg_ιn.dat.rpt_xsum. fldlO += sector_xsum[ι] ; /* byte checksum of this msg */ 15 Return_Message ( ) ; /* acknowledge msg is processed */ break; case CMI_CDL_RESET : /* CMI Reset instructions 20 */ /* ========================================================================== ./ /* first verify the patterns in the message are correct */ if (( msg_ιn.dat.cdl_reset_cmι.pattl == OxB ) £-& ( msg_ιn.dat.cdl_reset_cmι.patt2 == OxE ) && 25 ( msg_ιn.dat.cdl_reset_cmι.patt3 == OxE ) --& ( msg_ιn.dat.cdl_reset_cmι.patt4 == OxF )) {/* correct pattern - so process the message */ Return_Message ( ) ; /* acknowledge msg is received */ 30 /* allow a first time succ run of the new downloaded code to store its version to EE */ πte_EEprom( (char xdata * ) EEP_CMI_ONLINE , FALSE);/* not acquireα is the key ' */ πte_EEprom( (char xdata *)EEP_INTENT_REΞET, TRUE); /* update the flag in EE so the reset code knows where to get values from */ 35 if ( msg_ιn . dat . cdl_reset_cmι . source == OxEE )/* the HIC wants reset to last known values ? * / {/* yes - OR in the bit */ pattern = * (char xdata * ) EEP_CMI_STATUS | PU_FRM_ΞTATUS_BIT ; . _ Wnte_EEprom( (char xdata * ) EEP_CMI_STATUS , pattern) ; 40 } else i f ( msg_ιn. dat . cdl_reset_cmι . source == OxDE ) / * want reset from DEfaults ? * / { / * yes - Clear the bit */ pattern = Mchar xdata * ) EEP_CMI_STATUS & -PU_FRM_ΞTATUS_BIT , Wnte_EEprom ( (char xdata * ) EEP_CMI_ΞTATUS , pattern) ; 45 ) /* don't update EE if the value isn't one of the above ' */ /* indicate the reset instructions */ load_stat = msg_ιn.dat.cdl_reset_cmι .reset_mst, -50 else /* the message is corrupted or illegal */ - Send_Back_Nac ( /* Nack the msg is NOT processed */ ENCODED_MΞG_CORRUPTED, /* reason code */ msg_ιn.number) ; /* support data */ break; 55 case CMI_CDL_STAT_INSTR :/* indicates download instructions */ /. . 60 /* first verify the patterns in the message are correct */ if (( msg_ιn.dat.cdl_stat_recv.pattl == OxB ) _.& ( msg_m.dat.cdl_stat_recv.patt2 == OxE ) && ( msg_ιn.dat.cdl_stat_recv.patt3 == OxE ) && Λ ( msg_m.dat.cdl_stat_recv.patt4 == OxF )) θJ {/* correct pattern - so process the message */ download_mode = msg_in.dat .cdl_stat_recv.dl_mode; /* indicate dl mode */ process_broadcast_msgs = msg_m.dat .cdl_stat_recv.proc_brdcast_msgs; /* indicates brdcast instructions */ verιfy_page_wrιte = msg_ιn.dat.cdl_stat_recv.verιfy_page_wrιte; /* verify or not */ 70 if ( msg_m.dat.cdl_stat_recv.sparel ) /* are we to invalidate last sector xsum bit map ? */ {/* yes */ for (ι=0; ι<8; ι++) /* now clac xsum of msg */ sector_xsum[ι]=0xFF; /* invalidated old bit map of sector checksums */ 75 } Return_Message ( ) ; /* acknowledge msg is processed */ ) else /* the message is corrupted or illegal */ { Send_Back_Nack ( /* Nack the msg is NOT processed */ ENCODED_MSG_CORRUPTED, /* reason code */ msg_m.number) ; /* support data */ } break; 10 case CMI_CDL_FLUSH :/* indicates a "flush" of the EEprom */ /* */ if ( download_mode == TRUE ) /* are we supposed to be getting these ? * 15 { /* yes - process the message */ /* first verify the patterns in the message are correct if (( msg_ιn. at. cdl_ lush.pattl == OxF ) £_& ( msg_ιn.dat.cdl_flush.patt2 == OxA ) __& ( msg_ιn.dat.cdl_flush.patt3 == OxD ) && 20 ( msg_ιn.dat.cdl_flush.patt4 == OxE )) {/* correct pattern - so process the message */ /* NOTE: we are verifying these writes which does take longer - but since it */ /* only takes one message from the HECU to clear all of EEprom - who cares 25 s_addr = msg_in.dat .cdl_flush. s_addr; /* indicate the start_address */ count = msg_ιn. dat. cdl_flush. count; /' indicate the amount of bytes */ pattern = msg_m.dat .cdl_flush.pattern; / ' indicates the pattern */ 30 Ensure that we are not in a download (using the contiguous buffer) */ if ( ! ιmproved_dl_struct.m_use) {/* structure is not in use by a download - so we can use it in the flusn */ _ if ( ! veπfy_page_wrιte )/* if we are not going to verify */ ->J Return_Message ( ) ; /* acknowledge msg is received prior to processing */ for ( mt_ι=0; ιnt_κ MAX_CDL_BUF; mt_ι++ )/* put the pattern in a buffer */ contιguous_dl_data[ιnt_ι] = pattern; 40 l = count / MAX_CDL_BUF; /* number of full buffer writes */ for( 3 =0; ]<ι; 3++)/* using page_wπte put out as many MAX_CDL_BUF byte buffers */ { Enable_EEprom( ) ; /* enable EEprom for writes */ ret_stat = Page_Wπte_EEPROM( 45 (xdata unsigned mt* ) &s_addr , /* dest. addres */ MAX_CDL_BUF, /* num_bytes to write */ contιguous_dl_data, /* pointer to source */ veπfy_page_wrιte ) , /* verify flag */ 50 Protect_EEprom( ) ; /* protectthe EE from writes */ * s_addr += MAX_CDL_BUF; /* move the destination pointer up */ if ( ret_stat '= SUCCESS) __ {/* the page write failed - indicate failure to the HECU */ 55 Set_Up_A_Nack( PAGE_WRITE_FAILURE , / * reason */ ret_stat) ; /* support data: the failure stat code */ break; /* from loop no need to continue ' */ } }/* end for loop */ 60 ιf( ret_stat == SUCCESS ) { /* continue and put out the remainder of the count */ l = count % MAX_CDL_BUF; /* the last (remainder) write */ 65 Enable_EEprom( ) ; /* enable EEprom for writes */ ret_stat = Page_Wπ e_EEPROM ( (xdata unsigned mt*) &s_addr, / * dest. addr */ i, /* num_bytes to write */ contιguous_dl_data, /* pointer to source */ verιfy_page_wπte ) , /* verify flag */ 70 Protect_EEprom( ) ; /* protectthe EE from writes */ }/* end if the ret_stat '- Fail */ if ( veπfy_page_wrιte )/* if we are verifying */ 75 { /* then we d d NOT respond prior to processing - so respond now */ if ( recvd_brdcst_msg '= BROADCAST) { /* not a broadcasted message */ if ( ret_stat '= SUCCESS ) Send_Back_Nack ( PAGE_WRITE_FAILURE, / * reason code */ msg_ιn.number ) ; /* support data */ 5 else /* the message processed was succesful */ Return_Message( ) ; /* acknowledge msg is processed */ )/* end if the msg was a broadcasted msg */ ) 10 else/* the structure we need to use is already in use - Nack the msgs */ { Send_Back_Nack ( CDL_STRUCT_IN_USE, /* reason code */ msg_ιn.number ); /* support data */ 15 ) } else /* the message is corrupted or illegal */ { Send_Back_Nack ( /* Nack the msg is NOT processed */ 0 ENCODED_MΞG_CORRUPTED, /* reason code */ msg_ιn.number) ; /* support data */ } } else/* we are not in the correct mode to receive this message ' */ 5 { Send_Back_Nack ( /* Nack the msg is NOT processed */ CDL_WR0NG_M0DE, /* Reason code */ msg_m.number); /* supporting data */ > 0 break ; /* ========================================================================== * / case CMI_CDL_PART_XSUM:/* Calculate a checksum of the code in EEPROM */ 5 /* ========================================================================== - / x_addr = (unsigned char xdata *)_nsg_in.dat .cdl_part_xsum. s_addr; /* where to start */ chksu = 0; /* start at zero */ count = msg_m.dat .cdl_part_xsum. count; 0 for ( ιnt_ι = 0; ιnt_ι < count; ιnt_ι++) { chksum += *x_addr; /* add this byte */ x_addr++; /* next byte */ } 5 (unsigned long)msg_m.dat .cdl_part_xsum.xsum = chksum;/* report it back */ Return_Message ( ) ; /* acknowledge msg is processed */ break; 50 35 /**********_***********_*„„*_*_**_*__*_★#**__*******#*__*_*„„_***___*_*_*___* ** TITLE: Improved_DL_Code ** ** DESCRIPTION: - ** This procedure is the improved download code. It processes a number 60 ** if different message types to increase the amount of data received ** in messages, and to reduce the amount of data sent if the data is ** redundant. The procedure also calls a Page Write EE function. This ** procedure can write data to the EEprom much faster and as many bytes ** as needed (not hard coded to 6 bytes) . 65 INPUTS: None OUTPUTS: Continue Download flag: T or F-this is the end of the download 70 ** ASSUMPTIONS/LIMITATIONS: ** This procedure will look into the received msg for indications of size. ** The maximum amount of contiguous DL data is 256 bytes. ** The maximum amount of fill data is 256 bytes. _ ** This procedure will not properly handle re-sends of any CONTINUATION 5 ** type download messages (it expects the next message is sequence (not ** a resend of a previous msgs; this would happen if the HIC was re-sendmg ** msgs in a broadcast mode to a failed CMI) ** The caller ensures we are in download mode. *« ** This procedure will NOT handle Unicast downloads. * _ 5 ** Revision History: ** PCSC-122 2/23/98 Created * * ** PCSC-161 4/24/98 Moved the Ack of EEprom sent CDL messages prior to processing ** also added NACK of 15.4 download message. 0 ** PCSC-174 5/20/98 This procedure no longer handles Unicast CDL messages. There is * * NO check for contiguous Tags, and no check for re-sends of a message. / 5 char Improved_DL_Code (voιd) { unsigned int l ; unsigned mt 3 , z ; unsigned char contιnue_download; 0 unsigned char ret_stat; contmue-_download = TRUE; /* ========================================================================== */ 5 switch ( msg_ιn.number ) /* which message are we processing ? */ /* ========================================================================== */ C /* ========================================================================== */ 0 case CMI_CDL_FILL_PATT: /* fill pattern message */ /* ========================================================================== * / for ( ι=0; Kmsg_in.dat .cdl_fιll_recv.num_bytes; ι++) 5 contιguous_dl_data[ι] = msg_ιn. dat. cdl_fιll_recv.pattern; /* fill in array */ Enable_EEprom( ) ; /* enable EEprom for writes ' */ ret_stat = Page_Wπte_EEPROM( (xdata unsigned t* ) --msg_m.dat .cdl_fιll_recv.addr , /* pointer to dest. addres */ U msg_ιn.dat.cdl_fιll_recv.num_bytes, /* DF # 4 = num_bytes */ contιguous_dl_data, /* pointer to source */ veπfy_page_wrιte ) ; /* verify flag */ Protect_EEprom( ) ; /* protectthe EE from writes */ ιf( ret_stat '= SUCCESS) 5 {/* the page write failed - indicate failure to the HECU */ Set_Up_A_Nack( PAGE_WRITE_FAILURE , / * reason */ ret_stat); /* support data: the failure code */ } __ break; 0 case CMI_CDL_NOR : /* download data message */ 5 Enable_EEprom( ) ; /* enable EEprom for writes */ ret_stat = Page_Wπte_EEPROM( (xdata unsigned int* ) __msg_m.dat .cdl_norm_.recv.addr, -n /* pointer to dest. addres */ 0 msg_ιn.dat.cdl_norm_recv.num_bytes, /* DF # 4 = num_bytes */ &msg_m. dat .cdl_norm_recv.dat [0] , /* pointer to source */ veπfy_page_wrιte ) ; /* verify flag */ Protect_EEprom( ) ; /* protect the EE from writes */ 65 if ( ret_stat '= SUCCESS) {/* the page write failed - indicate failure to the HECU */ Set_Up_A_Nack ( PAGE_WRITE_FAILURE, /* reason */ ret_stat); /* support data: the failure code */ } 70 break; case CMI_CDL_START_CON : /* start of a continuation load 75 /• ====__-__.=================================================================== /* This message allows for the HIC/HECU to send many packets of data, with the address and length overhead in 3 ust this message. It will be followed by CMI_CDL_CONT msgs until the length is satisfied. Once all data is in, the whole array will be written to EEprom in a page write. */ ιmproved_dl_struct.data_ιndex = MAX_NORM_DL_DATA; /* next place to store */ improved_dl_struct.num_bytes = msg_in.dat .cdl_strt_cont_recv.num_bytes ,- /* DF # 4 num_bytes * / ιmproved_dl_struct. address = (unsigned intlmsg_m.da .cdl_strt_cont_recv.addr; j=0; /* index into message data */ for ( 1=0; 1< MAX_NORM_DL_DATA; 1++ ) contιguous_dl_data[ι] = msg_m.dat .cdl_strt_cont_recv.dat [_ι++] ιmproved_dl_struct.ιn_use = TRUE; /* other places check this */ break,- / * ========================================================================== case CMI_CDL_CONT : /* a continuation load: see note on CMI_CDL_START_CONT */ /* ========================================================================== -/ l = ιmproved_dl_s ruct.data_ιndex; /* current index into array */ / * determine how much to read in */ z = ( (ιmproved_dl_struct.num_bytes - ιmproved_dl_struct .data_ιndex) < MAX_CONT_DL_DATA) ? (ιmproved_dl_struct.num_bytes - ιmproved_dl_struct .data_ιndex) : MAX_CONT_DL_DATA; for ( 3 =0; 3 < z; 3 ++,ι++ ) contιguous_dl_data[ι] = msg_m.da .cdl_cont_recv.dat [ 3 ] ; improved_dl_struct.data_mdex = l; /* next place to store */ if ( l >= ιmproved_dl_struct.num_bytes ) /* do we have all the data ? */ {/* yes: not checking for exect count: ok if its over, we will only write the exact amount to EE anyway */ Enable_EEprom( ) ; /* enable EEprom for writes */ ret_stat = Page_Wrιte_EEPROM(-ciιrtproved_dl_struct .address, /* pointer to dest. addres * / improved_dl_struct .num_bytes , contιguous_dl_data, /* pointer to source */ verl y_page_wrlte) ; / * verify flag */ Protect_EEprom( ) ; /* protect the EE from writes */ /* Clean up the data structure to indicate end */ ιmproved_dl_struct.m_use = FALSE; /* otner places check this */ ιf( ret_stat '= SUCCESS) {/* the page write failed - indicate failure to the HECU */ Set_Up_A_Nack ( PAGE_WRITE_FAILURE, /* reason */ ret_stat) ; /* support data: the failure code */ j J break, /- ========================================================================== -/ case CMI_CDL_FUTURE : /* special DL msg that has no code in ROM: jump to EE */ /* ========================================================================== */ /* IF the EEPROM has a bad checksum, the ROM code will never 3 um into EE. This message will "Allow" us to 3 ump to EE IT will 3 ump to code in the last EEprom sector to the Future_Stub ( ) which does a bunch of 3 unk and then returns This area of EE can be used to poke code, diagnostics or whatever, to get the ROM to ju p to it. What ever happens there is NOT defined here. /* 10 data fields in the msg that can be used ' ' ' */ Future_Stub() ; break; /* ========================================================================== * / default: /* these are not handled by this routine */ Set_Up_A_Nack( MSG_NOT_SUPPRTD_BY_ROM_CODE , / * reason */ msg_m.number) ; /* support data: the msg received */ break; }/* end switch */ return (contmue_download) ; } /* end ROM:Download_Code */ ** TITLE: Dnload_Code ** DESCRIPTION: This procedure coordinates the downloading of code to EEprom. ** Once this procedure is called, it becomes the main loop. It ** waits for a download sequence to end cleanly. ** ** INPUTS: ** load_flag - indicates who the originator is: PROM or EEPROM 10 * * OUTPUTS : * * None ** ** ASSUMPTIONS/LIMITATIONS: ** 15 ** Revision History: ** ** PCSC-122 2/17/98 This procedure now checks to see if Poll_Neuron is ** returning an error status. If it does, the Neuron ** will be reset. 0 # * ** PCSC-122 2/23/98 " Removed the xdata declaration on local variable l ** PCSC-174 6/2/98 Removed the timer stuff at the beg of this procedure. ** Removed the clearing of serial co minications variables. * PCSC-213 7/17/98 Added Flsuh msg type to this procedure 5 void Dnload_Code(char load_flag) { unsigned char dl_stat; 0 dl_stat = TRUE; /* indicate that a download is in progress */ /* ========================================================================== -/ if (load_flag == RELOAD ) /* is entry from eeprom resident code ? */ { /* yes - downloads can start from a request made to the code in EEprom */ 5 /* and the request must be replied to. The code in EEprom must ensure that*/ /* this message was supposed to be processed (accepting broadcast messages*/ /* for example ) */ /* ========================================================================== */ 0 FeedWDO; /* do not let WDT expire */ switch! msg_m.number ) /* which message was received ? 5 */ /* ========================================================================== */ { /* improved download commands (post Version 4 EEprom code) 50 */ /* case CMI_CDL_FILL_PATT: /* indicates a fill pattern */ case CMI_CDL_NORM : /* all data in one record */ case CMI_CDL_START_CON : /* start of a continuation load */ 55 case CMI_CDL_CONT : /* a continuation load */ case CMI_CDL_FUTURE : /* a future enhancement download */ Return_Message( ) ; /* acknowledge msg is processed*/ dl_stat = Improved_DL_Code ( ) ; /* process the download msg */ -_ break; 60 case CMI_CDL_RESET : /* CMI Reset instructions */ case CMI_CDL_FLUSH :/* indicates a "flush" of the Eeprom */ /. ========================================================================== OJ dl_stat = Proc_Mess ( ) ; /* process the Reset message and acknowledge */ break; /* ========================================================================== */ 70 default: /* these messages are not processed - send back a NACK */ /* ./ Send_Back_Nack ( /* Nack the message */ MSG_NOT_SUPPRTD_BY_ROM_CODE, /* reason code */ msg_m. number) ; /* support data */ 75 break; )/* end switch */ }/* end if this is a RELOAD */ / * ========================================================================== * / while (dl_stat)/* continue processing msgs while the download is not complete */ /. ========================================================================== { FeedWDO; /* don't let timer expire */ if (seπal_data_flag == TRUE) /* is there an RS232 message avail? */ /* ========================================================================== */ { /* yes - there is an RS232 message ready */ / * -/ memcpy ( _-msg_m.number, £.rs232_msg[0] , sizeof (msg_ιn) ) ; dl_stat = Proc_Mess ( ) ; /* process the message and Acknowledge */ } else /* there is no msg from RS232 avail */ { if (neuron_mεg_flag == TRUE) /* is there an HIC/HECU msg avail ? */ /* ========================================================================== */ { /* yes- there is a NEURON message from the HIC/HECU available */ /. /* Flash the COMMs LED: turn it on (on receipt)- off (on Response) */ led_save = (led_save & -COMMs_LED) ; /* LED on is a clear of just that bit*/ • (unsigned char xdata * ) LED_ADR = led_save; /* updates the actual LEDs */ Reset_Neuron_Tιmer ( ) ; Read_Neuron( (char xdata *) __msg_m.number) ; Reset_Comms_Timer_0 ( ) ; /* prior to processing, check the debug flag to see if we are to dump the input message out the RS232 spicket ' */ if ( dump_neuron_ιnput) { seπal_data_flag = TRUE ; / * will be cleared after the send * / Return_Message ( ) ; / * dump it out 232 * / send_msg_flg = TRUE; / * fix this back * / neuron_msg_flag = TRUE; / * fix this back */ } dl_stat = Proc_Mess ( ) ; /* process the message and acknowledge */ else/* there is no Neuron message available */ { if ( neuron_msg_flag == TIMEOUT_ERROR) /* does Neuron indicate an error 7 */ {/* yes - reset the Neuron */ Reset_Neuron ( ) ; } } }/* end if */ neuron_msg_flag = Poll_Neuron( ) , /* poll the Neuron for new messages */ } /* endwhile */ /* =========================================================================== */ /* The download has completed. */ /* This procedure will force the processor to reset, so that on reset, */ /* the prom code will go out and check the EEprom code (checksum) matches what*/ /* is in the EEprom, and if it is valid, it will then ju p to it */ /* =========================================================================== * / /* Force processor reset by performing invalid feed of watchdog */ Dιsable_T mer_0 ( ) ; /* do not allow the Interrupt handler to get us out of the infinite loop */ WFEED1 = 0xA5; /* reload with a small value */ while (1); /* forces a processor reset */ } /• end ROM:Dnload_Code */ /* END OF CMI BROADCAST DOWNLOAD CODE */ /* BEGIN HECU BROADCAST DOWNLOAD CODE • / * FILENAME: m_cmi_dl .cpp * * CSCI Name: HECU * * ABSTRACT: This class will handle the process of Broadcast Download to all the CMIs on a given HIC. The basic flow is such that the Inιtιate_Download method is called with the list of desired CMIs and the file to download passed to this method. Error checking is then performed in this method as well as in Perform_Fιle_Valιdatιon. Once validation is complete, a series of steps are performed with the use of Perform_Next_Step. Each step must be completed on ALL CMIs before proceeding to the next step. Upon startup, completion, or a failure that causes the process to be aborted, the Inιtιalιze_Class method will be called to perform cleanup of the class to prepare it for next use. * * REVISION HISTORY: * * CHANGE DOC. REV DATE ENGINEER DESCRIPTION * PCSC-357 12/7/98 Moody new file * ♦♦•★★★♦•♦♦a****-********************-***-***********************-************ * * "This material is considered and contains PROPRIETARY Information of * Sanders, a Lockheed-Martin Company. Disclosure to others, use or * copying without the express written consent of Sanders is strictly * probihited." * "(c) Copyright 1995, Sanders, a Lockheed Martin Company. * Unpublished work. All rights reserved. ♦include "m_cmι_dl.h" #ιnclude "defaults.h" tinclude <fstream.h> ♦include <dr.h> ♦include <stdιo.h> #defιne MYNL 10 #defιne LINESIZE 8192 * Name: Download_CMI_Class (constructor) * Class: Download_CMI_Class * Abstract: Initialize attributes * Rev History- * PCR Number Date Engineer Description * PCSC-152 3/31/98 Moody New ************************************************************** Download_CMI_Class. :Download_CMI_Class (HEC * parent) { //store pointer to parent parent_class = parent; //poll flag poll_flag = FALSE; //make call to function to initialize class attributes Imtιalιze_Class ( ) ; //Fill in the Valid Message Table Fιll_Valιd_Message_Table( ) , } * Name: Download_CMI_Class (destructor) * Class: Download_CMI_Class * Abstract: * Rev History: * PCR Number Date Engineer Description * PCSC-152 3/31/98 Moody New ********************* * * * ** ** *** * * * * * ****** ****** * ** * ***** * *** ** * **/ Download_CMI_Class :: -Download CMI Class ( ) { " " } * Name: Fιll_Valιd_Message_Table * Class: Download_CMI_Class * Abstract: Function to define the valid messages for each phase * Rev History: * PCR Number Date Engineer Description PCSC-152 4/30/98 Moody New Download_CMI_Class: :Fιll_Valιd_Message_Table ( ) { //initialize them first fordnt 1 = 0; l < NUM_M0DES; 1++) fordnt . = 0; J < MAX_MSG_TYPES ; _++ ) { Valιd_Message_Types [l] [ j ] = -1; } } //fill in valid values fordnt k = 0; k < NUM_MODEΞ; k++) { switch (k) { case FIND_CMIΞ: Valιd_Message_Types [k] [0] = rua_lost_cmi ; break; case WAKE_UP_CMIΞ : Valιd_Message_Types [k] [0! = act_cmι_msg; break; case DL_SECTOR_XSUMS : case DOWNLOAD_MESSAGES : Val d_Message_Types[k] [0] cmι_cdl_con , Valιd_Message_Types[k] [1] cmι_cdl_fιll_patt; Valιd_Message_Types [k] [2] cmι_cdl_norm; Valιd_Message_Types[k] [3] cmι_cdl_star _cont ; Valιd_Message_Types [k] [4] cmι_cdl_flush; break; case TURN_FLAGS_ON: Valιd_Message_Types [k] [0] = cmι_cdl_stat_ιnstr, break; case CALC_ΞECTOR_XΞUMS . Valιd_Message_Types [k] [0] = cmi_cdl_calc_sect_xs-_m, break, case GET_ΞECTOR_XSUMS Valιd_Message_Types [k] [0] = cmi_cdl_rpt_sect_xs--m, break; case VALIDATE_CMI_DL : Valid_Message_Types[k] [0] = cmι_power_stat_msg, break; case REΞET_CMIS: Valιd_Message_Types [k] [0] = cmι_cdl_reset ; break; default: case NONE: case FINISHED: case ABORT_MODE: break; } * Name: Inιtιalιze_Class * Class: Download_CMI_Class * Abstract: * Rev History: * PCR Number Date Engineer Description * PCSC-152 3/31/98 Moody New Download_CMI_Class: :Imtιalιze_Class( ) t broadcast_mode = NONE; HIC_ld = NULL; for dnt ι = 0; l < MAX_CMIS; ι++) fordnt _ = 0; _ < NUM_SECTORS; _-.+) { c_nι_number_array[_] [I] = DO_NOT_DOWNLOAD; cmι_status_array[ 3 ] [I] = NO_ERROR; , ' cmι_counter = 0; dl_fιle[0] = '\0'; nuirt_cmis = 0; num_bytes = 0; fιle_checksum = 0; fιle_pos = 0; steρ_flag = AUTO, for dnt J = 0; 3 < NUM_DL_PAGEΞ ; _++) pages_to_download[. ] = DO_N0T_DOWNLOAD ; } //call this to stop timer if it's on and to set reset flag to OFF dl_tιmer_flag = OFF; //set the parent class logging flag to ON parent_class->log_flag = TRUE; //restore parent poll flag ιf(poll_flag == TRUE) { parent_class->Pollmg_Enable = TRUE; poll_flag = FALSE; } force_state = FALSE; } * Name: Inιtιate_Download (broadcast) * Class- Download_CMI_Class * Abstract: Begin download for a sector of CMIs in broadcast * Rev History: * PCR Number Date Engineer Descπptio * PCSC-152 3/31/98 Moody New ****************************************************************** int Download_CMI_Class: :Inιtιate_Download(HIC * HlCm, int **cmι_ιds, char * file, /•sector*/, int force) { int Status = NO_ERROR; int CMI_IDs[NUM_SECTORS] [MAX_CMIS] ; if (cmι_ιds) { memcpyf (void *) CMI_IDs, (void *) cmι_ιds, NUM_ΞECTORS * MAX_CMIS * sizeof dnt) ) , } //make sure that we are in a mode that will allow a download ιf( (broadcast_mode '= NONE) && (broadcas _mode '= FINISHED) ) { Status = DOWNLOAD IN PROGRESS; } else { //initialize all of the class attributes Inιtιalιze_Class ( ) ; //set the class member attributes HIC_ιd = HlCm; strcpy(dl_fιle, file) ; force_state = force; ) //validate file checksum if (status == NO_ERROR) { status = Perform File Validation ( file) ; } - - //get and check the CMIs to download if (status == NO_ERROR) ιf (cmι_ιds ' = NULL) { for dnt 3 =0 ; 3 <NUM_ΞECTORS ; 3 + + ) { for dnt 1 = 0 ; 1<MAX_CMIS; 1 + + ) { if (CMI_IDs[3] [1) == GO_DOWNLOAD) { cmι_number_array [3 ] [ 1 ] = CMI_IDs [ 3 ] [1 ] , num cmιs++; ) else { c_rα_number_array [ 3 ) [ 1 ) = DO_N0T_DOWNL0AD , ) ιf (nu_n_cmιs == 0 ) status = NO_CMIS_SELECTED; } } else status = NO_CMIΞ_SELECTED; } / /begin the download process if (status == NO_ERROR) { if (parent_class->Pollmg_Enable == TRUE ) { poll_flag = TRUE , parent_class->Pollmg_Enable = FALSE , ) status = Perf oπr_Next_Step ( ) } / /set the remaining attributes if (Status == NO_ERROR) { //make call to update the interfaces parent_class->Update_DL_Status (broadcast_mode, (mt **) cmι_status_array) //set HEC flag parent_class->System_Mode_Flag = DOWNLOAD_MODE , ) else { //set the data back to initialized values Inιtιalιze_Class ( ) , return (status) ,- } * Name : Perform_Fιle_Valιdatιon • Class: Download_CMI_Class * Abstract: Verify that the file chosen has valid checksum * Rev History: * PCR Number Date Engineer Description * PCSC-152 3/31/98 Moody New ♦A****************************************************************/ int Download_CMI_Class: :Perform_Fιle_Val datιon(char * file) { int status = NO_ERROR; ifstream infile; ofstream outfile; //get handle to file stream and create buffer for line of code infile. open (file, los: :m| ιos: :binary| IOS: ocreate) ; //make sure file exists if (-infile) { Status = BAD_FILENAME ; } infile. close () ; if (status == NO_ERROR) { // If Extension == .cd2 / run through CRC-32 char Extension [5 ] ; char * Parse_FιleName = strrchr (flie, '.'); strcpy(Extensιon, ++Parse_FιleName) ,- char temp_fllename[MAX_FILENAME_SIZE] ; if (strcmp (Extension, "cd2") == 0) // Get Checksum from file char * Fιrst_Lme; char * Fιle_Check_Sum_Ptr; unsigned long Fιle_Check_Sum; Fιrst_Lme = new char [LINESIZE] ; FILE * fptr; fptr = fopen ( fιle , " rt" ) ; fgetε (Fιrst_Lme, LINESIZE, fptr) Fιle_Check_Ξum_Ptr = strchr (Fιrst_Lme , if (Fιle_Check_Sum_Ptr == NULL) { delete F rst_Lme ; fcloεe (fptr) ,- return (INVALID_FILE_DATA) ; } F le_Check_Sum_Ptr++ ; Fιle_Check_Sum = strtoul (Fιle_Check_Sum_Ptr, NULL, 10); // Create CRC Table in Memory unsigned long * CRC_Table; unsigned long CRC_For_Table; unsigned long CRC_Poly; mt tempi , temp3 ; CRC_Table = new unsigned long[256]; CRC_Poly = 0xEDB88320L; for (tempi = 0; tempi < 256; tempi-. + ) { CRC_For_Table = tempi; for(temp3 = 8; temp3 > 0; temp3--) { if (CRC_For_Table & 1) CRC__For_Table = (CRC_For_Table » 1) " CRC_Poly; } else CRC_For_Table »= 1 ; } ) CRC_Table[ tempi] = CRC_For_Table; } // Calculate crc int Lιne_Buf fer_Length; char * Lme_Buf fer; L e_Buffer = new char [LINESIZE] ,- 10 if (Lιne_Buffer == NULL) { fclose (fptr) ,- delete CRC_Table; delete Fιrst_Lιne; 15 return (INVALID_FILE_DATA) ; } unsigned long CRC_Save; unεigned long CRC_Code; 0 mt Trailing = 0; CRC_Save = CRC_Code = OxFFFFFFFFL; 5 Lme_Buf fer_Length = 1; while (fgets(Lme_Buf fer, LINESIZE, fptr) '= NULL) { char * Limit; 0 char * P; Lme_Buf fer_Length = strlen (Lme_Buf fer) ; Limit = Lme_Buffer + Lme_Buf f er_Length; 5 // Search for NewLme Characters and replace with '10' for(P = Lme_Buffer; P '= Limit; P++) { _ Λ lf(*P == '\n') 0 { *P = MYNL; } } 5 // Perform CRC algorithm on 1 line of input data fordnt l = 0; l < Lme_Buf f er_Length; ι++) { CRC_Code = CRC_Table[ (int) ( (CRC_Code) Λ (Lιne_Buf fer [l] ) ) OxFF] " ( 50 ( (CRC_Code) » 8) & OxOOFFFFFFL) ; } if (Lme_Buf fer_Length != 1) 55 CRC_Save = CRC_Code; ) } lfMTrailmg && Lιne_Buf fer_Length == 1) 60 { CRC_Code = CRC_Save; ) f close (fptr) ; 65 delete CRC_Table; delete Lme_Buffer; delete Fιrst_Lme; 70 ιf(CRC_Code '= Fιle_Check_Sum) { retur (INVALID_FILE_DATA) ; 75 //DO CRC CHECK HERE status = NO_ERROR; //Once CRC Check done, need to strip off first line of code from file //(remember, this is a temp file. The "real" file is still in the hicdl directory) strcpy(temp_fιlename, "c: WhecWtem Wtemp.bak" ) ; remove ( emp_fιlename) ,- 5 mfιle.open(flie, 10s: : in | 10s: : binary | ιos : :nocreate) ; outflie. open (temp_fιlen--me, 10s: :out 110s: : binary) ; //read m first line of infile char buf [80] ; 0 mfile.getlmefbuf ,79, ' \n' ) ; // Loop through input file and transfer remaining bytes to output file char ch; while dnf lle . get (ch) ) 5 { if (infile. fail!)) { status = INVALID_FILE_DATA; 0 outflie.put (ch) ; ) // Close the I/O files infile. closet ) ; 5 outflie. close! ) ; //rename temp file to output file remove ( file) ; rename (temp_fιlename, flie) , 0 > ) //make sure data is valid - check all characters then make sure segment IDs are valid Char buffer[MAX_LINE_SIZE] ; 5 char temp_sect [3] ; char temp_num[3 ] ,- int ι; if (status == NO_ERROR) 0 infile. open (file, ιos: :m| ιos: :bmary| ιos : :nocreate) ; infιle.seekg(O) ,- while ( ' infile . eof ( ) ) me (buf fer, MAX_LINE_ΞIZE) _LINE_SIZE ] = ' \0 ' , / /validate line size 0 i f ( strlen (buffer) < CODE_LINE_SIZE) { //make sure that we are not dealing with a last line that is 3ust padded //with blames and newlmes ford = 0; l < CODE_LINE_SIZE; ι++) 5 { //see if any valid chars - which there shouldn't be if dsxdigit (buffer [l] ) ) { Status = INVALID_FILE_DATA; 0 break; //out of for loop } else if (buffer[ι] == '\0') { break; //out of for loop 5 ) ) //now see if there lε actually another line to be read if (dnfile.eof () ) 0 { status = INVALID_FILE_DATA; ) //regardless of scenario, break out of while /5 break; //out of while } //check for valid chars - which they all should be ford = 0; l < CODE_LINE_SIZE; ι++) { if ( sxdigit (buffer [i] ) ) { Status = INVALID_FILE_DATA; break; //out of for loop } ) if (status '= NO_ERROR) { break; //out of while } //check the message number temp_num[0] = buffer[0]; temp_num[l] = bufferfl] ; temp_num[2] = '\0'; //convert the message number from a hex (radixlδ) val to a decimal and compare //to valid CMI DL range ιf( ( ( (mt)strtol (temp_num,NULL, 16) ) < fut_enhc_dl_msg) || ( ( (mt)strtol (temp_num,NULL, 16) ) > cmι_cdl_reset) ) { Status = INVALID_FILE_DATA; break; //out of while ) //check the sector temp_sect[0] = buffer [2]; temp_sect[l] = buffer [3]; temp_εect [2] = '\0'; //convert the sector from a hex (radιxl6) val to a decimal and compare if ( ( (ιnt)strtol(temp_sect,NULL,16) ) > CHECKSUM_ΞECTOR) { Status = INVALID_FILE_SEGMENT; break; //out of while } } inflie. close ( ) ; } return (status) ; } * Name: Message_Returned * Class: Download_CMI_Class * Abstract: Function indicating that a Dl message has returned from HIC/CMI * Rev History: * PCR Number Date Engineer Description PCSC-152 3/31/98 Moody New int Download_CMI_Clasε : :Meεsage_Returne (unsigned mt data [ ] , mt faιled_flag) { //retry counters static int reset_retrιes = 0; static mt calc_retπes = 0; //flag for use after the switch statement int ιndιvιdual_flag = FALSE; //status flag for function return int status = NO_ERROR, //Make a call to a function that will process the returned message - //pass it the message and the failed flag status = Handle_Return_Data(data, faιled_flag) ; //a switch that is based on the mode that we are in at the time - only want to //process if Handle_Return_Data didn't return an error indicating that the message //type was wrong for the mode we are n if (Status != INVALID_MESSAGE_TYPE) { switch (broadcast_mode) { case (FIND_CMIS) : case (TURN_FLAGS_ON) : 5 case (GET_SECTOR_XSUMS) : case (WAKE_UP_CMIS) : case (VALIDATE_CMI_DL) : reset_retrιes = 0; calc_retrιes = 0; 10 //set flag for use after switch statement mdιvιdual_flag = TRUE; break; caεe (CALC_SECTOR_XSUMS) : 15 if (status == BROADCAST_MSG_FAILED) { //see how many in a row 20 calc_retrιes = 0 ; status = Perf orm_Next_Step ( ) , break; ) 25 / /retry message status = Calc_Sector_Checksums ( ) ) else 30 { calc_retrιes = 0; status = Perform_Next_Step( ) ; } 35 (REΞET_CMIS) : if (Status == BROADCAΞT_MSG_FAILED) { //see how many m a row 40 reset_retrιes++ ; if (reεet_retπeε == 3) { reεet retπeε = 0; status = Perform_Next_Step ( ) 45 break; } //retry mesεage εtatus = Perform_Resets ( ) , 50 } else { reset_retrιes = 0; status = Perform_Next_Step ( ) ; 55 } break, case (DL_SECTOR_XSUMS ) : ^ case (DOWNLOAD_MESΞAGES) : 60 case (FINISHED) . reset_retπes = 0 ; calc_retπes = 0 ; status = Perf oπr_Next_Step ( ) ; , _ break; 65 case (NONE) : default: brea ,- 70 , } //if the message returned was not a broadcast message (sent to an //individual CMI), then we need to check some other stuff if (ιndιvιdual_flag == TRUE) 75 { //see which CMI is responding at temp_sector = (data(DINl) >>6) & 0x03; t cmι_number = data [DINl ) & 0x3F; / /verify that this CMI is supposed to be downloaded i f (cmι_number_array[ temp_sector] [cmι_number] == GO_DOWNLOAD) { //if we have found no errors above, then indicate a successful status //otherwise set the status flag to whatever the error was if (Status == NO_ERROR) if (cmι_status_array[ temp_sector] [cmι_number] == OPEN_STATUS) { cmι_status_array [temp_sector] [cmι_number] = GOOD_STATUS; } else ιf( (cmi_status_array[temp_sector] [cmι_number] == CMI_DID_NOT_RESPOND) SS (broadcast_mode == VALIDATE_CMI_DL) ) { cmι_status_array[temp_sector] [cmι_number] = GOOD_STATUS ; } else { cmι_status_array [ temp_εector] [cm _number] = status ; } //turn the download flag off for this CMI only if we've failed to //find the CMI through the RUA_LOΞT_CMI message - decrement the //number of CMIs we wish to Download ιf( (broadcast_mode == FIND_CMIS) && (status ' = NO_ERROR) ) cmι_number_array [ temp_sector] [cmι_number] = DO_NOT_DOWNL0AD; num_cmι s - - ; } else { //increment the counter cmι_counter++ ,- } //see if we're ready to go to next step if (cmι_counter == num_cmιs) { //check to see if there are any CMIs to be downloaded (did they all //not talk during FIND_CMIS stage???) if (broadcast_mode == FIND_CMIS) { status = COULDNT_FIND_CM ; for dnt 3 = 0; 3 < NUM_SECTORS; 3++) { fordnt 1 = 0; l < MAX_CMIS; ι++) { if ( crrα_number_array [ ] [ l ] == GO_DOWNLOAD) { status = NO_ERROR; break; } ) } if ( Status == NO_ERROR) / /go do the next step in the download process status = Perform_Next_Step ( ) ; } else { Cancel_Download( ) ; return (statuε) ; } } else { status = Perform_Next_Step ( ) ,- ) } ) } //make a call to the mam window to indicate DL εtatus if( (broadcast_mode != FINISHED) _.£_ (broadcast_mode != NONE) ) { parent_class->Update_DL_Status(broadcast_mode, dnt **) cmι_status_array) ; ) return ( status) ,- } / ...- .»,.......... * . * ... * ................... ..„..-.......... * * Name: Handle_Return_Data * Class : Download_CMI_Class * Abstract: validate and process the return data from the CMIs * Rev History: * PCR Number Date Engineer Description * PCSC-152 4/30/98 Moody New int Download_CMI_Class: :Handle_Return_Data (unsigned int data[], int faιled_flag) { int status = NO_ERROR,- //get CMI int sect = (data[DINl]»6) & 0x03; int cminum = data[DINl] & 0x3F; CMI * temp_cmι = HIC_ιd->Chιld_CMIs [sect] [cminum] ; if (temp_cmι == NULL) { status = NULL CMI; ) //call function to make εure the message type(s) are valid for the mode we are in if (status == NO_ERROR) status = Coπpare_Mesεage_Type (data [MESSAGE-ID] , faιled_flag ) ; } //do any other validation of the data that needs to be done if (Status == NO_ERROR) { if (faιled_flag == FAILED) //want to set status flag to an error condition { switch (broadcast_mode) { case FIND_CMIΞ: status = COULDNT_FIND_CMI ; break; case TURN_FLAGS_ON: case GET_ΞECTOR_XSUMS : status = CMI_DID_NOT_REΞPOND; break; case WAKE_UP_CMIS: case VALIDATE_CMI_DL : status = INVALID_RETURN_DATA; break,- default: case DL_ΞECTOR_XΞUMΞ : case CALC_SECTOR_XSUMS : case DOWNLOAD_MESΞAGES : case RESET_CMIΞ: status = BROADCAST_MΞG_FAILED; brea ; ) ) else //not a failed situation - want to perform actions based on message type { switch (broadcast_mode) { case TURN_FLAGS_ON: //make sure message has flags set properly ιf( (data[DIN3] != ACCEPT_BROADCAΞT_MSGS) |] (data[DIN5] ! = ACCEPT_DL_MSGS ) || (data[DIN7] != CLEAR_REPORT_AREA) ) { status INVALID_RETURN_DATA; } break; case GET_SECTOR_XSUMS : //store the sectors for which there are bad checksums to indicate which //sectors to download status = Store_Download_Ξectors (data) ; break; caεe DL_SECTOR_XSUMS : caεe DOWNLOAD_MESSAGES : case CALC_SECTOR_XSUMS : case RESET_CMIS: case FIND_CMIS: case WAKE_UP_CMIS: case VALIDATE_CMI_DL : default : break ; } } return (status) } * Name: Compare_Message_Type * Class : Download_CMI_Class * Abstract: verify that the message type returned is valid for that phase * Rev History: * PCR Number Date Engineer Description * PCSC-152 4/30/98 Moody New int Download_CMI_Class : : Compare_Message_Type ( mt data_value , int faιled_flag) { int status = NO_ERROR; if ( failed_flag ! = FAILED) { int succesε_flag = 0 ; for (mt l = 0; l < MAX_MSG_TYPES; ι++ ) { if (data_value Valιd_Message_Types [broadcast_mode] [l] ) { success_flag = 1; if ( ! success_f lag) { status = INVALID_MESSAGE_TYPE; ) return status; } ********* ************** * Name: Store_Download_Sectors * Class: Download_CMI_Class * Abstract: store the sectors of the CMI that need to be downloaded * Rev History: * PCR Number Date Engineer Description * PCSC-152 5/ 2 /98 Moody New mt Download_CMI_Clasε : : Store_Download_Sectors (unsigned mt data [ ] ) { mt Status = N0_ERROR; //make sure that the message checksum matches the DF10 checksum unsigned char checksum = 0; fordnt l = DIN2; l < DIN10; ι++ ) { checksum += data [ 1 ] ,- } if (checksum '= data . DINIO]) 5 status = INVALID_MEΞSAGE_CHECKSUM; } if (Status == NO_ERROR) 10 //if data[DIN9] is VALID (0), tnen the checksum on sector-57 (which contains //the checksums of the other 56 sectors) is OK and we can trust the mfo in //the reset of the bitmap if (data[DIN9] == 0) 15 fordnt l = DIN2; l < DIN9; ι++) { for dnt 3 = 0; 3 < 8; 3++) { __ iff (<data[ι]»3)∑-l) == 1) 20 { pages_to_download[8* d-DIN2)+3) = GO_DOWNLOAD; } 25 , ' elεe //εector that contains the checksumε lε bad εtatus = INVALID_SECTOR_CHECKSUM; } 30 return (status) , } 35 ***************************************************************** * Name: Perform_Next_Step * Class : Download_CMI_Class * Abstract: do the next step in the download process 40 * Rev History: * PCR Number Date Engineer Description * PCSC-152 4/29/98 Moody New A * lnt 45 Download_CMI_Class : : Perform_Next_Ξte ( ) { int status = NO_ERROR, if (step_flag '= MANUAL_WAIT) //it must be in AUTO or MANUAL_GO 50 { switch (broadcast_mode) { case NONE: status = Fmd_CMIs ( ) ,- 55 break,- case FIND_CMIS. status = Set_CMI_Flags ( ) ; break; 60 case TURN_FLAGS_ON: //set the parent class logging flag to FALSE parent_class->log_flag = FALSE; 65 status = DL_Sector_Checksums ( ) break,- case DL_SECTOR_XSUMS : //continue to download until an EOF is returned 70 status = DL_Sector_Checksums ( ) ; if (Status == END_OF_FILE) { //set the parent class logging flag to ON 75 parent_class->log_flag = TRUE; //Download is complete, so turn off the broadcast and download flags status = Calc_Ξector_Checksums ( ) ; brea ; case CALC_SECTOR_XSUMS : //continue to download until an EOF is returned if (dl_tιmer_flag == OFF) { //start the DL timer status = Set_DL_Tιmer () ; } else { //turn off the reset timer flag dl_tιmer_flag = OFF; //this was a broadcast message - change all open CMIs back to good for dnt 3=0;3<NUM_ΞECTORS;3++ ) { for (int 1 = 0; l < MAX_CMIS; ι++) { if (cmi_status_array[3l [I] == OPEN_STATUS) { cmι_status_array[3] [I] = GOOD_STATUS; } } ) //perform next step status = Get_Sector_Checksums ( ) ; break; case GET_ΞECTOR_XSUMS • //set the parent class logging flag to FALSE parent_class->log_flag = FALSE; status = Download_Fιle() ; //m this special case, if (status == ALL_SECTORS_DOWNLOADED) { //set the parent claεs logging flag to ON parent_class->log_flag = TRUE; //Download is complete, so turn off the broadcast and download flags status = Per orm_Resets ( ) , break, case DOWNLOAD_MEΞSAGES : //continue to download until an EOF or an ALL_ΞECTORS_DOWNLOADED is returned status = Download_Fιle( ) , if (status END_OF_FILE) { //current sector is complete - download next sector status = Download_Fιle( ) ; if (status ALL_SECTORΞ_DOWNLOADED) { //set the parent class logging flag to ON parent_class->log_flag = TRUE, //Download is complete, so turn off the broadcast and download flags εtatus = Perform_Resets ( ) ,- } break,- caεe REΞET_CMIS if (dl_tιmer_flag == OFF) //start the 15s reset timer status = Ξet_DL_Tιmer ( ) ; elεe { //turn off the reset timer flag dl_tιmer_flag = OFF; 5 //this was a broadcast message - change all open CMIs back to good for dnt 3 =0,-3<NUM_SECTORS;3-.+ ) { for dnt 1 = 0; l < MAX_CMIS; ι++) 10 if (cmι_status_array[3] [I] == OPEN_STATUS) { cmι_statuε_array [ 3 ] [ 1 ] = GOOD_STATUS; } 15 , ' //perform next step status = Wake_Up_CMIs ( ) ; 20 break; case WAKE_UP_CMIS: status = Valιdate_CMI_DL() ,- break; 25 case VALIDATE_CMI_DL : status = Download_Complete ( ) ; break,- 30 case FINISHED: default: break; ) ) 35 return status; } ***************************************************************** * Name: Fιnd_CMIs 40 * Class: Download_CMI_Class * Abstract: Send messages to all of the CMIs to find them * Rev History: * PCR Number Date Engineer Description * PCSC-152 4/1/98 Moody New -4-5 *********** * *** * * * ** * * *** ********* ****** ******* *** ********** ** ** ** int Download_CMI_Class : : Fmd_CMIs ( ) { int Status = NO ERROR; 50 //build message to send to CMIs MSG_PKT msg_out; msg_out.message_ιd = rua_lost_cmι ; msg_out.message_tag = 0; 55 for dnt 3 = D0UT2; 3 < MAX_DATA_BYTES ; 3++) { msg_out.data[3 ] = 0; ) 60 //set counter to 0 cmι_counter = 0 , //set mode flag broadcast_mode = FIND_CMIS; 65 for (3 = 0; 3 < NUM_SECTORS ; 3++) ( msg_out.data[D0UT2] = HIC_ιd->US_Prιmary_Chaι_nel [3 ] ,- msg_out.data[D0UT3] = HIC_ιd->UΞ_Dιversιty_Channel [3 ] 70 //send messages to CMI for (int 1 = 0; 1 < MAX_CMIS; 1++) { 1f (cmι_number_array [ 3 ] [ 1 ] == GO_DOWNLOAD) 75 { //set CMI id in datafield 1 msg_out.data[DOUTl] = (3<<6) + 1; //start the CMIs out as all being open cmι_status_array(3 ] [I] = OPEN_STATUS,- //place messages into queue parent_clasε->Send_Meεsage(msg_out, HIC_ιd, NO_POLL, INTERNAL, -1, -1, TRUE) , } return ( status ) ; } * Name: Set_CMI_Flagε * Class: Download_CMI_Class * Abstract: Send messages to all of the CMIs to set their Broadcaεt flags * Rev History: * PCR Number Date Engineer Description * PCSC-152 3/31/98 Moody New int Download_CMI_Class : : Set_CMI_Flags ( ) int status = NO_ERROR; //build message to send to CMIε MSG_PKT mεg_out; msg_out.message_ιd = cmι_cdl_εtat_ιnεtr; mεg_out.message_tag = 0; msg_out.data[D0UT2] = OxOB; //data integrity msg_OUt.data[DOUT3] = ACCEPT_BROADCAΞT_MSGΞ ; msg_out.data[DOUT4] = OxOE; //data integrity msg_out.data[DOUT5] = ACCEPT_DL_MSGS ; msg_out.data(DOUT6] = OxOE; //data integrity msg_OUt.data[DOUT7] = CLEAR_REPORT_AREA; msg_out.data[DOUT8] = OxOF; //data integrity ιnsg_out.data[DOUT9] = 0; msg_out.data[DOUT10] = 0; //set counter to 0 cmι_counter = 0; //set mode flag broadcast_mode = TURN_FLAGS_ON; for dnt 3 = 0; 3 < NUM_SECTORS; 3++) { //send messageε to CMI for dnt ι = 0; l < MAX_CMIS; ι++ ) { if ( cmι_number_array [ 3 ] [I] == GO_DOWNLOAD) { //set CMI id in datafield 1 msg_out.data[DOUTl] = (3<<6) + l; //set status flag to 'open' if it hasn't failed any steps so far if (cmι_status_array[3] [l] == GOOD_STATUS) { cmι_εtatus_array[3 ] [l] = OPEN_STATUS ; } //place messages into queue parent_class->Send_Message(mεg_out, HIC_ιd, NO_POLL , INTERNA ,-1 ,-1 , TRUE ) } return (status) ; } /* ........... * .. * ..,.. * ,, * .,., * ,,,...», ** , * ,,.,,., * . *** ,, * * ... * ... * Name: DL_Sector_Checksumε * Class: Download_CMI_Clasε * Abstract: Send messages to the CMIs to download the sector checksums * Rev History: * PCR Number Date Engineer Description * PCSC-152 4/30/98 Moody New .. **** . * ». * ........... * ........ * .. * ...... * ...... * .... * .. * ... * ..... / Download_CMI_Clasε : :DL_Sector_Checksums ( ) { int Status = NO_ERROR; mt l , 3 ,- //set broadcast mode broadcast_mode = DL_ΞECTOR_XΞUMΞ ; //this function handles the downloading of a given sector. Need to scan the //download file to find those lines status = Download_Sector(CHECKSUM_SECTOR) ; //see if status returned indicates END_OF_FILE or an error switch (status) { case COULDNT_FIND_FILE_SECTOR: case INVALID_FILE_DATA: case INCORRECT_SECTOR_REQUES : //since this is a critical step in the download process, we need //to abort if we got an error in the Download_Sector file for (3 = 0; 3 < NUM_SECTORΞ ; 3++) { for (1 = 0; 1 < MAX_CMIS; 1++) { if (cmι_status_array[3] [1] == OPEN_ΞTATUS) { cmι_εtatus_array [3 ] [1 ] = status; ) ) ) brea ,- case NO_ERROR: //this lε a broadcast message - change all good CMIs to open for (3 = 0; 3 < NUM_ΞECTORS; 3++) { for (1 = 0; 1 < MAX_CMIS; 1++) { if (cmι_status_array[3 ] [1] == GOOD_ΞTATUS) { cmι_status_array [3 ] [1] = OPEN_ΞTATUS; ) } } break; caεe END_OF_FILE: //this is a broadcast message - change all open CMIs back to good for (3 = 0; 3 < NUM_SECTORS ; 3++) { for (1 = 0; 1 < MAX_CMIS; 1++) { if (cmι_statuε_array [ 3 ] [ 1 ] == OPEN_STATUS) { cmι_status_array[ 3 ] [ 1 ] = G00D_ΞTATUS ; } } } break; default: //do nothing break; } return (status); * ..... * ... * .... *** .. * ..»..,.,,. ** . ** .,, * . **** ,,,.. ***** .. ** , * ,,, * * Name: Calc_Sector_Checksums * Claεs: Download_CMI_Class * Abstract: Send mesεages to the CMIs to instruct that they calculate * the sector checksums * Rev History: * PCR Number Date Engineer Description * PCSC-152 4/30/98 Moody New int J Download_CMI_Clasε : : Calc_Sector_Checksums ( ) { t Status = NO_ERROR; //if user chose to force all checksums to be downloaded, then ignore steps 0 //or asking CMIs to calculate them and go right to download step if (force_state == TRUE) { for dnt 3 = 0 ; 3 < NUM_DL_PAGES ; 3 ++ ) 5 pages_to_download ( 3 ] = GO_DOWNLOAD; } Download_Fιle ( ) ,- return status ; } 0 //set mode flag and make sure timer flag is OFF dl_tιmer_flag = OFF; broadcast_mode = CALC_SECTOR_XSUMS,- 5 //build message to send to CMIs MSG_PKT msg_out ,- msg_out message_ιd cmι_cdl_calc_sect_xsum msg_out message_tag 0; msg_out data[D0UT2] OxOB //data integrity 0 mεg_out data[D0UT3] 0; msg_out data[DOUT4) OxOE //data integrity msg_out data[D0UT5] 0; msg_out data[DOUT6] OxOE //data integrity msg_out data[DOUT7] 0; 5 ιnsg_out data[D0UT8] OxOF //data integrity msg_out data[DOUT9] 0; msg_out datalDOUTIO] 0; //set counter to 0 0 cmι_counter = 0; //broadcast message msg_OUt.data[DOUTl] = BROADCAΞT_MASK; parent_clasε->Send_MesΞage(msg_out, HIC_ιd, NO_POL , INTERNA ,-1 ,-1 , TRUE) ; 5 //this is a broadcast message - change all good CMIs to open for (mt 3 = 0; 3 < NUM_SECTORS; 3 ++) { for ( t 1 = 0; 1 < MAX_CMIS; 1++ ) 0 { if (cmi_status_arrayt3) [1] == GOOD_ΞTATUS) { cmι_status_array [ ] ] [ 1 ] = OPEN_STATUΞ ; } 5 } ) return (status) ,- } 0 / * .... * . * ., * ... * .,.,,., * ,..,...., * , ***** .,, ** ,....,. * ., *** .... * , * , * Name: Get_Sector_Checksums * Class: Download_CMI_Class * Abstract: Send messages to the CMIs to get their sector xsum flags 5 * Rev History: * PCR Number Date Engineer Description * PCSC-152 4/30/98 Moody New . * * .. * .,....,..,., * .. * ,,, * ,, * * * , * , * . * * , , * ... * * ...,.... , * * * .. * * . * . * / mt 0 Download_CMI_Class : :Get_Sector_Checkεums ( ) { int Status = NO_ERROR; / /build message to send to CMIs 5 MSG_PKT msg_out ; msg_out .message_ιd = cmi_cdl_rpt_sect_xsu_n; msg_out .message_tag = 0 ; fordnt 1 = DOUT2; l < MAX_DATA_BYTES ; 1++) ( msg_out . data [ l ] = 0; //set counter to 0 cmι_counter = 0; //set mode flag broadcast_mode = GET_SECTOR_XSUMS ; for (int 3 = 0; 3 < NUM_SECTORS; 3++) { //send messages to CMI for dnt 1 = 0; l < MAX_CMIS; ι++ ) { lf ( cmi_number_array[3][ι] == GO_DOWNLOAD) { //set CMI id in datafield 1 msg_out.data[DOUTl] = (3<<6) + l; //set status flag to 'open' if it hasn't failed any stepε so far if (cmι_status_array[3] [l] == GOOD_STATUS) cmι_status_array[3] [l] = OPEN_STATUS; } //place messages into queue parent_clas8->Send_Meεεage(msg_out, HIC_ιd, NO_POLL , INTERNAL ,-1 ,-1 , TRUE ) ; return ( status ) ; } / ***************************************************************** * Name: Download_Fιle * Class: Download_CMI_Clasε * Abstract: Read download file and broadcaεt meεsageε to the CMIs * Rev History: * PCR Number Date Engineer Description * PCSC-152 4/7/98 Moody New ****************************************************************** int Download_CMI_Class : : Download_Fιle ( ) { int statuε = NO_ERROR; //a static variable to keep track of which sector we are downloading static int dl sector = -1; //set the dl_sector if(dl_sector == -1) { int 1 = 0; while! (pages_to_download[ι] == DO_NOT_DOWNLOAD) &-. d < NUM_DL_PAGES) ) { 1++; } lf(l '= NUM_DL_PAGES ) { //want to set the sector_to_dl flag to 'ι', which was determined to //be the next sector to download. Also want to set that sector' ε //dl flag to false, so it won't get re-downloaded dl_sector = l; pages_to_download[ι] = DO_NOT_DOWNLOAD; } else //no more sectors to download Status = ALL_ΞECTORΞ..DOWNLOADED, //set mode broadcast_mode = DOWNLOAD_MESSAGES; lflstatuε =-= NO_ERROR) { //this function handles the downloading of a given sector. Need to scan the //download file to find those lines status = Download_Sector (dl_sector) ; } //see if status returned indicates END_OF_FILE or an error switch (status) { case END_OF_FILE: case COULDNT_FIND_FILE_ΞECTOR: case INVALID_FILE_DATA: caεe INCORRECT_SECTOR_REQUES : //if END_OF_FILE, we want to set the dl_sector flag back to -1 εo it will //determine the next sector to download, if one of the error conditions, //want to skip this sector and go to the next sector dl_sector = -1; break; caεe NO_ERROR: //thiε is a broadcast message - change all good CMIs to open for (3 = 0; 3 < NUM_SECTORS; 3++) { for (1 = 0; 1 < MAX_CMIΞ; 1++) if (cmi_status_array[3) [1] == GOOD_STATUΞ) { cmι_status_array[3] [1] = OPEN_STATUΞ; } ) } break,- case ALL_SECTORΞ_DOWNLOADED : //this is a broadcast message - change all open CMIs back to good for (3 = 0; 3 < NUM_ΞECTORΞ ; 3++) { for (1 = 0; 1 < MAX_CMIS; 1++ ) t if (cmι_εtatuε_array[3] [1] == OPEN_STATUS) { cmι_εtatuε_array [3 ] [1] = GOOD_STATUS, } } dl_sector = -1; break; default: //don't do anything - the sector is not finished being downloaded brea ; } return (status) ,- ) * Name: Perform_Resets * Class: Download_CMI_Class * Abstract: Function to send reset messages to all of the good CMIs * Rev History: * PCR Number Date Engineer Description PCSC-152 3/31/98 Moody New ... * ......, ** ....,,, * ,,. * .,...,.. * ... * . **** .». * ,., * ,...,,.,.,... * ,/ int Download_CMI_Class : : Perform_Resets ( ) { int statuε = NO_ERROR; //build meεsage to send to CMIs MSG_PKT msg_out; msg_out.message_ιd = cπu_cdl_reset; msg_out.meεεage_tag = 0; msg_out . ata [DOUT2 ] OxOB; //data integrity msg_out .data [DOUT3 ] 0; msg_out . at [DOUT4 ] OxOE; //data integrity msg_ou . ata [DOUT5 ] RESET_FROM_EEPROM; msg_out . ata [DOUT6 ] OxOE; //data integrity msg_out . ata [DOUT7 ] DL_RESET; //perform reset _nsg_out .data [DOUT8 ] OxOF; //data integrity msg_out .data [DOUT9 ] 0; -nsg_out .data [DOUT10 ] 0; 10 //set counter to 0 cmi counter = 0; //set mode flag 15 dl_tιmer_flag = OFF; broadcast_mode = RESET_CMIS; //broadcast message msg_out.data[DOUTl] = BROADCAST_MASK; 20 parent_class->Send_Message(msg_out, HIC_ιd, NO_POLL, INTERNAL,-1 ,-1 , RUE) //this is a broadcast message - change all good CMIs to open for dnt 3 = 0; 3 < NUM_SECTORS ; 3++) 25 for dnt 1 = 0; 1 < MAX_CMIS; 1++) { i (cmι_status_array[ 3 ] [1] == GOOD_STATUS) { cmi_status_array[ 3 ] [1] = OPEN_ΞTATUS, 30 ) ) } __ return (status); 35 } ***************************************************************** * Name: Wake_Up_CMIs * Class: Download_CMI_Claεε 40 * Abstract: Function to re-activate CMIs * Rev History: * PCR Number Date Engineer Description ****** * ** * * * *** ** * ** * * ******* * * *** ** * **** * *********** * * ** * ** ******/ ,, mt 45 Download_CMI_Class : :Wake_Up_CMIε ( ) { mt statuε = NO_ERROR; //build message to send to CMIs 50 CMI * temp_cmι ; MSG_PKT msg_out; msg_out .message_ιd = act_cmι_msg; insg_out.message_tag = 0; for (int 3 = DOUT2; 3 < MAX_DATA_BYTES ; 3++) 55 { msg_out . data [ 3 ] = 0 ; ) //set counter to 0 60 cmι_counter = 0; //set mode flag broadcast_mode = WAKE UP CMIS; 65 //build common part of message structure msg_out.data[4] = HIC_ιd->DS_Channel; msg_out.data[5] = HIC_ιd->DS_Channel_Type; msg_out . data [ 6 ] = (HIC_ιd->PCS_Channel_-1792) »8; msg_out.data[7] = HIC_ιd->PCS_Channel_-255; 70 msg_out.data[9] = 0; for (3 = 0; 3 < NUM_SECTORΞ; 3 ++) { //build sector portion of mesεage εtructure 75 msg_out.data[2] = HIC_ιd->UΞ_Pπmary_Channel [3 ] , msg_out.data[3] = HIC_ιd->US_Dιversιty_Channel [3 ] ; //loop thru CMIs for dnt 1 = 0; l < MAX_CMIS; ι++) { if (cmι_number_array[3] ti] = GO_DOWNLOAD) { temp_cmι = HIC_ιd->Chιld_CMIs [3 ] [1] ; 1f ( temp_cmι • = NULL) { //set status flag to 'open' if it hasn't failed any steps so far 1f (cmι_εtatuε_array [ 3 ] [ 1 ] == GOOD_STATUS) { cmι_status_array[3 ] [1] = OPEN_STATUS; } //build CMI portion of message structure msg_out.data[DOUTl] = (3<<6) + 1; msg_out.data[DOUT2] = te_πp_cmι->State + (temp_cmι->Autostat<<l) + (temp_cmι->DS_Autogaιn«2) + (LAΞT_KNOWN_STATE«3) + (temp_cmι->Alarm_Dιsposιtιon«4) + (temp_cmι->UΞ_Autogaιn«5) ; msg_out.data[DOUT9] = te_np_cmi->PA_State + (temp_cmι->Prιm_Rcv_State«l) + (temp_cmι->Dιv_Rcv_State«2) ; //place mesεageε into queue parent_class->Send_Message(msg_out, HIC_ιd, NO_POLL, INTERNAL,-1 , - l.TRUE) ; else cmι_statuε_array[3] [1] = COULDNT_FIND_CMI ,- } return (εtatus) ; } ***************************************************************** * Name: Valιdate_CMI_DL * Clasε- Download_CMI_ClaεΞ * Abstract: Function to get the updated checksum flags of the CMIs * Rev History: * PCR Number Date Engineer Description ****************************************************************** int Download_CMI_Class : :Valιdate_CMI_DL ( ) { t status = NO_ERROR; //build message to send to CMIs MSG_PKT msg_out, msg_out .message_ιd = cmι_power_stat_mεg; msg_out.meεεage_tag = 0; for dnt 1 = D0UT2; 1 < MAX_DATA_BYTES ; 1++) { msg_out .data[ι ] = 0, } //set counter to 0 cmι_counter = 0; //set mode flag broadcast_mode = VALIDATE_CMI_DL ; for dnt 3 = 0; 3 < NUM_SECTORS; 3+ + ) { //send messages to CMI for dnt 1 = 0; l < MAX_CMIS; ι++) ς t J if (cmι_number_array[3] [1] == GO_DOWNLOAD) { //set CMI id in datafield 1 msg_out.data[DOUTl] = (3«6) + l; 10 //set status flag to 'open' if it hasn't failed any steps so far lf (cmι_status_array [ 3 ] [ l ] == GOOD_STATUS) { // cmι_status_array[3] [3] = OPEN_STATUS; cmι_status_array[3] [1] = OPEN_STATUS; 15 } //place messages into queue parent_class->Send_Meεsage(msg_out, HIC_ιd, NO_POLL, INTERNAL, -1, -1,TRUE) } 20 return (status) ,- } 25 / ***************************************************************** * Name: Download_Complete * Class : Download_CMI_Class * Abstract: Function to send statuε requeεtε to CMI 30 * Rev History: * PCR Number Date Engineer Description * PCSC-152 4/10/98 Moody New ft ***************************************************************** / • Oa*. D in ow t nload_CMI_Class: :Download_Complete(mt cancel_f lag) { int status = NO ERROR ,- MSG_PKT msg_out; 40 msg_out.message_tag = 0; for dnt 3 = 0; 3 < MAX_DATA_BYTEΞ; 3++) { msg_out . data [ 3 ] = 0 ,- } 45 if (cancel_flag == NOT_CANCEL) { //set mode flag broadcast_mode = FINISHED, 50 //need to finish by sending status meεsageε to each of the CMIs //to get the HECU updated for dnt 3 = 0; 3 < NUM_ΞECTORS; 3++) { 55 //now εend out εtatus update messages msg_out.data[D0UT2] = HIC_ιd->US_Pπmary_Channel [3 ] ; for dnt 1 = 0; 1 < MAX_CMIS; 1++) { 60 if (cmι_number_array [3 ] [1] == GO_DOWNLOAD) { msg_out.data[DOUTl] = (3<<6) + 1; // send attenuator status message 65 msg_out.message_ιd = cmι_att_stat_msg; parent_ciass->Send_Message (msg_out, HIC_ιd, N0_P0LL, INTERNAL, -1, -1, TRUE) ; // send c i version number message msg_out.message_ιd = cιrα_read_ver_msg ; 70 parent_claεs->Send_Mesεage(mεg_out, HIC_ιd, N0_P0LL, INTERNAL, -1, -1, TRUE) , // send freq stat message msg_out .message_ιd = c_r_ι_freq_stat_msg; parent_class->Send_Mesεage(msg_out, HIC_ιd, N0_P0LL, INTERNAL, -1, -l.TRUE) , 75 // send power status message msg_out .message_ιd = cmι_power_stat_mεg, msg_out.data[DOUT3] = HIC_ιd->US_Dιversιty_Channel [3 ] ; parent_class->Send_Message(msg_out, HIC_ιd, NO_POLL, INTERNAL, -1, -1,TRUE) , // send message to get cmi faults in read mode msg_out.message_ιd = cmι_enable_faults; msg_out .message_tag = 0; msg_out.data[DOUT2] = 0; msg_out.data[DOUT3] = 0; msg_out.data[DOUT10] = 0; parent_clas8->Send_Message(msg_out, HIC_ιd, NO_POLL, INTERNAL, -1,-1, TRUE) , // Send Messages to get cmi fault limits in read mode msg_out.message_ιd = cmι_set_fault_lιmιt_2; msg_out.message_tag = 0; msg_out.data[DOUT10] = 0; parent_class->Send_Message(msg_out, HIC_ιd, NO_POLL, INTERNAL, -1, -1,TRUE) ; msg_out .message_ιd = cmι_set_fault_lιmιt; parent_class->Send_Message(msg_out, HIC_ιd, NO_POLL, INTERNAL, -1, -1, TRUE) ; else //set mode flag broadcaεt_mode = ABORT_MODE; //send mesεage out to turn off broadcast/download flags msg_out .message_ιd = cmι_cdl_stat_ιnstr; msg_out . data [ D0UT2 ] = OxOB, //αata integrity msg_out.data[DOUT3] = DO_NOT_ACCEPT_BROADCAST_MSGS ; msg_out.data[DOUT4] = OxOE; //data integrity msg_out.data[DOUT5] = DO_NOT_ACCEPT_DL_MSGS ; msg_out.data[DOUT6] = OxOE; //data integrity mεg_out.data[DOUT7] = DO_NOT_CLEAR_RPT_AREA; msg_out.data[DOUT8] = OxOF; //data integrity msg_out.data[DOUT9] = 0; msg_out .data [DOUT10] = 0; //broadcast message msg_out.data[DOUTl] = BROADCAΞT_MASK; parent_class->Send_Message(msg_out, HIC_ιd, NO_POLL, INTERNAL ,-1 ,- 1 , TRUE) ; //need to reεet function that handles downloading of code Download_Sector (0,TRUE) ; ) //call function to notify parent class (HEC) that the download is complete parent_claεε->Update_DL_Ξtatuε (broadcast_mode, (int **) cmι_status_array) , //turn off mode flag parent_clasε->Syεtem_Mode_Flag = NO_MODE; //call function to re-initialize all class members Inιtιalιze_Class ( ) ; return (status) ; } /.. * ..... * ... * ... *** ....,. ** ., ***** . *** ............ **** ... * ... * ... * Name: Download_Sector * Clasε: Download_CMI_Claεs * Abstract: Function to download a particular sector of the CMI * Rev History: * PCR Number Date Engineer Description * PCSC-152 5/6/98 Moody New .. * .. * ... * ......, * ... * . * ..... * ... ** .. *** ,., * ... *** ., ***** . * . *** .. * / int Download_CMI_Class : :Download_Sector dnt sector, mt cancel_flag) { //status flag to return int Status = NO_ERROR; //temp buffers char buffer[MAX_LINE_SIZE] char temp_sect [3] ; //this variable will let us know if we need to go to a different part of //the file or continue with the portion we are working on static int current_sector = -1; //if we cancelled the download, we want to set the "current_εector" flag //to -1 so that on the next download we won't get errors, if (cancel_flag == TRUE) { current_sector = -1; return status ,- } //get handle to file stream and create buffer for line of code ifstream infile (dl_fιle, IOS: :m| ιos: : binary| ιos: :nocreate) ; //if the current sector equals the sector pasεed in, it lε a normal download //else - if the current sector is NOT equal to the passes sector, then we need //to check to be sure that current_sector is -1, indicating that there is //not a DL in progress for a different sector if (current_sector == sector) { //set the file pointer to the laεt known position, get the code, //store the new position infιle.seekg(fιle_pos) ; infile. getlmelbuffer, MAX_LINE_ΞIZE) ; buffer [CODE_LINE_SIZE] = '\0'; fιle_pos = mfile. tellgl ) ; //make sure buffer size is OK if ( strlen (buffer) '= CODE_LINE_SIZE ) //check code size ιf( strlen (buffer) == 0) Statuε = END_OF_FILE; else status = INVALID_FILE_DATA; //whether or not line is good, εet sector = -1 current_sector = -1; } //see if the sector field is the same as the current sector if (Status == NO_ERROR) { temp_sect[0] = buffer [2], temp_sect [1] = bu fer [3]; temp_εect [2] = '\0',- if ( ( (mt)strtol (temp_sect,NULL, 16) ) '= current_sector) { //reset the current sector and set status flag to indicate there //are no more lines in this sector current_sector = -1; Statuε = END_OF_FILE; } ) } else //current_sector ' = sector { if (current_sector '= -1) { //current sector was already εet to a different sector current_sector = -1; Status = INCORRECT_SECTOR_REQUEΞT; } else //legitamately starting a new sector { //reassign the current sector current_sector = sector,- //set the file pointer to the beginning of the file fιle_poε = 0; mfιle.seekg(fιle_pos) ; //εearch through file until find a line with correct sector id mt success_flag = FALSE; do{ //store current position, get line, store new position infile. getlmelbuffer, MAX_LINE_SIZE) ,- buffer [CODE_LINE_SIZE] = '\0'; 5 fιle_pos = infile. tellg( ) ; //get the sector temp_sect[0] = buffer[2]; temp_sect[l] = buffer [3]; 10 temp_sect[2] = '\0'; / /convert the sector from a hex (radιxl6) val to a decimal and compare if ( ( (mt) strtol (temp_sect,NULL, 16) ) == current_sector) 15 success_flag = TRUE; break; } } while ( strlen (buffer) == (CODE_LINE_SIZE) ) ; 20 //see if we did not break out of do/while loop if (succeεε_flag == FALSE) { statuε = COULDNT_FIND_FILE_SECTOR; _,_ current_sector = -1; 25 } } } //close the file 30 inf le. close! ) ,- //send message to the CMIs in broadcast mode if (status == NO_ERROR) 35 int l = 0, 3 = 0, index = 0; char temp_str[3],- mt datafιeld[DATA_PACKET_SIZE] ; //want to get two characters at a time, stopping at the return char - alεo 40 //use the check of 'l' for CODE_LINE_SIZE as a boundary check while ( <buffer[ι] '= '\r') -.£. d < CODE_LINE_SIZE) ) { while (3 < 2) 45 temp_str[3] = buffer[ι]; D++; l++; } 50 tertp_str [ 3 ] = ' \0 ' ; 3 = 0 ; datafιeld[ index] = (unsigned char) strtol ( temp_str , NULL, 16 ) ; mdex-. + ; 55 } //build the download message MSG_PKT msg_out; msg_out.message_ιd = (MΞG_ID) datafιeld[MESSAGE_ID] ; 60 msg_out.message_tag = 0; //set DF #2 thru DF #10 ford = D0UT2; l < MAX_DATA_BYTEΞ ; ι++ ) 65 msg_out . ata [ l ] = (unsigned char) datafιeld[ι+OVERHEAD_BYTES] ; } //broadcast mesεage mεg_out.data[DOUTl] = BROADCAST_MASK; 70 parent_clasε->Send_Message(msg_out, HIC_ιd, NO_POLL, INTERNAL, -1 , -1 , TRUE) , } return (status) ; } 75 * Name: Set_DL__Tιmer * Class: Download_CMI_Class * Abstract: Function to activate a timer to let the CMIs reset * Rev History: * PCR Number Date Engineer Description * PCSC-152 4/10/98 Moody New *.*........*..**..*.....*.*..*******.*....*..*.*.*.....*...*.*.*. * / int Download_CMI_Class : : Set_DL_Tιmer ( ) int Status = NO_ERROR; // f SetTimer returns a 0, operaton has failed, so set status flag accordingly if (parent_class->Set_DL_Tιmer ( ) == 0) Status = COULDNT_SET_DL_TIMER; } else { dl_tιmer_flag = ON; } return (status) ; ) /.—. * Name: Stop_Reset_Tιmer * Class: Download_CMI_Class * Abstract: Function to stop the CMI reset timer * Rev History: * PCR Number Date Engineer Description * PCSC-152 5/13/98 Moody New _...*..*......*....*****..**.**********.... * .****.** ***** . * ......*/ void Download_CMI_Class : : Stop_DL_Tιmer ( ) { //Call to parent class which will call parent window to stop timer parent_class->Ξtop_DL_Tιmer ( ) ,- ) /* ****.... * **** * *******.********.***.******.**.*********.*** * Name: DL_Tιmer_Complete * Clasε: Download_CMI_Class * Abstract: Outside clasε indicating that reset timer is complete * Rev History: * PCR Number Date Engineer Description * PCSC-152 4/29/98 Moody New .....*......***.*..*».*.**,..,**»*.*.*....*.*. ** * ***** .... * ,*. * ..*/ int Download CMI_Class: :DL Timer Complete!) { " ~ int Status = NO_ERROR; if (dl_tιmer_flag == ON) //make call to perform next step status = Perform_Next_Step ( ) ; ) if (Status ! = NO_ERROR) { Cancel_Download ( ) ,- } else parent_class->Update_DL_Status (broadcast_mode , dnt * * ) cmi_status_array) ; } return ( status) ; } / ..... ** .. * . * ..,...,, * ,.,... ** .... * . ** . ** , ** ,..,,.,. * . * ...,. * * .. * . * Name: Cancel_Download * Class: Download_CMI_Class * Abstract: Outside clasε indicating that reset timer is complete * Rev History: * PCR Number Date Engineer Description * PCSC-152 4/29/98 Moody New *...*........**..*...*........**..*..**...**....*.*.*.*.. * ...*..** int Download_CMI_Class: :Cancel_Download( ) -- < 5 Stop_DL_Tιmer ( ) ; Download_Complete (CANCEL) ; return (NO_ERROR) ; 10 } * Name: Get_Step_State * Class : Download_CMI_Clasε 15 * Abstract: return the current step state * Rev History: * PCR Number Date Engineer Description * PCSC-152 4/29/98 Moody New 20 ** *" *** *** *********************************** " ****************** / Download_CMI_Class : : Get_Step_State ( ) { retur (step_f lag) ; } 25 ..........., * .... * ** . * .. * .. * .. * * * .. * ... ** ........... * . * .. * * * ... * . * Name: Set_Step_State * Clasε: Download_CMI_Class * Abstract: set the current step εtate 30 * Rev History: * PCR Number Date Engineer Description * PCSC-152 4/29/98 Moody New * ....... ** . ** . *** ... * ... * ......... ************ . ** . * .» ** . * .. * ...., * / ■J-. nt JJ Download_CMI_Class: :Set_Step_State(mt flag) { step_flag = flag; return (NO_ERROR) ,- 40 } It will be appreciated that the above described system is more efficient in the downloading of information to the cable microcell integrators due to the hybrid unicast/broadcast mode of operation. Additional efficiencies in the downloading of information include the data formatting techniques indicated in the program listing below, written in C and batch instructions. Of importance is one 45 efficiency due to the fact that in the broadcast mode addresses are not necessary. This frees up the address blocks so that data can be placed therein. By way of overview, the purpose of the code referred to as HEX2CDL is to convert the output file of a cable microcell integrator compilation (HEX) to a CDL file format that takes advantage of the cable microcell integrator's broadcast download messages. CDL messages are 50 ordered in the CDL file in such a way as to allow the head end control unit to quickly download checksums of a new image to the cable microcell integrators and to allow easy access and sending of any specific sector of the cable microcell integrator code. Each sector of this code is represented by the smallest number of CDL messages possible. In detail, what follows is a list of the tasks that are done by the HEX2CDL code. First, the HEX2CDL code separates the ROM code from the EEPROM code. Note that ROM code does not 5 get downloaded. The EEPROM is broken into Fifty-Seven 512 byte sectors (0-56 inclusive). A 32 bit checksum is calculated for each sector. A checksum is placed inside messages marked as sector 56 (0x38). These checksum messages are in order, Sector 0 first, and are placed at the top of the CDL file. Each Sector of EEPROM code is processed to produce the minimum number of CDL messages and Run Length Encoding. All messages pertaining to a Sector are grouped together. The 10 tag field of each message contains the sector number, which is how the head end control unit can download any specific sector. Each line of the CDL is a separate message all ready to be sent by the head end control unit. More particularly, the following is a sample CDL Output file. Comments are to the right of // and are not part of the file. Typically there are about 3000 lines to a CDL file. The 3rd and 4th -15 Character in each line is considered to be the TAG byte, 0x38 = sector 56 which tells the HECU it is checksum information The F000 is the address to write 3B3800F000E400010CD50001 //Checksum information in each line until the tag = 0 37380003370000D2AFOOOOE9 //each checksum is 4 bytes, 20 37380029000107FD0000F8AD 3738000001FE000001FEOOOO 37380001FE000001FE000001 25 373800FOA0000028C3000000 3B00008000F9E4906771F0E4 //first line of Sector 0, write it at address 0x8000 37000090676FF0E4906770F0 //The above message is a Start of block 0x3B, this message is 0x37 Block 30 . //Continuation message 393500EA00FCFF0000000000 // There is no code in sector 0x35 (53 decimal) FF 35 is the blank Character 393500EAFCFCFF0000000000 // One wants to erase anything that might have been there before 393500EBF806FF0000000000 // One can accomplish replacing 512 bytes with these 3A3500EBFE02FFFF00000000 // 4 messages 393600EC00FCFF0000000000 // Start of Sector 54, it too is blank 393600ECFCFCFF0000000000 393600EDF806FF0000000000 3A3600EDFE02FFFF00000000 393700EE00FCFF0000000000 393700EF26D8FF0000000000 3B3700EEFC2AFFFFFFFF9066 // Some code exists in sector 55 starting at address OxEEFF 373700DAE0FAA3E0FB9066DC 373700E0FD7C00EB2DFFEA3C 373700FE9066D8EEF0A3EFF0 37370074002508F50822FFFF 3A3700EFFE02FFFF00000000 rem re B OCKSEG.BAT rem rem The batchfile makes 55 calls of the blockout executable to process rem all the files created by condseg.bat rem rem blockout segOOOO.zzc segOOOO.blo blockout segOOOl.zzc segOOOl.blo blockout seg0002.zzc seg0002.blo blockout seg0003.zzc seg0003.blo blockout seg0004.zzc seg0004.blo blockout εeg0005.zzc seg0005.blo blockout segOOOβ.zzc segOOOβ.blo blockout seg0007.zzc seg0007.blo blockout seg0008.zzc seg0008.blo blockout seg0009.zzc seg0009.blo blockout segOOOA.zzc segOOOA.blo blockout segOOOB.zzc segOOOB.blo blockout segOOOC.zzc segOOOC.blo blockout segOOOD.zzc segOOOD.blo blockout segOOOE.zzc segOOOE.blo blockout segOOOF.zzc segOOOF.blo blockout segOOlO.zzc seg0010.blo blockout segOOll.zzc segOOll.blo blockout seg0012.zzc seg0012.blo blockout seg0013.zzc seg0013.blo blockout seg0014.zzc seg0014.blo blockout seg0015.zzc seg0015.blo blockout segOOlβ.zzc segOOlδ.blo blockout seg0017.zzc seg0017.blo blockout segOOlδ.zzc segOOlδ.blo blockout seg0019.zzc seg0019.blo blockout segOOlA.zzc segOOlA.blo blockout segOOlB.zzc segOOlB.blo blockout segOOlC.zzc segOOlC.blo blockout segOOlD.zzc segOOlD.blo blockout segOOlE.zzc segOOlE.blo blockout segOOlF.zzc segOOlF.blo blockout seg0020.zzc seg0020.blo blockout seg0021.zzc seg0021.blo blockout seg0022.zzc seg0022.blo blockout seg0023.zzc seg0023.blo blockout seg0024.zzc seg0024.blo blockout seg0025.zzc seg0025.blo blockout seg0026.zzc seg0026.blo blockout seg0027.zzc seg0027.blo blockout seg0028.zzc seg0028.blo blockout seg0029.zzc seg0029.blo blockout seg002A.zzc seg002A.blo blockout seg002B.zzc seg002B.blo blockout seg002C.zzc seg002C.blo blockout seg002D.zzc seg002D.blo blockout seg002E.zzc seg002E.blo blockout seg002F.zzc seg002F.blo blockout seg0030.zzc seg0030.blo blockout seg0031.zzc seg0031.blo blockout seg0032.zzc seg0032.blo blockout seg0033.zzc seg0033.blo blockout seg0034.zzc seg0034.blo blockout seg0035.zzc seg0035.blo blockout seg0036.zzc seg0036.blo blockout seg0037.zzc seg0037.blo rem rem rem C0 DSEG.BAT rem rem This batch file makes a call to condence for each of the segment files rem generated by GENSEGS rem rem condense segOOOO. zzz FF segOOOO con segOOOO. zzc condense segOOOl. zzz FF segOOOl con segOOOl. zzc condense seg0002. zzz FF seg0002 con seg0002. zzc condense seg0003. zzz FF seg0003 con seg0003. zzc condense seg0004. zzz FF seg0004 con seg0004. zzc condense seg0005. zzz FF seg0005 con seg0005. zzc condense segOOOβ. zzz FF segOOOβ con segOOOβ. zzc condense seg0007. zzz FF seg0007 con seg0007. zzc condense seg0008. zzz FF seg0008 con seg0008. zzc condense seg0009. zzz FF seg0009 con seg0009. zzc condense segOOOA. zzz FF segOOOA con segOOOA. zzc condense segOOOB. zzz FF segOOOB con segOOOB. zzc condense segOOOC. zzz FF segOOOC con segOOOC. zzc condense segOOOD. zzz FF segOOOD con segOOOD. zzc condense segOOOE. zzz FF segOOOE con segOOOE. zzc condense segOOOF. zzz FF segOOOF con segOOOF. zzc condense segOOlO. zzz FF segOOlO con segOOlO. zzc condense segOOll. zzz FF segOOll con segOOll. zzc condense seg0012. zzz FF seg0012 con seg0012. zzc condense seg0013. zzz FF seg0013 con seg0013. zzc condense seg0014. zzz FF seg0014 con seg0014. zzc condense seg0015. zzz FF seg0015 con seg0015. zzc condense segOOlβ. zzz FF segOOlβ con segOOlβ. zzc condense seg0017. zzz FF seg0017 con seg0017. zzc condense seg0018. zzz FF seg0018 con seg0018. zzc condense seg0019. zzz FF seg0019 con seg0019. zzc condense segOOlA. zzz FF segOOlA con segOOlA. zzc condense segOOlB. zzz FF segOOlB con segOOlB. zzc condense segOOlC. zzz FF segOOlC con segOOlC. zzc condense segOOlD. zzz FF segOOlD con segOOlD, zzc condense segOOlE. zzz FF segOOlE con segOOlE zzc condense segOOlF. zzz FF segOOlF con segOOlF. zzc condense seg0020. zzz FF seg0020 con seg0020. zzc condense seg0021. zzz FF seg0021 con seg0021. zzc condense seg0022. zzz FF seg0022 con seg0022. zzc condense seg0023. zzz FF seg0023 con seg0023. zzc condense seg0024. zzz FF seg0024 con seg0024, zzc condense seg0025. zzz FF seg0025. con seg0025. zzc condense seg0026. zzz FF seg0026 con seg0026. zzc condense seg0027. zzz FF seg0027. con seg0027. zzc condense seg0028. zzz FF seg0028. con seg0028. zzc condense seg0029. zzz FF seg0029. con seg0029. zzc condense seg002A. zzz FF seg002A, con seg002A. zzc condense seg002B. zzz FF seg002B, con seg002B. zzc condense seg002C. zzz FF seg002C. con seg002C. zzc condense seg002D. zzz FF seg002D. con seg002D. zzc condense seg002E. zzz FF seg002E. con seg002E. zzc condense seg002F. zzz FF seg002F. con seg002F. zzc condense seg0030. zzz FF seg0030. con seg0030. zzc condense seg0031. zzz FF seg0031. con seg0031. zzc condense seg0032. zzz FF seg0032. con seg0032. zzc condense seg0033. zzz FF seg0033. con seg0033. zzc condense seg0034. zzz FF seg0034. con seg0034. zzc condense seg0035. zzz FF seg0035. con seg0035. zzc condense seg0036. zzz FF seg0036. con seg0036. zzc condense seg0037. zzz FF seg0037. con seg0037. zzc rem *******★★***★★***★*****★**************************+******** rem rem GROUPOUT.BAT rem rem The batchfile group the output of the condence and blockout stages rem into one file that can be processed by TAGINC to set the tag field rem to be the same as the 2 HEX character before the . in the filename, rem The last character of the input file to TAGINC will be changes to a rem to incate Processed, and this will be used as the output file. rem rem copy segOOOO. con + segOOOO. io segOOOO. zzc >nul taginc segOOOO. zzc foo -N copy segOOOl. con + segOOOl. bio segOOOl. zzc >nul taginc segOOOl. zzc foo -N copy seg0002.con + seg0002.blo seg0002.zzc >nul taginc seg0002.zzc foo -N copy seg0003.con + seg0003.blo seg0003.zzc >nul taginc seg0003.zzc foo -N copy seg0004.con + seg0004.blo seg0004.zzc >nul taginc seg0004.zzc foo -N copy seg0005.con + seg0005.blo seg0005.zzc >nul taginc seg0005.zzc foo -N copy segOOOβ. con + segOOOβ. bio segOOOβ. zzc >nul taginc segOOOβ. zzc foo -N copy seg0007.con + seg0007.blo seg0007.zzc >nul taginc seg0007.zzc foo -N copy segOOOδ.con + segOOOδ.blo seg0008.zzc >nul taginc segOOOδ.zzc foo -N copy seg0009.con + seg0009.blo seg0009.zzc >nul taginc seg0009.zzc foo -N copy segOOOA. con + segOOOA. bio segOOOA. zzc >nul taginc segOOOA. zzc foo -N copy segOOOB. con + segOOOB.bio segOOOB. zzc >nul taginc segOOOB. zzc foo -N copy segOOOC. con + segOOOC.bio segOOOC. zzc >nul taginc segOOOC. zzc foo -N copy segOOOD.con + segOOOD.bio segOOOD. zzc >nul taginc segOOOD. zzc foo -N copy segOOOE. con + segOOOE.bio segOOOE. zzc >nul taginc segOOOE. zzc foo -N copy segOOOF. con + segOOOF.bio segOOOF. zzc >nul taginc segOOOF. zzc foo -N copy segOOlO.con + segOOlO.blo segOOlO.zzc >nul taginc segOOlO.zzc foo -N copy segOOll. con + segOOll.bio segOOll. zzc >nul taginc segOOll. zzc foo -N copy seg0012.con + seg0012.blo seg0012.zzc >nul taginc seg0012.zzc foo -N copy seg0013.con + seg0013.blo seg0013.zzc >nul taginc seg0013.zzc foo -N copy seg0014.con + seg0014.blo seg0014.zzc >nul taginc seg0014.zzc foo -N copy seg0015.con + seg0015.blo seg0015.zzc >nul taginc seg0015.zzc foo -N copy segOOlβ. con + segOOlβ.bio segOOlβ. zzc >nul taginc segOOlβ. zzc foo -N copy seg0017.con + seg0017.blo seg0017.zzc >nul taginc seg0017.zzc foo -N copy segOOlδ.con + segOOlδ.blo segOOlδ.zzc >nul taginc segOOlδ.zzc foo -N copy seg0019.con + seg0019.blo seg0019.zzc >nul taginc seg0019.zzc foo -N copy segOOlA.con + segOOlA.blo segOOlA.zzc >nul taginc segOOlA.zzc foo -N copy segOOlB.con + segOOlB.blo segOOlB.zzc >nul taginc segOOlB.zzc foo -N copy segOOlC.con + segOOlC.blo segOOlC.zzc >nul taginc segOOlC.zzc foo -N copy segOOlD.con + segOOlD.blo segOOlD.zzc >nul taginc segOOlD.zzc foo -N copy segOOlE.con + segOOlE.blo segOOlE.zzc >nul taginc segOOlE.zzc foo -N copy segOOlF.con + segOOlF.blo segOOlF.zzc >nul taginc segOOlF.zzc foo -N copy seg0020.con + seg0020.blo seg0020.zzc >nul taginc seg0020.zzc foo -N copy seg0021.con + seg0021.blo seg0021.zzc >nul taginc seg0021.zzc foo -N copy seg0022.con + seg0022.blo seg0022.zzc >nul taginc seg0022.zzc foo -N copy seg0023.con + seg0023.blo seg0023.zzc >nul taginc seg0023.zzc foo -N copy seg0024.con + seg0024.blo seg0024.zzc >nul taginc seg0024.zzc foo -N copy seg0025.con + seg0025.blo seg0025.zzc >nul taginc seg0025.zzc foo -N copy seg0026.con + seg0026.blo seg0026.zzc >nul taginc seg0026.zzc foo -N copy seg0027.con + seg0027.blo seg0027.zzc >nul taginc seg0027.zzc foo -N copy seg0028.con + seg0028.blo seg0028.zzc >nul taginc seg0028.zzc foo -N copy seg0029.con + seg0029.blo seg0029.zzc >nul taginc seg0029.zzc foo -N copy seg002A.con + seg002A.blo seg002A.zzc >nul taginc seg002A.zzc foo -N copy seg002B.con + seg002B.blo seg002B.zzc >nul taginc seg002B.zzc foo -N copy seg002C.con + seg002C.blo seg002C.zzc >nul taginc seg002C.zzc foo -N copy seg002D.con + seg002D.blo seg002D.zzc >nul taginc seg002D.zzc foo -N copy seg002E.con + seg002E.blo seg002E.zzc >nul taginc seg002E.zzc foo -N copy seg002F.con + seg002F.blo seg002F.zzc >nul taginc seg002F.zzc foo -N copy seg0030.con + seg0030.blo seg0030.zzc >nul taginc seg0030.zzc foo -N copy seg0031.con + seg0031.blo seg0031.zzc >nul taginc seg0031.zzc foo -N copy seg0032.con + seg0032.blo seg0032.zzc >nul taginc seg0032.zzc foo -N copy seg0033.con + seg0033.blo seg0033.zzc >nul taginc seg0033.zzc foo -N copy seg0034.con + seg0034.blo seg0034.zzc >nul taginc seg0034.zzc foo -N copy seg0035.con + seg0035.blo seg0035.zzc >nul taginc seg0035.zzc foo -N copy seg0036.con + seg0036.blo seg0036.zzc >nul taginc seg0036.zzc foo -N copy seg0037.con + seg0037.blo seg0037.zzc >nul taginc seg0037.zzc foo -N rem ******HEX2CDL RAT******************************* ©echo off REM TEST THE INPUT PARAMETERS IF %1N0THING==N0THING GOTO USAGE IF %2N0THING==N0THING GOTO USAGE rem Now clean up from before if exist tempi. hex del tempi. hex if exist chkmsg.msg del chkmsg.msg for %%f in (*.zzp) do del %%f for %%f in (*.zzc) do del %%f for %%f in (*.con) do del %%f for %%f in (*.blo) do del %%f for %%f in (*.zzz) do del %%f rem First convert to hex with width of 6 convert %1 tempi.hex -NO6 rem Then generate the CDL checksum messages for each code sector cdlcheck tempi.hex -M > chkmsg3δ .msg rem foo is ignored, TAGINC w/ _N as 3rd param generates its own filename taginc chkmsg38.msg foo -N rem Generate 55 file one for each segment of the EEPROM rem filenames will be segOOOO. zzz thru seg0037.zzz rem the numbers in the filename are HEX indicating the segment number gensegs tempi.hex rem Then remove the FF's from the 55 segment files call condseg rem Now remove all contigious download blocks into messages call blockseg rem now I need to group the output of condseg with blockseg then change the tags rem to indicate to the hecu which segment of EEPROM they are call groupout rem Now create the final output file from all the *.zzP files from taginc rem the checksum messages head off the file copy chkmsg3δ.msP %2 >nul for % f in (*.zzp) do type %%f » %2 rem Now clean up if exist tempi.hex del tempi.hex if exist chkmsg.msg del chkmsg.msg for %%f in ( * . zzp) do del %%f for %%f in ( * . zzc) do del %%f for %%f in ( * .con) do del %%f for %%f in ( * .bio) do del %%f for %%f in ( * . zzz) do del %%f goto END :USAGE ECHO. ECHO. ECHO. ECHO. ERROR ! ! ! ECHO. ECHO. ECHO.USAGE: ECHO. ECHO. %0 FILE1 FILE2 ECHO. ECHO. HERE FILE1 = INPUT FILE: IN HEX FILE FORMAT ECHO. FILE2 = OUTPUT FILE: SEGMENTED MESSAGE FILE F. .. " J TO DOWNLOAD ECHO. ECHO.THIS UTILITY CONVERTS A HEX FILE TO A SEGMENTED MESSAGE FILE CONTAINING A ECHO. SERIES OF DOWNLOAD MESSAGES WITH THE TAG FIELD INDICATING THE SEGMENT NUMBER. ECHO. ECHO. ECHO. ECHO. ECHO. ECHO. ECHO. ECHO. -.END rem this causes CR before prompt echo . /*** BLOCKOUT. C ***/ ♦include <stdio.h> ♦include <εtdlib.h> ♦include <string.h> ♦include "constant .h" ♦include "helpers. c" ♦include "proto.h" /* Function Prototypes */ long Locateϋong Start, t which); //mt Hex_Value(char c) ,- //unsigned int Get_Address(char *Lιne) ,- //mt Get_Bytes(voιd) ; //void Dump_Data(voιd) ,- //int Generate_Hex_F le(FILE *fpout, mt OutputByteε) int Generate_Msg_Fιle(FILE *fpout, mt bufsize); ♦define ARRAY_SIZE 32768L //oxFFFF - 0x8000 Valid EEPROM Range ♦define MAX_BUFSIZE OxFF //CMI MAX Buffer s ze ♦define MIN_BUFSIZE OxOF //CMI MIN Buffer size ♦define DEF_BUFSIZE OxFF //CMI DEFAULT Buffer size ♦define CMI_CDL_CHECKSUM 0x38 //CMI Checksum msg ♦define CMI_CDL_FILL_PATT 0x39 //CMI Fill pattern msg (RLE) ♦define CMI_CDL_NORM 0x3A //CMI Nomral DL message ♦define CMI_CDL_START_CONT 0x3B //CMI Continuation msg started with START_CONT ♦define CMI_CDL_CONT 0x37 //CMI Continuation sg started with ΞTART_CONT ♦define CMI CDL_STAT_INSTR 0x36 //CMI Download instructions/status ♦define BYTEΞ_IN_NORM_MSG 6 ♦define BYTEΞ_IN_START_CONT_MSG ♦define BYTEΞ_IN_CONT_MSG 9 ♦define END_OF_Z_STRING 0 ♦define START_OF_Z_ΞTRING 1 //♦define BYTES_PER_CONT_MSG 6 //number of bytes in a continuatin message ♦define DATA_ΞTART 32768L //Decima; form of Ox-jOOO ♦define LINE_LENGTH 81 //Input and output line length ♦define MAX_BYTES_PER_LINE 50 //If you up thiε best up lme_length too ' */ char Inline [LINE_LENGTH] ; char Outline [LINE_LENGTH] ; char c; //This is the character currently under evaluation /* The [0] element of thiε arrary lε the data at hex address 0x6000, which is DATA_START (decimal) so, If I convert the 4 char Hex address to a decimal and then subtract DATA_START I have the index to the array where the data for the hex record is to εtart. The data in the array lε 3ust hex characters Data [address] [0] holds the Most significant hex character and Data [address] [1 ] holds the other cnaracter. */ char huge Data [ARRAY_SIZE] [2] ; unsigned mt tempadd ; unsigned t minadd, axadd; int Nbytes; //Number of data bytes on the line unsigned mt address; //Decimal version of addreεs, remember to subtract 0x8000 //before using to index array unsigned long Fιle_Checksum; I la. 32 bit checksum will be appended to file & to screen, used by downloader int OutputBytes ,- //Number of data bytes on the line of the output file - ********* _ int Generate_Msg_Fιle(FILE *fpout, mt bufsize) This routine maximizes the use of the START_CONT_MΞG and CONT_MΞG messages to minimize the amount of messages sent to the CMI for a download. unsigned mt 1,3, address; char done=0; long εtartB, stopB; //start and stop of a block of contiguos code. int Max_Byte8_Per_Block; //an mt < 256 long size; //size in bytes of the contigious section of code nt blocks; //a block holds the maximum # of contig bytes we can send to CMI buffer t Max_N_of_CONT_Msgs; int bytes_to_send; int num_CONT_msgs ,- Max_N_of_CONT_Msgs = dnt) ( (bufεize - BYTES_IN_START_CONT_MSG ) / BYTES_IN_CONT_MSG ); Max_Bytes_Per_Block = (Max_N_of_CONT_Msgs * BYTES_IN_CONT_MΞG) + BYTEΞ_IN_ΞTART_CONT_MΞG; 1=0; startB=0;address=0; if ( (Data[0][0] == 'Z') &-< (Data[0][0] == 'Z') ) { //started with void area, look for non -Z starting point StartB=Locate(0,END_OF_Z_STRING) ; address = startB; ) while ( done '= 1) { //Starting at startB find the next ZZ that indicates the end of a contiuous run of data stopB=Locate ( startB, START_OF_Z_STRING) ; //find end of contig data size = stopB - startB; //Num. of contig bytes if ( size > 0 )//end of array yet { address = startB; i ( εize > BYTES_IN_NORM_MΞG) I Is. full block lε 255 bytes of data blocks = (size / Max_Bytes_Per_Block) ,- //full blocks //will we have a partial block ?? ■» if ((size - (blocks * Max_Bytes_Per_Block) ) > BYTEΞ_IN_NORM_MSG ) blocks-.-., while ( (blocks > 0) &_. (size > BYTES_IN_NORM_MΞG ) ) { blocks-- ; bytes_to_send = mm(Max_ ' Bytes_Per_Block, size); //first the START_CONT_MSG message fpnntf (fpout, "%2X" , CMI_CDL_START_CONT) , //msg # fprmtf (fpout, "0000%4X" , (address+DATA_START) ) ; fprmtf (fpout, "%02X" , bytes_to_send) ; for(ι=0, ι< BYTES_IN_ΞTART_CONT_MSG ; ι++) { fprmtf (fpout, "%c%c" , Data [address] [0] , Data [address] [1] ) , addresε ++; bytes_to_εend-- ; „ .//end for fprmtf (fpout, " \n" ) ; //now all the CONT_MΞG messages num_CONT_msgs = (bytes_to_εend /BYTEΞ_IN_CONT_MSG) ; //are we going to need a spill over message if ( (byteε_to_send - (num_CONT_msgs *BYTES_IN_CONT_MΞG) ) > 0 ) num_CONT_msgs++ ; //limmit to the max num_CONT_msgs = mini num_CONT_msgs, Max_N_of_CONT_Msgs) , for (1=0; l < nu_n_CONT_msgs ; ι + + ) { fprmtf (fpout, "%2X" ,CMI_CDL_CONT) ; //msg fprmtf (fpout, "0000") ; //cmi # and tag for (3=0; 3< BYTEΞ_IN_CONT_MΞG ; 3++> { if ( address < stopB ) fprmtf (fpout, "%c%c" , Data [address] [0] , Data [address] [1] ) address++ ,- size-- ; } else fprmtf ( fpout , " 00 " ) ; / /pad w/ 0 ' s )//end for fpπntf ( fpout , " \n" ) ; }//end for }//end while (blocks < 0 ) //we have a case where we have leεs byteε than needed to start a block //we will send a normal down load mesεage fprmtf (fpout, "%2X" ,CMI_CDL_NORM) ; 000%4X" , (address-. DATA_START) ) ; fprintf (fpout, "0%X",sιze) ; else fprintf (fpout, "%2X", size) ; for (i=0,-i<sιze;i++ ) { //dump out the data byteε fprintf (fpout, "%c%c" , Data [address] [0] , Data [address] [1] ) ; address++ ; } for (ι=0; ι< (BYTES IN NORM MSG - size) ; ι++ ) { / /padd the data if neccesεary fprmtf ( fpout , " 00 " ) ; ) fprintf (fpout, " \n" ) ,- )//end if )//end if ( size > BYTES_IN_NORM_MSG) else { //need to generate a CMI_CDL_NORM message fprintf (fpout, "%2X" ,CMI_CDL_NORM) ; 000%4X" , (address-. DATA_START) ) ; fprintf (fpout, "0%X" .size) ; else fprintf ( fpout, "%2X" , size) ; for (ι=0; KΞize,- 1++ ) { //dump out the data bytes „ fprmtf (fpout, "%c%c" , Data [address] [0] , Data [address] [1] address-. + ; j fprmtf (fpout, "\n" ) ; ) //end elεe startB = LocatelstopB, END_OF_Z_STRING) ; //fmd start of next run of contig data } elεe { done = 1 ; / /we are outa here ) }//end while return (0) ,- //success ) //end function Generate_Msg_Fιle int main dnt argc, char *argv[]) { char c; long l ; FILE *fpιn; //Input file pointer FILE *fpout; //Output file pointer t bufsize; Fιle_Checksum = 0; maxadd = 0; minadd = OxFFFF; lf ( (argc < 3 ) | | (argc > 4) | | ( (argc == 4) __. (argv[3][0] ' = '-') &£- (argv[3][l] ■= 'N' ) ) fprintf (stderr, "USAGE: %s Input_Fιle Output_Fιle -Nxx\n" , argv[0]); fprintf (stderr, "This utility will read in a partial HEX file and generate\n" ) ; fprintf (stderr, "Messageε using CMI_CDL_START_CONT followed by several\n" ) ; fprintf (stderr, "CMI_CDL_CONT messages. The -Nxx option allows the user to\n" ) ; fprintf (stderr, "specifly the CMI buffer size. The xx in the -Nxx are two HEX \n"), fprintf (stderr, "Characters that specify the number of bytes in the CMI buffer. \n"), fprintf (stderr, "Ex: -N64 (100 bytes) By Default 256 (OxFF) byte buffer is usedΛn"); fprintf (stderr, "Range of N : OxOF <= N <= OxFF \n\n"),- return 1; ) if ( (fpm=fopen(argv[l] , "rt" ) ) == NULL) fprmtf (stderr, "Cannot open input file %s\n" , argv[l] ) ,- return 1 ; } if ( (fpout=fopen(argv[2] , "wt" ) ) == NULL) { fprintf (stderr, "Cannot open output file %s\n" , argv[2] ) ; return 1; for (1=0; K ARRAY_SIZE; 1++) { C='F' ; Data[ι][0] = c; //remember t's characters and F's are blanks Data [l ] [1 ] = c,- ) if ( (argc==4) &.& (argv[3][0] == '-') &.= (argv[3][l] == 'N' ) ) { if ( (argc==4) S.& ( lsxdigit (argv[3 ] [2 ] ) S.& lsxdigit (argv[3 ) r . ] ) ) ) { //the user is specifying the width c = argv[3] [2] , bufsize = 16 * Hex_Value ( c ) ,- c = argv[3] [3] ,- bufsize += Hex_Value (c) ; if (bufsize > MAX_BUFΞIZE ) { fprintf (stderr, "Error- N value > %d\n" ,MAX_BUFSIZE) ; return 1, } if (bufsize < MIN_BUFΞIZE ) { fprintf (stderr, "Error: N value < %d\n" ,MIN_BUFΞIZE) ; return 1 , ) } else fprintf (stderr, "You must provide a valid 2 character HEX value after -N\n"); return 1 ,- } elεe { bufsize = DEF_BUFSIZE; } / /blank out the array for d = 0 ; KARRAY_SIZE; ι++ ) { Data[ι] [0] = 'Z' ; Data [ l ] [ 1 ] = ' Z ' ,- ) while! ( fgets (Inline, LINE_LENGTH-1 , fpin) ) ) { if (Inline [8] '= '1') //a 1 in this loc . indicates last line { //Process the input line if (lnlme[0] != • :') { fprintf (stderr, "Invalid Hex file %s: %s, \n" ,argv[l] , InlmetO] ) ; return 1 ,- Nbytes=Get_Byteε ( --Inline [0 ]) ,- address = Get_Address(&Inline[0] ) ; //starting address from HEX line //Now for as many CHARACTERS m the input line, stuff them into the Data array for (ι=0; κ(Nbytes*2) ; ι+=2) //each byte has 2 hex characters { if ( address >= DATA_START ) //then we need to put it into array //otherwise it'ε ROM Code & we dont care { if (address > maxadd) maxadd = address; if (address < m add) minadd = address ; //Data always starts at the 9th character c = Inlme[9+ι]; tempadd=address-DATA_START, //translate, le 0x8000 -> 0x0000 Data[tempadd] [0] = c, //Get the MS(Most signif ) Character c = Inl e[9+l+l] ; //Get the LSiLeast Ξig) Chatacter Data! teiπpadd) [1] = c; } //end if addresε++; /*when we have both characters */ //end for )//end if )//end while / /Generate_Hex_Fιle ( pout , OutputBytes ) ; Generate_Msg_Fιle ( fpout, bufεize) ; fclose(fpm) ; fcloset fpout) ,- pπntf ("."),- return 0; /* indicate success to the world */ )//end main ******************** *********** ******* '/ long Locate (long Start, mt which) { //Either the address of the ZZ will be returned or ARRAY_ΞIZE will //be indicating NOT found. //if which = 1, start at Start+1 and look for next occurance of ZZ //if which = 0, start at Ξtart+1 and keep looking until it's NOT a ZZ Start-. + ; if (which == 1) { while (Start < ARRAY_SIZE) { if ( (DatatStart] [0] == 'Z') &_. (Data [Start] [1 ] == 'Z') ) ( return (Start) ; ) Start-. + ; )//end while )//end if if (which == 0) { while ( (Start < ARRAY_SIZE) && (DatalΞtart] [0] == 'Z') && 0 (DatalStart] [1] == 'Z' ) ) { Start-. + ; }//end while return (Start) ; 5 }//end if //should never get here return (ARRAY_SIZE) ; 0 ***************************************************************************** / 5 /*** CDLCHECK.C ***/ ♦include <stdιo.h> ♦include <stdlιb.h> ♦ include <strmg.h> ♦include "constant. " 0 ♦include "helpers. c" ♦include "proto.h" /* Function Prototypes 5 int Hex_Value(char c) ; unsigned int Get_Addresε (char 'Line); int Get_Bytes(voιd) ,- */ 0 char huge Data [ARRAY_SIZE] [2] ; char Inline [LINE_LENGTH] ; Char Outline [LINE_LENGTH] ; char bufl[600],- //256 bytes = 512 nibbles (hex characters) with extra 5 char c; //This is the character currently under evaluation unsigned long checksum, //must be a 32 bit checksum unsigned mt tempadd ; unsigned int m add, maxadd; char OK; 0 int Nbytes,- //Numner of data bytes on the line unsigned mt address; //Decimal version of address, rememDer to subtract 0x8000 before //using to index array void Usage (char *Str) 5 { fpr tf (stderr, "USAGE: %s Input_Fιle [-X] [-M] \n\n" , Str) ; fprintf (stderr, "This utility will generate 56 checksums for the EEPROM \n" ) ; fprintf (stderr, "of the hex file specified by Input_Fιle. The values are in decimal format\n" ) ,- 0 fprintf (stderr, "and are one per line by default. The -X is optional, but if provided willXn") ; fprintf (stderr, "display the checkεumε in HEX format one on each line. The -M option wιll\n"), fprintf (stderr, "generate a series of download mesεages that can be used to download the.\n") fprintf (stderr, "generated checksums to the CMI. You may use -X, or -M or Neither, \n" ) ; 5 fprintf (stderr, "but NOT bothΛn"); ) 0 t main dnt argc, char *argv[]) { char c; /5 r_checksum[57] ,- address; r checksum; FILE *fpιn; //Input file pointer // FILE *fpout; //Output file pointer maxadd = 0; m add = OxFFFF; checksuιτι=0; lf ( argc > 3 ) Usage (argv[0]); return 1 ; ) OK=0; if ( (argc == 3) S.& (strcmp(argv[2] , "-X" ) == 0) ) OK = 1; lf ( (argc == 3) -.& ( s tr cm ( arg [ 2 ] , " -M" ) == 0) ) OK =1; if ( (argc == 3) && (strcmp(argv[2] , " -H" ) == 0) ) OK =1; if ( argc == 2) // 3 ust the two mput files, def output is decimal OK = 1; lf (OK == 0) { Usage (argv[0] ) ; return 1; } if ( (fpm=fopen(argv[l) , "rt") ) == NULL) { fprmtf (stderr, "Cannot open input file %s" , argv[l] , " . \n" ) ; return 1; ) //Read m the input HEX file while ( (fgets (Inline, LINE_LENGTH-1, fp ) ) ) { if (Inlme[8] '= '1') 11 a.1 in this loc. indicates last l ne { //Process the input line if (Inline [0] ' = ':') { fprintf (stderr, "Invalid Hex file %s: %s, \n" , argv[l ] , lnlιne[0] ) ; return 1; ) ; //starting address from HEX line //Now for as many CHARACTERS in the input line, stuff them into the Data array for d=0; κ(Nbytes*2); ι+=2) //each byte has 2 hex characters { if ( (address >= DATA_START) --& (addreεs <= (long)MAX_CHECKΞUM_ADDR) ) //then we need to put it into array //otherwiεe it's ROM Code or DATA Page (>= OxFOOO) & we dont care { //Data alwayε starts at the 9th character c = Inline [9+ι] ; tempadd=addresε-DATA_START; //translate, le 0x8000 -> 0x0000 Data[tempadd] [0] = c; //Get the MS(Most signif) Character c = Inlme[9+ι+l] ; //Get the LSlLeast Sig) Chatacter Dataltempadd] [1] = c; //fprmtf (fpout, "%X, %lX\n" .address, checksum); ) //end if address++; /*when we have both characters */ } //end for .//end if )//end while //Clear out the checksums for (ι=0; ι<57; ι++) { sector_checksum[ι] = 0L; ) ♦define KK 56 //the 57th (array location 56) sector is the checksum of the chechsums //Now generate the sector checksums for d=0; KKK; ι++) { 3 = ι *512; //each sector is 512 bytes for (k=0; k<512; k++) { c=Data[3] [0] ,- temp = (Hex_Value(c)«4) ,- c=Data[3] [1] ; temp += Hex_Value (c) ; sector_checksu_n[i] += temp; /* prmtf ( "3=%d",3) ; printfC val=0x%c",Data[ 3 ] [0] ) ; pr tf <"%c",Data[_] [1] ) ; prmtf (" = %d " , temp ); prmtf (" \tSect 0 Check ="),- prmtf ( "%ld" , sector_checksum[ι] ) ; printfC = %081X\n" , sector_checksum[ι] ) ; J-++; //now for the checksum of the checksums for (1=0; KKK; 1++) { //we wanted a bytewise checksum ' ' ' foo = (sector_checksum[ι] £_ OxFFOOOOOO), //Mask off MSP k=foo»24; sector_cnecksum[KK] += k; foo = (sector_checksum[ι] & OxOOFFOOOO) ; k=foo»16; εector_checkεum[KK] += k ; foo = (εector_checksum[ι] & OxOOOOFFOO) ; k =foo»8; sector_checksum[KK] += k ; foo = sector_checkεum[ι] _ OxOOOOOOFF; εector_checkεum[KK] += foo ; ) //We will now generate the user specified output format deεired if ( (argc == 3) && (strcrnp (argv[2] , " -X" ) ) == 0 ) { for (ι=0; ι<57; ι++) //NOTE ! ' ! It took a LONG TIME to figure out that when displaying //a long you MUST have it in a SEPARATE prmtf ' ' ' ' prmtf ( "Sector %d checksum = ", I) , prmtf ( "%081X \n" , sector_checksum[ι] ) ,- , ' if ( (argc == 3) && (strcrnp (argv[2] ," -H" ) ) == 0 ) ( /* I will generate a series of output hex formated data lines to the output file. Each of the checksums will De on there own hex output line. And of course to make things a little more interesting each of tr.ese output lines must have a checksum calculated for it... that is the vaπaole checksum. */ address = OxFOOO; //Starting location for the checksum data for d=0; ι<57; ι++) //56 * 8 characters per Checksum = 448 HEX Chars = 224 bytes { / /printf ("%081X" , sector_checksum[ι] ) ,- sprintf (S_bufl[0],":04") ,- sprintf bufl [3] , "%04X" .address) ,- sprintf (ibufl [7] ,"00") ; sprintf (£_bufl [9] , "%081X" , sector_checksum[ι] ) ,- //calculate bytewise checksum for output line checksum = 0; for ( 3= 1; 3<17; 3 +=2 ) // { checksum += (Hex_Value(buf1 [3 ] ) «4) , //the MSB checksum += (Hex_Value(buf1 [3+1] ) ) , //the LSB ) checksum = -checksum + 1; //get the l's comp checksum = checksum & OxFF; //we only want this much sprintf (&bufl [17] , "%02X" .checksum) ; //insert checksum into char string prmtf ("%s\n" ,bufl) ,- //barf it out address += 4; //each checksum is a long...4 bytes... next checksum please. . ) //end of Hex outputfile processing if ( (argc == 3) £_& (strcrnp (argv[2] , " -M" ) ) == 0 ) { generate a series of download messageε to load the checksums. I'll use a string to hold the checkεumε to make prepmg the messages easier One Download code block will do it but there will need to be padding. The DL block will contain 224 bytes (56 longs *4 bytes per long) =224 bytes. We will need to transmit 231 bytes ( (25 * 9) + 6) so we will need to pad 231-224 = 7 bytes */ for (1=0; ι<57; 1++) //56 * 8 characters per Checksum = 448 HEX Chars = 224 bytes { //prmtf ("%081X" , εector_checks__m[ι] ) , sprintf (.cbuf1 [1*8] , "%081X" , sector checksum[ι] ) , } // sprintf (S-bufl[56*8] , "%081X", 0L) ; 114 bytes of PAD '• sprintf (&buf1(57*8] , "%081X" , 0L) ; 114 more Dytes of PAD '' prmtf ("3B0000F000E4") ; //CMI_CDL_START_CNT address = FOOO, 228 bytes (57 * 4) buf_ptr =0; //which means the last byte of the last 37 message is pad for d=0;ι<12;l++) prmtf ( "%c" ,bufl[buf_ptr] ) ; //first 6 bytes of data from out buffer buf_ptr++; ) prmtf ( "\n" ) ; for d=0; ι<25; 1++) //25 0x37 messages please and thanks { prmtf ( " 370000 " ) ; for ( 3 =0 ; 3<18 ; 3 ++ ) { prmtf ( "%c " , bufl [buf_ptr ] ) ; 119 bytes of data from out buffer buf_ptr++ ; } prmtf ( " \n" ) ; / /end of the line ) } if (argc == 2 ) { for (1=0; i<57; 1++) { printf ( "sector_checksum[%d] = ",ι); printf ( "%ld\n" , sector_checksum[ι] ) ; ) } fcloεe(fpιn) ; return 0; /* indicate succesε to the world */ ) //end mam ******** ** *** **** *** **** **** **** * ** * **** * * * ****** *** * ** ** ** *** * * *** * * * *********** * ******* * **** * ******* * ** * * *********** **** ******** ** * * * ** * *** CONDENSE . C ♦include <stdιo.h> ♦include <stdlιb.h> ♦include <strιng.h> ♦include "constant .h" ♦include "helpers. c" ♦include "proto.h" /* Function Prototypes mt Lιnes_In_Fιle(FILE *fp) ; int Hex_Value ( char c ) ; unsigned t Get_Addresε (char "Line) ; int Get_Byteε(char *Lme) ; void Dump_Data (void) ; char Get_Valιd_Hex_Record (FILE *fp, char *Lme) ; void dump_message_to_flie (FILE *fpoutl, int FF_Count, mt FF_Start_Addr, char "Str) ; void Dιεplay_Condense_Usage(char *); // Displays usage information to user ♦define ARRAY_SIZE 32768L //oxFFFF - 0x8000 Valid EEPROM Range ♦define DATA_START 32768L // Decimal form of 0x8000 ♦define LINE_LENGTH 150 // Input and output line length ♦define TRUE 0 ♦define FALSE 1 ♦define MAX_CMI_BUFFSIZE 256 ♦define CMI_CDL_FILL_PATT 0x39 */ char huge Data [ARRAY_SIZE] [2] ; char Inlιnel[LINE_LENGTH] ; // We will look at two lines at a time //char Inlme2[LINE_LENGTH] ; // We will look at two lines at a time unsigned int addressl; //each l ne has an address unsigned t address2 ; //each line has an address Char Outline [LINE_LENGTH] //used to build up an ouput line char c; // This is the character currently under evaluation"" char Search_Ξtr [12] ,- // 6 occurances of the Search character from command line int Nbytesl; // Number of data bytes on the line mt Nbytes2; // Number of data bytes on the line //These are the input argument poεitionε in argvM ♦define INPUT_FILE_ARG 1 ♦define HEX_STRING_ARG 2 ♦define MΞG_OUTPUT_FILE_ARG 3 ♦define DATA_OUTPUT_FILE 4 //other Related input constants ♦define REQUIRED_ARGS 5 ♦define REQUIRED_BYTES_PER_LINE 6 /************* ******** ****** ** ** m () * * **** * * * *** *** * * ** * ** mt ma dnt argc , char *argv [ ] ) ( long i; FILE *fpιn; //Input file pointer FILE *fpoutl; //Output file pointer FILE *fpout2; //Output file pointer mt Doιng_a_Block; int FF_Count; int FF_Ξtart_Addr; int InputL es; unsigned int Last_lme_addr, Current_lιne_addr; mt pattern_found; unsigned int bytes_wπtten,- //debug stuff unsigned mt bytes_read; unsigned mt bytes_bypassed; unsigned mt bytes_msg; bytes_ιrιsg=0 ; bytes_written=0 ; bytes_read=0 ; bytes_bypassed=0 ,- if ( argc REQUIRED_ARGS fprintf (stderr, "ERROR : Invalid Number of Aruments ... \n\n" ) , Display_Condense_Usage(argv[0] ) ,- return 1 ; if ( ( strlen ( argv [HEX_STRING_ARG] ) 2) II ! dsxdιgιt ( argv [HEX_ΞTRING_ARG] [ 0 ] ) ) II 1 dsxdιgιt (argv[HEX_STRING_ARG] [1] ) ) ) { fprmtf (εtderr, "ERROR : 'Hex_Strmg' must be 2 Valid Hex characters describing the data byte\n" ) , fprintf (stderr, "ERROR : 'Ex: FF\n\n"); Dιsplay_Condenεe_Usage (argv[0] ) ,- return 1; } for (ι=0; ι<12; ι+=2) { Search_Str[ι]= argv[HEX_STRING_ARG] [0] ; //This is the pattern of 6 bytes Search_Str[ι+l]= argv [HEX_STRING_ARG] [ 1 ] ; //that we will look for in each input line } lf ( ( fpin-fope (argv[INPUT_FILE_ARG] , "rt" ) ) == NULL) fpr tf (stderr, "Cannot open input file %ε" , argv[INPUT_FILE_ARG) , " . \n\n" ) ; Dιsplay_Condense_Usage (argv[0] ) ,- return 1; } if ( (fpoutl=fopen(argv[MSG_OUTPUT_FILE_ARG] , "wt") ) == NULL) { fprintf (stderr, "Cannot open %s as output .", arg [MSG_OUTPUT_FILE_ARG] ,". \n\n" ) , Display_Condense_Usage(argv[0] ) ; return 1; ) if ( (fpout2=fopen(argv[DATA_OUTPUT_FILE) , "wt") ) == NULL) { fpr tf (stderr, "Cannot open %s aε output .", argv[DATA_OUTPUT_FILE] ,". \n\n" ) ,- Display_Condense_Usage(argv[0] ) ,- return 1; for d = 0; 1<LINE_LENGTH ; 1 + +) Inlmel ti] = 0; } Last_lιne_addr = (0x8000 - 6 ) ; / / force first line to be contig Domg_a_Block = FALSE ; FF_Count = 0 ; FF_Start_Addr = NULL; InputLines = Lmes_In_File (fpm) ; for d=0; ι< InputLines; ι++) //process each line in the input file { Rtn = Get_Valιd_Hex_Record (fp , fclnlinel [0] ) ; //read a line from input file bytes_read +=Get_Bytes(S.Inlinel [0] ) ,- //debug ιf( Rtn == 2) //This should not happen check for EOF fprintf (stderr, "Unexpected EOF encountered.. termιnatιng\n" ) ; exιt(l) ; ) if ( Rtn == 1 ) //this is either invalid hex or a hex line with > 6 data bytes { //3ust pass it on to the catch all file fputs(ScInlmel[0] ,fpout2) ; bytes_bypaεsed +=Get_Bytes (&Inlιnel [0] ) ; //debug bytes_wrιtten +=Get_Bytes (_Inlmel [0] ) ; //debug continue; // start the for loop over again } Current_l e_addr=Get_Address(_Inlinel [0] ) ,- //Check string 3ust read in looking for our pattern //data always starts at the 9th character for a hex record pattern_found=strncmpι (Search_Str, £lnlιnel[9] , εizeof (Search_Str) ) ; if (Last_lme_addr + 6 == Current_lιne_addr ) //lineε are contiguous { if (pattern_found==0) //we found the pattern { if (Domg_a_Block == TRUE ) { //will our buffer be full i f ( FF_Count + 6 > MAX_CMI_BUFFSIZE ) { / /we can' t swueeze any more in time to dump & need to empty buffer and reset dump_message_to_f lie ( fpoutl , FF_Count , FF_Start_Addr , Search_Str) ; bytes_wπtten+=FF_Count ; / /debug bytes_msg+=FF_Count ,- / /debug FF_Count = 6 ; FF_Ξtart_Addr = Current_lme_addr; / /Domg_a_Block is STILL TRUE } else FF_Count + = 6 , / / 3 ust up the co ir } } else / /we were NOT Domg_a_Block But now have at least 6 bytes of pattern //while it is possible that we may only have a block of only one line / / it will generate 1 message either way . . . so we ' ' generate th s one FF_Count =6 ; FF_Ξtart_Addr = Current_lme_addr; Domg_a_Block = TRUE ; } ) else //Pattern not found { if (Doιng_a_Block == TRUE ) / /we ' re all done with that block { dump_message_to_f lie ( fpoutl , FF_Count , FF_Start_Addr , Search_Str ) , / /send to file bytes_wrιtten+=FF_Count ; / /debug bytes_msg+=FF_Count ; / /debug FF_Count = 0 ; / /reset our vars FF_Start_Addr = 0 ; Domg_a_Block = FALSE; ) / /3ust pass it through it ' s not what we are looking for fputs UInlmeK O ] , fpout2 ) ; bytes_wrιtten+=6 ; / /debug else //not contigious to last 5 i if (Doιng_a_Block == TRUE ) i 1n0 { dump_message_to_flie ( fpoutl, FF_Count , FF_Start_Addr, Search_Str) ,- bytes_wrιtten+=FF_Count; //debug FF_Count = 0; FF_Start_Addr = 0; Domg_a_Block = FALSE; 15 } //end if if (pattern_found==0) //so were not contig, we found our pattern { //while it is possible that we may only have a block of only one line 20 //it will generate 1 message either way... so what the heck FF_Count =6; FF_Start_Addr = Current_lιne_addr; Domg_a_Block = TRUE; ) 25 else { fputs ( - lnlmel [ 0 ] , fpout2 ) ,- / /dump bytes_wrιtten+=6 ; / /debug 30 } )//end else not contig //gear up for next line 35 t_lιne_addr; } //end //flush the buffer 40 if (Domg_a_Block == TRUE ) { dump_message_to_flie ( fpoutl,FF_Count, FF_Start_Addr, Search_Str) ; bytes_wrιtten+=FF_Count ,- / /debug FF_Count = 0; 45 FF_Start_Addr = 0; Domg_a_Block = FALSE; } //end if /• 50 printf ("bytes_wπtten = %u\n" ,bytes_wrιtten) ,- printf ("byteε_read = %u\n" ,bytes_read) ,- printf ( "bytes_bypassed = %u\n" ,bytes_bypassed) ,- */ printfC."); 55 fclose(fpm) ,- fclosetfpoutl) ; fclose(fpout2) ; return 0; /* indicate success to the world */ ***************** char Get_Valid_Hex_Record (FILE * £ρ, char *Lme) 65 { /* Input: fp : pointer to input f le to read Line: array of chars to read data into Output: 0 if successful 1 if failed tests 70 2 EOF */ mt Nbytes; 75 //read a line, if end of file, return fail status if (fgets(Line, LINE_LENGTH-1, fp) == NULL ) return (2),- if (Lme[0] != ':') //Hex lines MUST start with : (cept for 1st) { return (1); //bad 5 ) Nbytes=Get_Bytes l-Lιne[0] ) ; //number of databytes in this line if (Nbytes '= REQUIRED_BYTES_PER_LINE ) 10 return (1); //bad ) return (0); //success )//end function Get_Valιd_Hex_Record 15 / ****** ********* *********************** ******** void Display_Condenεe_Usage (char *Str) 20 { fprmtf (stderr, "USAGE: %s Input_Fιle Hex_Strmg Msg_Output_Fιle Data_Output_Fιle \n\n" , Ξtr) ; fprmtf (stderr, "Input_Fιle : MUST be Output File generated by the CONVERT Utility \n"); fprintf (stderr, " using -N06 option !\n"); fprintf (stderr, "Hex_Strιng : Is the 2 character HEX Value that is being stripped.n" ) , 25 fprintf (stderr, " out. ex: FF\n" ) ; fprintf (εtderr, "Msg_Output_Fιle : Name of the file created that contains the RLE\n"); fprintf (stderr, " messages for each block removed from input data fιle.\n"), fprintf (stderr, "Data_Output_Fιle : Name of the file created that contains the original \n" ) ; fprintf (stderr, " input data minus the the striped out blocks of\n" ) ; 30 fprintf (stderr, " the 'Hex_Strmg' character. \n\n" ) ; fprintf (stderr, "This utility parces the input file looking for consecutive occurances\n" ) , fprintf (stderr, "of 'Hex_Strmg' in the input data file When it is possible to elιmιnate\n" ) ; fprintf (stderr, "2 or more messages from the input file, a RLE-type mesεage is sent to \n" ) ,- 35 fprintf (stderr, " 'Msg_Output_Fιle' which describeε start addresε and length (up to 255) \n" ) , fprintf (εtderr, "of this consecutive occurance. The remaining data, is sent to the\n" ) ; fprintf (stderr, " 'Data_Output_Fιle' . \n" ) ,- ) //end function Dιsplay_Usage Λ ****************************************************** / void dump_message_to_f lie (FILE * fpoutl , t FF_Count , mt FF_Start_Addr , char *Str) { / * this function dumps an RLE message to the message file * / 45 fprintf ( fpoutl , " %2X" , CMI_CDL_FILL_PATT) ; i f (FF_Count < 0x10 ) fprintf ( fpoutl , " 0000%xθ%x%c%c0000000000 \n" , FF_Ξtart_Addr , FF_Count , Ξtr [ 0 ] , St [ 1 ] ) , else fprintf ( fpoutl , " 0000%x%x%c%c0000000000\n" , FF_Start_Addr , FF_Count , Str [ 0 ] , Str [ l ] ) ; 50 / / DF T 1 2 4 5 6 7 8 9 A } /A****************************************************************************/ 55 ***************************************************************************** / /*** CONVERT. C ***/ ♦include <stdιo.h> 60 ♦include <stdlιb.h> ♦include <εtπng.h> ♦include "constant.h" ♦include "helpers.c" ♦include "proto.h" 65 char Inline [LINE_LENGTH] ,- char Outline[LINE_LENGTH] ; char c; //This is the character currently under evaluation 70 /* The [0] element of this arrary is the data at hex address 0x6000, which is DATA_START (decimal) so, If I convert the 4 char Hex address to a decimal and then subtract DATA_START I have the index to the array where the data for the hex record is to start. The data in the array is 3 ust hex characters. Data [address] 10] holds the Most significant hex character and Datafaddress] [1 ] 75 holds the other character. */ char huge Data[ARRAY_SIZE] [2] ,- unsigned mt tempadd ,- unsigned int minadd, maxadd; int Nbytes; //Number of data bytes on the line unsigned mt address; //Decimal version of address, remember to subtract 0x8000 //before using to index array unsigned long Fιle_Checksum; I la.32 bit checksum will be appended to f le & to screen, used by downloader int OutputBytes; //Number of data bytes on the line of the output file 0 int main nt argc, char *argv[]) { char c; long l ; FILE *fp ; //Input file pointer 5 FILE *fpout; //Output file pointer t supress,- //supresses the printing of the end of file statment if Fιle_Checksum = 0; 0 maxadd = 0; minadd = OxFFFF; supress = 0; //by default we will print the end of file line 5 if (argc < 3 ) | | (argc > 4) | | ((argc == 4) && (argv[3] [0] ' = '-') && (argv[3][l] '= 'N' ) ) || ((argc == 4) _.£_ (argv[3][0) '= '-') && (argv[3][l] '= 'H')) ) 0 fprintf (stderr, "USAGE: %s Input_Fιle Output_Fιle -Nxx\n" , argv[0]); fprintf (stderr, "This utility will convert St sort the Input hex file into a\n" ) ; fprint (stderr , "sorte (by address) output hex file containing the entire \n" ) ; fprint (stderr, "address range (0x8000-0xFFFF) . The -Nxx option allows tne user 5 to\n" ) ; fprint (stderr, "control the Number of data bytes per line. The xx in the -Nxx are two HEX \n") ; fprintf (stderr, "Characterε that εpecify the number of bytes. Ex: -N06 (6 bytes) -N15 (21 bytes) \n" ) ,- 0 fprintf (stderr, "By Default 6 (0x06) bytes per line is used.\n"); fprintf (stderr, "The Max number of bytes per line is 50. -H performs the same function as -N \n" ) ; fprintf (stderr, "except it supresses the HEX End of File statement. \n" ) ; _ _ return 1; 5 } if ( (fpm=fopen(argv[l] , "rt" ) ) == NULL) 0 fprintf (stder , "Cannot open input file %s\n" , argv[l ] ) , return 1 ,- } if ( (fpout=fopen(argv[2] , "wt" ) ) 5 == NULL) { fprintf (εtderr, "Cannot open output file %ε\n" , argv[2] ) ; return 1; } 0 for (1=0; ι< ARRAY_SIZE; ι++) { c= ' F ' ; Data[ι][0] = c; //remember it's characters and F's are blanks 5 Data[ι] [1] = c; ) if ( (argc==4) S<& (argv[3][0] == '-') _=_= (argv[3][l] == *N' ) ) 0 if ( (argc==4) && (lsxdigit (argv[3] [2] ) && lsxdigit (argv[3 ] [3] ) ) ( //the user is specifying the width c = argv[3] [2]; OutputBytes = 16 * Hex_Value ( c ) ; 5 c = argv [ 3 ] [ 31 ; OutputBytes += Hex_Value(c) ; if (OutputBytes > MAX_BYTES_PER_LINE ) fprmtf ( stderr , "Error : N value > %d\n" , MAX_BYTEΞ_PER_LINE) ; return 1 ,- } else { fprmtf (stderr, "You must provide a valid 2 character HEX value after -N\n"); return 1 ,- 10 ) else 15 OutputBytes = DEFAULT_DATA_WIDTH; } if ( (argc==4) St& (argv[3][0] == '-') _.& (argv . 3] [1] == 'H') ) 20 if ( (argc==4) &S= ( isxdigit (argv[3] [2] ) &St isxdigit (argv[3 ] [3 ]) ) ) { //the user is specifying the width supress = 1, //don't print end of file indicator c = argv[3] [2] ; 25 OutputBytes = 16 * Hex_Value(c) ; c = argv[3] [31; OutputBytes += Hex_Value ( c ) ; f (OutputBytes > MAX_BYTES_PER_LINE ) 30 fprintf ( stderr , "Error : N value > %d\n" , MAX_BYTES_PER_LINE) ,- return 1 ; } } Q< else 35 { fprintf (stderr, "You must provide a valid 2 character HEX value after -H\n") return 1 ; ) 40 } else OutputBytes = DEFAULT_DATA_WIDTH; 45 while! (fgets(Inlme,LINE_LENGTH-l, fpm) ) ) { if (Inlιne[8] '= '1') //a 1 in this loc. indicates last line 50 { //Process tne input line if (Inline [0] '= ': • ) { fprmtf (stderr, "Invalid Hex file %s: %s, \n" , argv[l] , Inline [0] ) ; 55 return 1 ; ) Nbytes=Get_Bytes(StInlme[0] ) ,- address = Get_Addreεε (4Inlιne[0] ) ; //starting address from HEX line 60 //Now for as many CHARACTERS in the input line, stuff them into the Data array for d=0; ι< (Nbytes*2) ; ι+=2) //each byte has 2 hex characters { if ( (address >= DATA_ΞTART) St-, address <= MAX_CHECKSUM_ADDR ) 65 //then we need to put it into array //otherwise it's ROM or data Code & we dont care { if (address > maxadd) maxadd = address; if (address < minadd) minadd = address; 70 //Data always startε at the 9th character c = Inlme[9+ι] ; tempadd=address-DATA_START; //translate, le 0x8000 -> 0x0000 Dataltempadd] [0] = c; //Get the MSIMost signif) Character c = Inline [ 9+1+1 ] ; //Get the LS(Least Sig) Chatacter 75 Dataltempadd] [1] = c ; } //end f address++; /*when we have both characters */ 11 end for .//end if }//end while Generate_Hex_Fιle (fpout, OutputBytes, supress) ,- 10 print ("minaddr = %ud\n" ,minadd) ; printf ("maxaddr = %ud\n" ,maxadd) ; printf C . " ) ; 15 fclose(fpιn) ; close! fpout) ; return 0; /* indicate success to the world */ ) I lend mam 0 5 GENSEGS .C ♦include <stdιo.h> ♦include <stdlιb.h> 30 ♦include <strmg.h> ♦include "constant.h" ♦include "helpers. c" ♦include "proto.h" 35 Char Inline [LINE_LENGTH] ; char Out1 e [LINE_LENGTH] ; char fιle_name[20] ,- char c; //This is the character currently under evaluation 0 /* The [0] element of this arrary is the data at hex addreεs 0x6000, which is DATA_START (decimal) so. If I convert the 4 char Hex address to a decimal and then subtract DATA_START I have the index to the array where the data for the hex record is to start. The data in the array is 3ust hex characters. Data[address] [0] holds the Most significant hex character and Data(addreεs] [1] 45 holds the other character. */ char huge Data[ARRAY_ΞIZE] [2] ; unsigned mt tempadd ; unsigned int minadd, maxadd; 50 int Nbytes; //Number of data bytes on the line unsigned mt address; //Decimal version of address, remember to subtract 0x8000 //before using to index array unsigned long Fιle_Checksum; //a 32 bit checksum will be appended to file St to screen, uεed by downloader 55 int OutputByteε; //Number of data bytes on the line of the output file int ma dnt argc, char *argv[]) { char c; OU long i; FILE *fpm; //Input file pointer FILE *fpout; //Output file pointer Fιle_Checksum = 0; 65 maxadd = 0; imnadd = OxFFFF; if ( (argc '= 2) ) 70 { fprmtf (stderr, "USAGE: %s Input_Fιle\n" , argv[0] ) ; fprintf (stderr, "This utility will read the input hex file and create 55 hex a\n" ) ; fprintf (stderr, "fileε, one for each 512 byte 'sector' off EEPROM. These ιles\n" ) ; fprintf (stderr, "will later be post processed to build an INDEXED message fιle\n" ) , 75 fprintf (stderr, "which will allow the HECU to download A SPECIFIC sector \n" ) , fprintf (stderr, " (l/64th of EEPROM) with minimum number of messages. \n") ; return 1; ) if ( (fpm=fopen(argv[l] , "rt") ) == NULL) { fprintf (stderr, "Cannot open input file %s\n" ,argv[l] ) ,- return 1; ) for d=0, ι< ARRAY_SIZE; ι++) { c= ' F ' ; Data[ι] [0] = c; //remember t's characters and F'ε are blanks Data[ι] [1] = c, while! (fgets(Inlιne,LINE_LENGTH-l,fpm) ) ) { if (Inline [8] '= '1') //a 1 in this loc. indicates last line { //Procesε the input line if (Inline [0] ' = ':') { fprintf (stderr, "Invalid Hex file %s: %s, \n" , argv.l] , Inline [0] ) , return 1; ) , //starting address from HEX line // if ((address > 0x8200) StSt (address < 0x82FF) ) // { // address = address, //debug hook // ) //Now for as many CHARACTERS in the input line, stuff them into the Data array for d=0, ι< (Nbytes*2) ; ι+=2) //each byte has 2 hex characters { if ( address >= DATA_ΞTART ) //then we need to put it into array //otherwise it's ROM Code Se we dont care { if (address > maxadd) maxadd = address, if (address < minadd) minadd = address; //Data always starts at the 9th character c = Inline [9+ι] , tempadd=address-DATA_START, //translate, le 0x8000 -> 0x0000 Dataltempadd] [0] = c, //Get the MSfMost signif) Character c = Inlme[9+ι+l] , //Get the LSILeast Sig) Chatacter Dataltempadd] [1] = c, } //end if address++, /*when we have both characters */ } //end for )//end if }//end while for (l=0;l<56; ι++) //0-55 inclusive { sprintf (Stfιle_name, "seg%04X.ZZZ" , i) ; if ( ( fpout=fopen (fιle_name, "wt" ) ) == NULL) { fprintf (εtderr, "Cannot open output file %s\n" , argv[2] ) , return 1; } Generate_Segment_Hex_Fιle( pout, l) , fclose ( fpout) , } //end for printfC . ") ; fcloεe(fpm) ,- return 0; /* indicate success to the world */ )//end mam /*** HELPERS. C ***/ ♦include "constant.h" ♦include "proto.h" ♦include <stdιo.h> ♦include <stdlιb.h> ♦include <stπng.h> extern char huge Data[ARRAY_SIZE] [2] ; ******************************* , int Get_Bytes (char *Lιne) { char c; int NBytes; NBytes = 16 * Hex_Value (c) ; NBytes += Hex_Value(c) ; return (NBytes) ,- } //End function Get_Bytes **************************************************************** , int Generate_ROM_Hex_Fιle(FILE * fpout, int OutputBytes) { //Addresε space 0x0000 => 0x5FFF ROM Space unsigned int 1,3, tempadd; unεigned char checksum; //0x00 - OxFF unsigned char val; char c; unεigned long Fιle_Checksum; ι=0, Fιle_Checksum = 0, / / while ( 1 < ARRAY_SIZE) while ( 1 < 0x5FFF) { //Check for a short line that might happen at the end of the file if ( (ARRAY_SIZE - 1) < OutputBytes) { OutputBytes = (ARRAY_SIZE - 1) ; ) if (OutputBytes > 15) fprintf (fpout, " :%2X" .OutputBytes) ; elεe fprintf ( fpout , " : 0%X" , OutputBytes ) ; checksum = OutputBytes, //Now for the address tempadd=ι; // fprmtf (fpout, "%04X" , tempadd) ,- //this will work val = (tempadd » 12); // divide by 4096 if ( val < 10) c=val+48; else c=val+55; //ad3ust to the ASCII char 0-9=48-57, A-F=65- 70 tempadd = tempadd - ( val «12 ) ; fputc ( c , fpout ) ; checksum += Hex_Value(c) * 16; //MS Nibble High val = (tempadd » 8), // divide by 256 if ( val < 10) c=val+48; else c=val+55; //ad3ust to the ASCII char tempadd = tempadd - ( val «8) ; fputc (c, fpout) ; checksum += Hex_Value (c ) ; //LS Nibble High val = (tempadd » 4) ; // divide by 16 if ( val < 10) c=val+48; else c=val+55; //ad3ust to the ASCII char tempadd = tempadd - ( val « 4 ) ,- fputc (c, fpout) ; checksum += Hex_Value(c) * 16; //MS Nibble, Low val = tempadd; if ( val < 10) c=val+48; else c=val+55, //ad3ust to the ASCII char fputc (c, fpout) ; checksum += Hex_Value (c ) ; // LS Nibble low //this is the record byte fputc ( ' 0 ' , fpout ) ; putc CO', fpout ) ; //now for the data for (3=0; 3 <OutputByteε ; 3++) //each line of hex holdε OutputByteε data bytes c = Data [1+3] [0] ; Fιle_Checksum += Hex_Value(c) * 16; //MS Nibble fputc (c , fpout ) ,- checksum += (Hex_Value(c) << 4 ) ; //Most Ξig Nibble c = Data [1+3] [1] ,- Fιle_Checksum += Hex Value (c) ; //LS Nibble fputc (c, fpout) ; checkεu += Hex_Value ( c ) ; //Least Sig Nibble }//end for // now the ONE Comp of the checksum and a CR checksum = checksum St OxFF; //mask off all but least sig byte checksum = 0x100 - checksum; val = checksum >> 4 ,- if ( val < 10) c=val+48; else c=val+55; //ad3ust to the ASCII char fputc (c, fpout) ; val = checksum - (val «4); if ( val < 10) c=val+48; else c=val+55; //ad3uεt to the ASCII char fputc (c, fpout) ; fputc (' \n' , fpout) , //end of line 1 += OutputBytes; } //end while fputεC :00000001FF\n" , fpout) ; //indicates end of file return(O); //εucceεε } //end function Generate_Hex_Fιle / « **************************************************************** //int Generate_Hex_Fιle(FILE *fpout, mt OutputByteε, char huge *Data[ARRAY_ΞIZE] [2] ) mt Generate_Hex_Fιle(FILE *fpout, mt OutputByteε, mt εupress) { ♦define OUTPUT_ONLY_CODE_PLEASE 0x6FFF 110 maps to 0x8000, this maps to OxEFFF, last code address unsigned t 1,3, tempadd; unsigned char checksum; //0x00 - OxFF unsigned char val; char c; unεigned long F le_Checksum, 1=0 ,- Fιle_Checksum = 0; // while (1 < ARRAY_SIZE) While (1 < OUTPUT_ONLY_CODE_PLEASE ) //Check for a short line that might happen at the end of the file if ( (ARRAY_SIZE - l) < OutputBytes) OutputBytes = (ARRAY_SIZE - 1); ) if (OutputBytes > 15) fpr tf (fpout, " :%2X" .OutputBytes) ; else fprintf (fpout, " :0%X" .OutputBytes) ; checksum = OutputBytes ,- //Now for the address tempadd=ι+0x8000 ; // fprintf (fpout, "%04X" , tempadd) ; //this will work val = (tempadd » 12); // divide by 4096 if ( val < 10) c=val+48; else c=val+55; //ad3ust to the ASCII char 0-9=43-57, A-F=65- 0 tempadd = tempadd - ( val «12) ; fputc (c, fpout) ; checksum += Hex_Value(c) * 16; //MS Nibble High val = (tempadd » 8); // divide by 256 if ( val < 10) c=val+48; else c=val+55; //ad3ust to the ASCII char tempadd = tempadd - ( val «8) ; fputc (c , fpout) ,- checkεum += Hex_Value(c) ; //LS Nibble High val = (tempadd » 4); // divide by 16 if ( val < 10) c=val+48; else c=val+55; //ad3ust to the ASCII char tempadd = tempadd - ( val « 4) ,- fputc (c, fpout) ; checksum += Hex Value(c) * 16; //MS Nibble, Low val = tempadd; if ( val < 10) c=val+48; else c=val+55; //ad3ust to the ASCII char fputc (c, fpout) ; checksum += Hex_Value (c) ; // LS Nibble low //this lε the record byte fputc ( '0' , pout) ; fputc ( ' 0 ' , fpout) ; //now for the data for (3=0; 3 <OutputBytes; 3++) //each line of hex holds OutputBytes data bytes { c = Data [1+3] [0] ; Fιle_Checksum += Hex_Value(c) * 16; //MS Nibble fputc ( c , fpout) ; checksum += (Hex_Value (c) « 4 ) ; //Most Sig Nibble c = Data [1+3] [1] ; Fιle_Checksum += Hex_Value (c) ; //LS Nibble fputc (c, fpout) ,- checkεum += Hex_Value(c) ; //Least Sig Nibble )//end for // now the ONE Comp of the checkεum and a CR checksum = checksum St OxFF; //mask off all but least sig byte checksum = 0x100 - checksum; val = checksum » 4 ; if ( val < 10) c=val+48; else c=val+55; //ad3ust to the ASCII char fputc (c, fpout) ; val = checksum - (val «4 ) ; if ( val < 10) c=val+48; else c=val+55; //ad3ust to the ASCII char fputc (c , fpout) ; fputc (' \n' , fpout) ; //end of line 1 += OutputBytes ; } //end while if (supress == 0) { fputsC :00000001FF\n" , fpout) ; //indicates end of file ) // fprintf (fpout, "%1X %ld Download Checksum (Hex Decimal) \n" , Fιle_Checksum, Fιle_Checksum) // printf ("%1X %Id Download Checksum (Hex Decimal) \n" , Fιle_Checksum, Fιle_Checksum) ; // printf ("Done. An" ) ; // fclose ( fpout) ,- return(O),- //εuccess ) //end function Generate_Hex_Fιle * ** *** *** * V unsigned int Get_Address(char *Lιne) { char c; unsigned int address; address =0; addreεs = 4096 * Hex_Value(c) ; address += 256 * Hex_Value(c) ; addreεs += 16 * Hex_Value (c ) ; c= Line [6] ; address += Hex_Value(c) ,- return (address) ; ) //End function Get_Addreεε ************ *********** ******* ******* ***************** void Dump_Data(voιd) { long i ; FILE * fpout; extern char huge Data[ARRAY_SIZE] [2] , if ((fpout = fopen ( "c : /toolε/hex/outdata. txt wt") ) == NULL) fprintf (εtderr, "Cannot open output file c : /tools/hex/outdata. tx . \n" ) for (1=1219; ι<1319; ι++) { fputc (Data [l ] [ 0 ] , fpout ) ,- fputc (Data . ι] [1] , fpout) ; if ( ( l > 0 ) StS. ( (i % 9) == 0) ) fputc ( ' \n ' , fpout ) ; } //end for fclose (fpout) ; } //end function Dump_data /************************** *********** ********** int Hex_Value(char c) { //This function returns the hex value of the input character //If it is not a hex character then it retunrε -1 //prmtf ( "Hex_Values char is %c\n",c); switch ( c ) { case '0' :Val= 0; break; case '1' :Val= 1 ;break,- case *2' :Val= 2;break; case '3' :Val= 3,-break,- case '4' :Val= 4 ; break; case '5' :Val= 5;break; case '6' :Val= 6 ;break; case , 7 , :Val= 7 ;break; caεe '8' :Val= 8 ; break,- case '9' :Val= 9,-brea ,- case 'A' :Val= 10,-break case 'B' :Val= 11; break case 'C :Val= 12;break case 'D' :Val= 13,-break case 'E' :Val= 14,-break case ■ F' :Val= 15,-break case 'a' :Val= 10,-break case 'b' :Val= 11,-break case ' c' :Val= 12,-break case 'd' :Val= 13;break case 'e' :Val= 14; break caεe 'f ' :Val= 15,-break default: Val= -1; break )//end switch //printf CHex_Val Val= %d\n",Val); return (Val) ,- )//end function Hex_Value / ****************************************************** / int Lιnes_In_Fιle(FILE *fp) { /* This function counts the number of lines in the file */ char Line [ INE_LENGTH] ; ι=0; //reset the fp fseek(fp,0,SEEK_SET) ; while ( ( fgets (Line, LINE_LENGTH-1, fp) ) != NULL ) ι++; //count the lines fseek(fp,0,SEEK_SET) ; //rewind it return d) ,- } //end function Lιneε_In_Fιle ********** ******************************* t Generate_Segment_Hex_Fιle(FILE *fpout, t segment) { // The Caller should have a separate filename for each call to this //routine. Each file can then be processed by "condense Se blockout" to //optimize the download. //This routine will not attemp to calculate the line checksum that is //usually output as the last byte... I do not use this information in //any of my tools. 00 will be output for this checksum. unεigned int 1, 3 , tempadd; char c; int OutputBytes; OutputBytes = 6; 116 bytes per HEX line 1=0; // While (1 < ARRAY_SIZE) while (1 < 512) //this may need to be larger ' ' ' ' ' ' { //Check for a short line that might happen at the end of the file < < l == 510) OutputBytes = 2; //last line wnatε to have 2 bytes 85 l^neε of 6 then last ) if (OutputBytes > 15) fprintf (fpout, " :%2X" .OutputBytes) ,- else fprintf (fpout, " :0%X" .OutputBytes) ,- //Now for the address tempadd=ι+ (segment*512) +0x8000 ; if (segment == 1 ) tempadd = tempadd; ) fprintf ( fpout, "%04 " , tempadd) ; //this is the record byte fputc ( '0' , pout) ; fputc ( ' 0 ' , fpout) ; //now for the data for ( 3 =0; 3<0utputBytes; 3++) //each line of hex holds OutputBytes data bytes { c = Data[tempadd-0x8000+ 3 ] [0] , fputc (c, fpout) ; c = Data[teιrpadd-0x8000+j] [1] ; fputc (c, fpout) ; )//end for //checksum bytes putc CO', fpout) ; fputc CO', fpout) ; fputc C \n', fpout) ,- //end of line i += OutputBytes,- ) //end while fputsC :00000001FF\n", fpout) ; //indicates end of file return (0); //success } //end function Generate_Hex_File Having now described a few embodiments of the invention, and some modifications and variations thereto, it should be apparent to those skilled in the art that the foregoing is merely illustrative and not limiting, having been presented by the way of example only. Numerous modifications and other embodiments are within the scope of one of ordinary skill in the art and are contemplated as falling within the scope of the invention as limited only by the appended claims and equivalents thereto.

Claims: WHAT IS CLAIMED IS: 1. In a wireless microcell distribution system, a system for rapidly downloading information from a first location to a plurality of remote locations at which cable microcell integrators are located, comprising: means for broadcasting information to update said cable microcell integrators from said first location such that multiple cable microcell integrators are simultaneously provided with update information with no response required from the cable microcell integrators to said first location. 2. The system of Claim 1, and further including means at said first location for sending a query message to each of said cable microcell integrators separately, with said message inquiring as to the receipt of the information broadcast. 3. The system of Claim 1, and further including at said first location means for transmitting to said cable microcell integrators a request to have each of said cable microcell integrators reconfigure itself to receive broadcast messages, thereby to establish a broadcast mode for each of said cable microcell integrators. 4. The system of Claim 3 wherein the transmission of said reconfiguration request is accomplished serially on an address-by-address unicast basis. 5. The system of Claim 1, and further including at each cable microcell integrator means for ascertaining the integrity of the message broadcast from said first location, thus to provide the status of the information broadcast to the cable microcell integrator; and means for transmitting the status of a received broadcast at a cable microcell integrator to said first location. 6. The system of Claim 5, and further including means at said first location for evaluating the status of broadcast messages from each of the associated cable microcell integrators and for re- broadcasting information back to all of said cable microcell integrators for the purpose of correcting improperly received information at a cable microcell integrator. 7. The system of Claim 6, and further including means at each of said cable microcell integrators for ascertaining which of said re-broadcast information is to replace improperly received information and for replacing the improperly received information with the appropriate re-broadcast information. 8. In a wireless microcell distribution system, a method for providing rapid updates to each of the cable microcell integrators from a head end control unit, comprising the steps of: requesting in a unicast mode that each of the cable microcell integrators be put in a broadcast mode; transmitting information to all of said cable microcell integrators simultaneously in a broadcast mode; and, having each of the cable microcell integrators providing a message in a unicast mode indicating the status of the receipt of the broadcast message to the head end control unit, whereby each of the cable microcell integrators is placed in a broadcast mode on a unicast basis, in which the updates are transmitted to the cable microcell integrators in a broadcast mode and in which the status of the receipt of the broadcast information is returned to the head end interface converter in a unicast mode. 9. In a wireless microcell distribution system, a method for rapidly downloading information from a first location to a plurality of remote locations at which cable microcell integrators are located, comprising the step of: broadcasting information to update cable microcell integrators from the first location such that multiple cable microcell integrators are simultaneously provided with update information with no response required from the cable microcell integrators to the first location. 10. The method of Claim 9, and further including at the first location, the step of sending a query message to each of the cable microcell integrators separately, with the message inquiring as to the receipt of the information broadcast. 11. The method of Claim 9, and further including at the first location the step of transmitting to said cable microcell integrators a request to have each of said cable microcell integrators reconfigure itself to receive broadcast messages, thereby to establish a broadcast mode for each of the cable microcell integrators. 12. The method of Claim 11 wherein the transmission of the reconfiguration request is accomplished serially on an address-by-address unicast basis. 13. The method of Claim 9, and further including at each cable microcell integrator the steps of ascertaining the integrity of the message broadcast from the first location, thus to provide the status of the information broadcast to the cable microcell integrator; and transmitting the status of a received broadcast at a cable microcell integrator to the first location. 14. The method of Claim 13, and further including at the first location the steps evaluating the status of broadcast messages from each of the associated cable microcell integrators and re-broadcasting information back to all of the cable microcell integrators for the purpose of correcting improperly received information at a cable microcell integrator. 15. The method of Claim 6, and further including at each of the cable microcell integrators the steps of ascertaining v.' .ch of the re-broadcast information is to replace improperly received information and replacing the improperly received informaiiυ.. the appropriate re-broadcast information. 16. In a wireless microcell distribution system, a method for providing rapid updates to each of the cable microcell integrators from a head end control unit, comprising th.. ,.ιeps of requesting in a unicast mode that each of the cable microcell integrators be put in a broadcast mode; transmitting information to all of said cable microcell integrators simultaneously in a broadcast mode; and, having each of the cable microcell integrators providing a message in a unicast mode indicating the status of the receipt of the broadcast message to the head end control unit.

Inventors: HERBERT THOMAS G, PELLETIER JAMES A, RIGAZIO JOSEPH L III, HERBERT, THOMAS, G., PELLETIER, JAMES, A., RIGAZIO, JOSEPH, L., III
Applicants: TRANSCEPT INC, TRANSCEPT, INC.
Application year: 2000
Main classification: G06F9
IPC codes: G06F9, H04B7, H04L12, H04W4, H04W16, H04W24, H04W88, H04W92