/*++ Copyright (c) 1999 Microsoft Corporation Module Name: hidphone.h Abstract: This module contains the definitions of all the data structures being used in hidphone.c Author: Shivani Aggarwal --*/ #ifndef _HIDPHONE_H_ #define _HIDPHONE_H_ #include #include #include #include #include #include #include // * NOTE - initguid.h must always be defined before devguid.h #include #include #include #include "hidsdi.h" #include "hid.h" #include "resource.h" #include "audio.h" #include "mymem.h" #define LOW_VERSION 0x00020000 #define HIGH_VERSION 0x00030001 // // MAX_CHARS is used as an upper limit on the number of chars required // to store the phone id as a string. The phone ids begin from 0 // to gdwNumPhones which a DWORD, hence 32-bit. Therefore the largest number // possible is 4294967296. Hence 20 chars are enough to store the largest string // #define MAX_CHARS 20 // In order to distinguish between value and button usages #define PHONESP_BUTTON 1 #define PHONESP_VALUE 0 // Registry strings #define REGSTR_PATH_WINDOWS_CURRENTVERSION TEXT("Software\\Microsoft\\Windows\\CurrentVersion") #define TAPI_REGKEY_ROOT REGSTR_PATH_WINDOWS_CURRENTVERSION TEXT("\\Telephony") #define TAPI_REGKEY_PROVIDERS TAPI_REGKEY_ROOT TEXT("\\Providers") #define TAPI_REGVAL_NUMPROVIDERS TEXT("NumProviders") #define HIDPHONE_TSPDLL TEXT("HIDPHONE.TSP") ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // // Telephony HID definitions // These are usages already defined in the Hid Telephony page. // Just defining the usages with User-friendly names // // Definitions of relevant usages on the telephony page. #define HID_USAGE_TELEPHONY_HANDSET ((USAGE) 0x04) #define HID_USAGE_TELEPHONY_HEADSET ((USAGE) 0x05) #define HID_USAGE_TELEPHONY_HOOKSWITCH ((USAGE) 0x20) #define HID_USAGE_TELEPHONY_FLASH ((USAGE) 0x21) #define HID_USAGE_TELEPHONY_HOLD ((USAGE) 0x23) #define HID_USAGE_TELEPHONY_REDIAL ((USAGE) 0x24) #define HID_USAGE_TELEPHONY_TRANSFER ((USAGE) 0x25) #define HID_USAGE_TELEPHONY_DROP ((USAGE) 0x26) #define HID_USAGE_TELEPHONY_PARK ((USAGE) 0x27) #define HID_USAGE_TELEPHONY_FORWARD_CALLS ((USAGE) 0x28) #define HID_USAGE_TELEPHONY_LINE ((USAGE) 0x2A) #define HID_USAGE_TELEPHONY_SPEAKER_PHONE ((USAGE) 0x2B) #define HID_USAGE_TELEPHONY_CONFERENCE ((USAGE) 0x2C) #define HID_USAGE_TELEPHONY_RING_SELECT ((USAGE) 0x2E) #define HID_USAGE_TELEPHONY_PHONE_MUTE ((USAGE) 0x2F) #define HID_USAGE_TELEPHONY_CALLERID ((USAGE) 0x30) #define HID_USAGE_TELEPHONY_SEND ((USAGE) 0x31) #define HID_USAGE_TELEPHONY_DONOTDISTURB ((USAGE) 0x72) #define HID_USAGE_TELEPHONY_RINGER ((USAGE) 0x9E) #define HID_USAGE_TELEPHONY_PHONE_KEY_0 ((USAGE) 0xB0) #define HID_USAGE_TELEPHONY_PHONE_KEY_1 ((USAGE) 0xB1) #define HID_USAGE_TELEPHONY_PHONE_KEY_2 ((USAGE) 0xB2) #define HID_USAGE_TELEPHONY_PHONE_KEY_3 ((USAGE) 0xB3) #define HID_USAGE_TELEPHONY_PHONE_KEY_4 ((USAGE) 0xB4) #define HID_USAGE_TELEPHONY_PHONE_KEY_5 ((USAGE) 0xB5) #define HID_USAGE_TELEPHONY_PHONE_KEY_6 ((USAGE) 0xB6) #define HID_USAGE_TELEPHONY_PHONE_KEY_7 ((USAGE) 0xB7) #define HID_USAGE_TELEPHONY_PHONE_KEY_8 ((USAGE) 0xB8) #define HID_USAGE_TELEPHONY_PHONE_KEY_9 ((USAGE) 0xB9) #define HID_USAGE_TELEPHONY_PHONE_KEY_STAR ((USAGE) 0xBA) #define HID_USAGE_TELEPHONY_PHONE_KEY_POUND ((USAGE) 0xBB) #define HID_USAGE_TELEPHONY_PHONE_KEY_A ((USAGE) 0xBC) #define HID_USAGE_TELEPHONY_PHONE_KEY_B ((USAGE) 0xBD) #define HID_USAGE_TELEPHONY_PHONE_KEY_C ((USAGE) 0xBE) #define HID_USAGE_TELEPHONY_PHONE_KEY_D ((USAGE) 0xBF) #define HID_USAGE_CONSUMER_VOLUME ((USAGE) 0xE0) #define PHONESP_ALLBUTTONMODES \ ( PHONEBUTTONMODE_CALL | \ PHONEBUTTONMODE_FEATURE | \ PHONEBUTTONMODE_KEYPAD | \ PHONEBUTTONMODE_LOCAL | \ PHONEBUTTONMODE_DISPLAY ) #define PHONESP_ALLBUTTONSTATES \ (PHONEBUTTONSTATE_UP | \ PHONEBUTTONSTATE_DOWN) // These act like bit masks which specify which reports are valid for a usage #define INPUT_REPORT 1 #define OUTPUT_REPORT 2 #define FEATURE_REPORT 4 /*****************************************************************************/ // // This structure holds the information for the button // typedef struct _PHONESP_BUTTON_INFO { // The ID for this button DWORD dwButtonID; // The ButtonMode (whether it is a PHONEBUTTONMODE_FEATURE or _KEYPAD, etc) DWORD dwButtonMode; // the Function (PHONEBUTTONFUNCTION_NONE or _FLASH, etc), DWORD dwButtonFunction; // // This data is relevant for only on-off control buttons. The current state // of the button is stored here // DWORD dwButtonState; // the Button Text associated for the button - these are present in the // string table LPWSTR szButtonText; } PHONESP_BUTTONINFO, *PPHONESP_BUTTONINFO; /*****************************************************************************/ // // // User friendly names for the indexes into the capabilities of the phone structure // #define PHONESP_PHONE_KEY_0 0 #define PHONESP_PHONE_KEY_1 1 #define PHONESP_PHONE_KEY_2 2 #define PHONESP_PHONE_KEY_3 3 #define PHONESP_PHONE_KEY_4 4 #define PHONESP_PHONE_KEY_5 5 #define PHONESP_PHONE_KEY_6 6 #define PHONESP_PHONE_KEY_7 7 #define PHONESP_PHONE_KEY_8 8 #define PHONESP_PHONE_KEY_9 9 #define PHONESP_PHONE_KEY_STAR 10 #define PHONESP_PHONE_KEY_POUND 11 #define PHONESP_PHONE_KEY_A 12 #define PHONESP_PHONE_KEY_B 13 #define PHONESP_PHONE_KEY_C 14 #define PHONESP_PHONE_KEY_D 15 // The number of dial buttons supported by this tsp #define PHONESP_NUMBER_PHONE_KEYS 16 // Feature Button indices #define PHONESP_FEATURE_FLASH 16 #define PHONESP_FEATURE_HOLD 17 #define PHONESP_FEATURE_REDIAL 18 #define PHONESP_FEATURE_TRANSFER 19 #define PHONESP_FEATURE_DROP 20 #define PHONESP_FEATURE_PARK 21 #define PHONESP_FEATURE_FORWARD 22 #define PHONESP_FEATURE_LINE 23 #define PHONESP_FEATURE_CONFERENCE 24 #define PHONESP_FEATURE_RING_SELECT 25 #define PHONESP_FEATURE_PHONE_MUTE 26 #define PHONESP_FEATURE_CALLERID 27 #define PHONESP_FEATURE_DONOTDISTURB 28 #define PHONESP_FEATURE_SEND 29 #define PHONESP_FEATURE_VOLUMEUP 30 #define PHONESP_FEATURE_VOLUMEDOWN 31 // The number of Feature buttons supported by this tsp #define PHONESP_NUMBER_FEATURE_BUTTONS 16 #define PHONESP_NUMBER_BUTTONS ( PHONESP_NUMBER_PHONE_KEYS + \ PHONESP_NUMBER_FEATURE_BUTTONS ) // // The functions associated with the feature buttons // DWORD gdwButtonFunction[] = { PHONEBUTTONFUNCTION_FLASH, PHONEBUTTONFUNCTION_HOLD, PHONEBUTTONFUNCTION_LASTNUM, PHONEBUTTONFUNCTION_TRANSFER, PHONEBUTTONFUNCTION_DROP, PHONEBUTTONFUNCTION_PARK, PHONEBUTTONFUNCTION_FORWARD, PHONEBUTTONFUNCTION_CALLAPP, PHONEBUTTONFUNCTION_CONFERENCE, PHONEBUTTONFUNCTION_SELECTRING, PHONEBUTTONFUNCTION_MUTE, PHONEBUTTONFUNCTION_CALLID, PHONEBUTTONFUNCTION_DONOTDISTURB, PHONEBUTTONFUNCTION_SEND, PHONEBUTTONFUNCTION_VOLUMEUP, PHONEBUTTONFUNCTION_VOLUMEDOWN }; // // The associated string table ID for the text of the phone buttons // DWORD gdwButtonText[] = { IDS_PHONE_KEY_0, IDS_PHONE_KEY_1, IDS_PHONE_KEY_2, IDS_PHONE_KEY_3, IDS_PHONE_KEY_4, IDS_PHONE_KEY_5, IDS_PHONE_KEY_6, IDS_PHONE_KEY_7, IDS_PHONE_KEY_8, IDS_PHONE_KEY_9, IDS_PHONE_KEY_STAR, IDS_PHONE_KEY_POUND, IDS_PHONE_KEY_A, IDS_PHONE_KEY_B, IDS_PHONE_KEY_C, IDS_PHONE_KEY_D, IDS_BUTTON_FLASH, IDS_BUTTON_HOLD, IDS_BUTTON_REDIAL, IDS_BUTTON_TRANSFER, IDS_BUTTON_DROP, IDS_BUTTON_PARK, IDS_BUTTON_FORWARD, IDS_BUTTON_LINE, IDS_BUTTON_CONFERENCE, IDS_BUTTON_RING_SELECT, IDS_BUTTON_MUTE, IDS_BUTTON_CALLERID, IDS_BUTTON_DONOTDISTURB, IDS_BUTTON_SEND, IDS_BUTTON_VOLUMEUP, IDS_BUTTON_VOLUMEDOWN }; typedef struct _PHONESP_LOOKUP_USAGEINDEX { USAGE Usage; DWORD Index; }PHONESP_LOOKUPUSAGEINDEX, *PPHONESP_LOOKUPUSAGEINDEX; // inorder to look up the index for the feature button usages // The 1st value in this 2-D array are the feature usages supported // The 2nd value is the respective index PHONESP_LOOKUPUSAGEINDEX gdwLookupFeatureIndex [] = { { HID_USAGE_TELEPHONY_FLASH, PHONESP_FEATURE_FLASH }, { HID_USAGE_TELEPHONY_HOLD, PHONESP_FEATURE_HOLD }, { HID_USAGE_TELEPHONY_REDIAL, PHONESP_FEATURE_REDIAL }, { HID_USAGE_TELEPHONY_TRANSFER, PHONESP_FEATURE_TRANSFER }, { HID_USAGE_TELEPHONY_DROP, PHONESP_FEATURE_DROP }, { HID_USAGE_TELEPHONY_PARK, PHONESP_FEATURE_PARK }, { HID_USAGE_TELEPHONY_FORWARD_CALLS, PHONESP_FEATURE_FORWARD }, { HID_USAGE_TELEPHONY_LINE, PHONESP_FEATURE_LINE }, { HID_USAGE_TELEPHONY_CONFERENCE, PHONESP_FEATURE_CONFERENCE }, { HID_USAGE_TELEPHONY_RING_SELECT, PHONESP_FEATURE_RING_SELECT }, { HID_USAGE_TELEPHONY_PHONE_MUTE, PHONESP_FEATURE_PHONE_MUTE }, { HID_USAGE_TELEPHONY_CALLERID, PHONESP_FEATURE_CALLERID }, { HID_USAGE_TELEPHONY_DONOTDISTURB, PHONESP_FEATURE_DONOTDISTURB }, { HID_USAGE_TELEPHONY_SEND, PHONESP_FEATURE_SEND } }; /****************************************************************************/ // // This structure maintains the information available about the phone. Every // phone that has been enumerated has this structure associated with it // typedef struct _PHONESP_PHONE_INFO { // The deviceID for the phone. The Device ID for the phone is initialized // in TSPI_providerInit DWORD dwDeviceID; // // The version negotiated with TAPI using TSPI_phoneNegotiateTSPIVersion // function that returns the highest SPI version the TSP can operate under // for this device. // DWORD dwVersion; // // if this is true then it means that the // phone is open and phone close on the device hasn't been called yet // BOOL bPhoneOpen; // // if this is false it means that this entry in the phone array is // unused and can be filled in with a new phone // BOOL bAllocated; // // if this is true it means that a PHONE_CREATE message was sent for this // phone, but we are waiting for a TSPI_providerCreatePhoneDevice // BOOL bCreatePending; // // if this is true it means that a PHONE_REMOVE message was sent for this // phone, but we are waiting for a TSPI_phoneClose // BOOL bRemovePending; // // This variable keeps a count of the number of requests queued for this // phone in the async queue // DWORD dwNumPendingReqInQueue; // // A handle to an event object which is set when there are no requests // pending in the queue for this phone. Phone Close waits on this event // to ensure that all asynchronous operations on the phone has been // completed // HANDLE hNoPendingReqInQueueEvent; // // The handle for the phone received from TAPI and used by the phone // to notify TAPI about the events occuring on this phone // HTAPIPHONE htPhone; // //Pointer to the Hid Device structure associated with this device // PHID_DEVICE pHidDevice; // // Whether the phone device has a render device associated with it // BOOL bRender; // // if the render device exists for this phone, this data contains the // render device id // DWORD dwRenderWaveId; // // Whether the phone device has a capture device associated with it // BOOL bCapture; // // if the capture device exists for this phone, this data contains the // capture device id // DWORD dwCaptureWaveId; // This event is signalled when a input report is recieved from the device HANDLE hInputReportEvent; // This event is signalled when the phone is closed HANDLE hCloseEvent; // A handle to the read thread HANDLE hReadThread; // The structure to be passed to the ReadFile function - This struct will // pass the hInputReportEvent which will be triggered when ReadFile returns LPOVERLAPPED lpOverlapped; // The Critical Section for this phone CRITICAL_SECTION csThisPhone; // lpfnPhoneEventProc is a callback function implemented by TAPI and // supplied to the TSP as a parameter to TSPI_phoneOpen The TSP calls this // function to report events that occur on the phone. // PHONEEVENT lpfnPhoneEventProc; // The phone states messages for which TAPI can receive notification DWORD dwPhoneStates; // // The phone state messages TAPI is interested in receiving // DWORD dwPhoneStateMsgs; // // The last three bits of this data signify which reports are valid for the // handset/speaker. If zero, the handset does not exist, if bit 0 is set - // input report can be received, if bit 1 is set - output report can be // sent, if bit 2 is set - feature report supported // DWORD dwHandset; DWORD dwSpeaker; // // The mode of the handset/ speaker at the moment whether _ONHOOK, _MIC, // _SPEAKER, _MICSPEAKER. These modes are defined by TAPI // DWORD dwHandsetHookSwitchMode; DWORD dwSpeakerHookSwitchMode; BOOL bSpeakerHookSwitchButton; // // The hookswitch supported on this phone - handset and/or speaker // DWORD dwHookSwitchDevs; // To determine whether the phone has a keypad BOOL bKeyPad; // // The last three bits of this data signify which reports are valid for the // ringer. If zero, the handset does not exist, if bit 0 is set - input // report can be received, if bit 1 is set - output report can be sent, if // bit 2 is set - feature report supported // DWORD dwRing; // // The last three bits of this data signify which reports are valid for the // volume control. If zero, the handset does not exist, if bit 0 is set - input // report can be received, if bit 1 is set - output report can be sent, if // bit 2 is set - feature report supported // DWORD dwVolume; // // The mode of the handset/ speaker at the moment whether ringing or not // if zero the phone is not ringing // DWORD dwRingMode; // The buttonmodes for which the phone will send phone events DWORD dwButtonModesMsgs; // The button states for which the phone will send phone events DWORD dwButtonStateMsgs; // Number of usable buttons on this phone DWORD dwNumButtons; PPHONESP_BUTTONINFO pButtonInfo; // // The Phone Name and other Info on this Phone which will be displayed // LPWSTR wszPhoneName, wszPhoneInfo; // // The buttons valid for this phone - the entry for the // corresponding button contains 0 if the button associated with the index // does not exist else it specifies the report types valid for this button // using the last 3 bits. // DWORD dwReportTypes[PHONESP_NUMBER_BUTTONS]; // // After the button is created this contains the // report Id assigned to the button // DWORD dwButtonIds[PHONESP_NUMBER_BUTTONS]; } PHONESP_PHONE_INFO, *PPHONESP_PHONE_INFO; /*****************************************************************************/ typedef void (CALLBACK *ASYNCPROC)(PPHONESP_ASYNCREQINFO, BOOL); /*****************************************************************************/ typedef struct _PHONESP_FUNC_INFO { // number of parameters in this array - don't actually use it, can be removed DWORD dwNumParams; // The pointer to the phone ULONG_PTR dwParam1; // // The rest of the parameters are dependent on the function // to which this parameter list is passed // ULONG_PTR dwParam2; ULONG_PTR dwParam3; ULONG_PTR dwParam4; ULONG_PTR dwParam5; ULONG_PTR dwParam6; ULONG_PTR dwParam7; ULONG_PTR dwParam8; } PHONESP_FUNC_INFO, far *PPHONESP_FUNC_INFO; /*****************************************************************************/ typedef struct _PHONESP_ASYNC_REQUEST_INFO { // The function to be executed ASYNCPROC pfnAsyncProc; // Parameters to be passed to the async function PPHONESP_FUNC_INFO pFuncInfo; } PHONESP_ASYNC_REQ_INFO, *PPHONESP_ASYNC_REQ_INFO; /*****************************************************************************/ typedef struct _PHONESP_ASYNC_QUEUE { // //The handle to the thread which services the queue // HANDLE hAsyncEventQueueServiceThread; // // The event if set signifies pending entries in the queue // else the thread waits on this thread // HANDLE hAsyncEventsPendingEvent; CRITICAL_SECTION AsyncEventQueueCritSec; DWORD dwNumTotalQueueEntries; DWORD dwNumUsedQueueEntries; //Pointer to the queue PPHONESP_ASYNC_REQ_INFO *pAsyncRequestQueue; //Pointer to the next entry in the queue where the request can be added PPHONESP_ASYNC_REQ_INFO *pAsyncRequestQueueIn; //Pointer to the next request to be serviced in the queue PPHONESP_ASYNC_REQ_INFO *pAsyncRequestQueueOut; } PHONESP_ASYNCQUEUE, *PPHONESP_ASYNCQUEUE; /*****************************************************************************/ // // All these might be combined in a global structure // DWORD gdwNumPhones; HINSTANCE ghInst; DWORD gdwPermanentProviderID; DWORD gdwPhoneDeviceIDBase; HPROVIDER ghProvider; // The memory for this queue is allocated in providerInit and will be used to // store requests on the phone. These requests will be processed asynchronously // by a separate Thread created on this queue PHONESP_ASYNCQUEUE gAsyncQueue, gInputReportQueue; // 256 is just a random number taken for the initial number of entries that the // can have.. the queue can be expanded later as required #define MAX_QUEUE_ENTRIES 256 // // glpfnCompletionProc is a callback function implemented by TAPI and supplied // to the TSP as a parameter to TSPI_providerInit.The TSP calls this function // to report the completion of a line or phone procedure that it executes // asynchronously. // ASYNC_COMPLETION glpfnCompletionProc; // // glpfnPhoneCreateProc is a callback function implemented by TAPI and supplied // to the TSP as a parameter to TSPI_providerInit The TSP calls this function // to report the creation of a new device. // PHONEEVENT glpfnPhoneCreateProc; // gpPhone maintains an array of the phones enumerated - each of these phones // have a corresponding HidDevice value in the gpHidDevices. PPHONESP_PHONE_INFO *gpPhone; // This the global heap from which all the memory allocations are carried out HANDLE ghHeap; // This two handles are required for registering for PNP events HANDLE ghDevNotify; HWND ghWndNotify; const LPCWSTR gpcstrServiceName = _T("TapiSrv"); LPCWSTR gszProviderInfo; // This is to notify the thread that services the queue to exit // maybe this could be changed to an event based termination of thread BOOL gbProviderShutdown = FALSE; CRITICAL_SECTION csAllPhones; CRITICAL_SECTION csHidList; PPHONESP_MEMINFO gpMemFirst = NULL, gpMemLast = NULL; CRITICAL_SECTION csMemoryList; BOOL gbBreakOnLeak = FALSE; /**********************PRIVATE FUNCTIONS**************************************/ BOOL AsyncRequestQueueIn ( PPHONESP_ASYNC_REQ_INFO pAsyncReqInfo ); LONG CreateButtonsAndAssignID( PPHONESP_PHONE_INFO pPhone ); PPHONESP_BUTTONINFO GetButtonFromID ( PPHONESP_PHONE_INFO pPhone, DWORD dwButtonID ); VOID GetButtonUsages( PPHONESP_PHONE_INFO pPhone, PHIDP_BUTTON_CAPS pButtonCaps, DWORD dwNumberButtonCaps, DWORD ReportType ); PPHONESP_PHONE_INFO GetPhoneFromID( DWORD dwDeviceID, DWORD * pdwPhoneID ); PPHONESP_PHONE_INFO GetPhoneFromHid ( PHID_DEVICE HidDevice ); VOID GetValueUsages( PPHONESP_PHONE_INFO pPhone, PHIDP_VALUE_CAPS pValueCaps, DWORD dwNumberCaps, DWORD ReportType ); VOID InitPhoneAttribFromUsage ( DWORD ReportType, USAGE UsagePage, USAGE Usage, PPHONESP_PHONE_INFO pPhone, LONG Min, LONG Max ); LONG LookupIndexForUsage( IN DWORD Usage, OUT DWORD *Index ); DWORD WINAPI PNPServiceHandler( DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext ); VOID ReportUsage ( PPHONESP_PHONE_INFO pPhone, USAGE UsagePage, USAGE Usage, ULONG Value ); VOID SendPhoneEvent( PPHONESP_PHONE_INFO pPhone, DWORD dwMsg, ULONG_PTR Param1, ULONG_PTR Param2, ULONG_PTR Param3 ); LONG SendOutputReport( PHID_DEVICE pHidDevice, USAGE Usage, BOOL bSet ); VOID CALLBACK ShowData( PPHONESP_FUNC_INFO pAsyncFuncInfo ); LPWSTR PHONESP_LoadString( IN UINT ResourceID, PLONG lResult ); BOOL ReadInputReport ( PPHONESP_PHONE_INFO pPhone ); VOID InitUsage ( PPHONESP_PHONE_INFO pPhone, USAGE Usage, BOOL bON ); VOID ReenumDevices (); VOID FreePhone ( PPHONESP_PHONE_INFO pPhone ); LONG CreatePhone ( PPHONESP_PHONE_INFO pPhone, PHID_DEVICE pHidDevice, DWORD dwPhoneCnt ); #endif