xlLINFunctions.cpp
Upload User: dfymccf
Upload Date: 2008-03-14
Package Size: 18k
Code Size: 18k
Category:

SCM

Development Platform:

Visual C++

  1. /*----------------------------------------------------------------------------
  2. | File        : LINFunctions.cpp
  3. | Project     : Vector LIN Example - manage the LIN access
  4. |
  5. | Description : 
  6. |-----------------------------------------------------------------------------
  7. | $Author: J鰎g $    $Locker: $   $Revision: 16 $
  8. | $Header: /VCANDRV/XLAPI/samples/xlLinExample/xlLINFunctions.cpp 16    14.11.05 10:54 J鰎g $
  9. |-----------------------------------------------------------------------------
  10. | Copyright (c) 2004 by Vector Informatik GmbH.  All rights reserved.
  11. |---------------------------------------------------------------------------*/
  12. #include "stdafx.h"
  13. #include "xlLINExample.h"
  14. #include "xlLINFunctions.h"
  15. #include "debug.h"
  16. #ifdef _DEBUG
  17. #undef THIS_FILE
  18. static char THIS_FILE[]=__FILE__;
  19. #define new DEBUG_NEW
  20. #endif
  21. // ---------------------------------------------------
  22. // globals
  23. BOOL      g_bThreadRun;
  24. TStruct   g_th;
  25. //////////////////////////////////////////////////////////////////////
  26. // Construction/Destruction
  27. //////////////////////////////////////////////////////////////////////
  28. CLINFunctions::CLINFunctions() {
  29.   m_xlPortHandle = XL_INVALID_PORTHANDLE;
  30.   m_xlChannelMask[MASTER] = m_xlChannelMask[SLAVE] = 0;
  31. }
  32. CLINFunctions::~CLINFunctions() 
  33. {
  34. }
  35. ////////////////////////////////////////////////////////////////////////////
  36. //! LINGetDevice
  37. //! readout the registry to get the hardware information. If there is no 
  38. //! application which is named "xlLINExample" a new one is generated. 
  39. //!
  40. //////////////////////////////////////////////////////////////////////////// 
  41. XLstatus CLINFunctions::LINGetDevice()
  42. {
  43.   XLstatus         xlStatus = XL_ERROR;
  44.   char            tmp[100];
  45.   xlStatus = xlOpenDriver();
  46.   sprintf(tmp, "xlOpenDriver, stat: %d", xlStatus);
  47.   DEBUG(DEBUG_ADV, tmp);
  48.   if (xlStatus != XL_SUCCESS) return xlStatus;
  49.   xlStatus = linGetChannelMask(MASTER);
  50.   xlStatus = linGetChannelMask(SLAVE);
  51.   if ( (m_xlChannelMask[MASTER] == 0) || (m_xlChannelMask[SLAVE] == 0) ) return XL_ERROR;
  52.   
  53.   return xlStatus;
  54. }
  55. ////////////////////////////////////////////////////////////////////////////
  56. //! LINInit
  57. //! LINExample use ONE port for master and slave which is opened. Also a 
  58. //! thread for all incoming messages is created.
  59. //!
  60. //////////////////////////////////////////////////////////////////////////// 
  61. XLstatus CLINFunctions::LINInit(int linID)
  62. {
  63.   XLstatus         xlStatus = XL_ERROR;
  64.   XLaccess         m_xlChannelMask_both;
  65.   XLaccess         xlPermissionMask;
  66.   char             tmp[100];
  67.   // ---------------------------------------
  68.   // Open ONE port for both channels master+slave
  69.   // ---------------------------------------
  70.   // calculate the channelMask for both channel 
  71.   m_xlChannelMask_both = m_xlChannelMask[MASTER] + m_xlChannelMask[SLAVE];
  72.   xlPermissionMask = m_xlChannelMask_both;
  73.   xlStatus = xlOpenPort(&m_xlPortHandle, "LIN Example", m_xlChannelMask_both, &xlPermissionMask, 256, XL_INTERFACE_VERSION, XL_BUS_TYPE_LIN); 
  74.   sprintf(tmp, "xlOpenPort: PortHandle: %d; Permissionmask: 0x%I64x; Status: %d", m_xlPortHandle, xlPermissionMask, xlStatus);
  75.   DEBUG(DEBUG_ADV, tmp);
  76.   m_pStatusBox->InsertString(-1,"xlOpenPort for both");
  77.   
  78.   if (m_xlPortHandle == XL_INVALID_PORTHANDLE) return XL_ERROR;
  79.   if (xlStatus == XL_ERR_INVALID_ACCESS) return xlStatus;
  80.   // ---------------------------------------
  81.   // Create ONE thread for both channels
  82.   // ---------------------------------------
  83.   linCreateRxThread();
  84.   // ---------------------------------------
  85.   // Init each channel (master+slave)
  86.   // ---------------------------------------
  87.   xlStatus = linInitMaster();
  88.   if (xlStatus) {
  89.     m_pStatusBox->InsertString(-1,"Init Master failed!");
  90.     return xlStatus;
  91.   }
  92.   m_pStatusBox->InsertString(-1,"Init Master");
  93.   xlStatus = linInitSlave(linID);
  94.   if (xlStatus) {
  95.     m_pStatusBox->InsertString(-1,"Init Slave failed!");
  96.     return xlStatus;
  97.   }
  98.   m_pStatusBox->InsertString(-1,"Init Slave");
  99.  
  100.   return xlStatus;
  101. }
  102. ///////////////////////////////////////////////////////////////////////////
  103. //! LINClose()
  104. //! Close the port
  105. //!
  106. ////////////////////////////////////////////////////////////////////////////
  107. XLstatus CLINFunctions::LINClose() {
  108.   XLstatus         xlStatus = XL_SUCCESS;
  109.   XLaccess         xlChannelMask_both = m_xlChannelMask[MASTER] | m_xlChannelMask[SLAVE];
  110.   char            tmp[100];
  111.  
  112.   g_bThreadRun = FALSE;
  113.   // Wait until the thread is done...
  114.   Sleep(100);
  115.   if(XL_INVALID_PORTHANDLE == m_xlPortHandle) {
  116.     return(xlStatus);
  117.   }
  118.  
  119.   if(xlChannelMask_both) {
  120.     xlStatus = xlDeactivateChannel(m_xlPortHandle, xlChannelMask_both);
  121.     sprintf(tmp, "xlDeactivateChannel, status: %d",  xlStatus);
  122.     DEBUG(DEBUG_ADV, tmp);
  123.     if(xlStatus) return xlStatus;
  124.   }
  125.   xlStatus = xlClosePort(m_xlPortHandle);
  126.   sprintf(tmp, "xlClosePort, status: %d",  xlStatus);
  127.   DEBUG(DEBUG_ADV, tmp);
  128.   if(xlStatus) return xlStatus;
  129.   m_xlPortHandle = XL_INVALID_PORTHANDLE;
  130.   xlStatus = xlCloseDriver();
  131.   sprintf(tmp, "xlCloseDriver, status: %d",  xlStatus);
  132.   DEBUG(DEBUG_ADV, tmp);
  133.   if(xlStatus) return xlStatus;
  134.   m_pStatusBox->InsertString(-1,"Close All");
  135.   return xlStatus;
  136. }
  137. ///////////////////////////////////////////////////////////////////////////
  138. //! LINSendMasterReq()
  139. //! Sends a master request to the LIN bus.
  140. //!
  141. ////////////////////////////////////////////////////////////////////////////
  142. XLstatus CLINFunctions::LINSendMasterReq(BYTE data, int linID)
  143. {
  144.   XLstatus        xlStatus = XL_ERROR;
  145.   char            tmp[100];
  146.   
  147.   // send the master request
  148.   xlStatus = xlLinSendRequest(m_xlPortHandle, m_xlChannelMask[MASTER], linID, 0);
  149.   sprintf(tmp, "SendRq CM: '%I64u', status: %d", m_xlChannelMask[MASTER], xlStatus);
  150.   DEBUG(DEBUG_ADV, tmp);
  151.   m_pStatusBox->InsertString(-1,"Master Request");
  152.   // setup the slave
  153.   xlStatus = linSetSlave(data);
  154.   
  155.   return xlStatus;
  156. }
  157. ////////////////////////////////////////////////////////////////////////////
  158. //! linGetChannelMask
  159. //! parse the registry to get the channelmask
  160. //!
  161. //////////////////////////////////////////////////////////////////////////// 
  162. XLstatus CLINFunctions::linGetChannelMask(int LINType)
  163. {
  164.   XLstatus        xlStatus = XL_ERROR;
  165.   char            tmp[100];
  166.   // default values
  167.   unsigned int  hwType    = XL_HWTYPE_CANCARDXL;
  168.   unsigned int  hwIndex   = 0;
  169.   unsigned int  hwChannel = LINType-1;   // because 0->CH1 should be MASTER, 1->CH2 should be SLAVE
  170.   unsigned int  busType   = XL_BUS_TYPE_LIN;   
  171.   unsigned int  i; 
  172.  
  173.   XLdriverConfig  xlDrvConfig;
  174.   xlStatus = xlGetApplConfig("xlLINExample", hwChannel, &hwType, &hwIndex, &hwChannel, busType);              
  175.   
  176.   // Set the params into registry (default values...!)
  177.   if (xlStatus) {
  178.     DEBUG(DEBUG_ADV,"set in registry");
  179.     //check for hardware:
  180.     xlStatus = xlGetDriverConfig(&xlDrvConfig);
  181.     for (i=0; i<xlDrvConfig.channelCount; i++) {
  182.       // check PC for hardware with LINCabs or LINPiggy's 
  183.       if ( xlDrvConfig.channel[i].channelBusCapabilities & XL_BUS_ACTIVE_CAP_LIN) {
  184.         hwType = xlDrvConfig.channel[i].hwType;
  185.         sprintf (tmp, "Found LIN hWType: %d;", hwType);
  186.         DEBUG(DEBUG_ADV,tmp);
  187.          xlStatus = xlSetApplConfig( // Registration of Application with default settings
  188.         "xlLINExample",          // Application Name
  189.         LINType-1,              // Application channel 0 or 1
  190.         hwType,                 // hwType  (CANcardXL...)    
  191.         hwIndex,                // Index of hardware (slot) (0,1,...)
  192.         hwChannel,              // Index of channel (connector) (0,1,...)
  193.         busType);               // the application is for LIN.
  194.       }
  195.     }
  196.   }
  197.   else DEBUG(DEBUG_ADV,"found in registry");
  198.   
  199.   // check for LINPiggy or LINCabs
  200.   xlStatus = xlGetDriverConfig(&xlDrvConfig);
  201.   for (i=0; i<xlDrvConfig.channelCount; i++) {
  202.     // check for LINCabs or LINPiggy's 
  203.     if ( xlDrvConfig.channel[i].channelBusCapabilities & XL_BUS_ACTIVE_CAP_LIN) {
  204.       // and check the right hardwaretype
  205.       if (xlDrvConfig.channel[i].hwType==hwType) {
  206.         m_xlChannelMask[LINType] = xlGetChannelMask(hwType, hwIndex, hwChannel);
  207.       }
  208.     }
  209.   }
  210.   sprintf (tmp, "Init LIN hWType: %d; hWIndex: %d; hwChannel: %d, channelMask: 0x%I64x for %d", hwType, hwIndex, hwChannel, m_xlChannelMask[LINType], LINType);
  211.   DEBUG(DEBUG_ADV,tmp);
  212.   return xlStatus;
  213. }
  214. ////////////////////////////////////////////////////////////////////////////
  215. //! linCreateRxThread
  216. //! set the notification and creates the thread.
  217. //!
  218. ////////////////////////////////////////////////////////////////////////////
  219. XLstatus CLINFunctions::linCreateRxThread()
  220. {
  221.   
  222.   XLstatus      xlStatus;
  223.   DWORD         ThreadId=0;
  224.   char          tmp[100];
  225.  
  226.   if (m_xlPortHandle!= XL_INVALID_PORTHANDLE) {
  227.     sprintf(tmp, "Found OpenPort: %d", m_xlPortHandle);
  228.     DEBUG(DEBUG_ADV, tmp);
  229.     // Send a event for each Msg!!!
  230.     xlStatus = xlSetNotification (m_xlPortHandle, &m_hMsgEvent, 1);
  231.     sprintf(tmp, "SetNotification '%d', xlStatus: %d", m_hMsgEvent, xlStatus);
  232.     DEBUG(DEBUG_ADV, tmp);
  233.     // for the RxThread
  234.     g_th.xlPortHandle = m_xlPortHandle;
  235.     g_th.hMsgEvent    = m_hMsgEvent; 
  236.     g_th.pListRX      = m_pRXBox;
  237.     g_th.pStatusBox   = m_pStatusBox;
  238.   
  239.     m_hThread = CreateThread(0, 0x1000, RxThread, (LPVOID) &g_th, 0, &ThreadId);
  240.     sprintf(tmp, "CreateThread %d", m_hThread);
  241.     DEBUG(DEBUG_ADV, tmp);
  242.     
  243.   }
  244.   return xlStatus;
  245. }
  246. ////////////////////////////////////////////////////////////////////////////
  247. //! linInitMaster
  248. //! initialize the LIN master, set the master DLC's, opens the 
  249. //! message filter and activate the LIN channel (-> bus on).
  250. //!
  251. //////////////////////////////////////////////////////////////////////////// 
  252. XLstatus CLINFunctions::linInitMaster()
  253. {
  254.   XLstatus        xlStatus = XL_ERROR;
  255.   char            tmp[100];
  256.  
  257.   // ---------------------------------------
  258.   // Setup the channel as a MASTER
  259.   // ---------------------------------------
  260.   XLlinStatPar     xlStatPar;
  261.   xlStatPar.LINMode    = XL_LIN_MASTER; 
  262.   xlStatPar.baudrate   = 9600;               // set the baudrate to 9k6
  263.   xlStatPar.LINVersion = XL_LIN_VERSION_1_3;    // use LIN 1.3
  264.   xlStatus = xlLinSetChannelParams(m_xlPortHandle, m_xlChannelMask[MASTER], xlStatPar);
  265.   sprintf(tmp, "Init Master PH: '%d', CM: '0x%I64x', status: %d", m_xlPortHandle, m_xlChannelMask[MASTER], xlStatus );
  266.   DEBUG(DEBUG_ADV, tmp);
  267.   // ---------------------------------------
  268.   // Setup the Master DLC's
  269.   // ---------------------------------------
  270.   unsigned char DLC[64];
  271.   // set the DLC for all ID's to 8
  272.   for (int i=0;i<64;i++) DLC[i] = 8;
  273.   xlStatus = xlLinSetDLC(m_xlPortHandle, m_xlChannelMask[MASTER], DLC);
  274.   // ---------------------------------------
  275.   // Activate the Master Channel
  276.   // ---------------------------------------
  277.   xlStatus = xlActivateChannel(m_xlPortHandle, m_xlChannelMask[MASTER], XL_BUS_TYPE_LIN, XL_ACTIVATE_RESET_CLOCK);
  278.   sprintf(tmp, "Activate Channel, CM: '0x%I64x', status: %d", m_xlChannelMask[MASTER], xlStatus);
  279.   DEBUG(DEBUG_ADV, tmp);
  280.   if (xlStatus != XL_SUCCESS) return xlStatus;
  281.   
  282.   xlStatus = xlFlushReceiveQueue(m_xlPortHandle);
  283.   sprintf(tmp, "FlushReceiveQueue stat: %d", xlStatus);
  284.   DEBUG(DEBUG_ADV, tmp);
  285.   return xlStatus;
  286. }
  287. ////////////////////////////////////////////////////////////////////////////
  288. //! linInitSlave
  289. //! initialize the LIN slave, define the slave (id, dlc, data), opens the 
  290. //! message filter and activate the LIN channel (-> bus on).
  291. //!
  292. //////////////////////////////////////////////////////////////////////////// 
  293. XLstatus CLINFunctions::linInitSlave(int linID)
  294. {
  295.   XLstatus        xlStatus = XL_ERROR;
  296.   char            tmp[100];
  297.  
  298.   // ---------------------------------------
  299.   // Setup the channel as a SLAVE
  300.   // ---------------------------------------
  301.   XLlinStatPar     xlStatPar;
  302.   xlStatPar.LINMode    = XL_LIN_SLAVE;
  303.   xlStatPar.baudrate   = 9600;                 // set the baudrate to 9k6
  304.   xlStatPar.LINVersion = XL_LIN_VERSION_1_3;   // use LIN 1.3
  305.   xlStatus = xlLinSetChannelParams(m_xlPortHandle, m_xlChannelMask[SLAVE], xlStatPar);
  306.   sprintf(tmp, "Init Slave PH: '%d', CM: '0x%I64x', status: %d", m_xlPortHandle, m_xlChannelMask[SLAVE], xlStatus );
  307.   DEBUG(DEBUG_ADV, tmp);
  308.   // ---------------------------------------
  309.   // Setup the SLAVE 
  310.   // ---------------------------------------
  311.   unsigned char            data[8];
  312.   unsigned char            id  = linID;
  313.   unsigned char            dlc = 8;
  314.   data[0] = 0x00;
  315.   data[1] = 0x00;
  316.   data[2] = 0x00;
  317.   data[3] = 0x00;
  318.   data[4] = 0x00;
  319.   data[5] = 0x00;
  320.   data[6] = 0x00;
  321.   data[7] = 0x00;
  322.   xlStatus = xlLinSetSlave(m_xlPortHandle, m_xlChannelMask[SLAVE], id, data, dlc, XL_LIN_CALC_CHECKSUM);
  323.   sprintf(tmp, "Set Slave ID CM: '0x%I64x', status: %d", m_xlChannelMask[SLAVE], xlStatus);
  324.   DEBUG(DEBUG_ADV, tmp);
  325.   // ---------------------------------------
  326.   // Activate the Slave Channel
  327.   // ---------------------------------------
  328.   xlStatus = xlActivateChannel(m_xlPortHandle, m_xlChannelMask[SLAVE], XL_BUS_TYPE_LIN, XL_ACTIVATE_RESET_CLOCK);
  329.   sprintf(tmp, "Activate Channel CM: '0x%I64x', status: %d", m_xlChannelMask[SLAVE], xlStatus);
  330.   DEBUG(DEBUG_ADV, tmp);
  331.   if (xlStatus != XL_SUCCESS) return xlStatus;
  332.   
  333.   xlStatus = xlFlushReceiveQueue(m_xlPortHandle);
  334.   sprintf(tmp, "FlushReceiveQueue stat: %d", xlStatus);
  335.   DEBUG(DEBUG_ADV, tmp);
  336.   return xlStatus;
  337. }
  338. ////////////////////////////////////////////////////////////////////////////
  339. //! linSetSlave
  340. //! change the slave
  341. //!
  342. //////////////////////////////////////////////////////////////////////////// 
  343. XLstatus CLINFunctions::linSetSlave(byte databyte)
  344. {
  345.   XLstatus        xlStatus = XL_ERROR;
  346.   char            tmp[100];
  347.   unsigned char            data[8];
  348.   unsigned char            id  = 0x04;
  349.   unsigned char            dlc = 8;
  350.   data[0] = databyte;
  351.   data[1] = 0x00;
  352.   data[2] = 0x00;
  353.   data[3] = 0x00;
  354.   data[4] = 0x00;
  355.   data[5] = 0x00;
  356.   data[6] = 0x00;
  357.   data[7] = 0x00;
  358.   xlStatus = xlLinSetSlave(m_xlPortHandle, m_xlChannelMask[SLAVE], id, data, dlc, XL_LIN_CALC_CHECKSUM);
  359.   sprintf(tmp, "Set Slave ID CM: '0x%I64x', status: %d", m_xlChannelMask[SLAVE], xlStatus);
  360.   DEBUG(DEBUG_ADV, tmp);
  361.   return xlStatus;
  362. }
  363. ///////////////////////////////////////////////////////////////////////////
  364. //! RxThread
  365. //! thread to readout the message queue and parse the incoming messages
  366. //!
  367. ////////////////////////////////////////////////////////////////////////////
  368. DWORD WINAPI RxThread(LPVOID par) 
  369. {
  370.   XLstatus        xlStatus;
  371.   
  372.   //char            tmp[100];
  373.   unsigned int    msgsrx = RECEIVE_EVENT_SIZE;
  374.   XLevent         xlEvent; 
  375.   char            tmp[100];
  376.   CString         str;
  377.   
  378.   g_bThreadRun = TRUE;
  379.   TStruct *g_th;
  380.   g_th = (TStruct*) par;  
  381.   sprintf(tmp, "thread: SetNotification '%d'", g_th->hMsgEvent);
  382.   DEBUG(DEBUG_ADV, tmp);
  383.   while (g_bThreadRun) { 
  384.    
  385.     WaitForSingleObject(g_th->hMsgEvent,10);
  386.     xlStatus = XL_SUCCESS;
  387.     
  388.    
  389.     while (!xlStatus) {
  390.       
  391.       
  392.       msgsrx = RECEIVE_EVENT_SIZE;
  393.       xlStatus = xlReceive(g_th->xlPortHandle, &msgsrx, &xlEvent);
  394.       
  395.       if ( xlStatus!=XL_ERR_QUEUE_IS_EMPTY ) {
  396.           
  397.         //sprintf(tmp, "thread: ReceiveEx tag: '%d'", vEvent2.tag);
  398.         //DEBUG(DEBUG_ADV, tmp);
  399.         switch (xlEvent.tag) {
  400.         // CAN events
  401.         case XL_SYNC_PULSE:
  402.             sprintf(tmp, "SYNC_PULSE: on Ch: '%d'", xlEvent.chanIndex);
  403.             DEBUG(DEBUG_ADV, tmp); 
  404.             g_th->pListRX->InsertString(-1,tmp);
  405.             break;
  406.         case XL_TRANSCEIVER:
  407.             sprintf(tmp, "TRANSCEIVER: on Ch: '%d'", xlEvent.chanIndex);
  408.             DEBUG(DEBUG_ADV, tmp); 
  409.             g_th->pListRX->InsertString(-1,tmp);
  410.             break;
  411.         // LIN events
  412.         
  413.           case XL_LIN_NOANS:
  414.             sprintf(tmp, "LIN NOANS ID: '0x%x' on Ch: '%d', time: %I64u", xlEvent.tagData.linMsgApi.linNoAns.id, xlEvent.chanIndex, xlEvent.timeStamp);
  415.             DEBUG(DEBUG_ADV, tmp); 
  416.             g_th->pListRX->InsertString(-1,tmp);
  417.             break;
  418.           case XL_LIN_MSG: {
  419.             CString         str1, sData;
  420.             str = "RX: ";
  421.             if (xlEvent.tagData.linMsgApi.linMsg.flags & XL_LIN_MSGFLAG_TX) str = "TX: ";
  422.             str1="";
  423.             for (int i=0; i<xlEvent.tagData.linMsgApi.linMsg.dlc;i++) {
  424.               str1.Format(_T("%02x"),xlEvent.tagData.linMsgApi.linMsg.data[i]);
  425.               sData = sData + str1;
  426.             }
  427.             
  428.             sprintf(tmp, "ID: 0x%02x, dlc: '%d', Data: 0x%s, time: %I64u, Ch: '%d'", xlEvent.tagData.linMsgApi.linMsg.id, xlEvent.tagData.linMsgApi.linMsg.dlc, sData, xlEvent.timeStamp, xlEvent.chanIndex);
  429.             DEBUG(DEBUG_ADV, tmp); 
  430.             g_th->pListRX->InsertString(-1, str + tmp);
  431.             break;
  432.           }
  433.           case XL_LIN_SLEEP:
  434.             sprintf(tmp, "LIN SLEEP flag: 0x%x, time: %I64u, Ch: '%d'", xlEvent.tagData.linMsgApi.linSleep.flag, xlEvent.timeStamp, xlEvent.chanIndex);
  435.             DEBUG(DEBUG_ADV, tmp); 
  436.             g_th->pListRX->InsertString(-1,tmp);
  437.             break;
  438.           case XL_LIN_ERRMSG:
  439.             sprintf(tmp, "LIN ERROR, Ch: '%d'", xlEvent.chanIndex);
  440.             DEBUG(DEBUG_ADV, tmp); 
  441.             g_th->pListRX->InsertString(-1,tmp);
  442.             break;
  443.           case XL_LIN_SYNCERR:
  444.             sprintf(tmp, "LIN SYNCERR on Ch: '%d'", xlEvent.chanIndex);
  445.             DEBUG(DEBUG_ADV, tmp); 
  446.             g_th->pListRX->InsertString(-1,tmp);
  447.             break;
  448.           case XL_LIN_WAKEUP:
  449.             sprintf(tmp, "LIN WAKEUP flags: 0x%x on Ch: '%d'", xlEvent.tagData.linMsgApi.linWakeUp.flag, xlEvent.chanIndex);
  450.             DEBUG(DEBUG_ADV, tmp); 
  451.             g_th->pListRX->InsertString(-1,tmp);
  452.             break;
  453.          }
  454.         ResetEvent(g_th->hMsgEvent);
  455.         //int nCount = pmyListBox->GetCount();
  456.         //if (nCount > 0)
  457.         g_th->pListRX->SetCurSel(g_th->pListRX->GetCount()-1);
  458.         g_th->pStatusBox->SetCurSel(g_th->pStatusBox->GetCount()-1);
  459.       }  
  460.     }
  461.           
  462.   }
  463.   return NO_ERROR; 
  464. }