| 复制代码/*******************************  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_FILEstatic 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 0x02CSerialAPI api;BYTE nodeType[255];BYTE lastLearnedNodeID;BYTE lastLearnedNodeType;BYTE RoadList[6];static void *this_instance;static HWND this_hWnd;BYTE locateCount;BOOL replSend;int selected[255];BYTE selectCount;static BYTE routingTable[232][232/8];BOOL secondaryCtrl;char uCversion[40];BYTE bAbortNow = FALSE;/////////////////////////////////////////////////////////////////////////////// CAboutDlg dialog used for App Aboutclass 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// Implementationprotected://{{AFX_MSG(CAboutDlg)//}}AFX_MSGDECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD){//{{AFX_DATA_INIT(CAboutDlg)m_txtVersion = _T("");m_txtDevVer = _T("");//}}AFX_DATA_INITchar str[80];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_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CInstallerToolDlg dialogCInstallerToolDlg::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 Win32m_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 >= 1300ON_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)#elseON_MESSAGE(WM_USER+2, EnableUI)ON_MESSAGE(WM_USER+4, OnReceiveRemoteData)#endifON_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[nid] = ntype;while((nodeType[i]==0)&&(i>0))i--;if(i)bMaxNodeID = i;elsebMaxNodeID = 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[4];int item;memset(buf4, 0, sizeof(buf4));lfv.flags = LVFI_STRING;  // Search on parmeterlfv.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[k++] = 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[100];BYTE HomeId[4];BYTE NodeId;NODEINFO nodeInfo;char txt[40];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[i] = 0;for (i=0;i<bLen;i++){if (bNodes[i] != 0){bFound = TRUE;for (j=0;j<8;j++){if (bNodes[i] & (1<<j)){sprintf(txt,"Reading %i nodelist",byNode);m_txtStatus.SetWindowText(txt);api.ZW_GetNodeProtocolInfo(byNode, &nodeInfo);nodeType[byNode] = nodeInfo.nodeType.generic;bMaxNodeID = byNode;}    byNode++;}}elsebyNode += 8;}return bFound;}/*============================ DisplayStandardItems ==========================** Function description**      Displays the nodeTable, Home ID and other standard items** Side effects:****--------------------------------------------------------------------------*/void CInstallerToolDlg::DisplayStandardItems(void){char buffer[50];char a[50];BYTE HomeId[4];BYTE NodeId;int item;char buf4[4];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[i+1]!=0){if(NodeId == (i+1))sprintf(buffer, "This node");elsesprintf(buffer, "%s",WriteNodeTypeString(nodeType[i+1]));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[0],HomeId[1],HomeId[2],HomeId[3],NodeId);GetInstance()->m_txtHomeId.SetWindowText(a);GetInstance()->m_txtNodePoint.SetWindowText("...");GetInstance()->m_txtHomeId.UpdateWindow();}void CInstallerToolDlg::RemoveNodeFromList(BYTE bSource){   char buf4[4];   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[80];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 dialogSetIcon(m_hIcon, TRUE);         // Set big iconSetIcon(m_hIcon, FALSE);         // Set small iconthis_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;#elsebySpeed = CSerialAPI.SPEED_115200;#endiflSpeed  = 115200;for (int i = 1; i < __argc; i++){LPCTSTR pszParam = __argv[i];if (pszParam[0] == '-' || pszParam[0] == '/'){++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;#elsebySpeed = CSerialAPI.SPEED_19200;#endiflSpeed = 19200;}else if (lstrcmpi(pszParam,"speed=57600") == 0){#if _MSC_VER >= 1300            bySpeed = CSerialAPI::SPEED_57600;#else            bySpeed = CSerialAPI.SPEED_57600;#endiflSpeed = 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[40];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[1];APPL_NODE_TYPE appType;ca[0] = 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[4];  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 TRUE  unless 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[8];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 paintingSendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);// Center icon in client rectangleint 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 icondc.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 drawingbkBrush.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[byteToLookIn]>>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 colorfont.CreatePointFont(scale*5,"Ariel");(CFont*)dc->SelectObject(font);for(y=0;y<sizeof(nodeTypeList);y++){CBrush bkBrush;bkBrush.CreateSolidBrush(GetNodeColor(nodeTypeList[y],FALSE));(CBrush*)dc->SelectObject(bkBrush);int xCenter = scale*1;int yCenter = scale*y+size;//-(scale/2);char txt[40];dc->Rectangle((xCenter-2*size),(yCenter-size+1),(xCenter),(yCenter+size-1));sprintf(txt,"%s",WriteNodeTypeString(nodeTypeList[y]));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[nodeID];elseuse = 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 colorfont.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[y-1])){color = NODE_OK_COLOR;}else {if(nodeType[x])color = NODE_BAD_COLOR;elsecolor = NO_NODE_COLOR;}if(nodeType[y]==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[4];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 moduleint y;char txt[20],i;/*Reload the nodelist from the module*/DisplayStandardItems();for(y=1;y<=bMaxNodeID;y++){if(nodeType[y]){api.ZW_GetRoutingInfo(y,routingTable[y-1],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[y-1][i]=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[10];char str[40];char txt[40];char count = api.ZW_GetTXCounter();int s = selected[locateCount-1];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[selected[locateCount]]!=0)){sprintf(txt, "Transmitting to node: %i", selected[locateCount]);GetInstance()->m_txtStatus.SetWindowText(txt);command[CMDBUF_CMDCLASS_OFFSET] = 0;command[CMDBUF_CMD_OFFSET] = 0;GetInstance()->EnableButtons(FALSE);api.ZW_SendData(selected[locateCount++], 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[10];char txt[40];api.ZW_ResetTXCounter();bAbortNow = FALSE;GetUnitList(selected, &selectCount);if(selectCount!=0){locateCount = 0;if((locateCount<=selectCount)&&(nodeType[selected[locateCount]]!=0)){sprintf(txt, "Transmitting to node: %i", selected[locateCount]);m_txtStatus.SetWindowText(txt);command[CMDBUF_CMDCLASS_OFFSET] = 0;command[CMDBUF_CMD_OFFSET] = 0;EnableButtons(FALSE);api.ZW_SendData(selected[locateCount++], command, 2,TRANSMIT_OPTION_AUTO_ROUTE | TRANSMIT_OPTION_ACK, TXTestComplete);}elsem_txtStatus.SetWindowText(OPERATION_FAILED_STR);}elsem_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[40];GetUnitList(selected, &selectCount);bAbortNow = FALSE;if(selectCount!=0){locateCount = 0;if((locateCount<=selectCount)&&(nodeType[selected[locateCount]]!=0)){sprintf(txt,"Getting neighbors for: %i",selected[locateCount]);m_txtStatus.SetWindowText(txt);GetInstance()->EnableButtons(FALSE);api.ZW_RequestNodeNeighborUpdate(selected[locateCount++], GettingRouting);}elsem_txtStatus.SetWindowText(INVALID_NODE_SELECT_STR);}elsem_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[255];if(bStatus == LEARN_STATE_DONE){GetInstance()->m_txtStatus.SetWindowText("Discovery success");}if(bStatus == LEARN_STATE_FAIL){sprintf(outstr, "Failed at Node %d ", selected[locateCount-1]);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[40];if (bStatus != LEARN_STATE_ROUTING_PENDING){if(bAbortNow){GetInstance()->m_txtStatus.SetWindowText("User Aborted");return;}if(bStatus==LEARN_STATE_DONE){if((locateCount<selectCount)&&(nodeType[selected[locateCount]]!=0)){sprintf(txt,"Getting neighbors for: %i",selected[locateCount]);GetInstance()->m_txtStatus.SetWindowText(txt);api.ZW_RequestNodeNeighborUpdate(selected[locateCount++], GettingRouting);}elseNeighborDiscovery_Compl(LEARN_STATE_DONE);}else{NeighborDiscovery_Compl(LEARN_STATE_FAIL);sprintf(txt,"Neighbors for: %i failed",selected[locateCount-1]);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 hereunsigned 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,  // IN  Status of learn process  BYTE bSource,  // IN  Node id of the node that send node info  BYTE* pCmd,    // IN  Pointer to Node information  BYTE bLen)     // IN  Node 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[100];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]),yCenter,WriteNodeTypeString(nodeType[xCenter]),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 secGetInstance()->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[i]!=0)nodeCount++;GetInstance()->timerID.timeOutCount = 10; //1 secs timeout on this oneGetInstance()->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 defaultCDialog::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 hereEnableButtons(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[NodeNumber];    if(unitType != 0)       return NodeNumber;    else     return 0;}// Find the neighbours used in RoadMapint CInstallerToolDlg::FindNeighbours(int x, int y){    if(IsBitSet(x,routingTable[y-1])){    return x;}    return 0;}// Get MaxNodeId for for RoadMapBYTE CInstallerToolDlg::GetMaxNodes(){    return bMaxNodeID;}void CInstallerToolDlg::Mesh() {    //Reload the nodelist from the modulefor(int y=1;y<=bMaxNodeID;y++){if(nodeType[y]){api.ZW_GetRoutingInfo(y,routingTable[y-1],FALSE,FALSE);}else{        //No node here.. Reset valuesfor(int i=0;i<(MAX_NODES/8);i++)routingTable[y-1][i]=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 1if (nodeState[RoadList[0]]){nodeState[RoadList[0]] = 0;    command.ZW_BasicSetFrame.value = SWITCHED_OFF;}else{nodeState[RoadList[0]] = 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..");elseGetInstance()->m_txtStatus.SetWindowText("Set SUC failed");}void CInstallerToolDlg::OnBnClickedButton14(){// TODO: Add your control notification handler code hereBYTE nodeID = api.ZW_GetSUCNodeID();if(!nodeID)while((nodeType[nodeID]!=GENERIC_TYPE_STATIC_CONTROLLER)&&(nodeID<232))nodeID++;elseSetSUCCompleted(ZW_SUC_SET_SUCCEEDED);if(nodeType[nodeID]==GENERIC_TYPE_STATIC_CONTROLLER)        api.ZW_SetSUCNodeID(nodeID,TRUE,FALSE,SetSUCCompleted);elsem_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;}
 |