初步完成外设相关功能

This commit is contained in:
HEYAHONG 2022-09-20 16:51:25 +08:00
parent bde0d750ad
commit 0c8f68ed07
6 changed files with 615 additions and 3 deletions

View File

@ -5,6 +5,8 @@
#include <wx/treectrl.h>
#include <wx/clipbrd.h>
#include "InputDialog.h"
class wxTreeCtrlPerhItemData:public wxTreeItemData
{
@ -49,7 +51,13 @@ public:
}
virtual ~wxTreeCtrlServiceCharItemData()
{
if(perh.initialized())
{
SimpleBLE::Safe::Peripheral _perh(perh);
_perh.notify(ServiceUUID,CharUUID,[](SimpleBLE::ByteArray payload) {});
_perh.indicate(ServiceUUID,CharUUID,[](SimpleBLE::ByteArray payload) {});
_perh.unsubscribe(ServiceUUID,CharUUID);
}
}
};
@ -241,7 +249,7 @@ void BLEPeripheralDialog::OnTreeItemRightClick( wxTreeEvent& event )
for(size_t i=0; i<str.length(); i++)
{
char buff[10]= {0};
snprintf(buff,sizeof(buff)-1,"%02X ",(int)str.c_str()[i]);
snprintf(buff,sizeof(buff)-1,"%02X ",(int)(str.c_str()[i]));
hexstr+=buff;
}
}
@ -256,6 +264,160 @@ void BLEPeripheralDialog::OnTreeItemRightClick( wxTreeEvent& event )
wxMenuItem *item=menu.Append(1301,_T("读取"));
menu.Bind(wxEVT_COMMAND_MENU_SELECTED,menufunc,item->GetId(),item->GetId());
}
{
auto menufunc=[&]( wxCommandEvent& event_menu )
{
InputDialog dlg(this);
if(wxID_OK==dlg.ShowModal())
{
std::string str=dlg.GetData();
std::string hexstr;
{
for(size_t i=0; i<str.length(); i++)
{
char buff[10]= {0};
snprintf(buff,sizeof(buff)-1,"%02X ",(int)(str.c_str()[i]));
hexstr+=buff;
}
}
wxLogMessage(wxString(_T("准备写入数据到设备\r\n\t设备:%s\r\n\t服务:%s\r\n\t特征:%s\r\n\t数据:%s\r\n\t数据(HEX):%s")),wxString(_Data->perh.address()),_Data->ServiceUUID,_Data->CharUUID,wxString::FromUTF8(str.c_str(),str.length()),hexstr);
if(perh.write_request(_Data->ServiceUUID,_Data->CharUUID,str))
{
wxLogMessage(_T("%s 写入数据成功!"),perh.address().value_or(""));
wxMessageBox(_T("写入成功!"),_T("提示"));
}
else
{
wxLogMessage(_T("%s 写入数据失败!"),perh.address().value_or(""));
wxMessageBox(_T("写入失败!"),_T("错误"));
}
}
else
{
wxLogMessage(_T("%s 取消输入数据!!"),perh.address().value_or(""));
}
};
wxMenuItem *item=menu.Append(1302,_T("写入请求"));
menu.Bind(wxEVT_COMMAND_MENU_SELECTED,menufunc,item->GetId(),item->GetId());
}
{
auto menufunc=[&]( wxCommandEvent& event_menu )
{
InputDialog dlg(this);
if(wxID_OK==dlg.ShowModal())
{
std::string str=dlg.GetData();
std::string hexstr;
{
for(size_t i=0; i<str.length(); i++)
{
char buff[10]= {0};
snprintf(buff,sizeof(buff)-1,"%02X ",(int)(str.c_str()[i]));
hexstr+=buff;
}
}
wxLogMessage(wxString(_T("准备写入数据到设备\r\n\t设备:%s\r\n\t服务:%s\r\n\t特征:%s\r\n\t数据:%s\r\n\t数据(HEX):%s")),wxString(_Data->perh.address()),_Data->ServiceUUID,_Data->CharUUID,wxString::FromUTF8(str.c_str(),str.length()),hexstr);
if(perh.write_command(_Data->ServiceUUID,_Data->CharUUID,str))
{
wxLogMessage(_T("%s 写入数据成功!"),perh.address().value_or(""));
wxMessageBox(_T("写入成功!"),_T("提示"));
}
else
{
wxLogMessage(_T("%s 写入数据失败!"),perh.address().value_or(""));
wxMessageBox(_T("写入失败!"),_T("错误"));
}
}
else
{
wxLogMessage(_T("%s 取消输入数据!!"),perh.address().value_or(""));
}
};
wxMenuItem *item=menu.Append(1303,_T("写入命令"));
menu.Bind(wxEVT_COMMAND_MENU_SELECTED,menufunc,item->GetId(),item->GetId());
}
{
auto menufunc=[&]( wxCommandEvent& event_menu )
{
auto cb=[=](SimpleBLE::ByteArray payload)
{
std::string str=payload;
std::string hexstr;
{
for(size_t i=0; i<str.length(); i++)
{
char buff[10]= {0};
snprintf(buff,sizeof(buff)-1,"%02X ",(int)(str.c_str()[i]));
hexstr+=buff;
}
}
wxLogMessage(wxString(_T("接收到通知数据\r\n\t设备:%s\r\n\t服务:%s\r\n\t特征:%s\r\n\t数据:%s\r\n\t数据(HEX):%s")),wxString(_Data->perh.address()),_Data->ServiceUUID,_Data->CharUUID,wxString::FromUTF8(str.c_str(),str.length()),hexstr);
};
if(perh.notify(_Data->ServiceUUID,_Data->CharUUID,cb))
{
wxMessageBox(_T("设置通知数据成功!"),_T("提示"));
}
else
{
wxMessageBox(_T("设置通知数据失败!"),_T("错误"));
}
};
wxMenuItem *item=menu.Append(1304,_T("接收通知数据"));
menu.Bind(wxEVT_COMMAND_MENU_SELECTED,menufunc,item->GetId(),item->GetId());
}
{
auto menufunc=[&]( wxCommandEvent& event_menu )
{
auto cb=[=](SimpleBLE::ByteArray payload)
{
std::string str=payload;
std::string hexstr;
{
for(size_t i=0; i<str.length(); i++)
{
char buff[10]= {0};
snprintf(buff,sizeof(buff)-1,"%02X ",(int)(str.c_str()[i]));
hexstr+=buff;
}
}
wxLogMessage(wxString(_T("接收到指示数据\r\n\t设备:%s\r\n\t服务:%s\r\n\t特征:%s\r\n\t数据:%s\r\n\t数据(HEX):%s")),wxString(_Data->perh.address()),_Data->ServiceUUID,_Data->CharUUID,wxString::FromUTF8(str.c_str(),str.length()),hexstr);
};
if(perh.notify(_Data->ServiceUUID,_Data->CharUUID,cb))
{
wxMessageBox(_T("设置指示数据成功!"),_T("提示"));
}
else
{
wxMessageBox(_T("设置指示数据失败!"),_T("错误"));
}
};
wxMenuItem *item=menu.Append(1305,_T("接收指示数据"));
menu.Bind(wxEVT_COMMAND_MENU_SELECTED,menufunc,item->GetId(),item->GetId());
}
{
auto menufunc=[&]( wxCommandEvent& event_menu )
{
if(perh.unsubscribe(_Data->ServiceUUID,_Data->CharUUID))
{
wxMessageBox(_T("取消数据订阅成功!"),_T("提示"));
}
else
{
wxMessageBox(_T("取消数据订阅失败!"),_T("错误"));
}
};
wxMenuItem *item=menu.Append(1306,_T("取消数据订阅"));
menu.Bind(wxEVT_COMMAND_MENU_SELECTED,menufunc,item->GetId(),item->GetId());
}
}
}
@ -287,7 +449,7 @@ void BLEPeripheralDialog::OnTreeItemRightClick( wxTreeEvent& event )
for(size_t i=0; i<str.length(); i++)
{
char buff[10]= {0};
snprintf(buff,sizeof(buff)-1,"%02X ",(int)str.c_str()[i]);
snprintf(buff,sizeof(buff)-1,"%02X ",(int)(str.c_str()[i]));
hexstr+=buff;
}
}
@ -302,6 +464,44 @@ void BLEPeripheralDialog::OnTreeItemRightClick( wxTreeEvent& event )
wxMenuItem *item=menu.Append(1401,_T("读取"));
menu.Bind(wxEVT_COMMAND_MENU_SELECTED,menufunc,item->GetId(),item->GetId());
}
{
auto menufunc=[&]( wxCommandEvent& event_menu )
{
InputDialog dlg(this);
if(wxID_OK==dlg.ShowModal())
{
std::string str=dlg.GetData();
std::string hexstr;
{
for(size_t i=0; i<str.length(); i++)
{
char buff[10]= {0};
snprintf(buff,sizeof(buff)-1,"%02X ",(int)(str.c_str()[i]));
hexstr+=buff;
}
}
wxLogMessage(wxString(_T("准备写入数据到设备\r\n\t设备:%s\r\n\t服务:%s\r\n\t特征:%s\r\n\t描述符:%s\r\n\t数据:%s\r\n\t数据(HEX):%s")),wxString(_Data->perh.address()),_Data->ServiceUUID,_Data->CharUUID,_Data->DescUUID,wxString::FromUTF8(str.c_str(),str.length()),hexstr);
if(perh.write(_Data->ServiceUUID,_Data->CharUUID,_Data->DescUUID,str))
{
wxLogMessage(_T("%s 写入数据成功!"),perh.address().value_or(""));
wxMessageBox(_T("写入成功!"),_T("提示"));
}
else
{
wxLogMessage(_T("%s 写入数据失败!"),perh.address().value_or(""));
wxMessageBox(_T("写入失败!"),_T("错误"));
}
}
else
{
wxLogMessage(_T("%s 取消输入数据!!"),perh.address().value_or(""));
}
};
wxMenuItem *item=menu.Append(1402,_T("写入"));
menu.Bind(wxEVT_COMMAND_MENU_SELECTED,menufunc,item->GetId(),item->GetId());
}
}
}

View File

@ -239,3 +239,45 @@ GUIPeripheral::~GUIPeripheral()
m_mgr.UnInit();
}
GUIInputDialog::GUIInputDialog( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
wxWrapSizer* wSizer;
wSizer = new wxWrapSizer( wxHORIZONTAL, wxWRAPSIZER_DEFAULT_FLAGS );
m_textCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 500,200 ), 0 );
wSizer->Add( m_textCtrl, 1, wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 );
wxBoxSizer* bSizer;
bSizer = new wxBoxSizer( wxHORIZONTAL );
bSizer->Add( 400, 0, 1, wxEXPAND, 5 );
m_checkBox_Hex = new wxCheckBox( this, wxID_ANY, wxT("HEX"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer->Add( m_checkBox_Hex, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_button_ok = new wxButton( this, wxID_ANY, wxT("确定"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer->Add( m_button_ok, 0, wxALL, 5 );
wSizer->Add( bSizer, 1, wxEXPAND, 5 );
this->SetSizer( wSizer );
this->Layout();
this->Centre( wxBOTH );
// Connect Events
m_button_ok->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GUIInputDialog::OnOk ), NULL, this );
}
GUIInputDialog::~GUIInputDialog()
{
// Disconnect Events
m_button_ok->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GUIInputDialog::OnOk ), NULL, this );
}

View File

@ -32,6 +32,8 @@
#include <wx/dataview.h>
#include <wx/button.h>
#include <wx/toolbar.h>
#include <wx/checkbox.h>
#include <wx/wrapsizer.h>
///////////////////////////////////////////////////////////////////////////
@ -154,3 +156,27 @@ class GUIPeripheral : public wxFrame
};
///////////////////////////////////////////////////////////////////////////////
/// Class GUIInputDialog
///////////////////////////////////////////////////////////////////////////////
class GUIInputDialog : public wxDialog
{
private:
protected:
wxTextCtrl* m_textCtrl;
wxCheckBox* m_checkBox_Hex;
wxButton* m_button_ok;
// Virtual event handlers, override them in your derived class
virtual void OnOk( wxCommandEvent& event ) { event.Skip(); }
public:
GUIInputDialog( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("请输入数据:"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 500,300 ), long style = wxDEFAULT_DIALOG_STYLE );
~GUIInputDialog();
};

63
InputDialog.cpp Normal file
View File

@ -0,0 +1,63 @@
#include "InputDialog.h"
#include "wx/msgdlg.h"
InputDialog::InputDialog(wxWindow* parent):GUIInputDialog(parent)
{
//ctor
}
InputDialog::~InputDialog()
{
//dtor
}
wxString InputDialog::GetData()
{
return data;
}
void InputDialog::OnOk( wxCommandEvent& event )
{
data=m_textCtrl->GetValue();
if(data.length()==0)
{
wxMessageBox(_T("输入不能为空!直接退出请点关闭!"),_T("提示"));
return;
}
if(m_checkBox_Hex->IsChecked())
{
wxString raw_str=data;
raw_str.Replace(" ","");
raw_str.Replace("\r","");
raw_str.Replace("\n","");
if((raw_str.length()%2)!=0)
{
raw_str+=_T("0");
}
{
data=_T("");
for(size_t i=0;i<raw_str.length();i+=2)
{
char buff[2]={0};
std::string tempstr=raw_str.substr(i,2).ToStdString();
try
{
buff[0]=std::stoi(tempstr,NULL,16);
}
catch(...)
{
wxMessageBox(_T("输入的不是Hex字符串!"),_T("错误"));
return;
}
data+=std::string(buff,1);
}
}
}
EndModal(wxID_OK);
}

23
InputDialog.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef INPUTDIALOG_H
#define INPUTDIALOG_H
#include "GUIFrame.h"
class InputDialog:public GUIInputDialog
{
public:
InputDialog(wxWindow* parent);
virtual ~InputDialog();
wxString GetData();
protected:
virtual void OnOk( wxCommandEvent& event );
private:
wxString data;
};
#endif // INPUTDIALOG_H

View File

@ -1102,5 +1102,263 @@
<property name="window_style"></property>
</object>
</object>
<object class="Dialog" expanded="0">
<property name="aui_managed">0</property>
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
<property name="bg"></property>
<property name="center">wxBOTH</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="enabled">1</property>
<property name="event_handler">impl_virtual</property>
<property name="extra_style"></property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size"></property>
<property name="name">GUIInputDialog</property>
<property name="pos"></property>
<property name="size">500,300</property>
<property name="style">wxDEFAULT_DIALOG_STYLE</property>
<property name="subclass">; ; forward_declare</property>
<property name="title">请输入数据:</property>
<property name="tooltip"></property>
<property name="two_step_creation">0</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<object class="wxWrapSizer" expanded="0">
<property name="flags">wxWRAPSIZER_DEFAULT_FLAGS</property>
<property name="minimum_size"></property>
<property name="name">wSizer</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL</property>
<property name="proportion">1</property>
<object class="wxTextCtrl" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="maxlength"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_textCtrl</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size">500,200</property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="value"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bSizer</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="spacer" expanded="0">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">400</property>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">HEX</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_checkBox_Hex</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxButton" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">确定</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_button_ok</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnOk</event>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</wxFormBuilder_Project>