rendered paste body// Pam.cpp : Defines the entry point for the DLL application.
//
#include "stdAfx.h"
// Pam.cpp : Defines the entry point for the DLL application.
// Pam.cpp : Defines the class behaviors for the application.
//
// Waarschuwing bij debuggen: in een sessie wordt een key bepaald met een geldigheidsduur van X seconden.
// Bij het verzenden van beschermde berichten moet deze key nog geldig zijn. Let hierop bij het plaatsen
// van breakpoints.
#include "Pam.h"
#include "StandardDlg.h"
#include "DebugDlg.h"
#include "AboutDlg.h"
#include "ProgressDlg.h"
#include "url.h"
#include "GrabWininet.h"
#include "TaskBarApplet.hpp"
#define _MFC_TASKBAR_APPLET
#include "TaskBarAppletMain.hpp"
#ifdef USE_COM_PORTS
#include "serialWnd.h"
#else
#include "SiUSBXp.h"
#endif
#include "betronic.h"
#include <iostream> // for XOR operator???
#include <iso646.h> // for XOR operator???
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// Definieer de types die uit de WinHttp.dll nodig zijn:
#include <winhttp.h>
typedef BOOL (WINAPI *TFWinHttpReadData)(
IN HINTERNET hRequest,
IN LPVOID lpBuffer,
IN DWORD dwNumberOfBytesToRead,
OUT LPDWORD lpdwNumberOfBytesRead
);
typedef HINTERNET (WINAPI *TFWinHttpOpen)(
IN LPCWSTR pwszUserAgent,
IN DWORD dwAccessType,
IN LPCWSTR pwszProxyName OPTIONAL,
IN LPCWSTR pwszProxyBypass OPTIONAL,
IN DWORD dwFlags
);
typedef HINTERNET (WINAPI *TFWinHttpConnect)(
IN HINTERNET hSession,
IN LPCWSTR pswzServerName,
IN INTERNET_PORT nServerPort,
IN DWORD dwReserved
);
typedef HINTERNET (WINAPI *TFWinHttpOpenRequest)(
IN HINTERNET hConnect,
IN LPCWSTR pwszVerb,
IN LPCWSTR pwszObjectName,
IN LPCWSTR pwszVersion,
IN LPCWSTR pwszReferrer OPTIONAL,
IN LPCWSTR FAR * ppwszAcceptTypes OPTIONAL,
IN DWORD dwFlags
);
typedef BOOL (WINAPI *TFWinHttpSendRequest)(
IN HINTERNET hRequest,
IN LPCWSTR pwszHeaders OPTIONAL,
IN DWORD dwHeadersLength,
IN LPVOID lpOptional OPTIONAL,
IN DWORD dwOptionalLength,
IN DWORD dwTotalLength,
IN DWORD_PTR dwContext
);
typedef BOOL (WINAPI *TFWinHttpReceiveResponse) (
IN HINTERNET hRequest,
IN LPVOID lpReserved
);
typedef BOOL (WINAPI *TFWinHttpQueryDataAvailable)(
IN HINTERNET hRequest,
OUT LPDWORD lpdwNumberOfBytesAvailable OPTIONAL
);
/////////////////////////////////////////////////////////////////////////////
// CPamTaskBar:
//
class CPamTaskBar : public CJBTaskBarApplet
{
public:
//MFCApplet();
private:
extern "C" bool __declspec(dllexport) __stdcall InitInstance(LPSTR lpCmdLine);
extern "C" void __declspec(dllexport) __stdcall OnLeftDoubleClick();
// extern "C" void __declspec(dllexport) __stdcall void SettingsDialog();
extern "C" void __declspec(dllexport) __stdcall AboutDialog();
extern "C" HICON __declspec(dllexport) __stdcall GetIcon();
extern "C" HMENU __declspec(dllexport) __stdcall GetMenu();
extern "C" void __declspec(dllexport) __stdcall HandleMenuCommand(int command);
enum menuIDs { ID_CLOSE = 1, ID_OPEN, ID_ABOUT, ID_UPLOAD, ID_PAM };
extern "C" bool ShowError __declspec(dllexport) __stdcall (LONG lError, LPCTSTR lptszMessage, BOOL bShowPopup);
extern "C" void __declspec(dllexport) __stdcall OnSerialMessage(WPARAM wParam);
extern "C" void __declspec(dllexport) __stdcall OnTimerMessage(WPARAM wParam);
CSerialWnd m_serial;
extern "C" void __declspec(dllexport) __stdcall NotifyUser(CString strMsg, BOOL bShow, BOOL bReset);
ProgressDlg * m_pProgressDlg;
CString m_TrayTip;
extern "C" LPCTSTR __declspec(dllexport) __stdcall GetTrayTip();
#ifdef USE_COM_PORTS
extern "C" bool __stdcall OpenComPort();
extern "C" bool __declspec(dllexport) __stdcall CloseComPort();
#else
extern "C" bool __declspec(dllexport) __stdcall OpenUSB();
extern "C" bool __declspec(dllexport) __stdcall CloseUSB();
extern "C" bool __declspec(dllexport) __stdcall ReadUSB();
extern "C" bool __declspec(dllexport) __stdcall PamStillThere();
#endif
extern "C" bool __declspec(dllexport) __stdcall PamToggleMode();
extern "C" bool __declspec(dllexport) __stdcall PamSetTime();
extern "C" bool __declspec(dllexport) __stdcall PamGetTime();
extern "C" bool __declspec(dllexport) __stdcall PamReadMode();
extern "C" bool __declspec(dllexport) __stdcall PamSetMode(BYTE mode, BYTE key_return); // added by E. Damen for AM200
extern "C" bool __declspec(dllexport) __stdcall PamSetAux(BYTE CalorieperPam); // added by E. Damen for AM200
extern "C" bool __declspec(dllexport) __stdcall PamStaticMode();
extern "C" bool __declspec(dllexport) __stdcall PamReadSerialNumber();
extern "C" bool __declspec(dllexport) __stdcall PamReadDockingDate();
extern "C" bool __declspec(dllexport) __stdcall PamReadCalibrationFactor();
extern "C" bool __declspec(dllexport) __stdcall PamReadEeprom();
extern "C" bool __declspec(dllexport) __stdcall PamReadToday();
extern "C" bool __declspec(dllexport) __stdcall PamReadEepromPage0(BYTE key_return); // added by E. Damen for AM102
extern "C" bool __declspec(dllexport) __stdcall PamReadEepromPage1(BYTE key_return); // added by E. Damen for AM102
extern "C" bool __declspec(dllexport) __stdcall PamReadEepromPage2(BYTE key_return); // added by E. Damen for AM102
extern "C" bool __declspec(dllexport) __stdcall PamReadEepromPage3(BYTE key_return); // added by E. Damen for AM102
extern "C" bool __declspec(dllexport) __stdcall PamUploadData();
extern "C" bool __declspec(dllexport) __stdcall PamReadRam(UINT address);
extern "C" bool __declspec(dllexport) __stdcall SendCommand(struct Message *message, BOOL bReading);
extern "C" void __declspec(dllexport) __stdcall StartHeartbeat();
int m_State;
int m_TimeOut;
extern "C" void __declspec(dllexport) __stdcall ProcessBreak();
extern "C" BOOL __declspec(dllexport) __stdcall ProcessMessage();
BYTE m_Buffer[256];
DWORD m_dwEob;
BOOL m_DiscardInput;
BOOL m_bSkipBreak;
UINT m_bSkipCounter;
UINT m_SerialNumber;
struct { UINT Major; UINT Minor; UINT Build; } m_VersionNumber;
DWORD m_Config;
BYTE m_Key;
BYTE m_Key_return;
BYTE m_PamMode;
BYTE m_CalorieperPam; // Added by E. Damen for AM200
BYTE m_UpdateDockDay; // Added by E. Damen for AM200
BYTE m_PamDayScore16;
UINT m_PamLowScore;
UINT m_PamMedScore;
UINT m_PamHighScore;
UINT m_PamDistanceTD;
UINT m_PamFruitTD;
BOOL m_ConsumerMode; // The real mode in which the docked Pam is running
CTime m_Time;
UINT m_Heartbeat;
UINT m_GainAdjustMultiplier;
UINT m_GainAdjustDivider;
UINT m_TresholdHeavy;
UINT m_TresholdLight;
UINT m_Fifo; // The current pointer in the PAM data
UINT m_Size;
UINT m_Pam[512]; // changed by E. Damen for AM102
UINT m_LightActivity[512]; // changed by E. Damen for AM102
UINT m_MediumActivity[512]; // changed by E. Damen for AM102
UINT m_HeavyActivity[512]; // changed by E. Damen for AM102
UINT m_Distance[512]; // added by E. Damen for AM200
UINT m_Fruit[512]; // added by E. Damen for AM200
UINT m_code1[512]; // added by E. Damen for AM200
UINT m_code2[512]; // added by E. Damen for AM200
BOOL m_bMilitary;
BYTE Eepromt[0x1FF]; // changed by E. Damen for AM102
HANDLE m_hUSBDevice;
// Dit zijn variabelen die de adressen naar de WinHTTP functies gaan bevatten:
TFWinHttpReadData FWinHttpReadData;
TFWinHttpConnect FWinHttpConnect;
TFWinHttpOpen FWinHttpOpen;
TFWinHttpOpenRequest FWinHttpOpenRequest;
TFWinHttpSendRequest FWinHttpSendRequest;
TFWinHttpReceiveResponse FWinHttpReceiveResponse;
TFWinHttpQueryDataAvailable FWinHttpQueryDataAvailable;
// Hier komen onze varianten van de WinHTTP functies:
extern "C" BOOL __declspec(dllexport) __stdcall WinHttpReadData
(
IN HINTERNET hRequest,
IN LPVOID lpBuffer,
IN DWORD dwNumberOfBytesToRead,
OUT LPDWORD lpdwNumberOfBytesRead
);
extern "C" HINTERNET __declspec(dllexport) __stdcall WinHttpConnect
(
IN HINTERNET hSession,
IN LPCWSTR pswzServerName,
IN INTERNET_PORT nServerPort,
IN DWORD dwReserved
);
extern "C" HINTERNET __declspec(dllexport) __stdcall WinHttpOpen(
IN LPCWSTR pwszUserAgent,
IN DWORD dwAccessType,
IN LPCWSTR pwszProxyName OPTIONAL,
IN LPCWSTR pwszProxyBypass OPTIONAL,
IN DWORD dwFlags
);
extern "C" HINTERNET __declspec(dllexport) __stdcall WinHttpOpenRequest(
IN HINTERNET hConnect,
IN LPCWSTR pwszVerb,
IN LPCWSTR pwszObjectName,
IN LPCWSTR pwszVersion,
IN LPCWSTR pwszReferrer OPTIONAL,
IN LPCWSTR FAR * ppwszAcceptTypes OPTIONAL,
IN DWORD dwFlags
);
extern "C" BOOL __declspec(dllexport) __stdcall WinHttpSendRequest(
IN HINTERNET hRequest,
IN LPCWSTR pwszHeaders OPTIONAL,
IN DWORD dwHeadersLength,
IN LPVOID lpOptional OPTIONAL,
IN DWORD dwOptionalLength,
IN DWORD dwTotalLength,
IN DWORD_PTR dwContext
);
extern "C" BOOL __declspec(dllexport) __stdcall WinHttpReceiveResponse(
IN HINTERNET hRequest,
IN LPVOID lpReserved
);
extern "C" BOOL __declspec(dllexport) __stdcall WinHttpQueryDataAvailable(
IN HINTERNET hRequest,
OUT LPDWORD lpdwNumberOfBytesAvailable OPTIONAL
);
BOOL m_bUseWinHttp;
extern "C" BOOL CPamTaskBar::GrabWinHttpFile(LPCWSTR strServer,
LPCWSTR strUrl,
CString &strBuffer,
LPCWSTR strAgentName);
};
#define STATE_NULL 0
#define STATE_UNDOCKED 1
#define STATE_RDSERNR 100
#define STATE_READMODE 101
#define STATE_READCAL_FACTOR 102
#define STATE_STATICMODE 103
#define STATE_READEEP 104
#define STATE_READDAYSCORE 105
#define STATE_READMEDSCORE 106
#define STATE_READHEAVYSCORE 107
#define STATE_UPLOADDATA 108
#define STATE_VERIFYCLK 111
#define STATE_READEEPP0 112 // added by E. Damen for AM102
#define STATE_READEEPP1 113 // added by E. Damen for AM102
#define STATE_READEEPP2 114 // added by E. Damen for AM102
#define STATE_READEEPP3 115 // added by E. Damen for AM102
#define STATE_READDAYSCORE102 116 // added by E. Damen for AM102
#define STATE_READMEDSCORE102 117 // added by E. Damen for AM102
#define STATE_READHEAVYSCORE102 118 // added by E. Damen for AM102
#define STATE_READTODAY 119 // added by E. Damen for AM200
#define STATE_SETMODE 120 // added by E. Damen for AM200
#define STATE_SETAUX 121 // added by E. Damen for AM200
#define STATE_READCLK 200
#define STATE_SETCLK 201
#define STATE_TOGGLEMODE 300
#define STATE_DOCKED 800
/////////////////////////////////////////////////////////////////////////////
// Serial and USB communications.
//
bool __stdcall CPamTaskBar::ShowError (LONG lError, LPCTSTR lptszMessage, BOOL bShowPopup)
{
// Generate a message text
m_TrayTip = lptszMessage;
if ( bShowPopup ) {
CString msg;
msg.Format(_T("%s\nError code %d"), lptszMessage, lError);
// Display message-box and return with an error-code
::MessageBox(0, msg, _T(DRIVER_NAME), MB_ICONSTOP|MB_OK);
}
TRACE("ERROR: %s (error code %d)\n", lptszMessage, lError);
return FALSE;
}
#ifdef USE_COM_PORTS
bool __stdcall CPamTaskBar::OpenComPort()
{
LONG lLastError = ERROR_SUCCESS;
CWinApp* pApp = AfxGetApp();
CString ComPort = pApp->GetProfileString(_T(PAM_VERSION), _T(REG_COM_PORT), _T("COM1"));
m_bSkipBreak = TRUE;
// Attempt to open the serial port.
lLastError = m_serial.Open(ComPort, s_hWnd, WM_NULL, (LPARAM)m_nObjectIndex);
if ( lLastError != ERROR_SUCCESS )
return ShowError(m_serial.GetLastError(), _T("Unable to open COM-port"), TRUE);
// Setup no handshaking (DTR high, CTS low).
lLastError = m_serial.SetupHandshaking(CSerial::EHandshakePam);
if ( lLastError != ERROR_SUCCESS )
return ShowError(m_serial.GetLastError(), _T("Unable to set COM-port handshaking"), TRUE);
// Setup the serial port (1200,N81).
lLastError = m_serial.Setup(CSerial::EBaud1200,
CSerial::EData8,
CSerial::EParNone,
CSerial::EStop1);
if ( lLastError != ERROR_SUCCESS )
return ShowError(m_serial.GetLastError(), _T("Unable to set COM-port setting"), TRUE);
// Register only for the receive event
// lLastError = m_serial.SetMask(CSerial::EEventBreak | CSerial::EEventRecv);
lLastError = m_serial.SetMask(CSerial::EEventRecv);
if ( lLastError != ERROR_SUCCESS )
return ShowError(m_serial.GetLastError(), _T("Unable to set COM-port event mask"), TRUE);
// The serial port is now ready and we can send/receive data.
return TRUE;
}
#else
bool __stdcall CPamTaskBar::OpenUSB()
{
DWORD device = 0, dwNumDevices = 0;
SI_STATUS status;
status = SI_GetNumDevices(&dwNumDevices);
if ( status != SI_SUCCESS || dwNumDevices == 0 )
{
return ShowError(status, _T("Undocked"), FALSE);
}
for (device = 0; device < dwNumDevices; device++)
{
SI_DEVICE_STRING devStr;
// status = SI_GetProductString(device, devStr, SI_RETURN_SERIAL_NUMBER);
status = SI_GetProductString(device, devStr, SI_RETURN_VID);
if ( status != SI_SUCCESS || strcmp(devStr, "10c4") != 0 )
{
continue;
}
status = SI_GetProductString(device, devStr, SI_RETURN_PID);
if ( status != SI_SUCCESS || strcmp(devStr, "82b0") != 0 )
{
continue;
}
// We ondersteunen alleen 1 Pam, en nemen dus altijd de eerste die we vinden.
break; // We found one!!!
}
if ( device >= dwNumDevices ) {
// Helaas, er hangen geen Pammetjes aan...
return ShowError(status, _T("Undocked"), FALSE);
}
if ( m_hUSBDevice ) {
// Driver already opened
return TRUE;
}
status = SI_Open(device, &m_hUSBDevice);
if ( status != SI_SUCCESS )
{
return ShowError(status, _T("Error: could not open Pam"), TRUE);
}
// Setup the serial port (2400) for USB. the old Pam used 1200 baud.
status = SI_SetBaudRate(m_hUSBDevice, 2400);
if ( status != SI_SUCCESS )
{
return ShowError(status, _T("Error: Failed to set baud rate"), TRUE);
}
// Setup the serial port (N81).
status = SI_SetLineControl(m_hUSBDevice, 0x0800);
if ( status != SI_SUCCESS )
{
return ShowError(status, _T("Error: Failed to set line control"), TRUE);
}
// Setup no handshaking (DTR high, CTS low).
status = SI_SetFlowControl(m_hUSBDevice,
/*bCTS_MaskCode */ SI_STATUS_INPUT,
/*bRTS_MaskCode */ SI_HELD_INACTIVE,
/*bDTR_MaskCode */ SI_HELD_INACTIVE, // SI_HELD_INACTIVE
/*bDSRMaskCode */ SI_STATUS_INPUT,
/*bDCD_MaskCode */ SI_STATUS_INPUT,
/*bFlowXonXoff */ FALSE);
if ( status != SI_SUCCESS )
{
return ShowError(status, _T("Error: Failed to set flow control"), TRUE);
}
// Maak reads non-blocking. Write time-out seconde
status = SI_SetTimeouts(0, /*DEFAULT_HEARTBEAT * 0.8*/0);
if ( status != SI_SUCCESS )
{
return ShowError(status, _T("Error: Failed to write timeout Pam"), TRUE);
}
status = SI_FlushBuffers(m_hUSBDevice, TRUE, TRUE);
if ( status != SI_SUCCESS )
{
return ShowError(status, _T("Error: Failed to purge Pam"), TRUE);
}
return TRUE;
}
#endif
#ifdef USE_COM_PORTS
bool __stdcall CPamTaskBar::CloseComPort()
{
LONG lLastError = ERROR_SUCCESS;
// Attempt to open the serial port.
lLastError = m_serial.Close();
if ( lLastError != ERROR_SUCCESS )
return ShowError(m_serial.GetLastError(), _T("Unable to close COM-port"), TRUE);
return TRUE;
}
#else
bool __stdcall CPamTaskBar::CloseUSB()
{
if ( m_hUSBDevice )
{
SI_STATUS status = SI_Close(m_hUSBDevice);
if ( status != SI_SUCCESS )
{
return ShowError(status, _T("Error: Failed to close Pam"), FALSE);
}
m_hUSBDevice = 0;
}
return TRUE;
}
#endif
#ifndef USE_COM_PORTS
bool __stdcall CPamTaskBar::PamStillThere()
{
BYTE PartNum;
SI_STATUS status = SI_GetPartNumber (m_hUSBDevice, &PartNum);
return status == SI_SUCCESS;
}
bool __stdcall CPamTaskBar::ReadUSB()
{
bool DataAvailable;
do
{
if ( m_dwEob >= sizeof m_Buffer ) {
m_dwEob = 0; // should not occur, prevent buffer overflow
TRACE("\nERROR: ######################### buffer overflow ########################\n");
}
DWORD dwBytesRead = 0;
SI_STATUS status = SI_Read(m_hUSBDevice, m_Buffer + m_dwEob, sizeof m_Buffer - m_dwEob, &dwBytesRead);
if ( status != SI_SUCCESS )
{
ShowError(status, _T("Error: Failed to read Pam"), TRUE);
return false;
}
if ( 0 /* debugging */ )
{
unsigned int i;
for ( i = 0 ; i < dwBytesRead ; i++ )
TRACE(" [%02x]", m_Buffer[m_dwEob+i]);
}
m_dwEob += dwBytesRead;
DataAvailable = (m_dwEob == sizeof m_Buffer);
while ( ProcessMessage() ) {};
}
while ( DataAvailable );
return true;
}
#endif
bool __stdcall CPamTaskBar::SendCommand(struct Message *message, BOOL bReading)
{
#ifdef USE_COM_PORTS
long lLastError = m_serial.Write(message->data, message->size);
if ( lLastError != ERROR_SUCCESS ) {
return ShowError(m_serial.GetLastError(), _T("Unable to send data"), TRUE);
}
#else
DWORD written;
// Voorlopig een blocking write. Misschien later asynchroon.
SI_STATUS status = SI_Write(m_hUSBDevice, message->data, message->size, &written);
if ( status != SI_SUCCESS )
{
return ShowError(status, _T("Error: Failed to write to Pam"), TRUE);
}
#endif
CString msg(bReading ? _T("Reading ") : _T("Updating "));
msg += PAM_NAME;
NotifyUser(msg, TRUE, FALSE);
return TRUE;
}
bool __stdcall CPamTaskBar::PamGetTime()
{
CWinApp* pApp = AfxGetApp();
#ifdef USE_COM_PORTS
bool sync_clock = pApp->GetProfileInt(_T(PAM_VERSION), _T(REG_SYNC_CLOCK), 1) != 0;
#else
bool sync_clock = TRUE;
#endif
if ( sync_clock && m_State != STATE_VERIFYCLK )
{
m_Time = CTime::GetCurrentTime();
if ( m_State == STATE_READCLK ) {
m_State = STATE_SETCLK;
TRACE("STATE: SETCLK\n");
}
return true;
}
else
{
struct Message message;
if ( ! MakeGetClockMessage(&message) )
{
return ShowError(0, _T("Unable to get time"), TRUE);
}
return SendCommand(&message, TRUE);
}
}
bool __stdcall CPamTaskBar::PamSetTime()
{
CWinApp* pApp = AfxGetApp();
// Load the clock setting from the registry.
#ifdef USE_COM_PORTS
int nClock = pApp->GetProfileInt(_T(PAM_VERSION), _T(REG_CLOCK_MODE), 0);
#else
int nClock = m_bMilitary ? 0 : 1;
#endif
struct Message message;
m_Time = CTime::GetCurrentTime(); // Voorheen werd dit gedaan in PamGetTime(). Dit wordt niet meer gebruikt.
if ( ! MakeSetClockMessage(&message, m_Time.GetHour(), m_Time.GetMinute(), nClock == 0) )
{
return ShowError(0, _T("Unable to set time"), TRUE);
}
return SendCommand(&message, FALSE);
}
bool __stdcall CPamTaskBar::PamReadMode()
{
struct Message message;
if ( ! MakeReadModeMessage(&message) )
{
return ShowError(0, _T("Unable to read mode"), TRUE);
}
return SendCommand(&message, TRUE);
}
bool __stdcall CPamTaskBar::PamSetMode(BYTE mode, BYTE key_return) // added by E. Damen for AM200
{
struct Message message;
if ( ! MakeSetModeMessage(&message, mode, key_return) )
{
return ShowError(0, _T("Unable to set mode"), TRUE);
}
return SendCommand(&message, TRUE);
}
bool __stdcall CPamTaskBar::PamSetAux(BYTE CalorieperPam) // added by E. Damen for AM200
{
struct Message message;
if ( ! MakeSetAuxMessage(&message, CalorieperPam) )
{
return ShowError(0, _T("Unable to set Calorie per Pam unit"), TRUE);
}
return SendCommand(&message, TRUE);
}
/* bool CPamTaskBar::PamStaticMode()
{
struct Message message;
CWinApp* pApp = AfxGetApp();
if ( ! MakeSetModeMessage(&message, m_PamMode | BIT_MODE_INTEGRATOR) )
{
return ShowError(0, _T("Unable to set static mode"), TRUE);
}
return SendCommand(&message, TRUE);
}
bool CPamTaskBar::PamReadDockingDate()
{
struct Message message;
if ( ! MakeReadDockingDateMessage(&message) )
{
return ShowError(0, _T("Unable to read docking date"), TRUE);
}
return SendCommand(&message, TRUE);
}
bool CPamTaskBar::PamToggleMode()
{
struct Message message;
CWinApp* pApp = AfxGetApp();
if ( ! MakeSetModeMessage(&message, m_PamMode ^ BIT_MODE_PAM_MODE) )
{
return ShowError(0, _T("Unable to set mode"), TRUE);
}
return SendCommand(&message, TRUE);
}
*/
bool __stdcall CPamTaskBar::PamReadToday()
{
struct Message message;
if ( ! MakeReadTodayMessage(&message) )
{
return ShowError(0, _T("Unable to read today"), TRUE);
}
return SendCommand(&message, TRUE);
}
bool __stdcall CPamTaskBar::PamReadEepromPage0(BYTE key_return) // added by E. Damen for AM102
{
struct Message message;
if ( ! MakeReadEepromPage0Message(&message, key_return) )
{
return ShowError(0, _T("Unable to read eeprom"), TRUE);
}
return SendCommand(&message, TRUE);
}
bool __stdcall CPamTaskBar::PamReadEepromPage1(BYTE key_return) // added by E. Damen for AM102
{
struct Message message;
if ( ! MakeReadEepromPage1Message(&message, key_return) )
{
return ShowError(0, _T("Unable to read eeprom"), TRUE);
}
return SendCommand(&message, TRUE);
}
bool __stdcall CPamTaskBar::PamReadEepromPage2(BYTE key_return) // added by E. Damen for AM102
{
struct Message message;
if ( ! MakeReadEepromPage2Message(&message, key_return) )
{
return ShowError(0, _T("Unable to read eeprom"), TRUE);
}
return SendCommand(&message, TRUE);
}
bool __stdcall CPamTaskBar::PamReadEepromPage3(BYTE key_return) // added by E. Damen for AM102
{
struct Message message;
if ( ! MakeReadEepromPage3Message(&message, key_return) )
{
return ShowError(0, _T("Unable to read eeprom"), TRUE);
}
return SendCommand(&message, TRUE);
}
bool __stdcall CPamTaskBar::PamReadCalibrationFactor()
{
struct Message message;
if ( ! MakeReadCalibrationFactorMessage(&message) )
{
return ShowError(0, _T("Unable to read calibration factor"), TRUE);
}
return SendCommand(&message, TRUE);
}
bool __stdcall CPamTaskBar::PamReadSerialNumber()
{
struct Message message;
if ( ! MakeReadSerialNumberMessage(&message) )
{
return ShowError(0, _T("Unable to read serial number"), TRUE);
}
return SendCommand(&message, TRUE);
}
bool __stdcall CPamTaskBar::PamReadRam(UINT address)
{
struct Message message;
if ( ! MakeReadRamMessage(&message, address) )
{
return ShowError(0, _T("Unable to read ram"), TRUE);
}
return SendCommand(&message, TRUE);
}
CString GetValueByKey(CString strBuffer, CString strKeyword)
{
strKeyword += ": ";
int pos = strBuffer.Find(strKeyword);
if ( pos != -1 )
{
return strBuffer.Mid(pos + strKeyword.GetLength()).SpanExcluding("\n\r");
}
else
{
return "";
}
}
BOOL __stdcall CPamTaskBar::GrabWinHttpFile(LPCWSTR strServer,
LPCWSTR strUrl,
CString &strBuffer,
LPCWSTR strAgentName)
{
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;
BOOL bResults = FALSE;
HINTERNET hSession = NULL,
hConnect = NULL,
hRequest = NULL;
hSession = CPamTaskBar::WinHttpOpen( strAgentName,
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS,
0 /*synchrone*/ );
// Specify an HTTP server.
if ( hSession )
hConnect = CPamTaskBar::WinHttpConnect( hSession,
strServer,
INTERNET_DEFAULT_HTTP_PORT, 0 );
// Create an HTTP request handle.
if( hConnect )
hRequest = CPamTaskBar::WinHttpOpenRequest( hConnect, L"GET",
strUrl,
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
WINHTTP_FLAG_REFRESH );
// Send a request.
if( hRequest ) {
bResults = CPamTaskBar::WinHttpSendRequest( hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS, 0,
WINHTTP_NO_REQUEST_DATA, 0, /* voor een post*/
0, 0 );
}
// End the request.
if( bResults )
bResults = CPamTaskBar::WinHttpReceiveResponse( hRequest, NULL );
// Keep checking for data until there is nothing left.
if( bResults )
{
do
{
// Check for available data.
dwSize = 0;
bResults = CPamTaskBar::WinHttpQueryDataAvailable( hRequest, &dwSize );
if( ! bResults )
TRACE( "Error %u in WinHttpQueryDataAvailable.\n",
GetLastError( ) );
// Allocate space for the buffer.
pszOutBuffer = new char[dwSize+1];
if( !pszOutBuffer )
{
TRACE( "Out of memory\n" );
bResults = FALSE;
}
else
{
// Read the data.
ZeroMemory( pszOutBuffer, dwSize+1 );
if( !CPamTaskBar::WinHttpReadData( hRequest, (LPVOID)pszOutBuffer,
dwSize, &dwDownloaded ) ) {
TRACE( "Error %u in WinHttpReadData.\n", GetLastError( ) );
bResults = FALSE;
}
else {
strBuffer += pszOutBuffer;
}
// Free the memory allocated to the buffer.
delete [] pszOutBuffer;
}
} while( dwSize > 0 && bResults );
}
if ( ! bResults ) {
TRACE( "Error %u in GrabWinHttpFile.\n",
GetLastError( ) );
}
return bResults;
}
bool __stdcall CPamTaskBar::PamUploadData()
{
CWinApp* pApp = AfxGetApp();
NotifyUser(_T("Uploading data"), TRUE, FALSE);
// Build the upload URL and add all Pam data to it.
CString strServerUrl;
strServerUrl.Format(_T(UPLOAD_PAGE "?software=%u&firmware=%u&sn=%u&days=%d&tz=%d&config=%u&ds=%u&living=%u&health=%u&sports=%u&distance=%u&fruit=%u"),
(VERSION_MAJOR << 8) | VERSION_MINOR,
(m_VersionNumber.Major << 16) |
(m_VersionNumber.Minor << 8) |
(m_VersionNumber.Build << 0),
m_SerialNumber,
m_Size,
/*_timezone*/ _get_timezone,
m_Config,
m_PamDayScore16,
m_PamLowScore,
m_PamMedScore,
m_PamHighScore,
m_PamDistanceTD,
m_PamFruitTD
);
// strServerUrl += "&eep=";
// The rest of the routine is written by E. Damen for AM102.
// Because a URL has a maximum length of 2023 bytes and the numbers of days in AM102
// in scientific mode is 4 times larger, data has to be compressed to fit in the URL
for ( UINT day = 0 ; day < m_Size ; day++ )
{
CString strData;
// long int code = m_Pam[day] *16777216;
// code += m_LightActivity[day]*65536;
// code += m_MediumActivity[day]*256;
// code += m_HeavyActivity[day];
strData.Format(_T("&q[]=%06x%08x"), m_code2[day],m_code1[day]);
strServerUrl += strData;
}
// m_State = STATE_READCLK;
// TRACE("STATE: READCLK\n");
m_State = STATE_SETMODE;
TRACE("STATE: SETMODE\n");
// if ( ::MessageBox(0, msg, _T("Pam mode"), MB_OKCANCEL|MB_ICONWARNING) != IDOK )
CString message;
do
{
INT_PTR rc = 0;
CURL url;
#ifdef USE_ONE_WAY_COM
rc = url.Open(_T("http://" + SITE_SERVER + strServerUrl, false);
#else
// Connect to the upload server and expect the redirection URL back.
CString strBuffer;
BOOL bUploadedData;
if ( !m_bUseWinHttp )
{
bUploadedData = GrabWinHttpFile(CT2CW(SITE_SERVER),
CT2CW( (LPCTSTR) strServerUrl),
strBuffer,
CT2CW(PAM_NAME " " PAM_VERSION));
}
else
{
bUploadedData = GrabWininetFile(_T("http://" SITE_SERVER) + strServerUrl,
strBuffer,
_T(PAM_NAME " " PAM_VERSION));
}
if ( bUploadedData )
{
// Parseer het van de server verkregen resultaat. Ondermeer de URL die we moeten tonen.
CString strKeyword;
strKeyword = GetValueByKey(strBuffer, "Calorie");
m_CalorieperPam = atoi(strKeyword);
strKeyword = GetValueByKey(strBuffer, "MilitaryClock");
m_bMilitary = atoi(strKeyword);
strKeyword = GetValueByKey(strBuffer, "Paid");
m_UpdateDockDay = atoi(strKeyword);
strKeyword = GetValueByKey(strBuffer, "Location");
if ( strKeyword != "" ) {
TRACE("INFO: launching %s\n", strKeyword);
//strKeyword = "url:" + strKeyword;
//::ShellExecute(NULL, NULL, strKeyword, NULL, NULL, SW_SHOWNORMAL);
rc = url.Open(strKeyword, false);
// if ( m_State == STATE_UPLOADINGDATA ) {
// m_State = STATE_READCLK;
// TRACE("STATE: READCLK\n");
// }
// } else if ( m_State == STATE_UPLOADINGDATA ) {
// m_State = STATE_READCLK;
// TRACE("STATE: READCLK\n");
}
}
#endif
if ( rc > 32 ) break; // No error, continue.
message.Format(_T("Could not connect to the %s web site.\n\nMake sure that you have a working internet connection. In case you installed a firewall, make sure it allows the %s to access the internet.\n(error code %d)"),
PAM_NAME,
DRIVER_NAME,
rc);
}
while ( ::MessageBox(0, message, _T(DRIVER_NAME), MB_ICONWARNING|MB_RETRYCANCEL) == IDRETRY);
// Added by E. Damen for AM200: information comes back from server: 1) paid or not paid
// 2) Calories per Pam unit
// if paid then m_UpdateDockDay = 1 else m_UpdateDockDay=0
// Calories per Pam unit should be stored in m_CalorieperPam
m_PamMode = (m_PamMode & 0xFE) + m_UpdateDockDay; // Added by E. Damen for AM200
return true;
}
void __stdcall CPamTaskBar::StartHeartbeat()
{
CWinApp* pApp = AfxGetApp();
#ifdef USE_COM_PORTS
m_Heartbeat = pApp->GetProfileInt(_T(PAM_VERSION), _T(REG_HEARTBEAT), DEFAULT_HEARTBEAT);
#else
m_Heartbeat = DEFAULT_HEARTBEAT;
#endif
SetTimer(s_hWnd, // hWnd of the Taskbar Applet
1, // Timer identifier
m_Heartbeat, // Timeout value in order to give the PAM time to process
(TIMERPROC)m_nObjectIndex); // identifier of the taskbar instance
TRACE("INFO: timer started (%u ms)\n", m_Heartbeat);
}
bool __stdcall CPamTaskBar::InitInstance(LPSTR lpCmdLine)
{
_tzset(); // Sets time environment variables.
// http://groups.google.com/groups?q=CWnd::FindWindow&hl=nl&lr=&ie=UTF-8&selm=34353492.1572921%40msnews.microsoft.com&rnum=1
// http://groups.google.com/groups?q=CWnd::FindWindow&hl=nl&lr=&ie=UTF-8&selm=8psnq1%24oco%241%40fe1.cs.interbusiness.it&rnum=10
HANDLE hMutex = CreateMutex(NULL, FALSE, _T("MutexToEnforceSinglePamDriver"));
if ( GetLastError() == ERROR_ALREADY_EXISTS )
{
return FALSE; // Leave quietly the application
}
m_DiscardInput = FALSE;
/*
CWinApp* pApp = AfxGetApp();
pApp->SetRegistryKey(COMPANY_NAME);
*/
m_TrayTip = _T(DRIVER_NAME);
m_SerialNumber = m_Config = 0;
m_pProgressDlg = NULL;
m_State = STATE_NULL;
TRACE("STATE: NULL\n");
m_bSkipBreak = TRUE;
#ifdef USE_COM_PORTS
if ( OpenComPort() ) {
m_State = STATE_UNDOCKED;
m_SerialNumber = m_Config = 0;
TRACE("STATE: UNDOCKED\n");
}
#endif
// Bepaal of we WinHTTP kunnen gebruiken
/*
SystemInfo sysInfo;
if ( sysInfo.GetMajorVersion() < 5 ) {
// Windows ME en ouder ondersteunen geen WinHttp
m_bUseWinHttp = FALSE;
} else {
switch ( sysInfo.GetMinorVersion() ) {
case 0: // Windows 2000, SP 3 ondersteunt WinHttp
m_bUseWinHttp = sysInfo.GetServicePackMajor() >= 3;
break;
case 1: // Windows XP, SP 1 ondersteunt WinHttp
m_bUseWinHttp = sysInfo.GetServicePackMajor() >= 1;
break;
default: // Nieuwere OSsen
m_bUseWinHttp = TRUE;
break;
}
}
*/
// Nu gaan we proberen om de WinHttp.dll dynamisch te laden. Als dat lukt:
// - zetten we m_bUseWinHttp op TRUE;
// - halen we de adressen op van de WinHttp functies.
HINSTANCE hHandle;
hHandle = ::LoadLibrary("WINHTTP.DLL");
if ( hHandle != NULL ) {
FWinHttpReadData = (TFWinHttpReadData)::GetProcAddress(hHandle, _T("WinHttpReadData"));
FWinHttpConnect = (TFWinHttpConnect)::GetProcAddress(hHandle, _T("WinHttpConnect"));
FWinHttpOpen = (TFWinHttpOpen)::GetProcAddress(hHandle, _T("WinHttpOpen"));
FWinHttpOpenRequest = (TFWinHttpOpenRequest)::GetProcAddress(hHandle, _T("WinHttpOpenRequest"));
FWinHttpSendRequest = (TFWinHttpSendRequest)::GetProcAddress(hHandle, _T("WinHttpSendRequest"));
FWinHttpReceiveResponse = (TFWinHttpReceiveResponse)::GetProcAddress(hHandle, _T("WinHttpReceiveResponse"));
FWinHttpQueryDataAvailable = (TFWinHttpQueryDataAvailable)::GetProcAddress(hHandle, _T("WinHttpQueryDataAvailable"));
}
m_bUseWinHttp = hHandle != NULL &&
FWinHttpReadData != NULL &&
FWinHttpConnect != NULL &&
FWinHttpOpen != NULL &&
FWinHttpOpenRequest != NULL &&
FWinHttpSendRequest != NULL &&
FWinHttpReceiveResponse != NULL &&
FWinHttpQueryDataAvailable != NULL;
ASSERT(s_hWnd != NULL);
StartHeartbeat();
return TRUE;
}
BOOL __stdcall CPamTaskBar::WinHttpReadData
(
IN HINTERNET hRequest,
IN LPVOID lpBuffer,
IN DWORD dwNumberOfBytesToRead,
OUT LPDWORD lpdwNumberOfBytesRead
)
{
ASSERT(FWinHttpReadData != NULL);
if (FWinHttpReadData)
return FWinHttpReadData(hRequest,lpBuffer,dwNumberOfBytesToRead,lpdwNumberOfBytesRead);
return FALSE;
}
HINTERNET __stdcall CPamTaskBar::WinHttpConnect
(
IN HINTERNET hSession,
IN LPCWSTR pswzServerName,
IN INTERNET_PORT nServerPort,
IN DWORD dwReserved
)
{
ASSERT(FWinHttpConnect != NULL);
if (FWinHttpConnect)
return FWinHttpConnect(hSession,pswzServerName,nServerPort,dwReserved);
return FALSE;
}
HINTERNET __stdcall CPamTaskBar::WinHttpOpen(
IN LPCWSTR pwszUserAgent,
IN DWORD dwAccessType,
IN LPCWSTR pwszProxyName OPTIONAL,
IN LPCWSTR pwszProxyBypass OPTIONAL,
IN DWORD dwFlags
)
{
ASSERT(FWinHttpOpen != NULL);
if (FWinHttpOpen)
return FWinHttpOpen(pwszUserAgent,dwAccessType,pwszProxyName,pwszProxyBypass,dwFlags);
return FALSE;
}
HINTERNET __stdcall CPamTaskBar::WinHttpOpenRequest(
IN HINTERNET hConnect,
IN LPCWSTR pwszVerb,
IN LPCWSTR pwszObjectName,
IN LPCWSTR pwszVersion,
IN LPCWSTR pwszReferrer OPTIONAL,
IN LPCWSTR FAR * ppwszAcceptTypes OPTIONAL,
IN DWORD dwFlags
)
{
ASSERT(FWinHttpOpenRequest != NULL);
if (FWinHttpOpenRequest)
return FWinHttpOpenRequest(hConnect,pwszVerb,pwszObjectName,pwszVersion,pwszReferrer,ppwszAcceptTypes,dwFlags);
return FALSE;
}
BOOL __stdcall CPamTaskBar::WinHttpSendRequest(
IN HINTERNET hRequest,
IN LPCWSTR pwszHeaders OPTIONAL,
IN DWORD dwHeadersLength,
IN LPVOID lpOptional OPTIONAL,
IN DWORD dwOptionalLength,
IN DWORD dwTotalLength,
IN DWORD_PTR dwContext
)
{
ASSERT(FWinHttpSendRequest != NULL);
if (FWinHttpSendRequest)
return FWinHttpSendRequest(hRequest,pwszHeaders,dwHeadersLength,lpOptional,dwOptionalLength,dwTotalLength,dwContext);
return FALSE;
}
BOOL __stdcall CPamTaskBar::WinHttpReceiveResponse(
IN HINTERNET hRequest,
IN LPVOID lpReserved
){
ASSERT(FWinHttpReceiveResponse != NULL);
if (FWinHttpReceiveResponse)
return FWinHttpReceiveResponse(hRequest,lpReserved);
return FALSE;
}
BOOL __stdcall CPamTaskBar::WinHttpQueryDataAvailable(
IN HINTERNET hRequest,
OUT LPDWORD lpdwNumberOfBytesAvailable OPTIONAL
)
{
ASSERT(FWinHttpQueryDataAvailable != NULL);
if (FWinHttpQueryDataAvailable)
return FWinHttpQueryDataAvailable(hRequest,lpdwNumberOfBytesAvailable);
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// Instantiate the CPamTaskBar applet.
//
CPamTaskBar theApplet;
/////////////////////////////////////////////////////////////////////////////
// Define the methods of CPamTaskBar.
//
void __stdcall CPamTaskBar::OnTimerMessage(WPARAM wParam)
{
m_DiscardInput = FALSE; /* Start from scratch */
TRACE("heartbeat: counter=%d\n", m_TimeOut);
#ifndef USE_COM_PORTS
if ( m_State == STATE_NULL ) {
if ( OpenUSB() ) {
NotifyUser(_T("Pam found"), FALSE, TRUE);
m_PamMode = -1;
m_State = STATE_UNDOCKED;
TRACE("STATE: UNDOCKED\n");
}
} else if ( m_State == STATE_DOCKED ) {
// Kijk of de Pam er nog steeds aanhangt
if ( ! PamStillThere() ) {
CloseUSB();
m_State = STATE_NULL;
TRACE("STATE: NULL\n");
NotifyUser(_T("Undocked"), FALSE, TRUE);
}
} else {
// Kijk of er iets op te halen is. Vanwege de heartbeat, mag deze polling.
if ( ReadUSB() ) {
m_TimeOut = BREAK_RETRY * 1000 / m_Heartbeat + 1; // always round up
}
}
#endif
switch ( m_State )
{
case STATE_UNDOCKED:
// Hier mogen we eigenlijk niet meer komen met de USB variant...
m_TimeOut = MSG_RETRY; /* Start counting from now. */
m_State = STATE_RDSERNR;
TRACE("STATE: RDSERNR\n");
// Fall through
case STATE_RDSERNR:
PamReadSerialNumber();
break;
// case STATE_READMODE:
// PamReadMode();
// break;
// case STATE_STATICMODE:
// PamStaticMode();
// break;
// case STATE_READCAL_FACTOR:
// PamReadCalibrationFactor();
// break;
// case STATE_READEEP:
// PamReadEeprom();
// break;
case STATE_READEEPP0: // added by E. Damen for AM102
PamReadEepromPage0(m_Key_return);
break;
case STATE_READEEPP1: // added by E. Damen for AM102
PamReadEepromPage1(m_Key_return);
break;
case STATE_READEEPP2: // added by E. Damen for AM102
PamReadEepromPage2(m_Key_return);
break;
case STATE_READEEPP3: // added by E. Damen for AM102
PamReadEepromPage3(m_Key_return);
break;
case STATE_UPLOADDATA:
PamUploadData();
break;
// case STATE_READDAYSCORE:
// PamReadRam(RAM_DAYSCORE);
// break;
// case STATE_READMEDSCORE:
// PamReadRam(RAM_MEDSCORE);
// break;
// case STATE_READHEAVYSCORE:
// PamReadRam(RAM_HEAVYSCORE);
// break;
// case STATE_READDAYSCORE102: // added by E. Damen for AM102
// PamReadRam(RAM_DAYSCORE102);
// break;
// case STATE_READMEDSCORE102: // added by E. Damen for AM102
// PamReadRam(RAM_MEDSCORE102);
// break;
// case STATE_READHEAVYSCORE102: // added by E. Damen for AM102
// PamReadRam(RAM_HEAVYSCORE102);
// break;
case STATE_READTODAY: // added for AM200
PamReadToday();
break;
// case STATE_TOGGLEMODE:
// PamToggleMode();
// break;
case STATE_SETMODE: // added for AM200 to set UpdateDockDay
PamSetMode(m_PamMode, m_Key_return);
break;
case STATE_SETAUX: // added for AM200 to set Calories per Pam unit
PamSetAux(m_CalorieperPam);
break;
case STATE_VERIFYCLK:
case STATE_READCLK:
PamGetTime();
break;
case STATE_SETCLK:
PamSetTime();
break;
}
/* Check the time out. */
if ( m_State != STATE_NULL &&
m_State != STATE_UNDOCKED &&
m_State != STATE_DOCKED &&
m_TimeOut-- == 0 )
{
// We didn't get an event on time. Reset state to undocked.
if ( m_State == STATE_DOCKED )
{
NotifyUser(_T("Undocked"), FALSE, TRUE);
}
else
{
CString msg(_T("Could not synchronize " PAM_NAME "..."));
NotifyUser(msg, FALSE, TRUE);
}
m_State = STATE_UNDOCKED;
m_SerialNumber = m_Config = 0;
TRACE("STATE: UNDOCKED\n");
}
}
void __stdcall CPamTaskBar::NotifyUser(CString strMsg, BOOL bShow, BOOL bReset)
{
if ( m_pProgressDlg == NULL )
{
m_pProgressDlg = new ProgressDlg;
m_pProgressDlg->Create(IDD_PROGRESS);
m_pProgressDlg->m_ctlProgressBar.SetRange(0,12);
m_pProgressDlg->m_ctlProgressBar.SetStep(1);
m_pProgressDlg->m_ctlProgressBar.SetPos(0);
m_pProgressDlg->SetIcon(LoadIcon(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_ICONBIG)), TRUE);
m_pProgressDlg->m_bDismissed = FALSE;
}
if ( m_pProgressDlg != NULL )
{
m_pProgressDlg->m_strProgress = strMsg;
m_pProgressDlg->UpdateData(FALSE);
m_pProgressDlg->SetWindowText(strMsg);
if ( bReset )
{
m_pProgressDlg->m_ctlProgressBar.SetPos(0);
m_pProgressDlg->m_bDismissed = FALSE;
}
else
{
m_pProgressDlg->m_ctlProgressBar.StepIt();
}
if ( ! m_pProgressDlg->m_bDismissed )
{
m_pProgressDlg->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
}
}
m_TrayTip = strMsg;
UpdateShellInfo();
}
void __stdcall CPamTaskBar::ProcessBreak()
{
if ( m_State == STATE_UNDOCKED )
{
if ( m_bSkipBreak ) {
m_bSkipCounter += 1;
if (m_bSkipCounter == 2) {
m_bSkipBreak = FALSE;}
} else {
// m_dwEob = 0; /* Flush the message buffer. */
m_TimeOut = MSG_RETRY; /* Start counting from now. */
m_State = STATE_RDSERNR; // Always first determine Pam version!
TRACE("STATE: RDSERNR\n");
}
}
else if ( m_State == STATE_DOCKED )
{
m_TimeOut = BREAK_RETRY * 1000 / m_Heartbeat + 1; // always round up
}
}
void __stdcall CPamTaskBar::OnSerialMessage(WPARAM wParam)
// Deze functie wordt aangeroepen indien er seriele communicatie binnenkomt.
// In geval van een USB device, wordt dit niet gebruikt.
{
# ifdef USE_COM_PORTS
const CSerialWnd::EEvent eEvent = CSerialWnd::EEvent(LOWORD(wParam));
const CSerialWnd::EError eError = CSerialWnd::EError(HIWORD(wParam));
if ( eEvent & CSerialWnd::EEventBreak ) {
TRACE("\nRECEIVE: hardware break\n");
}
if ( eEvent & CSerialWnd::EEventRecv ) {
bool DataAvailable;
do
{
// Read data from the COM-port
DWORD dwBytesRead = 0;
if ( m_dwEob >= sizeof m_Buffer ) {
m_dwEob = 0; // should not occur, prevent buffer overflow
TRACE("\nERROR: ######################### buffer overflow ########################\n");
}
long lLastError = m_serial.Read(m_Buffer + m_dwEob,
sizeof m_Buffer - m_dwEob,
&dwBytesRead);
if ( FALSE /* debugging */ )
{
unsigned int i;
for ( i = 0 ; i < dwBytesRead ; i++ )
TRACE(" [%02x]", m_Buffer[m_dwEob+i]);
}
m_dwEob += dwBytesRead;
if ( lLastError != ERROR_SUCCESS )
{
ShowError(m_serial.GetLastError(), _T("Unable to read from COM-port."), TRUE);
return;
}
DataAvailable = (m_dwEob == sizeof m_Buffer);
while ( ProcessMessage() ) {};
}
while ( DataAvailable );
}
if ( eEvent & CSerialWnd::EEventError ) {
switch ( eError )
{
case CSerial::EErrorBreak: TRACE("\nERROR: serial break condition\n"); break;
case CSerial::EErrorFrame: TRACE("\nERROR: serial framing error\n"); break;
case CSerial::EErrorIOE: TRACE("\nERROR: serial IO device error\n"); break;
case CSerial::EErrorMode: TRACE("\nERROR: serial unsupported mode\n"); break;
case CSerial::EErrorOverrun: TRACE("\nERROR: serial buffer overrun\n"); break;
case CSerial::EErrorRxOver: TRACE("\nERROR: serial input buffer overflow\n"); break;
case CSerial::EErrorParity: TRACE("\nERROR: serial input parity error\n"); break;
case CSerial::EErrorTxFull: TRACE("\nERROR: serial output buffer full\n"); break;
default: TRACE("\nERROR: serial %d\n", eError); break;
}
}
#endif
}
BOOL __stdcall CPamTaskBar::ProcessMessage()
{
if ( m_DiscardInput ) {
if ( m_dwEob > 0 ) {
TRACE("\nERROR: %d bytes dropped\n", m_dwEob);
}
m_dwEob = 0;
return false;
}
while ( m_dwEob > 0 && m_Buffer[0] == 0x00 )
{
memmove(m_Buffer + 1, m_Buffer, --m_dwEob);
TRACE("\nRECEIVE: software break\n");
ProcessBreak();
}
if ( m_dwEob < 5 ) {
return false; // Partial (or empty) message, wait for more.
}
BYTE Length = m_Buffer[2];
BYTE Command = m_Buffer[1];
BYTE Checksum = 0;
if ( m_Buffer[0] != PAM_STX ) {
TRACE("\nERROR: ##################### STX missing (0x%02x) #####################\n", PAM_STX);
m_DiscardInput = TRUE;
return true;
}
if ( Length > 170 || Length < 5 ) {
TRACE("##################### bad length (%d) #######################", Length);
m_DiscardInput = TRUE;
return true;
}
if ( m_dwEob < Length ) {
return false; // Partial message, wait for more.
}
TRACE("[");
{
unsigned int i;
for ( i = 0 ; i < m_dwEob ; i++ )
TRACE("%02x", m_Buffer[i]);
}
TRACE("] ");
for ( int i = 0 ; i < Length - 2 ; i++ ) {
Checksum += m_Buffer[i];
}
if ( m_Buffer[Length - 2] != Checksum ) {
if ( m_VersionNumber.Major == 0 &&
m_VersionNumber.Minor == 1 &&
(Command == ACK_READCLK || Command == ACK_READMODE) ) {
// Work around Pam bug: ignore checksum failure
} else if ( m_VersionNumber.Major == 0 &&
m_VersionNumber.Minor == 2 &&
Command == ACK_READEEP ) {
// Work around a new Pam bug: ignore checksum failure
} else {
TRACE("\nERROR: ##################### Checksum failure ##################### \n");
m_DiscardInput = TRUE;
return true;
}
}
if ( m_Buffer[Length - 1] != PAM_EOT ) {
TRACE("\nERROR: ##################### EOT missing (0x%0x) #####################\n", m_Buffer[Length - 1]);
if ( (m_VersionNumber.Major == 1 && m_VersionNumber.Minor == 0) ||
(m_VersionNumber.Major == 0) ) {
if ( Command == ACK_READEEP ) {
// Work around a new Pam bug: reset timer on checksum failure
m_TimeOut = MSG_RETRY; /* Start counting from now. */
}
}
m_DiscardInput = TRUE;
return true;
}
// Now we have a properly formatted message layout. So reset the passed-out counter.
m_TimeOut = MSG_RETRY;
switch ( Command ) {
case NACK:
// Negative acknowledgment, ignore it. Our app will retry in a second.
TRACE("\nRECEIVE: NACK\n");
break;
/*
case ACK_READRAM:
switch ( (m_Buffer[3] << 8) | m_Buffer[4] ) {
case RAM_DAYSCORE:
{
m_PamDayScore16 = m_Buffer[5];
TRACE("\nRECEIVE: ack READDAYSCORE: %u\n", m_PamDayScore16);
m_State = STATE_READMEDSCORE;
TRACE("STATE: READMEDSCORE\n");
break;
}
case RAM_MEDSCORE:
{
m_PamMedScore = (m_Buffer[6] << 8) | m_Buffer[5];
TRACE("\nRECEIVE: ack READMEDSCORE: %u\n", m_PamMedScore);
m_State = STATE_READHEAVYSCORE;
TRACE("STATE: READHEAVYSCORE\n");
break;
}
case RAM_HEAVYSCORE: // changed by E. Damen for AM102
{
if (m_VersionNumber.Major == 1 && m_VersionNumber.Minor < 3)
{
m_PamHighScore = (m_Buffer[6] << 8) | m_Buffer[5];
} else
{
m_PamHighScore = (m_Buffer[6] & 0xF0 << 4) | (m_Buffer[5] & 0x0F << 4) | (m_Buffer[5] & 0xF0 >> 4);
}
TRACE("\nRECEIVE: ack READHEAVYSCORE: %u\n", m_PamHighScore);
m_State = STATE_UPLOADDATA;
TRACE("STATE: UPLOADDATA\n");
break;
}
case RAM_DAYSCORE102: // added by E. Damen for AM102
{
m_PamDayScore16 = m_Buffer[5];
TRACE("\nRECEIVE: ack READDAYSCORE: %u\n", m_PamDayScore16);
m_State = STATE_READMEDSCORE102;
TRACE("STATE: READMEDSCORE102\n");
break;
}
case RAM_MEDSCORE102: // added by E. Damen for AM102
{
m_PamMedScore = (m_Buffer[6] & 0xF0 << 4) | (m_Buffer[5] & 0x0F << 4) | (m_Buffer[5] & 0xF0 >> 4);
TRACE("\nRECEIVE: ack READMEDSCORE: %u\n", m_PamMedScore);
m_State = STATE_READHEAVYSCORE102;
TRACE("STATE: READHEAVYSCORE102\n");
break;
}
default:
{
TRACE("\nRECEIVE: ack READRAM unexpected address: 0x%04x\n",
(m_Buffer[3] << 8) | m_Buffer[4]);
break;
}
}
break;
*/
case ACK_RDSERNR: // Erik Damen: changed for AM200
// m_Buffer contains unsigned values, so shifting is safe.
// MSB and LSB swapped according to new specs
m_SerialNumber = m_Buffer[6] | (m_Buffer[5] << 8) | (m_Buffer[4] << 16) | (m_Buffer[3] << 24);
m_VersionNumber.Major = m_Buffer[7];
m_VersionNumber.Minor = m_Buffer[8];
m_VersionNumber.Build = m_Buffer[9];
m_Key = m_Buffer[10] ;
m_Key_return = m_Key ^ 0xAA ; // key encryption for AM200 secured commands (^ means XOR)
TRACE("\nRECEIVE: ack RDSERNR 0x%08x, version %d.%d.%d, key %d\n",
m_SerialNumber,
m_VersionNumber.Major, m_VersionNumber.Minor, m_VersionNumber.Build, m_Key);
if ( m_State == STATE_RDSERNR ) {
m_State = STATE_READEEPP0; // Erik Damen: changed state machine
TRACE("STATE: READEEPP0\n");
}
break;
case ACK_READTODAY: // Erik Damen: added for AM200
m_PamDayScore16 = m_Buffer[3] + ((m_Buffer[4]&0x1F)<<8);
m_PamLowScore = ((m_Buffer[4]&0xE0)>>5) + (m_Buffer[5]<<3);
m_PamMedScore = m_Buffer[6] + ((m_Buffer[7]&0x03)<<8);
m_PamHighScore = ((m_Buffer[7]&0xFC)>>2) + ((m_Buffer[8]&0x03)<<6);
m_PamDistanceTD = ((m_Buffer[8]&0xFC)>>2) + ((m_Buffer[9]&0x0F)<<6);
m_PamFruitTD = ((m_Buffer[9]&0xF0)>>4);
TRACE("\nRECEIVE: ack READTODAY %d\n",
m_PamDayScore16 >> 4);
if ( m_State == STATE_READTODAY ) {
m_State = STATE_UPLOADDATA; // Erik Damen: changed state machine
TRACE("STATE: UPLOADDATA\n");
}
break;
case ACK_READMODE:
TRACE("\nRECEIVE: ack READMODE\n");
/* m_PamMode = m_Buffer[3];
m_ConsumerMode = (m_PamMode & BIT_MODE_PAM_MODE) == BIT_MODE_CONSUMER;
TRACE("\nRECEIVE: ack %s 0x%02x (%s)\n",
m_State == STATE_READMODE ? "READMODE" : "SETMODE",
m_PamMode,
m_ConsumerMode ? "consumer" : "scientific");
if ( m_State == STATE_READMODE || m_State == STATE_STATICMODE )
{
if ( (m_PamMode & BIT_MODE_INTEGRATOR) == 0 && m_VersionNumber.Major == 1 && m_VersionNumber.Minor < 3) {
TRACE("WARNING: Pam in dynamic mode!\n");
m_State = STATE_STATICMODE;
TRACE("STATE: STATICMODE\n");
} else {
if (m_VersionNumber.Major == 1 && m_VersionNumber.Minor == 3) {
m_State = STATE_READEEPP0;}
else {
m_State = STATE_READEEP;}
TRACE("STATE: READEEP\n");
}
}
else if ( m_State == STATE_TOGGLEMODE )
{
m_Fifo = 0x10;
m_State = STATE_READCLK;
TRACE("STATE: READCLK\n");
}
*/
m_State = STATE_SETAUX;
TRACE("STATE: SETAUX\n");
break;
case ACK_READAUX:
TRACE("\nRECEIVE: ack READAUX\n");
m_State = STATE_SETCLK;
TRACE("STATE: STATE_SETCLK\n");
break;
case ACK_READCAL_FACTOR:
// m_Buffer contains unsigned values, so shifting is safe.
m_GainAdjustMultiplier = m_Buffer[3];
m_GainAdjustDivider = m_Buffer[4];
m_TresholdLight = m_Buffer[5] | (m_Buffer[6] << 8);
m_TresholdHeavy = m_Buffer[7] | (m_Buffer[8] << 8);
TRACE("\nRECEIVE: ack READCL_FACTOR mult=%d, div=%d, light=%d, heavy=%d\n",
m_GainAdjustMultiplier,
m_GainAdjustDivider,
m_TresholdLight,
m_TresholdHeavy);
if ( m_State == STATE_READCAL_FACTOR ) {
//m_State = STATE_READDOCKINGDATE;
TRACE("STATE: READDOCKINGDATE\n");
}
break;
case ACK_READADDRESS:
TRACE("\nWARNING : SHOULD NOT OCCUR!\n");
if ( m_Buffer[3] == ADDRESS_FIFO &&
m_Buffer[4] == m_Fifo /*&&
m_State == STATE_SETDOCKINGDATE */ )
{
TRACE("\nRECEIVE: ack SETFIFO\n");
m_Size = 0;
m_State = STATE_READCLK;
TRACE("STATE: READCLK\n");
}
else
{
TRACE("\nRECEIVE: ack READADDRESS not asked for!");
TRACE(" (0x%02x, 0x%02x)\n", m_Buffer[3], m_Buffer[4]);
}
break;
case ACK_READCLK:
if ( m_State == STATE_VERIFYCLK ) {
if ( m_Buffer[3] != m_Time.GetMinute() || m_Buffer[4] != m_Time.GetHour() ) {
TRACE("\nRECEIVE: ack READCLK, nok!!!");
m_State = STATE_SETCLK;
TRACE("STATE: SETCLK");
break;
}
}
if ( m_State == STATE_READCLK ) {
m_Time = CTime(2000, 1, 1, m_Buffer[4], m_Buffer[3], 0, 0);
TRACE("\nRECEIVE: ack READCLK %d:%02d\n", m_Buffer[4], m_Buffer[3]);
m_State = STATE_SETCLK;
TRACE("STATE: SETCLK\n");
} else if ( m_State == STATE_SETCLK ) {
TRACE("\nRECEIVE: ack SETCLK\n");
CString msg(_T(" docked"));
msg = PAM_NAME + msg;
NotifyUser(msg, FALSE, TRUE);
// NotifyUser(_T("Pam docked"), FALSE, TRUE);
m_State = STATE_DOCKED;
TRACE("STATE: DOCKED\n");
m_TimeOut = IDLE_RETRY * 1000 / m_Heartbeat + 1; /* Start counting from now. Within x seconds we expect a break signal. */
} else if ( m_State == STATE_VERIFYCLK ) {
TRACE("\nRECEIVE: ack READCLK, ok\n");
CString msg(_T(" docked"));
msg = PAM_NAME + msg;
NotifyUser(msg, FALSE, TRUE);
// NotifyUser(_T("Pam docked"), FALSE, TRUE);
m_State = STATE_DOCKED;
TRACE("STATE: DOCKED\n");
m_TimeOut = IDLE_RETRY * 1000 / m_Heartbeat + 1; /* Start counting from now. Within x seconds we expect a break signal. */
} else {
TRACE("\nRECEIVE: ack READCLK not asked for!\n");
}
break;
}
if (m_VersionNumber.Major == 1 && m_VersionNumber.Minor < 3) // changed by E. Damen for AM102
{switch ( Command ) {
case ACK_READEEP:
{
BYTE *Eeprom = m_Buffer + 3;
m_Fifo = Eeprom[0x0f];
TRACE("\nRECEIVE: ack READEEP ");
m_Config = Eeprom[0x0a] | (Eeprom[0x09] << 8) | (Eeprom[0x08] << 16) | (Eeprom[0x07] << 24);
if ( ! m_ConsumerMode ) {
_ASSERTE((m_Fifo - 0x10) % RAM_BYTES_PER_DAY == 0);
}
m_Size = 0;
UINT Fifo = m_Fifo;
do {
m_Pam[m_Size] = Eeprom[Fifo++];
if ( ! m_ConsumerMode )
{
m_LightActivity[m_Size] = (Eeprom[Fifo + 1] << 8) | Eeprom[Fifo]; Fifo += 2;
m_MediumActivity[m_Size] = (Eeprom[Fifo + 1] << 8) | Eeprom[Fifo]; Fifo += 2;
m_HeavyActivity[m_Size] = (Eeprom[Fifo + 1] << 8) | Eeprom[Fifo]; Fifo += 2;
}
if ( Fifo >= 0x80 ) Fifo = 0x10; // Modulo de geheugen grootte.
TRACE("%d ", m_Pam[m_Size]);
m_Size++;
}
while ( Fifo != m_Fifo );
TRACE("\n%d days, fifo=0x%02x\n", m_Size, m_Fifo);
if ( m_State == STATE_READEEP ) {
m_State = STATE_READDAYSCORE;
TRACE("STATE: READDAYSCORE\n");
}
break;
}
}}
else
{switch ( Command ) {
case ACK_READEEPPAGE0:
{
BYTE *Eeprom = m_Buffer + 3;
for (int i=0;i<128;i++) {
Eepromt[i] = m_Buffer[i+3];}
TRACE("\nRECEIVE: ack READEEPPAGE0 ");
// m_Fifo = Eeprom[0x0f] +256*Eeprom[0x10]; // fifo is 2 bytes long in AM102
//
// TRACE("\nm_Fifo = %d ",m_Fifo);
//
// m_Config = Eeprom[0x0a] | (Eeprom[0x09] << 8) | (Eeprom[0x08] << 16) | (Eeprom[0x07] << 24);
m_Fifo = (Eeprom[0x30] - 1) * RAM_BYTES_PER_DAY + RAM_START_DAY_ADDR; // Today_index times 7 + offset
m_PamMode = Eeprom[0x05];
m_Config = Eeprom[0x0B] | (Eeprom[0x07] << 8) | (Eeprom[0x06] << 16) | (Eeprom[0x05] << 24);
// for AM200: GCorr, Calories per Pam unit, Last Docking Day Index, Mode setting
if ( m_State == STATE_READEEPP0 ) {
m_State = STATE_READEEPP1;
TRACE("STATE: READEEPPAGE1\n");
}
break;
}
case ACK_READEEPPAGE1:
{
for (int i=0;i<128;i++) {
Eepromt[i+0x80] = m_Buffer[i+3];}
TRACE("\nRECEIVE: ack READEEPPAGE1 ");
if ( m_State == STATE_READEEPP1 ) {
m_State = STATE_READEEPP2;
TRACE("STATE: READEEPPAGE2\n");
}
break;
}
case ACK_READEEPPAGE2:
{
for (int i=0;i<128;i++) {
Eepromt[i+0x100] = m_Buffer[i+3];}
TRACE("\nRECEIVE: ack READEEPPAGE2 ");
if ( m_State == STATE_READEEPP2 ) {
m_State = STATE_READEEPP3;
TRACE("STATE: READEEPPAGE3\n");
}
break;
}
case ACK_READEEPPAGE3:
{
for (int i=0;i<128;i++) {
Eepromt[i+0x180] = m_Buffer[i+3];}
TRACE("\nm_Fifo = %d ",m_Fifo);
TRACE("\nRECEIVE: ack READEEPPAGE3 ");
if ( ! m_ConsumerMode ) {
_ASSERTE((m_Fifo - RAM_START_DAY_ADDR) % RAM_BYTES_PER_DAY == 0);
}
m_Size = 0;
UINT Fifo = m_Fifo;
do {
m_Pam[m_Size] = Eepromt[Fifo]; // Erik, check dit: // Fifo++;
// if ( ! m_ConsumerMode )
// {
// m_LightActivity[m_Size] = Eepromt[Fifo]; Fifo++;
// m_MediumActivity[m_Size] = Eepromt[Fifo]; Fifo++;
// m_HeavyActivity[m_Size] = Eepromt[Fifo]; Fifo++;
// }
// For the AM200, the day is stored in a different way from the AM102:
// Pam Score: 13 bits
// Low activity minutes: 11 bits
// Medium activity minutes: 10 bits
// High activity minutes: 8 bits
// Distance: 10 bits
// Fruit: 4 bits
// m_Pam[m_Size] = Eepromt[Fifo] + (Eepromt[Fifo+1]&0x1F)<<8;
// m_LightActivity[m_Size] = (Eepromt[Fifo+1]&0xE0)>>5 + Eepromt[Fifo+2]<<3;
// m_MediumActivity[m_Size] = Eepromt[Fifo+3] + (Eepromt[Fifo+4]&0x03)<<8;
// m_HeavyActivity[m_Size] = (Eepromt[Fifo+4]&0xFC)>>2 + (Eepromt[Fifo+5]&0x03)<<6;
// m_Distance[m_Size] = (Eepromt[Fifo+5]&0xFC)>>2 + (Eepromt[Fifo+6]&0x0F)<<6;
// m_Fruit[m_Size] = (Eepromt[Fifo+6]&0xF0)>>4;
m_code1[m_Size] = Eepromt[Fifo] + (Eepromt[Fifo+1]<<8) + (Eepromt[Fifo+2]<<16) + (Eepromt[Fifo+3]<<24);
m_code2[m_Size] = Eepromt[Fifo+4] + (Eepromt[Fifo+5]<<8) + (Eepromt[Fifo+6]<<16);
Fifo = Fifo + RAM_BYTES_PER_DAY;
if ( Fifo >= RAM_END_DAY_ADDR ) Fifo = RAM_START_DAY_ADDR; // Modulo memory size
m_Size++;
}
while ( Fifo != m_Fifo );
TRACE("\n%d days, fifo=0x%02x\n", m_Size, m_Fifo);
if ( m_State == STATE_READEEPP3 ) {
m_State = STATE_READTODAY;
TRACE("STATE: READTODAY\n");
}
break;
}
}}
m_dwEob -= Length;
return true;
}
//////////////////////////////////////////////////////////////////
void __stdcall CPamTaskBar::OnLeftDoubleClick()
{
#ifdef USE_COM_PORTS
SettingsDialog();
#else
AboutDialog();
#endif
}
void __stdcall CPamTaskBar::AboutDialog()
{
CAboutDlg dlgAbout;
if ( m_SerialNumber == 0 ) {
CString msg;
msg.Format(_T("Serial number unknown (%s not docked)"), PAM_NAME);
dlgAbout.m_strSerial = msg;
} else {
int country = m_SerialNumber >> 24;
dlgAbout.m_strSerial.Format(IDS_ABOUT_SERIAL_FIRMWARE,
m_SerialNumber & 0x00ffffff,
country == COUNTRY_US ? " (US)" : (country == COUNTRY_UK ? " (UK)": ""),
m_VersionNumber.Major,
m_VersionNumber.Minor,
m_VersionNumber.Build,
PAM_NAME,
m_PamDayScore16 >> 4);
}
if ( m_Config == 0 ) {
dlgAbout.m_strConfig = m_bUseWinHttp ? "WinHTTP mode" : "WinINet mode";
} else {
dlgAbout.m_strConfig.Format(IDS_ABOUT_CONFIG_FIRMWARE,
m_Config,
m_bUseWinHttp ? "WinHTTP" : "WinINet");
}
CString Msg;
Msg.Format(_T("%s Version %d.%d"), DRIVER_NAME, VERSION_MAJOR, VERSION_MINOR);
dlgAbout.m_strVersion = Msg;
dlgAbout.DoModal();
}
/*
void CPamTaskBar::SettingsDialog()
{
//IDC_STATIC_PAMMODE
CString Msg;
Msg.Format(_T("%s Settings"), DRIVER_NAME);
CPropertySheet dlg(Msg);
StandardDlg dlgStandard;
DebugDlg dlgDebug;
CWinApp* pApp = AfxGetApp();
// Load the settings from the registry.
CString strComPort
= pApp->GetProfileString(_T(PAM_VERSION), _T(REG_COM_PORT), _T("COM1"));
LONG nClock
= pApp->GetProfileInt(_T(PAM_VERSION), _T(REG_CLOCK_MODE), 0);
BOOL bSyncToPC
= pApp->GetProfileInt(_T(PAM_VERSION), _T(REG_SYNC_CLOCK), 1) != 0;
int nPamMode;
if ( m_State != STATE_DOCKED ) {
nPamMode = -1;
} else if ( ((m_VersionNumber.Major << 16) |
(m_VersionNumber.Minor << 8) |
(m_VersionNumber.Build << 0)) < 0x010200 ) {
// version < 1.2.0
nPamMode = -1;
} else {
nPamMode = m_ConsumerMode ? 0 : 1;
}
dlgStandard.m_pSerial = &m_serial;
dlgStandard.m_strComPort = strComPort;
dlgStandard.m_bSyncToPC = bSyncToPC;
dlgStandard.m_nClock = nClock;
dlgStandard.m_nPamMode = nPamMode;
dlgStandard.m_bModeSwitchAllowed = TRUE; // functie wordt niet gebruikt
Msg.Format(_T("%s mode:"), PAM_NAME);
dlgStandard.m_PamModeLabel = Msg;
dlgDebug.m_strUploadServer = pApp->GetProfileString(_T(PAM_VERSION),
_T(REG_SERVER_URL),
_T(UPLOAD_URL));
dlgDebug.m_lHeartbeat = pApp->GetProfileInt(_T(PAM_VERSION), _T(REG_HEARTBEAT), DEFAULT_HEARTBEAT);
dlg.AddPage(&dlgStandard);
if ( pApp->GetProfileInt(_T(PAM_VERSION), _T(REG_GODDESS), 0) != 0 ) {
dlg.AddPage(&dlgDebug);
}
INT_PTR nResponse = dlg.DoModal();
if ( nResponse == IDOK )
{
if ( dlgStandard.m_nPamMode != nPamMode ) {
CString msg;
msg = _T("Are you sure you want to set your ");
msg += PAM_NAME;
if ( m_ConsumerMode ) {
msg += " to Advanced Mode?";
} else {
msg += " to Memory Mode?";
}
if ( ::MessageBox(0, msg, _T("Pam mode"), MB_OKCANCEL|MB_ICONWARNING) != IDOK )
{
// Restore old value
dlgStandard.m_nPamMode = nPamMode;
}
}
// Save the settings to the registry.
#ifdef USE_COM_PORTS
pApp->WriteProfileString(_T(PAM_VERSION), _T(REG_COM_PORT), dlgStandard.m_strComPort);
pApp->WriteProfileInt (_T(PAM_VERSION), _T(REG_CLOCK_MODE), dlgStandard.m_nClock);
pApp->WriteProfileInt (_T(PAM_VERSION), _T(REG_SYNC_CLOCK), dlgStandard.m_bSyncToPC);
pApp->WriteProfileString(_T(PAM_VERSION), _T(REG_SERVER_URL), dlgDebug.m_strUploadServer);
pApp->WriteProfileInt (_T(PAM_VERSION), _T(REG_HEARTBEAT), dlgDebug.m_lHeartbeat);
#endif
if ( dlgDebug.m_lHeartbeat != m_Heartbeat ) {
StartHeartbeat();
}
# ifdef USE_COM_PORTS
if ( dlgStandard.m_strComPort != strComPort || m_State == STATE_NULL ) {
// Close the current com port and open the newly selected one.
m_State = STATE_NULL;
TRACE("STATE: NULL\n");
CloseComPort();
if ( OpenComPort() ) {
NotifyUser(_T("Undocked"), TRUE, TRUE);
m_State = STATE_UNDOCKED;
m_PamMode = -1;
TRACE("STATE: UNDOCKED\n");
}
} else
# endif
if ( dlgStandard.m_nPamMode != nPamMode && m_State == STATE_DOCKED ) {
// The user has toggled the Pammode setting.
m_State = STATE_TOGGLEMODE;
TRACE("STATE: TOGGLEMODE\n");
} else if ( dlgStandard.m_bSyncToPC != bSyncToPC &&
m_State == STATE_DOCKED &&
dlgStandard.m_bSyncToPC ) {
// The user checked the synchronise button, so set the time again.
m_State = STATE_READCLK;
TRACE("STATE: READCLK\n");
} else if ( dlgStandard.m_nClock != nClock && m_State == STATE_DOCKED ) {
// The user has toggled the clock setting, so set the time again.
m_State = STATE_READCLK;
TRACE("STATE: READCLK\n");
}
}
else if (nResponse == IDCANCEL)
{
}
}
*/
LPCTSTR __stdcall CPamTaskBar::GetTrayTip()
{
return m_TrayTip;
}
HICON __stdcall CPamTaskBar::GetIcon()
{
return ::LoadIcon(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_ICONSMALL));
}
HMENU __stdcall CPamTaskBar::GetMenu()
{
HMENU hMenu = CreatePopupMenu();
MENUITEMINFO item;
memset(&item, 0, sizeof(MENUITEMINFO));
item.cbSize = sizeof(MENUITEMINFO);
///////////////////////////////////////
#ifdef USE_COM_PORTS
item.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
item.wID = ID_OPEN;
item.fType = MFT_STRING;
item.dwTypeData = _T("&Settings");
item.fState = MFS_DEFAULT;
InsertMenuItem(hMenu, 0, FALSE, &item);
#endif
///////////////////////////////////////
item.fMask = MIIM_TYPE | MIIM_ID;
item.wID = ID_PAM;
item.fType = MFT_STRING;
item.dwTypeData = _T("&Open " PAM_NAME " site");
InsertMenuItem(hMenu, 0, FALSE, &item);
///////////////////////////////////////
/*
item.fMask = MIIM_TYPE | MIIM_ID;
item.wID = ID_UPLOAD;
item.fType = MFT_STRING;
item.dwTypeData = _T("&Upload Data");
InsertMenuItem(hMenu, 0, FALSE, &item);
*/
///////////////////////////////////////
item.wID = ID_ABOUT;
item.fType = MFT_STRING;
item.dwTypeData = _T("&About");
#ifdef USE_COM_PORTS
item.fMask = MIIM_TYPE | MIIM_ID;
#else
item.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
item.fState = MFS_DEFAULT;
#endif
InsertMenuItem(hMenu, 0, FALSE, &item);
///////////////////////////////////////
item.fMask = MIIM_TYPE | MIIM_ID;
item.fType = MFT_SEPARATOR;
InsertMenuItem(hMenu, 0, FALSE, &item);
///////////////////////////////////////
item.wID = ID_CLOSE;
item.fType = MFT_STRING;
item.dwTypeData = _T("E&xit");
InsertMenuItem(hMenu, 0, FALSE, &item);
///////////////////////////////////////
return hMenu;
}
void __stdcall CPamTaskBar::HandleMenuCommand(int command)
{
switch (command)
{
case ID_CLOSE:
{
CloseApplet();
break;
}
case ID_ABOUT:
{
AboutDialog();
break;
}
case ID_UPLOAD:
{
if ( m_State == STATE_DOCKED ) {
NotifyUser(_T(DRIVER_NAME), TRUE, TRUE);
m_State = STATE_NULL;
m_PamMode = -1;
} else if ( m_State == STATE_NULL ) {
#ifdef USE_COM_PORTS
CloseComPort();
if ( OpenComPort() ) {
NotifyUser(_T("Undocked"), TRUE, TRUE);
m_State = STATE_UNDOCKED;
//m_State = STATE_RDSERNR;
m_PamMode = -1;
TRACE("STATE: UNDOCKED\n");
}
#else
/*
CloseUSB();
if ( OpenUSB() ) {
NotifyUser(_T("Undocked"), TRUE, TRUE);
m_State = STATE_UNDOCKED;
//m_State = STATE_RDSERNR;
m_PamMode = -1;
TRACE("STATE: UNDOCKED\n");
}
*/
#endif
}
break;
}
/*
case ID_OPEN:
{
SettingsDialog();
break;
}
*/
case ID_OPEN:
case ID_PAM:
{
CURL url;
url.Open(_T(SITE_URL), false);
break;
}
}
}