Instrument.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /* =STS=> Instrument.h[1729].aa09 open SMID:10 */
  2. //////////////////////////////////////////////////////////////////////
  3. //
  4. // (c) Copyright 2003 Cyberkinetics, Inc.
  5. //
  6. // $Workfile: Instrument.h $
  7. // $Archive: /Cerebus/WindowsApps/Central/Instrument.h $
  8. // $Revision: 4 $
  9. // $Date: 1/05/04 4:36p $
  10. // $Author: Kkorver $
  11. //
  12. // $NoKeywords: $
  13. //
  14. //////////////////////////////////////////////////////////////////////
  15. #ifndef INSTRUMENT_H_INCLUDED
  16. #define INSTRUMENT_H_INCLUDED
  17. #if _MSC_VER > 1000
  18. #pragma once
  19. #endif // _MSC_VER > 1000
  20. #include "cbhwlib.h"
  21. #include "UDPsocket.h"
  22. #include "cki_common.h"
  23. #define NSP_IN_ADDRESS cbNET_UDP_ADDR_INST // NSP default address
  24. #define NSP_OUT_ADDRESS cbNET_UDP_ADDR_CNT // NSP subnet default address
  25. #define NSP_IN_PORT cbNET_UDP_PORT_BCAST // Neuroflow Data Port
  26. #define NSP_OUT_PORT cbNET_UDP_PORT_CNT // Neuroflow Control Port
  27. #define NSP_REC_BUF_SIZE (4096 * 2048) // Receiving system buffer size (multiple of 4096)
  28. class Instrument
  29. {
  30. public:
  31. Instrument();
  32. virtual ~Instrument();
  33. // Open the NSP instrument
  34. cbRESULT OpenNSP(STARTUP_OPTIONS nStartupOptionsFlags, uint16_t nNSPnum);
  35. cbRESULT Open(STARTUP_OPTIONS nStartupOptionsFlags, bool bBroadcast = false, bool bDontRoute = true,
  36. bool bNonBlocking = true, int nRecBufSize = NSP_REC_BUF_SIZE);
  37. void SetNetwork(int nInPort, int nOutPort, LPCSTR szInIP, LPCSTR szOutIP);
  38. void Close();
  39. void Standby();
  40. void Shutdown();
  41. void TestForReply(void * pPacket);
  42. enum { TICK_COUNT = 15 }; // Default number of ticks to wait for a response ( 10ms per tick)
  43. enum { RESEND_COUNT = 10 }; // Default number of times to "resend" a packet before erroring out.
  44. void Reset(int nMaxTickCount = TICK_COUNT, int nMaxRetryCount = RESEND_COUNT);
  45. // Called every 10 ms...use for "resending"
  46. // Outputs:
  47. // TRUE if any instrument error has happened; FALSE otherwise
  48. bool Tick(void);
  49. enum ModeType
  50. {
  51. MT_OK_TO_SEND, // It is OK to send out a packet
  52. MT_WAITING_FOR_REPLY, // We are waiting for the "response"
  53. };
  54. ModeType GetSendMode(); // What is our current send mode?
  55. int Recv(void * packet);
  56. int Send(void *ppkt); // Send this packet out
  57. // Is it OK to send a new packet out?
  58. bool OkToSend();
  59. // Purpose: receive a buffer from the "loopback" area. In other words, get it from our
  60. // local buffer. It wasn't really sent
  61. // Inputs:
  62. // pBuffer - Where to stuff the packet
  63. // Outputs:
  64. // the number of bytes read, or 0 if no data was found
  65. int LoopbackRecv(void * pBuffer, uint32_t nInstance = 0)
  66. {
  67. uint32_t nIdx = cb_library_index[nInstance];
  68. // The logic here is quite complicated. Data is filled in from other processes
  69. // in a 2 pass mode. First they fill all except they skip the first 4 bytes.
  70. // The final step in the process is to convert the 1st dword from "0" to some other number.
  71. // This step is done in a thread-safe manner
  72. // Consequently, all packets can not have "0" as the first DWORD. At the time of writing,
  73. // We were looking at the "time" value of a packet.
  74. if (cb_xmt_local_buffer_ptr[nIdx]->buffer[cb_xmt_local_buffer_ptr[nIdx]->tailindex] != 0)
  75. {
  76. cbPKT_GENERIC * pPacket = (cbPKT_GENERIC*)&(cb_xmt_local_buffer_ptr[nIdx]->buffer[cb_xmt_local_buffer_ptr[nIdx]->tailindex]);
  77. return LoopbackRecvLow(pBuffer, pPacket, nInstance);
  78. }
  79. return 0;
  80. }
  81. protected:
  82. UDPSocket m_icUDP; // Socket to deal with the sending of the UDP packets
  83. // Purpose: receive a buffer from the "loopback" area. In other words, get it from our
  84. // local buffer. It wasn't really sent. We assume that there is enough memory for
  85. // all of the memory copies that take place
  86. // Inputs:
  87. // pBuffer - Where to stuff the packet
  88. // pPacketData - the packet put put in this location
  89. // Outputs:
  90. // the number of bytes read, or 0 if no data was found
  91. int LoopbackRecvLow(void * pBuffer, void * pPacketData, uint32_t nInstance = 0);
  92. class CachedPacket
  93. {
  94. public:
  95. CachedPacket();
  96. ModeType GetMode() { return m_enSendMode; }
  97. void Reset(int nMaxTickCount = TICK_COUNT, int nMaxRetryCount = RESEND_COUNT); // Stop trying to send packets and restart
  98. bool AddPacket(void * pPacket, int cbBytes); // Save this packet, of this size
  99. void CheckForReply(void * pPacket); // A packet came in, compare to see if necessary
  100. bool OkToSend() { return m_enSendMode == MT_OK_TO_SEND; }
  101. // Called every 10 ms...use for "resending"
  102. // Outputs:
  103. // TRUE if any instrument error has happened; FALSE otherwise
  104. bool Tick(const UDPSocket & rcUDP);
  105. protected:
  106. ModeType m_enSendMode; // What is our current send mode?
  107. int m_nTickCount; // How many ticks have passed since we sent?
  108. int m_nRetryCount; // How many times have we re-sent this packet?
  109. int m_nMaxTickCount; // How many ticks to wait for a response ( 10ms per tick)
  110. int m_nMaxRetryCount; // How many times to "resend" a packet before erroring out.
  111. // This array MUST be larger than the largest data packet
  112. char m_abyPacket[2048]; // This is the packet that was sent out.
  113. int m_cbPacketBytes; // The size of the most recent packet addition
  114. };
  115. enum { NUM_OF_PACKETS_CACHED = 6 };
  116. CachedPacket m_aicCache[NUM_OF_PACKETS_CACHED];
  117. private:
  118. int m_nInPort;
  119. int m_nOutPort;
  120. LPCSTR m_szInIP;
  121. LPCSTR m_szOutIP;
  122. };
  123. extern Instrument g_icInstrument; // The one and only instrument
  124. #endif // include guard