/******************************************************************************
** File Name:      UartComm.h                                            *
** Author:         Apple Gao                                                 *
** DATE:           07/22/2004                                                *
** Copyright:      Spreatrum, Incoporated. All Rights Reserved.              *
** Description:    This files contains dll interface.                        *
******************************************************************************

  ******************************************************************************
  **                        Edit History                                       *
  ** ------------------------------------------------------------------------- *
  ** DATE				NAME				DESCRIPTION                       *
  ** 07/21/2004			Apple Gao			Create.							  * 
******************************************************************************/

#ifndef _UARTCOMM_H
#define	_UARTCOMM_H


/**---------------------------------------------------------------------------*
**                         Dependencies                                      *
**---------------------------------------------------------------------------*/
#include "Channelitf.h"

#ifndef UARTCOMM_API
#ifdef  UARTCOMM_EXPORTS
#define UARTCOMM_API __declspec(dllexport)
#else
#define UARTCOMM_API __declspec(dllimport)
#endif  
#endif  

class UARTCOMM_API CUartComm 
        : public ICommunicationChannel
{
public:
    CUartComm();
    
    virtual ~CUartComm();
            
//ICommunicationChannel
public:
    
    STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj);
    STDMETHOD_(ULONG,AddRef) (THIS);
    STDMETHOD_(ULONG,Release) (THIS);
    
    STDMETHOD( SetReceiver )( THIS_ DWORD  dwMsgId, BOOL bRcvThread,
        const LPVOID pReceiver );
    
    STDMETHOD( GetReceiver )( THIS_ DWORD  &dwMsgId, BOOL &bRcvThread,
        LPVOID &pReceiver );    
    
    STDMETHOD( Open )( THIS_ LPBYTE pOpenArgument );
    
    STDMETHOD( Close )( THIS ) ;
    
    STDMETHOD( Clear )( THIS );
    
    STDMETHOD( Read )( THIS_ LPVOID lpData, ULONG ulDataSize ) ;
    
    STDMETHOD( Write )( THIS_ LPVOID lpData,ULONG ulDataSize ) ;
    
    STDMETHOD( FreeMem )(THIS_ LPVOID pMemBlock );
    
    STDMETHOD( GetChannelHandle )( THIS );

private:
    BOOL _SetReceiver(  DWORD  dwMsgId, BOOL bRcvThread,
        const LPVOID pReceiver );
    
    void _GetReceiver( DWORD  &dwMsgId, BOOL &bRcvThread, LPVOID &pReceiver ); 
    
    BOOL _Open( LPBYTE pOpenArgument );
    
    void _Close(  ) ;
    
    BOOL _Clear( );
    
    DWORD _Read(  LPVOID lpData, ULONG ulDataSize ) ;
    
    DWORD _Write( LPVOID lpData,ULONG ulDataSize ) ;
    
    void _FreeMem(  LPVOID pMemBlock );

    HANDLE _GetChannelHandle();
    
private:
    
    // -----------------------------------------------------------------------------
    // Name:
    //      GetThreadProc
    //
    // Function:
    //      Retrieve the main process function of the monitor thread.
    // 
    // Discription:
    //      GetThreadProc() is a static member function, so it gets the real instance
    //      'pThis' via the parameter 'lpParam'. Through 'pThis', it can call any
    //      member function of CSciUart.
    // -----------------------------------------------------------------------------
    static DWORD WINAPI GetThreadProc(
        LPVOID lpParam
        );
    
    // -----------------------------------------------------------------------------
    // Name:
    //      UartWatchProc
    //
    // Function:
    //      Main function of the monitor thread
    // 
    // Discription:
    //      This function monitors the UART RX buffer all the time. When the data
    //      arrives, it notifies the registered application to receive the data.
    // -----------------------------------------------------------------------------
    DWORD WINAPI UartWatchProc();
    
    // -----------------------------------------------------------------------------
    // Name:
    //      SendDataToUplevel
    //
    // Function:
    //      Forward the data to the registered up-level application
    // 
    // Discription:
    //      The registered up-level receiver is specified via SetReceiver()
    // -----------------------------------------------------------------------------
    void SendDataToUplevel(
        const void * pData, // Data buffer
        DWORD        dwSize // Data size
        );
    
private:    
    // Handle of the UART
    volatile HANDLE  m_hUart;
    
    // Has connected with the UART?
    volatile BOOL    m_bConnected;
    
    // Handle of the UART watch thread
    HANDLE  m_hUartThread;
    
    // Overlapped structures for overlapped I/O
    OVERLAPPED  m_osRead;
    OVERLAPPED  m_osWrite;
    
    // Message ID for the up-level application to receive the UART data
    DWORD   m_dwMsgId;
    // Indicates the up-level receiver is a thread or a window
    BOOL    m_bRcvThread;
    // ID of the up-level receiving thread
    DWORD   m_dwRcvThreadID;
    // Handle of the up-level receiving window
    HWND    m_hRcvWindow;   
    
    ULONG   m_ulRef;
};
#endif // _UARTCOMM_H
