/*
			 Siemens AG
		 Mobile Radio Terminals
		  Munich, Germany

.AUTHOR         U.Mennchen, ICM MD MP MCH 95

.VERSION        2.3

.DATE           13.05.04

.SHORT_DESCR    Dialog Window for BT Control

.SW_COMPONENT   PC-MMI-Testumgebung

.SW_TYPE        Support-File

.STATUS         TEST

.CHANGE_CONTROL
Version |  Date  | Changed by | Reason for Change
  1.0    06.10.00  U.Mennchen   file created<NL>
  1.1    20.12.00  K. Drexler   btobex_.h instead of bt_obex_.h included<nl>
  1.2    21.12.00  U.Mennchen   all bttraces should be switched on for PCMMI<nl>
  1.3    20.02.01  K. Drexler   tmpstring in BTW_TerminalOut has now a size of 512+1 
                                instead of 256<nl>
  1.4    20.03.01  K. Drexler   BTR_bTopDataIn() has to be called with a new parameter
                                'Instance' for Multiserverchannel<nl>
  1.5    18.06.01  U. Mennchen  tracing changed
  1.6    30.07.01  U. Mennchen  Size of Output windows corrected
  1.7    29.08.01  U. Mennchen  Terminal Window Output repaired
  1.8    20.09.01  K. Drexler   old interface to obex (used for first tests )removed
  1.9    13.02.02  U. Mennchen  Changes for Multipoint Connections in RFCOMM Added
  1.91   22.05.93  B. Baier     BT deactivated	
  2.0    02.12.03  U. Mennchen  BT activation depending on Header File btpcmmi_.h
  2.1    15.01.04  U. Mennchen  added support to store the Bluetooth Comport in Registry
  2.2    13.05.04  J. Brandst.  add code for SDP API tests (enable define BT_SDP_CL_EMU)		                          
  2.3    13.05.04  E.Soenksen   Merged versions 2.1 and 2.2
  2.4    20.08.04  W. Thaler    canged "DWORD len" to "unsigned int" len of BTW_TraceLine()
  2.5    25.10.04  M.Waltinger (Ulm)
                   changed #include order
*/

extern "C"
{
#include <global.h>
#include <mopiext.h>
#include "gbs.h"
#include  "procid.h"
#include "bt_conf_.h"                  // BT configurations
#include "bt_defs_.h"                  // general BT defines

#include "btmbuf_.h"
#include "btprtd_.h"
#include "btosadp_.h"
#include "bt_msg_.h"
#include "bt_tool_.h"
#include "bthci_.h"
#include "btaapi_.h"
#include "bt_defs_.h"
#include "btlcm_.h"
#include "btrdsfu_.h"
#include "btrfcom_.h"

}
// dirty fix for PC Simu due to error in a Windows header file; should be removed soon.
#if MOBSIM == 1
#undef Calendar
#endif

#include <stdio.h>
#include <stdarg.h>
#include <string.h>

#include "winmain.h"
#include "winrc.h"
#include <richedit.h>
#include "btpcmmi_.h"

#if BT_AVAILABLE_PCMMI > 0

//#define BT_SDP_CL_EMU 1

#ifdef __WIN32__
extern HANDLE /*hStdIn, */hStdOut; /* standard input, output handles */
#endif

//defines

//externals
extern "C" HWND DispGetWinHandle(void);
extern "C" void BTPC_SetUart (unsigned int uiUart);
extern "C" void BlueTooth_Init(void);
extern "C" unsigned char BTRP_ucGetRFCOMM_Handle ( unsigned char ucServerChannel );
extern "C" void BTW_TraceLine(unsigned char *Line, unsigned int len);
#include "sim_regh.h"


//Prototypes
BOOL btHexToBin(char *pszSource,char *pszDest);
void TraceOpen (HWND hWnd);
void TraceClose (void);
void TerminalOpen (HWND hWnd);
void TerminalClose (void);
static void RemoveSpaces(char *pszBuffer);
static BOOL RegistryRead ( unsigned int *Comport );
static void RegistryWrite(unsigned int Comport);
void BT_vCopyReadibleChars ( unsigned char *ucOutPut, unsigned char *pucHex, unsigned int uiLen);
void BT_vConvertHexToStringEx( unsigned char *ucOutPut, unsigned char *pucHex, unsigned int uiLen);


//Globals
static HWND  hwndTrace = NULL;
static HWND  hwndTerm = NULL;
//Statics
static HANDLE hTraceFile = NULL;

#ifdef  BT_SDP_CL_EMU

//--------------------------------
/* values for BTA_vVerifyServiceReq call */
//--------------------------------
static UINT32           VerifyServiceReq_ulTransId;
static UINT8            VerifyServiceReq_pucBD_ADDR[6];
static SDP_UUID_ENTRY   VerifyServiceReq_pstServiceSearchPatternList[12];
static UINT8            VerifyServiceReq_ucServiceSearchPatternListSize;
static UINT16           VerifyServiceReq_puiAttributeIdList[10];
static UINT8            VerifyServiceReq_ucAttributeIdListSize;
static UINT8            VerifyServiceReq_ucSearchRule;

//--------------------------------
/* values for BTA_vBtBrowseServiceReq call */
//--------------------------------
static UINT32           BrowseServiceReq_ulTransId;
static UINT8            BrowseServiceReq_pucBD_ADDR[6];
static SDP_UUID_ENTRY   BrowseServiceReq_pstServiceSearchPatternList[12];
static UINT8            BrowseServiceReq_ucServiceSearchPatternListSize;
static UINT16           BrowseServiceReq_uiMaxRecordCount;

//--------------------------------
/* values for BTA_vVerifyServiceRecReq call */
//--------------------------------
static UINT32           VerifyServiceRecReq_ulTransId;
static UINT8            VerifyServiceRecReq_pucBD_ADDR[6];
static UINT32           VerifyServiceRecReq_ulServiceRecordHandle;
static UINT16           VerifyServiceRecReq_puiAttributeIdList[10];
static UINT8            VerifyServiceRecReq_ucAttributeIdListSize;

//--------------------------------
/* values for BTA_vBtSdpAddServiceRecordReq call */
//--------------------------------
static UINT8  ucSrMem[200];


#endif

#ifdef  BT_SDP_CL_EMU

/*--------**************-----------*/
/* SDP_CL AUX  functions           */
/*--------**************-----------*/
/* ----------------------------------------------------------------------------*/
/* print SR  */
/* ----------------------------------------------------------------------------*/
void BtSdpCl_print_Sr(SDP_SERVICE_REC   *pstServiceRecord)
{
    UINT8 ucIndex;
    UINT8 BtSdpClEmuTraceMsg[100];
    UINT16 uiNumDataElems;
    UINT16 uiStrLen;
    UINT16 uiRc;


    sprintf ((char *)BtSdpClEmuTraceMsg,"--------  Service Record  data --------------------\n");
    BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));
	sprintf ((char *)BtSdpClEmuTraceMsg," Ptr: %p, Handle: 0x%08x, Flags: 0x%02x  \n",
	            pstServiceRecord
	            ,pstServiceRecord->stRecordHeader.ulServiceRecordHandle
	            ,pstServiceRecord->stRecordHeader.ucServRecFlags
	            );
    BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));
	sprintf ((char *)BtSdpClEmuTraceMsg," No of Buffers: %d\n",pstServiceRecord->stBufDescr.uiNumOfBuffer);
    BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));
	for (ucIndex=0; ucIndex < pstServiceRecord->stBufDescr.uiNumOfBuffer ; ucIndex++)
	{
  	    sprintf ((char *)BtSdpClEmuTraceMsg,"     [%02d] -> %p, Len: %d\n",ucIndex,
  	                                           pstServiceRecord->stBufDescr.astBufTab[ucIndex].pucBuf,
  	                                           pstServiceRecord->stBufDescr.astBufTab[ucIndex].uiBufferLen);
    BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));
	}

	sprintf ((char *)BtSdpClEmuTraceMsg," No of Attrs:   %d\n",pstServiceRecord->stRecordHeader.ucNumOfAttribute);
    BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));
	for (ucIndex=0; ucIndex < pstServiceRecord->stRecordHeader.ucNumOfAttribute ; ucIndex++)
	{
  	    UINT8  *pucSdpPdu;
        UINT16 uiPduIndex;
        UINT8  ucBufferIndex;  

        sprintf ((char *)BtSdpClEmuTraceMsg,"     [%02d] Id 0x%04x,  Len: %d, Buffer: %d, Offset: %d ",ucIndex
  	                                           ,pstServiceRecord->stRecordHeader.astAttrDescr[ucIndex].uiAttributeId
  	                                           ,pstServiceRecord->stRecordHeader.astAttrDescr[ucIndex].uiAttrLength
  	                                           ,pstServiceRecord->stRecordHeader.astAttrDescr[ucIndex].ucAttrBufId
  	                                           ,pstServiceRecord->stRecordHeader.astAttrDescr[ucIndex].uiAttrBufOffset
  	                                           ,pstServiceRecord->stRecordHeader.astAttrDescr[ucIndex].ucAttrFlags
  	                                           );
        BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));
        ucBufferIndex = pstServiceRecord->stRecordHeader.astAttrDescr[ucIndex].ucAttrBufId;
        pucSdpPdu     = pstServiceRecord->stBufDescr.astBufTab[ucBufferIndex].pucBuf +
                        pstServiceRecord->stRecordHeader.astAttrDescr[ucIndex].uiAttrBufOffset;

        sprintf ((char *)BtSdpClEmuTraceMsg,"        -|");
        for (uiPduIndex = 0; uiPduIndex < pstServiceRecord->stRecordHeader.astAttrDescr[ucIndex].uiAttrLength;  uiPduIndex ++)
        {
            UINT8 tmpStr[8];
            sprintf ((char *)tmpStr,"%02x ",pucSdpPdu[uiPduIndex]);
            strcat ((char *)BtSdpClEmuTraceMsg,(char *)tmpStr);
//            BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));
        }
        BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));

        uiRc = BT_uiSdpGetAttributeSize(pstServiceRecord, 
                       pstServiceRecord->stRecordHeader.astAttrDescr[ucIndex].uiAttributeId, 
                       &uiNumDataElems, &uiStrLen);

        sprintf ((char *)BtSdpClEmuTraceMsg,"<-- GetAttributeSize Id: 0x%04x,  Rc: 0x%04x, NumData: %d, StrLen: %d",
            pstServiceRecord->stRecordHeader.astAttrDescr[ucIndex].uiAttributeId,        
            uiRc, uiNumDataElems, uiStrLen);
        BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));

	}
}


/*--------**************-----------*/
/* SDP_CL 'ES' functions           */
/*--------**************-----------*/
void BTA_vBtVerifyServiceReq_ES (
    void
)
{
    BTA_vBtVerifyServiceReq      (
                                  VerifyServiceReq_ulTransId,
                                  VerifyServiceReq_pucBD_ADDR,
                                  VerifyServiceReq_pstServiceSearchPatternList,
                                  VerifyServiceReq_ucServiceSearchPatternListSize,
                                  VerifyServiceReq_puiAttributeIdList,
                                  VerifyServiceReq_ucAttributeIdListSize,
                                  VerifyServiceReq_ucSearchRule
                                  );
}

void BTA_vBtBrowseServiceReq_ES (
    void
)
{
    BTA_vBtBrowseServiceReq      (
                                  BrowseServiceReq_ulTransId,
                                  BrowseServiceReq_pucBD_ADDR,
                                  BrowseServiceReq_pstServiceSearchPatternList,
                                  BrowseServiceReq_ucServiceSearchPatternListSize,
                                  BrowseServiceReq_uiMaxRecordCount
                                  );
}

void BTA_vBtVerifyServiceRecReq_ES (
    void
)
{
    BTA_vBtVerifyServiceRecReq      (
                                  VerifyServiceRecReq_ulTransId,
                                  VerifyServiceRecReq_pucBD_ADDR,
                                  VerifyServiceRecReq_ulServiceRecordHandle,
// in order to get all            NULLP,
// attributes                     0,
                                  VerifyServiceRecReq_puiAttributeIdList,
                                  VerifyServiceRecReq_ucAttributeIdListSize,
                                  0x0000  // uuiLanguage
                                  );
}
void BTA_vBtVerifyServiceCancel_ES (
    void
)
{
    BTA_vBtVerifyServiceCancel      (
                                  VerifyServiceReq_ulTransId
                                  );
}

void BTA_vBtBrowseServiceCancel_ES (
    void
)
{
    BTA_vBtBrowseServiceCancel     (
                                  BrowseServiceReq_ulTransId
                                  );
}
void BTA_vBtSdpAddServiceRecordReq_ES (
    void
)
{
    BTA_vBtSdpAddServiceRecordReq      (
                                  0x00220000,
                                  NULL,
                                  (SDP_SERVICE_REC  *)ucSrMem
                                  );
}


/*--------**************-----------*/
/* SDP_CL callback functions       */
/*--------**************-----------*/
//--------------------------------
/* APP_vBtVerifyServiceCfm call */
//--------------------------------
void WinAPP_vBtVerifyServiceCfm (
    UINT32 ulTransId, 
    T_BtStackResult *pstResultCode, 
    UINT16 uiRecordCount, 
    SDP_SERVICE_REC **ppstServiceRecords
)
{
    UINT8 BtSdpClEmuTraceMsg[100];


    sprintf ((char *)BtSdpClEmuTraceMsg,"<-- BtVerifyServiceCfm TrId: 0x%08x, Rc: 0x%04x(layer: %d), NoOfRec: %d ",
        ulTransId, pstResultCode->uiErrorCode,pstResultCode->eLayerInfo, uiRecordCount);
    BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));
    if ((pstResultCode->uiErrorCode == BT_SUCCESS) && (uiRecordCount>0))
    {
        UINT8 ucRec;
        for (ucRec = 0; ucRec < uiRecordCount; ucRec ++ )
        {
            BtSdpCl_print_Sr(ppstServiceRecords[ucRec]);
        }
    }
}

//--------------------------------
/* APP_vBtBrowseServiceCfm call */
//--------------------------------
void WinAPP_vBtBrowseServiceCfm (
    UINT32 ulTransId, 
    T_BtStackResult *pstResultCode, 
    UINT16 uiRecordCount, 
    SDP_SERVICE_REC_ID *ppstServiceRecordIds
)
{
    UINT8 BtSdpClEmuTraceMsg[100];
    sprintf ((char *)BtSdpClEmuTraceMsg,"<-- BtBrowseServiceCfm TrId: 0x%08x, Rc: 0x%04x(layer: %d), NoOfRec: %d ",
        ulTransId, pstResultCode->uiErrorCode,pstResultCode->eLayerInfo, uiRecordCount);
    BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));
    if ((pstResultCode->uiErrorCode == BT_SUCCESS) && (uiRecordCount>0))
    {
        UINT8 ucRec;
        for (ucRec = 0; ucRec < uiRecordCount; ucRec ++ )
        {
            sprintf ((char *)BtSdpClEmuTraceMsg," RecHand: 0x%08x, ServId: 0x%04x (as Uuid16)",
                ppstServiceRecordIds[ucRec].ulServiceRecordHandle,
                ppstServiceRecordIds[ucRec].stMostSpecificServiceClassId.uUuid.uiUuid16);
            BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));
        }
    }
}
//--------------------------------
/* APP_vBtVerifyServiceRecCfm call */
//--------------------------------
void WinAPP_vBtVerifyServiceRecCfm (
    UINT32 ulTransId, 
    T_BtStackResult *pstResultCode, 
    SDP_SERVICE_REC *pstServiceRecord
)
{
    UINT8  BtSdpClEmuTraceMsg[100];
    UINT16 uiNumDataElems;
    UINT16 uiStrLen;
    UINT16 uiRc;

    sprintf ((char *)BtSdpClEmuTraceMsg,"<-- BtVerifyServiceRecCfm TrId: 0x%08x, Rc: 0x%04x(layer: %d)",
        ulTransId, pstResultCode->uiErrorCode,pstResultCode->eLayerInfo);
    BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));
    if ((pstResultCode->uiErrorCode == BT_SUCCESS))
    {
        BtSdpCl_print_Sr(pstServiceRecord );

    }
}
//--------------------------------
/* APP_vBtSdpAddServiceRecordCfm call */
//--------------------------------
void WinAPP_vBtSdpAddServiceRecordCfm (
    UINT32 ulTransId, 
    T_BtStackResult *pstResultCode, 
    UINT32 ulServiceRecordHandle 
)
{
    UINT8 BtSdpClEmuTraceMsg[100];
    sprintf ((char *)BtSdpClEmuTraceMsg,"<-- BtSdpAddServiceReocrdCfm TrId: 0x%08x, Rc: 0x%04x(layer: %d), Handle: 0x%08x ",
        ulTransId, pstResultCode->uiErrorCode,pstResultCode->eLayerInfo, ulServiceRecordHandle);
    BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));
}

#endif



////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// RC Message Dialog
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
HWND hBTDialog;
static BOOL BTAlreadyInited = FALSE;
////////////////////////////////////////////////////////////////////////////////

#pragma argsused
////////////////////////////////////////////////////////////////////////////////
BOOL CALLBACK BTDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
////////////////////////////////////////////////////////////////////////////////
{
	DWORD i;
	char psztmp[6];
	char pszPin[20];
	char pszBDADDR[50];
	char pszBDADDRbin[7];
	char pszLocSrvCh[3];
	char pszRemSrvCh[3];
	unsigned int Comport;
	int result;

	switch (message)
	{
	case WM_INITDIALOG:
		// Init the Combobox for the Comports
		for ( i=1; i<9; i++)
		{
			sprintf(psztmp, "COM%d:", i);
			SendMessage(GetDlgItem(hwndDlg, IDC_BT_COMPORT), CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) psztmp);

		}
    Comport = ReadSimulatorRegistry( "BT_COMPort", &result)-1;
		if ( result != 0)
		{
			return (FALSE);
		}
		SendMessage(GetDlgItem(hwndDlg, IDC_BT_COMPORT), CB_SETCURSEL, Comport, 0);
		// preset the server channels
		SetDlgItemText(hwndDlg, IDC_BT_SRVCH, "1");
		SetDlgItemText(hwndDlg, IDC_BT_SRVCHPEER, "1");

		if ( BTAlreadyInited )
		{  // disable Init Button 
            EnableWindow(GetDlgItem(hwndDlg, IDC_BT_INIT), FALSE);
			// and enable all the other buttons
            EnableWindow(GetDlgItem(hwndDlg, IDC_BT_PRESENTREQ), TRUE);
            EnableWindow(GetDlgItem(hwndDlg, IDC_BT_SCANMODE), TRUE);
            EnableWindow(GetDlgItem(hwndDlg, IDC_BT_SENDPIN), TRUE);
            EnableWindow(GetDlgItem(hwndDlg, IDC_BT_DLCESTREQ), TRUE);
            EnableWindow(GetDlgItem(hwndDlg, IDC_BT_DLCRELREQ), TRUE);
			EnableWindow(GetDlgItem(hwndDlg, IDC_BT_INQUIRY), TRUE);
		}
		else
		{
            EnableWindow(GetDlgItem(hwndDlg, IDC_BT_INIT), TRUE);
			// disable all the other buttons
            EnableWindow(GetDlgItem(hwndDlg, IDC_BT_PRESENTREQ), FALSE);
            EnableWindow(GetDlgItem(hwndDlg, IDC_BT_SCANMODE), FALSE);
            EnableWindow(GetDlgItem(hwndDlg, IDC_BT_SENDPIN), FALSE);
            EnableWindow(GetDlgItem(hwndDlg, IDC_BT_DLCESTREQ), FALSE);
            EnableWindow(GetDlgItem(hwndDlg, IDC_BT_DLCRELREQ), FALSE);
			EnableWindow(GetDlgItem(hwndDlg, IDC_BT_INQUIRY), FALSE);
		}
		TraceOpen (hwndDlg);
		TerminalOpen (hwndDlg);
		return (TRUE);
		break;
	case WM_CLOSE:
		{
			DestroyWindow(hwndDlg);
			TraceClose ();
			TerminalClose();
			hBTDialog = 0;
			return TRUE;
		}
	case WM_COMMAND:
		{
			switch(LOWORD(wParam))
			{
			case IDC_BT_INIT:
				if ( (i=SendMessage(GetDlgItem(hwndDlg, IDC_BT_COMPORT), CB_GETCURSEL, 0, 0)) != CB_ERR )
				{
					BTPC_SetUart(i+1);

					//MOPI_ExecuteFunction(0, (T_MOPI_ExtFunction)BlueTooth_Init, 0);
					BTOS_vSwitchTracesOn(1); // for PCMMI all traces should be switched on
					BTAlreadyInited= TRUE;
					// disable the Init Button
					EnableWindow(GetDlgItem(hwndDlg, IDC_BT_INIT), FALSE);
					// and enable all the other buttons
					EnableWindow(GetDlgItem(hwndDlg, IDC_BT_PRESENTREQ), TRUE);
					EnableWindow(GetDlgItem(hwndDlg, IDC_BT_SCANMODE), TRUE);
					EnableWindow(GetDlgItem(hwndDlg, IDC_BT_SENDPIN), TRUE);
					EnableWindow(GetDlgItem(hwndDlg, IDC_BT_DLCESTREQ), TRUE);
					EnableWindow(GetDlgItem(hwndDlg, IDC_BT_DLCRELREQ), TRUE);
					EnableWindow(GetDlgItem(hwndDlg, IDC_BT_INQUIRY), TRUE);
					(void)WritePermanentSimulatorRegistry( "BT_COMPort", i+1);
				}
				SetFocus(DispGetWinHandle());
				break;
			case ID_BT_CLOSE:
				DestroyWindow(hwndDlg);
				TraceClose ();
				TerminalClose();
				hBTDialog = 0;
				return TRUE;
			case IDC_BT_PRESENTREQ:
					BTOS_vSwitchTracesOn(1); // for PCMMI all traces should be switched on
			    MOPI_ExecuteFunction(0, (T_MOPI_ExtFunction)BTA_bBtPresentReq_ES,0);
				SetFocus(DispGetWinHandle());
				break;
			case IDC_BT_SCANMODE:
#ifdef  BT_SDP_CL_EMU
                {
                UINT8 BtSdpClEmuTraceMsg[100];
                char BtSrHVal[20];

                GetDlgItemText(hwndDlg, IDC_BT_BDADDR, pszBDADDR, 49);
				RemoveSpaces(pszBDADDR);
				if ( strlen(pszBDADDR) == 0 )
				{
					MessageBox(hwndDlg, "Please Enter a Device Address first", "VerifyServiceRecReq", MB_OK);
				}
                else
                {
					if ( (strlen(pszBDADDR) != 12) || btHexToBin(pszBDADDR,pszBDADDRbin) == FALSE )
					{
						MessageBox(hwndDlg, "Wrong Device Address", "VerifyServiceRecReq", MB_OK);
                        break;
					}
                }
                /*   ---------------------      */
                /* call BTA_vBtVerifyServiceRecReq */
                /*   ---------------------      */

                VerifyServiceRecReq_ulTransId = BrowseServiceReq_ulTransId;
				memcpy (VerifyServiceRecReq_pucBD_ADDR, pszBDADDRbin, 6);

   			    GetDlgItemText(hwndDlg, IDC_BT_SRVCHPEER, BtSrHVal, 19);
                sscanf (BtSrHVal,"%x",&VerifyServiceRecReq_ulServiceRecordHandle);

                VerifyServiceRecReq_puiAttributeIdList[0]  = 0x0000; /* AttrID for SR handle */
                VerifyServiceRecReq_puiAttributeIdList[1]  = 0x0004; /* AttrID for Protocol descr list */
                VerifyServiceRecReq_ucAttributeIdListSize  = 2;

                sprintf ((char *)BtSdpClEmuTraceMsg,"--> BtVerifyServiceRecReq TrId: 0x%08x, BtAddr %s, RH: 0x%08x",
                    VerifyServiceRecReq_ulTransId,pszBDADDR,
                    VerifyServiceRecReq_ulServiceRecordHandle);
                BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));
			    MOPI_ExecuteFunction(0, (T_MOPI_ExtFunction)BTA_vBtVerifyServiceRecReq_ES,0);
                }
#else
				  MOPI_ExecuteFunction(0, (T_MOPI_ExtFunction)BTA_vBtScanModeReq_ES,0);
				  SetFocus(DispGetWinHandle());
#endif
				break;

			case IDC_BT_SENDPIN:
#ifdef  BT_SDP_CL_EMU
                {
                    UINT16 uiRc;
                    BT_TREE_ELEM      astTreeElems[10];
                    BT_SDP_TREE_ATTR  stAttrClassList;
                    BT_SDP_TREE_ATTR  stAttrPrtDescList;
                    UINT8 BtSdpClEmuTraceMsg[100];
                    char    BtUuidVal[20];
                    UINT16  uiUuid;

                    UINT8 ucSppUuid[16] =  {0x00,0x00,0x11,0x01,0x00,0x00,0x10,0x00,0x80,0x00,0x00,0x80,0x5F,0x9B,0x34,0xFB};

                    // get UUID16
     			    GetDlgItemText(hwndDlg, IDC_BT_SRVCH, BtUuidVal, 19);
                    sscanf (BtUuidVal,"%x",&uiUuid);
                    // Q&D set uuid
                    ucSppUuid [2] = uiUuid/256;
                    ucSppUuid [3] = uiUuid%256; 
   
                    // set attribute IDs
                    stAttrClassList.uiAttrId    = SDP_Att_ServiceClassIDList;
                    stAttrPrtDescList.uiAttrId  = SDP_Att_ProtocolDescrList;


                    uiRc = BT_uiSdpCreateLinearServiceRecord((SDP_SERVICE_REC *)ucSrMem,
                                                              NULL,
                                                              0,
                                                              200,
                                                              TRUE);
                    sprintf ((char *)BtSdpClEmuTraceMsg," CreateLinearServiceRecord rc: 0x%02x", uiRc);
                    BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));
                    
                    // generate ServiceClassIDlist Attr
                    astTreeElems[0].eType                = DE_DATSEQ;
                    astTreeElems[0].uCont.pstSubTreeRoot = &(astTreeElems[1]);
                    astTreeElems[0].pstNextElem          = NULL;

                    astTreeElems[1].eType                = DE_UUID128;
                    //astTreeElems[1].uCont.aucUuid128     = 
                        
                    memcpy (astTreeElems[1].uCont.aucUuid128,ucSppUuid,16);
                    astTreeElems[1].pstNextElem          = NULL;

                    stAttrClassList.pstTreeRoot = &(astTreeElems[0]);

                    uiRc = BT_uiSdpAddAttribute((SDP_SERVICE_REC *)ucSrMem,
                                                &stAttrClassList);
                    sprintf ((char *)BtSdpClEmuTraceMsg," SdpAddAttribute rc: 0x%02x", uiRc);
                    BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));
   			        MOPI_ExecuteFunction(0, (T_MOPI_ExtFunction)BTA_vBtSdpAddServiceRecordReq_ES,0);

                }
                break;
#else
				GetDlgItemText(hwndDlg, IDC_BT_BDADDR, pszBDADDR, 49);
				RemoveSpaces(pszBDADDR);
				if ( strlen(pszBDADDR) == 0 )
				{
					MessageBox(hwndDlg, "Please Enter a Device Address first", "Send Pin", MB_OK);
				}
				else
				{
					if ( (strlen(pszBDADDR) != 12) || btHexToBin(pszBDADDR,pszBDADDRbin) == FALSE )
					{
						MessageBox(hwndDlg, "Wrong Device Address", "Send Pin", MB_OK);
					}
					else
					{
						GetDlgItemText(hwndDlg, IDC_BD_PIN, pszPin, 20);
						if ( strlen(pszPin) == 0 )
						{
							MessageBox(hwndDlg, "Please Enter a Pin first", "Send Pin", MB_OK);
						}
						else
						{
							// call the function to send the pin
						   BT_PRIMITIVE  stBtPrimitive;

						   stBtPrimitive.ucEvent = ADP_HCI_PinCodeReply;
						   stBtPrimitive.ucLength = SIZEOF_ACT_PRIM(ADP_HCI_PIN_CODE_REPLY);

						   memcpy(stBtPrimitive.uMsg.stAdpHciPinCodeReply.aucBD_ADDR,
											 pszBDADDRbin, BD_ADDR_SIZE);

						   memcpy(stBtPrimitive.uMsg.stAdpHciPinCodeReply.aucPinCode,
											 pszPin,BT_MAX_PIN_CODE_SIZE);

						   stBtPrimitive.uMsg.stAdpHciPinCodeReply.ucPinCodeLength = 
									(UINT8)strlen((char*)stBtPrimitive.uMsg.stAdpHciPinCodeReply.aucPinCode);

						   BTH_vTopCtrlIn( &stBtPrimitive );
 
						}

					}
				}

				SetFocus(DispGetWinHandle());
				break;
#endif

			case IDC_BT_DLCESTREQ:
#ifdef  BT_SDP_CL_EMU
                {
                UINT8 BtSdpClEmuTraceMsg[100];
                char BtUuidVal[20];

                GetDlgItemText(hwndDlg, IDC_BT_BDADDR, pszBDADDR, 49);
				RemoveSpaces(pszBDADDR);
				if ( strlen(pszBDADDR) == 0 )
				{
					MessageBox(hwndDlg, "Please Enter a Device Address first", "VerifyServiceReq", MB_OK);
				}
                else
                {
					if ( (strlen(pszBDADDR) != 12) || btHexToBin(pszBDADDR,pszBDADDRbin) == FALSE )
					{
						MessageBox(hwndDlg, "Wrong Device Address", "VerifyServiceReq", MB_OK);
					}
                }
                /*   ---------------------      */
                /* call BTA_vBtVerifyServiceReq */
                /*   ---------------------      */

                VerifyServiceReq_ulTransId++;
				memcpy (VerifyServiceReq_pucBD_ADDR, pszBDADDRbin, 6);

                VerifyServiceReq_pstServiceSearchPatternList[0].ucUuidType      = SDP_UUID_16;
   			    GetDlgItemText(hwndDlg, IDC_BT_SRVCH, BtUuidVal, 19);
                sscanf (BtUuidVal,"%x",&VerifyServiceReq_pstServiceSearchPatternList[0].uUuid.uiUuid16);
//                VerifyServiceReq_pstServiceSearchPatternList[0].uUuid.uiUuid16  = 0x1101; /*  UUID for SPP */
                VerifyServiceReq_ucServiceSearchPatternListSize                 = 1;

                VerifyServiceReq_puiAttributeIdList[0]  = 0x0001; /* AttrID for service class ID list */
                VerifyServiceReq_puiAttributeIdList[1]  = 0x0004; /* AttrID for Protocol descr list */
                VerifyServiceReq_ucAttributeIdListSize  = 2;
                VerifyServiceReq_ucSearchRule           = SDP_DEFAULT_SEARCH_RULE; 

                sprintf ((char *)BtSdpClEmuTraceMsg,"--> BtVerifyServiceReq TrId: 0x%08x, BtAddr %s, Uuid: 0x%04x",
                    VerifyServiceReq_ulTransId,pszBDADDR,
                    VerifyServiceReq_pstServiceSearchPatternList[0].uUuid.uiUuid16);
                BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));
			    MOPI_ExecuteFunction(0, (T_MOPI_ExtFunction)BTA_vBtVerifyServiceReq_ES,0);
                }
#else
				GetDlgItemText(hwndDlg, IDC_BT_BDADDR, pszBDADDR, 49);
				RemoveSpaces(pszBDADDR);
				if ( strlen(pszBDADDR) == 0 )
				{
					MessageBox(hwndDlg, "Please Enter a Device Address first", "DLCEstablishReq", MB_OK);
				}
				else
				{
					if ( (strlen(pszBDADDR) != 12) || btHexToBin(pszBDADDR,pszBDADDRbin) == FALSE )
					{
						MessageBox(hwndDlg, "Wrong Device Address", "DLCEstablishReq", MB_OK);
					}
					else
					{

						GetDlgItemText(hwndDlg, IDC_BT_SRVCH, pszLocSrvCh, 3);
						GetDlgItemText(hwndDlg, IDC_BT_SRVCHPEER, pszRemSrvCh, 3);
						if ( pszLocSrvCh[0]<'1' || pszLocSrvCh[0]>'9')
						{
							MessageBox(hwndDlg, "Wrong Local Server Channel", "DLCEstablishReq", MB_OK);
						}
						else if ( pszRemSrvCh[0]<'1' || pszRemSrvCh[0]>'9')
						{
							MessageBox(hwndDlg, "Wrong Peer Server Channel", "DLCEstablishReq", MB_OK);
						}
						else
						{
							// send the Establish request
							BT_PRIMITIVE sPrimitive;

							sPrimitive.ucEvent= BT_DLC_EstablishReq;
							sPrimitive.uMsg.stDLCEstablishReq.ucLocalSrvCh= pszLocSrvCh[0]-'0';
							sPrimitive.uMsg.stDLCEstablishReq.ucRemoteSrvCh= pszRemSrvCh[0]-'0';
							memcpy (sPrimitive.uMsg.stDLCEstablishReq.aucBD_ADDR, pszBDADDRbin, 6);
							sPrimitive.uMsg.stDLCEstablishReq.uiFrameSize= 48;
							sPrimitive.uMsg.stDLCEstablishReq.ucPriority= 1;
							sPrimitive.ucLength= SIZEOF_ACT_PRIM(BT_DLC_ESTABLISH_REQ);	

							BTR_vTopCtrlIn(&sPrimitive);
						}					
					
					}
				}
				SetFocus(DispGetWinHandle());
#endif
				break;
			case IDC_BT_DLCRELREQ:
#ifdef  BT_SDP_CL_EMU
                {
                UINT8 BtSdpClEmuTraceMsg[100];
                char BtUuidVal[20];

                GetDlgItemText(hwndDlg, IDC_BT_BDADDR, pszBDADDR, 49);
				RemoveSpaces(pszBDADDR);
				if ( strlen(pszBDADDR) == 0 )
				{
					MessageBox(hwndDlg, "Please Enter a Device Address first", "BrowseServiceReq", MB_OK);
				}
                else
                {
					if ( (strlen(pszBDADDR) != 12) || btHexToBin(pszBDADDR,pszBDADDRbin) == FALSE )
					{
						MessageBox(hwndDlg, "Wrong Device Address", "BrowseServiceReq", MB_OK);
					}
                }
                /*   ---------------------      */
                /* call BTA_vBtBrowseServiceReq */
                /*   ---------------------      */

                BrowseServiceReq_ulTransId++;
				memcpy (BrowseServiceReq_pucBD_ADDR, pszBDADDRbin, 6);

                BrowseServiceReq_pstServiceSearchPatternList[0].ucUuidType      = SDP_UUID_16;
   			    GetDlgItemText(hwndDlg, IDC_BT_SRVCH, BtUuidVal, 19);
                sscanf (BtUuidVal,"%x",&BrowseServiceReq_pstServiceSearchPatternList[0].uUuid.uiUuid16);
//                BrowseServiceReq_pstServiceSearchPatternList[0].uUuid.uiUuid16  = 0x1101; /*  UUID for SPP */
                BrowseServiceReq_ucServiceSearchPatternListSize                 = 1;

                BrowseServiceReq_uiMaxRecordCount                               = 12; 

                sprintf ((char *)BtSdpClEmuTraceMsg,"--> BrowseServiceReq TrId: 0x%08x, BtAddr %s, Uuid: 0x%04x",
                    BrowseServiceReq_ulTransId,pszBDADDR,
                    BrowseServiceReq_pstServiceSearchPatternList[0].uUuid.uiUuid16);
                BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));
			    MOPI_ExecuteFunction(0, (T_MOPI_ExtFunction)BTA_vBtBrowseServiceReq_ES,0);
                }
#else
				GetDlgItemText(hwndDlg, IDC_BT_SRVCH, pszLocSrvCh, 3);
				if ( pszLocSrvCh[0]<'1' || pszLocSrvCh[0]>'9')
				{
					MessageBox(hwndDlg, "Wrong Server Channel", "DLCReleaseReq", MB_OK);
				}
				else
				{
					// send the Release request
					BT_PRIMITIVE sPrimitive;

					sPrimitive.ucEvent= BT_DLC_ReleaseReq;
					sPrimitive.uMsg.stDLCEstablishReq.ucLocalSrvCh= pszLocSrvCh[0]-'0';
					sPrimitive.ucLength= SIZEOF_ACT_PRIM(BT_DLC_RELEASE_REQ);	

					BTR_vTopCtrlIn(&sPrimitive);
				}
				SetFocus(DispGetWinHandle());
#endif
				break;
			case IDC_BT_INQUIRY:
				//_ES_BTA_vDeviceSearchReq(TRUE, UNCLASSIFIED_COS, UNCLASSIFIED_COD, UNCLASSIFIED_MCOD_PHN);
#ifdef  BT_SDP_CL_EMU
                {
                    T_BtAppFct *cbFctPtr;


                    UINT8 BtSdpClEmuTraceMsg[60]= "SDP_CL_EMU  init";
                    BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));

                    /* get pointer for cb functions */
                    cbFctPtr = Bt_vGetAppFctStruct();
                    cbFctPtr->APP_vBtVerifyServiceCfm       = WinAPP_vBtVerifyServiceCfm;
                    cbFctPtr->APP_vBtBrowseServiceCfm       = WinAPP_vBtBrowseServiceCfm;
                    cbFctPtr->APP_vBtVerifyServiceRecCfm    = WinAPP_vBtVerifyServiceRecCfm;
                    cbFctPtr->APP_vBtSdpAddServiceRecordCfm = WinAPP_vBtSdpAddServiceRecordCfm;

                    /* init trans ids */
                    VerifyServiceReq_ulTransId     = 0;
                    VerifyServiceRecReq_ulTransId  = 0x1000;
                    BrowseServiceReq_ulTransId     = 0x2000;

                }
#else
				SetFocus(DispGetWinHandle());
#endif
				break;
			case IDC_BT_DLCDATAREQ:
#ifdef  BT_SDP_CL_EMU
                {
                UINT8 BtSdpClEmuTraceMsg[100];
				unsigned char szData[128];

                /*   ---------------------      */
                /* call BTA_vBtxxServiceCancel  */
                /*   ---------------------      */

				GetDlgItemText(hwndDlg, IDC_BT_DLCDATA, (char*)szData, 127);
				if (szData[0] == 'b' )
				{
                    /* send BrowseServiceCancel */
                    sprintf ((char *)BtSdpClEmuTraceMsg,"--> BtBrowseServiceCancel TrId: 0x%08x",
                    BrowseServiceReq_ulTransId);
                    BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));
			        MOPI_ExecuteFunction(0, (T_MOPI_ExtFunction)BTA_vBtBrowseServiceCancel_ES,0);
				}
				else
				{
                    /* send BrowseServiceCancel */
                    sprintf ((char *)BtSdpClEmuTraceMsg,"--> BtVerifyServiceCancel TrId: 0x%08x",
                    VerifyServiceReq_ulTransId);
                    BTW_TraceLine(BtSdpClEmuTraceMsg, strlen ((const char *)BtSdpClEmuTraceMsg));
			        MOPI_ExecuteFunction(0, (T_MOPI_ExtFunction)BTA_vBtVerifyServiceCancel_ES,0);
				}
                }
#else
				GetDlgItemText(hwndDlg, IDC_BT_SRVCH, pszLocSrvCh, 3);
				if ( pszLocSrvCh[0]<'1' || pszLocSrvCh[0]>'9')
				{
					MessageBox(hwndDlg, "Wrong Server Channel", "DLCReleaseReq", MB_OK);
				}
				else
				{
					BOOL bReturnedVal;
					TX_ACL_BUFFER *pstACLTxFrame;
					UINT8         ucWriteOffset;
					unsigned char szData[128];

					
					GetDlgItemText(hwndDlg, IDC_BT_DLCDATA, (char*)szData, 127);
					if (strcmp((char*)szData, "+++") == 0 )
					{
						// send a +++ means no CR at the end
					}
					else
					{
						strcat((char*)szData, "\r\n");
					}
					pstACLTxFrame = BTR_pstAllocTxAclBuffer(BTRP_ucGetRFCOMM_Handle ( pszLocSrvCh[0]-'0' ), &ucWriteOffset);
					memcpy (((pstACLTxFrame->uL2CAP.L2CAP.aucL2capPayload)+ucWriteOffset),szData, strlen((char*)szData)); 
					bReturnedVal= BTR_bTopDataIn(BTRP_ucGetRFCOMM_Handle ( pszLocSrvCh[0]-'0' ), pszLocSrvCh[0]-'0', pstACLTxFrame, strlen((char*)szData));
					if ( !bReturnedVal )
					{
						MessageBox(hwndDlg, "Could not send Data due to FlowControl", "DLCDataReq", MB_OK);
					}
				}

				SetFocus(DispGetWinHandle());
#endif
				break;
			default:
				return (FALSE);
				break;
			}
		}
	}
/*	
	if (GetFocus() != DispGetWinHandle())
	{
		SetFocus(DispGetWinHandle());
	}
*/
	return FALSE;
}

////////////////////////////////////////////////////////////////////////////////
//extern "C" void open_bt_command_dialog( void )
void open_bt_command_dialog( void )
////////////////////////////////////////////////////////////////////////////////
{
	if(hBTDialog != NULL)
	{
		return;
	}
	
#ifdef _MSC_VER
	hBTDialog = CreateDialog(MainApp::hInstance,MAKEINTRESOURCE(DLG_BT),DispGetWinHandle(),(DLGPROC)BTDialogProc);
#else
	hBTDialog = CreateDialog(MainApp::hInstance,MAKEINTRESOURCE(DLG_BT),DispGetWinHandle(),(FARPROC)BTDialogProc);
#endif
	
	if (hBTDialog == NULL)
	{
		print_d("ERROR in creating 'BT Command Dialog!");
		MessageBox( DispGetWinHandle(), "Error: Could not create BT Dialog Window",
			"PC-Simulator: BT Command Dialog",
			(MB_OK | MB_ICONEXCLAMATION) | MB_TASKMODAL );
		return;
	}
	
	ShowWindow(hBTDialog,SW_SHOW);
}

BOOL btHexToBin(char *pszSource,char *pszDest)
{
	unsigned char ucCurByte;
	unsigned int  uiDestIndex= 0;
	BOOL bisEven = TRUE;
	unsigned int i;

	for (i=0; i<strlen(pszSource); i++)
	{
		ucCurByte= pszSource[i];
		if ( ( ucCurByte >= '0' && ucCurByte <= '9' ) ||
			 ( toupper(ucCurByte) >= 'A' && toupper(ucCurByte) <= 'F' ) )

		{
			if ( ucCurByte < 'A' )
			{
				// numeric value
				if ( bisEven )
				{
					pszDest[uiDestIndex]= 16*(ucCurByte-'0');
					bisEven= FALSE;
				}
				else
				{
					pszDest[uiDestIndex]+= (ucCurByte-'0');
					bisEven= TRUE;
					uiDestIndex++;
				}
			}
			else
			{
				// alpha value
				if ( bisEven )
				{
					pszDest[uiDestIndex]= 16*(toupper(ucCurByte)-'A'+10);
					bisEven= FALSE;
				}
				else
				{
					pszDest[uiDestIndex]+= (toupper(ucCurByte)-'A'+10);
					bisEven= TRUE;
					uiDestIndex++;
				}
			}
		}
		else
		{
			// error while conversion 
			return FALSE;
		}

	}

	return (TRUE);
}


void TraceOpen (HWND hWnd)
{
	DWORD last;
	DWORD ErrorCode;
	RECT ComRect, DlgClRect, DlgRect;
	HFONT hfnt;

	hTraceFile=  CreateFile( TEXT("bttrace.txt"),	// address of name of the file
    						   GENERIC_WRITE,	// access (read-write) mode
							   FILE_SHARE_READ|FILE_SHARE_WRITE,	// share mode
    						   NULL,	// address of security descriptor
							   CREATE_ALWAYS,	// how to create
							   FILE_ATTRIBUTE_NORMAL,	// file attributes
							   0 	// handle of file with attributes to copy
    						 );

	GetWindowRect(GetDlgItem(hWnd, IDC_BT_PRESENTREQ), &ComRect);
	GetWindowRect(hWnd, &DlgRect);
	GetClientRect(hWnd, &DlgClRect);

	LoadLibrary("RICHED32.DLL ");
	hwndTrace = CreateWindowEx( 0,
        "RichEdit", NULL, 
        WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | WS_BORDER |
		ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY, 
		0,
		0,
		ComRect.left-DlgRect.left-30,
		DlgClRect.bottom/2,
        hWnd, (HMENU)0, MainApp::hInstance, NULL 
        ); 

	
	if ( hwndTrace == NULL)
	{
		ErrorCode= GetLastError();
		MessageBox(hWnd, "Trace Window not Created", "ERROR", MB_OK);
	}
	hfnt=(HFONT)GetStockObject(ANSI_FIXED_FONT);
	SendMessage(hwndTrace, WM_SETFONT, (WPARAM)hfnt, MAKELPARAM(FALSE,0));

	ShowWindow( hwndTrace, SW_SHOWNORMAL  );    // Fenster anzeigen
	UpdateWindow( hwndTrace );            // Client-Area aktualisieren

	last= SendMessage(hwndTrace, WM_GETTEXTLENGTH, 0, 0);
	SendMessage(hwndTrace, EM_SETSEL, 0, last);
	SendMessage(hwndTrace, EM_REPLACESEL, FALSE, (LPARAM) TEXT(""));
	SendMessage(hwndTrace, EM_LINESCROLL, 0, 1);
}

void TraceClose (void)
{
	CloseHandle(hTraceFile);
	DestroyWindow(hwndTrace);
	hTraceFile= NULL;
	hwndTrace= NULL;
}

extern "C" void BTW_TraceLine(unsigned char *Line, unsigned int len)
{
	DWORD NumberOfBytesWritten;
	DWORD last;
	char tmpstring[258];
	unsigned int uiBytesLeft=len;
	unsigned int CRPos;
	char *SrcBegin=(char*)Line;
	char *SrcTmp;

	//if ( len >255)
	//{
	//	len = 255;
	//}


	if ( (hTraceFile != NULL)  && (hwndTrace != NULL) )
	{
		while (uiBytesLeft)
		{
			
			// skip Returns
			if ( *SrcBegin=='\r')
			{
				SrcBegin++;
				uiBytesLeft--;
			}
			else
			{
				SrcTmp=strstr(SrcBegin, "\n");
				//-SrcBegin;
				if ( SrcTmp == NULL)
				{
					CRPos=uiBytesLeft;
				}
				else if ( SrcTmp==SrcBegin)
				{
					CRPos = 1;
					*SrcBegin=' ';
					SrcTmp++;
				}
				else
				{
					CRPos=SrcTmp-SrcBegin;
				}

				if ( CRPos > 255 )
				{
					memcpy(tmpstring, SrcBegin, 255);
				}
				else
				{
					memcpy(tmpstring, SrcBegin, CRPos);
		}
				SrcBegin=SrcTmp+1;
				uiBytesLeft-=CRPos;

				
				if ( tmpstring[CRPos-1] == 0 )
				{
					tmpstring[CRPos-1]= '\n';
					tmpstring[CRPos]= 0;
				}
				else
				{
					tmpstring[CRPos]= '\n';
					tmpstring[CRPos+1]= 0;
					CRPos++;
				}
				WriteFile( hTraceFile, tmpstring, CRPos, &NumberOfBytesWritten, NULL); 
				
				last= SendMessage(hwndTrace, WM_GETTEXTLENGTH, 0, 0);
				SendMessage(hwndTrace, EM_SETSEL, last, last);
				
				SendMessage(hwndTrace, EM_REPLACESEL, FALSE, (LPARAM) tmpstring);
				SendMessage(hwndTrace, EM_LINESCROLL, 0, 1);
			}
		}
	}
} 
		
extern "C" void BTW_TraceHexLine(unsigned char *Line, unsigned int len)
{
	unsigned int last;

	unsigned char  ucOutPut[1501];
	unsigned int   uiOutputLen;
	unsigned int   uiBufferLeft=1500;
	unsigned int   uiSourceLeft = len;
	unsigned int   uiSourceIndex=0;
	unsigned int   uiLineLength;
	DWORD NumberOfBytesWritten;

	uiOutputLen= 0;

	if ( (hTraceFile != NULL)  && (hwndTrace != NULL) )
	{

		while ( uiSourceLeft )
		{
			if ( uiSourceLeft < 16 )
			{
				uiLineLength = uiSourceLeft;
			}
			else
			{
				uiLineLength = 16;
			}
			// a line fits in the output buffer
			ucOutPut[uiOutputLen]=0x00;
			BT_vConvertHexToStringEx (&ucOutPut[uiOutputLen], Line+uiSourceIndex, uiLineLength);
			memset(&ucOutPut[uiOutputLen+3*uiLineLength],' ', 49-3*uiLineLength);
			BT_vCopyReadibleChars (&ucOutPut[uiOutputLen+49], Line+uiSourceIndex, uiLineLength);
			uiOutputLen+=(49+uiLineLength);	
			ucOutPut[uiOutputLen++]='\n';
			ucOutPut[uiOutputLen]=0x00;
			uiSourceLeft-=uiLineLength;
			uiSourceIndex+=uiLineLength;

			WriteFile( hTraceFile, ucOutPut, uiOutputLen, &NumberOfBytesWritten, NULL); 
		
//			last= SendMessage(hwndTrace, WM_GETTEXTLENGTH, 0, 0);
//			SendMessage(hwndTrace, EM_SETSEL, last, last);
//			SendMessage(hwndTrace, EM_REPLACESEL, FALSE, (LPARAM) ucOutPut);
//			SendMessage(hwndTrace, EM_LINESCROLL, 0, 1);
			uiOutputLen=0;
		}
	}
} 


void BT_vConvertHexToStringEx( unsigned char *ucOutPut, unsigned char *pucHex, unsigned int uiLen)
{
  unsigned char acByte[] = " xx";
  unsigned int uiI;
  unsigned char  ucX;

  for(uiI = 0; uiI < uiLen ; uiI++)
  {
    ucX = ((*pucHex >>  4) & 0x0F);
    acByte[1] = ((ucX <= 9)?
                  (ucX + '0') :
                  (ucX + 'A'-10));
    ucX = ((*pucHex ) & 0x0F);
    acByte[2] = ((ucX <= 9)?
                  (ucX + '0') :
                  (ucX + 'A'-10));
    (void)strcat((char*)ucOutPut, (char*)acByte);
    pucHex++;
  }

}

void BT_vCopyReadibleChars ( unsigned char *ucOutPut, unsigned char *pucHex, unsigned int uiLen)
{
	unsigned int i;
	unsigned char  CurChar;

	for(i=0; i<uiLen; i++)
	{
		CurChar= *(pucHex+i);
		if ( CurChar >= ' ' && CurChar <= 0x7E )
		{
			// Human Readible Character
			*(ucOutPut+i)= CurChar;
		}
		else
		{
			*(ucOutPut+i)= '.';
		}
	}
}

void ReSizeTraceWindow(int x,int y, int width, int height)
{
	MoveWindow(hwndTrace, x, y, width, height, TRUE);
}

static void RemoveSpaces(char *pszBuffer)
{
	unsigned int len = strlen(pszBuffer);
	unsigned int i;
	unsigned int n=0;

	for (i=0; i<=len; i++)
	{
		if (pszBuffer[i] != ' ')
		{
			// copy the byte
			pszBuffer[n]= pszBuffer[i];
			n++;
		}
	}
}

static BOOL RegistryRead ( unsigned int *Comport )
{
	HKEY  hkResult1;
	LONG  lErgebnis= 0;
	DWORD ErgLaenge;
	
	*Comport= 0;
	if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE,
   				 "SOFTWARE\\Siemens\\Bluetooth",	// address of name of subkey to open
    				 0,	// reserved
				KEY_ALL_ACCESS ,	// security access mask
				&hkResult1) 	// address of handle of open key
		 != ERROR_SUCCESS )
	{
	  return (FALSE);
	}
	ErgLaenge= sizeof(DWORD);
	lErgebnis= RegQueryValueEx(hkResult1, "COM",
				   0, NULL, (BYTE*)(Comport),&ErgLaenge	);
	if ( lErgebnis != ERROR_SUCCESS )
	{

		LPVOID lpMsgBuf;
		FormatMessage( 
			FORMAT_MESSAGE_ALLOCATE_BUFFER | 
			FORMAT_MESSAGE_FROM_SYSTEM | 
			FORMAT_MESSAGE_IGNORE_INSERTS,
			NULL,
			GetLastError(),
			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
			(LPTSTR) &lpMsgBuf,
			0,
			NULL 
		);
		MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
		// Free the buffer.
		LocalFree( lpMsgBuf );
 		
		RegCloseKey(hkResult1);
		
		return(FALSE);
	}
	else
	{
		RegCloseKey(hkResult1);
		return (TRUE);
	}
}

static void RegistryWrite(unsigned int Comport)
{
    char  szClass[20]= "\0";
    HKEY  hkResult;
    DWORD dwDispos;
    if ( RegCreateKeyEx(HKEY_LOCAL_MACHINE,	// handle of an open key
                   "SOFTWARE\\Siemens\\Bluetooth",	// address of subkey name
                   0,	// reserved
                   szClass,	// address of class string
                   REG_OPTION_NON_VOLATILE,	// special options flag
                   KEY_ALL_ACCESS,	// desired security access
                   NULL,	// address of key security structure
                   &hkResult,	// address of buffer for opened handle
                   &dwDispos) 	// address of disposition value buffer
          != ERROR_SUCCESS )
    {
       return;
    }

	RegSetValueEx( hkResult, "COM",	0, REG_DWORD,
                   (BYTE*)(&Comport),  sizeof(DWORD)  );
	RegCloseKey(hkResult);

}

extern "C" BOOL BTWinGetBDAddress( char *pszBDADDRbin )
{
	char pszBDADDR[50];

	GetDlgItemText(hBTDialog, IDC_BT_BDADDR, pszBDADDR, 49);
	RemoveSpaces(pszBDADDR);
	if ( strlen(pszBDADDR) == 0 )
	{
		MessageBox(hBTDialog, "Please Enter a Device Address first", "Error", MB_OK);
		return ( FALSE );
	}
	else
	{
		if ( (strlen(pszBDADDR) != 12) || btHexToBin(pszBDADDR,pszBDADDRbin) == FALSE )
		{
			MessageBox(hBTDialog, "Address Wrong", "Error", MB_OK);
			return ( FALSE );
		}
	}
	return ( TRUE );
}

extern "C" BOOL BTWinGetRemoteServerChannel( unsigned char *pucRemoteServCh )
{
	char pszRemSrvCh[3];

	GetDlgItemText(hBTDialog, IDC_BT_SRVCHPEER, pszRemSrvCh, 3);

	if ( pszRemSrvCh[0]<'1' || pszRemSrvCh[0]>'9')
	{
		MessageBox(hBTDialog, "Please Enter RemoteServerChannel first", "Error", MB_OK);
		return ( FALSE );
	}
	else
	{
		*pucRemoteServCh = pszRemSrvCh[0]-'0';
	}

	return ( TRUE );
}

void TerminalOpen (HWND hWnd)
{
	DWORD last;
	DWORD ErrorCode;
	RECT  ComRect, DlgClRect, DlgRect;
	HFONT hfnt;

	
	GetWindowRect(GetDlgItem(hWnd, IDC_BT_PRESENTREQ), &ComRect);
	GetWindowRect(hWnd, &DlgRect);
	GetClientRect(hWnd, &DlgClRect);


	hwndTerm = CreateWindowEx( 0,
        "RichEdit", NULL, 
        WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | WS_BORDER |
		ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY, 
		0,
		DlgClRect.bottom /2,
		ComRect.left-DlgRect.left-30,
		DlgClRect.bottom /2,
        hWnd, (HMENU)0, MainApp::hInstance, NULL 
        ); 

	
	if ( hwndTerm == NULL)
	{
		ErrorCode= GetLastError();
		MessageBox(hWnd, "Terminal Window not not Created", "ERROR", MB_OK);
	}

	hfnt=(HFONT)GetStockObject(ANSI_FIXED_FONT);
	SendMessage(hwndTrace, WM_SETFONT, (WPARAM)hfnt, MAKELPARAM(FALSE,0));

	ShowWindow( hwndTerm, SW_SHOWNORMAL  );    // Fenster anzeigen
	UpdateWindow( hwndTerm );            // Client-Area aktualisieren

	last= SendMessage(hwndTerm, WM_GETTEXTLENGTH, 0, 0);
	SendMessage(hwndTerm, EM_SETSEL, 0, last);
	SendMessage(hwndTerm, EM_REPLACESEL, FALSE, (LPARAM) TEXT(""));
	SendMessage(hwndTerm, EM_LINESCROLL, 0, 1);
}

void TerminalClose (void)
{
	DestroyWindow(hwndTerm);
	hwndTerm= NULL;
}

extern "C" void BTW_TerminalOut(unsigned char *Line, DWORD len)
{
	DWORD dwBegin = 0;
	DWORD last;
	DWORD i;
	
	for (i=0; i<len; i++)
	{
		if (( Line[i]=='\n' )||( Line[i]=='\r' ))
		{
			if ( Line[i]=='\r')
			{
			    Line[i]=' ';
			}
			else
			{
			    Line[i]=0;
				last= SendMessage(hwndTerm, WM_GETTEXTLENGTH, 0, 0);
				SendMessage(hwndTerm, EM_SETSEL, last, last);
				SendMessage(hwndTerm, EM_REPLACESEL, FALSE, (LPARAM)(Line+dwBegin));
				SendMessage(hwndTerm, EM_REPLACESEL, FALSE, (LPARAM) "\n");
				SendMessage(hwndTerm, EM_LINESCROLL, 0, 1);
				dwBegin=i+1;
			}
		}

	}
	if (dwBegin <= i )
	{
	   Line[i]=0;
		last= SendMessage(hwndTerm, WM_GETTEXTLENGTH, 0, 0);
		SendMessage(hwndTerm, EM_SETSEL, last, last);
		SendMessage(hwndTerm, EM_REPLACESEL, FALSE, (LPARAM)(Line+dwBegin));
	}
} 

#endif // BT_AVAILABLE_PCMMI
