📄 netelectronsrvdlg.cpp
字号:
m_nWaterHeaterOpenOrClose = pJiadianState->nWaterHeaterOpenOrClose;
SetDlgItemText ( IDC_STATIC_WATER_HEATER_OPEN_OR_CLOSE,
m_nWaterHeaterOpenOrClose?"开":"关" );
m_nWaterHeaterTemperature = pJiadianState->nWaterHeaterTemperature;
m_nMicroWaveOvenOpenOrClose = pJiadianState->nMicroWaveOvenOpenOrClose;
SetDlgItemText ( IDC_STATIC_MicroWaveOven_OPEN_OR_CLOSE,
m_nMicroWaveOvenOpenOrClose?"开":"关" );
m_nMicroWaveOvenTiming = pJiadianState->nMicroWaveOvenTiming;
m_nCurtainOpenOrClose = pJiadianState->nCurtainOpenOrClose;
SetDlgItemText ( IDC_STATIC_Curtain_OPEN_OR_CLOSE,
m_nCurtainOpenOrClose?"开":"关" );
m_nCurtainTiming = pJiadianState->nCurtainTiming;
UpdateData ( FALSE );
}
void CNetElectronSrvDlg::OnAccept()
{
if ( !m_sockListen.Accept ( m_sockSend ) )
{
Log ( "接受客户连接失败" );
return;
}
m_bSockConnected = TRUE;
Log ( "连接成功,正在身份验证 ..." );
// 身份验证
char str[] = "Password:";
// 发送验证字符串
SendSockData ( str,strlen (str ) + 1 );
m_sockSend.m_CommState = CSTATE_WAIT_PASS;
}
// 处理收到的数据
void CNetElectronSrvDlg::HandleWhenReceivedData(char *pData, int nLen)
{
Log ( "收到数据:%s", Data2String(pData,nLen) );
switch ( m_sockSend.m_CommState )
{
case CSTATE_START:
break;
case CSTATE_WAIT_PASS:
if ( strcmp ( pData, "xhw" ) == 0 ) // 身份验证已经通过
{
Log ( "身份验证已经通过!" );
m_sockSend.m_CommState = CSTATE_LOGINOK;
SendSockData ( (char*)&m_JiaDianState, sizeof(t_JiaDianState) );
}
else
{
char str[] = "Password:";
SendSockData ( str, strlen (str ) + 1 );
}
break;
case CSTATE_LOGINOK:
if ( sizeof(t_JiaDianState) == nLen )
{
if ( memcmp ( &m_JiaDianState, pData, nLen ) != 0 )
{
memcpy ( &m_JiaDianState, pData, nLen );
SetNewStatus ( &m_JiaDianState );
// 将新状态发送给串口
SendNewStatusToCOM ( &m_JiaDianState );
}
}
break;
}
}
void CNetElectronSrvDlg::OnClose()
{
// 关闭所有端口
m_COM.Close();
m_sockSend.Close();
m_sockListen.Close();
m_SrvStart = FALSE;
EnableCtrlWindow ( m_SrvStart );
// 重新启动
OnButtonStartSrv();
}
// 参数:bStart - 服务是否已经启动
void CNetElectronSrvDlg::EnableCtrlWindow( BOOL bStart)
{
m_btnStartSrv.EnableWindow ( !bStart );
GetDlgItem(IDC_EDIT_COM)->EnableWindow ( !bStart );
GetDlgItem(IDC_EDIT_PORT)->EnableWindow ( !bStart );
GetDlgItem(IDC_BUTTON_TEST_COM)->EnableWindow ( bStart );
}
CString CNetElectronSrvDlg::Data2String(char *pData, int nSize)
{
CString csData, csTemp;
for ( int i=0; i<nSize; i++ )
{
csTemp.Format ( "%02x ", (UCHAR)pData[i] );
csData += csTemp;
}
csTemp.Format ("\t-\t%s", pData );
csData += csTemp;
return csData;
}
// 构造一个数据包,返回包长度
int CNetElectronSrvDlg::BuildPkt(t_JiaDianState *pJiaDianState,char *pBuf,int nBufSize)
{
int nCount = 0;
// 空调开关
pBuf[nCount] = pJiaDianState->nKongTiaoOpenOrClose?0x01:0x00;
nCount ++;
ASSERT ( nCount < nBufSize );
// 空调温度
pBuf[nCount] = pJiaDianState->nKongTiaoTemperature;
nCount ++;
ASSERT ( nCount < nBufSize );
// 热水器开关
pBuf[nCount] = pJiaDianState->nWaterHeaterOpenOrClose?0x01:0x00;
nCount ++;
ASSERT ( nCount < nBufSize );
// 热水器温度
pBuf[nCount] = pJiaDianState->nWaterHeaterTemperature;
nCount ++;
ASSERT ( nCount < nBufSize );
// 微波炉开关
pBuf[nCount] = pJiaDianState->nMicroWaveOvenOpenOrClose?0x01:0x00;
nCount ++;
ASSERT ( nCount < nBufSize );
// 微波炉定时
pBuf[nCount] = pJiaDianState->nMicroWaveOvenTiming;
nCount ++;
ASSERT ( nCount < nBufSize );
// 窗帘开关
pBuf[nCount] = pJiaDianState->nCurtainOpenOrClose?0x01:0x00;
nCount ++;
ASSERT ( nCount < nBufSize );
// 窗帘定时
pBuf[nCount] = pJiaDianState->nCurtainTiming;
nCount ++;
ASSERT ( nCount < nBufSize );
return nCount;
}
// 给串口发送AT命令,来测试串口通信是否完好。
void CNetElectronSrvDlg::OnButtonTestCom()
{
UpdateData ( TRUE );
CString csTemp;
csTemp.Format ( "先在串口〖COM%d〗上接好一个modem并打开modem开关,然后就可以开始测试了,测试程序将拨号到〖%s〗,如果modem提机并拨号,说明对串口的操作是正确的,准备好了吗?",
m_nComNo, m_csPhoneNo );
if ( MessageBox ( csTemp, "Question", MB_ICONQUESTION | MB_YESNO ) == IDNO )
return;
char buf[256] = {0};
int nLen = _snprintf((char*)buf,sizeof(buf) - 1,"ATDT%s\r\n",m_csPhoneNo);
Log ( "发送%d字节的串口数据:%s", nLen, Data2String(buf,nLen) );
if ( m_COM.Write ( buf, nLen ) != nLen )
{
csTemp.Format ( "发送数据到串口失败 - %s", m_COM.GetLastErrorString() );
MessageBox ( csTemp, "错误", MB_ICONERROR );
}
else
{
Log ( "发送串口数据成功" );
}
}
// 从串口中读取数据,得到设备当前状态
BOOL CNetElectronSrvDlg::GetDevStatusFromCOM(t_JiaDianState *pJiaDianState)
{
char cComData [ 128*COM_DATA_SIZE ] = {0};
int nReadyDataLen = m_COM.GetCommInputBuffLen();
if ( nReadyDataLen < 1 )
{
// Log ( "串口〖COM%d〗中没有足够的数据可以读取", m_nComNo );
return FALSE;
}
int nComDataLen = m_COM.Read ( cComData, nReadyDataLen );
if ( nComDataLen <= 0 )
{
Log ( "从串口中读数据出错!" );
return FALSE;
}
Log ( "从串口〖COM%d〗读到%d字节数据:%s", m_nComNo, nComDataLen, Data2String(cComData,nComDataLen) );
if ( nComDataLen < COM_DATA_SIZE )
{
Log ( "读到 %d 字节数据,不够一个包长度(%d字节)", nComDataLen, COM_DATA_SIZE );
return FALSE;
}
int nCount = 0;
// 空调开关
pJiaDianState->nKongTiaoOpenOrClose = cComData[nCount];
nCount ++;
// 空调温度
pJiaDianState->nKongTiaoTemperature = cComData[nCount];
nCount ++;
// 热水器开关
pJiaDianState->nWaterHeaterOpenOrClose = cComData[nCount];
nCount ++;
// 热水器温度
pJiaDianState->nWaterHeaterTemperature = cComData[nCount];
nCount ++;
// 微波炉开关
pJiaDianState->nMicroWaveOvenOpenOrClose = cComData[nCount];
nCount ++;
// 微波炉定时
pJiaDianState->nMicroWaveOvenTiming = cComData[nCount];
nCount ++;
// 窗帘开关
pJiaDianState->nCurtainOpenOrClose = cComData[nCount];
nCount ++;
// 窗帘定时
pJiaDianState->nCurtainTiming = cComData[nCount];
nCount ++;
return TRUE;
}
// 从串口中取最新的家电状态,并处理这些最新的状态
void CNetElectronSrvDlg::GetAndHandleNewSTFromCOM()
{
t_JiaDianState JiaDianState;
if ( !GetDevStatusFromCOM ( &JiaDianState ) )
return;
if ( memcmp ( &JiaDianState, &m_JiaDianState, sizeof(t_JiaDianState) ) == 0 )
return;
memcpy ( &m_JiaDianState, &JiaDianState, sizeof(t_JiaDianState) );
SetNewStatus ( &m_JiaDianState );
SendSockData ( (char*)&m_JiaDianState, sizeof(t_JiaDianState) );
}
// 将新的电器状态发送给串口
BOOL CNetElectronSrvDlg::SendNewStatusToCOM(t_JiaDianState *pJiadianState)
{
char cComData [ COM_DATA_SIZE+1 ] = {0};
int nComDataLen = BuildPkt ( pJiadianState, cComData, sizeof(cComData) );
ASSERT ( nComDataLen == COM_DATA_SIZE );
Log ( "发送%d字节的串口数据:%s", nComDataLen, Data2String(cComData,nComDataLen) );
if ( m_COM.Write ( cComData, nComDataLen ) != nComDataLen )
{
CString csTemp;
csTemp.Format ( "发送数据到串口失败 - %s", m_COM.GetLastErrorString() );
MessageBox ( csTemp, "错误", MB_ICONERROR );
Log ( "发送串口数据失败" );
return FALSE;
}
else
{
Log ( "发送串口数据成功" );
}
return TRUE;
}
void CNetElectronSrvDlg::OnDblclkListLogInfo()
{
int nCurSel = m_ListLogInfo.GetCurSel();
if ( nCurSel < 0 ) return;
CString csText;
m_ListLogInfo.GetText ( nCurSel, csText );
MessageBox ( csText, "日志信息", MB_ICONINFORMATION );
}
// 将新的状态数据通过socket发送给客户端
BOOL CNetElectronSrvDlg::SendSockData(char *pData, int nSize)
{
if ( !m_bSockConnected ) return FALSE;
Log ( "发送%d字节到客户端:%s", nSize, Data2String(pData,nSize) );
int nReturned = m_sockSend.Send ( (const void*)pData, nSize );
if ( nReturned != nSize )
{
Log ( "发送 %d 字节数据到客户端失败!", nSize );
return FALSE;
}
return TRUE;
}
void CNetElectronSrvDlg::OnTimer(UINT nIDEvent)
{
GetAndHandleNewSTFromCOM ();
CDialog::OnTimer(nIDEvent);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -