void controlRemove(PMINIPORT_ADAPTER Adapter) { PCONTROL_PROCESS_DESCRIPTOR process; PBUFFER_DESCRIPTOR dsc; ENTER; // Free the received control packets queue while(!QueueEmpty(Adapter->ctl.Q_Received.Head)) { // queue is not empty DumpDebug(DISPATCH, "<1> Freeing Control Receive Queue"); dsc = (PBUFFER_DESCRIPTOR)QueueGetHead(Adapter->ctl.Q_Received.Head); if (!dsc) { DumpDebug(DISPATCH, "<1> Fail...node is null"); continue; } QueueRemoveHead(Adapter->ctl.Q_Received.Head); --Adapter->stats.tx.Control; if(dsc->Buffer) kfree(dsc->Buffer); if(dsc) kfree(dsc); } // process list // sangam : appln read indicates error status -ENODEV if(Adapter->ctl.Apps.Inited) { if(!QueueEmpty(Adapter->ctl.Apps.ProcessList)) { // first time gethead needed to get the dsc nodes process = (PCONTROL_PROCESS_DESCRIPTOR) QueueGetHead(Adapter->ctl.Apps.ProcessList); while (process != NULL) { if(process->Irp) { // sangam : process read waiting process->Irp = FALSE; wake_up_interruptible(&process->read_wait); } process = (PCONTROL_PROCESS_DESCRIPTOR)process->Node.next; DumpDebug (TX_CONTROL,"sangam dbg : waking processes"); } //*************** SANGAM check if needed ***************************** /* while(!QueueEmpty(Adapter->ctl.Apps.ProcessList)) DumpDebug (TX_CONTROL,"still waiting for process close"); msleep(1); } */ msleep(100); //delay for the process release } } Adapter->ctl.Apps.Inited = FALSE; LEAVE; return; }
// // Function: Rcv_FillBuffer // // Description: Recursive function to fill Buff with data // It will fill data with BufferSize, or if there is // less amount of data, with data size, if BufferSize // greater than one message, next message will be added // to the BufferPtr // // Arguments: // // Name Type Direction Description // ----------- ----------- ----------- ----------------------------------- // BufferPtr t_uchar * OUT Data buffer to get data // BufferSize t_ushort IN Amount of data to get // // Return Values: // // Name Explanation // ----------- --------------------------------------------------------------- // RetStatus Error code < 0 if error // = 0 success ( no data ) // > 0 success ( num bytes of data received and copyed ) // int Rcv_FillBuffer( t_uchar *Buff, t_ushort BufferSize ) { QueueNodeDef *pHead = QueueGetHead( RECV_QUEUE ); int QueueLen = QueueGetLen( RECV_QUEUE ); DataRecord *FirstMsg = NULL; t_ushort MsgLen = 0; t_ushort ReturnLen = 0; //Condition to exit from recursion ( return 0 ) if ( BufferSize <= 0 || QueueLen <= 0 || QueueLen > MAX_QUEUE_LEN ) return( ReturnLen ); FirstMsg = QueueGetFirstNode( RECV_QUEUE ); MsgLen = FirstMsg->DataLength; //If MsgLen > BufferSize I only need to copy BufferSize bytes // and shift message in node if ( MsgLen > BufferSize ) { memcpy( Buff, FirstMsg->DataBuffer, BufferSize ); // copy the buffer FirstMsg->DataLength = Data_BuffShiftLeft( FirstMsg->DataBuffer, BufferSize, MsgLen ); ReturnLen = BufferSize; }//end if //In this case I need to delete node and call reursive to Fill Buffer else // if ( MsgLen <= BufferSize ) { memcpy( Buff, FirstMsg->DataBuffer, MsgLen ); // copy the buffer QueueDeleteNode( RECV_QUEUE, pHead->Next ); ReturnLen = MsgLen + Rcv_FillBuffer( (Buff+MsgLen), (t_ushort)(BufferSize-MsgLen) ); }//end else return( ReturnLen ); }//end Rcv_FillBuffer
VOID hwRemove(MINIPORT_ADAPTER *Adapter) { PBUFFER_DESCRIPTOR dsc; ENTER; //sangam :Free the pending data packets and control packets while(!QueueEmpty(Adapter->hw.Q_Send.Head)) { //sangam dbg : used only for data packet so free skb DumpDebug(DISPATCH, "<1> Freeing Q_Send"); dsc = (PBUFFER_DESCRIPTOR) QueueGetHead(Adapter->hw.Q_Send.Head); if (!dsc) { DumpDebug(DISPATCH, "<1> Fail...node is null"); continue; } QueueRemoveHead(Adapter->hw.Q_Send.Head); if(dsc->Buffer) kfree(dsc->Buffer); if(dsc) kfree(dsc); } // stop data out buffer // if (Adapter->hw.ReceiveBuffer!= NULL) // kfree(Adapter->hw.ReceiveBuffer); // stop TempData out buffer #if 0 //cky 20100624 if (Adapter->hw.ReceiveTempBuffer!= NULL) kfree(Adapter->hw.ReceiveTempBuffer); #endif hwGPIODeInit(); LEAVE; }
/////////////////////////////////////////////////////////////////////////////// // ReqMgrResume // // Description: // Continues (and completes if possible) a pending request for objects, // if any. // // Inputs: // pReqMgr - Pointer to a request manager. // // Outputs: // pCount - Number of objects available for a resuming request. // ppfnCallback - Contains the callback function pointer as provided // in the ReqMgrGet function. // pContext1 - Contains the Context1 value for the resuming request, // as provided in the ReqMgrGet function. // pContext2 - Contains the Context2 value for the resuming request, // as provided in the ReqMgrGet function. // // Returns: // FSUCCESS - A request was completed. // FNOT_DONE - There were no pending requests. // FINSUFFICIENT_RESOURCES - There were not enough resources to complete a // pending request. // FPENDING - A request was continued, but not completed. // // Remarks: // At most one requset is resumed. // /////////////////////////////////////////////////////////////////////////////// FSTATUS ReqMgrResume( IN REQ_MGR* const pReqMgr, OUT uint32* const pCount, OUT REQ_CALLBACK* const ppfnCallback, OUT void** const pContext1, OUT void** const pContext2 ) { uint32 AvailableCount; REQUEST_OBJECT *pQueuedRequest; ASSERT( pReqMgr ); ASSERT( pReqMgr->m_Initialized ); // If no requests are pending, there's nothing to return. if( !QueueCount( &pReqMgr->m_RequestQueue ) ) return FNOT_DONE; // Get the item at the head of the request queue, but do not remove it yet. pQueuedRequest = (REQUEST_OBJECT*) QueueGetHead( &pReqMgr->m_RequestQueue ); // If no requests are pending, there's nothing to return. if (pQueuedRequest == NULL) return FNOT_DONE; *ppfnCallback = pQueuedRequest->pfnCallback; *pContext1 = pQueuedRequest->Context1; *pContext2 = pQueuedRequest->Context2; AvailableCount = pReqMgr->m_pfnGetCount( pReqMgr->m_GetContext ); // See if the request can be fulfilled. if( pQueuedRequest->Count > AvailableCount ) { if( !pQueuedRequest->PartialOk ) return( FINSUFFICIENT_RESOURCES ); pQueuedRequest->Count -= AvailableCount; *pCount = AvailableCount; return( FPENDING ); } *pCount = pQueuedRequest->Count; // The entire request can be met. Remove it from the request queue // and return. QueueRemove( &pReqMgr->m_RequestQueue ); // Return the internal request object to the free stack. GrowPoolPut( &pReqMgr->m_RequestPool, pQueuedRequest ); return( FSUCCESS ); }
// // Function: Rcv_GetUartBuffer // // Description: Get Data from UART // // Arguments: // // Name Type Direction Description // ----------- ----------- ----------- ----------------------------------- // MessageBuf UartMsgDef * OUT Data buffer // // Return Values: // // Name Explanation // ----------- ---------------------------------------------------------------- // RetStatus Error code < 0 if error // = 0 success ( no data ) // > 0 success ( num bytes of data received and copyed ) // int Rcv_GetUartBuffer( UartMsgDef *MessageBuf ) { QueueNodeDef *pHead = QueueGetHead(RECV_QUEUE); //Uart_BytesToRead (pHead->NumChann); MessageBuf->DataLength = MAX_LENGTH_MSG; MessageBuf->NumChann = pHead->NumChann; MessageBuf->DataLength = Uart_GetBuf( MessageBuf->NumChann, MessageBuf->DataBuffer, MessageBuf->DataLength ); return( MessageBuf->DataLength ); }//end Rcv_GetUartBuffer
// // Function: Resp_ProcessSyntaxSDU // // Description: Process Responce Message Data with SYNTAX status // // Arguments: // // Name Type Direction Description // ----------- ----------- ----------- ----------------------------------- // pNode QueueNodeDef * IN Node in QUEUE ( For check for what command this responce ) // Buff t_uchar * IN Buffer with data to process // Len int IN Length of buffer // MessageBuf char * OUT Buffer to return formatted string // // Return Values: // // Name Explanation // ----------- --------------------------------------------------------------- // RetStatus Error code // static int Resp_ProcessSyntaxSDU( QueueNodeDef *pNode, t_uchar *Buff, int Len, char *MessageBuf ) { int RetStatus = RM_SUCCESS; SyntaxErrorCode SyntaxType = Buff[EXT_RESULT_CODE]; #ifdef RM_HEAP char *TempBuf = (char *)Mem_Allocate( MAX_LENGTH_STR ); #else char TempBuf[MAX_LENGTH_STR]; #endif QueueNodeDef *pHead = QueueGetHead(SEND_QUEUE); VRM_StateDef *Statistics = (VRM_StateDef *)(pHead->Message.DataBuffer); if ( pNode->Message.DataBuffer != NULL ) PrintBuffer( "[E] Syntax error in command:", pNode->Message.DataBuffer, pNode->Message.DataLength ); RetStatus = Resp_CheckCommandType( pNode, Buff, Len, MessageBuf ); switch( SyntaxType ) { case INVALID: //ASCII 'b' //Invalid option in command Statistics->SYNTAX_CODE.INVALID++; Statistics->LAST_UPDATED_FIELD = POS_INVALID; sprintf( TempBuf, "%s Invalid option in command\n", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability break; case TOO_LONG: //ASCII 'c' //Data too long Statistics->SYNTAX_CODE.TOO_LONG++; Statistics->LAST_UPDATED_FIELD = POS_TOO_LONG; sprintf( TempBuf, "%s Data too long\n", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability break; default: Statistics->SYNTAX_CODE.UNDEFINED++; Statistics->LAST_UPDATED_FIELD = POS_UNDEFINED_SYNTAX_CODE; sprintf( TempBuf, "%s UNKNOWN = %04X HEX\n", MessageBuf, SyntaxType ); strcpy( MessageBuf, TempBuf );//for DOS compatability break; }//end switch #ifdef RM_HEAP Mem__Free( TempBuf ); #endif return( RetStatus ); //Responce SDU }//end Resp_ProcessSyntaxSDU
// // Function: Rcv_ProcessInQueue // // Description: Get Data from UART and compose Data for RM_Receive function // // Arguments: // // Name Type Direction Description // ----------- ----------- ----------- ----------------------------------- // dataR DataRecord * OUT Data buffer // // Return Values: // // Name Explanation // ----------- ---------------------------------------------------------------- // RetStatus Error code // int Rcv_ProcessInQueue( DataRecord *dataR ) { int RetStatus = RM_SUCCESS; #ifdef RM_HEAP UartMsgDef *pMessageBuf = (UartMsgDef *)Mem_Allocate( sizeof( UartMsgDef ) ); #else UartMsgDef MessageBuf; UartMsgDef *pMessageBuf = &MessageBuf; #endif QueueNodeDef *pHead = QueueGetHead(RECV_QUEUE); HeapBuffDef *UnProcessedData = Data_GetHeapPtr(); //Get data from UART pMessageBuf->DataBuffer = (t_uchar *)Mem_Allocate( MAX_LENGTH_MSG+16 ); RetStatus = Rcv_GetUartBuffer( pMessageBuf ); if ( pMessageBuf->DataLength > 0 ) // if ( RetStatus > 0 ) { //Print not processed data //PrintBuffer( "[I] Uart_GetBuf:", pMessageBuf->DataBuffer, pMessageBuf->DataLength ); Data_AddToHeap( UnProcessedData, pMessageBuf ); //All work will be done here RetStatus = Rcv_ProcessHeap( UnProcessedData, dataR ); }//end if else if ( pMessageBuf->DataLength < 0 ) RetStatus = pMessageBuf->DataLength; if ( pHead->Message.messagesInQueue > 0 ) PrintLogMessage( "[I] QUEUE LENGTH:", "", pHead->Message.messagesInQueue ); Mem__Free( pMessageBuf->DataBuffer ); #ifdef RM_HEAP Mem__Free( pMessageBuf ); #endif return( RetStatus ); }//end Rcv_ProcessInQueue
// // Function: Resp_DisplayFormatted // // Description: Process Responce Message Data // // Arguments: // // Name Type Direction Description // ----------- ----------- ----------- ----------------------------------- // pNode QueueNodeDef * IN Node in QUEUE ( For check for what command this responce ) // Buff t_uchar * IN Buffer with data to process // Len int IN Length of buffer // // Return Values: // // Name Explanation // ----------- --------------------------------------------------------------- // RetStatus Error code // int Resp_DisplayFormatted( QueueNodeDef *pNode, t_uchar *Buff, int Len ) { int RetStatus = RM_SUCCESS; time_t ltime = 0; #ifdef RM_HEAP char *TempBuf = (char *)Mem_Allocate( MAX_LENGTH_STR ); char *MessageBuf = (char *)Mem_Allocate( MAX_LENGTH_STR ); #else char TempBuf[MAX_LENGTH_STR]; char TimeBuf[MAX_LENGTH_STR]; char MessageBuf[MAX_LENGTH_STR]; #endif QueueNodeDef *pHead = QueueGetHead(SEND_QUEUE); VRM_StateDef *Statistics = (VRM_StateDef *)(pHead->Message.DataBuffer); RetStatus = Buff[RESULT_CODE]; MessageBuf[0] = '\0'; sprintf( MessageBuf, "Length = %04X HEX, SDU Tag = %04X HEX, Result Code =", Len - RESPONCE_DATA_OVERHEAD, pNode->InternalID ); //Get current time string _strtime( TimeBuf ); switch( RetStatus ) { case SUCCESS: //SUCCESS == '1' Statistics->RESP.SUCCESS++; Statistics->LAST_UPDATED_FIELD = POS_SUCCESS; sprintf( TempBuf, "%s SUCCESS\n Details:", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability sprintf( TempBuf, "[S] Response: SUCCESS, SENT: %ld, RESP: %ld, DIFF: %ld, TIME: %s", pNode->TimeStamp, time( <ime ), time( <ime ) - pNode->TimeStamp, TimeBuf ); Resp_ProcessSuccessSDU( pNode, Buff, Len, MessageBuf ); RetStatus = RM_SUCCESS; break; case XFAIL: //XFAIL == '2' Statistics->RESP.XFAIL++; Statistics->LAST_UPDATED_FIELD = POS_XFAIL; sprintf( TempBuf, "%s XFAIL \n Details:", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability sprintf( TempBuf, "[E] Response: XFAIL, SENT: %ld, RESP: %ld, TIME: %s", pNode->TimeStamp, time( <ime ), TimeBuf ); Resp_ProcessXfailSDU( pNode, Buff, Len, MessageBuf ); RetStatus = RM_ERROR_GENERAL; break; case SYNTAX: //SYNTAX == '3' Statistics->RESP.SYNTAX++; Statistics->LAST_UPDATED_FIELD = POS_SYNTAX; sprintf( TempBuf, "%s SYNTAX \n Details:", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability sprintf( TempBuf, "[E] Response: SYNTAX ERROR, SENT: %ld, RESP: %ld, TIME: %s", pNode->TimeStamp, time( <ime ), TimeBuf ); Resp_ProcessSyntaxSDU( pNode, Buff, Len, MessageBuf ); RetStatus = RM_ERROR_GENERAL; break; default: Statistics->RESP.UNDEFINED++; Statistics->LAST_UPDATED_FIELD = POS_UNDEFINED_RESP; sprintf( TempBuf, "%s UNKNOWN = %04X HEX\n", MessageBuf, RetStatus ); strcpy( MessageBuf, TempBuf );//for DOS compatability strcpy( TempBuf, "[E] Response: UNKNOWN" ); break; }//end switch //Print all messages formatted in MessageBuf PrintLogMessage( TempBuf, "", 0 ); PrintBuffer( "[RESP][Length][SDU Tag][Result Code][Responce Information]", Buff, Len ); PrintLogMessage( MessageBuf, "", 0 ); #ifdef RM_HEAP Mem__Free( MessageBuf ); Mem__Free( TempBuf ); #endif return( RetStatus ); //Responce SDU }//end Resp_DisplayFormatted
// // Function: Resp_ProcessXfailSDU // // Description: Process Responce Message Data with XFAIL status // // Arguments: // // Name Type Direction Description // ----------- ----------- ----------- ----------------------------------- // pNode QueueNodeDef * IN Node in QUEUE ( For check for what command this responce ) // Buff t_uchar * IN Buffer with data to process // Len int IN Length of buffer // MessageBuf char * OUT Buffer to return formatted string // // Return Values: // // Name Explanation // ----------- --------------------------------------------------------------- // RetStatus Error code // static int Resp_ProcessXfailSDU( QueueNodeDef *pNode, t_uchar *Buff, int Len, char *MessageBuf ) { int RetStatus = RM_SUCCESS; XFailErrorCode XFailType = Buff[EXT_RESULT_CODE]; #ifdef RM_HEAP char *TempBuf = (char *)Mem_Allocate( MAX_LENGTH_STR ); #else char TempBuf[MAX_LENGTH_STR]; #endif QueueNodeDef *pHead = QueueGetHead(SEND_QUEUE); VRM_StateDef *Statistics = (VRM_StateDef *)(pHead->Message.DataBuffer); RetStatus = Resp_CheckCommandType( pNode, Buff, Len, MessageBuf ); switch( XFailType ) //Page APP-124 { case NO_RESPONSE: //ASCII 'A' //No response from network Statistics->XFAIL_CODE.NO_RESPONSE++; Statistics->LAST_UPDATED_FIELD = POS_NO_RESPONSE; sprintf( TempBuf, "%s\b No response from network\n", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability /* Terminal Error logger */ PrintError ("No response from network", "", 0); break; case NACK: //ASCII 'B' //Negative ACK received Statistics->XFAIL_CODE.NACK++; Statistics->LAST_UPDATED_FIELD = POS_NACK; sprintf( TempBuf, "%s\b Negative ACK received\n", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability /* Terminal Error logger */ PrintError ("Negative ACK received", "", 0); break; case HOST_DOWN: //ASCII 'C' //Host down Statistics->XFAIL_CODE.HOST_DOWN++; Statistics->LAST_UPDATED_FIELD = POS_HOST_DOWN; sprintf( TempBuf, "%s\b Host down\n", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability /* Terminal Error logger */ PrintError ("Host down", "", 0); break; case NOT_REGISTERED: //ASCII 'D' //VRM 500 not registered Statistics->XFAIL_CODE.NOT_REGISTERED++; Statistics->LAST_UPDATED_FIELD = POS_NOT_REGISTERED; sprintf( TempBuf, "%s\b VRM 500 not registered\n", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability /* Terminal Error logger */ PrintError ("VRM 500 not registered", "", 0); break; case LOW_BATTERY: //ASCII 'E' //Low battery - cannot transmit Statistics->XFAIL_CODE.LOW_BATTERY++; Statistics->LAST_UPDATED_FIELD = POS_LOW_BATTERY; sprintf( TempBuf, "%s\b Low battery - cannot transmit\n", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability /* Terminal Error logger */ PrintError ("VRM 500 Low battery", "", 0); break; case IBQ_FULL: //ASCII 'F' //VRM 500 inbound queue full Statistics->XFAIL_CODE.IBQ_FULL++; Statistics->LAST_UPDATED_FIELD = POS_IBQ_FULL; sprintf( TempBuf, "%s\b VRM 500 inbound queue full\n", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability /* Terminal Error logger */ PrintError ("VRM 500 inbound queue full", "", 0); break; case TX_DISABLED: //ASCII 'G' //Radio transmitter disabled Statistics->XFAIL_CODE.TX_DISABLED++; Statistics->LAST_UPDATED_FIELD = POS_TX_DISABLED_XFAIL; sprintf( TempBuf, "%s\b Radio transmitter disabled\n", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability /* Terminal Error logger */ PrintError ("Radio transmitter disabled", "", 0); break; case BUSY: //ASCII 'H' //Resource unavalialible Statistics->XFAIL_CODE.BUSY++; Statistics->LAST_UPDATED_FIELD = POS_BUSY; sprintf( TempBuf, "%s\b Resource unavalialible\n", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability /* Terminal Error logger */ PrintError ("Resource unavalialible", "", 0); break; case NOT_AVAILABLE: //ASCII 'I' //Unimplemented service Statistics->XFAIL_CODE.NOT_AVAILABLE++; Statistics->LAST_UPDATED_FIELD = POS_NOT_AVAILABLE; sprintf( TempBuf, "%s\b Unimplemented service\n", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability /* Terminal Error logger */ PrintError ("Unimplemented service", "", 0); break; case HW_ERROR: //ASCII 'J' //Generic error Statistics->XFAIL_CODE.HW_ERROR++; Statistics->LAST_UPDATED_FIELD = POS_HW_ERROR; sprintf( TempBuf, "%s\b Generic error\n", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability /* Terminal Error logger */ PrintError ("Generic error", "", 0); break; case INVALID_MODE: //ASCII 'K' //Invalid mode of operation Statistics->XFAIL_CODE.INVALID_MODE++; Statistics->LAST_UPDATED_FIELD = POS_INVALID_MODE; sprintf( TempBuf, "%s\b Invalid mode of operation\n", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability /* Terminal Error logger */ PrintError ("Invalid mode of operation", "", 0); break; case NO_MESSAGES: //ASCII 'L' //No outbound messages avaliable Statistics->XFAIL_CODE.NO_MESSAGES++; Statistics->LAST_UPDATED_FIELD = POS_NO_MESSAGES; sprintf( TempBuf, "%s\b No outbound messages avaliable\n", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability /* Terminal Error logger */ PrintError ("No outbound messages avaliable", "", 0); break; case MSGS_PENDING: //ASCII 'M' //Cannnot execute command due to pending inbound messages Statistics->XFAIL_CODE.MSGS_PENDING++; Statistics->LAST_UPDATED_FIELD = POS_MSGS_PENDING; sprintf( TempBuf, "%s\b Cannnot execute command due to pending inbound messages\n", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability /* Terminal Error logger */ PrintError ("Cannnot execute command", "", 0); break; case SW_ERROR: //ASCII 'N' //Sofware error has occured Statistics->XFAIL_CODE.SW_ERROR++; Statistics->LAST_UPDATED_FIELD = POS_SW_ERROR; sprintf( TempBuf, "%s\b Sofware error has occured\n", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability /* Terminal Error logger */ PrintError ("Sofware error has occured", "", 0); break; case OUT_OF_RANGE: //ASCII 'O' //RF not in range Statistics->XFAIL_CODE.OUT_OF_RANGE++; Statistics->LAST_UPDATED_FIELD = POS_OUT_OF_RANGE; sprintf( TempBuf, "%s\b RF not in range\n", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability /* Terminal Error logger */ PrintError ("RF not in range", "", 0); break; case PACKET_ERROR: //ASCII 'Z' //SDU DATA corruption( only in confirmed mode ) Statistics->XFAIL_CODE.PACKET_ERROR++; Statistics->LAST_UPDATED_FIELD = POS_PACKET_ERROR; sprintf( TempBuf, "%s\b SDU DATA corruption( only in confirmed mode )\n", MessageBuf ); strcpy( MessageBuf, TempBuf );//for DOS compatability /* Terminal Error logger */ PrintError ("DATA corruption", "", 0); break; default: Statistics->XFAIL_CODE.UNDEFINED++; Statistics->LAST_UPDATED_FIELD = POS_UNDEFINED_XFAIL_CODE; sprintf( TempBuf, "%s\b UNKNOWN = %04X HEX\n", MessageBuf, XFailType ); strcpy( MessageBuf, TempBuf );//for DOS compatability break; }//end switch #ifdef RM_HEAP Mem__Free( TempBuf ); #endif return( RetStatus ); //Responce SDU }//end Resp_ProcessXfailSDU