⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bus232.cpp

📁 SITEL的2.4G无线分机CVM的客户端PP参考程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
*  Program/file: BUS232.CPP
*
*  Copyright (C) by RTX TELECOM A/S, Denmark.
*  These computer program listings and specifications, are the property of
*  RTX TELECOM A/S, Denmark and shall not be reproduced or copied or used in
*  whole or in part without written permission from RTX TELECOM A/S, Denmark.
*
*  Programmer: LHJ
*
*  MODULE: WIN32SIM
*  CONTROLLING DOCUMENT:
*  SYSTEM DEPENDENCIES:
*
*
*  DESCRIPTION: RS232 driver
*
*
*
*
*
****************************************************************************/

/****************************************************************************
*                                  PVCS info
*****************************************************************************

$Author:   SS  $
$Date:   17 Jul 2003 11:38:08  $
$Revision:   1.7  $
$Modtime:   16 Jul 2003 12:43:54  $

*/

#include <conio.h>
#include <process.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <windows.h>
#include <process.h>

#ifdef CVMCON
  #include <std-def.h>
  #include <dbg_mail.h>
  #include <clrsx.h>
  #include <cmclient.h>
#else
  #include <win32sim\common\std-def.h>
  #include <win32sim\rsx\dbg_mail.h>
  #include <win32sim\rsx\clrsx.h>
  #include <win32sim\cm\cmclient.h>
#endif  

#ifdef RSX
   #include <win32sim\debug\dbg_intf.h>
#endif   


#ifndef RSX   
   extern void sendmail_ReceivePacket(uint16 Length, uint8 *bDataPtr);
#endif



extern clRsxType clRsx;                  // RSX vindow.
extern void internal_SendPacketToTask(int iTaskId, int iLength, unsigned char *bInputDataPtr);

//extern int32 debug_ProgramId;
//extern long debug_ProgramId;
#ifdef RSX
  extern "C" void PrintfInt(char *format, ...);
#endif

HANDLE hComPortHandle = NULL;
OVERLAPPED ovlRd,ovlWr;

HANDLE Rx232Id, Tx232Id, RtsTaskId;  // Thread handles
void InitRs232(int Port, int BaudRate);

// Used to stop the tasks.
bool StopTxTask, StopRxTask, StopRtsTask;


HANDLE semTestbusFrameQueueSem;     // mutex semaphore to protect TestbusFrameQueue

int RtsTimeout = 0;

uint32 iTxDelay = 0;

#define MAX_PACKET_LENGTH 350

#ifdef BUSM_HDLC // Sliding window protocol
#define MIN_PACKET_LENGTH 1   // Control frames have length 1
#else
#define MIN_PACKET_LENGTH 4
#endif


#ifdef SIM_RS232_ERRORS
uint8 BUSM_SimulateRxError = 0;
uint8 BUSM_SimulateTxError = 0;
#endif


#ifdef BUSM_HDLC // CVM HDLC
#define BUSM_FLOW_FINAL         0x08
#define BUSM_FLOW_RX_SEQ_MASK   0x07
#define BUSM_FLOW_TX_SEQ_MASK   0x70
#define BUSM_FLOW_CONTROL_FRAME 0x80
#define BUSM_FLOW_CONTROL_MASK  0x70
#define BUSM_FLOW_CONTROL_SHIFT 4

/****************************************************************************
*                     Enumerations/Type definitions/Structs
****************************************************************************/

typedef enum
{
  BUSM_UNLOCKED,
  BUSM_LOCK_PENDING,
  BUSM_LOCKED
}ENUM8(eBusmState);

typedef enum
{
  INFORMATION_FRAME,
  SUPERVISORY_FRAME,
  UNNUMBERED_FRAME,
  MAX_FRAME
} ENUM8(eFrameTypeEnum);

typedef enum
{
  BUSM_FLOW_CTRL_RR  = 0 ,
  BUSM_FLOW_CTRL_REJ = 1 ,
  BUSM_FLOW_CTRL_RNR = 2 ,
} ENUM8(BusmCtrlSpecType);

typedef enum
{
  BUSM_FLOW_UNNMB_SABM = 0,  // Set Asynchronous Balanced Mode, i.e. ask peer to reset counters
} ENUM8(BusmUnNmbSpecType);

typedef struct
{
  uint8 RxSeq       : 3; // Next sequence expected from peer
  uint8 PollFinal   : 1; // If set -> peer must be answered
  uint8 TxSeq       : 3; // Sequence of this frame
  uint8 InfoControl : 1; // Must be 0
} BUSM_InfoFrameType;

typedef struct
{
  uint8 RxSeq               : 3; // Next sequence expected from peer
  uint8 PollFinal           : 1; // If set -> peer must be answered -
  BusmCtrlSpecType CtrlSpec : 2; 
  uint8 Supervisory         : 1; // Must be 0
  uint8 InfoControl         : 1; // Must be 1
} BUSM_SuperVisoryControlFrameType;

typedef struct
{
  uint8 Modifier                : 3; // Not used
  uint8 PollFinal               : 1; // If set -> peer must be answered - 
  BusmUnNmbSpecType UnNmbSpec   : 2;
  uint8 Unnumbered              : 1; // Must be 1
  uint8 InfoControl             : 1; // Must be 1
} BUSM_UnnumberedControlFrameType;


// Types for length and sequence fields in buffer
typedef uint16 BUSM_PacketLengthType;
typedef uint8 BUSM_SequenceNrType;
typedef uint8 BUSM_DleType;
// Type for paylaod header
typedef struct 
{
  uint8 uProgId;
  uint8 uTaskId;
} BUSM_PayloadHeaderType;

// Buffer header, a mail in the buffer is organized as: BUSM_BufferHeaderType - Mail - BUSM_TailMarkerType
typedef struct
{
  //BUSM_PacketLengthType length; // length filtered out in RSX
  BUSM_SequenceNrType uControl;
  BUSM_PayloadHeaderType payloadHead;
} BUSM_BufferHeaderType;


typedef struct
{
  BUSM_DleType Dle;
  uint8 uLengthMSB;
  uint8 uLengthLSB;
  BUSM_InfoFrameType uControl;
  BUSM_PayloadHeaderType payloadHead;
  uint8 payloadTail[1];  // Equals zero length package with 1 CRC byte
} BUSM_FrameType;

#define BUSM_HDLC_SEQ_MOD 0x07
#define BUSM_MAX_OUTSTANDING_FRAMES 0x06

#define BUSM_MAX_FRAMES_BEFORE_FINAL_FLAG 0x03


typedef struct 
{
  uint8   bExpectedRxSeq; 
  uint8   bNextTxSeq;
  uint8   bTxNoAckCnt;
  uint8   bExpectedAck;
  clock_t tNoAckNowledge;
  eBusmState eHdlcState;
} sHdlcControlType;

sHdlcControlType sHdlcControl;

static bool RsxSwpCheckReceivedFrame(uint8 *RxFrame);


#define NO_ACKNOWLEDGE_TIMEOUT 0.2 //200 ms

extern void bus232_ResetHDLCprotocol(void);
extern void bus232_SendPacketToUnit(int iTaskId, int iLength, unsigned char *bInputDataPtr);
//static void bus232_RetransmitFrame(BUSM_FrameType *bInputDataPtr);
static void bus232_RetransmitFrame(BUSM_FrameType *bInputDataPtr, bool boolPollFinal);
static void bus232_SendUnnumberedFrame(int iTaskId, bool boolPollFinal);


static bool Between(unsigned char a, unsigned int b, unsigned int c);

uint8 WrongFrame;
BUSM_FrameType *NotAcknowledgeFramePtr[BUSM_HDLC_SEQ_MOD+1];

HANDLE semBusmHdlcSem;     // mutex semaphore to protect hdlc data

FILE *Rs232HdlcLogFile;

bool Rs232LogToFile=FALSE;

typedef struct 
{
  int  iTaskId;
  int  iLength;
  void *Next;
  uint8 Data[1]; // variable length
} sUnsentInfoframes;

sUnsentInfoframes *FirstUnsent=NULL;
sUnsentInfoframes *LastUnsent=NULL;

#endif  //HDLC




// Queue stuff.
struct QueueStorage {
  struct QueueStorage *Next;
  void *Data;
};

typedef struct {
  struct QueueStorage *First,*Last;
} QueueRecord;

typedef struct {
  uint8 bLength;
  uint8 bData[1];
} QueueElement;

QueueRecord TestbusFrameQueue;

void EnQueue(QueueRecord *rec,void *vdata)
{
  struct QueueStorage *tmp;
  tmp=(struct QueueStorage *) malloc(sizeof(struct QueueStorage));
  tmp->Next=NULL;
  tmp->Data=vdata;
  if(rec->First==NULL) {
    rec->First=tmp;
    rec->Last=tmp;
  } else {
    rec->Last->Next=tmp;
    rec->Last=tmp;
  }
}

void *DeQueue(QueueRecord *rec)
{
  void *tmp;
  struct QueueStorage *tmpqe;
  if(rec->First==NULL)
    return NULL;
  tmpqe=rec->First;
  rec->First=tmpqe->Next;
  tmp=tmpqe->Data;
  free(tmpqe);
  return tmp;
}

#ifdef __TURBOC__
   #pragma argsused
#endif   
VOID RtsProc(PVOID unused)
{
   while(StopRtsTask == FALSE)
   {
      Sleep(500);
      switch(RtsTimeout)
      {
         case 0:
            break;
         case 1:
            EscapeCommFunction( hComPortHandle, CLRRTS );
         default:
            RtsTimeout--;
            break;
      }
   }

   StopRtsTask = FALSE;   // To indicate that the task has stopped
   ExitThread(0);
}


#ifdef __TURBOC__
   #pragma argsused
#endif   
VOID Tx232Proc(PVOID unused)
{
   uint8 bTransmit232ElementArr[500];
   uint8 *Rs232FrameQueuePtr;
   uint16 bSenderSize;
   unsigned long dwWritten;
   

   while(StopTxTask == FALSE)
   {
      WaitForSingleObject(semTestbusFrameQueueSem, INFINITE);
      if(TestbusFrameQueue.First != NULL)
      {
         Rs232FrameQueuePtr = (uint8*) DeQueue(&TestbusFrameQueue);
         bSenderSize = (uint16) (256*Rs232FrameQueuePtr[1] + Rs232FrameQueuePtr[2] + 4);
         memcpy(bTransmit232ElementArr, Rs232FrameQueuePtr, bSenderSize);

         #ifdef BUSM_HDLC // Sliding window protocol
         if (Rs232LogToFile)
         { 
           if (bSenderSize > 0x100)
           {           
              fprintf(Rs232HdlcLogFile, "\n bSenderSize fuck up!!! %x",bSenderSize);       
              #ifdef RSX
                PrintfInt("bSenderSize fuck up!!!\n");
              #endif  
           }
         }
         #endif

         #ifdef SIM_RS232_ERRORS // 
         if (--BUSM_SimulateTxError == 0)
         {
           bTransmit232ElementArr[6]++; // Simulate transmit error, will be percieved as receive error in target
           #ifdef RSX
           if(clRsx.iPrintBytes)
           {
             clRsx.Printf("\n Sim Tx Error Checksum = %02X",bTransmit232ElementArr[6]);
           }
           #endif
           BUSM_SimulateTxError = rand()&0x1F; // a littlebit random
           if (BUSM_SimulateTxError == 0) BUSM_SimulateTxError = 1;
         }
         #endif

         #ifdef RSX
         if(clRsx.iPrintBytes)
         {
            int c1;
            clRsx.Printf("\nO: ");
            for(c1=0; c1<bSenderSize; c1++)
               clRsx.Printf("%02X ",(int) bTransmit232ElementArr[c1]);
         }
         #else
            #ifdef SENDMAIL_DEBUG
            {
               int c1;
               printf("\nO: ");
               for(c1=0; c1<bSenderSize; c1++)
                  printf("%02X ",(int) bTransmit232ElementArr[c1]);
            }
            #endif
         #endif

         EscapeCommFunction( hComPortHandle, SETRTS );

//         Sleep(10);   // To fix bug in target.

         ovlWr.Offset     = 0;
         ovlWr.OffsetHigh = 0;
         ResetEvent(ovlWr.hEvent);

         if(iTxDelay == 0)
         {
            //DWORD lpEvtMask;
           
            WriteFile(hComPortHandle, bTransmit232ElementArr, bSenderSize, &dwWritten, &ovlWr);            
/*          lpEvtMask = 0;
            while (!(lpEvtMask&EV_TXEMPTY))  // Wait until finished transmitting buffer
            {
              WaitCommEvent(hComPortHandle, &lpEvtMask, &ovlWr);              
            };*/
         }
         else
         {
            int i;

            for(i=0; i<bSenderSize; i++)
            {
               WriteFile(hComPortHandle, &bTransmit232ElementArr[i], 1, &dwWritten, &ovlWr);
               Sleep(iTxDelay);
            }
         }
         free(Rs232FrameQueuePtr);
         ReleaseMutex(semTestbusFrameQueueSem);

         RtsTimeout = 3;

      }
      else
      {
         ReleaseMutex(semTestbusFrameQueueSem);
         #ifdef BUSM_HDLC // Sliding window protocol
         Sleep(10);  // OK to sleep 10 ms, corresponds to target kernel tick
         #else
         Sleep(100);  //If staying in idle loop give other programs CPU time
         #endif
      }
      
      #ifdef BUSM_HDLC // Sliding window protocol
      WaitForSingleObject(semBusmHdlcSem, INFINITE);
      if (sHdlcControl.tNoAckNowledge)
      {
        if ((clock()-sHdlcControl.tNoAckNowledge)>(CLOCKS_PER_SEC*NO_ACKNOWLEDGE_TIMEOUT)) // timer has run out
        {          
          uint8 bFirstUnAcknowledged;
          uint8 i;
          bool boolFinal;
          #ifdef RSX
            PrintfInt("Retransmit\n");
          #endif  
          if (Rs232LogToFile)
          {
            fprintf(Rs232HdlcLogFile, "\n Retransmit");
          }
          // Transmit all outstanding frames again.
          bFirstUnAcknowledged = sHdlcControl.bExpectedAck;
          for (i=0;i<sHdlcControl.bTxNoAckCnt;i++)
          { 
            if ((i+1)== sHdlcControl.bTxNoAckCnt) // if last
            {
              boolFinal=TRUE;
            }
            else
            {
              boolFinal=FALSE;
            }
            bus232_RetransmitFrame(NotAcknowledgeFramePtr[bFirstUnAcknowledged],boolFinal);
            bFirstUnAcknowledged=(bFirstUnAcknowledged+1)&BUSM_HDLC_SEQ_MOD;
          }
          sHdlcControl.tNoAckNowledge = clock();          
        }
      }
      ReleaseMutex(semBusmHdlcSem);
      #endif
   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -