邢远 发表于 2014-9-20 21:06:07

installertooldlg.cpp:源码内容

/*******************************InstallerToolDlg.cpp*********************
*         #######
*         ####
*         ###    ####   #####    #########   #####
*             ##    ##########      ######
*            #############   ####   ####   ####
*         ######      ####      ##   #####      ##
*          #######   ####   #########       #######
*                                           #####
*          Z-Wave, the wireless language.
*
*            Copyright (c) 2001
*            Zensys A/S
*            Denmark
*
*            All Rights Reserved
*
*    This source file is subject to the terms and conditions of the
*    Zensys Software License Agreement which restricts the manner
*    in which it may be used.
*
*---------------------------------------------------------------------------
*
* Description: Implementation file for InstallerTool source code.
*       All functionality for the Serial API based installer tool
*       should be defined here.
*
* Author:   Henrik Holm
*
* Last Changed By:$Author: heh $
* Revision:         $Revision: 1.36 $
* Last Changed:   $Date: 2005/04/14 11:34:52 $
*
****************************************************************************/
/****************************************************************************/
/*                              INCLUDE FILES                               */
/****************************************************************************/
#include "stdafx.h"
#include "InstallerTool.h"
#include "InstallerToolDlg.h"
#include "winver.h"
#include ".installertooldlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//Version values
#define PC_VERSION_MAJOR 1
#define PC_VERSION_MINOR 11
/*Number of ms between timer events*/
#define TIMEOUT_TIME 100 /*ms*/
/*Define colors to use           BBGGRR*/
#define INVALID_COLOR       0x000000
#define NODE_GT_COLOR       0x00FF99       //Generic controller
#define NODE_ST_COLOR       0x9999FF       //Static controller
#define NODE_SB_COLOR       0x660000       //Binary Switch
#define NODE_SM_COLOR       0xFF0000       //Multilevel Switch
#define NODE_SENB_COLOR       0x00AA00       //Binary sensor
#define NODE_SENM_COLOR       0x111111       //Multilevel sensor
#define NODE_MB_COLOR       0XE6E61C       //Meter
#define NODE_EC_COLOR       0xAAAAAA       //Entry Control
#define NO_NODE_COLOR       0xFFFFFF       //No node at this node id
#define NODE_UNKNOWN_COLOR        0x9900FF
#define NODE_BAD_COLOR       0x0000FF       //There is a node, but unable to the other node
#define NODE_OK_COLOR       0xFF0000
#define GRAPH_TOPOLOGY_SIZE 512       // The size of the network topologi map in pixels
/* Max number of nodes in a Z-wave system */
#define ZW_MAX_NODES      232
/*Defined used to access m_nodeList display*/
#define ID_FIELD        0
#define NODE_ID_TXT 1
#define DEVICE_TYPE 2
#define TX_COUNT        3
#define REPORT_LEVEL_TIMEOUT 0x01
#define GET_LEVEL_TIMEOUT 0x02
CSerialAPI api;
BYTE nodeType;
BYTE lastLearnedNodeID;
BYTE lastLearnedNodeType;
BYTE RoadList;
static void *this_instance;
static HWND this_hWnd;
BYTE locateCount;
BOOL replSend;
int selected;
BYTE selectCount;
static BYTE routingTable;
BOOL secondaryCtrl;
char uCversion;
BYTE bAbortNow = FALSE;
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
CString        m_txtVersion;
CString        m_txtDevVer;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
m_txtVersion = _T("");
m_txtDevVer = _T("");
//}}AFX_DATA_INIT
char str;
m_txtVersion.Delete(0,80);
sprintf(str,"PC version: %i.%i",PC_VERSION_MAJOR,PC_VERSION_MINOR);
m_txtVersion.Insert(0, str);
sprintf(str,"Module: %s",uCversion);
m_txtDevVer.Delete(0,80);
m_txtDevVer.Insert(0,str);
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
DDX_Text(pDX, IDC_STATICVERSION, m_txtVersion);
DDV_MaxChars(pDX, m_txtVersion, 80);
DDX_Text(pDX, IDC_STATICDEV, m_txtDevVer);
DDV_MaxChars(pDX, m_txtDevVer, 80);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CInstallerToolDlg dialog
CInstallerToolDlg::CInstallerToolDlg(CWnd* pParent /*=NULL*/)
: CDialog(CInstallerToolDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CInstallerToolDlg)
m_RoutingTable = _T("");
m_intLowNode = 0;
m_intHighNode = 0;
m_uintFrames = 10;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CInstallerToolDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CInstallerToolDlg)
DDX_Control(pDX, IDCANCEL, m_btnQuit);
DDX_Control(pDX, IDC_BUTTON13, m_btnAbortAction);
DDX_Control(pDX, IDC_BUTTON10, m_btnResetTool);
DDX_Control(pDX, IDC_COMBO1, m_cTXLevel);
DDX_Control(pDX, IDC_LQRESULT, m_txtLQResult);
DDX_Control(pDX, IDC_LEGEND, m_legend);
DDX_Control(pDX, IDC_LIST2, m_nodeList);
DDX_Control(pDX, IDC_STATIC4, m_txtNodePoint);
DDX_Control(pDX, IDC_BUTTON9, m_btnResetNode);
DDX_Control(pDX, IDC_BUTTON6, m_btnRecInfo);
DDX_Control(pDX, IDC_BUTTON4, m_btnRestore);
DDX_Control(pDX, IDC_BUTTON3, m_btnBackup);
DDX_Control(pDX, TOPOLOGY, m_btnTopology);
DDX_Control(pDX, IDC_BUTTON8, m_btnAddNode);
DDX_Control(pDX, IDC_BUTTON7, m_btnCheckLink);
DDX_Control(pDX, IDC_BUTTON2, m_btnLocateNode);
DDX_Control(pDX, IDC_BUTTON1, m_btnGetNeighbors);
DDX_Control(pDX, IDC_STATIC2, m_txtHomeId);
DDX_Control(pDX, IDC_STATIC1, m_txtStatus);
DDX_Control(pDX, IDC_ROUTEMAP, m_cstaticNodeMap);
DDX_Text(pDX, IDC_EDIT1, m_uintFrames);
DDV_MinMaxUInt(pDX, m_uintFrames, 1, 32000);
DDX_Control(pDX, IDC_BUTTON12, m_btnHandOverPrimary);
    //}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CInstallerToolDlg, CDialog)
//{{AFX_MSG_MAP(CInstallerToolDlg)
//ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(TOPOLOGY, OnTOPOLOGY)
ON_BN_CLICKED(IDC_BUTTON1, OnGetNeighbors)
ON_WM_DRAWITEM()
ON_BN_CLICKED(IDC_BUTTON2, OnLocateNode)
ON_BN_CLICKED(IDC_BUTTON6, OnReplRec)
ON_LBN_SELCHANGE(IDC_LIST2, OnSelchangeList2)
ON_BN_CLICKED(IDC_BUTTON7, OnCheckLink)
ON_BN_CLICKED(IDCANCEL, OnExit)
ON_BN_CLICKED(IDC_BUTTON8, OnAddNode)
ON_BN_CLICKED(IDC_BUTTON9, OnResetNode)
ON_BN_CLICKED(IDC_BUTTON10, OnResetTool)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDBLCLK()
ON_EN_CHANGE(IDC_EDIT1, OnChangeEdit1)
ON_CBN_EDITCHANGE(IDC_COMBO1, OnEditchangeCombo1)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BUTTON12, OnHandOverPrimary)
ON_BN_CLICKED(IDC_BUTTON13, OnAbortButton)
ON_WM_MBUTTONDBLCLK()
ON_WM_ACTIVATE()
//}}AFX_MSG_MAP
#if _MSC_VER >= 1300
ON_MESSAGE(WM_USER+2, (LRESULT (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM)) EnableUI)
ON_MESSAGE(WM_USER+4, (LRESULT (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM)) OnReceiveRemoteData)
#else
ON_MESSAGE(WM_USER+2, EnableUI)
ON_MESSAGE(WM_USER+4, OnReceiveRemoteData)
#endif
ON_BN_CLICKED(IDC_BUTTON14, OnBnClickedButton14)
ON_WM_SYSCOMMAND()
END_MESSAGE_MAP()
/*============================   EnableUI ====================================
** Function description
**      Enables button presses
**
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::EnableUI()
{
EnableButtons(TRUE);
}
/*============================   AddNode   ==================================
** Function description
**      Add a node to the internal nodeType table.
**
** Side effects:
**       Updates the bMaxNodeID variable.
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::AddNode(BYTE nid, BYTE ntype)
{
BYTE i=255;
nodeType = ntype;
while((nodeType==0)&&(i>0))
i--;
if(i)
bMaxNodeID = i;
else
bMaxNodeID = 0;
}
/*============================   SetNodeIDText ==============================
** Function description
**      Finds the nodeID in the Item list and updates the selected information
**       Returns TRUE if success, FALSE if not
** Side effects:
**
**--------------------------------------------------------------------------*/
BOOL CInstallerToolDlg::SetNodeIDText(BYTE nodeID,        /*IN nodeid to update*/
BYTE field,        /* IN What field we want updated*/
CString txtStr)        /*IN String containing the text write*/
{
BOOL retVal = FALSE;
char buf4;
int item;
memset(buf4, 0, sizeof(buf4));
lfv.flags = LVFI_STRING;// Search on parmeter
lfv.psz = itoa(nodeID, buf4, 10);       /*Find node ID*/
item = m_nodeList.FindItem(&lfv,-1);
if(item!=-1)
{
m_nodeList.SetItemText(item,field,txtStr);
m_nodeList.SetItemText(item, NODE_ID_TXT,itoa(nodeID, buf4, 10));
retVal = TRUE;
}
return retVal;
}
/*============================   ConvertStrtoInt===========================
** Function description
**      Converts a string to an integer
**
** Side effects:
**
**--------------------------------------------------------------------------*/
int CInstallerToolDlg::ConvertStrtoInt(CString UnitIdStrTemp)
{
   BYTE Number = 0;

   Number = atoi(UnitIdStrTemp);
   return Number;
}
/*============================   GetUnitList ================================
** Function description
**      Gets a list of selected node ids
**
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::GetUnitList(int *unitList, BYTE *numberUnits)
{
   CString UnitIdStrTemp;
   int k=0;
   memset(unitList, 0, 255);
   POSITION pos = m_nodeList.GetFirstSelectedItemPosition();
   int nSelectedItem = -1;
   for (int i = 0;i < itemIndex;i++)
   {
if (pos != NULL)
{
nSelectedItem = m_nodeList.GetNextSelectedItem(pos);
UnitIdStrTemp = m_nodeList.GetItemText(nSelectedItem,1);
unitList = ConvertStrtoInt(UnitIdStrTemp);
   }
   }
   *numberUnits = k;
}
/*============================   ReloadNodeList =============================
** Function description
**      Reloads the node IDs and types from the Device module
** Side effects:
**--------------------------------------------------------------------------*/
BOOL CInstallerToolDlg::ReloadNodeList(void)
{
BOOL bFound = FALSE;
BYTE byNode = 1;
BYTE j,i;
BYTE bVer = 0;
BYTE bCapab = 0;
BYTE bLen = 0;
BYTE bNodes;
BYTE HomeId;
BYTE NodeId;
NODEINFO nodeInfo;
char txt;
bMaxNodeID = 0;
api.MemoryGetID(HomeId, &NodeId);
secondaryCtrl = api.SerialAPI_GetInitData(&bVer, &bCapab, &bLen, bNodes);
/*Reset the nodelist before loading it again*/
for (i=0;i<255;i++)
nodeType = 0;
for (i=0;i<bLen;i++)
{
if (bNodes != 0)
{
bFound = TRUE;
for (j=0;j<8;j++)
{
if (bNodes & (1<<j))
{
sprintf(txt,"Reading %i nodelist",byNode);
m_txtStatus.SetWindowText(txt);
api.ZW_GetNodeProtocolInfo(byNode, &nodeInfo);
nodeType = nodeInfo.nodeType.generic;
bMaxNodeID = byNode;
}
    byNode++;
}
}
else
byNode += 8;
}
return bFound;
}
/*============================ DisplayStandardItems ==========================
** Function description
**      Displays the nodeTable, Home ID and other standard items
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::DisplayStandardItems(void)
{
char buffer;
char a;
BYTE HomeId;
BYTE NodeId;
int item;
char buf4;
memset(buf4, 0, sizeof(buf4));
lfv.flags = LVFI_STRING;// Search on text
/*Get homeID*/
api.MemoryGetID(HomeId, &NodeId);
if(bMaxNodeID)
{
for(int i=0;i< bMaxNodeID;i++)
{
       lfv.psz = itoa(i+1, buf4, 10);       /*Find node ID*/
item = m_nodeList.FindItem(&lfv,-1);
if(nodeType!=0)
{
if(NodeId == (i+1))
sprintf(buffer, "This node");
else
sprintf(buffer, "%s",WriteNodeTypeString(nodeType));
if (item != -1)
{
SetNodeIDText(i+1,DEVICE_TYPE,buffer);
}
else
{
memset(buf4, 0, sizeof(buf4));
m_nodeList.InsertItem(itemIndex, itoa(i+1, buf4, 10));
m_nodeList.SetItemText(itemIndex, NODE_ID_TXT,itoa(i+1, buf4, 10));
SetNodeIDText(i+1,DEVICE_TYPE,buffer);
itemIndex++;
}
}
else
{        /*No node found here*/
if (item != -1)
{
m_nodeList.DeleteItem(item);
itemIndex--;
}
}
}
if(itemIndex>(bMaxNodeID))
{
m_nodeList.DeleteItem(--itemIndex);
}
}
else /*No nodes in the controller*/
m_nodeList.DeleteAllItems();
sprintf(a,"%02X%02X%02X%02X, NodeId:%dn",HomeId,HomeId,HomeId,HomeId,NodeId);
GetInstance()->m_txtHomeId.SetWindowText(a);
GetInstance()->m_txtNodePoint.SetWindowText("...");
GetInstance()->m_txtHomeId.UpdateWindow();
}
void CInstallerToolDlg::RemoveNodeFromList(BYTE bSource)
{
   char buf4;
   memset(buf4, 0, sizeof(buf4));
   lfv.flags = LVFI_STRING;// Search on text
   lfv.psz = itoa(bSource, buf4, 10);
   int nodelst = m_nodeList.FindItem(&lfv,-1);
   if (nodelst != -1)
   {
       m_nodeList.DeleteItem(nodelst);
   itemIndex--;
   }
}
/*============================   IdleLearnNodeState_Compl ====================
** Function description
**      Callback which is called when a node is added or removed by
**       a SUC
**
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::IdleLearnNodeState_Compl(BYTE bStatus, /*IN Status of learn mode*/
BYTE bSource, /*IN Source node*/
BYTE *pCmd,   /*IN Data*/
BYTE bLen)    /*Length of data*/
{
static BYTE lastLearnedNodeType;
if (bLen)
{
      NODEINFO nodeInfo;
      api.ZW_GetNodeProtocolInfo(bSource, &nodeInfo);
      if (nodeInfo.nodeType.basic<BASIC_TYPE_SLAVE)
      {
         lastLearnedNodeType = nodeInfo.nodeType.basic;/*For now we store the learned basic node type*/
      }
      else
      {
         lastLearnedNodeType = nodeInfo.nodeType.generic; /* Store learned generic node type*/
      }
}
if (bStatus == UPDATE_STATE_ROUTING_PENDING)
{
GetInstance()->m_txtStatus.SetWindowText("Waiting ...");
}
else if (bStatus == UPDATE_STATE_ADD_DONE)
{
GetInstance()->AddNode(bSource,lastLearnedNodeType);
GetInstance()->m_txtStatus.SetWindowText("Node included ...");
::PostMessage(this_hWnd, WM_USER+2, 0, 0);
}
else if (bStatus == UPDATE_STATE_DELETE_DONE)
{
GetInstance()->RemoveNodeFromList(bSource);
GetInstance()->AddNode(bSource,0);
GetInstance()->m_txtStatus.SetWindowText("Node removed...");
::PostMessage(this_hWnd, WM_USER+2, 0, 0);
}
}
/*============================   CommErrorNotification =======================
** Function description
**      Called when a communication error occours between Z-Wave module and
**       PC
**
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::CommErrorNotification(BYTE byReason)
{
switch(byReason)
{
case CSerialAPI::COMM_RETRY_EXCEEDED:
   GetInstance()->MessageBox("Communication with Z-Wave module was lost while sending command.nCheck the cable and either retry the operation or restart the application.","Error");
   break;
case CSerialAPI::COMM_NO_RESPONSE:
   GetInstance()->MessageBox("Communication with Z-Wave module timed out while waiting for response.nCheck the cable and either retry the operation or restart the application.","Error");
   break;
default:
   GetInstance()->MessageBox("Communication with Z-Wave module was lost.nCheck the cable and either retry the operation or restart the application.","Error");
   break;
}
}
/*======================   ApplicationCommandHandler =======================
** Function description
**      All non protocol RF messages received are handled by this function
**
**
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::ApplicationCommandHandler(BYTE rxStatus,
   BYTE sourceNode,
   BYTE *pCmd,
   BYTE cmdLength)
{
ZW_APPLICATION_TX_BUFFER *pdata = (ZW_APPLICATION_TX_BUFFER *) pCmd;
char txt;
switch(*(pCmd+CMDBUF_CMDCLASS_OFFSET))
{
           case COMMAND_CLASS_SWITCH_MULTILEVEL:
case COMMAND_CLASS_BASIC:
if(*(pCmd+CMDBUF_CMD_OFFSET)== BASIC_REPORT)
{
}
else if (*(pCmd+CMDBUF_CMD_OFFSET)== BASIC_SET)
{
}
break;
case COMMAND_CLASS_SENSOR_BINARY:
if (*(pCmd+CMDBUF_CMD_OFFSET)== SENSOR_BINARY_REPORT)
{
}
break;
case COMMAND_CLASS_CONTROLLER_REPLICATION:
api.ZW_ReplicationCommandComplete();
break;
case COMMAND_CLASS_POWERLEVEL:
if(*(pCmd+CMDBUF_CMD_OFFSET)==POWERLEVEL_TEST_NODE_REPORT)
{
if(GetInstance()->timerID.eventID)
GetInstance()->KillTimer(GetInstance()->timerID.eventID);
GetInstance()->timerID.eventID = 0;
unsigned int recCount = (pdata->ZW_PowerLevelTestNodeReportFrame.testFrameCountMsb<<8)&0xFF00;
recCount |= pdata->ZW_PowerLevelTestNodeReportFrame.testFrameCountLsb&0x00FF;
sprintf(txt," %d to: %d Frames OK:%i", sourceNode, pdata->ZW_PowerLevelTestNodeReportFrame.nodeId,
recCount);
/*pdata->ZW_PowerLevelTestNodeReportFrame.testStatus*/
GetInstance()->m_txtLQResult.SetWindowText(txt);
GetInstance()->EnableButtons(TRUE);
   }
   break;
default:
break;
}
}
/////////////////////////////////////////////////////////////////////////////
// CInstallerToolDlg message handlers
/*================================   GetInstance =============================
** Function description
**      Used to get the instance
**
** Side effects:
**
**--------------------------------------------------------------------------*/
CInstallerToolDlg *CInstallerToolDlg::GetInstance()
{
return (CInstallerToolDlg *)this_instance;
}
/*================================ OnInitDialog =============================
** Function description
**      Called on program startup. Initializes the program and module
**
** Side effects:
**
**--------------------------------------------------------------------------*/
BOOL CInstallerToolDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog.The framework does this automatically
//when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE);       // Set big icon
SetIcon(m_hIcon, FALSE);       // Set small icon
this_instance = this;
this_hWnd = m_hWnd;
/* Start the Z-Wave initilization*/
/* Find out which port is connected.*/
bMaxNodeID = 0;
    PortValue = 0;
    libType = 0;
#if _MSC_VER >= 1300
      bySpeed = CSerialAPI::SPEED_115200;
#else
bySpeed = CSerialAPI.SPEED_115200;
#endif
lSpeed= 115200;
for (int i = 1; i < __argc; i++)
{
LPCTSTR pszParam = __argv;
if (pszParam == '-' || pszParam == '/')
{
++pszParam;
}
if (lstrcmpi(pszParam,"com=1") == 0)
PortValue = 1;
else if (lstrcmpi(pszParam,"com=2") == 0)
PortValue = 2;
else if (lstrcmpi(pszParam,"com=3") == 0)
PortValue = 3;
else if (lstrcmpi(pszParam,"com=4") == 0)
PortValue = 4;
else if (lstrcmpi(pszParam,"com=5") == 0)
PortValue = 5;
else if (lstrcmpi(pszParam,"com=6") == 0)
PortValue = 6;
else if (lstrcmpi(pszParam,"com=7") == 0)
PortValue = 7;
if (lstrcmpi(pszParam,"speed=19200") == 0)
{
#if _MSC_VER >= 1300
            bySpeed = CSerialAPI::SPEED_19200;
#else
bySpeed = CSerialAPI.SPEED_19200;
#endif
lSpeed = 19200;
}
else if (lstrcmpi(pszParam,"speed=57600") == 0)
{
#if _MSC_VER >= 1300
            bySpeed = CSerialAPI::SPEED_57600;
#else
            bySpeed = CSerialAPI.SPEED_57600;
#endif
lSpeed = 57600;
}
if (FindLib(PortValue,bySpeed) == 0)
{
api.Shutdown();
            str.Format("This application requires a static controller Z-Wave module connected to the serialport.nnDownload the correct Serial API code to the Z-Wave Module and restart the application.");
}
}
   if (__argc < 2)
{   
       m_txtStatus.SetWindowText("No nodes added to controller");
   while((libType != ZW_LIB_INSTALLER) && (PortValue < 8))
   {
       PortValue++;
   FindLib(PortValue,bySpeed);
   }
}
    if (libType != ZW_LIB_INSTALLER)
{
       MessageBox(str, "Error");
   OnOK();
   return TRUE;
           }
else
{
    char aa;
CString str;
    GetWindowText(str);
sprintf(aa," - com%d %ld baud",PortValue,lSpeed);
SetWindowText(str + aa);
}
/*Reload the nodes*/
m_nodeList.SetExtendedStyle( (m_nodeList.GetExtendedStyle()| LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT |
LVIS_SELECTED | LVS_SHOWSELALWAYS )& ~LVS_EX_TRACKSELECT);
m_nodeList.InsertColumn( ID_FIELD, "Id");
m_nodeList.InsertColumn( NODE_ID_TXT, "Node Id");
m_nodeList.InsertColumn( DEVICE_TYPE, "Device Type");
m_nodeList.InsertColumn(TX_COUNT, "TxCount");
itemIndex = 0;
m_nodeList.SetColumnWidth( ID_FIELD, 0);
m_nodeList.SetColumnWidth( NODE_ID_TXT, 50);
m_nodeList.SetColumnWidth( DEVICE_TYPE, 120);
m_nodeList.SetColumnWidth( TX_COUNT, 50);
if (ReloadNodeList())
{
        m_txtStatus.SetWindowText("Nodes copied from Z-Wave module.");
}
EnableButtons(TRUE);
/*Set the node type to Generic controller, NOT listening*/
BYTE ca;
APPL_NODE_TYPE appType;
ca = 0;
/*        appType.specific = */
appType.generic = GENERIC_TYPE_GENERIC_CONTROLLER;
api.SerialAPI_ApplicationNodeInformation(FALSE,appType, ca, 0 );
/*Set Idle learn mode function.*/
api.ZW_SetIdleNodeLearn(IdleLearnNodeState_Compl);
/*reset timer*/
timerID.eventID = 0;
   /* Print the node table */
DisplayStandardItems();
memset(nodeState, 0, sizeof(nodeState));
/*Verify if ApplicationNodeInformation is stored correctly*/
BYTE HomeId;
BYTE NodeId;
NODEINFO nodeInfo;
api.MemoryGetID(HomeId, &NodeId);
api.ZW_GetNodeProtocolInfo(NodeId,&nodeInfo);
if(nodeInfo.nodeType.generic!= appType.generic)
{
    m_txtStatus.SetWindowText("Incorrect type set for this nodetype. Please reset module");
    EnableButtons(false);
    m_btnResetTool.EnableWindow(true);
    m_btnQuit.EnableWindow(true);
//    api.ZW_SetDefault(SetDefault_Compl);
}
return TRUE;// return TRUEunless you set the focus to a control
}
BYTE CInstallerToolDlg::FindLib(int PortValue, BYTE bySpeed)
{
   if (api.Initialize(PortValue, bySpeed, ApplicationCommandHandler, CommErrorNotification))
   {
      libType = api.ZW_Version((BYTE*)uCversion);        //Get the lib type and version from module
switch (libType)
{
    case ZW_NO_INTELLIGENT_LIFE:
{
    api.Shutdown();
str.Format("No Serial API code detected on port: com%d - check serial connections.nThis application requires an Installer version of the Serial APInon a Z-Wave module connected via a serialport.nDownload the correct Serial API code to the Z-Wave Module and restart the application.", PortValue);
}
      break;
case ZW_LIB_CONTROLLER_STATIC:
{
              api.Shutdown();
             str.Format("Controller based serial API code detected on port: com%d.nThis application requires an Installer version of the Serial APInon a Z-Wave module connected via a serialport.nDownload the correct Serial API code to the Z-Wave Module and restart the application.", PortValue);
}
      break;
case ZW_LIB_CONTROLLER:
{
             api.Shutdown();
            str.Format("Controller based serial API code detected on port: com%d.nThis application requires an Installer version of the Serial APInon a Z-Wave module connected via a serialport.nDownload the correct Serial API code to the Z-Wave Module and restart the application.", PortValue);
       }
      break;
case ZW_LIB_SLAVE_ENHANCED:
{
   api.Shutdown();
             str.Format("Enhanced Slave based serial API code detected on port: com%d.nThis application requires an Installer version of the Serial APInon a Z-Wave module connected via a serialport.nDownload the correct Serial API code to the Z-Wave Module and restart the application.", PortValue);
       }
      break;
case ZW_LIB_SLAVE:
{
    api.Shutdown();
str.Format("Slave based serial API code detected on port: com%d.nThis application requires an Installer version of the Serial APInon a Z-Wave module connected via a serialport.nDownload the correct Serial API code to the Z-Wave Module and restart the application.", PortValue);
}
      break;
case ZW_LIB_INSTALLER:
{
    char portstr;
sprintf(portstr,"COM%d:",PortValue);
Open(portstr);
sprintf((char *)uCversion,"%s - Installer",uCversion);
}
      break;
default:
{
    api.Shutdown();
            str.Format("This application requires an Installer version of the Z-Wave module connected to the serialport.nnDownload the correct Serial API code to the Z-Wave Module and restart the application.");
}
      break;
}
   }
return libType;
}
/*============================ OnSysCommand ===============================
** Function description
**      System command handler (Prints the About box
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
        }
}
/*============================ OnPaint ===============================
** Function description
**       If you add a minimize button to your dialog, you will need the code below
**       to draw the icon.For MFC applications using the document/view model,
**       this is automatically done for you by the framework.
**      
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
DrawRoutingTable();
}
}
// The system calls this to obtain the cursor to display while the user drags
//the minimized window.
HCURSOR CInstallerToolDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
/*================================= DoDot ====================================
** Function description
**      Paints a scaled square at the relative position given by x and y.
**       Assumes that the resolution is pixels*pixels
** Side effects:
**
**--------------------------------------------------------------------------*/
void DoDot(CDC *dc,       /*IN Device context pointer to update*/
   int x,       /*IN relative x position*/
   int y,       /*IN relative y position*/
   COLORREF color,/*IN Fill color*/
   int pixels,       /*IN x or y number of total pixels for the whole node map*/
   int maxNodes)        /*IN The number of nodes to make room for in the bitmap*/
{
    CBrush bkBrush;
int scale =(int)(((float)pixels)/(float)maxNodes);
int size = scale/2;
int xCenter = scale*x-size;
int yCenter = scale*y-size;
//Create color to use for drawing
bkBrush.CreateSolidBrush(color);
//Set the color
(CBrush*)dc->SelectObject(bkBrush);
dc->Rectangle((xCenter-size),(yCenter-size),(xCenter+size),(yCenter+size));
}
/*============================ IsBitSet =====================================
** Function description
**      Checks if a bit is set in a given nodemask
** Side effects:
**
**--------------------------------------------------------------------------*/
BYTE       /*RET TRUE if bit is set, FALSE if not*/
IsBitSet(BYTE nodeID,       /*IN Node ID to check for*/
BYTE *nodeMask)        /*IN Pointer to the nodemask to use*/
{
BYTE retVal = FALSE;
BYTE byteToLookIn = (nodeID-1)/8;
BYTE bitToLookAt = (nodeID-1)%8;
if(((nodeMask>>bitToLookAt)&0x01)!=0)
retVal = TRUE;
return retVal;
}
/*============================ DrawLegend ===================================
** Function description
**      Draws a color coded legend which shows the colors attached to
**       nodetypes
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::DrawLegend(void)
{
int y;
int scale =sizeof(nodeTypeList)+6;
int size = scale/2;
CStatic *m_test = (CStatic*) GetDlgItem(IDC_LEGEND);
CDC *dc = m_test->GetDC();
CFont font;
//Set the pen and color
font.CreatePointFont(scale*5,"Ariel");
(CFont*)dc->SelectObject(font);
for(y=0;y<sizeof(nodeTypeList);y++)
{
CBrush bkBrush;
bkBrush.CreateSolidBrush(GetNodeColor(nodeTypeList,FALSE));
(CBrush*)dc->SelectObject(bkBrush);
int xCenter = scale*1;
int yCenter = scale*y+size;//-(scale/2);
char txt;
dc->Rectangle((xCenter-2*size),(yCenter-size+1),(xCenter),(yCenter+size-1));
sprintf(txt,"%s",WriteNodeTypeString(nodeTypeList));
dc->TextOut(xCenter+size,yCenter-size,txt);
}
dc->Detach();
}
/*============================GetNodeColor ============================
** Function description
**      Returns the color associated with a given node ID
** Side effects:
**
**--------------------------------------------------------------------------*/
COLORREF CInstallerToolDlg::GetNodeColor(BYTE nodeID, BOOL useID = TRUE)
{
COLORREF color;
BYTE use;
if(useID)
use = nodeType;
else
use = nodeID;
switch(use)
{
case 0:
color = NO_NODE_COLOR;
break;
   case GENERIC_TYPE_GENERIC_CONTROLLER:
color = NODE_GT_COLOR;
break;
   case GENERIC_TYPE_STATIC_CONTROLLER:
           color = NODE_ST_COLOR;
break;
   case GENERIC_TYPE_SWITCH_BINARY:
           color = NODE_SB_COLOR;
break;
   case GENERIC_TYPE_SWITCH_MULTILEVEL:
           color = NODE_SM_COLOR;
break;
   case GENERIC_TYPE_SENSOR_BINARY:
           color = NODE_SENB_COLOR;
break;
   case GENERIC_TYPE_SENSOR_MULTILEVEL:
color = NODE_SENM_COLOR;
break;
   case GENERIC_TYPE_METER_PULSE:
color = NODE_MB_COLOR;
break;
   case GENERIC_TYPE_ENTRY_CONTROL:
color = NODE_EC_COLOR;
break;
default:
color = NODE_UNKNOWN_COLOR;
}
return color;
}
/*============================DrawRoutingTable ============================
** Function description
**      Draws the routing Table from the global array routingTable[][]
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::DrawRoutingTable(void)
{
int x,y;
int nodeToUse=1;
BOOL mirror=FALSE;
CStatic *m_test = (CStatic*) GetDlgItem(IDC_ROUTEMAP);
CDC *dc = m_test->GetDC();
COLORREF color;
CFont font;
    CBrush bkBrush;
//Set the pen and color
font.CreatePointFont(60,"Ariel");
(CFont*)dc->SelectObject(font);
/*Clear the rectangle*/
dc->FillSolidRect(-20,-20,GRAPH_TOPOLOGY_SIZE+20,GRAPH_TOPOLOGY_SIZE+20,dc->GetBkColor());
//Draw the topologi from routingTable[][]
if(bMaxNodeID)
{
for(y=1;y<=bMaxNodeID;y++)
{
for(x=1;x<=bMaxNodeID;x++)
{
if(x==y)
{
color = NO_NODE_COLOR;
}
else if(IsBitSet(x,routingTable))
{
color = NODE_OK_COLOR;
}
else
{
if(nodeType)
color = NODE_BAD_COLOR;
else
color = NO_NODE_COLOR;
}
if(nodeType==0)
color = NO_NODE_COLOR;
DoDot(dc,x,y,color,GRAPH_TOPOLOGY_SIZE,bMaxNodeID);
}
}
/*Draw the legend*/
for(y=1;y<=bMaxNodeID;y++)
{
CBrush bkBrush;
bkBrush.CreateSolidBrush(GetNodeColor(y));
(CBrush*)dc->SelectObject(bkBrush);
int scale =(int)(((float)GRAPH_TOPOLOGY_SIZE)/(float)bMaxNodeID);
int size = scale/2;
int xCenter = 0;
int yCenter = scale*y-(scale/2);
char txt;
if(size>10)
size = 10;
dc->Rectangle((xCenter-2*size),(yCenter-size),(xCenter),(yCenter+size));
sprintf(txt,"%i",y);
if((!(y%5))||(y==1))
{
dc->TextOut(-20,yCenter-5,txt);
dc->TextOut(yCenter-5,-10,txt);
}
}
}/*if Max ID*/
DrawLegend();
}
/*============================ OnTOPOLOGY ===============================
** Function description
**      Called when the Get Topology button is pressed.
**       This function loads the routingtable from the z-wavemodule and
**       prints it out
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::OnTOPOLOGY()
{
//Get the topology from the device module.
//For test purpuse we make a bitmap!
//Get the topology from Z-Wave module
int y;
char txt,i;
/*Reload the nodelist from the module*/
DisplayStandardItems();
for(y=1;y<=bMaxNodeID;y++)
{
if(nodeType)
{
api.ZW_GetRoutingInfo(y,routingTable,FALSE,FALSE);
sprintf(txt,"Reading %i",y);
m_txtStatus.SetWindowText(txt);
}
else
{        /*No node here.. Reset values*/
for(i=0;i<(MAX_NODES/8);i++)
routingTable=0;
}
}
m_txtStatus.SetWindowText("Routing table read!");
DrawRoutingTable();
}
/*============================   TXTestComplete =============================
** Function description
**      Callback function for completion of the TX test
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::TXTestComplete(BYTE txStatus)
{
BYTE command;
char str;
char txt;
char count = api.ZW_GetTXCounter();
int s = selected;
sprintf(str,"%i",count);
if (txStatus != TRANSMIT_COMPLETE_OK)
{
GetInstance()->m_txtStatus.SetWindowText(OPERATION_FAILED_STR);
sprintf(str,"nACK");
}
GetInstance()->SetNodeIDText(s,TX_COUNT,str);
api.ZW_ResetTXCounter();
if(bAbortNow)
{
GetInstance()->m_txtStatus.SetWindowText("User Aborted");
return;
}
/*Transmit to next in line if any*/
if((locateCount<=selectCount)&&(nodeType]!=0))
{
sprintf(txt, "Transmitting to node: %i", selected);
GetInstance()->m_txtStatus.SetWindowText(txt);
command = 0;
command = 0;
GetInstance()->EnableButtons(FALSE);
api.ZW_SendData(selected, command, 2,
TRANSMIT_OPTION_AUTO_ROUTE | TRANSMIT_OPTION_ACK, TXTestComplete);
}
else
{
GetInstance()->EnableButtons(TRUE);
GetInstance()->m_txtStatus.SetWindowText(OPERATION_SUCCESS_STR);
}
GetInstance()->m_txtStatus.SetWindowText(str);
}
/*============================   OnCheckLink =================================
** Function description
**      Makes a NOP operation to the node selected and updates the TX count
**       needed to reach the node.
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::OnCheckLink()
{
BYTE command;
char txt;
api.ZW_ResetTXCounter();
bAbortNow = FALSE;
GetUnitList(selected, &selectCount);
if(selectCount!=0)
{
locateCount = 0;
if((locateCount<=selectCount)&&(nodeType]!=0))
{
sprintf(txt, "Transmitting to node: %i", selected);
m_txtStatus.SetWindowText(txt);
command = 0;
command = 0;
EnableButtons(FALSE);
api.ZW_SendData(selected, command, 2,
TRANSMIT_OPTION_AUTO_ROUTE | TRANSMIT_OPTION_ACK, TXTestComplete);
}
else
m_txtStatus.SetWindowText(OPERATION_FAILED_STR);
}
else
m_txtStatus.SetWindowText(NO_NODES_SELECTED_STR);
}
/*============================ OnGetNeighbors ===============================
** Function description
**      Function called when the Get Neighbour button is pressed.
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::OnGetNeighbors()
{
char txt;
GetUnitList(selected, &selectCount);
bAbortNow = FALSE;
if(selectCount!=0)
{
locateCount = 0;
if((locateCount<=selectCount)&&(nodeType]!=0))
{
sprintf(txt,"Getting neighbors for: %i",selected);
m_txtStatus.SetWindowText(txt);
GetInstance()->EnableButtons(FALSE);
api.ZW_RequestNodeNeighborUpdate(selected, GettingRouting);
}
else
m_txtStatus.SetWindowText(INVALID_NODE_SELECT_STR);
}else
m_txtStatus.SetWindowText(NO_NODES_SELECTED_STR);
}
/*============================ OnDrawItem ===============================
** Function description
**      
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
}
/*============================ NeighborDiscovery_Compl====================
** Function description
**      Callback function Called when neighbour discovery terminates.
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::NeighborDiscovery_Compl(BYTE bStatus)
{
char outstr;
if(bStatus == LEARN_STATE_DONE)
{
GetInstance()->m_txtStatus.SetWindowText("Discovery success");
}
if(bStatus == LEARN_STATE_FAIL)
{
sprintf(outstr, "Failed at Node %d ", selected);
GetInstance()->m_txtStatus.SetWindowText(outstr);
}
if (bStatus != LEARN_STATE_ROUTING_PENDING)
{
GetInstance()->EnableButtons(TRUE);
GetInstance()->OnTOPOLOGY();
}
}
/*============================GettingRouting ==============================
** Function description
**      Runs through the selected nodes and updates their neighbour information
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::GettingRouting(BYTE bStatus)
{
char txt;
if (bStatus != LEARN_STATE_ROUTING_PENDING)
{
if(bAbortNow)
{
GetInstance()->m_txtStatus.SetWindowText("User Aborted");
return;
}
if(bStatus==LEARN_STATE_DONE)
{
if((locateCount<selectCount)&&(nodeType]!=0))
{
sprintf(txt,"Getting neighbors for: %i",selected);
GetInstance()->m_txtStatus.SetWindowText(txt);
api.ZW_RequestNodeNeighborUpdate(selected, GettingRouting);
}
else
NeighborDiscovery_Compl(LEARN_STATE_DONE);
}
else
{
NeighborDiscovery_Compl(LEARN_STATE_FAIL);
sprintf(txt,"Neighbors for: %i failed",selected);
GetInstance()->m_txtStatus.SetWindowText(txt);
}
}
}
/*============================ OnLocateNode ===============================
** Function description
**      
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::OnLocateNode(void)
{
// TODO: Add your control notification handler code here
}
/*============================ OnReplRec ====================================
** Function description
**      Called when the replication receive button is pressed.
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::OnReplRec(void)
{
// TODO: Add your control notification handler code here
unsigned char i;
EnableButtons(FALSE);
m_txtStatus.SetWindowText("Resetting remote ....");
/*Reset local nodelist*/
for(i=1;i<=ZW_MAX_NODES;i++)
AddNode(i,0);
::PostMessage(this_hWnd, WM_USER+4, 0, 0); /*Signal*/
}
/*============================ OnReceiveRemoteData ==========================
** Function description
**      Sets the controller in replication receive mode
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::OnReceiveRemoteData()
{
//        ResetTables();
replSend = FALSE;
m_txtStatus.SetWindowText("Remote reset");
api.ZW_SetLearnMode(TRUE,CopyRemoteComplete);
//        api.ZW_NewController(NEW_CTRL_STATE_RECEIVE, CopyRemoteComplete);
}
/*============================ CopyRemoteComplete ===========================
** Function description
**      Callback function called during replication.
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::CopyRemoteComplete(
BYTE bStatus,// INStatus of learn process
BYTE bSource,// INNode id of the node that send node info
BYTE* pCmd,    // INPointer to Node information
BYTE bLen)   // INNode info length
{
bLen = bLen;
        pCmd = pCmd;

BYTE bVer = 0;
BYTE bCapab = 0;
if (bStatus == LEARN_MODE_STARTED)
{
       /*Disable Abort Button once we are started*/
       GetInstance()->m_btnAbortAction.EnableWindow(FALSE);
       GetInstance()->m_txtStatus.SetWindowText("Replication started");
}
else if (bStatus == LEARN_MODE_FAILED)
{
           GetInstance()->ReloadNodeList();
       GetInstance()->m_txtStatus.SetWindowText("Replication failed");
       GetInstance()->EnableButtons(TRUE);
       GetInstance()->DisplayStandardItems();
    api.ZW_ControllerChange(CONTROLLER_CHANGE_STOP_FAILED,NULL);
}
else if (bStatus == LEARN_MODE_DONE)
{
/*        if(replSend)
       api.ZW_NewController(NEW_CTRL_STATE_STOP_OK, NULL);
*/
    api.ZW_SetLearnMode(FALSE,NULL);
    GetInstance()->ReloadNodeList();
    GetInstance()->m_txtStatus.SetWindowText("Replication complete");
       GetInstance()->EnableButtons(TRUE);
       GetInstance()->DisplayStandardItems();
}
else
{
    GetInstance()->m_txtStatus.SetWindowText("Unknown Callbackstate");
}
}
/*============================ EnableButtons ===============================
** Function description
**      This function is used to enable and disable the buttons on the
**       InstallerTool
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::EnableButtons(BOOL bEnabled)
{
m_btnRecInfo.EnableWindow(bEnabled);
m_btnRestore.EnableWindow(bEnabled);
m_btnBackup.EnableWindow(bEnabled);
m_btnTopology.EnableWindow(bEnabled);
m_btnAddNode.EnableWindow(bEnabled);
m_btnCheckLink.EnableWindow(bEnabled);
m_btnLocateNode.EnableWindow(bEnabled);
m_btnQuit.EnableWindow(bEnabled);
m_btnResetTool.EnableWindow(bEnabled);
if(secondaryCtrl)
{
m_btnGetNeighbors.EnableWindow(FALSE);
m_btnResetNode.EnableWindow(FALSE);
    m_btnAddNode.EnableWindow(FALSE);
    m_btnHandOverPrimary.EnableWindow(FALSE);
}
else
{
m_btnGetNeighbors.EnableWindow(bEnabled);
m_btnResetNode.EnableWindow(bEnabled);
    m_btnAddNode.EnableWindow(bEnabled);
    m_btnHandOverPrimary.EnableWindow(bEnabled);
}
/*Only enable Abort button, Disabling is handled seperatly*/
if(bEnabled==TRUE)
m_btnAbortAction.EnableWindow(bEnabled);
}
/*===========================================================
** Function description
**      
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::OnSelchangeList2()
{
// TODO: Add your control notification handler code here
}
/*============================   WriteNodeTypeString ========================
** Function description
**      Returns a CString containing a fitting name to the nodetype supplied
** Side effects:
**
**--------------------------------------------------------------------------*/
CString CInstallerToolDlg::WriteNodeTypeString(BYTE nodeType)
{
switch (nodeType)
   {
   case GENERIC_TYPE_GENERIC_CONTROLLER:
   return "Generic Controller";
   case GENERIC_TYPE_STATIC_CONTROLLER:
         return "Static Controller";
   case GENERIC_TYPE_REPEATER_SLAVE:
         return "Repeater Slave";
   case GENERIC_TYPE_SWITCH_BINARY:
             return "Binary Switch";
   case GENERIC_TYPE_SWITCH_MULTILEVEL:
   return "Multilevel Switch";
   case GENERIC_TYPE_SENSOR_BINARY:
   return "Binary Sensor";
   case GENERIC_TYPE_SENSOR_MULTILEVEL:
   return "Multilevel Sensor";
   case GENERIC_TYPE_METER_PULSE:
   return "Pulse Meter";
       case GENERIC_TYPE_ENTRY_CONTROL:
         return "Entry control";
   case 0:       /* No NodeID */
   return "No device";
   default:
   return "Unknown Device type";
}
}
/*=============================== OnExit ===================================
** Function description
**      Called when the Quit button is pressed.
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::OnExit()
{
api.Shutdown();
EndDialog(IDCANCEL);
}
/*============================   OnAddNode =================================
** Function description
**      Includes a new node to the network
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::OnAddNode()
{
m_txtStatus.SetWindowText("Press button on Unit");
EnableButtons(FALSE);
api.ZW_AddNodeToNetwork(ADD_NODE_ANY,SetLearnNodeState_Compl);
//api.ZW_SetLearnNodeState(LEARN_NODE_STATE_NEW,SetLearnNodeState_Compl);
}
/*============================ SetLearnNodeState_Compl ======================
** Function description
**      Called when a new node have been added
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::SetLearnNodeState_Compl(
BYTE bStatus, /*IN Status of learn process*/
BYTE bSource, /*IN Node ID of node learned*/
BYTE *pCmd,          /*IN Pointer to node information*/
BYTE bLen)          /*IN Length of node information*/
{
if(bLen!=0)
{
      NODEINFO nodeInfo;
      api.ZW_GetNodeProtocolInfo(bSource, &nodeInfo);
/*Only store learned node type when length is != 0*/
      if (nodeInfo.nodeType.basic<BASIC_TYPE_SLAVE)
      {
         lastLearnedNodeType = nodeInfo.nodeType.basic;/*For now we store the learned basic node type*/
      }
      else
      {
         lastLearnedNodeType = nodeInfo.nodeType.generic; /* Store learned generic node type*/
      }
lastLearnedNodeID = bSource;
}
switch(bStatus)
{
    case ADD_NODE_STATUS_LEARN_READY:
      break;
    case ADD_NODE_STATUS_NODE_FOUND:
             /*Disable Abort button*/
           GetInstance()->m_btnAbortAction.EnableWindow(FALSE);
    GetInstance()->m_txtStatus.SetWindowText("Waiting ...");
      break;
    case ADD_NODE_STATUS_ADDING_SLAVE:
    GetInstance()->m_txtStatus.SetWindowText("Adding slave unit...");
      break;
    case ADD_NODE_STATUS_ADDING_CONTROLLER:
    GetInstance()->m_txtStatus.SetWindowText("Adding Controller unit...");
      break;
    case ADD_NODE_STATUS_PROTOCOL_DONE:
    case ADD_NODE_STATUS_DONE:
      api.ZW_AddNodeToNetwork(ADD_NODE_STOP,NULL);
        GetInstance()->m_txtStatus.SetWindowText("Node included ...");
GetInstance()->AddNode(lastLearnedNodeID,lastLearnedNodeType);
       GetInstance()->DisplayStandardItems();
      GetInstance()->ReloadNodeList();
       GetInstance()->EnableButtons(TRUE);
      break;
    case ADD_NODE_STATUS_FAILED:
    default:
/*If were not pending, we want to turn off learn mode..*/
       GetInstance()->EnableButtons(TRUE);
      api.ZW_AddNodeToNetwork(ADD_NODE_STOP,NULL);
       GetInstance()->DisplayStandardItems();
GetInstance()->m_txtStatus.SetWindowText(OPERATION_FAILED_STR);
      break;
}
}
/*============================ OnResetNode ===============================
** Function description
**      Called when the Reset Node button is called
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::OnResetNode()
{
m_txtStatus.SetWindowText("Press button on Unit");
EnableButtons(FALSE);
api.ZW_RemoveNodeFromNetwork(REMOVE_NODE_ANY,SetLearnNodeStateDelete_Compl);
//        api.ZW_SetLearnNodeState(LEARN_NODE_STATE_DELETE,SetLearnNodeStateDelete_Compl);
}
/*============================ SetLearnNodeStateDelete_Compl ================
** Function description
**      Callback function for when deleting a node
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::SetLearnNodeStateDelete_Compl(BYTE bStatus,
BYTE bSource,
BYTE *pCmd,
BYTE bLen)
{
switch(bStatus)
{
    case REMOVE_NODE_STATUS_LEARN_READY:
      break;
    case REMOVE_NODE_STATUS_NODE_FOUND:
/*Disable Abort button*/
GetInstance()->m_btnAbortAction.EnableWindow(FALSE);
GetInstance()->m_txtStatus.SetWindowText("Waiting..");
      break;
    case REMOVE_NODE_STATUS_REMOVING_SLAVE:
    case REMOVE_NODE_STATUS_REMOVING_CONTROLLER:
GetInstance()->m_txtStatus.SetWindowText("Node reset..");
GetInstance()->RemoveNodeFromList(bSource);
GetInstance()->AddNode(bSource,0);
    case REMOVE_NODE_STATUS_DONE:
GetInstance()->EnableButtons(TRUE);
      api.ZW_AddNodeToNetwork(REMOVE_NODE_STOP,NULL);
GetInstance()->DisplayStandardItems();
      break;
    case REMOVE_NODE_STATUS_FAILED:
    default:
/*If were not pending, we want to turn off learn mode..*/
GetInstance()->EnableButtons(TRUE);
    api.ZW_AddNodeToNetwork(REMOVE_NODE_STOP,NULL);
GetInstance()->DisplayStandardItems();
GetInstance()->m_txtStatus.SetWindowText(OPERATION_FAILED_STR);
      break;
}
}
/*============================ SetDefault_Compl ==============================
** Function description
**      Callback function for resetting Z-Wave module
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::SetDefault_Compl()
{
GetInstance()->ReloadNodeList();
GetInstance()->DisplayStandardItems();
GetInstance()->EnableButtons(TRUE);
GetInstance()->OnTOPOLOGY();
}
/*============================ OnResetTool ==================================
** Function description
**      Called when Reset Tool button is pressed
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::OnResetTool()
{
EnableButtons(FALSE);
m_txtStatus.SetWindowText("Resetting Installer Tool..");
api.ZW_SetDefault(SetDefault_Compl);
}
/*============================ OnMouseMove ==============================
** Function description
**      Called when the mouse is moved. This place is used to update
**       the text associated with the routing table
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::OnMouseMove(UINT nFlags, CPoint point)
{
CStatic *m_test = (CStatic*) GetDlgItem(IDC_ROUTEMAP);
CDC *dc = m_test->GetDC();
POINT mypoint;
RECT rect;
char txt;
if(bMaxNodeID)
{
int scale =(int)(((float)GRAPH_TOPOLOGY_SIZE)/(float)bMaxNodeID);
int xCenter = 0;
int yCenter = 0;
CDialog::OnMouseMove(nFlags, point);
/*Get the coords of static*/
m_test->GetWindowRect(&rect);
mypoint.x = rect.left;
mypoint.y = rect.top;
ScreenToClient(&mypoint);
mypoint.x = point.x-mypoint.x;
mypoint.y = point.y-mypoint.y;
/*Calculate node number*/
xCenter = mypoint.x/scale+1;
yCenter = mypoint.y/scale+1;
if((xCenter>0)&&(xCenter<=bMaxNodeID)&&
(yCenter>0)&&(yCenter<=bMaxNodeID))
{
sprintf(txt,"%s(%i),%s(%i)",WriteNodeTypeString(nodeType),yCenter,
WriteNodeTypeString(nodeType),xCenter);
m_txtNodePoint.SetWindowText(txt);
}
}
}
/*============================   TestNodeSetComplete   =======================
** Function description
**      Callback function for completion of the TX test
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::TestNodeSetComplete(BYTE command)
{
UINT testFrames = GetInstance()->m_uintFrames;
if (command != TRANSMIT_COMPLETE_OK)
{
GetInstance()->m_txtLQResult.SetWindowText(OPERATION_FAILED_STR);
GetInstance()->EnableButtons(TRUE);
}
else
{
GetInstance()->m_txtLQResult.SetWindowText("Link check started");
GetInstance()->timerID.timeOutCount = testFrames*4,5+1; //Time out in 0.1 sec
GetInstance()->timerID.eventID = GetInstance()->SetTimer(REPORT_LEVEL_TIMEOUT,TIMEOUT_TIME,NULL); //Run it every 100ms
}
}
/*============================ OnLButtonDblClk ==============================
** Function description
**      Called when the Left mouse button is double clicked.
**       This is used to handle events when doubleclicking the routing table
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::OnLButtonDblClk(UINT nFlags, CPoint point)
{
CStatic *m_test = (CStatic*) GetDlgItem(IDC_ROUTEMAP);
CDC *dc = m_test->GetDC();
POINT mypoint;
RECT rect;
ZW_APPLICATION_TX_BUFFER command;
if(bMaxNodeID)
{
int scale =(int)(((float)GRAPH_TOPOLOGY_SIZE)/(float)bMaxNodeID);
int xCenter = 0;
int yCenter = 0;
CDialog::OnLButtonDblClk(nFlags, point);
m_test->GetWindowRect(&rect);
mypoint.x = rect.left;
mypoint.y = rect.top;
ScreenToClient(&mypoint);
mypoint.x = point.x-mypoint.x;
mypoint.y = point.y-mypoint.y;
/*Calculate node number, from coord*/
xCenter = mypoint.x/scale+1;
yCenter = mypoint.y/scale+1;
/*If we are within node table then select the nodes in the list box*/
if((xCenter>0)&&(xCenter<=bMaxNodeID)&&
(yCenter>0)&&(yCenter<=bMaxNodeID)&&
(xCenter!=yCenter))
{
EnableButtons(FALSE);
CListBox *m_NodeTable = (CListBox*) GetDlgItem(IDC_LIST2);
m_NodeTable->SetSel(xCenter-1);
m_NodeTable->SetSel(yCenter-1);
command.ZW_PowerLevelTestNodeSetFrame.cmd = POWERLEVEL_TEST_NODE_SET;
command.ZW_PowerLevelTestNodeSetFrame.cmdClass = COMMAND_CLASS_POWERLEVEL;
command.ZW_PowerLevelTestNodeSetFrame.nodeId = xCenter;
if(m_cTXLevel.GetCurSel()!=CB_ERR)
{
timerID.nodeID = yCenter;
command.ZW_PowerLevelTestNodeSetFrame.powerLevel = m_cTXLevel.GetCurSel();
command.ZW_PowerLevelTestNodeSetFrame.testFrameCountMsb = m_uintFrames>>8;
command.ZW_PowerLevelTestNodeSetFrame.testFrameCountLsb = m_uintFrames;
api.ZW_SendData(yCenter,&command.ZW_PowerLevelTestNodeSetFrame.cmdClass,sizeof(ZW_POWERLEVEL_TEST_NODE_SET_FRAME),
TRANSMIT_OPTION_AUTO_ROUTE | TRANSMIT_OPTION_ACK,TestNodeSetComplete);
}
else
{
m_txtLQResult.SetWindowText("Error select Power level");
EnableButtons(TRUE);
}
}
} /*bMaxNodeID*/
}
void CInstallerToolDlg::OnChangeEdit1()
{
// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CDialog::OnInitDialog()
// function and call CRichEditCtrl().SetEventMask()
// with the ENM_CHANGE flag ORed into the mask.
UpdateData(TRUE);
// TODO: Add your control notification handler code here
}
void CInstallerToolDlg::OnEditchangeCombo1()
{
// TODO: Add your control notification handler code here
}
/*============================   TestNodeGetComplete   =======================
** Function description
**      Callback function for completion of the TX test
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::TestNodeGetComplete(BYTE command)
{
BYTE i, nodeCount=0;
if (command != TRANSMIT_COMPLETE_OK)
{
GetInstance()->m_txtLQResult.SetWindowText(OPERATION_FAILED_STR);
GetInstance()->EnableButtons(TRUE);
}
else
{
GetInstance()->m_txtLQResult.SetWindowText("Link check started");
/*Calculate timeout in ms.*/
for(i=1;i<=bMaxNodeID;i++)
if(nodeType!=0)
nodeCount++;
GetInstance()->timerID.timeOutCount = 10; //1 secs timeout on this one
GetInstance()->timerID.eventID = GetInstance()->SetTimer(GET_LEVEL_TIMEOUT,TIMEOUT_TIME,NULL);
}
}
/*============================   GetPowerLevelResult   =======================
** Function description
**      Function to request result of a TX test
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::GetPowerLevelResult(
BYTE nodeID) // Node ID to get result from
{
ZW_APPLICATION_TX_BUFFER command;
command.ZW_PowerLevelTestNodeGetFrame.cmdClass = COMMAND_CLASS_POWERLEVEL;
command.ZW_PowerLevelTestNodeGetFrame.cmd = POWERLEVEL_TEST_NODE_GET;
api.ZW_SendData(nodeID, &command.ZW_PowerLevelTestNodeGetFrame.cmdClass,
sizeof(ZW_POWERLEVEL_TEST_NODE_GET_FRAME),
TRANSMIT_OPTION_AUTO_ROUTE | TRANSMIT_OPTION_ACK,
TestNodeGetComplete);
}
/*============================   OnTimer===================================
** Function description
**      Windows timer handling.. This function handles ON_TIMER events for
**       the InstallerTool
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
CDialog::OnTimer(nIDEvent);
if((--timerID.timeOutCount==0))
{
switch(nIDEvent)
{
case REPORT_LEVEL_TIMEOUT:
if(timerID.nodeID)
GetPowerLevelResult(timerID.nodeID);
else
{
m_txtLQResult.SetWindowText("Error undefined node");
EnableButtons(TRUE);
}
break;
case GET_LEVEL_TIMEOUT:
m_txtLQResult.SetWindowText("Error no response");
EnableButtons(TRUE);
break;
}
/*We only support one timer at a time so kill the timer*/
KillTimer(nIDEvent);
}
}
/*============================   OnHandOverPrimary==========================
** Function description
**      This function is called when the user wants to hand over the primary
**       controller status to another controller. Typically this would be done
**       when the Installation of the network is complete and configured.
**
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::OnHandOverPrimary()
{
// TODO: Add your control notification handler code here
EnableButtons(FALSE);
replSend = TRUE;
m_txtStatus.SetWindowText("Waiting for Receiving Controller..");
api.ZW_ControllerChange(CONTROLLER_CHANGE_START,SetLearnNodeState_Compl);
//        api.ZW_NewController(NEW_CTRL_STATE_CHANGE, CopyRemoteComplete);
}
/*============================   OnAbortButton==========================
** Function description
**      Used to abort selected operations before they have started.
**       Button is disabled once a protocol operation is in progress.
**
** Side effects:
**
**--------------------------------------------------------------------------*/
void CInstallerToolDlg::OnAbortButton()
{
// TODO: Add your control notification handler code here
//        api.ZW_NewController(NEW_CTRL_STATE_ABORT,NULL);
//        api.ZW_SetLearnNodeState(LEARN_NODE_STATE_OFF,NULL);
   api.ZW_AddNodeToNetwork(ADD_NODE_STATUS_DONE,NULL);
bAbortNow = TRUE;
EnableButtons(TRUE);
m_txtStatus.SetWindowText("Action Aborted by user");
}
//////////////////////////////////////////////////////////////////////////////
//Following functions are used in the RoadMap file...
//
//
/////////////////////////////////////////////////////////////////////////////
BYTE CInstallerToolDlg::NodeGetType(BYTE NodeNumber)
{
    unitType = nodeType;
    if(unitType != 0)
       return NodeNumber;
    else
    return 0;
}
// Find the neighbours used in RoadMap
int CInstallerToolDlg::FindNeighbours(int x, int y)
{
    if(IsBitSet(x,routingTable))
{
    return x;
}
    return 0;
}
// Get MaxNodeId for for RoadMap
BYTE CInstallerToolDlg::GetMaxNodes()
{
    return bMaxNodeID;
}
void CInstallerToolDlg::Mesh()
{
    //Reload the nodelist from the module
for(int y=1;y<=bMaxNodeID;y++)
{
if(nodeType)
{
api.ZW_GetRoutingInfo(y,routingTable,FALSE,FALSE);
}
else
{        //No node here.. Reset values
for(int i=0;i<(MAX_NODES/8);i++)
routingTable=0;
}
}
}
//void CInstallerToolDlg::PowerOnOff(BYTE *RoadList , BYTE numberUnits,void(__cdecl *completedFunc)(BYTE *txStatus))
void CInstallerToolDlg::PowerOnOff(BYTE *RoadList , BYTE numberUnits)
{
    ZW_APPLICATION_TX_BUFFER command;
command.ZW_BasicSetFrame.cmdClass = COMMAND_CLASS_BASIC;
    command.ZW_BasicSetFrame.cmd = BASIC_SET;
#if 1
if (nodeState])
{
nodeState] = 0;
    command.ZW_BasicSetFrame.value = SWITCHED_OFF;
}
else
{
nodeState] = 1;
    command.ZW_BasicSetFrame.value = SWITCHED_ON;
}
#else
    command.ZW_BasicSetFrame.value = SWITCHED_ON;
#endif
   api.ZW_SendDataMulti(RoadList, numberUnits, &command.ZW_BasicSetFrame.cmdClass, sizeof(ZW_BASIC_SET_FRAME), TRANSMIT_OPTION_AUTO_ROUTE | TRANSMIT_OPTION_ACK , RouteOnCompleted);
}
void CInstallerToolDlg::RouteOnCompleted(BYTE command)
{
}
void CInstallerToolDlg::AllOff()
{
    ZW_APPLICATION_TX_BUFFER command;
command.ZW_Common.cmdClass = COMMAND_CLASS_SWITCH_ALL;
command.ZW_Common.cmd = SWITCH_ALL_OFF;
api.ZW_SendData(NODE_BROADCAST, &command.ZW_Common.cmdClass, sizeof(ZW_ALL_SWITCH_OFF_FRAME), TRANSMIT_OPTION_AUTO_ROUTE | TRANSMIT_OPTION_ACK, NULL);
}
void CInstallerToolDlg::SetSUCCompleted(BYTE bStatus)
{
if(ZW_SUC_SET_SUCCEEDED)
GetInstance()->m_txtStatus.SetWindowText("Set SUC Success..");
else
GetInstance()->m_txtStatus.SetWindowText("Set SUC failed");
}
void CInstallerToolDlg::OnBnClickedButton14()
{
// TODO: Add your control notification handler code here
BYTE nodeID = api.ZW_GetSUCNodeID();
if(!nodeID)
while((nodeType!=GENERIC_TYPE_STATIC_CONTROLLER)&&(nodeID<232))
nodeID++;
else
SetSUCCompleted(ZW_SUC_SET_SUCCEEDED);
if(nodeType==GENERIC_TYPE_STATIC_CONTROLLER)
      api.ZW_SetSUCNodeID(nodeID,TRUE,FALSE,SetSUCCompleted);
else
m_txtStatus.SetWindowText("No static controller");
}
HANDLE CInstallerToolDlg::Open(char *szComPort)
{
    hComm = CreateFile(szComPort, GENERIC_READ | GENERIC_WRITE,0, NULL, OPEN_EXISTING, NULL, NULL);
if (hComm != INVALID_HANDLE_VALUE)
{
    CloseHandle(hComm);
}
    return hComm;
}


页: [1]
查看完整版本: installertooldlg.cpp:源码内容