Merge remote-tracking branch 'remotes/origin/develop' into huangbingcheng_branch

pull/18/head
golden 1 year ago
commit 3ce8a151fa

5
src/.gitignore vendored

@ -0,0 +1,5 @@
.deveco/**
.vscode/**
**/.DS_Store
.remote-sync.json
.ftpconfig*

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

@ -1,106 +0,0 @@
##### 说明
硬盘上的一份截图代码,作者是[sudami](https://bbs.pediy.com/thread-54302.htm)。
提取了里面的3个类CatchScreenDlg、MyTracker.hMyEdit自己在实现下。
双缓冲,完美无闪烁。
##### 截图
![snatshot.png](snatshot.png)
##### 说明
1、重写了MyEdit的绘制避免闪烁。
2、修改CCatchScreenDlg中部分逻辑避免闪烁
3、增加ToolBar控件仿QQ截图界面。按钮实际功能未开发。
4、实现截图飞选中区域暗色处理
##### ToolBar控件消息处理
```c++
BOOL CCatchScreenDlg::OnCommand(WPARAM wParam, LPARAM lParam)
{
bool bHandle = true;
HWND hWnd = m_toolBar.GetHWND();
if(lParam == (LPARAM)m_toolBar.GetHWND())
{
int wmId = LOWORD(wParam);
switch(wmId)
{
case MyToolBar_ID:
AfxMessageBox(_T("矩形"));
break;
case MyToolBar_ID+1:
AfxMessageBox(_T("圆形"));
break;
case MyToolBar_ID +2:
AfxMessageBox(_T("画笔"));
break;
case MyToolBar_ID +3:
AfxMessageBox(_T("马赛克"));
break;
case MyToolBar_ID +4:
AfxMessageBox(_T("文字"));
break;
case MyToolBar_ID +5:
AfxMessageBox(_T("撤销"));
break;
case MyToolBar_ID +6:
CopyScreenToBitmap(m_rectTracker.m_rect, TRUE);
PostQuitMessage(0);
break;
case MyToolBar_ID +7:
PostQuitMessage(0);
break;
case MyToolBar_ID +8:
CopyScreenToBitmap(m_rectTracker.m_rect, TRUE);
PostQuitMessage(0);
break;
default:
bHandle = false;
break;
}
::SetFocus(hWnd);
}
if (bHandle == false)
{
return CDialog::OnCommand(wParam,lParam);
}
}
```
##### 神奇的非选中区域暗色处理算法
```c++
Gdiplus::Graphics graphics(dcCompatible);
HRGN hgn1 = CreateRectRgn(m_rectTracker.m_rect.left,m_rectTracker.m_rect.top,
m_rectTracker.m_rect.right,m_rectTracker.m_rect.bottom);
Region region1(hgn1);
HRGN hgn2 = CreateRectRgn(rect.left,rect.top,
rect.right,rect.bottom);
Region region2(hgn2);
region2.Exclude(&region1);
SolidBrush solidBrush(Color(100, 128, 128, 128));
graphics.FillRegion(&solidBrush,&region2);
DeleteObject(hgn1);
DeleteObject(hgn2);
```

Binary file not shown.

@ -1,20 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Screenshot", "Screenshot\Screenshot.vcproj", "{24E39ACB-AB81-485D-8D36-749B3F5EC1E8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{24E39ACB-AB81-485D-8D36-749B3F5EC1E8}.Debug|Win32.ActiveCfg = Debug|Win32
{24E39ACB-AB81-485D-8D36-749B3F5EC1E8}.Debug|Win32.Build.0 = Debug|Win32
{24E39ACB-AB81-485D-8D36-749B3F5EC1E8}.Release|Win32.ActiveCfg = Release|Win32
{24E39ACB-AB81-485D-8D36-749B3F5EC1E8}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

@ -1,679 +0,0 @@
/******************************************************************************
* FileName : CatchScreenDlg.cpp
* Author : Unknown
* Mender : sudami
* Time : 2007/09/09
*
* Comment :
*
******************************************************************************/
#include "stdafx.h"
#include "Screenshot.h"
#include "CatchScreenDlg.h"
#include <GdiPlus.h>
using namespace Gdiplus;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// CCatchScreenDlg dialog
CCatchScreenDlg::CCatchScreenDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCatchScreenDlg::IDD, pParent)
{
m_bLBtnDown = FALSE;
//初始化像皮筋类,新增的resizeMiddle 类型
m_rectTracker.m_nStyle = CMyTracker::resizeMiddle | CMyTracker::solidLine;
m_rectTracker.m_rect.SetRect(-1, -2, -3, -4);
//设置矩形颜色
m_rectTracker.SetRectColor(RGB(10, 100, 130));
m_hCursor = AfxGetApp()->LoadCursor(IDC_CURSOR1);
m_bDraw = FALSE;
m_bFirstDraw = FALSE;
m_bQuit = FALSE;
m_bNeedShowMsg = FALSE;
m_startPt = 0;
//获取屏幕分辩率
m_xScreen = GetSystemMetrics(SM_CXSCREEN);
m_yScreen = GetSystemMetrics(SM_CYSCREEN);
//截取屏幕到位图中
CRect rect(0, 0, m_xScreen, m_yScreen);
m_hBitmap = CopyScreenToBitmap(&rect);
m_pBitmap = CBitmap::FromHandle(m_hBitmap);
//初始化刷新窗口区域 m_rgn
m_rgn.CreateRectRgn(0, 0, 50, 50);
}
void CCatchScreenDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EDIT1, m_tipEdit);
}
BEGIN_MESSAGE_MAP(CCatchScreenDlg, CDialog)
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDBLCLK()
ON_WM_ERASEBKGND()
ON_WM_SETCURSOR()
ON_WM_RBUTTONUP()
ON_WM_CTLCOLOR()
ON_WM_RBUTTONDOWN()
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCatchScreenDlg message handlers
BOOL CCatchScreenDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//把对化框设置成全屏顶层窗口
SetWindowPos(&wndTopMost, 0, 0, m_xScreen, m_yScreen, SWP_SHOWWINDOW);
//移动操作提示窗口
CRect rect;
m_tipEdit.GetWindowRect(&rect);
m_tipEdit.MoveWindow(10, 10, rect.Width(), rect.Height());
m_toolBar.CreateToolBar(m_hWnd);
m_toolBar.RemoveChildStyle();
::MoveWindow(m_toolBar.GetHWND(),300,300,230,30,FALSE);
UpdateTipString();
SetEidtWndText();
((CScreenshotApp *)AfxGetApp())->m_hwndDlg = AfxGetMainWnd()->GetSafeHwnd();
return TRUE;
}
void CCatchScreenDlg::OnPaint()
{
// 如果窗口是最小化状态
if (IsIconic())
{
CPaintDC dc(this);
SendMessage(WM_ICONERASEBKGND, (WPARAM)dc.GetSafeHdc(), 0);
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;
}
else // 如果窗口正常显示
{
CPaintDC dc(this);
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(&dc);
RECT rect;
::GetClientRect(m_hWnd, &rect);
HBITMAP hBitmap = ::CreateCompatibleBitmap(dc.m_hDC,rect.right-rect.left,rect.bottom-rect.top);
::SelectObject(dcCompatible.m_hDC,hBitmap);
HBRUSH s_hBitmapBrush = CreatePatternBrush(m_hBitmap);
::FillRect(dcCompatible.m_hDC,&rect,s_hBitmapBrush);
//显示截取矩形大小信息
if (m_bNeedShowMsg && m_bFirstDraw)
{
CRect rect = m_rectTracker.m_rect;
DrawMessage(rect, &dcCompatible);
}
//画出像皮筋矩形
if (m_bFirstDraw)
{
m_rectTracker.Draw(&dcCompatible);
}
Gdiplus::Graphics graphics(dcCompatible);
HRGN hgn1 = CreateRectRgn(m_rectTracker.m_rect.left,m_rectTracker.m_rect.top,
m_rectTracker.m_rect.right,m_rectTracker.m_rect.bottom);
Region region1(hgn1);
HRGN hgn2 = CreateRectRgn(rect.left,rect.top,
rect.right,rect.bottom);
Region region2(hgn2);
region2.Exclude(&region1);
SolidBrush solidBrush(Color(100, 128, 128, 128));
graphics.FillRegion(&solidBrush,&region2);
DeleteObject(hgn1);
DeleteObject(hgn2);
dc.BitBlt(0,0,rect.right, rect.bottom,&dcCompatible,0,0,SRCCOPY);
DeleteObject(hBitmap);
DeleteObject(s_hBitmapBrush);
//CDialog::OnPaint();
}
}
void CCatchScreenDlg::OnCancel()
{
if (m_bFirstDraw)
{
//取消已画矩形变量
m_bFirstDraw = FALSE;
m_bDraw = FALSE;
m_rectTracker.m_rect.SetRect(-1, -1, -1, -1);
InvalidateRgnWindow();
}
else
{
CDialog::OnCancel();
}
}
void CCatchScreenDlg::OnMouseMove(UINT nFlags, CPoint point)
{
if(m_bLBtnDown)
m_toolBar.HideToolBar();
else
m_toolBar.ShowToolBar();
if (m_bDraw)
{
//动态调整矩形大小,并刷新画出
m_rectTracker.m_rect.SetRect(m_startPt.x + 4, m_startPt.y + 4, point.x, point.y);
InvalidateRgnWindow();
}
//弥补调整大小和位置时,接收不到MouseMove消息
CRect rect;
m_tipEdit.GetWindowRect(&rect);
if (rect.PtInRect(point))
m_tipEdit.SendMessage(WM_MOUSEMOVE);
UpdateMousePointRGBString();
SetEidtWndText();
CDialog::OnMouseMove(nFlags, point);
}
void CCatchScreenDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
m_bLBtnDown = TRUE;
int nHitTest;
nHitTest = m_rectTracker.HitTest(point);
//判断击中位置
if (nHitTest < 0)
{
if (!m_bFirstDraw)
{
//第一次画矩形
m_startPt = point;
m_bDraw = TRUE;
m_bFirstDraw = TRUE;
//设置当鼠标按下时最小的矩形大小
m_rectTracker.m_rect.SetRect(point.x, point.y, point.x + 4, point.y + 4);
//保证当鼠标当下时立刻显示信息
if (m_bFirstDraw)
m_bNeedShowMsg = TRUE;
UpdateTipString();
SetEidtWndText();
InvalidateRgnWindow();
}
}
else
{
//保证当鼠标当下时立刻显示信息
m_bNeedShowMsg = TRUE;
if (m_bFirstDraw)
{
//调束大小时,Track会自动调整矩形大小,在些期间,消息归CRectTracker内部处理
m_rectTracker.Track(this, point, TRUE);
InvalidateRgnWindow();
}
}
CDialog::OnLButtonDown(nFlags, point);
}
void CCatchScreenDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
m_bLBtnDown = FALSE;
m_bNeedShowMsg = FALSE;
m_bDraw = FALSE;
UpdateTipString();
SetEidtWndText();
m_toolBar.SetShowPlace(m_rectTracker.m_rect.right,m_rectTracker.m_rect.bottom);
InvalidateRgnWindow();
CDialog::OnLButtonUp(nFlags, point);
}
void CCatchScreenDlg::OnLButtonDblClk(UINT nFlags, CPoint point)
{
int nHitTest;
nHitTest = m_rectTracker.HitTest(point);
//如果在是矩形内部双击
if (nHitTest == 8)
{
//保存位图到粘贴板中,bSave 为TRUE,
CopyScreenToBitmap(m_rectTracker.m_rect, TRUE);
PostQuitMessage(0);
}
CDialog::OnLButtonDblClk(nFlags, point);
}
void CCatchScreenDlg::OnRButtonDown(UINT nFlags, CPoint point)
{
m_toolBar.HideToolBar();
//InvalidateRgnWindow();
CDialog::OnRButtonDown(nFlags, point);
}
void CCatchScreenDlg::OnRButtonUp(UINT nFlags, CPoint point)
{
m_bLBtnDown = FALSE;
if (m_bFirstDraw)
{
//如果已经截取矩则清除截取矩形
m_bFirstDraw = FALSE;
//清除矩形大小
m_rectTracker.m_rect.SetRect(-1, -1, -1, -1);
UpdateTipString();
SetEidtWndText();
InvalidateRgnWindow();
}
else
{
//关闭程序
PostQuitMessage(0);
}
CDialog::OnRButtonUp(nFlags, point);
}
HBRUSH CCatchScreenDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
//设置操作提示窗口文本颜色
if (pWnd->GetDlgCtrlID() == IDC_EDIT1)
{
pDC->SetTextColor(RGB(247,76,128));
}
return hbr;
}
BOOL CCatchScreenDlg::OnEraseBkgnd(CDC* pDC)
{
return FALSE;
//用整个桌面填充全屏对话框背景
BITMAP bmp;
m_pBitmap->GetBitmap(&bmp);
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(pDC);
dcCompatible.SelectObject(m_pBitmap);
CRect rect;
GetClientRect(&rect);
pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &dcCompatible, 0, 0, SRCCOPY);
return TRUE;
}
BOOL CCatchScreenDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
//设置改变截取矩形大小时光标
if (pWnd == this &&m_rectTracker.SetCursor(this, nHitTest)
&& !m_bDraw &&m_bFirstDraw) //此处判断保截取时当标始中为彩色光标
{
return TRUE;
}
//设置彩色光标
SetCursor(m_hCursor);
return TRUE;
}
// 拷贝屏幕, 这段源码源自CSDN
// lpRect 代表选定区域
HBITMAP CCatchScreenDlg::CopyScreenToBitmap(LPRECT lpRect, BOOL bSave)
{
HDC hScrDC, hMemDC;
// 屏幕和内存设备描述表
HBITMAP hBitmap, hOldBitmap;
// 位图句柄
int nX, nY, nX2, nY2;
// 选定区域坐标
int nWidth, nHeight;
// 确保选定区域不为空矩形
if (IsRectEmpty(lpRect))
return NULL;
//为屏幕创建设备描述表
hScrDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = CreateCompatibleDC(hScrDC);
// 获得选定区域坐标
nX = lpRect->left;
nY = lpRect->top;
nX2 = lpRect->right;
nY2 = lpRect->bottom;
//确保选定区域是可见的
if (nX < 0)
nX = 0;
if (nY < 0)
nY = 0;
if (nX2 > m_xScreen)
nX2 = m_xScreen;
if (nY2 > m_yScreen)
nY2 = m_yScreen;
nWidth = nX2 - nX;
nHeight = nY2 - nY;
// 创建一个与屏幕设备描述表兼容的位图
hBitmap = CreateCompatibleBitmap
(hScrDC, nWidth, nHeight);
// 把新位图选到内存设备描述表中
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
// 把屏幕设备描述表拷贝到内存设备描述表中
if (bSave)
{
//创建兼容DC,当bSave为中时把开始保存的全屏位图,按截取矩形大小保存
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(CDC::FromHandle(hMemDC));
dcCompatible.SelectObject(m_pBitmap);
BitBlt(hMemDC, 0, 0, nWidth, nHeight,
dcCompatible, nX, nY, SRCCOPY);
}
else
{
BitBlt(hMemDC, 0, 0, nWidth, nHeight,
hScrDC, nX, nY, SRCCOPY);
}
hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
//得到屏幕位图的句柄
//清除
DeleteDC(hScrDC);
DeleteDC(hMemDC);
if (bSave)
{
if (OpenClipboard())
{
//清空剪贴板
EmptyClipboard();
//把屏幕内容粘贴到剪贴板上,
//hBitmap 为刚才的屏幕位图句柄
SetClipboardData(CF_BITMAP, hBitmap);
//关闭剪贴板
CloseClipboard();
}
}
// 返回位图句柄
return hBitmap;
}
// 显示操作提示信息
void CCatchScreenDlg::UpdateTipString()
{
CString strTemp;
if (!m_bDraw && !m_bFirstDraw)
{
strTemp = _T("\r\n\r\n·按下鼠标左键不放选择截取\r\n\r\n·ESC键、鼠标右键退出");
}
else
if (m_bDraw && m_bFirstDraw)
{
strTemp = _T("\r\n\r\n·松开鼠标左键确定截取范围\r\n\r\n·ESC键退出");
}
else if (!m_bDraw && m_bFirstDraw)
{
CString sudami(_T("\r\n\r\n·矩形内双击鼠标左键保存\r\n\r\n·点击鼠标右键重新选择"));
strTemp = _T("\r\n\r\n·鼠标在矩形边缘调整大小");
strTemp += sudami;
}
m_strEditTip = strTemp;
}
// 显示截取矩形信息
void CCatchScreenDlg::DrawMessage(CRect &inRect, CDC * pDC)
{
//截取矩形大小信息离鼠标间隔
const int space = 3;
//设置字体颜色大小
CPoint pt;
CPen pen(PS_SOLID, 1, RGB(47, 79, 79));
CPen *pOldPen;
pOldPen = pDC->SelectObject(&pen);
//pDC->SetTextColor(RGB(147,147,147));
CFont font;
CFont * pOldFont;
font.CreatePointFont(90, _T("宋体"));
pOldFont = pDC->SelectObject(&font);
//得到字体宽度和高度
GetCursorPos(&pt);
int OldBkMode;
OldBkMode = pDC->SetBkMode(TRANSPARENT);
TEXTMETRIC tm;
int charHeight;
CSize size;
int lineLength;
pDC->GetTextMetrics(&tm);
charHeight = tm.tmHeight + tm.tmExternalLeading;
size = pDC->GetTextExtent(_T("顶点位置 "), _tcslen(_T("顶点位置 ")));
lineLength = size.cx;
//初始化矩形, 以保证写下六行文字
CRect rect(pt.x + space, pt.y - charHeight * 6 - space, pt.x + lineLength + space, pt.y - space);
//创建临时矩形
CRect rectTemp;
//当矩形到达桌面边缘时调整方向和大小
if ((pt.x + rect.Width()) >= m_xScreen)
{
//桌面上方显示不下矩形
rectTemp = rect;
rectTemp.left = rect.left - rect.Width() - space * 2;
rectTemp.right = rect.right - rect.Width() - space * 2;;
rect = rectTemp;
}
if ((pt.y - rect.Height()) <= 0)
{
//桌面右方显示不下矩形
rectTemp = rect;
rectTemp.top = rect.top + rect.Height() + space * 2;;
rectTemp.bottom = rect.bottom + rect.Height() + space * 2;;
rect = rectTemp;
}
//创建空画刷画矩形
CBrush * pOldBrush;
pOldBrush = pDC->SelectObject(CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)));
pDC->Rectangle(rect);
rect.top += 2;
//在矩形中显示文字
CRect outRect(rect.left, rect.top, rect.left + lineLength, rect.top + charHeight);
CString string(_T("顶点位置"));
pDC->DrawText(string, outRect, DT_CENTER);
outRect.SetRect(rect.left, rect.top + charHeight, rect.left + lineLength, charHeight + rect.top + charHeight);
string.Format(_T("(%d,%d)"), inRect.left, inRect.top);
pDC->DrawText(string, outRect, DT_CENTER);
outRect.SetRect(rect.left, rect.top + charHeight * 2, rect.left + lineLength, charHeight + rect.top + charHeight * 2);
string = _T("矩形大小");
pDC->DrawText(string, outRect, DT_CENTER);
outRect.SetRect(rect.left, rect.top + charHeight * 3, rect.left + lineLength, charHeight + rect.top + charHeight * 3);
string.Format(_T("(%d,%d)"), inRect.Width(), inRect.Height());
pDC->DrawText(string, outRect, DT_CENTER);
outRect.SetRect(rect.left, rect.top + charHeight * 4, rect.left + lineLength, charHeight + rect.top + charHeight * 4);
string = _T("光标坐标");
pDC->DrawText(string, outRect, DT_CENTER);
outRect.SetRect(rect.left, rect.top + charHeight * 5, rect.left + lineLength, charHeight + rect.top + charHeight * 5);
string.Format(_T("(%d,%d)"), pt.x, pt.y);
pDC->DrawText(string, outRect, DT_CENTER);
pDC->SetBkMode(OldBkMode);
pDC->SelectObject(pOldFont);
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
}
// 刷新局部窗口
void CCatchScreenDlg::InvalidateRgnWindow()
{
//获取当全屏对话框窗口大小
CRect rect1;
GetWindowRect(rect1);
//获取编辑框窗口大小
CRect rect2;
m_tipEdit.GetWindowRect(rect2);
CRgn rgn1, rgn2;
rgn1.CreateRectRgnIndirect(rect1);
rgn2.CreateRectRgnIndirect(rect2);
//获取更新区域,就是除了编辑框窗口不更新
//m_rgn.CombineRgn(&rgn1, &rgn2, RGN_DIFF);
// 添加ToolBar不刷新
CRect rect3;
::GetWindowRect(m_toolBar.GetHWND(),&rect3);
CRgn rgn3;
rgn3.CreateRectRgnIndirect(rect3);
CRgn rgnTemp;
rgnTemp.CreateRectRgn(0, 0, 50, 50);
rgnTemp.CombineRgn(&rgn1, &rgn2, RGN_DIFF);
m_rgn.CombineRgn(&rgnTemp, &rgn3, RGN_DIFF);
InvalidateRgn(&m_rgn);
}
void CCatchScreenDlg::UpdateMousePointRGBString()
{
static CString strOld("");
CPoint pt;
GetCursorPos(&pt);
COLORREF color;
CClientDC dc(this);
color = dc.GetPixel(pt);
BYTE rValue, gValue, bValue;
rValue = GetRValue(color);
gValue = GetGValue(color);
bValue = GetGValue(color);
//按格式排放字符串
CString string;
string.Format(_T("\r\n\r\n·当前像素RGB(%d,%d,%d)"), rValue, gValue, bValue);
//如果当前颜色没变则不刷新RGB值,以免窗口有更多闪烁
if (strOld != string)
{
m_strRgb = string;
}
strOld = string;
}
void CCatchScreenDlg::SetEidtWndText()
{
m_tipEdit.SetWindowText(this->GetEditText());
}
CString CCatchScreenDlg::GetEditText()
{
CString str;
str.Append(m_strRgb);
str.Append(m_strEditTip);
return str;
}
BOOL CCatchScreenDlg::OnCommand(WPARAM wParam, LPARAM lParam)
{
bool bHandle = true;
HWND hWnd = m_toolBar.GetHWND();
if(lParam == (LPARAM)m_toolBar.GetHWND())
{
int wmId = LOWORD(wParam);
switch(wmId)
{
case MyToolBar_ID:
AfxMessageBox(_T("矩形"));
break;
case MyToolBar_ID+1:
AfxMessageBox(_T("圆形"));
break;
case MyToolBar_ID +2:
AfxMessageBox(_T("画笔"));
break;
case MyToolBar_ID +3:
AfxMessageBox(_T("马赛克"));
break;
case MyToolBar_ID +4:
AfxMessageBox(_T("文字"));
break;
case MyToolBar_ID +5:
AfxMessageBox(_T("撤销"));
break;
case MyToolBar_ID +6:
CopyScreenToBitmap(m_rectTracker.m_rect, TRUE);
PostQuitMessage(0);
break;
case MyToolBar_ID +7:
PostQuitMessage(0);
break;
case MyToolBar_ID +8:
CopyScreenToBitmap(m_rectTracker.m_rect, TRUE);
PostQuitMessage(0);
break;
default:
bHandle = false;
break;
}
::SetFocus(hWnd);
}
if (bHandle == false)
{
return CDialog::OnCommand(wParam,lParam);
}
}
////////////////////////////////// END OF FILE ///////////////////////////////////////

@ -1,90 +0,0 @@
#if !defined(AFX_CATCHSCREENDLG_H__536FDBC8_7DB2_4BEF_8943_70DBE8AD845F__INCLUDED_)
#define AFX_CATCHSCREENDLG_H__536FDBC8_7DB2_4BEF_8943_70DBE8AD845F__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif
//--------------------------------------------------------------------------
#include "Resource.h"
#include "MyEdit.h"
#ifndef MYTRACKER_
#include "MyTracker.h"
#endif
#include "MyToolBar.h"
//--------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
class CCatchScreenDlg : public CDialog
{
public:
CCatchScreenDlg(CWnd* pParent = NULL);
enum { IDD = IDD_DIALOGFORIMG };
CMyEdit m_tipEdit;
CMyToolBar m_toolBar;
public:
int m_xScreen;
int m_yScreen;
BOOL m_bLBtnDown;
BOOL m_bNeedShowMsg; // 显示截取矩形大小信息
BOOL m_bDraw; // 是否为截取状态
BOOL m_bFirstDraw; // 是否为首次截取
BOOL m_bQuit; // 是否为退出
CPoint m_startPt; // 截取矩形左上角位置
CMyTracker m_rectTracker; // 像皮筋类
CBrush m_brush;
HCURSOR m_hCursor; // 光标
CBitmap* m_pBitmap; // Edit关联控件的背景位图
HBITMAP m_hBitmap;
CRgn m_rgn; // 背景擦除区域
public:
HBITMAP CopyScreenToBitmap(LPRECT lpRect,BOOL bSave=FALSE); /* 拷贝桌面到位图 */
void UpdateTipString(); //显示操作提示信息
void DrawMessage(CRect &inRect,CDC * pDC); //显示截取矩形信息
void InvalidateRgnWindow(); //重画窗口
void UpdateMousePointRGBString();
CString m_strRgb;
CString m_strEditTip;
void SetEidtWndText();
CString GetEditText();
protected:
virtual void DoDataExchange(CDataExchange* pDX);
virtual BOOL OnInitDialog();
virtual void OnCancel();
afx_msg void OnPaint();
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
DECLARE_MESSAGE_MAP()
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
};
///////////////////////////////////////////////////////////////////////////////////////////
#endif

@ -1,120 +0,0 @@
/******************************************************************************
* FileName : MyEdit.CPP
* Author : Unknown
* Mender : sudami
* Time : 2007/09/09
*
* Comment :
*--------------------------------------------------------
* .
* ,
*--------------------------------------------------------
******************************************************************************/
#include "stdafx.h"
#include "MyEdit.h"
#include "resource.h"
///////////////////////////////////////////////////////////////////////////////
// 构造函数、析构函数
//
CMyEdit::CMyEdit()
{
m_bMove=TRUE;
}
CMyEdit::~CMyEdit()
{
}
BEGIN_MESSAGE_MAP(CMyEdit, CEdit)
/* 2个小消息 */
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_SETFOCUS()
/* 3个大消息 */
ON_WM_MOUSEMOVE()
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//
int CMyEdit::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CEdit::OnCreate(lpCreateStruct) == -1)
return -1;
return 0;
}
void CMyEdit::OnPaint()
{
CPaintDC dc(this);
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(&dc);
dcCompatible.SetBkMode(TRANSPARENT);
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP_BK);
dcCompatible.SelectObject(&bitmap);
RECT rt = {5,5,0,0};
RECT rtClient = {0};
GetClientRect(&rtClient);
rt.right = rtClient.right;
rt.bottom = rtClient.bottom;
CString str;
GetWindowText(str);
CFont font;
CFont * pOldFont;
font.CreatePointFont(90, _T("宋体"));
pOldFont = dcCompatible.SelectObject(&font);
dcCompatible.DrawText(str,&rt,DT_LEFT);
dcCompatible.SelectObject(pOldFont);
CRect rect;
GetClientRect(&rect);
dc.BitBlt(0,0,rect.Width(),rect.Height(),&dcCompatible,0,0,SRCCOPY);
}
/////////////////////////////////////////////////////////////////////////////
// <响应 WM_MOUSEMOVE 消息>
// 和QQ的截图差不多的效果,只要鼠标挪到该控件区域,该区域就变换位置
//
void CMyEdit::OnMouseMove(UINT nFlags, CPoint point)
{
CEdit::OnMouseMove(nFlags, point);
CRect rect;
GetWindowRect(&rect);
int xScreen = GetSystemMetrics(SM_CXSCREEN);
if(m_bMove)
{
//移动到左上角
MoveWindow(10,10,rect.Width(),rect.Height());
m_bMove=FALSE;
}
else
{
//移动到右上角
MoveWindow(xScreen-180,10,rect.Width(),rect.Height());
m_bMove=TRUE;
}
}
/////////////////////////////////////////////////////////////////////////////
//
void CMyEdit::OnSetFocus(CWnd* pOldWnd)
{
CEdit::OnSetFocus(pOldWnd);
// 隐藏光标提示符
this->HideCaret();
}
BOOL CMyEdit::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}

@ -1,51 +0,0 @@
/*****************************************************************************
* FileName : MyEdit.h
* Author : Unknown
* Mender : sudami
* Time : 2007/09/09
*
* Comment :
*--------------------------------------------------------
* .
* ,
*--------------------------------------------------------
******************************************************************************/
#if !defined(AFX_MYEDIT_H__A34EEA6D_E8FC_4D15_B03C_BAA42FDF6FCB__INCLUDED_)
#define AFX_MYEDIT_H__A34EEA6D_E8FC_4D15_B03C_BAA42FDF6FCB__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif
//-----------------------------------------------------------------------------
#include <afxwin.h>
//-----------------------------------------------------------------------------
class CMyEdit : public CEdit
{
public:
CMyEdit();
virtual ~CMyEdit();
BOOL m_bMove; // 类似"单刀双掷开关"
protected:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSetFocus(CWnd* pOldWnd);
afx_msg void OnPaint();
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
DECLARE_MESSAGE_MAP()
};
//////////////////////////////////////////////////////////////////////////////////
#endif

@ -1,148 +0,0 @@
#include "StdAfx.h"
#include "MyToolBar.h"
#include <GdiPlus.h>
#include "resource.h"
BOOL ImageFromIDResource(UINT nID, LPCTSTR sTR, Gdiplus::Bitmap * & pImg)
{
HINSTANCE hInst = AfxGetResourceHandle();
HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(nID),sTR); // type
if (!hRsrc)
return FALSE;
// load resource into memory
DWORD len = SizeofResource(hInst, hRsrc);
BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc);
if (!lpRsrc)
return FALSE;
// Allocate global memory on which to create stream
HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);
BYTE* pmem = (BYTE*)GlobalLock(m_hMem);
memcpy(pmem,lpRsrc,len);
IStream* pstm;
CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);
// load from stream
pImg=Gdiplus::Bitmap::FromStream(pstm);
// free/release stuff
GlobalUnlock(m_hMem);
pstm->Release();
FreeResource(lpRsrc);
return TRUE;
}
CMyToolBar::CMyToolBar()
{
m_hImageList = NULL;
m_hWnd_toolbar = 0;
m_hWndParent = 0;
}
CMyToolBar::~CMyToolBar(void)
{
ImageList_Destroy(m_hImageList);
}
BOOL CMyToolBar::CreateToolBar(HWND hWndParent)
{
if (m_hImageList)
return FALSE;
m_hWndParent = hWndParent;
m_hImageList= ImageList_Create(18,18,ILC_COLOR32,1,1);
Gdiplus::Bitmap * pImage = NULL;
for(int i=0;i< 9;i++)
{
ImageFromIDResource(IDB_RECTANGLE + i,_T("PNG"),pImage);
HBITMAP pHbitmap=0;;
if(pImage)
{
pImage->GetHBITMAP(Gdiplus::Color(0xff,0xff,0xff,0xff),&pHbitmap);
ImageList_Add(m_hImageList,pHbitmap,NULL);
delete pImage;
pImage = NULL;
}
}
m_hWnd_toolbar = ::CreateWindowEx(0,TOOLBARCLASSNAME,0,WS_CHILD | WS_VISIBLE|WS_BORDER ,
0,0,0,0,hWndParent,NULL,GetModuleHandle(NULL),NULL);
if (m_hWnd_toolbar == NULL)
return FALSE;
::SendMessage(m_hWnd_toolbar,TB_SETIMAGELIST, 0, (LPARAM) m_hImageList);
::SendMessage(m_hWnd_toolbar,TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
::SendMessage(m_hWnd_toolbar,
(UINT) TB_SETBITMAPSIZE,(WPARAM) 0,//not used, must be zero
(LPARAM) MAKELONG (18, 18)// = (LPARAM) MAKELONG (dxBitmap, dyBitmap)
);
//TCHAR tooltips[16][30]={_T("AAAA"),_T("BBBB"),_T("CCCC"),_T("DDDD")};
for(int i = 0; i < 9; i++)
{
TBBUTTON tbbutton;
// 换行
int wrapnow = 0;
//if (i % 2 == 1)
// wrapnow = TBSTATE_WRAP;
ZeroMemory(&tbbutton, sizeof(TBBUTTON));
//tbbutton.iString = (INT_PTR) tooltips[i];
tbbutton.fsStyle = TBSTYLE_CHECKGROUP; // 单选属性
tbbutton.fsState = TBSTATE_ENABLED | wrapnow;
tbbutton.idCommand = MyToolBar_ID + i; // 定义控件的id
tbbutton.iBitmap = i;
::SendMessage(m_hWnd_toolbar,TB_ADDBUTTONS, 1, (LPARAM) &tbbutton);
}
::SendMessage(m_hWnd_toolbar, TB_AUTOSIZE, 0, 0);
return TRUE;
}
HWND CMyToolBar::GetHWND()
{
return m_hWnd_toolbar;
}
void CMyToolBar::AddChildStyle()
{
DWORD dwStyle = GetWindowLong(m_hWnd_toolbar, GWL_STYLE);
dwStyle &= WS_CHILD;
SetWindowLong(m_hWnd_toolbar,GWL_STYLE,dwStyle);
}
void CMyToolBar::RemoveChildStyle()
{
DWORD dwStyle = GetWindowLong(m_hWnd_toolbar, GWL_STYLE);
dwStyle &= ~WS_CHILD;
SetWindowLong(m_hWnd_toolbar,GWL_STYLE,dwStyle);
}
void CMyToolBar::ShowToolBar()
{
::ShowWindow(m_hWnd_toolbar,SW_SHOW);
}
void CMyToolBar::HideToolBar()
{
::ShowWindow(m_hWnd_toolbar,SW_HIDE);
}
void CMyToolBar::SetAtCurMousePlase()
{
RECT rtWin = {0};
::GetWindowRect(m_hWnd_toolbar,&rtWin);
POINT pt = {0};
::GetCursorPos(&pt);
this->SetShowPlace(pt.x,pt.y);
}
void CMyToolBar::SetShowPlace(int nCurPointX,int nCurPointY)
{
RECT rtWin = {0};
::GetWindowRect(m_hWnd_toolbar,&rtWin);
::SetWindowPos(m_hWnd_toolbar,HWND_TOP,nCurPointX - (rtWin.right-rtWin.left),nCurPointY + 2,0,0,SWP_NOSIZE|SWP_SHOWWINDOW);
}

@ -1,24 +0,0 @@
#pragma once
#define MyToolBar_ID 600
class CMyToolBar
{
public:
CMyToolBar();
~CMyToolBar(void);
BOOL CreateToolBar(HWND hWndParent);
void AddChildStyle();
void RemoveChildStyle();
void ShowToolBar();
void HideToolBar();
void SetAtCurMousePlase();
void SetShowPlace(int nCurPointX,int nCurPointY);
HWND GetHWND();
private:
HIMAGELIST m_hImageList;
HWND m_hWndParent;
HWND m_hWnd_toolbar;
};

@ -1,839 +0,0 @@
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include "MyTracker.h"
#include "Resource.h"
#include "CatchScreenDlg.h"
/////////////////////////////////////////////////////////////////////////////
// CMyTracker global state
// various GDI objects we need to draw
AFX_STATIC_DATA HCURSOR _afxCursors[10] = { 0,};
AFX_STATIC_DATA HBRUSH _afxHatchBrush = 0;
AFX_STATIC_DATA HPEN _afxBlackDottedPen = 0;
AFX_STATIC_DATA HPEN _afxBlackSolidPen = 0;
AFX_STATIC_DATA int _afxHandleSize = 0;
void AFX_CDECL AfxTrackerTerm()
{
AfxDeleteObject((HGDIOBJ*)&_afxHatchBrush);
AfxDeleteObject((HGDIOBJ*)&_afxBlackDottedPen);
}
char _afxTrackerTerm = (char)atexit(&AfxTrackerTerm);
// the struct below is used to determine the qualities of a particular handle
struct AFX_HANDLEINFO
{
size_t nOffsetX; // offset within RECT for X coordinate
size_t nOffsetY; // offset within RECT for Y coordinate
int nCenterX; // adjust X by Width()/2 * this number
int nCenterY; // adjust Y by Height()/2 * this number
int nHandleX; // adjust X by handle size * this number
int nHandleY; // adjust Y by handle size * this number
int nInvertX; // handle converts to this when X inverted
int nInvertY; // handle converts to this when Y inverted
};
// this array describes all 8 handles (clock-wise)
AFX_STATIC_DATA const AFX_HANDLEINFO _afxHandleInfo[] =
{
// corner handles (top-left, top-right, bottom-right, bottom-left
{ offsetof(RECT, left), offsetof(RECT, top), 0, 0, 0, 0, 1, 3 },
{ offsetof(RECT, right), offsetof(RECT, top), 0, 0, -1, 0, 0, 2 },
{ offsetof(RECT, right), offsetof(RECT, bottom), 0, 0, -1, -1, 3, 1 },
{ offsetof(RECT, left), offsetof(RECT, bottom), 0, 0, 0, -1, 2, 0 },
// side handles (top, right, bottom, left)
{ offsetof(RECT, left), offsetof(RECT, top), 1, 0, 0, 0, 4, 6 },
{ offsetof(RECT, right), offsetof(RECT, top), 0, 1, -1, 0, 7, 5 },
{ offsetof(RECT, left), offsetof(RECT, bottom), 1, 0, 0, -1, 6, 4 },
{ offsetof(RECT, left), offsetof(RECT, top), 0, 1, 0, 0, 5, 7 }
};
// the struct below gives us information on the layout of a RECT struct and
// the relationship between its members
struct AFX_RECTINFO
{
size_t nOffsetAcross; // offset of opposite point (ie. left->right)
int nSignAcross; // sign relative to that point (ie. add/subtract)
};
// this array is indexed by the offset of the RECT member / sizeof(int)
AFX_STATIC_DATA const AFX_RECTINFO _afxRectInfo[] =
{
{ offsetof(RECT, right), +1 },
{ offsetof(RECT, bottom), +1 },
{ offsetof(RECT, left), -1 },
{ offsetof(RECT, top), -1 },
};
/////////////////////////////////////////////////////////////////////////////
// CMyTracker intitialization
CMyTracker::CMyTracker(LPCRECT lpSrcRect, UINT nStyle)
{
ASSERT(AfxIsValidAddress(lpSrcRect, sizeof(RECT), FALSE));
Construct();
m_rect.CopyRect(lpSrcRect);
m_nStyle = nStyle;
}
CMyTracker::CMyTracker()
{
Construct();
}
void CMyTracker::Construct()
{
// do one-time initialization if necessary
//********************************************************
m_rectColor=RGB(0,0,0);
//********************************************************
AfxLockGlobals(CRIT_RECTTRACKER);
static BOOL bInitialized;
if (!bInitialized)
{
// sanity checks for assumptions we make in the code
ASSERT(sizeof(((RECT*)NULL)->left) == sizeof(int));
ASSERT(offsetof(RECT, top) > offsetof(RECT, left));
ASSERT(offsetof(RECT, right) > offsetof(RECT, top));
ASSERT(offsetof(RECT, bottom) > offsetof(RECT, right));
if (_afxHatchBrush == NULL)
{
// create the hatch pattern + bitmap
WORD hatchPattern[8];
WORD wPattern = 0x1111;
for (int i = 0; i < 4; i++)
{
hatchPattern[i] = wPattern;
hatchPattern[i+4] = wPattern;
wPattern <<= 1;
}
HBITMAP hatchBitmap = CreateBitmap(8, 8, 1, 1, &hatchPattern);
if (hatchBitmap == NULL)
{
AfxUnlockGlobals(CRIT_RECTTRACKER);
AfxThrowResourceException();
}
// create black hatched brush
_afxHatchBrush = CreatePatternBrush(hatchBitmap);
DeleteObject(hatchBitmap);
if (_afxHatchBrush == NULL)
{
AfxUnlockGlobals(CRIT_RECTTRACKER);
AfxThrowResourceException();
}
}
//CreatePen for DottedLine and SolidLine
CreatePen();
// Note: all track cursors must live in same module
HINSTANCE hInst = AfxFindResourceHandle(
MAKEINTRESOURCE(AFX_IDC_TRACK4WAY), RT_GROUP_CURSOR);
// initialize the cursor array
_afxCursors[0] = ::LoadCursor(hInst, MAKEINTRESOURCE(AFX_IDC_TRACKNWSE));
_afxCursors[1] = ::LoadCursor(hInst, MAKEINTRESOURCE(AFX_IDC_TRACKNESW));
_afxCursors[2] = _afxCursors[0];
_afxCursors[3] = _afxCursors[1];
_afxCursors[4] = ::LoadCursor(hInst, MAKEINTRESOURCE(AFX_IDC_TRACKNS));
_afxCursors[5] = ::LoadCursor(hInst, MAKEINTRESOURCE(AFX_IDC_TRACKWE));
_afxCursors[6] = _afxCursors[4];
_afxCursors[7] = _afxCursors[5];
_afxCursors[8] = ::LoadCursor(hInst, MAKEINTRESOURCE(AFX_IDC_TRACK4WAY));
_afxCursors[9] = ::LoadCursor(hInst, MAKEINTRESOURCE(AFX_IDC_MOVE4WAY));
// get default handle size from Windows profile setting
static const TCHAR szWindows[] = _T("windows");
static const TCHAR szInplaceBorderWidth[] =
_T("oleinplaceborderwidth");
_afxHandleSize = GetProfileInt(szWindows, szInplaceBorderWidth, 4);
bInitialized = TRUE;
}
AfxUnlockGlobals(CRIT_RECTTRACKER);
m_nStyle = 0;
m_nHandleSize = _afxHandleSize;
m_sizeMin.cy = m_sizeMin.cx = m_nHandleSize*2;
m_rectLast.SetRectEmpty();
m_sizeLast.cx = m_sizeLast.cy = 0;
m_bErase = FALSE;
m_bFinalErase = FALSE;
}
CMyTracker::~CMyTracker()
{
}
/////////////////////////////////////////////////////////////////////////////
// CMyTracker operations
void CMyTracker::Draw(CDC* pDC) const
{
// set initial DC state
VERIFY(pDC->SaveDC() != 0);
pDC->SetMapMode(MM_TEXT);
pDC->SetViewportOrg(0, 0);
pDC->SetWindowOrg(0, 0);
// get normalized rectangle
CRect rect = m_rect;
rect.NormalizeRect();
CPen* pOldPen = NULL;
CBrush* pOldBrush = NULL;
CGdiObject* pTemp;
int nOldROP;
// draw lines
if ((m_nStyle & (dottedLine|solidLine)) != 0)
{
if (m_nStyle & dottedLine)
{
//改变当前矩形颜色
pOldPen = pDC->SelectObject(CPen::FromHandle(_afxBlackDottedPen));
}
else
{
//改变当前矩形颜色
//pOldPen = (CPen*)pDC->SelectStockObject(BLACK_PEN); //BLACK_PEN
pOldPen = pDC->SelectObject(CPen::FromHandle(_afxBlackSolidPen));
}
pOldBrush = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);
nOldROP = pDC->SetROP2(R2_COPYPEN);
rect.InflateRect(+1, +1); // borders are one pixel outside
pDC->Rectangle(rect.left, rect.top, rect.right, rect.bottom);
pDC->SetROP2(nOldROP);
}
// if hatchBrush is going to be used, need to unrealize it
if ((m_nStyle & (hatchInside|hatchedBorder)) != 0)
UnrealizeObject(_afxHatchBrush);
// hatch inside
if ((m_nStyle & hatchInside) != 0)
{
pTemp = pDC->SelectStockObject(NULL_PEN);
if (pOldPen == NULL)
pOldPen = (CPen*)pTemp;
pTemp = pDC->SelectObject(CBrush::FromHandle(_afxHatchBrush));
if (pOldBrush == NULL)
pOldBrush = (CBrush*)pTemp;
pDC->SetBkMode(TRANSPARENT);
nOldROP = pDC->SetROP2(R2_MASKNOTPEN);
pDC->Rectangle(rect.left+1, rect.top+1, rect.right, rect.bottom);
pDC->SetROP2(nOldROP);
}
// draw hatched border
if ((m_nStyle & hatchedBorder) != 0)
{
pTemp = pDC->SelectObject(CBrush::FromHandle(_afxHatchBrush));
if (pOldBrush == NULL)
pOldBrush = (CBrush*)pTemp;
pDC->SetBkMode(OPAQUE);
CRect rectTrue;
GetTrueRect(&rectTrue);
pDC->PatBlt(rectTrue.left, rectTrue.top, rectTrue.Width(),
rect.top-rectTrue.top, 0x000F0001 /* Pn */);
pDC->PatBlt(rectTrue.left, rect.bottom,
rectTrue.Width(), rectTrue.bottom-rect.bottom, 0x000F0001 /* Pn */);
pDC->PatBlt(rectTrue.left, rect.top, rect.left-rectTrue.left,
rect.Height(), 0x000F0001 /* Pn */);
pDC->PatBlt(rect.right, rect.top, rectTrue.right-rect.right,
rect.Height(), 0x000F0001 /* Pn */);
}
// draw resize handles
if ((m_nStyle & (resizeInside|resizeOutside)) != 0)
{
UINT mask = GetHandleMask();
for (int i = 0; i < 8; ++i)
{
if (mask & (1<<i))
{
GetHandleRect((TrackerHit)i, &rect);
//改变当前调整手柄矩形颜色,也就是那八个点
pDC->FillSolidRect(rect, m_rectColor);
}
}
}
// cleanup pDC state
if (pOldPen != NULL)
pDC->SelectObject(pOldPen);
if (pOldBrush != NULL)
pDC->SelectObject(pOldBrush);
VERIFY(pDC->RestoreDC(-1));
}
BOOL CMyTracker::SetCursor(CWnd* pWnd, UINT nHitTest) const
{
// trackers should only be in client area
if (nHitTest != HTCLIENT)
return FALSE;
// convert cursor position to client co-ordinates
CPoint point;
GetCursorPos(&point);
pWnd->ScreenToClient(&point);
// do hittest and normalize hit
int nHandle = HitTestHandles(point);
if (nHandle < 0)
return FALSE;
// need to normalize the hittest such that we get proper cursors
nHandle = NormalizeHit(nHandle);
// handle special case of hitting area between handles
// (logically the same -- handled as a move -- but different cursor)
if (nHandle == hitMiddle && !m_rect.PtInRect(point))
{
// only for trackers with hatchedBorder (ie. in-place resizing)
if (m_nStyle & hatchedBorder)
nHandle = (TrackerHit)9;
}
//ASSERT(nHandle < _countof(_afxCursors));
::SetCursor(_afxCursors[nHandle]);
return TRUE;
}
int CMyTracker::HitTest(CPoint point) const
{
TrackerHit hitResult = hitNothing;
CRect rectTrue;
GetTrueRect(&rectTrue);
ASSERT(rectTrue.left <= rectTrue.right);
ASSERT(rectTrue.top <= rectTrue.bottom);
if (rectTrue.PtInRect(point))
{
if ((m_nStyle & (resizeInside|resizeOutside)) != 0)
hitResult = (TrackerHit)HitTestHandles(point);
else
hitResult = hitMiddle;
}
return hitResult;
}
int CMyTracker::NormalizeHit(int nHandle) const
{
ASSERT(nHandle <= 8 && nHandle >= -1);
if (nHandle == hitMiddle || nHandle == hitNothing)
return nHandle;
const AFX_HANDLEINFO* pHandleInfo = &_afxHandleInfo[nHandle];
if (m_rect.Width() < 0)
{
nHandle = (TrackerHit)pHandleInfo->nInvertX;
pHandleInfo = &_afxHandleInfo[nHandle];
}
if (m_rect.Height() < 0)
nHandle = (TrackerHit)pHandleInfo->nInvertY;
return nHandle;
}
BOOL CMyTracker::Track(CWnd* pWnd, CPoint point, BOOL bAllowInvert,
CWnd* pWndClipTo)
{
// perform hit testing on the handles
int nHandle = HitTestHandles(point);
if (nHandle < 0)
{
// didn't hit a handle, so just return FALSE
return FALSE;
}
// otherwise, call helper function to do the tracking
m_bAllowInvert = bAllowInvert;
return TrackHandle(nHandle, pWnd, point, pWndClipTo);
}
BOOL CMyTracker::TrackRubberBand(CWnd* pWnd, CPoint point, BOOL bAllowInvert)
{
// simply call helper function to track from bottom right handle
m_bAllowInvert = bAllowInvert;
m_rect.SetRect(point.x, point.y, point.x, point.y);
return TrackHandle(hitBottomRight, pWnd, point, NULL);
}
void CMyTracker::DrawTrackerRect(
LPCRECT lpRect, CWnd* pWndClipTo, CDC* pDC, CWnd* pWnd)
{
// first, normalize the rectangle for drawing
/*CRect rect = *lpRect;
rect.NormalizeRect();
// convert to client coordinates
if (pWndClipTo != NULL)
{
pWnd->ClientToScreen(&rect);
pWndClipTo->ScreenToClient(&rect);
}
CSize size(0, 0);
if (!m_bFinalErase)
{
// otherwise, size depends on the style
if (m_nStyle & hatchedBorder)
{
size.cx = size.cy = max(1, GetHandleSize(rect)-1);
rect.InflateRect(size);
}
else
{
size.cx = CX_BORDER;
size.cy = CY_BORDER;
}
}
// and draw it
if (m_bFinalErase || !m_bErase)
{
pDC->DrawDragRect(rect, size, m_rectLast, m_sizeLast);
}
// remember last rectangles
m_rectLast = rect;
m_sizeLast = size;
*/
//此函数是画调整大小和位置时画虚线
//由于本程序不需要,如果要正常使作的话把上面注示去掉就行了!
((CCatchScreenDlg *)pWnd)->InvalidateRgnWindow();
}
void CMyTracker::AdjustRect(int nHandle, LPRECT)
{
if (nHandle == hitMiddle)
return;
// convert the handle into locations within m_rect
int *px, *py;
GetModifyPointers(nHandle, &px, &py, NULL, NULL);
// enforce minimum width
int nNewWidth = m_rect.Width();
int nAbsWidth = m_bAllowInvert ? abs(nNewWidth) : nNewWidth;
if (px != NULL && nAbsWidth < m_sizeMin.cx)
{
nNewWidth = nAbsWidth != 0 ? nNewWidth / nAbsWidth : 1;
//ASSERT((int*)px - (int*)&m_rect < _countof(_afxRectInfo));
const AFX_RECTINFO* pRectInfo = &_afxRectInfo[(int*)px - (int*)&m_rect];
*px = *(int*)((BYTE*)&m_rect + pRectInfo->nOffsetAcross) +
nNewWidth * m_sizeMin.cx * -pRectInfo->nSignAcross;
}
// enforce minimum height
int nNewHeight = m_rect.Height();
int nAbsHeight = m_bAllowInvert ? abs(nNewHeight) : nNewHeight;
if (py != NULL && nAbsHeight < m_sizeMin.cy)
{
nNewHeight = nAbsHeight != 0 ? nNewHeight / nAbsHeight : 1;
//ASSERT((int*)py - (int*)&m_rect < _countof(_afxRectInfo));
const AFX_RECTINFO* pRectInfo = &_afxRectInfo[(int*)py - (int*)&m_rect];
*py = *(int*)((BYTE*)&m_rect + pRectInfo->nOffsetAcross) +
nNewHeight * m_sizeMin.cy * -pRectInfo->nSignAcross;
}
}
void CMyTracker::GetTrueRect(LPRECT lpTrueRect) const
{
ASSERT(AfxIsValidAddress(lpTrueRect, sizeof(RECT)));
CRect rect = m_rect;
rect.NormalizeRect();
int nInflateBy = 0;
if ((m_nStyle & (resizeOutside|hatchedBorder)) != 0)
nInflateBy += GetHandleSize() - 1;
if ((m_nStyle & (solidLine|dottedLine)) != 0)
++nInflateBy;
rect.InflateRect(nInflateBy, nInflateBy);
*lpTrueRect = rect;
}
void CMyTracker::OnChangedRect(const CRect& /*rectOld*/)
{
// no default implementation, useful for derived classes
}
/////////////////////////////////////////////////////////////////////////////
// CMyTracker implementation helpers
void CMyTracker::GetHandleRect(int nHandle, CRect* pHandleRect) const
{
ASSERT(nHandle < 8);
// get normalized rectangle of the tracker
CRect rectT = m_rect;
rectT.NormalizeRect();
if ((m_nStyle & (solidLine|dottedLine)) != 0)
rectT.InflateRect(+1, +1);
// since the rectangle itself was normalized, we also have to invert the
// resize handles.
nHandle = NormalizeHit(nHandle);
// handle case of resize handles outside the tracker
int size = GetHandleSize();
if(m_nStyle & resizeOutside)
{
if(1000000 & m_nStyle)
{
rectT.InflateRect(size-size/2-1, size-size/2-1);
}
else
{
rectT.InflateRect(size-1, size-1);
}
}
// calculate position of the resize handle
int nWidth = rectT.Width();
int nHeight = rectT.Height();
CRect rect;
const AFX_HANDLEINFO* pHandleInfo = &_afxHandleInfo[nHandle];
rect.left = *(int*)((BYTE*)&rectT + pHandleInfo->nOffsetX);
rect.top = *(int*)((BYTE*)&rectT + pHandleInfo->nOffsetY);
rect.left += size * pHandleInfo->nHandleX;
rect.top += size * pHandleInfo->nHandleY;
rect.left += pHandleInfo->nCenterX * (nWidth - size) / 2;
rect.top += pHandleInfo->nCenterY * (nHeight - size) / 2;
rect.right = rect.left + size;
rect.bottom = rect.top + size;
*pHandleRect = rect;
}
int CMyTracker::GetHandleSize(LPCRECT lpRect) const
{
if (lpRect == NULL)
lpRect = &m_rect;
int size = m_nHandleSize;
if (!(m_nStyle & resizeOutside))
{
// make sure size is small enough for the size of the rect
int sizeMax = min(abs(lpRect->right - lpRect->left),
abs(lpRect->bottom - lpRect->top));
if (size * 2 > sizeMax)
size = sizeMax / 2;
}
return size;
}
int CMyTracker::HitTestHandles(CPoint point) const
{
CRect rect;
UINT mask = GetHandleMask();
// see if hit anywhere inside the tracker
GetTrueRect(&rect);
if (!rect.PtInRect(point))
return hitNothing; // totally missed
// see if we hit a handle
for (int i = 0; i < 8; ++i)
{
if (mask & (1<<i))
{
GetHandleRect((TrackerHit)i, &rect);
if (rect.PtInRect(point))
return (TrackerHit)i;
}
}
// last of all, check for non-hit outside of object, between resize handles
if ((m_nStyle & hatchedBorder) == 0)
{
CRect rect = m_rect;
rect.NormalizeRect();
if ((m_nStyle & dottedLine|solidLine) != 0)
rect.InflateRect(+1, +1);
if (!rect.PtInRect(point))
return hitNothing; // must have been between resize handles
}
return hitMiddle; // no handle hit, but hit object (or object border)
}
BOOL CMyTracker::TrackHandle(int nHandle, CWnd* pWnd, CPoint point,
CWnd* pWndClipTo)
{
ASSERT(nHandle >= 0);
ASSERT(nHandle <= 8); // handle 8 is inside the rect
// don't handle if capture already set
if (::GetCapture() != NULL)
return FALSE;
AfxLockTempMaps(); // protect maps while looping
ASSERT(!m_bFinalErase);
// save original width & height in pixels
int nWidth = m_rect.Width();
int nHeight = m_rect.Height();
// set capture to the window which received this message
pWnd->SetCapture();
ASSERT(pWnd == CWnd::GetCapture());
pWnd->UpdateWindow();
if (pWndClipTo != NULL)
pWndClipTo->UpdateWindow();
CRect rectSave = m_rect;
// find out what x/y coords we are supposed to modify
int *px, *py;
int xDiff, yDiff;
GetModifyPointers(nHandle, &px, &py, &xDiff, &yDiff);
xDiff = point.x - xDiff;
yDiff = point.y - yDiff;
// get DC for drawing
CDC* pDrawDC;
if (pWndClipTo != NULL)
{
// clip to arbitrary window by using adjusted Window DC
pDrawDC = pWndClipTo->GetDCEx(NULL, DCX_CACHE);
}
else
{
// otherwise, just use normal DC
pDrawDC = pWnd->GetDC();
}
ASSERT_VALID(pDrawDC);
CRect rectOld;
BOOL bMoved = FALSE;
// get messages until capture lost or cancelled/accepted
for (;;)
{
MSG msg;
VERIFY(::GetMessage(&msg, NULL, 0, 0));
if (CWnd::GetCapture() != pWnd)
break;
//增加的,把消息派送给窗口
DispatchMessage(&msg);
switch (msg.message)
{
// handle movement/accept messages
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
rectOld = m_rect;
// handle resize cases (and part of move)
if (px != NULL)
*px = (int)(short)LOWORD(msg.lParam) - xDiff;
if (py != NULL)
*py = (int)(short)HIWORD(msg.lParam) - yDiff;
// handle move case
if (nHandle == hitMiddle)
{
m_rect.right = m_rect.left + nWidth;
m_rect.bottom = m_rect.top + nHeight;
}
// allow caller to adjust the rectangle if necessary
AdjustRect(nHandle, &m_rect);
// only redraw and callback if the rect actually changed!
m_bFinalErase = (msg.message == WM_LBUTTONUP);
if (!rectOld.EqualRect(&m_rect) || m_bFinalErase)
{
if (bMoved)
{
m_bErase = TRUE;
DrawTrackerRect(&rectOld, pWndClipTo, pDrawDC, pWnd);
}
OnChangedRect(rectOld);
if (msg.message != WM_LBUTTONUP)
{
bMoved = TRUE;
}
}
if (m_bFinalErase)
goto ExitLoop;
if (!rectOld.EqualRect(&m_rect))
{
m_bErase = FALSE;
DrawTrackerRect(&m_rect, pWndClipTo, pDrawDC, pWnd);
}
break;
// handle cancel messages
case WM_KEYDOWN:
if (msg.wParam != VK_ESCAPE)
break;
case WM_RBUTTONDOWN:
if (bMoved)
{
m_bErase = m_bFinalErase = TRUE;
//DrawTrackerRect(&m_rect, pWndClipTo, pDrawDC, pWnd);
}
m_rect = rectSave;
goto ExitLoop;
// just dispatch rest of the messages
default:
DispatchMessage(&msg);
break;
}
}
ExitLoop:
if (pWndClipTo != NULL)
pWndClipTo->ReleaseDC(pDrawDC);
else
pWnd->ReleaseDC(pDrawDC);
ReleaseCapture();
AfxUnlockTempMaps(FALSE);
// restore rect in case bMoved is still FALSE
if (!bMoved)
m_rect = rectSave;
m_bFinalErase = FALSE;
m_bErase = FALSE;
// return TRUE only if rect has changed
return !rectSave.EqualRect(&m_rect);
}
void CMyTracker::GetModifyPointers(
int nHandle, int** ppx, int** ppy, int* px, int* py)
{
ASSERT(nHandle >= 0);
ASSERT(nHandle <= 8);
if (nHandle == hitMiddle)
nHandle = hitTopLeft; // same as hitting top-left
*ppx = NULL;
*ppy = NULL;
// fill in the part of the rect that this handle modifies
// (Note: handles that map to themselves along a given axis when that
// axis is inverted don't modify the value on that axis)
const AFX_HANDLEINFO* pHandleInfo = &_afxHandleInfo[nHandle];
if (pHandleInfo->nInvertX != nHandle)
{
*ppx = (int*)((BYTE*)&m_rect + pHandleInfo->nOffsetX);
if (px != NULL)
*px = **ppx;
}
else
{
// middle handle on X axis
if (px != NULL)
*px = m_rect.left + abs(m_rect.Width()) / 2;
}
if (pHandleInfo->nInvertY != nHandle)
{
*ppy = (int*)((BYTE*)&m_rect + pHandleInfo->nOffsetY);
if (py != NULL)
*py = **ppy;
}
else
{
// middle handle on Y axis
if (py != NULL)
*py = m_rect.top + abs(m_rect.Height()) / 2;
}
}
UINT CMyTracker::GetHandleMask() const
{
UINT mask = 0x0F; // always have 4 corner handles
int size = m_nHandleSize*3;
if (abs(m_rect.Width()) - size > 4)
mask |= 0x50;
if (abs(m_rect.Height()) - size > 4)
mask |= 0xA0;
return mask;
}
////////////////////增加的函数/////////////////////////////////////////////////////////////
void CMyTracker::SetRectColor(COLORREF rectColor)
{
m_rectColor=rectColor;
CreatePen();
}
void CMyTracker::CreatePen()
{
//if (_afxBlackDottedPen == NULL)
{
// create black dotted pen
_afxBlackDottedPen = ::CreatePen(PS_DOT, 0, m_rectColor);
if (_afxBlackDottedPen == NULL)
{
AfxUnlockGlobals(CRIT_RECTTRACKER);
AfxThrowResourceException();
}
}
//if (_afxBlackSolidPen == NULL)
{
// create black dotted pen
_afxBlackSolidPen = ::CreatePen(PS_SOLID, 0, m_rectColor);
if (_afxBlackSolidPen == NULL)
{
AfxUnlockGlobals(CRIT_RECTTRACKER);
AfxThrowResourceException();
}
}
}
void CMyTracker::SetResizeCursor(UINT nID_N_S,UINT nID_W_E,UINT nID_NW_SE,UINT nID_NE_SW,UINT nIDMiddle)
{
//////////////////////////////////////////////////////////////////////////////////
// N
// NW -----------|------------NE
// | |
// | |
// W | | E
// | Middle |
// | |
// | |
// SW-----------|------------SE
// S
////////////////////////////////////////////////////////////////////////////////////
_afxCursors[0] = AfxGetApp()->LoadCursor(nID_NW_SE); //nw
_afxCursors[1] = AfxGetApp()->LoadCursor(nID_NE_SW); //ne
_afxCursors[2] = _afxCursors[0]; //se
_afxCursors[3] = _afxCursors[1]; //sw
_afxCursors[4] = AfxGetApp()->LoadCursor(nID_N_S); //n
_afxCursors[5] = AfxGetApp()->LoadCursor(nID_W_E); //w
_afxCursors[6] = _afxCursors[4]; //s
_afxCursors[7] = _afxCursors[5]; //e
_afxCursors[8] = AfxGetApp()->LoadCursor(nIDMiddle); //m
// _afxCursors[9] = ::LoadCursor(hInst, MAKEINTRESOURCE(AFX_IDC_MOVE4WAY));
}

@ -1,102 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// CMyTracker - simple rectangular tracking rectangle w/resize handles
/////////////////////////////////////////////////////////////////////////
// Copy from MFC CRectTracker class
// Add Some member function
// Modify some place
////////////////////////////////////////////////////////////////////////
#define MYTRACKER_
#define CX_BORDER 1
#define CY_BORDER 1
#define CRIT_RECTTRACKER 5
void AFXAPI AfxLockGlobals(int nLockType);
void AFXAPI AfxUnlockGlobals(int nLockType);
void AFXAPI AfxDeleteObject(HGDIOBJ* pObject);
class CMyTracker
{
public:
// Constructors
CMyTracker();
CMyTracker(LPCRECT lpSrcRect, UINT nStyle);
// Style Flags
enum StyleFlags
{
solidLine = 1, dottedLine = 2, hatchedBorder = 4,
resizeInside = 8, resizeOutside = 16, hatchInside = 32,
resizeMiddle =80 //设置中间
};
// Hit-Test codes
enum TrackerHit
{
hitNothing = -1,
hitTopLeft = 0, hitTopRight = 1, hitBottomRight = 2, hitBottomLeft = 3,
hitTop = 4, hitRight = 5, hitBottom = 6, hitLeft = 7, hitMiddle = 8
};
// Attributes
UINT m_nStyle; // current state
CRect m_rect; // current position (always in pixels)
CSize m_sizeMin; // minimum X and Y size during track operation
int m_nHandleSize; // size of resize handles (default from WIN.INI)
// Operations
void Draw(CDC* pDC) const;
void GetTrueRect(LPRECT lpTrueRect) const;
BOOL SetCursor(CWnd* pWnd, UINT nHitTest) const;
BOOL Track(CWnd* pWnd, CPoint point, BOOL bAllowInvert =TRUE,
CWnd* pWndClipTo = NULL);
BOOL TrackRubberBand(CWnd* pWnd, CPoint point, BOOL bAllowInvert = TRUE);
int HitTest(CPoint point) const;
int NormalizeHit(int nHandle) const;
// Overridables
virtual void DrawTrackerRect(LPCRECT lpRect, CWnd* pWndClipTo,
CDC* pDC, CWnd* pWnd);
virtual void AdjustRect(int nHandle, LPRECT lpRect);
virtual void OnChangedRect(const CRect& rectOld);
virtual UINT GetHandleMask() const;
// Implementation
public:
virtual ~CMyTracker();
public:
//***********************************************************
//设置调整光标
void SetResizeCursor(UINT nID_N_S,UINT nID_W_E,UINT nID_NW_SE,
UINT nID_NE_SW,UINT nIDMiddle);
//创建军画刷,内部调用
void CreatePen();
//设置矩形颜色
void SetRectColor(COLORREF rectColor);
//**************************************************************
//**************************************************************
//当前矩形颜色
COLORREF m_rectColor;
//**************************************************************
BOOL m_bAllowInvert; // flag passed to Track or TrackRubberBand
CRect m_rectLast;
CSize m_sizeLast;
BOOL m_bErase; // TRUE if DrawTrackerRect is called for erasing
BOOL m_bFinalErase; // TRUE if DragTrackerRect called for final erase
// implementation helpers
int HitTestHandles(CPoint point) const;
void GetHandleRect(int nHandle, CRect* pHandleRect) const;
void GetModifyPointers(int nHandle, int**ppx, int**ppy, int* px, int*py);
virtual int GetHandleSize(LPCRECT lpRect = NULL) const;
BOOL TrackHandle(int nHandle, CWnd* pWnd, CPoint point, CWnd* pWndClipTo);
void Construct();
};
//////////////////////////////////////// END OF FILE /////////////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff

@ -1,117 +0,0 @@
/*
Copyright (C) 2004 Jacquelin POTIER <jacquelin.potier@free.fr>
Dynamic aspect ratio code Copyright (C) 2004 Jacquelin POTIER <jacquelin.potier@free.fr>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//-----------------------------------------------------------------------------
// Object: class helper for popupmenu control
//-----------------------------------------------------------------------------
#pragma once
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501 // for xp os
#endif
#include <windows.h>
#pragma warning (push)
#pragma warning(disable : 4005)// for '_stprintf' : macro redefinition in tchar.h
#include <TCHAR.h>
#pragma warning (pop)
#include <vector>
#include <commctrl.h>
#pragma comment (lib,"comctl32.lib")
class CPopUpMenu
{
public:
typedef void (*pfMessageCallback)(WPARAM wParam, LPARAM lParam,PVOID UserParam);
CPopUpMenu();
CPopUpMenu(CPopUpMenu* ParentPopUpMenu);
~CPopUpMenu();
HMENU GetControlHandle();
CPopUpMenu* GetParentPopUpMenu();
UINT Add(TCHAR* Name);
UINT Add(TCHAR* Name,UINT Index);
UINT Add(TCHAR* Name,HICON hIcon);
UINT Add(TCHAR* Name,HICON hIcon,UINT Index);
UINT Add(TCHAR* Name,int IdIcon,HINSTANCE hInstance);
UINT Add(TCHAR* Name,int IdIcon,HINSTANCE hInstance,UINT Index);
UINT Add(TCHAR* Name,int IdIcon,HINSTANCE hInstance,int Width,int Height,UINT Index);
UINT AddSeparator();
UINT AddSeparator(UINT Index);
UINT AddSubMenu(TCHAR* SubMenuName,CPopUpMenu* SubMenu,UINT Index);
UINT AddSubMenu(TCHAR* SubMenuName,CPopUpMenu* SubMenu);
UINT AddSubMenu(TCHAR* SubMenuName,CPopUpMenu* SubMenu,int IdIcon,HINSTANCE hInstance,UINT Index);
UINT AddSubMenu(TCHAR* SubMenuName,CPopUpMenu* SubMenu,int IdIcon,HINSTANCE hInstance);
UINT AddSubMenu(TCHAR* SubMenuName,CPopUpMenu* SubMenu,HICON hIcon,UINT Index);
UINT AddSubMenu(TCHAR* SubMenuName,CPopUpMenu* SubMenu,HICON hIcon);
void SetCheckedState(UINT MenuID,BOOL bChecked);
BOOL IsChecked(UINT MenuID);
void SetEnabledState(UINT MenuID,BOOL bEnabled);
BOOL IsEnabled(UINT MenuID);
BOOL SetText(UINT MenuID,TCHAR* pszText);
BOOL SetIcon(UINT MenuID,int IdIcon,HINSTANCE hInstance);
BOOL SetIcon(UINT MenuID,int IdIcon,HINSTANCE hInstance,int Width,int Height);
BOOL SetIcon(UINT MenuID,HICON hIcon);
int GetText(UINT MenuID,TCHAR* pszText,int pszTextMaxSize);
CPopUpMenu* GetSubMenu(UINT MenuID);
void Remove(UINT MenuID);
int GetItemCount();
int GetID(UINT MenuIndex);
int GetIndex(UINT MenuId);
UINT Show(int x,int y, HWND hOwner);
UINT Show(int x,int y, HWND hOwner,BOOL PositionRelativeToOwner);
UINT Show(int x,int y, HWND hOwner,BOOL PositionRelativeToOwner,BOOL ShowUpper);
UINT GetNextMenuId();
UINT GetMaxMenuId();
BOOL ReplaceMenuId(UINT OldMenuID,UINT NewMenuID);
BOOL SetMouseRightButtonUpCallback(pfMessageCallback Callback,PVOID UserParam);
BOOL SetMenuSelectCallback(pfMessageCallback Callback,PVOID UserParam);
BOOL bAllowIconsEffects;
private:
CPopUpMenu* ParentPopUpMenu;
HMENU hPopUpMenu;
int CurrentMenuId;
BOOL bThemingEnabledForVistaOrNewer;
std::vector<HBITMAP> ListLoadedBitmapToFree;
pfMessageCallback MouseRightButtonUpCallback;
PVOID MouseRightButtonUpUserParam;
pfMessageCallback MenuSelectCallback;
PVOID MenuSelectUserParam;
void CommonConstructor();
void SetMenuItemBitmapInfo(MENUITEMINFO* pMenuItem,HICON hIcon);
BOOL IsSubMenu(HMENU hMenu,HMENU hSubMenu);
BOOL OnMeasureItem(HWND hwnd, LPMEASUREITEMSTRUCT lpmis);
BOOL OnDrawItem(HWND hwnd, LPDRAWITEMSTRUCT lpdis);
void OnMouseRightButtonUp(WPARAM wParam, LPARAM lParam);
void OnMenuSelect(WPARAM wParam, LPARAM lParam);
void FreeItemMemory(UINT MenuID);
void FreeItemBitmap(UINT MenuID);
static LRESULT CALLBACK SubClassWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,UINT_PTR uIdSubclass,DWORD_PTR dwRefData);
};

@ -1,73 +0,0 @@
================================================================================
MICROSOFT 基础类库: Screenshot 项目概述
===============================================================================
应用程序向导已为您创建了这个 Screenshot 应用程序。此应用程序不仅演示 Microsoft 基础类的基本使用方法,还可作为您编写应用程序的起点。
本文件概要介绍组成 Screenshot 应用程序的每个文件的内容。
Screenshot.vcproj
这是使用应用程序向导生成的 VC++ 项目的主项目文件。
它包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
Screenshot.h
这是应用程序的主要头文件。它包括其他项目特定的头文件(包括 Resource.h),并声明 CScreenshotApp 应用程序类。
Screenshot.cpp
这是包含应用程序类 CScreenshotApp 的主要应用程序源文件。
Screenshot.rc
这是程序使用的所有 Microsoft Windows 资源的列表。它包括 RES 子目录中存储的图标、位图和光标。此文件可以直接在 Microsoft Visual C++ 中进行编辑。项目资源位于 2052 中。
res\Screenshot.ico
这是用作应用程序图标的图标文件。此图标包括在主要资源文件 Screenshot.rc 中。
res\Screenshot.rc2
此文件包含不在 Microsoft Visual C++ 中进行编辑的资源。您应该将不可由资源编辑器编辑的所有资源放在此文件中。
/////////////////////////////////////////////////////////////////////////////
应用程序向导创建一个对话框类:
ScreenshotDlg.hScreenshotDlg.cpp - 对话框
这些文件包含 CScreenshotDlg 类。该类定义应用程序主对话框的行为。该对话框的模板位于 Screenshot.rc 中,该文件可以在 Microsoft Visual C++ 中进行编辑。
/////////////////////////////////////////////////////////////////////////////
其他功能:
ActiveX 控件
应用程序包括对使用 ActiveX 控件的支持。
打印及打印预览支持
应用程序向导已通过从 MFC 库调用 CView 类中的成员函数,生成了用于处理打印、打印设置和打印预览命令的代码。
/////////////////////////////////////////////////////////////////////////////
其他标准文件:
StdAfx.hStdAfx.cpp
这些文件用于生成名为 Screenshot.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。
Resource.h
这是标准头文件,它定义新的资源 ID。
Microsoft Visual C++ 读取并更新此文件。
Screenshot.manifest
应用程序清单文件供 Windows XP 用来描述应用程序
对特定版本并行程序集的依赖性。加载程序使用此
信息从程序集缓存加载适当的程序集或
从应用程序加载私有信息。应用程序清单可能为了重新分发而作为
与应用程序可执行文件安装在相同文件夹中的外部 .manifest 文件包括,
也可能以资源的形式包括在该可执行文件中。
/////////////////////////////////////////////////////////////////////////////
其他注释:
应用程序向导使用“TODO:”指示应添加或自定义的源代码部分。
如果应用程序在共享的 DLL 中使用 MFC则需要重新发布这些 MFC DLL如果应用程序所用的语言与操作系统的当前区域设置不同则还需要重新发布对应的本地化资源 MFC90XXX.DLL。有关这两个主题的更多信息请参见 MSDN 文档中有关 Redistributing Visual C++ applications (重新发布 Visual C++ 应用程序)的章节。
/////////////////////////////////////////////////////////////////////////////

Binary file not shown.

@ -1,174 +0,0 @@
// Screenshot.cpp : 定义应用程序的类行为。
//
#include "stdafx.h"
#include "Screenshot.h"
#include "ScreenshotDlg.h"
#include "CatchScreenDlg.h"
#include <GdiPlus.h>
using namespace Gdiplus;
#pragma comment(lib,"GdiPlus.lib")
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define SHIFTED 0x8000
// CScreenshotApp
BEGIN_MESSAGE_MAP(CScreenshotApp, CWinApp)
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
// CScreenshotApp 构造
CScreenshotApp::CScreenshotApp()
{
// TODO: 在此处添加构造代码,
// 将所有重要的初始化放置在 InitInstance 中
}
// 唯一的一个 CScreenshotApp 对象
CScreenshotApp theApp;
// CScreenshotApp 初始化
BOOL CScreenshotApp::InitInstance()
{
// 如果一个运行在 Windows XP 上的应用程序清单指定要
// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
//则需要 InitCommonControlsEx()。否则,将无法创建窗口。
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// 将它设置为包括所有要在应用程序中使用的
// 公共控件类。
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
GdiplusStartupInput input;
GdiplusStartup(&m_gdiplusToken,&input,NULL);
AfxEnableControlContainer();
// 标准初始化
// 如果未使用这些功能并希望减小
// 最终可执行文件的大小,则应移除下列
// 不需要的特定初始化例程
// 更改用于存储设置的注册表项
// TODO: 应适当修改该字符串,
// 例如修改为公司或组织名
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
CScreenshotDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: 在此放置处理何时用
// “确定”来关闭对话框的代码
}
else if (nResponse == IDCANCEL)
{
// TODO: 在此放置处理何时用
// “取消”来关闭对话框的代码
}
// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
// 而不是启动应用程序的消息泵。
return FALSE;
}
BOOL CScreenshotApp::ProcessMessageFilter(int code, LPMSG lpMsg)
{
if(m_hwndDlg != NULL)
{
// 如果消息是从对话框发出的或者其子控件发出的,就进行处理
if((lpMsg->hwnd == m_hwndDlg) || ::IsChild(m_hwndDlg, lpMsg->hwnd))
{
// 如果消息是WM_KEYDOWN,用方向键调整位置
if(lpMsg->message == WM_KEYDOWN)
{
CRect rect(0,0,0,0);
CCatchScreenDlg * pDlg=(CCatchScreenDlg *)AfxGetMainWnd();
rect = pDlg->m_rectTracker.m_rect;
if(pDlg->m_bFirstDraw)
{
//如果Shift键按下则方向键调整大小
BOOL bIsShiftDown = FALSE;
if (GetKeyState(VK_SHIFT) & SHIFTED)
bIsShiftDown = TRUE;
////////////////////////////////////////////////////
switch(lpMsg->wParam)
{
case VK_UP:
//如果按下Shift,则只调整一边
if(!bIsShiftDown)
rect.top-=1;
rect.bottom-=1;
pDlg->m_rectTracker.m_rect = rect;
pDlg->InvalidateRgnWindow();
break;
case VK_DOWN:
rect.top+=1;
if(!bIsShiftDown)
rect.bottom+=1;
pDlg->m_rectTracker.m_rect=rect;
pDlg->InvalidateRgnWindow();
break;
case VK_LEFT:
if(!bIsShiftDown)
rect.left-=1;
rect.right-=1;
pDlg->m_rectTracker.m_rect=rect;
pDlg->InvalidateRgnWindow();
break;
case VK_RIGHT:
rect.left+=1;
if(!bIsShiftDown)
rect.right+=1;
pDlg->m_rectTracker.m_rect=rect;
pDlg->InvalidateRgnWindow();
break;
}
}
}
}
}
return CWinApp::ProcessMessageFilter(code, lpMsg);
}
int CScreenshotApp::ExitInstance()
{
GdiplusShutdown(m_gdiplusToken);
return CWinApp::ExitInstance();
}

@ -1,38 +0,0 @@
// Screenshot.h : PROJECT_NAME 应用程序的主头文件
//
#pragma once
#ifndef __AFXWIN_H__
#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
#endif
#include "resource.h" // 主符号
// CScreenshotApp:
// 有关此类的实现,请参阅 Screenshot.cpp
//
class CScreenshotApp : public CWinApp
{
public:
CScreenshotApp();
// 重写
public:
virtual BOOL InitInstance();
HWND m_hwndDlg;
virtual BOOL ProcessMessageFilter(int code, LPMSG lpMsg);
// 实现
DECLARE_MESSAGE_MAP()
private:
ULONG_PTR m_gdiplusToken;
public:
virtual int ExitInstance();
};
extern CScreenshotApp theApp;

@ -1,217 +0,0 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#ifndef APSTUDIO_INVOKED
#include "targetver.h"
#endif
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Chinese (P.R.C.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
#ifdef _WIN32
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page(936)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#ifndef APSTUDIO_INVOKED\r\n"
"#include ""targetver.h""\r\n"
"#endif\r\n"
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
"\r\n"
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)\r\n"
"LANGUAGE 4, 2\r\n"
"#pragma code_page(936)\r\n"
"#include ""res\\Screenshot.rc2"" // 非 Microsoft Visual C++ 编辑的资源\r\n"
"#include ""l.CHS\\afxres.rc"" // 标准组件\r\n"
"#endif\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME ICON "res\\Screenshot.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_SCREENSHOT_DIALOG DIALOGEX 0, 0, 181, 59
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "Screenshot"
FONT 9, "MS Shell Dlg", 0, 0, 0x1
BEGIN
PUSHBUTTON "截图",IDC_BTN_START,65,22,50,14
END
IDD_DIALOGFORIMG DIALOGEX 0, 0, 169, 140
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP
EXSTYLE WS_EX_TRANSPARENT
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
EDITTEXT IDC_EDIT1,14,20,137,93,ES_MULTILINE | ES_READONLY | NOT WS_BORDER
END
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080403a8"
BEGIN
VALUE "CompanyName", "TODO: <公司名>"
VALUE "FileDescription", "TODO: <文件说明>"
VALUE "FileVersion", "1.0.0.1"
VALUE "InternalName", "Screenshot.exe"
VALUE "LegalCopyright", "TODO: (C) <公司名>。保留所有权利。"
VALUE "OriginalFilename", "Screenshot.exe"
VALUE "ProductName", "TODO: <产品名>"
VALUE "ProductVersion", "1.0.0.1"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x804, 936
END
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_SCREENSHOT_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 174
TOPMARGIN, 7
BOTTOMMARGIN, 52
END
IDD_DIALOGFORIMG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 162
TOPMARGIN, 7
BOTTOMMARGIN, 133
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDB_BITMAP_BK BITMAP "res\\brackground.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// PNG
//
IDB_ARROW PNG "res\\Arrow.png"
IDB_RECTANGLE PNG "res\\Rectangle.png"
IDB_CIRCLE PNG "res\\Circle.png"
IDB_BRUSH PNG "res\\Brush.PNG"
IDB_MOSAIC PNG "res\\Mosaic.png"
IDB_TEXT PNG "res\\Text.png"
IDB_UNDO PNG "res\\Undo.png"
IDB_SAVE PNG "res\\Save.png"
IDB_EXIT PNG "res\\Exit.png"
IDB_FINISH PNG "res\\Finish.png"
/////////////////////////////////////////////////////////////////////////////
//
// Cursor
//
IDC_CURSOR1 CURSOR "res\\arrow_m.cur"
#endif // Chinese (P.R.C.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE 4, 2
#pragma code_page(936)
#include "res\Screenshot.rc2" // 非 Microsoft Visual C++ 编辑的资源
#include "l.CHS\afxres.rc" // 标准组件
#endif
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

@ -1,368 +0,0 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="Screenshot"
ProjectGUID="{24E39ACB-AB81-485D-8D36-749B3F5EC1E8}"
RootNamespace="Screenshot"
Keyword="MFCProj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
UseOfMFC="2"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="false"
ValidateParameters="true"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="2"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="2052"
AdditionalIncludeDirectories="$(IntDir)"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
UseOfMFC="2"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="false"
ValidateParameters="true"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
MinimalRebuild="false"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="2"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="2052"
AdditionalIncludeDirectories="$(IntDir)"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\CatchScreenDlg.cpp"
>
</File>
<File
RelativePath=".\MyEdit.cpp"
>
</File>
<File
RelativePath=".\MyToolBar.cpp"
>
</File>
<File
RelativePath=".\MyTracker.cpp"
>
</File>
<File
RelativePath=".\PopUpMenu.cpp"
>
</File>
<File
RelativePath=".\Screenshot.cpp"
>
</File>
<File
RelativePath=".\ScreenshotDlg.cpp"
>
</File>
<File
RelativePath=".\stdafx.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\CatchScreenDlg.h"
>
</File>
<File
RelativePath=".\MyEdit.h"
>
</File>
<File
RelativePath=".\MyToolBar.h"
>
</File>
<File
RelativePath=".\MyTracker.h"
>
</File>
<File
RelativePath=".\PopUpMenu.h"
>
</File>
<File
RelativePath=".\Resource.h"
>
</File>
<File
RelativePath=".\Screenshot.h"
>
</File>
<File
RelativePath=".\ScreenshotDlg.h"
>
</File>
<File
RelativePath=".\stdafx.h"
>
</File>
<File
RelativePath=".\targetver.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\res\Arrow.ico"
>
</File>
<File
RelativePath=".\res\Arrow.png"
>
</File>
<File
RelativePath=".\res\arrow_m.cur"
>
</File>
<File
RelativePath=".\res\brackground.bmp"
>
</File>
<File
RelativePath=".\res\Brush.PNG"
>
</File>
<File
RelativePath=".\res\Circle.png"
>
</File>
<File
RelativePath=".\res\Exit.png"
>
</File>
<File
RelativePath=".\res\Finish.png"
>
</File>
<File
RelativePath=".\res\Mosaic.png"
>
</File>
<File
RelativePath=".\res\Rectangle.png"
>
</File>
<File
RelativePath=".\res\Save.png"
>
</File>
<File
RelativePath=".\res\Screenshot.ico"
>
</File>
<File
RelativePath=".\Screenshot.rc"
>
</File>
<File
RelativePath=".\res\Screenshot.rc2"
>
</File>
<File
RelativePath=".\res\Text.png"
>
</File>
<File
RelativePath=".\res\toolbar1.bmp"
>
</File>
<File
RelativePath=".\res\Undo.png"
>
</File>
</Filter>
<File
RelativePath=".\ReadMe.txt"
>
</File>
</Files>
<Globals>
<Global
Name="RESOURCE_FILE"
Value="Screenshot.rc"
/>
</Globals>
</VisualStudioProject>

@ -1,169 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{24E39ACB-AB81-485D-8D36-749B3F5EC1E8}</ProjectGuid>
<RootNamespace>Screenshot</RootNamespace>
<Keyword>MFCProj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v120_xp</PlatformToolset>
<UseOfMfc>Dynamic</UseOfMfc>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v120_xp</PlatformToolset>
<UseOfMfc>Dynamic</UseOfMfc>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>15.0.27924.0</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>false</MkTypLibCompatible>
<ValidateAllParameters>true</ValidateAllParameters>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0804</Culture>
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>false</MkTypLibCompatible>
<ValidateAllParameters>true</ValidateAllParameters>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0804</Culture>
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="CatchScreenDlg.cpp" />
<ClCompile Include="MyEdit.cpp" />
<ClCompile Include="MyToolBar.cpp" />
<ClCompile Include="MyTracker.cpp" />
<ClCompile Include="PopUpMenu.cpp" />
<ClCompile Include="Screenshot.cpp" />
<ClCompile Include="ScreenshotDlg.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="Toolbar.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="CatchScreenDlg.h" />
<ClInclude Include="MyEdit.h" />
<ClInclude Include="MyToolBar.h" />
<ClInclude Include="MyTracker.h" />
<ClInclude Include="PopUpMenu.h" />
<ClInclude Include="Resource.h" />
<ClInclude Include="Screenshot.h" />
<ClInclude Include="ScreenshotDlg.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="Toolbar.h" />
</ItemGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
<None Include="res\Arrow.ico" />
<None Include="res\Arrow.png" />
<None Include="res\arrow_m.cur" />
<None Include="res\brackground.bmp" />
<None Include="res\Brush.PNG" />
<None Include="res\Circle.png" />
<None Include="res\Exit.png" />
<None Include="res\Finish.png" />
<None Include="res\Mosaic.png" />
<None Include="res\Rectangle.png" />
<None Include="res\Save.png" />
<None Include="res\Screenshot.ico" />
<None Include="res\Screenshot.rc2" />
<None Include="res\Text.png" />
<None Include="res\toolbar1.bmp" />
<None Include="res\Undo.png" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Screenshot.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<ProjectExtensions>
<VisualStudio>
<UserProperties RESOURCE_FILE="Screenshot.rc" />
</VisualStudio>
</ProjectExtensions>
</Project>

@ -1,116 +0,0 @@
// ScreenshotDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "Screenshot.h"
#include "ScreenshotDlg.h"
#include "CatchScreenDlg.h"
#ifdef _DEBUG
//#define new DEBUG_NEW
#endif
// CScreenshotDlg 对话框
CScreenshotDlg::CScreenshotDlg(CWnd* pParent /*=NULL*/)
: CDialog(CScreenshotDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CScreenshotDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CScreenshotDlg, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BTN_START, &CScreenshotDlg::OnBnClickedBtnStart)
ON_WM_CTLCOLOR()
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()
// CScreenshotDlg 消息处理程序
BOOL CScreenshotDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
// 使窗体在最顶层
::SetWindowPos(GetSafeHwnd(), HWND_TOPMOST, 150, 150, 0, 0,
SWP_NOMOVE|SWP_NOSIZE|SWP_NOREDRAW);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CScreenshotDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
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;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CScreenshotDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
//----------------------------------------------------------------------
// 线程函数,用来截图
//
UINT SccreenShot_Thread (LPVOID lpParam)
{
HWND hWndMain = (HWND) lpParam;
CCatchScreenDlg dlg;
dlg.DoModal();
::ShowWindow(hWndMain,SW_SHOW);
return 0;
}
void CScreenshotDlg::OnBnClickedBtnStart()
{
::ShowWindow (m_hWnd, SW_HIDE);
//使得被激活窗口出现在前景
::AfxBeginThread (SccreenShot_Thread, (LPVOID)GetSafeHwnd());
//::ShowWindow (GetSafeHwnd(), SW_SHOW);
}

@ -1,31 +0,0 @@
// ScreenshotDlg.h : 头文件
//
#pragma once
// CScreenshotDlg 对话框
class CScreenshotDlg : public CDialog
{
// 构造
public:
CScreenshotDlg(CWnd* pParent = NULL); // 标准构造函数
// 对话框数据
enum { IDD = IDD_SCREENSHOT_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedBtnStart();
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

@ -1,13 +0,0 @@
//
// Screenshot.RC2 - Microsoft Visual C++ 不会直接编辑的资源
//
#ifdef APSTUDIO_INVOKED
#error 此文件不能用 Microsoft Visual C++ 编辑
#endif //APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
// 在此处添加手动编辑的资源...
/////////////////////////////////////////////////////////////////////////////

Binary file not shown.

Before

Width:  |  Height:  |  Size: 276 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

@ -1,33 +0,0 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Screenshot.rc
//
#define IDD_SCREENSHOT_DIALOG 102
#define IDR_MAINFRAME 128
#define IDD_DIALOGFORIMG 129
#define IDB_BITMAP_BK 131
#define IDB_ARROW 132
#define IDC_CURSOR1 136
#define IDB_RECTANGLE 137
#define IDB_CIRCLE 138
#define IDB_BRUSH 139
#define IDB_MOSAIC 140
#define IDB_TEXT 141
#define IDB_UNDO 142
#define IDB_SAVE 143
#define IDB_EXIT 144
#define IDB_PNG2 145
#define IDB_FINISH 145
#define IDC_BTN_START 1000
#define IDC_EDIT1 1001
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 146
#define _APS_NEXT_COMMAND_VALUE 32772
#define _APS_NEXT_CONTROL_VALUE 1003
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

@ -1,7 +0,0 @@
// stdafx.cpp : 只包括标准包含文件的源文件
// Screenshot.pch 将作为预编译头
// stdafx.obj 将包含预编译类型信息
#include "stdafx.h"

@ -1,57 +0,0 @@
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
#pragma once
#ifndef _SECURE_ATL
#define _SECURE_ATL 1
#endif
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN // 从 Windows 头中排除极少使用的资料
#endif
#include "targetver.h"
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 某些 CString 构造函数将是显式的
// 关闭 MFC 对某些常见但经常可放心忽略的警告消息的隐藏
#define _AFX_ALL_WARNINGS
#include <afxwin.h> // MFC 核心组件和标准组件
#include <afxext.h> // MFC 扩展
#include <afxdisp.h> // MFC 自动化类
#ifndef _AFX_NO_OLE_SUPPORT
#include <afxdtctl.h> // MFC 对 Internet Explorer 4 公共控件的支持
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC 对 Windows 公共控件的支持
#endif // _AFX_NO_AFXCMN_SUPPORT
#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_IA64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif

@ -1,26 +0,0 @@
#pragma once
// 以下宏定义要求的最低平台。要求的最低平台
// 是具有运行应用程序所需功能的 Windows、Internet Explorer 等产品的
// 最早版本。通过在指定版本及更低版本的平台上启用所有可用的功能,宏可以
// 正常工作。
// 如果必须要针对低于以下指定版本的平台,请修改下列定义。
// 有关不同平台对应值的最新信息,请参考 MSDN。
#ifndef WINVER // 指定要求的最低平台是 Windows Vista。
#define WINVER 0x0600 // 将此值更改为相应的值,以适用于 Windows 的其他版本。
#endif
#ifndef _WIN32_WINNT // 指定要求的最低平台是 Windows Vista。
#define _WIN32_WINNT 0x0600 // 将此值更改为相应的值,以适用于 Windows 的其他版本。
#endif
#ifndef _WIN32_WINDOWS // 指定要求的最低平台是 Windows 98。
#define _WIN32_WINDOWS 0x0410 // 将此值更改为适当的值,以适用于 Windows Me 或更高版本。
#endif
#ifndef _WIN32_IE // 指定要求的最低平台是 Internet Explorer 7.0。
#define _WIN32_IE 0x0700 // 将此值更改为相应的值,以适用于 IE 的其他版本。
#endif

@ -0,0 +1,11 @@
### 该问题是怎么引起的?
### 重现步骤
### 报错信息

@ -0,0 +1,12 @@
### 相关的Issue
### 原因(目的、解决的问题等)
### 描述(做了什么,变更了什么)
### 测试用例(新增、改动、可能影响的功能)

@ -0,0 +1,177 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (c) 2022 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This is the configuration file template for OpenHarmony OSS Audit Tool, please copy it to your project root dir and modify it refer to OpenHarmony/tools_oat/README.
-->
<configuration>
<oatconfig>
<licensefile></licensefile>
<policylist>
<policy name="projectPolicy" desc="">
</policy>
</policylist>
<filefilterlist>
<filefilter name="defaultFilter" desc="Files not to check">
<filteritem type="filename" name="*.png|*.pngraw|*.json" desc="Temp files"/>
</filefilter>
<filefilter name="defaultPolicyFilter" desc="Filters for compatibilitylicense header policies">
<filteritem type="filename" name="*.png|*.pngraw|*.json" desc="NoLicenseHeader"/>
</filefilter>
<filefilter name="copyrightPolicyFilter" desc="Filters for copyright header policies">
<filteritem type="filename" name="*.png|*.pngraw|*.json" desc="InvalidCopyright file"/>
</filefilter>
<filefilter name="binaryFileTypePolicyFilter" desc="Filters for binary file policies">
<filteritem type="filename" name="*.png|*.pngraw|*.json" desc="already checked"/>
</filefilter>
</filefilterlist>
</oatconfig>
</configuration>

@ -0,0 +1,26 @@
# WIFI\_IOT\_APP<a name="EN-US_TOPIC_0000001132694217"></a>
- [Introduction](#section11660541593)
- [Directory Structure](#section1464106163817)
- [Repositories Involved](#section1718733212019)
## Introduction<a name="section11660541593"></a>
The WIFI\_IOT\_APP module provides sample code for iothardware, demolink, and samgr.
## Directory Structure<a name="section1464106163817"></a>
```
applications/sample/wifi-iot/ # Sample code
└── app
├── BUILD.gn # Build script
├── demolink # Sample code for integrating demolink
├── iothardware # Sample code for LED operations
├── samgr # Sample code for the service framework
└── startup
```
## Repositories Involved<a name="section1718733212019"></a>
applications\_sample\_wifi-iot

@ -0,0 +1,26 @@
# WIFI\_IOT\_APP组件<a name="ZH-CN_TOPIC_0000001132694217"></a>
- [简介](#section11660541593)
- [目录](#section1464106163817)
- [涉及仓](#section1718733212019)
## 简介<a name="section11660541593"></a>
WIFI\_IOT\_APP组件提供了iothardware、demolink、samgr等示例代码。
## 目录<a name="section1464106163817"></a>
```
applications/sample/wifi-iot/ # sample模块目录
└── app
├── BUILD.gn # 模块构建脚本
├── demolink # demolink集成示例代码
├── iothardware # LED操作示例代码
├── samgr # 服务框架示例代码
└── startup
```
## 涉及仓<a name="section1718733212019"></a>
applications\_sample\_wifi-iot

@ -0,0 +1,18 @@
# Copyright (c) 2020-2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/lite/config/component/lite_component.gni")
lite_component("app") {
features = [ "cloud_to_uart:cloud_uart", ]
}

@ -0,0 +1,41 @@
# Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("cloud_uart") {
sources = [
"app_demo_iot.c",
"cjson_init.c",
"iot_hmac.c",
"iot_log.c",
"iot_main.c",
"iot_profile.c",
"iot_sta.c",
"hal_iot_gpio_ex.c",
"hisignalling_protocol.c",
]
include_dirs = [
"./",
"//utils/native/lite/include",
"//kernel/liteos_m/kal/cmsis",
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/lwip_sack/include/lwip",
"//third_party/cJSON",
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/mbedtls/include/mbedtls",
"//foundation/communication/wifi_lite/interfaces/wifiservice",
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/paho.mqtt.c/include/mqtt",
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/libcoap/include/coap2",
]
defines = [ "WITH_LWIP" ]
}

@ -0,0 +1,507 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <hi_task.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <hi_wifi_api.h>
#include <hi_mux.h>
#include <hi_io.h>
#include <hi_gpio.h>
#include "iot_config.h"
#include "iot_log.h"
#include "iot_main.h"
#include "iot_profile.h"
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include <hi_stdlib.h>
#include <hisignalling_protocol.h>
#include <hi_uart.h>
#include <app_demo_uart.h>
#include <iot_uart.h>
#include "iot_gpio_ex.h"
/* attribute initiative to report */
#define TAKE_THE_INITIATIVE_TO_REPORT
#define TWO_SECOND (2000)
/* oc request id */
#define CN_COMMADN_INDEX "commands/request_id="
#define WECHAT_SUBSCRIBE_control "slot_num"
#define WECHAT_SUBSCRIBE_channel1 "slot_1"
#define WECHAT_SUBSCRIBE_channel2 "slot_2"
#define WECHAT_SUBSCRIBE_channel3 "slot_3"
#define WECHAT_SUBSCRIBE_channel4 "4"
#define topic_data "YT32IOSCAL/Hi38611_mqtt/data"
#define topic_event "YT32IOSCAL/Hi38611_mqtt/event"
#define topic_control "YT32IOSCAL/Hi38611_mqtt/control"
#define human_detect_io 7
int g_ligthStatus = -1;
int control_success = 0;
char *control_flag = "failed";
char *message = NULL;
UartDefConfig uartDefConfig = {0};
//int slot1 = 20,slot2 = 20, slot3 = 20, slot4 = 20;
typedef void (*FnMsgCallBack)(hi_gpio_value val);
typedef struct FunctionCallback {
hi_bool stop;
hi_u32 conLost;
hi_u32 queueID;
hi_u32 iotTaskID;
FnMsgCallBack msgCallBack;
}FunctionCallback;
FunctionCallback g_functinoCallback;
// uart
static void Uart1GpioCOnfig(void)
{
#ifdef ROBOT_BOARD
IoSetFunc(HI_IO_NAME_GPIO_5, IOT_IO_FUNC_GPIO_5_UART1_RXD);
IoSetFunc(HI_IO_NAME_GPIO_6, IOT_IO_FUNC_GPIO_6_UART1_TXD);
/* IOT_BOARD */
#elif defined (EXPANSION_BOARD)
IoSetFunc(HI_IO_NAME_GPIO_0, IOT_IO_FUNC_GPIO_0_UART1_TXD);
IoSetFunc(HI_IO_NAME_GPIO_1, IOT_IO_FUNC_GPIO_1_UART1_RXD);
#endif
}
/* CPU Sleep time Set */
unsigned int TaskMsleep(unsigned int ms)
{
if (ms <= 0) {
return HI_ERR_FAILURE;
}
return hi_sleep((hi_u32)ms);
}
static void DeviceConfigInit(hi_gpio_value val)
{
hi_io_set_func(HI_IO_NAME_GPIO_9, HI_IO_FUNC_GPIO_9_GPIO);
hi_gpio_set_dir(HI_GPIO_IDX_9, HI_GPIO_DIR_OUT);
hi_gpio_set_ouput_val(HI_GPIO_IDX_9, val);
}
static void engine_control(unsigned int IO){
IoTGpioInit(IO);
IoSetFunc(IO, 0);
IoTGpioSetDir(IO, IOT_GPIO_DIR_OUT);
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE1);
IOT_LOG_DEBUG("Engine at GPIO:%u started!\n", IO);
hi_udelay(20000);
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE0);
IOT_LOG_DEBUG("Engine at GPIO:%u stopped!\n", IO);
}
static void engine_start(unsigned int IO){
IoSetFunc(IO, 0);
IoTGpioSetDir(IO, IOT_GPIO_DIR_OUT);
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE1);
IOT_LOG_DEBUG("Engine at GPIO:%u started!\n", IO);
}
static void engine_stop(unsigned int IO){
IoSetFunc(IO, 0);
IoTGpioSetDir(IO, IOT_GPIO_DIR_OUT);
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE0);
IOT_LOG_DEBUG("Engine at GPIO:%u stopped!\n", IO);
}
static void engine_reinit(unsigned int IO){
IoTGpioInit(IO);
IoSetFunc(IO, 0);
IoTGpioSetDir(IO, IOT_GPIO_DIR_OUT);
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE0);
IOT_LOG_DEBUG("Engine at GPIO:%u initialized!\n", IO);
}
static void all_engine_reinit(){
engine_reinit(6);
engine_reinit(7);
engine_reinit(9);
engine_reinit(10);
IOT_LOG_DEBUG("All engines initialized!\n");
}
static void Sensor_init(){
IoTGpioInit(human_detect_io);
IoSetFunc(human_detect_io, 0);
IoTGpioSetDir(human_detect_io, IOT_GPIO_DIR_IN);
IOT_LOG_DEBUG("Sensor initialized!\n");
}
static int DeviceMsgCallback(FnMsgCallBack msgCallBack)
{
g_functinoCallback.msgCallBack = msgCallBack;
return 0;
}
static void wechatControlDeviceMsg(hi_gpio_value val)
{
DeviceConfigInit(val);
}
// < this is the callback function, set to the mqtt, and if any messages come, it will be called
// < The payload here is the json string
static void DemoMsgRcvCallBack(int qos, const char *topic, const char *payload)/*定义3861接收到json文件后的操作*/
{
IOT_LOG_DEBUG("RCVMSG:QOS:%d TOPIC:%s PAYLOAD:%s\r\n", qos, topic, payload);
printf(strstr(payload, WECHAT_SUBSCRIBE_control));
/* 云端下发命令后,板端的操作处理 */
if (strstr(payload, WECHAT_SUBSCRIBE_control) != NULL) {
//printf(strstr(payload, WECHAT_SUBSCRIBE_control));
all_engine_reinit();
if (strstr(payload, WECHAT_SUBSCRIBE_channel1) != NULL) {
engine_start(6);
hi_udelay(4000000);
engine_stop(6);
wechatControlDeviceMsg(HI_GPIO_VALUE1);
control_success = 1;
control_flag = payload;
}
else if (strstr(payload, WECHAT_SUBSCRIBE_channel2) != NULL) {
engine_start(7);
hi_udelay(4000000);
engine_stop(7);
wechatControlDeviceMsg(HI_GPIO_VALUE1);
control_success = 1;
control_flag = payload;
}
else if (strstr(payload, WECHAT_SUBSCRIBE_channel3) != NULL) {
engine_start(2);
hi_udelay(4000000);
engine_stop(2);
wechatControlDeviceMsg(HI_GPIO_VALUE1);
control_success = 1;
control_flag = payload;
}
else if (strstr(payload, WECHAT_SUBSCRIBE_channel4) != NULL) {
engine_start(10);
hi_udelay(4000000);
engine_stop(10);
wechatControlDeviceMsg(HI_GPIO_VALUE1);
control_success = 1;
control_flag = payload;
}
}
return HI_NULL;
}
static void DemoMsgRcvsynchronize(int qos, const char *topic, const char *payload)
{
message = payload;
}
/* publish sample */
/*hi_void IotPublishSample(int slot1, int slot2, int slot3, int slot4)
{
// reported attribute
WeChatProfile weChatProfile = {
.subscribeType = "type",
.status.subState = "state",
.status.subReport = "reported",
.status.reportVersion = "version",
.status.Token = "clientToken",
// report motor
.reportAction.subDeviceActionMotor = "slot_1",
.reportAction.motorActionStatus = slot1, // 0 : motor off
// report temperature
.reportAction.subDeviceActionTemperature = "slot_2",
.reportAction.temperatureData = slot2, // 30 :temperature data
// report humidity
.reportAction.subDeviceActionHumidity = "slot_3",
.reportAction.humidityActionData = slot3, // humidity data
// report light_intensity
.reportAction.subDeviceActionLightIntensity = "slot_4",
.reportAction.lightIntensityActionData = slot4, // 60 : light_intensity
};
// report light
if (g_ligthStatus == HI_TRUE) {
weChatProfile.reportAction.subDeviceActionLight = "light";
weChatProfile.reportAction.lightActionStatus = 1; // 1: light on
} else if (g_ligthStatus == HI_FALSE) {
weChatProfile.reportAction.subDeviceActionLight = "light";
weChatProfile.reportAction.lightActionStatus = 0; // 0: light off
} else {
weChatProfile.reportAction.subDeviceActionLight = "light";
weChatProfile.reportAction.lightActionStatus = 0; // 0: light off
}
//profile report
IoTProfilePropertyReport(CONFIG_USER_ID, &weChatProfile1);
}*/
// < this is the demo main task entry,here we will set the wifi/cjson/mqtt ready and
// < wait if any work to do in the while
//static hi_void *DemoEntry(const char *arg)
//{
//int feedback = 0;
/*6WifiStaReadyWait();
cJsonInit();
IoTMain();
/* 云端下发回调 */
//IoTSetMsgCallback(DemoMsgRcvCallBack);
/*if (control_success == 1)
{
//Uart1GpioCOnfig();
feedback = IoTUartWrite(DEMO_UART_NUM, control_flag, 7);
printf("feedback: %d", feedback);
}*/
/* 主动上报 */
/*#ifdef TAKE_THE_INITIATIVE_TO_REPORT
while (1) {
// 用户可以在这调用发布函数进行发布,需要用户自己写调用函数
IotPublishSample(slot1,slot2,slot3,slot4); // 发布例程
#endif*/
//TaskMsleep(TWO_SECOND);
//return NULL;
//}
///////////////////////////////////////////////////////////////////////////////////////////
int SetUartRecvFlag(UartRecvDef def)
{
if (def == UART_RECV_TRUE) {
uartDefConfig.g_uartReceiveFlag = HI_TRUE;
} else {
uartDefConfig.g_uartReceiveFlag = HI_FALSE;
}
return uartDefConfig.g_uartReceiveFlag;
}
int GetUartConfig(UartDefType type)
{
int receive = 0;
switch (type) {
case UART_RECEIVE_FLAG:
receive = uartDefConfig.g_uartReceiveFlag;
break;
case UART_RECVIVE_LEN:
receive = uartDefConfig.g_uartLen;
break;
default:
break;
}
return receive;
}
void ResetUartReceiveMsg(void)
{
(void)memset_s(uartDefConfig.g_receiveUartBuff, sizeof(uartDefConfig.g_receiveUartBuff),
0x0, sizeof(uartDefConfig.g_receiveUartBuff));
}
unsigned char *GetUartReceiveMsg(void)
{
return uartDefConfig.g_receiveUartBuff;
}
static hi_void *UartDemoTask(char *param)
{
hi_u8 uartBuff[UART_BUFF_SIZE] = {0};
char *recBuff = NULL;
int feedback_1 = 0;
int feedback_2 = 0;
int length = 0;
unsigned char *detect_flag = "start";
unsigned char *data_send = "jdata";
IotGpioValue value = IOT_GPIO_VALUE0;
hi_unref_param(param);
printf("Initialize uart demo successfully, please enter some datas via DEMO_UART_NUM port...\n");
Uart1GpioCOnfig();
Sensor_init();
printf("Please wait for 60 seconds for the system to start...\n");
TaskMsleep(60000);
printf("Done!\n");
for (;;)
{
int isTimeOut = 0;
IoTGpioGetInputVal(human_detect_io, &value);
if(value == IOT_GPIO_VALUE1)
{
//get from cloud and send to 3516
IoTUartWrite(DEMO_UART_NUM, detect_flag, 5);
IoTSetMsgCallback(DemoMsgRcvsynchronize);
//start to work
feedback_1 = IoTUartWrite(DEMO_UART_NUM, detect_flag, 5);//
printf("uart feedback %d\n", feedback_1);
//TaskMsleep(20);
uartDefConfig.g_uartLen = IoTUartRead(DEMO_UART_NUM, uartBuff, UART_BUFF_SIZE);
int waitCount = 0;
while (!((uartDefConfig.g_uartLen > 0) && (uartBuff[0] == 0xaa) && (uartBuff[1] == 0x55))) {
uartDefConfig.g_uartLen = IoTUartRead(DEMO_UART_NUM, uartBuff, UART_BUFF_SIZE);
TaskMsleep(50);
waitCount += 1;
if(waitCount > 400){
isTimeOut = 1;
printf("Timeout!\n");
break;
}
}
if(isTimeOut)
continue;
if (GetUartConfig(UART_RECEIVE_FLAG) == HI_FALSE) {
(void)memcpy_s(uartDefConfig.g_receiveUartBuff, uartDefConfig.g_uartLen,
uartBuff, uartDefConfig.g_uartLen);/*uartBuff中的信息放到uartDefConfig.g_receiveUartBuff*/
(void)SetUartRecvFlag(UART_RECV_TRUE);
}
printf("UART start\n");
printf("len:%d\n", uartDefConfig.g_uartLen);
recBuff = (char*)malloc(uartDefConfig.g_uartLen-3);
for (int i = 0; i<uartDefConfig.g_uartLen; i++)
{
if(i <= 2)
{
printf("0x%x ", uartBuff[i]);
}
else
{
printf("%c ", uartBuff[i]);
recBuff[i-3] = uartBuff[i];
}
}
//TaskMsleep(20); /* 20:sleep 20ms */
/*send to cloud*/
IoTProfilePropertyReport_uart(CONFIG_USER_ID, recBuff);
//printf("communicatuon completed\n");
free(recBuff);
TaskMsleep(50);
IoTSetMsgCallback(DemoMsgRcvCallBack);
while (control_success == 0)
{
TaskMsleep(50);
}
length = strlen(control_flag);
char len = length+'0';
IoTUartWrite(DEMO_UART_NUM, len, strlen(len));
TaskMsleep(10);
feedback_2 = IoTUartWrite(DEMO_UART_NUM, control_flag, length);
printf("feedback: %d\n", feedback_2);
}
TaskMsleep(50);
}
return HI_NULL;
}
/*
* This demo simply shows how to read datas from UART2 port and then echo back.
*/
/*hi_void UartTransmit(hi_void)
{
hi_u32 ret = 0;
IotUartAttribute uartAttr = {
.baudRate = 115200, /* baudRate: 115200
.dataBits = 8, /* dataBits: 8bits
.stopBits = 1, /* stop bit
.parity = 0,
};
/* Initialize uart driver
ret = IoTUartInit(DEMO_UART_NUM, &uartAttr);
if (ret != HI_ERR_SUCCESS) {
printf("Failed to init uart! Err code = %d\n", ret);
return;
}
/* Create a task to handle uart communication
osThreadAttr_t attr = {0};
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = 8096;
attr.priority = UART_DEMO_TASK_PRIORITY;
attr.name = (hi_char*)"uart demo";
if (osThreadNew((osThreadFunc_t)UartDemoTask, NULL, &attr) == NULL) {
printf("Falied to create uart demo task!\n");
}
}*/
//SYS_RUN(UartTransmit);
///////////////////////////////////////////////////////////////////////////////////////////
// < This is the demo entry, we create a task here,
// and all the works has been done in the demo_entry
#define CN_IOT_TASK_STACKSIZE 0x1000
#define CN_IOT_TASK_PRIOR 25
#define CN_IOT_TASK_NAME "IOTDEMO"
static void AppDemoIot(void)
{
hi_u32 ret = 0;
IotUartAttribute uartAttr = {
.baudRate = 115200, /* baudRate: 115200 */
.dataBits = 8, /* dataBits: 8bits */
.stopBits = 1, /* stop bit */
.parity = 0,
};
/* Initialize uart driver */
ret = IoTUartInit(DEMO_UART_NUM, &uartAttr);
if (ret != HI_ERR_SUCCESS) {
printf("Failed to init uart! Err code = %d\n", ret);
return;
}
osThreadAttr_t attr;
IoTWatchDogDisable();
WifiStaReadyWait();
cJsonInit();
IoTMain();
attr.name = "IOTDEMO";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = CN_IOT_TASK_STACKSIZE;
attr.priority = CN_IOT_TASK_PRIOR;
if (osThreadNew((osThreadFunc_t)UartDemoTask, NULL, &attr) == NULL) {
printf("Falied to create uart demo task!\n");
}
}
SYS_RUN(AppDemoIot);

@ -0,0 +1,48 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APP_DEMO_UART_H
#define APP_DEMO_UART_H
#define UART_BUFF_SIZE 1024
#define WRITE_BY_INT
#define UART_DEMO_TASK_STAK_SIZE 2048
#define UART_DEMO_TASK_PRIORITY 25
#define DEMO_UART_NUM HI_UART_IDX_1
typedef enum {
UART_RECEIVE_FLAG = 0,
UART_RECVIVE_LEN,
UART_SEND_FLAG = 2,
UART_SEND_LEN
}UartDefType;
typedef enum {
UART_RECV_TRUE = 0,
UART_RECV_FALSE,
}UartRecvDef;
typedef struct {
unsigned int uartChannel;
unsigned char g_receiveUartBuff[UART_BUFF_SIZE];
int g_uartReceiveFlag;
int g_uartLen;
}UartDefConfig;
int SetUartRecvFlag(UartRecvDef def);
int GetUartConfig(UartDefType type);
void ResetUartReceiveMsg(void);
unsigned char *GetUartReceiveMsg(void);
#endif

@ -0,0 +1,38 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdint.h>
#include <cJSON.h>
#include <hi_mem.h>
static void *cJsonMalloc(size_t sz)
{
return hi_malloc(0, sz);
}
static void cJsonFree(const char *p)
{
hi_free(0, p);
}
void cJsonInit(void)
{
cJSON_Hooks hooks;
hooks.malloc_fn = cJsonMalloc;
hooks.free_fn = cJsonFree;
cJSON_InitHooks(&hooks);
return;
}

@ -0,0 +1,46 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "iot_errno.h"
#include "iot_gpio_ex.h"
#include "hi_gpio.h"
#include "hi_io.h"
#include "hi_task.h"
#include "hi_types_base.h"
unsigned int IoSetPull(unsigned int id, IotIoPull val)
{
if (id >= HI_GPIO_IDX_MAX) {
return IOT_FAILURE;
}
return hi_io_set_pull((hi_io_name)id, (hi_io_pull)val);
}
unsigned int IoSetFunc(unsigned int id, unsigned char val)
{
if (id >= HI_GPIO_IDX_MAX) {
return IOT_FAILURE;
}
return hi_io_set_func((hi_io_name)id, val);
}
/*unsigned int TaskMsleep(unsigned int ms)
{
if (ms <= 0) {
return IOT_FAILURE;
}
return hi_sleep((hi_u32)ms);
}*/

@ -0,0 +1,286 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <hi_types_base.h>
#include <hi_early_debug.h>
#include <hi_stdlib.h>
#include <hi_uart.h>
#include <hi_task.h>
#include <app_demo_uart.h>
#include <iot_uart.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio_ex.h"
#include "hi_io.h"
#include "iot_gpio.h"
#include "hisignalling_protocol.h"
#define LED_TEST_GPIO 9
#define LED_INTERVAL_TIME_US 300000
hi_u8 g_sendUartBuff[UART_BUFF_SIZE];
UartDefConfig recConfig = {0};
/*
* crc32 Verification implementation
*/
static const unsigned int crc32table[] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL,
0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,
0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL,
0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,
0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L,
0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L,
0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L,
0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,
0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL,
0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L,
0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,
0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL,
0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,
0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L,
0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L,
0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,
0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL,
0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L,
0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL,
0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L,
0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL,
0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L,
0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L,
0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L,
0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,
0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L,
0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL,
0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L,
0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,
0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL,
0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,
0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,
0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL,
0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L,
0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L,
0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,
0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L,
0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
};
static unsigned int crc32(const unsigned char *buf, unsigned int len)
{
unsigned int i, crc = 0xFFFFFFFF;
for (i = 0; i < len; i++) {
crc = crc32table[(crc ^ buf[i]) & 0xff] ^ (crc >> 8); /* 8: right move 8 bit */
}
return crc ^ 0xFFFFFFFF;
}
/* Log level look up table */
static const char *hisignallingLevelNames[] = {
"TRACE",
"DEBUG",
"INFO",
"WARN",
"ERROR",
"FATAL"
};
/* get hisignaling log level */
const char *HisignallingLevelNum (HisignallingLogType hisignallingLevel)
{
if (hisignallingLevel >= HISIGNALLING_LEVEL_MAX) {
return "NULL";
} else {
return hisignallingLevelNames[hisignallingLevel];
}
}
#define RIGHT_MOVE_8_BIT (8)
#define RIGHT_MOVE_16_BIT (16)
#define RIGHT_MOVE_24_BIT (24)
/* hisignal Hi3861 message package */
static hi_u32 HisignallingDataPackage(HisignallingProtocalType *buf, hi_u32 len, hi_u8 *hisignallingDataBuf)
{
hi_u32 crcCheckSend = 0;
hi_u32 packageLen = 0;
memcpy_s(hisignallingDataBuf, HISGNALLING_MSG_FRAME_HEADER_LEN,
buf->frameHeader, HISGNALLING_MSG_FRAME_HEADER_LEN);
memcpy_s(&hisignallingDataBuf[HISGNALLING_MSG_FRAME_HEADER_LEN],
len, buf->hisignallingMsgBuf, len);
memcpy_s(&hisignallingDataBuf[HISGNALLING_MSG_FRAME_HEADER_LEN + len],
HISIGNALLING_MSG_HEADER_LEN, &(buf->endOfFrame), HISIGNALLING_MSG_HEADER_LEN);
crcCheckSend = crc32(hisignallingDataBuf, (len + HISIGNALLING_MSG_HEADER_TAIL_LEN));
hisignallingDataBuf[len + HISIGNALLING_MSG_HEADER_TAIL_LEN] =
(hi_u8) ((crcCheckSend & 0xff000000)>>RIGHT_MOVE_24_BIT);
hisignallingDataBuf[len + HISIGNALLING_MSG_HEADER_TAIL_LEN + 1] = /* 1: addr offset */
(hi_u8) ((crcCheckSend & 0x00ff0000)>>RIGHT_MOVE_16_BIT);
hisignallingDataBuf[len + HISIGNALLING_MSG_HEADER_TAIL_LEN + 2] = /* 2: addr offset */
(hi_u8) ((crcCheckSend & 0x0000ff00)>>RIGHT_MOVE_8_BIT);
hisignallingDataBuf[len + HISIGNALLING_MSG_HEADER_TAIL_LEN + 3] = /* 3: addr offset */
(hi_u8)crcCheckSend;
packageLen = len + HISIGNALLING_MSG_HEADER_TAIL_LEN + HISGNALLING_MSG_CRC32_LEN;
return packageLen;
}
/* hisignal Hi3861 message recevice */
HisignallingErrorType HisignallingMsgReceive(hi_u8 *buf, hi_u32 len)
{
hi_u32 crcCheckReceived = 0;
unsigned char testBuff[7] = {0xaa, 0x55, 0x0, 0x2, 0x0, 0x8, 0xff};
if (buf == HI_NULL && len > 0) {
HISIGNALLING_LOG_FATAL("received buf is null");
return HISGNALLING_RET_VAL_MAX;
}
printf("length:%u\n", len);
/* 校验crc */
if (len > HISGNALLING_MSG_CRC32_LEN) {
crcCheckReceived = crc32(buf, len - HISGNALLING_MSG_CRC32_LEN);
if (((hi_u8)((crcCheckReceived & 0xff000000)>>RIGHT_MOVE_24_BIT) != buf[len - 4]) && /* 4: addr offset */
((hi_u8)((crcCheckReceived & 0x00ff0000)>>RIGHT_MOVE_16_BIT) != buf[len - 3]) && /* 3: addr offset */
((hi_u8)((crcCheckReceived & 0x0000ff00)>>RIGHT_MOVE_8_BIT) != buf[len - 2]) && /* 2: addr offset */
((hi_u8)crcCheckReceived != buf[len - 1])) {
HISIGNALLING_LOG_ERROR("<Hi3861>: crc32 Verification failed!");
HISIGNALLING_LOG_ERROR("<Hi3861>:crc_4=0x%x, crc_3=0x%x, crc_2=0x%x, crc_1=0x%x",
buf[len - 4], buf[len - 3], buf[len - 2], buf[len - 1]); /* 4,3,2,1 addr offset */
return HISIGNALLING_RET_VAL_ERROR;
}
}
IoTGpioSetOutputVal(LED_TEST_GPIO, 0);
usleep(LED_INTERVAL_TIME_US);
IoTGpioSetOutputVal(LED_TEST_GPIO, 1);
usleep(LED_INTERVAL_TIME_US);
/* 输出回显收到的数据 */
/*if ((buf[0] == HISIGNALLING_MSG_FRAME_HEADER_1) && (buf[1] == HISIGNALLING_MSG_FRAME_HEADER_2)) {
for (int i = 0; i < len; i++) {
HISIGNALLING_LOG_INFO("0x%x", buf[i]);
}
}*/
return HISIGNALLING_RET_VAL_CORRECT;
}
/* hisignal Hi3861 message send */
hi_u32 HisignallingMsgSend(char *buf, hi_u32 dataLen)
{
HisignallingProtocalType hisignallingMsg = {0};
hi_u8 hisignallingSendBuf[HISIGNALLING_MSG_BUFF_LEN] = {0};
hi_u32 hisignallingPackageLen = 0;
hi_u32 writeDataLen = 0;
hisignallingMsg.frameHeader[0]= HISIGNALLING_MSG_FRAME_HEADER_1;
hisignallingMsg.frameHeader[1]= HISIGNALLING_MSG_FRAME_HEADER_2;
(void)memcpy_s(hisignallingMsg.hisignallingMsgBuf, dataLen, buf, dataLen);
hisignallingMsg.endOfFrame = HISIGNALLING_MSG_FRAME_TAIL;
hisignallingPackageLen = HisignallingDataPackage(&hisignallingMsg, dataLen, hisignallingSendBuf);
if (!hisignallingPackageLen) {
HISIGNALLING_LOG_ERROR("hisignaling_data_package failed\r\n");
return HI_ERR_FAILURE;
}
if (*hisignallingSendBuf == NULL) {
HISIGNALLING_LOG_ERROR("hisignal send buf is null!\r\n");
return HI_ERR_FAILURE;
}
writeDataLen = IoTUartWrite(HI_UART_IDX_1, hisignallingSendBuf, hisignallingPackageLen);
if (!writeDataLen) {
HISIGNALLING_LOG_ERROR("hi_uart_write failed\r\n");
return HI_ERR_FAILURE;
}
return HI_ERR_SUCCESS;
}
int SetUartReceiveFlag(void)
{
return recConfig.g_uartReceiveFlag;
}
hi_void *HisignallingMsgHandle(char *param)
{
unsigned char *recBuff = NULL;
int len;
while (1) {
/*g_sendUartBuff清零*/
(void)memset_s(g_sendUartBuff, sizeof(g_sendUartBuff) / sizeof(g_sendUartBuff[0]),
0x0, sizeof(g_sendUartBuff)/sizeof(g_sendUartBuff[0]));
/*GetUartConfig得到data的flag和length*/
if (GetUartConfig(UART_RECEIVE_FLAG) == HI_TRUE) {
/* 接收数据 */
HisignallingMsgReceive(GetUartReceiveMsg(), GetUartConfig(UART_RECVIVE_LEN));
/* 回显数据组包 */
if (GetUartConfig(UART_RECVIVE_LEN) > (HISGNALLING_MSG_CRC32_LEN + HISIGNALLING_MSG_HEADER_TAIL_LEN)) {
len = GetUartConfig(UART_RECVIVE_LEN);
recBuff = GetUartReceiveMsg();
for (int i = 0; i < len ; i++ ){
HISIGNALLING_LOG_INFO("0x%x", recBuff[i]);
}
printf("end\n");
(void)memcpy_s(g_sendUartBuff,
(GetUartConfig(UART_RECVIVE_LEN) - HISGNALLING_MSG_CRC32_LEN - HISIGNALLING_MSG_HEADER_TAIL_LEN),
&recBuff[HISGNALLING_MSG_FRAME_HEADER_LEN],
(GetUartConfig(UART_RECVIVE_LEN) - HISGNALLING_MSG_CRC32_LEN - HISIGNALLING_MSG_HEADER_TAIL_LEN));
/* 接收到Hi3516DV300数据后发送回显 */
HisignallingMsgSend(g_sendUartBuff,
(GetUartConfig(UART_RECVIVE_LEN) - HISGNALLING_MSG_CRC32_LEN - HISIGNALLING_MSG_HEADER_TAIL_LEN));
}
(void)SetUartRecvFlag(UART_RECV_FALSE);
ResetUartReceiveMsg();
}
TaskMsleep(HISGNALLING_FREE_TASK_TIME);
}
}
hi_u32 HisignalingMsgTask(hi_void)
{
hi_u32 ret = 0;
IoTGpioInit(LED_TEST_GPIO);
IoTGpioSetDir(LED_TEST_GPIO, IOT_GPIO_DIR_OUT);
osThreadAttr_t hisignallingAttr = {0};
hisignallingAttr.stack_size = HISIGNALLING_MSG_TASK_STACK_SIZE;
hisignallingAttr.priority = HISIGNALLING_MSG_TASK_PRIO;
hisignallingAttr.name = (hi_char*)"hisignal msg task";
if (osThreadNew((osThreadFunc_t)HisignallingMsgHandle, NULL, &hisignallingAttr) == NULL) {
HISIGNALLING_LOG_ERROR("Failed to create hisignaling msg task\r\n");
return HI_ERR_FAILURE;
}
return HI_ERR_SUCCESS;
}
//SYS_RUN(HisignalingMsgTask);

@ -0,0 +1,207 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HISIGNALLING_PROTOCOL_H
#define HISIGNALLING_PROTOCOL_H
#include <hi_types_base.h>
#include <stdarg.h>
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
/**
* @brief : hisignalling Macro definition
*/
#define HISIGNALLING_MSG_HEADER_LEN (1)
#define HISGNALLING_MSG_FRAME_HEADER_LEN (2)
#define HISIGNALLING_MSG_HEADER_TAIL_LEN (3)
#define HISGNALLING_MSG_CRC32_LEN (4)
#define HISIGNALLING_MSG_PAYLOAD_INDEX (5)
#define HISGNALLING_FREE_TASK_TIME (20)
#define HISIGNALLING_MSG_TASK_PRIO (28)
#define HISIGNALLING_UART_MSG_LEN (32)
#define HISIGNALLING_MSG_BUFF_LEN (512)
#define HISIGNALLING_MSG_TASK_STACK_SIZE (4096)
/* hisgnalling protocol frame header and tail */
#define HISIGNALLING_MSG_FRAME_HEADER_1 ((hi_u8)0xAA)
#define HISIGNALLING_MSG_FRAME_HEADER_2 ((hi_u8)0x55)
#define HISIGNALLING_MSG_FRAME_TAIL ((hi_u8)0xFF)
/**
* @brief Adapter plate selection
* 使使#define BOARD_SELECT_IS_EXPANSION_BOARD
* 使Robot#define BOARD_SELECT_IS_ROBOT_BOARD#define BOARD_SELECT_IS_EXPANSION_BOARD
**/
#define BOARD_SELECT_IS_EXPANSION_BOARD
#ifdef BOARD_SELECT_IS_EXPANSION_BOARD
#define EXPANSION_BOARD
#else
#define ROBOT_BOARD
#endif
/**
* @brief:this defines for the log module, and HISIGNALING_LOG_TRACE/HISIGNALING_LOG_DEBUG...
* will not participate the compile in the release version
* */
typedef enum {
HISIGNALLING_LEVEL_TRACE = 0,
HISIGNALLING_LEVEL_DEBUG,
HISIGNALLING_LEVEL_INFO,
HISIGNALLING_LEVEL_WARN,
HISIGNALLING_LEVEL_ERROR,
HISIGNALLING_LEVEL_FATAL,
HISIGNALLING_LEVEL_MAX
} HisignallingLogType;
/**
* @brief: use this function to get the hisignalling log level name
*
* @parameter[in]:level, the level to get
*
* @return: the mapped level name
* */
const char *HisignallingLevelNum (HisignallingLogType hisignallingLevel);
/**
* @brief: this is a weak function ,and you could rewrite one
*
* @param fmt: same use as the fmt for printf
*
* @param unfixed: same use for printf
*
* @return: don't care about it
*
* @attention: and the components should not call this function directly, you'd better
*
* call HISIGNALING_LOG groups
*
* */
#define HISIGNALLING_PRINT(fmt, ...) \
do \
{ \
printf(fmt, ##__VA_ARGS__); \
} while (0)
#define HISIGNALLING_LOG(level, fmt, ...) \
do \
{ \
HISIGNALLING_PRINT("<%s>, <%s>, <%d> "fmt" \r\n", \
HisignallingLevelNum((level)), __FUNCTION__, __LINE__, ##__VA_ARGS__); \
} while (0)
#define HISIGNALLING_LOG_TRACE(fmt, ...) \
do \
{ \
HISIGNALLING_LOG (HISIGNALLING_LEVEL_TRACE, fmt, ##__VA_ARGS__); \
} while (0)
#define HISIGNALLING_LOG_DEBUG(fmt, ...) \
do \
{ \
HISIGNALLING_LOG (HISIGNALLING_LEVEL_DEBUG, fmt, ##__VA_ARGS__); \
} while (0)
#define HISIGNALLING_LOG_INFO(fmt, ...) \
do \
{ \
HISIGNALLING_LOG (HISIGNALLING_LEVEL_INFO, fmt, ##__VA_ARGS__); \
} while (0)
#define HISIGNALLING_LOG_WARN(fmt, ...) \
do \
{ \
HISIGNALLING_LOG (HISIGNALLING_LEVEL_WARN, fmt, ##__VA_ARGS__); \
} while (0)
#define HISIGNALLING_LOG_ERROR(fmt, ...) \
do \
{ \
HISIGNALLING_LOG (HISIGNALLING_LEVEL_ERROR, fmt, ##__VA_ARGS__); \
} while (0)
#define HISIGNALLING_LOG_FATAL(fmt, ...) \
do \
{ \
HISIGNALLING_LOG (HISIGNALLING_LEVEL_FATAL, fmt, ##__VA_ARGS__); \
} while (0)
/**
* @brief: use this hisignalling Transmission protocol frame format
*
* @param frameHeader: Transmission protocol frame header
*
* @param hisignallingMsgBuf: Transmission protocol frame buffer
*
* @param hisigallingMsgLen: Transmission protocol frame buffer len
*
* @param endOfFrame: Transmission protocol frame tail
*
* @param hisignallingCrc32Check: Transmission protocol crc32 check
*
* */
typedef struct {
hi_u8 frameHeader[HISGNALLING_MSG_FRAME_HEADER_LEN];
hi_u8 hisignallingMsgBuf[HISIGNALLING_MSG_BUFF_LEN];
hi_u32 hisigallingMsgLen;
hi_u8 endOfFrame;
hi_u32 hisignallingCrc32Check;
}HisignallingProtocalType;
/**
* @brief: use this hisignalling return type
*
* @param HISIGNALLING_RET_VAL_CORRECT: return type is correct
*
* @param HISIGNALLING_RET_VAL_ERROR: return type is error
*
* @param HISIGNALLING_RET_VAL_ERROR: return type is unknown type
* */
typedef enum {
HISIGNALLING_RET_VAL_CORRECT = 0,
HISIGNALLING_RET_VAL_ERROR,
HISGNALLING_RET_VAL_MAX
}HisignallingErrorType;
/**
* @brief: use this hisignalling sample:Access peripheral enumeration type
*
* @param MOTOR_GO_FORWARD: peripheral motor go forward
*
* @param MOTOR_GO_BACK: peripheral motor go back
*
* @param STEERING_ENGINE_MOVEMENT/STEERING_ENGINE_AND_MOTOR_MOVEMENT/STEERING_ENGINE_AND_MOTOR_STOP
* the same use for peripheral
* */
typedef enum {
MOTOR_GO_FORWARD = 0,
MOTOR_GO_BACK,
STEERING_ENGINE_MOVEMENT,
STEERING_ENGINE_AND_MOTOR_MOVEMENT,
STEERING_ENGINE_AND_MOTOR_STOP,
TRASH_CAN_LID_OPEN,
TRASH_CAN_LID_COLSE
}HisignallingDataType;
/**
* @brief:hisignalling protocal Function declaration
**/
hi_u32 hisignallingMsgTask(hi_void);
/**
* @brief:hisignalling uart message receive API
* @param buf: uart receive buffer
* @param len: uart receive buffer len
*/
HisignallingErrorType hisignallingMsgReceive(hi_u8 *buf, hi_u32 len);
/**
* @brief:hisignalling uart send API
* @param buf: uart message send buffer
* @param len: uart message send buffer len
*/
hi_u32 hisignallingMsgSend(hi_void *buf, hi_u32 dataLen);
int SetUartReceiveFlag(void);
#endif /* HISIGNALING_PROTOCOL_H */

@ -0,0 +1,31 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IOT_CONFIG_H
#define IOT_CONFIG_H
// <CONFIG THE LOG
/* if you need the iot log for the development , please enable it, else please comment it */
#define CONFIG_LINKLOG_ENABLE 1
// < CONFIG THE WIFI
/* Please modify the ssid and pwd for the own */
#define CONFIG_AP_SSID "Metro" // WIFI SSID
#define CONFIG_AP_PWD "12364987" // WIFI PWD
/* Tencent iot Cloud user ID , password */
#define CONFIG_USER_ID "YT32IOSCALHi38611_mqtt;12010126;41883;1663689600"
#define CONFIG_USER_PWD "b4168d5d4b65898e6984346c81ad13e1b3f112ab7ce46f65cf29455f4c9e18e8;hmacsha256"
#define CN_CLIENTID "YT32IOSCALHi38611_mqtt" // Tencent cloud ClientID format: Product ID + device name
#endif

@ -0,0 +1,398 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file iot_gpio_ex.h
*
* @brief Declares the extended GPIO interface functions.
*
* These functions are used for settings GPIO pulls and driver strength. \n
*
* @since 1.0
* @version 1.0
*/
#ifndef IOT_GPIO_EX_H
#define IOT_GPIO_EX_H
/**
* @brief Enumerates GPIO pull-up or pull-down settings.
*/
typedef enum {
/** No pull */
IOT_IO_PULL_NONE,
/** Pull-up */
IOT_IO_PULL_UP,
/** Pull-down */
IOT_IO_PULL_DOWN,
/** Maximum value */
IOT_IO_PULL_MAX,
} IotIoPull;
/**
* @ingroup iot_io
*
* GPIO pin ID. CNcomment:IOCNend
*/
typedef enum {
IOT_IO_NAME_GPIO_0, /* <GPIO0 */
IOT_IO_NAME_GPIO_1, /* <GPIO1 */
IOT_IO_NAME_GPIO_2, /* <GPIO2 */
IOT_IO_NAME_GPIO_3, /* <GPIO3 */
IOT_IO_NAME_GPIO_4, /* <GPIO4 */
IOT_IO_NAME_GPIO_5, /* <GPIO5 */
IOT_IO_NAME_GPIO_6, /* <GPIO6 */
IOT_IO_NAME_GPIO_7, /* <GPIO7 */
IOT_IO_NAME_GPIO_8, /* <GPIO8 */
IOT_IO_NAME_GPIO_9, /* <GPIO9 */
IOT_IO_NAME_GPIO_10, /* <GPIO10 */
IOT_IO_NAME_GPIO_11, /* <GPIO11 */
IOT_IO_NAME_GPIO_12, /* <GPIO12 */
IOT_IO_NAME_GPIO_13, /* <GPIO13 */
IOT_IO_NAME_GPIO_14, /* <GPIO14 */
IOT_IO_NAME_SFC_CSN, /* <SFC_CSN */
IOT_IO_NAME_SFC_IO1, /* <SFC_IO1 */
IOT_IO_NAME_SFC_IO2, /* <SFC_IO2 */
IOT_IO_NAME_SFC_IO0, /* <SFC_IO0 */
IOT_IO_NAME_SFC_CLK, /* <SFC_CLK */
IOT_IO_NAME_SFC_IO3, /* <SFC_IO3 */
IOT_IO_NAME_MAX,
} IotIoName;
/**
* @ingroup iot_io
*
* GPIO_0 pin function.CNcomment:GPIO_0CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_0_GPIO,
IOT_IO_FUNC_GPIO_0_UART1_TXD = 2,
IOT_IO_FUNC_GPIO_0_SPI1_CK,
IOT_IO_FUNC_GPIO_0_JTAG_TDO,
IOT_IO_FUNC_GPIO_0_PWM3_OUT,
IOT_IO_FUNC_GPIO_0_I2C1_SDA,
} IotIoFuncGpio0;
/**
* @ingroup iot_io
*
* GPIO_1 pin function.CNcomment:GPIO_1CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_1_GPIO,
IOT_IO_FUNC_GPIO_1_UART1_RXD = 2,
IOT_IO_FUNC_GPIO_1_SPI1_RXD,
IOT_IO_FUNC_GPIO_1_JTAG_TCK,
IOT_IO_FUNC_GPIO_1_PWM4_OUT,
IOT_IO_FUNC_GPIO_1_I2C1_SCL,
IOT_IO_FUNC_GPIO_1_BT_FREQ,
} IotIoFuncGpio1;
/**
* @ingroup iot_io
*
* GPIO_2 pin function.CNcomment:GPIO_2CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_2_GPIO,
IOT_IO_FUNC_GPIO_2_UART1_RTS_N = 2,
IOT_IO_FUNC_GPIO_2_SPI1_TXD,
IOT_IO_FUNC_GPIO_2_JTAG_TRSTN,
IOT_IO_FUNC_GPIO_2_PWM2_OUT,
IOT_IO_FUNC_GPIO_2_SSI_CLK = 7,
} IotIoFuncGpio2;
/**
* @ingroup iot_io
*
* GPIO_3 pin function.CNcomment:GPIO_3CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_3_GPIO,
IOT_IO_FUNC_GPIO_3_UART0_TXD,
IOT_IO_FUNC_GPIO_3_UART1_CTS_N,
IOT_IO_FUNC_GPIO_3_SPI1_CSN,
IOT_IO_FUNC_GPIO_3_JTAG_TDI,
IOT_IO_FUNC_GPIO_3_PWM5_OUT,
IOT_IO_FUNC_GPIO_3_I2C1_SDA,
IOT_IO_FUNC_GPIO_3_SSI_DATA,
} IotIoFuncGpio3;
/**
* @ingroup iot_io
*
* GPIO_4 pin function.CNcomment:GPIO_4CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_4_GPIO,
IOT_IO_FUNC_GPIO_4_UART0_RXD = 2,
IOT_IO_FUNC_GPIO_4_JTAG_TMS = 4,
IOT_IO_FUNC_GPIO_4_PWM1_OUT,
IOT_IO_FUNC_GPIO_4_I2C1_SCL,
} IotIoFuncGpio4;
/**
* @ingroup iot_io
*
* GPIO_5 pin function.CNcomment:GPIO_5CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_5_GPIO,
IOT_IO_FUNC_GPIO_5_UART1_RXD = 2,
IOT_IO_FUNC_GPIO_5_SPI0_CSN,
IOT_IO_FUNC_GPIO_5_PWM2_OUT = 5,
IOT_IO_FUNC_GPIO_5_I2S0_MCLK,
IOT_IO_FUNC_GPIO_5_BT_STATUS,
} IotIoFuncGpio5;
/**
* @ingroup iot_io
*
* GPIO_6 pin function.CNcomment:GPIO_6CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_6_GPIO,
IOT_IO_FUNC_GPIO_6_UART1_TXD = 2,
IOT_IO_FUNC_GPIO_6_SPI0_CK,
IOT_IO_FUNC_GPIO_6_PWM3_OUT = 5,
IOT_IO_FUNC_GPIO_6_I2S0_TX,
IOT_IO_FUNC_GPIO_6_COEX_SWITCH,
} IotIoFuncGpio6;
/**
* @ingroup iot_io
*
* GPIO_7 pin function.CNcomment:GPIO_7CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_7_GPIO,
IOT_IO_FUNC_GPIO_7_UART1_CTS_N = 2,
IOT_IO_FUNC_GPIO_7_SPI0_RXD,
IOT_IO_FUNC_GPIO_7_PWM0_OUT = 5,
IOT_IO_FUNC_GPIO_7_I2S0_BCLK,
IOT_IO_FUNC_GPIO_7_BT_ACTIVE,
} IotIoFuncGpio7;
/**
* @ingroup iot_io
*
* GPIO_8 pin function.CNcomment:GPIO_8CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_8_GPIO,
IOT_IO_FUNC_GPIO_8_UART1_RTS_N = 2,
IOT_IO_FUNC_GPIO_8_SPI0_TXD,
IOT_IO_FUNC_GPIO_8_PWM1_OUT = 5,
IOT_IO_FUNC_GPIO_8_I2S0_WS,
IOT_IO_FUNC_GPIO_8_WLAN_ACTIVE,
} IotIoFuncGpio8;
/**
* @ingroup iot_io
*
* GPIO_9 pin function.CNcomment:GPIO_9CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_9_GPIO,
IOT_IO_FUNC_GPIO_9_I2C0_SCL,
IOT_IO_FUNC_GPIO_9_UART2_RTS_N,
IOT_IO_FUNC_GPIO_9_SDIO_D2,
IOT_IO_FUNC_GPIO_9_SPI0_TXD,
IOT_IO_FUNC_GPIO_9_PWM0_OUT,
IOT_IO_FUNC_GPIO_9_I2S0_MCLK = 7,
} IotIoFuncGpio9;
/**
* @ingroup iot_io
*
* GPIO_10 pin function.CNcomment:GPIO_10CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_10_GPIO,
IOT_IO_FUNC_GPIO_10_I2C0_SDA,
IOT_IO_FUNC_GPIO_10_UART2_CTS_N,
IOT_IO_FUNC_GPIO_10_SDIO_D3,
IOT_IO_FUNC_GPIO_10_SPI0_CK,
IOT_IO_FUNC_GPIO_10_PWM1_OUT,
IOT_IO_FUNC_GPIO_10_I2S0_TX = 7,
} IotIoFuncGpio10;
/**
* @ingroup iot_io
*
* GPIO_11 pin function.CNcomment:GPIO_11CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_11_GPIO,
IOT_IO_FUNC_GPIO_11_UART2_TXD = 2,
IOT_IO_FUNC_GPIO_11_SDIO_CMD,
IOT_IO_FUNC_GPIO_11_SPI0_RXD,
IOT_IO_FUNC_GPIO_11_PWM2_OUT,
IOT_IO_FUNC_GPIO_11_RF_TX_EN_EXT,
IOT_IO_FUNC_GPIO_11_I2S0_RX,
} IotIoFuncGpio11;
/**
* @ingroup iot_io
*
* GPIO_12 pin function.CNcomment:GPIO_12CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_12_GPIO,
IOT_IO_FUNC_GPIO_12_UART2_RXD = 2,
IOT_IO_FUNC_GPIO_12_SDIO_CLK,
IOT_IO_FUNC_GPIO_12_SPI0_CSN,
IOT_IO_FUNC_GPIO_12_PWM3_OUT,
IOT_IO_FUNC_GPIO_12_RF_RX_EN_EXT,
IOT_IO_FUNC_GPIO_12_I2S0_BCLK,
} IotIoFuncGpio12;
/**
* @ingroup iot_io
*
* GPIO_13 pin function.CNcomment:GPIO_13CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_13_SSI_DATA,
IOT_IO_FUNC_GPIO_13_UART0_TXD,
IOT_IO_FUNC_GPIO_13_UART2_RTS_N,
IOT_IO_FUNC_GPIO_13_SDIO_D0,
IOT_IO_FUNC_GPIO_13_GPIO,
IOT_IO_FUNC_GPIO_13_PWM4_OUT,
IOT_IO_FUNC_GPIO_13_I2C0_SDA,
IOT_IO_FUNC_GPIO_13_I2S0_WS,
} IotIoFuncGpio13;
/**
* @ingroup iot_io
*
* GPIO_14 pin function.CNcomment:GPIO_14CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_14_SSI_CLK,
IOT_IO_FUNC_GPIO_14_UART0_RXD,
IOT_IO_FUNC_GPIO_14_UART2_CTS_N,
IOT_IO_FUNC_GPIO_14_SDIO_D1,
IOT_IO_FUNC_GPIO_14_GPIO,
IOT_IO_FUNC_GPIO_14_PWM5_OUT,
IOT_IO_FUNC_GPIO_14_I2C0_SCL,
} IotIoFuncGpio14;
/**
* @ingroup iot_io
*
* SFC_CSN pin function.CNcomment:SFC_CSNCNend
*/
typedef enum {
IOT_IO_FUNC_SFC_CSN_SFC_CSN,
IOT_IO_FUNC_SFC_CSN_SDIO_D2,
IOT_IO_FUNC_SFC_CSN_GPIO9,
IOT_IO_FUNC_SFC_CSN_SPI0_TXD = 4,
} IotIoFuncSfcCsn;
/**
* @ingroup iot_io
*
* SFC_DO pin function.CNcomment:SFC_DOCNend
*/
typedef enum {
IOT_IO_FUNC_SFC_IO_1_SFC_DO,
IOT_IO_FUNC_SFC_IO_1_SDIO_D3,
IOT_IO_FUNC_SFC_IO_1_GPIO10,
IOT_IO_FUNC_SFC_IO_1_SPI0_CK = 4,
} IotIoFuncSfcIo1;
/**
* @ingroup iot_io
*
* SFC_WPN pin function.CNcomment:SFC_WPNCNend
*/
typedef enum {
IOT_IO_FUNC_SFC_IO_2_SFC_WPN,
IOT_IO_FUNC_SFC_IO_2_SDIO_CMD,
IOT_IO_FUNC_SFC_IO_2_GPIO11,
IOT_IO_FUNC_SFC_IO_2_RF_TX_EN_EXT,
IOT_IO_FUNC_SFC_IO_2_SPI0_RXD,
} IotIoFuncSfcIo2;
/**
* @ingroup iot_io
*
* SFC_DI pin function.CNcomment:SFC_DICNend
*/
typedef enum {
IOT_IO_FUNC_SFC_IO_0_SFC_DI,
IOT_IO_FUNC_SFC_IO_0_SDIO_CLK,
IOT_IO_FUNC_SFC_IO_0_GPIO12,
IOT_IO_FUNC_SFC_IO_0_RF_RX_EN_EXT,
IOT_IO_FUNC_SFC_IO_0_SPI0_CSN,
} IotIoFuncSfcIo0;
/**
* @ingroup iot_io
*
* SFC_CLK pin function.CNcomment:SFC_CLKCNend
*/
typedef enum {
IOT_IO_FUNC_SFC_CLK_SFC_CLK,
IOT_IO_FUNC_SFC_CLK_SDIO_D0,
IOT_IO_FUNC_SFC_CLK_GPIO13,
IOT_IO_FUNC_SFC_CLK_SSI_DATA = 4,
} IotIoFuncSfcClk;
/**
* @ingroup iot_io
*
* SFC_HOLDN pin function.CNcomment:SFC_HOLDNCNend
*/
typedef enum {
IOT_IO_FUNC_SFC_IO_3_SFC_HOLDN,
IOT_IO_FUNC_SFC_IO_3_SDIO_D1,
IOT_IO_FUNC_SFC_IO_3_GPIO14,
IOT_IO_FUNC_SFC_IO_3_SSI_CLK = 4,
} IotIoFuncSfcIo3;
/**
* @ingroup iot_io
*
* I/O drive capability.CNcomment:IOCNend
* Note: The HI_IO_NAME_GPIO_0~HI_IO_NAME_GPIO_11 and HI_IO_NAME_GPIO_13~HI_IO_NAME_GPIO_14 driver capabilities are
* optional.The value range is HI_IO_DRIVER_STRENGTH_0~HI_IO_DRIVER_STRENGTH_3, and the other I/O ranges are
* HI_IO_DRIVER_STRENGTH_0~HI_IO_DRIVER_STRENGTH_7.CNcomment::HI_IO_NAME_GPIO_0~HI_IO_NAME_GPIO_11
* HI_IO_NAME_GPIO_13~HI_IO_NAME_GPIO_14HI_IO_DRIVER_STRENGTH_0~HI_IO_DRIVER_STRENGTH_3
* IOHI_IO_DRIVER_STRENGTH_0~HI_IO_DRIVER_STRENGTH_7CNend
*/
typedef enum {
IOT_IO_DRIVER_STRENGTH_0 = 0, /* <Drive strength level 0 (highest).CNcomment:驱动能力0级驱动能力最高CNend */
IOT_IO_DRIVER_STRENGTH_1, /* <Drive strength level 1.CNcomment:驱动能力1级CNend */
IOT_IO_DRIVER_STRENGTH_2, /* <Drive strength level 2.CNcomment:驱动能力2级CNend */
IOT_IO_DRIVER_STRENGTH_3, /* <Drive strength level 3.CNcomment:驱动能力3级CNend */
IOT_IO_DRIVER_STRENGTH_4, /* <Drive strength level 4.CNcomment:驱动能力4级CNend */
IOT_IO_DRIVER_STRENGTH_5, /* <Drive strength level 5.CNcomment:驱动能力5级CNend */
IOT_IO_DRIVER_STRENGTH_6, /* <Drive strength level 6.CNcomment:驱动能力6级CNend */
IOT_IO_DRIVER_STRENGTH_7, /* <Drive strength level 7 (lowest).CNcomment:驱动能力7级驱动能力最低CNend */
IOT_IO_DRIVER_STRENGTH_MAX,
} IotIoDriverStrength;
unsigned int IoSetPull(unsigned int id, IotIoPull val);
unsigned int IoSetFunc(unsigned int id, unsigned char val);
//unsigned int TaskMsleep(unsigned int ms);
#endif
/** @} */

@ -0,0 +1,95 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This file make use the hmac to make mqtt pwd.
* The method is use the date string to hash the device passwd
* Take care that this implement depends on the hmac of the mbedtls
*/
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include "md.h"
#include "md_internal.h"
#define CN_HMAC256_LEN_MAX (65)
#define CN_HMAC256_LEN 32
#define RIGHT_MOVE_BIT_4 (4)
#define NUMBER_9 (9)
#define DECIMAL_BASE (10)
#define STRING_LEN_TIMES (2)
#define LEN_TIMES (2)
#define OFFSET (1)
// make a byte to 2 ascii hex
static int byte2hexstr(unsigned char *bufin, int len, char *bufout)
{
int i = 0;
unsigned char tmp_l = 0x0;
unsigned char tmp_h = 0;
if ((bufin == NULL)||(len <= 0)||(bufout == NULL)) {
return -1;
}
for (i = 0; i < len; i++) {
tmp_h = (bufin[i] >> RIGHT_MOVE_BIT_4) & 0X0F;
tmp_l = bufin[i] & 0x0F;
bufout[STRING_LEN_TIMES * i] = (tmp_h > NUMBER_9) ?
(tmp_h - DECIMAL_BASE + 'a'):(tmp_h +'0');
bufout[STRING_LEN_TIMES * i + OFFSET] = (tmp_l > NUMBER_9) ?
(tmp_l - DECIMAL_BASE + 'a'):(tmp_l +'0');
}
bufout[STRING_LEN_TIMES * len] = '\0';
return 0;
}
int HmacGeneratePwd(const unsigned char *content, int contentLen, const unsigned char *key,
int keyLen, unsigned char *buf)
{
int ret = -1;
mbedtls_md_context_t mbedtls_md_ctx;
const mbedtls_md_info_t *md_info;
unsigned char hash[CN_HMAC256_LEN];
if ((key == NULL)||(content == NULL)||(buf == NULL)||
(keyLen == 0)||(contentLen == 0)||
(CN_HMAC256_LEN_MAX < (CN_HMAC256_LEN * LEN_TIMES + OFFSET))) {
return ret;
}
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
if ((md_info == NULL)||((size_t)md_info->size > CN_HMAC256_LEN)) {
return ret;
}
mbedtls_md_init(&mbedtls_md_ctx);
ret = mbedtls_md_setup(&mbedtls_md_ctx, md_info, 1);
if (ret != 0) {
mbedtls_md_free(&mbedtls_md_ctx);
return ret;
}
(void)mbedtls_md_hmac_starts(&mbedtls_md_ctx, key, keyLen);
(void)mbedtls_md_hmac_update(&mbedtls_md_ctx, content, contentLen);
(void)mbedtls_md_hmac_finish(&mbedtls_md_ctx, hash);
// <transfer the hash code to the string mode
ret = byte2hexstr(hash, CN_HMAC256_LEN, (char *)buf);
if (ret != 0) {
return ret;
}
return ret;
}

@ -0,0 +1,32 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IOT_HMAC_H
#define IOT_HMAC_H
/**
* This function used to generate the passwd for the mqtt to connect the HW IoT platform
* @param content: This is the content for the hmac,
* and usually it is the device passwd set or get from the Iot Platform
* @param content_len: The length of the content
* @param key: This is the key for the hmac, and usually it is the time used in the client_id:
* the format isyearmonthdatehour:like 1970010100
* @param key_len: The length of the key
* @param buf: used to storage the hmac code
* @param buf_len:the buf length
* @return:0 success while others failed
*/
int HmacGeneratePwd(const unsigned char *content, int contentLen, const unsigned char *key,
int keyLen, unsigned char *buf);
#endif

@ -0,0 +1,50 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <iot_log.h>
static EnIotLogLevel gIoTLogLevel = EN_IOT_LOG_LEVEL_TRACE;
static const char *gIoTLogLevelNames[] = {
"TRACE",
"DEBUG",
"INFO ",
"WARN ",
"ERROR",
"FATAL"
};
int IoTLogLevelSet(EnIotLogLevel level)
{
int ret = -1;
if (level < EN_IOT_LOG_LEVEL_MAX) {
gIoTLogLevel = level;
ret = 0;
}
return ret;
}
EnIotLogLevel IoTLogLevelGet(void)
{
return gIoTLogLevel;
}
const char *IoTLogLevelGetName(EnIotLogLevel logLevel)
{
if (logLevel >= EN_IOT_LOG_LEVEL_MAX) {
return "NULL ";
} else {
return gIoTLogLevelNames[logLevel];
}
}

@ -0,0 +1,122 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IOT_LOG_H_
#define IOT_LOG_H_
/**
* @brief:this defines for the log module,
* and IOT_LOG_TRACE/IOT_LOG_DEBUG will not participate the compile in the release version
*
*
* */
typedef enum {
// < this is used as the trace function,like the function enter and function out
EN_IOT_LOG_LEVEL_TRACE = 0,
// < this is used as the debug, you could add any debug as you wish
EN_IOT_LOG_LEVEL_DEBUG,
// < which means it is import message, and you should known
EN_IOT_LOG_LEVEL_INFO,
// < this is used as the executed result,which means the status is not what we expected
EN_IOT_LOG_LEVEL_WARN,
// < this is used as the executed result,which means the status is not what we expected
EN_IOT_LOG_LEVEL_ERROR,
// < this is used as the parameters input for the api interface, which could not accepted
EN_IOT_LOG_LEVEL_FATAL,
EN_IOT_LOG_LEVEL_MAX,
}EnIotLogLevel;
/**
* @brief:use this function to get the current output log
*
* @return: the current output mask log, defined by en_iot_log_level_t
* */
EnIotLogLevel IoTLogLevelGet(void);
/**
* @brief: use this function to get the debug level name
*
* @parameter[in]:level, the level to get
*
* @return: the mapped level name
* */
const char *IoTLogLevelGetName(EnIotLogLevel logLevel);
/**
* @brief:use this function to set the current output log
*
* @parameter[in] level:defined by en_iot_log_level_t
*
* @return: 0 success while -1 failed
* */
int IoTLogLevelSet(EnIotLogLevel level);
/*
* @brief: this is a weak function ,and you could rewrite one
*
* @param fmt: same use as the fmt for printf
*
* @param unfixed: same use for printf
*
* @return: don't care about it
*
* @attention: and the components should not call this function directly, you'd better
*
* call IOT_LOG groups
*
* */
#ifndef IOT_PRINT
#define IOT_PRINT(fmt, ...) \
do \
{ \
printf(fmt, ##__VA_ARGS__); \
}while (0)
#endif
#ifdef CONFIG_LINKLOG_ENABLE
#define IOT_LOG(level, fmt, ...) \
do \
{ \
IOT_PRINT("[%s][%s] " fmt "\r\n", \
IoTLogLevelGetName((level)), __FUNCTION__, ##__VA_ARGS__); \
} while (0)
#define IOT_LOG_TRACE(fmt, ...) \
do \
{ \
if ((EN_IOT_LOG_LEVEL_TRACE) >= IoTLogLevelGet()) \
{ \
IOT_LOG(EN_IOT_LOG_LEVEL_TRACE, fmt, ##__VA_ARGS__); \
} \
} while (0)
#define IOT_LOG_DEBUG(fmt, ...) \
do \
{ \
if ((EN_IOT_LOG_LEVEL_DEBUG) >= IoTLogLevelGet()) \
{ \
IOT_LOG(EN_IOT_LOG_LEVEL_DEBUG, fmt, ##__VA_ARGS__); \
} \
} while (0)
#else
#define IOT_LOG(level, fmt, ...)
#define IOT_LOG_TRACE(fmt, ...)
#define IOT_LOG_DEBUG(fmt, ...)
#endif
#define IOT_LOG_TRACE(fmt, ...) IOT_LOG(EN_IOT_LOG_LEVEL_TRACE, fmt, ##__VA_ARGS__)
#define IOT_LOG_INFO(fmt, ...) IOT_LOG(EN_IOT_LOG_LEVEL_INFO, fmt, ##__VA_ARGS__)
#define IOT_LOG_WARN(fmt, ...) IOT_LOG(EN_IOT_LOG_LEVEL_WARN, fmt, ##__VA_ARGS__)
#define IOT_LOG_ERROR(fmt, ...) IOT_LOG(EN_IOT_LOG_LEVEL_ERROR, fmt, ##__VA_ARGS__)
#define IOT_LOG_FATAL(fmt, ...) IOT_LOG(EN_IOT_LOG_LEVEL_FATAL, fmt, ##__VA_ARGS__)
#endif /* IOT_LOG_H_ */

@ -0,0 +1,333 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* STEPS:
* 1, CONNECT TO THE IOT SERVER
* 2, SUBSCRIBE THE DEFAULT TOPIC
* 3, WAIT FOR ANY MESSAGE COMES OR ANY MESSAGE TO SEND
*/
#include <securec.h>
#include <hi_task.h>
#include <hi_msg.h>
#include <hi_mem.h>
#include <string.h>
#include <stdbool.h>
#include "iot_config.h"
#include "iot_log.h"
#include "iot_hmac.h"
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_watchdog.h"
#include "MQTTClient.h"
#include "iot_errno.h"
#include "iot_main.h"
#include "iot_gpio.h"
// < this is the configuration head
#define CN_IOT_SERVER "tcp://106.55.124.154:1883" // Tencent iot cloud address
#define CONFIG_COMMAND_TIMEOUT 10000L
#define CN_KEEPALIVE_TIME 50
#define CN_CLEANSESSION 1
#define CN_HMAC_PWD_LEN 65 // < SHA256 IS 32 BYTES AND END APPEND '\0'
#define CN_EVENT_TIME "1970000100"
#define CN_CLIENTID_FMT "%s_0_0_%s" // < This is the cient ID format, deviceID_0_0_TIME
#define CN_QUEUE_WAITTIMEOUT 1000
#define CN_QUEUE_MSGNUM 16
#define CN_QUEUE_MSGSIZE (sizeof(hi_pvoid))
#define CN_TASK_PRIOR 28
#define CN_TASK_STACKSIZE 0X2000
#define CN_TASK_NAME "IoTMain"
#define Signal_LED_IO 12
typedef enum {
EN_IOT_MSG_PUBLISH = 0,
EN_IOT_MSG_RECV,
}EnIotMsg;
typedef struct {
EnIotMsg type;
int qos;
const char *topic;
const char *payload;
}IoTMsg_t;
typedef struct {
bool stop;
unsigned int conLost;
unsigned int queueID;
unsigned int iotTaskID;
fnMsgCallBack msgCallBack;
MQTTClient_deliveryToken tocken;
}IotAppCb_t;
static IotAppCb_t gIoTAppCb;
static const char *gDefaultSubscribeTopic[] = {
/* Tencent iot cloud topic */
"YT32IOSCAL/Hi38611_mqtt/data",
"YT32IOSCAL/Hi38611_mqtt/event",
"YT32IOSCAL/Hi38611_mqtt/control",
};
#define CN_TOPIC_SUBSCRIBE_NUM (sizeof(gDefaultSubscribeTopic) / sizeof(const char *))
static int MsgRcvCallBack(char *context, char *topic, int topicLen, MQTTClient_message *message)
{
IoTMsg_t *msg;
char *buf;
unsigned int bufSize;
int topiLen = topicLen;
if (topiLen == 0) {
topiLen = strlen(topic);
}
bufSize = topiLen + 1 + message->payloadlen + 1 + sizeof(IoTMsg_t);
buf = hi_malloc(0, bufSize);
if (buf != NULL) {
msg = (IoTMsg_t *)buf;
buf += sizeof(IoTMsg_t);
bufSize -= sizeof(IoTMsg_t);
msg->qos = message->qos;
msg->type = EN_IOT_MSG_RECV;
(void)memcpy_s(buf, bufSize, topic, topiLen);
buf[topiLen] = '\0';
msg->topic = buf;
buf += topiLen + 1;
bufSize -= (topiLen + 1);
(void)memcpy_s(buf, bufSize, message->payload, message->payloadlen);
buf[message->payloadlen] = '\0';
msg->payload = buf;
IOT_LOG_DEBUG("RCVMSG:QOS:%d TOPIC:%s PAYLOAD:%s\r\n", msg->qos, msg->topic, msg->payload);
if (IOT_SUCCESS != osMessageQueuePut(gIoTAppCb.queueID, &msg, 0, CN_QUEUE_WAITTIMEOUT)) {
IOT_LOG_ERROR("Wrie queue failed\r\n");
hi_free(0, msg);
}
}
MQTTClient_freeMessage(&message);
MQTTClient_free(topic);
return 1;
}
// < when the connect lost and this callback will be called
static void ConnLostCallBack(char *context, char *cause)
{
IOT_LOG_DEBUG("Connection lost:caused by:%s\r\n", cause == NULL? "Unknown" : cause);
return;
}
static int MqttProcessQueueMsg(MQTTClient client, IoTMsg_t *msg, MQTTClient_message pubMsg)
{
int ret = 0;
switch (msg->type) {
case EN_IOT_MSG_PUBLISH:
pubMsg.payload = (void *)msg->payload;
pubMsg.payloadlen = (int)strlen(msg->payload);
pubMsg.qos = msg->qos;
pubMsg.retained = 0;
ret = MQTTClient_publishMessage(client, msg->topic, &pubMsg, &gIoTAppCb.tocken);
if (ret != MQTTCLIENT_SUCCESS) {
IOT_LOG_ERROR("MSGSEND:failed\r\n");
}
IOT_LOG_DEBUG("MSGSEND:SUCCESS\r\n");
gIoTAppCb.tocken++;
break;
case EN_IOT_MSG_RECV:
if (gIoTAppCb.msgCallBack != NULL) {
gIoTAppCb.msgCallBack(msg->qos, msg->topic, msg->payload); /*接受信息并进行相应的操作函数体在IoTSetMsgCallback中定义*/
}
break;
default:
break;
}
}
// <use this function to deal all the comming message
static int ProcessQueueMsg(MQTTClient client)
{
unsigned int ret;
unsigned int msgSize;
IoTMsg_t *msg;
unsigned int timeout;
MQTTClient_message pubmsg = MQTTClient_message_initializer;
timeout = CN_QUEUE_WAITTIMEOUT;
do {
msg = NULL;
msgSize = sizeof(hi_pvoid);
ret = osMessageQueueGet(gIoTAppCb.queueID, &msg, &msgSize, timeout);/*得到数据存入msg*/
if (msg != NULL) {
IOT_LOG_DEBUG("QUEUEMSG:QOS:%d TOPIC:%s PAYLOAD:%s\r\n", msg->qos, msg->topic, msg->payload);
MqttProcessQueueMsg(client, msg, pubmsg);
hi_free(0, msg);
}
timeout = 0; // < continous to deal the message without wait here
} while (ret == IOT_SUCCESS);
return 0;
}
int MqttDestory(int ret, MQTTClient client)
{
if (ret != MQTTCLIENT_SUCCESS) {
MQTTClient_destroy(&client);
return -1;
}
return MQTTCLIENT_SUCCESS;
}
static void MainEntryProcess(void)
{
int rc = 0, subQos[CN_TOPIC_SUBSCRIBE_NUM] = {1};
MQTTClient client = NULL;
MQTTClient_connectOptions connOpts = MQTTClient_connectOptions_initializer;
char *clientID = CN_CLIENTID;
char *userID = CONFIG_USER_ID;
char *userPwd = hi_malloc(0, CN_HMAC_PWD_LEN);
if (userPwd == NULL) {
hi_free(0, clientID);
return;
}
userPwd = CONFIG_USER_PWD;
connOpts.keepAliveInterval = CN_KEEPALIVE_TIME;
connOpts.cleansession = CN_CLEANSESSION;
connOpts.username = userID;
connOpts.password = userPwd;
connOpts.MQTTVersion = MQTTVERSION_3_1_1;
IOT_LOG_DEBUG("CLIENTID:%s USERID:%s USERPWD:%s, IOTSERVER:%s\r\n",
clientID, userID, userPwd==NULL?"NULL" : userPwd, CN_IOT_SERVER);
rc = MQTTClient_create(&client, CN_IOT_SERVER, clientID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
if (rc != MQTTCLIENT_SUCCESS) {
if (userPwd != NULL) {
hi_free(0, userPwd);
}
return;
}
rc = MQTTClient_setCallbacks(client, NULL, ConnLostCallBack, MsgRcvCallBack, NULL);
if (MqttDestory(rc, client) != MQTTCLIENT_SUCCESS) {
return;
}
rc = MQTTClient_connect(client, &connOpts);
if (MqttDestory(rc, client) != MQTTCLIENT_SUCCESS) {
return;
}
for (int i = 0; i < CN_TOPIC_SUBSCRIBE_NUM; i++) {
rc = MQTTClient_subscribeMany(client, CN_TOPIC_SUBSCRIBE_NUM,
(char *const *)gDefaultSubscribeTopic, (int *)&subQos[0]);
if (MqttDestory(rc, client) != MQTTCLIENT_SUCCESS) {
return;
}
}
IOT_LOG_DEBUG ("Connect success and Subscribe success\r\n");
IoTGpioSetOutputVal(Signal_LED_IO, IOT_GPIO_VALUE1);
while (MQTTClient_isConnected(client)) {
ProcessQueueMsg(client); // < do the job here
MQTTClient_yield(); // < make the keepalive done
}
MQTTClient_disconnect(client, CONFIG_COMMAND_TIMEOUT);
return;
}
/* MQTT processing entry */
static hi_void *MainEntry(char *arg)
{
(void)arg;
while (gIoTAppCb.stop == false) {
MainEntryProcess();
IOT_LOG_DEBUG("The connection lost and we will try another connect\r\n");
IoTGpioSetOutputVal(Signal_LED_IO, IOT_GPIO_VALUE0);
hi_sleep(1000); /* 1000: cpu sleep 1000ms */
}
return NULL;
}
static void engine_init(unsigned int IO){
IoTGpioInit(IO);
IoSetFunc(IO, 0);
IoTGpioSetDir(IO, IOT_GPIO_DIR_OUT);
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE0);
IOT_LOG_DEBUG("GPIO:%u initialized!", IO);
}
int IoTMain(void)
{
unsigned int ret = 0;
hi_task_attr attr = {0};
engine_init(6);
engine_init(7);
engine_init(9);
engine_init(10);
IoTGpioInit(Signal_LED_IO);
IoSetFunc(Signal_LED_IO, 0);
IoTGpioSetDir(Signal_LED_IO, IOT_GPIO_DIR_OUT);
IoTGpioSetOutputVal(Signal_LED_IO, IOT_GPIO_VALUE0);
gIoTAppCb.queueID = osMessageQueueNew(CN_QUEUE_MSGNUM, CN_QUEUE_MSGSIZE, NULL);
if (ret != IOT_SUCCESS) {
IOT_LOG_ERROR("Create the msg queue Failed\r\n");
}
attr.stack_size = CN_TASK_STACKSIZE;
attr.task_prio = CN_TASK_PRIOR;
attr.task_name = CN_TASK_NAME;
ret = hi_task_create(&gIoTAppCb.iotTaskID, &attr, MainEntry, NULL);
if (ret != IOT_SUCCESS) {
IOT_LOG_ERROR("Create the Main Entry Failed\r\n");
}
return 0;
}
int IoTSetMsgCallback(fnMsgCallBack msgCallback)
{
gIoTAppCb.msgCallBack = msgCallback;/*赋予函数*/
return 0;
}
int IotSendMsg(int qos, const char *topic, const char *payload)
{
int rc = -1;
IoTMsg_t *msg;
char *buf;
unsigned int bufSize;
bufSize = strlen(topic) + 1 +strlen(payload) + 1 + sizeof(IoTMsg_t);
buf = hi_malloc(0, bufSize);
if (buf != NULL) {
msg = (IoTMsg_t *)buf;
buf += sizeof(IoTMsg_t);
bufSize -= sizeof(IoTMsg_t);
msg->qos = qos;
msg->type = EN_IOT_MSG_PUBLISH;
(void)memcpy_s(buf, bufSize, topic, strlen(topic));
buf[strlen(topic)] = '\0';
msg->topic = buf;
buf += strlen(topic) + 1;
bufSize -= (strlen(topic) + 1);
(void)memcpy_s(buf, bufSize, payload, strlen(payload));
buf[strlen(payload)] = '\0';
msg->payload = buf;
IOT_LOG_DEBUG("SNDMSG:QOS:%d TOPIC:%s PAYLOAD:%s\r\n", msg->qos, msg->topic, msg->payload);
if (IOT_SUCCESS != osMessageQueuePut(gIoTAppCb.queueID, &msg, 0, CN_QUEUE_WAITTIMEOUT)) {
IOT_LOG_ERROR("Write queue failed\r\n");
hi_free(0, msg);
} else {
rc = 0;
}
}
return rc;
}

@ -0,0 +1,44 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IOT_MAIN_H
#define IOT_MAIN_H
typedef void (*fnMsgCallBack)(int qos, const char *topic, const char *payload);
/**
* This is the iot main function. Please call this function first
*/
int IoTMain(void);
/**
* Use this function to set the message call back function, when some messages comes,
* the callback will be called, if you don't care about the message, set it to NULL
*/
int IoTSetMsgCallback(fnMsgCallBack msgCallback);
/**
* When you want to send some messages to the iot server(including the response message),
* please call this api
* @param qos: the mqtt qos,:0,1,2
* @param topic: the iot mqtt topic
* @param payload: the mqtt payload
*
* @return 0 success while others failed
*
* @instruction: if success means we write the message to the queue susccess,
* not means communicate with the server success
*/
int IotSendMsg(int qos, const char *topic, const char *payload);
#endif /* IOT_MAIN_H_ */

@ -0,0 +1,361 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <hi_mem.h>
#include <cJSON.h>
#include <string.h>
#include "iot_main.h"
#include "iot_log.h"
#include "iot_config.h"
#include "iot_profile.h"
// < format the report data to json string mode
static cJSON *FormateProflleValue(IoTProfileKV_t *kv)
{
cJSON *ret = NULL;
switch (kv->type) {
case EN_IOT_DATATYPE_INT:
ret = cJSON_CreateNumber(kv->iValue);
break;
case EN_IOT_DATATYPE_LONG:
ret = cJSON_CreateNumber((double)(*(long *)kv->value));
break;
case EN_IOT_DATATYPE_STRING:
ret = cJSON_CreateString((const char *)kv->value);
break;
default:
break;
}
return ret;
}
static cJSON *MakeKvs(IoTProfileKV_t *kvlst)
{
cJSON *root;
cJSON *kv;
IoTProfileKV_t *kvInfo;
// < build a root node
root = cJSON_CreateObject();
if (root == NULL) {
cJSON_Delete(root);
root = NULL;
return root;
}
// < add all the property to the properties
kvInfo = kvlst;
while (kvInfo != NULL) {
kv = FormateProflleValue(kvInfo);
if (kv == NULL) {
if (root != NULL) {
cJSON_Delete(root);
root = NULL;
}
return root;
}
cJSON_AddItemToObject(root, kvInfo->key, kv);
kvInfo = kvInfo->nxt;
}
// < OK, now we return it
return root;
}
#define CN_PROFILE_SERVICE_KEY_SERVICEID "service_id"
#define CN_PROFILE_SERVICE_KEY_PROPERTIIES "properties"
#define CN_PROFILE_SERVICE_KEY_EVENTTIME "event_time"
#define CN_PROFILE_KEY_SERVICES "services"
static cJSON *MakeService(IoTProfileService_t *serviceInfo)
{
cJSON *root;
cJSON *serviceID;
cJSON *properties;
cJSON *eventTime;
// < build a root node
root = cJSON_CreateObject();
if (root == NULL) {
cJSON_Delete(root);
root = NULL;
return root;
}
// < add the serviceID node to the root node
serviceID = cJSON_CreateString(serviceInfo->serviceID);
if (serviceID == NULL) {
if (root != NULL) {
cJSON_Delete(root);
root = NULL;
}
return root;
}
cJSON_AddItemToObjectCS(root, CN_PROFILE_SERVICE_KEY_SERVICEID, serviceID);
// < add the properties node to the root
properties = MakeKvs(serviceInfo->serviceProperty);
if (properties == NULL) {
if (root != NULL) {
cJSON_Delete(root);
root = NULL;
}
return root;
}
cJSON_AddItemToObjectCS(root, CN_PROFILE_SERVICE_KEY_PROPERTIIES, properties);
// < add the event time (optional) to the root
if (serviceInfo->eventTime != NULL) {
eventTime = cJSON_CreateString(serviceInfo->eventTime);
if (eventTime == NULL) {
if (root != NULL) {
cJSON_Delete(root);
root = NULL;
}
return root;
}
cJSON_AddItemToObjectCS(root, CN_PROFILE_SERVICE_KEY_EVENTTIME, eventTime);
}
// < OK, now we return it
cJSON_Delete(properties);
return root;
}
static cJSON *MakeServices(IoTProfileService_t *serviceInfo)
{
cJSON *services = NULL;
cJSON *service;
IoTProfileService_t *serviceTmp;
// < create the services array node
services = cJSON_CreateArray();
if (services == NULL) {
cJSON_Delete(services);
services = NULL;
return services;
}
serviceTmp = serviceInfo;
while (serviceTmp != NULL) {
service = MakeService(serviceTmp);
if (service == NULL) {
if (services != NULL) {
cJSON_Delete(services);
services = NULL;
}
return services;
}
cJSON_AddItemToArray(services, service);
serviceTmp = serviceTmp->nxt;
}
// < now we return the services
return services;
}
// < use this function to make a topic to publish
// < if request_id is needed depends on the fmt
static char *MakeTopic(const char *fmt, const char *deviceID, const char *requestID)
{
int len;
char *ret = NULL;
len = strlen(fmt) + strlen(deviceID);
if (requestID != NULL) {
len += strlen(requestID);
}
ret = hi_malloc(0, len);
if (ret != NULL) {
if (requestID != NULL) {
(void)snprintf_s(ret, len, len, fmt, deviceID, requestID);
} else {
(void)snprintf_s(ret, len, len, fmt, deviceID);
}
}
return ret;
}
#define CN_PROFILE_CMDRESP_KEY_RETCODE "result_code"
#define CN_PROFILE_CMDRESP_KEY_RESPNAME "response_name"
#define CN_PROFILE_CMDRESP_KEY_PARAS "paras"
static char *MakeProfileCmdResp(IoTCmdResp_t *payload)
{
char *ret = NULL;
cJSON *root;
cJSON *retCode;
cJSON *respName;
cJSON *paras;
// < create the root node
root = cJSON_CreateObject();
if (root == NULL) {
cJSON_Delete(root);
return ret;
}
// < create retcode and retdesc and add it to the root
retCode = cJSON_CreateNumber(payload->retCode);
if (retCode == NULL) {
if (root != NULL) {
cJSON_Delete(root);
}
return ret;
}
cJSON_AddItemToObjectCS(root, CN_PROFILE_CMDRESP_KEY_RETCODE, retCode);
if (payload->respName != NULL) {
respName = cJSON_CreateString(payload->respName);
if (respName == NULL) {
if (root != NULL) {
cJSON_Delete(root);
}
return ret;
}
cJSON_AddItemToObjectCS(root, CN_PROFILE_CMDRESP_KEY_RESPNAME, respName);
}
if (payload->paras != NULL) {
paras = MakeKvs(payload->paras);
if (paras == NULL) {
if (root != NULL) {
cJSON_Delete(root);
}
return ret;
}
cJSON_AddItemToObjectCS(root, CN_PROFILE_CMDRESP_KEY_PARAS, paras);
}
// < OK, now we make it to a buffer
ret = cJSON_PrintUnformatted(root);
cJSON_Delete(root);
return ret;
}
static char *MakeProfilePropertyReport(IoTProfileService_t *payload)
{
char *ret = NULL;
cJSON *root;
cJSON *services;
// < create the root node
root = cJSON_CreateObject();
if (root == NULL) {
cJSON_Delete(root);
return ret;
}
// < create the services array node to the root
services = MakeServices(payload);
if (services == NULL) {
if (root != NULL) {
cJSON_Delete(root);
}
return ret;
}
cJSON_AddItemToObjectCS(root, CN_PROFILE_KEY_SERVICES, services);
// < OK, now we make it to a buffer
ret = cJSON_PrintUnformatted(root);
cJSON_Delete(root);
return ret;
}
#define WECHAT_SUBSCRIBE_TYPE "update"
#define WECHAT_SUBSCRIBE_VERSION "1.0.0"
#define WECHAT_SUBSCRIBE_TOKEN "DeviceSubscribe"
static char *MakeProfileReport(WeChatProfile *payload)
{
char *ret = NULL;
cJSON *root;
cJSON *state;
cJSON *reported;
/* create json root node */
root = cJSON_CreateObject();
if (root == NULL) {
return;
}
/* state create */
state = cJSON_CreateObject();
if (state == NULL) {
return;
}
/* reported create */
reported = cJSON_CreateObject();
if (reported == NULL) {
return;
}
/* add root object */
cJSON_AddItemToObject(root, payload->subscribeType, cJSON_CreateString(WECHAT_SUBSCRIBE_TYPE));
cJSON_AddItemToObject(root, payload->status.subState, state);
cJSON_AddItemToObject(state, payload->status.subReport, reported);
cJSON_AddItemToObject(root, payload->status.reportVersion, cJSON_CreateString(WECHAT_SUBSCRIBE_VERSION));
cJSON_AddItemToObject(root, payload->status.Token, cJSON_CreateString(WECHAT_SUBSCRIBE_TOKEN));
/* add reported item */
cJSON_AddNumberToObject(reported, payload->reportAction.subDeviceActionLight,
payload->reportAction.lightActionStatus);
cJSON_AddNumberToObject(reported, payload->reportAction.subDeviceActionMotor,
payload->reportAction.motorActionStatus);
cJSON_AddNumberToObject(reported, payload->reportAction.subDeviceActionTemperature,
payload->reportAction.temperatureData);
cJSON_AddNumberToObject(reported, payload->reportAction.subDeviceActionHumidity,
payload->reportAction.humidityActionData);
cJSON_AddNumberToObject(reported, payload->reportAction.subDeviceActionLightIntensity,
payload->reportAction.lightIntensityActionData);
ret = cJSON_PrintUnformatted(root);
cJSON_Delete(state);
cJSON_Delete(reported);
cJSON_Delete(root);
return ret;
}
#define CN_PROFILE_TOPICFMT_TOPIC "YT32IOSCAL/Hi38611_mqtt/event"
/*int IoTProfilePropertyReport(char *deviceID, WeChatProfile *payload)
{
int ret = -1;
char *topic;
char *msg;
if ((deviceID == NULL) || (payload== NULL)) {
return ret;
}
topic = MakeTopic(CN_PROFILE_TOPICFMT_TOPIC, deviceID, NULL);
if (topic == NULL) {
return;
}
msg = MakeProfileReport(payload);
if ((topic != NULL) && (msg != NULL)) {
ret = IotSendMsg(0, topic, msg);
}
hi_free(0, topic);
cJSON_free(msg);
return ret;
}*/
int IoTProfilePropertyReport_uart(char *deviceID, char *msg)
{
int ret = -1;
char *topic;
//char *msg;
if ((deviceID == NULL) || (msg == NULL)) {
return ret;
}
topic = MakeTopic(CN_PROFILE_TOPICFMT_TOPIC, deviceID, NULL);
if (topic == NULL) {
return;
}
//msg = MakeProfileReport(payload);
if ((topic != NULL) && (msg != NULL)) {
ret = IotSendMsg(0, topic, msg);
printf("send success\n");
}
hi_free(0, topic);
//cJSON_free(msg);
return ret;
}

@ -0,0 +1,95 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IOT_PROFILE_H
#define IOT_PROFILE_H
#include <hi_types_base.h>
#include "iot_config.h"
#define OC_BEEP_STATUS_ON ((hi_u8) 0x01)
#define OC_BEEP_STATUS_OFF ((hi_u8) 0x00)
// < enum all the data type for the oc profile
typedef enum {
EN_IOT_DATATYPE_INT = 0,
EN_IOT_DATATYPE_LONG,
EN_IOT_DATATYPE_FLOAT,
EN_IOT_DATATYPE_DOUBLE,
EN_IOT_DATATYPE_STRING, // < must be ended with '\0'
EN_IOT_DATATYPE_LAST,
}IoTDataType_t;
typedef enum {
OC_LED_ON = 1,
OC_LED_OFF
}OcLedValue;
typedef struct {
void *nxt; // < ponit to the next key
const char *key;
const char *value;
hi_u32 iValue;
IoTDataType_t type;
}IoTProfileKV_t;
typedef struct {
void *nxt;
char *serviceID;
char *eventTime;
IoTProfileKV_t *serviceProperty;
}IoTProfileService_t;
typedef struct {
int retCode; // < response code, 0 success while others failed
const char *respName; // < response name
const char *requestID; // < specified by the message command
IoTProfileKV_t *paras; // < the command paras
}IoTCmdResp_t;
typedef struct {
const char *subState;
const char *subReport;
const char *reportVersion;
const char *Token;
}WeChatProfileStatus;
typedef struct {
int lightActionStatus;
int motorActionStatus;
int temperatureData;
int humidityActionData;
int lightIntensityActionData;
const char *subDeviceActionLight;
const char *subDeviceActionMotor;
const char *subDeviceActionTemperature;
const char *subDeviceActionHumidity;
const char *subDeviceActionLightIntensity;
}WeChatProfileReporte;
typedef struct {
const char *subscribeType;
WeChatProfileStatus status;
WeChatProfileReporte reportAction;
}WeChatProfile;
/**
* use this function to report the property to the iot platform
*/
//int IoTProfilePropertyReport(char *deviceID, WeChatProfile *payload);
int IoTProfilePropertyReport_uart(char *deviceID, char *msg);
void cJsonInit(void);
void WifiStaReadyWait(void);
#endif

@ -0,0 +1,269 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// < this demo make the wifi to connect to the specified AP
#include <unistd.h>
#include <hi_wifi_api.h>
#include <lwip/ip_addr.h>
#include <lwip/netifapi.h>
#include <hi_types_base.h>
#include <hi_task.h>
#include <hi_mem.h>
#include "iot_config.h"
#include "iot_log.h"
#include "wifi_device.h"
#include "cmsis_os2.h"
#include "wifi_device_config.h"
#include "lwip/api_shell.h"
#define APP_INIT_VAP_NUM 2
#define APP_INIT_USR_NUM 2
static struct netif *gLwipNetif = NULL;
static hi_bool gScanDone = HI_FALSE;
unsigned char wifiStatus = 0;
unsigned char wifiFirstConnecting = 0;
unsigned char wifiSecondConnecting = 0;
unsigned char wifiSecondConnected = 0;
static struct netif* g_iface = NULL;
void WifiStopSta(int netId);
static int WifiStartSta(void);
int cnetId = -1;
int g_connected = 0;
#define WIFI_CONNECT_STATUS ((unsigned char)0x02)
void wifiReconnected(int netId)
{
int recnetId = netId;
if (wifiFirstConnecting == WIFI_CONNECT_STATUS) {
wifiSecondConnecting = HI_TRUE;
wifiFirstConnecting = HI_FALSE;
WifiStopSta(recnetId);
ip4_addr_t ipAddr;
ip4_addr_t ipAny;
IP4_ADDR(&ipAny, 0, 0, 0, 0);
IP4_ADDR(&ipAddr, 0, 0, 0, 0);
recnetId = WifiStartSta();
netifapi_dhcp_start(gLwipNetif);
while (0 == memcmp(&ipAddr, &ipAny, sizeof(ip4_addr_t))) {
IOT_LOG_DEBUG("<Wifi reconnecting>:Wait the DHCP READY");
netifapi_netif_get_addr(gLwipNetif, &ipAddr, NULL, NULL);
hi_sleep(1000); /* 1000: cpu sleep 1000 ms */
}
wifiSecondConnected = HI_FALSE;
wifiFirstConnecting = WIFI_CONNECT_STATUS;
wifiStatus = HI_WIFI_EVT_CONNECTED;
}
}
/* clear netif's ip, gateway and netmask */
static void StaResetAddr(struct netif *lwipNetif)
{
ip4_addr_t st_gw;
ip4_addr_t st_ipaddr;
ip4_addr_t st_netmask;
if (lwipNetif == NULL) {
IOT_LOG_ERROR("hisi_reset_addr::Null param of netdev");
return;
}
IP4_ADDR(&st_gw, 0, 0, 0, 0);
IP4_ADDR(&st_ipaddr, 0, 0, 0, 0);
IP4_ADDR(&st_netmask, 0, 0, 0, 0);
netifapi_netif_set_addr(lwipNetif, &st_ipaddr, &st_netmask, &st_gw);
}
static void WpaEventCB(const hi_wifi_event *hisiEvent)
{
if (hisiEvent == NULL)
return;
IOT_LOG_DEBUG("EVENT_TYPE:%d", hisiEvent->event);
switch (hisiEvent->event) {
case HI_WIFI_EVT_SCAN_DONE:
IOT_LOG_DEBUG("WiFi: Scan results available");
gScanDone = HI_TRUE;
break;
case HI_WIFI_EVT_CONNECTED:
IOT_LOG_DEBUG("WiFi: Connected");
netifapi_dhcp_start(gLwipNetif);
wifiStatus = HI_WIFI_EVT_CONNECTED;
if (wifiSecondConnected) {
wifiSecondConnected = HI_FALSE;
wifiFirstConnecting = WIFI_CONNECT_STATUS;
}
break;
case HI_WIFI_EVT_DISCONNECTED:
IOT_LOG_DEBUG("WiFi: Disconnected");
netifapi_dhcp_stop(gLwipNetif);
StaResetAddr(gLwipNetif);
wifiStatus = HI_WIFI_EVT_DISCONNECTED;
wifiReconnected(cnetId);
break;
case HI_WIFI_EVT_WPS_TIMEOUT:
IOT_LOG_DEBUG("WiFi: wps is timeout");
wifiStatus = HI_WIFI_EVT_WPS_TIMEOUT;
break;
default:
break;
}
}
static int StaStartConnect(void)
{
int ret;
errno_t rc;
hi_wifi_assoc_request assoc_req = {0};
/* copy SSID to assoc_req */
rc = memcpy_s(assoc_req.ssid, HI_WIFI_MAX_SSID_LEN + 1, CONFIG_AP_SSID, strlen(CONFIG_AP_SSID));
if (rc != EOK) {
return -1;
}
/*
* OPEN mode
* for WPA2-PSK mode:
* set assoc_req.auth as HI_WIFI_SECURITY_WPA2PSK,
* then memcpy(assoc_req.key, "12345678", 8).
*/
assoc_req.auth = HI_WIFI_SECURITY_WPA2PSK;
rc = memcpy_s(assoc_req.key, HI_WIFI_MAX_KEY_LEN + 1, CONFIG_AP_PWD, strlen(CONFIG_AP_PWD));
if (rc != EOK) {
return -1;
}
ret = hi_wifi_sta_connect(&assoc_req);
if (ret != HISI_OK) {
return -1;
}
return 0;
}
static void PrintLinkedInfo(WifiLinkedInfo* info)
{
int ret = 0;
if (!info) {
return;
}
static char macAddress[32] = {0};
unsigned char* mac = info->bssid;
if (snprintf_s(macAddress, sizeof(macAddress) + 1, sizeof(macAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]) < 0) { /* mac地址从0,1,2,3,4,5位 */
return;
}
}
static void OnWifiConnectionChanged(int state, WifiLinkedInfo* info)
{
if (!info) {
return;
}
printf("%s %d, state = %d, info = \r\n", __FUNCTION__, __LINE__, state);
PrintLinkedInfo(info);
if (state == WIFI_STATE_AVALIABLE) {
g_connected = 1;
} else {
g_connected = 0;
}
}
static void OnWifiScanStateChanged(int state, int size)
{
printf("%s %d, state = %X, size = %d\r\n", __FUNCTION__, __LINE__, state, size);
}
static WifiEvent g_defaultWifiEventListener = {
.OnWifiConnectionChanged = OnWifiConnectionChanged,
.OnWifiScanStateChanged = OnWifiScanStateChanged
};
static int WifiStartSta(void)
{
WifiDeviceConfig apConfig = {0};
strcpy_s(apConfig.ssid, sizeof(CONFIG_AP_SSID), CONFIG_AP_SSID);
strcpy_s(apConfig.preSharedKey, sizeof(CONFIG_AP_PWD), CONFIG_AP_PWD);
apConfig.securityType = WIFI_SEC_TYPE_PSK;
WifiErrorCode errCode;
int netId = -1;
errCode = RegisterWifiEvent(&g_defaultWifiEventListener);
printf("RegisterWifiEvent: %d\r\n", errCode);
errCode = EnableWifi();
printf("EnableWifi: %d\r\n", errCode);
errCode = AddDeviceConfig(&apConfig, &netId);
printf("AddDeviceConfig: %d\r\n", errCode);
g_connected = 0;
errCode = ConnectTo(netId);
printf("ConnectTo(%d): %d\r\n", netId, errCode);
while (!g_connected) { // wait until connect to AP
osDelay(10); /* 10: os sleep 10ms */
}
printf("g_connected: %d\r\n", g_connected);
g_iface = netifapi_netif_find("wlan0");
if (g_iface) {
err_t ret = netifapi_dhcp_start(g_iface);
printf("netifapi_dhcp_start: %d\r\n", ret);
osDelay(100); // 100: os sleep 100ms wait DHCP server give me IP
ret = netifapi_netif_common(g_iface, dhcp_clients_info_show, NULL);
printf("netifapi_netif_common: %d\r\n", ret);
}
return netId;
}
void WifiStopSta(int netId)
{
int stopNetId = netId;
if (g_iface) {
err_t ret = netifapi_dhcp_stop(g_iface);
printf("netifapi_dhcp_stop: %d\r\n", ret);
}
WifiErrorCode errCode = Disconnect(); // disconnect with your AP
printf("Disconnect: %d\r\n", errCode);
errCode = UnRegisterWifiEvent(&g_defaultWifiEventListener);
printf("UnRegisterWifiEvent: %d\r\n", errCode);
RemoveDevice(stopNetId); // remove AP config
printf("RemoveDevice: %d\r\n", errCode);
errCode = DisableWifi();
printf("DisableWifi: %d\r\n", errCode);
}
void WifiStaReadyWait(void)
{
ip4_addr_t ipAddr;
ip4_addr_t ipAny;
IP4_ADDR(&ipAny, 0, 0, 0, 0);
IP4_ADDR(&ipAddr, 0, 0, 0, 0);
cnetId = WifiStartSta();
IOT_LOG_DEBUG("wifi sta dhcp done");
}

@ -0,0 +1,27 @@
# Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("interconnectionClient") {
sources = [
"app_demo_uart.c",
"hal_iot_gpio_ex.c",
"hisignalling_protocol.c",
]
include_dirs = [
"./",
"//utils/native/lite/include",
"//kernel/liteos_m/kal/cmsis",
"//base/iot_hardware/peripheral/interfaces/kits",
]
}

@ -0,0 +1,86 @@
# Pegasus与Taurus串口互联通信<a name="ZH-CN_TOPIC_0000001130176841"></a>
## 硬件环境搭建
- 硬件要求Hi3861V100核心板、底板、外设扩展板或者机器人板硬件搭建如下图所示。注意这里需要跟Taurus同时使用详情可以参考[串口互联server](http://gitee.com/openharmony/device_soc_hisilicon/blob/master/hi3516dv300/sdk_linux/sample/taurus/ai_sample/interconnection_server/README.md)端。
- 外设扩展板使用的是Hi3861的GPIO0和GPIO1作为串口1复用功能请在程序初始化时注意管脚复用关系。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E4%BA%92%E8%81%94/10.jpg)
- 注意Robot板使用的串口1复用端口是Hi3861的GPIO5和GPIO6其中GPIO6要在程序烧录启动后才能使用如果用户在还没烧录和启动之前就将串口线与硬件连接上这时Hi3861将无法烧录和重启。GPIO6TX引脚影响Hi3861烧录和启动用户在使用Robot板时先拔掉Robot上4pin串口连接线在程序烧录启动后再将4pin串口连接线插回Robot板此时串口可以正常通信。如果用户在使用Robot板的过程中觉得频繁插拔串口线麻烦用户可在串口线上做一个开关当Hi3861烧录或复位启动前关闭开关单板启动后打开开关。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E4%BA%92%E8%81%94/11.jpg)
## 串口通信控制协议HiSignalling介绍
- 为了便于Taurus与Pegasus开发套件之间进行通信和控制定义了一套简易的HiSignalling通信控制协议数据帧格式如下表所示并提供相关参考代码大家也可以根据自己的需要使用其他协议。
| 帧头2Byte | Payload Len (2Byte) | payload | 帧尾1Byte | CRC32(4Byte) |
|---|---|---|---|---|
| 0xAA,0x55 | | | 0xFF | CRC32 |
例如一组数据帧为AA5500020003FF8ED2BEDF (十六进制不区分大小写)
- 0AA55: 帧头
- 0002 Payload Len
- 0003: Payload
- FF: 帧尾
- 8ED2BEDF: CRC32校验码
## 软件介绍
- 注意这里需要跟Taurus同时使用Taurus软件介绍详情可以参考串口互联server端。
- 1.代码目录结构及相应接口功能介绍
- UART API
| API | 接口说明 |
| ------------------------------------------------------------ | ------------------------ |
| unsigned int UartInit(WifiIotUartIdx id, const WifiIotUartAttribute *param, const WifiIotUartExtraAttr *extraAttr); | 初始化配置一个UART设备 |
| int UartRead(WifiIotUartIdx id, unsigned char *data, unsigned int dataLen) | 从UART设备中读取数据 |
| int UartWrite(WifiIotUartIdx id, const unsigned char *data, unsigned int dataLen) | 将数据写入UART设备 |
- 2.工程编译
- 将源码./vendor/hisilicon/hispark_pegasus/demo目录下的interconnection_client_demo整个文件夹及内容复制到源码./applications/sample/wifi-iot/app/下,如图。
```
.
└── applications
└── sample
└── wifi-iot
└── app
└──interconnection_client_demo
└── 代码
```
- 在hisignalling.h文件中如果是想使用硬件扩展板请将BOARD_SELECT_IS_EXPANSION_BOARD这个宏打开如果是想使用Robot板请将BOARD_SELECT_IS_ROBOT_BOARD 这个宏打开。
```
/**
* @brief Adapter plate selection
* 使用时选择打开宏,使用外设扩展板打开#define BOARD_SELECT_IS_EXPANSION_BOARD这个宏
* 使用Robot板打开#define BOARD_SELECT_IS_ROBOT_BOARD这个宏
**/
//#define BOARD_SELECT_IS_ROBOT_BOARD
#define BOARD_SELECT_IS_EXPANSION_BOARD
#ifdef BOARD_SELECT_IS_EXPANSION_BOARD
#define EXPANSION_BOARD
#else
#define ROBOT_BOARD
#endif
```
- 修改源码./applications/sample/wifi-iot/app/BUILD.gn文件在features字段中增加索引使目标模块参与编译。features字段指定业务模块的路径和目标,features字段配置如下。
```
import("//build/lite/config/component/lite_component.gni")
lite_component("app") {
features = [
"interconnection_client_demo:interconnectionClientDemo",
]
}
```
- 工程相关配置完成后,然后编译。
- 3.烧录
- 编译成功后点击DevEco Home->配置工程->hi3861->upload_port->选择对应串口端口号->选择upload_protocol->选择hiburn-serial->点击save保存在保存成功后点击upload进行烧录出现connecting, please reset device..字样复位开发板等待烧录完成。
- 烧录成功后再次点击Hi3861核心板上的“RST”复位键此时开发板的系统会运行起来。运行结果:打开串口工具,可以看到如下打印,同时3861主板灯闪亮一下。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E4%BA%92%E8%81%94/6.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E4%BA%92%E8%81%94/7.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E4%BA%92%E8%81%94/8.jpg)

@ -0,0 +1,144 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <hi_stdlib.h>
#include <hisignalling_protocol.h>
#include <hi_uart.h>
#include <app_demo_uart.h>
#include <iot_uart.h>
#include <hi_gpio.h>
#include <hi_io.h>
#include "iot_gpio_ex.h"
#include "ohos_init.h"
#include "cmsis_os2.h"
UartDefConfig uartDefConfig = {0};
static void Uart1GpioCOnfig(void)
{
#ifdef ROBOT_BOARD
IoSetFunc(HI_IO_NAME_GPIO_5, IOT_IO_FUNC_GPIO_5_UART1_RXD);
IoSetFunc(HI_IO_NAME_GPIO_6, IOT_IO_FUNC_GPIO_6_UART1_TXD);
/* IOT_BOARD */
#elif defined (EXPANSION_BOARD)
IoSetFunc(HI_IO_NAME_GPIO_0, IOT_IO_FUNC_GPIO_0_UART1_TXD);
IoSetFunc(HI_IO_NAME_GPIO_1, IOT_IO_FUNC_GPIO_1_UART1_RXD);
#endif
}
int SetUartRecvFlag(UartRecvDef def)
{
if (def == UART_RECV_TRUE) {
uartDefConfig.g_uartReceiveFlag = HI_TRUE;
} else {
uartDefConfig.g_uartReceiveFlag = HI_FALSE;
}
return uartDefConfig.g_uartReceiveFlag;
}
int GetUartConfig(UartDefType type)
{
int receive = 0;
switch (type) {
case UART_RECEIVE_FLAG:
receive = uartDefConfig.g_uartReceiveFlag;
break;
case UART_RECVIVE_LEN:
receive = uartDefConfig.g_uartLen;
break;
default:
break;
}
return receive;
}
void ResetUartReceiveMsg(void)
{
(void)memset_s(uartDefConfig.g_receiveUartBuff, sizeof(uartDefConfig.g_receiveUartBuff),
0x0, sizeof(uartDefConfig.g_receiveUartBuff));
}
unsigned char *GetUartReceiveMsg(void)
{
return uartDefConfig.g_receiveUartBuff;
}
static hi_void *UartDemoTask(char *param)
{
hi_u8 uartBuff[UART_BUFF_SIZE] = {0};
hi_unref_param(param);
printf("Initialize uart demo successfully, please enter some datas via DEMO_UART_NUM port...\n");
Uart1GpioCOnfig();
for (;;) {
uartDefConfig.g_uartLen = IoTUartRead(DEMO_UART_NUM, uartBuff, UART_BUFF_SIZE);
if ((uartDefConfig.g_uartLen > 0) && (uartBuff[0] == 0xaa) && (uartBuff[1] == 0x55)) {
if (GetUartConfig(UART_RECEIVE_FLAG) == HI_FALSE) {
(void)memcpy_s(uartDefConfig.g_receiveUartBuff, uartDefConfig.g_uartLen,
uartBuff, uartDefConfig.g_uartLen);/*uartBuff中的信息放到uartDefConfig.g_receiveUartBuff*/
(void)SetUartRecvFlag(UART_RECV_TRUE);
}
}
printf("len:%d\n", uartDefConfig.g_uartLen);
for (int i = 0; i<uartDefConfig.g_uartLen; i++)
{
if(i <= 2)
{
printf("0x%x ", uartBuff[i]);
}
else
{
printf("%c ", uartBuff[i]);
}
}
TaskMsleep(20); /* 20:sleep 20ms */
}
return HI_NULL;
}
/*
* This demo simply shows how to read datas from UART2 port and then echo back.
*/
hi_void UartTransmit(hi_void)
{
hi_u32 ret = 0;
IotUartAttribute uartAttr = {
.baudRate = 115200, /* baudRate: 115200 */
.dataBits = 8, /* dataBits: 8bits */
.stopBits = 1, /* stop bit */
.parity = 0,
};
/* Initialize uart driver */
ret = IoTUartInit(DEMO_UART_NUM, &uartAttr);
if (ret != HI_ERR_SUCCESS) {
printf("Failed to init uart! Err code = %d\n", ret);
return;
}
/* Create a task to handle uart communication */
osThreadAttr_t attr = {0};
attr.stack_size = UART_DEMO_TASK_STAK_SIZE;
attr.priority = UART_DEMO_TASK_PRIORITY;
attr.name = (hi_char*)"uart demo";
if (osThreadNew((osThreadFunc_t)UartDemoTask, NULL, &attr) == NULL) {
printf("Falied to create uart demo task!\n");
}
}
SYS_RUN(UartTransmit);

@ -0,0 +1,48 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APP_DEMO_UART_H
#define APP_DEMO_UART_H
#define UART_BUFF_SIZE 1024
#define WRITE_BY_INT
#define UART_DEMO_TASK_STAK_SIZE 2048
#define UART_DEMO_TASK_PRIORITY 25
#define DEMO_UART_NUM HI_UART_IDX_1
typedef enum {
UART_RECEIVE_FLAG = 0,
UART_RECVIVE_LEN,
UART_SEND_FLAG = 2,
UART_SEND_LEN
}UartDefType;
typedef enum {
UART_RECV_TRUE = 0,
UART_RECV_FALSE,
}UartRecvDef;
typedef struct {
unsigned int uartChannel;
unsigned char g_receiveUartBuff[UART_BUFF_SIZE];
int g_uartReceiveFlag;
int g_uartLen;
}UartDefConfig;
int SetUartRecvFlag(UartRecvDef def);
int GetUartConfig(UartDefType type);
void ResetUartReceiveMsg(void);
unsigned char *GetUartReceiveMsg(void);
#endif

@ -0,0 +1,45 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "iot_errno.h"
#include "hi_gpio.h"
#include "hi_io.h"
#include "hi_task.h"
#include "hi_types_base.h"
#include "iot_gpio_ex.h"
unsigned int IoSetPull(unsigned int id, IotIoPull val)
{
if (id >= HI_GPIO_IDX_MAX) {
return IOT_FAILURE;
}
return hi_io_set_pull((hi_io_name)id, (hi_io_pull)val);
}
unsigned int IoSetFunc(unsigned int id, unsigned char val) /* 复用功能 */
{
if (id >= HI_GPIO_IDX_MAX) {
return IOT_FAILURE;
}
return hi_io_set_func((hi_io_name)id, val);
}
unsigned int TaskMsleep(unsigned int ms)
{
if (ms <= 0) {
return IOT_FAILURE;
}
return hi_sleep((hi_u32)ms);
}

@ -0,0 +1,286 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <hi_types_base.h>
#include <hi_early_debug.h>
#include <hi_stdlib.h>
#include <hi_uart.h>
#include <hi_task.h>
#include <app_demo_uart.h>
#include <iot_uart.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio_ex.h"
#include "hi_io.h"
#include "iot_gpio.h"
#include "hisignalling_protocol.h"
#define LED_TEST_GPIO 9
#define LED_INTERVAL_TIME_US 300000
hi_u8 g_sendUartBuff[UART_BUFF_SIZE];
UartDefConfig recConfig = {0};
/*
* crc32 Verification implementation
*/
static const unsigned int crc32table[] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL,
0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,
0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL,
0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,
0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L,
0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L,
0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L,
0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,
0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL,
0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L,
0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,
0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL,
0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,
0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L,
0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L,
0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,
0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL,
0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L,
0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL,
0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L,
0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL,
0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L,
0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L,
0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L,
0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,
0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L,
0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL,
0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L,
0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,
0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL,
0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,
0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,
0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL,
0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L,
0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L,
0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,
0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L,
0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
};
static unsigned int crc32(const unsigned char *buf, unsigned int len)
{
unsigned int i, crc = 0xFFFFFFFF;
for (i = 0; i < len; i++) {
crc = crc32table[(crc ^ buf[i]) & 0xff] ^ (crc >> 8); /* 8: right move 8 bit */
}
return crc ^ 0xFFFFFFFF;
}
/* Log level look up table */
static const char *hisignallingLevelNames[] = {
"TRACE",
"DEBUG",
"INFO",
"WARN",
"ERROR",
"FATAL"
};
/* get hisignaling log level */
const char *HisignallingLevelNum (HisignallingLogType hisignallingLevel)
{
if (hisignallingLevel >= HISIGNALLING_LEVEL_MAX) {
return "NULL";
} else {
return hisignallingLevelNames[hisignallingLevel];
}
}
#define RIGHT_MOVE_8_BIT (8)
#define RIGHT_MOVE_16_BIT (16)
#define RIGHT_MOVE_24_BIT (24)
/* hisignal Hi3861 message package */
static hi_u32 HisignallingDataPackage(HisignallingProtocalType *buf, hi_u32 len, hi_u8 *hisignallingDataBuf)
{
hi_u32 crcCheckSend = 0;
hi_u32 packageLen = 0;
memcpy_s(hisignallingDataBuf, HISGNALLING_MSG_FRAME_HEADER_LEN,
buf->frameHeader, HISGNALLING_MSG_FRAME_HEADER_LEN);
memcpy_s(&hisignallingDataBuf[HISGNALLING_MSG_FRAME_HEADER_LEN],
len, buf->hisignallingMsgBuf, len);
memcpy_s(&hisignallingDataBuf[HISGNALLING_MSG_FRAME_HEADER_LEN + len],
HISIGNALLING_MSG_HEADER_LEN, &(buf->endOfFrame), HISIGNALLING_MSG_HEADER_LEN);
crcCheckSend = crc32(hisignallingDataBuf, (len + HISIGNALLING_MSG_HEADER_TAIL_LEN));
hisignallingDataBuf[len + HISIGNALLING_MSG_HEADER_TAIL_LEN] =
(hi_u8) ((crcCheckSend & 0xff000000)>>RIGHT_MOVE_24_BIT);
hisignallingDataBuf[len + HISIGNALLING_MSG_HEADER_TAIL_LEN + 1] = /* 1: addr offset */
(hi_u8) ((crcCheckSend & 0x00ff0000)>>RIGHT_MOVE_16_BIT);
hisignallingDataBuf[len + HISIGNALLING_MSG_HEADER_TAIL_LEN + 2] = /* 2: addr offset */
(hi_u8) ((crcCheckSend & 0x0000ff00)>>RIGHT_MOVE_8_BIT);
hisignallingDataBuf[len + HISIGNALLING_MSG_HEADER_TAIL_LEN + 3] = /* 3: addr offset */
(hi_u8)crcCheckSend;
packageLen = len + HISIGNALLING_MSG_HEADER_TAIL_LEN + HISGNALLING_MSG_CRC32_LEN;
return packageLen;
}
/* hisignal Hi3861 message recevice */
HisignallingErrorType HisignallingMsgReceive(hi_u8 *buf, hi_u32 len)
{
hi_u32 crcCheckReceived = 0;
unsigned char testBuff[7] = {0xaa, 0x55, 0x0, 0x2, 0x0, 0x8, 0xff};
if (buf == HI_NULL && len > 0) {
HISIGNALLING_LOG_FATAL("received buf is null");
return HISGNALLING_RET_VAL_MAX;
}
printf("length:%u\n", len);
/* 校验crc */
if (len > HISGNALLING_MSG_CRC32_LEN) {
crcCheckReceived = crc32(buf, len - HISGNALLING_MSG_CRC32_LEN);
if (((hi_u8)((crcCheckReceived & 0xff000000)>>RIGHT_MOVE_24_BIT) != buf[len - 4]) && /* 4: addr offset */
((hi_u8)((crcCheckReceived & 0x00ff0000)>>RIGHT_MOVE_16_BIT) != buf[len - 3]) && /* 3: addr offset */
((hi_u8)((crcCheckReceived & 0x0000ff00)>>RIGHT_MOVE_8_BIT) != buf[len - 2]) && /* 2: addr offset */
((hi_u8)crcCheckReceived != buf[len - 1])) {
HISIGNALLING_LOG_ERROR("<Hi3861>: crc32 Verification failed!");
HISIGNALLING_LOG_ERROR("<Hi3861>:crc_4=0x%x, crc_3=0x%x, crc_2=0x%x, crc_1=0x%x",
buf[len - 4], buf[len - 3], buf[len - 2], buf[len - 1]); /* 4,3,2,1 addr offset */
return HISIGNALLING_RET_VAL_ERROR;
}
}
IoTGpioSetOutputVal(LED_TEST_GPIO, 0);
usleep(LED_INTERVAL_TIME_US);
IoTGpioSetOutputVal(LED_TEST_GPIO, 1);
usleep(LED_INTERVAL_TIME_US);
/* 输出回显收到的数据 */
/*if ((buf[0] == HISIGNALLING_MSG_FRAME_HEADER_1) && (buf[1] == HISIGNALLING_MSG_FRAME_HEADER_2)) {
for (int i = 0; i < len; i++) {
HISIGNALLING_LOG_INFO("0x%x", buf[i]);
}
}*/
return HISIGNALLING_RET_VAL_CORRECT;
}
/* hisignal Hi3861 message send */
hi_u32 HisignallingMsgSend(char *buf, hi_u32 dataLen)
{
HisignallingProtocalType hisignallingMsg = {0};
hi_u8 hisignallingSendBuf[HISIGNALLING_MSG_BUFF_LEN] = {0};
hi_u32 hisignallingPackageLen = 0;
hi_u32 writeDataLen = 0;
hisignallingMsg.frameHeader[0]= HISIGNALLING_MSG_FRAME_HEADER_1;
hisignallingMsg.frameHeader[1]= HISIGNALLING_MSG_FRAME_HEADER_2;
(void)memcpy_s(hisignallingMsg.hisignallingMsgBuf, dataLen, buf, dataLen);
hisignallingMsg.endOfFrame = HISIGNALLING_MSG_FRAME_TAIL;
hisignallingPackageLen = HisignallingDataPackage(&hisignallingMsg, dataLen, hisignallingSendBuf);
if (!hisignallingPackageLen) {
HISIGNALLING_LOG_ERROR("hisignaling_data_package failed\r\n");
return HI_ERR_FAILURE;
}
if (*hisignallingSendBuf == NULL) {
HISIGNALLING_LOG_ERROR("hisignal send buf is null!\r\n");
return HI_ERR_FAILURE;
}
writeDataLen = IoTUartWrite(HI_UART_IDX_1, hisignallingSendBuf, hisignallingPackageLen);
if (!writeDataLen) {
HISIGNALLING_LOG_ERROR("hi_uart_write failed\r\n");
return HI_ERR_FAILURE;
}
return HI_ERR_SUCCESS;
}
int SetUartReceiveFlag(void)
{
return recConfig.g_uartReceiveFlag;
}
hi_void *HisignallingMsgHandle(char *param)
{
unsigned char *recBuff = NULL;
int len;
while (1) {
/*g_sendUartBuff清零*/
(void)memset_s(g_sendUartBuff, sizeof(g_sendUartBuff) / sizeof(g_sendUartBuff[0]),
0x0, sizeof(g_sendUartBuff)/sizeof(g_sendUartBuff[0]));
/*GetUartConfig得到data的flag和length*/
if (GetUartConfig(UART_RECEIVE_FLAG) == HI_TRUE) {
/* 接收数据 */
HisignallingMsgReceive(GetUartReceiveMsg(), GetUartConfig(UART_RECVIVE_LEN));
/* 回显数据组包 */
if (GetUartConfig(UART_RECVIVE_LEN) > (HISGNALLING_MSG_CRC32_LEN + HISIGNALLING_MSG_HEADER_TAIL_LEN)) {
len = GetUartConfig(UART_RECVIVE_LEN);
recBuff = GetUartReceiveMsg();
for (int i = 0; i < len ; i++ ){
HISIGNALLING_LOG_INFO("0x%x", recBuff[i]);
}
printf("end\n");
(void)memcpy_s(g_sendUartBuff,
(GetUartConfig(UART_RECVIVE_LEN) - HISGNALLING_MSG_CRC32_LEN - HISIGNALLING_MSG_HEADER_TAIL_LEN),
&recBuff[HISGNALLING_MSG_FRAME_HEADER_LEN],
(GetUartConfig(UART_RECVIVE_LEN) - HISGNALLING_MSG_CRC32_LEN - HISIGNALLING_MSG_HEADER_TAIL_LEN));
/* 接收到Hi3516DV300数据后发送回显 */
HisignallingMsgSend(g_sendUartBuff,
(GetUartConfig(UART_RECVIVE_LEN) - HISGNALLING_MSG_CRC32_LEN - HISIGNALLING_MSG_HEADER_TAIL_LEN));
}
(void)SetUartRecvFlag(UART_RECV_FALSE);
ResetUartReceiveMsg();
}
TaskMsleep(HISGNALLING_FREE_TASK_TIME);
}
}
hi_u32 HisignalingMsgTask(hi_void)
{
hi_u32 ret = 0;
IoTGpioInit(LED_TEST_GPIO);
IoTGpioSetDir(LED_TEST_GPIO, IOT_GPIO_DIR_OUT);
osThreadAttr_t hisignallingAttr = {0};
hisignallingAttr.stack_size = HISIGNALLING_MSG_TASK_STACK_SIZE;
hisignallingAttr.priority = HISIGNALLING_MSG_TASK_PRIO;
hisignallingAttr.name = (hi_char*)"hisignal msg task";
if (osThreadNew((osThreadFunc_t)HisignallingMsgHandle, NULL, &hisignallingAttr) == NULL) {
HISIGNALLING_LOG_ERROR("Failed to create hisignaling msg task\r\n");
return HI_ERR_FAILURE;
}
return HI_ERR_SUCCESS;
}
//SYS_RUN(HisignalingMsgTask);

@ -0,0 +1,207 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HISIGNALLING_PROTOCOL_H
#define HISIGNALLING_PROTOCOL_H
#include <hi_types_base.h>
#include <stdarg.h>
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
/**
* @brief : hisignalling Macro definition
*/
#define HISIGNALLING_MSG_HEADER_LEN (1)
#define HISGNALLING_MSG_FRAME_HEADER_LEN (2)
#define HISIGNALLING_MSG_HEADER_TAIL_LEN (3)
#define HISGNALLING_MSG_CRC32_LEN (4)
#define HISIGNALLING_MSG_PAYLOAD_INDEX (5)
#define HISGNALLING_FREE_TASK_TIME (20)
#define HISIGNALLING_MSG_TASK_PRIO (28)
#define HISIGNALLING_UART_MSG_LEN (32)
#define HISIGNALLING_MSG_BUFF_LEN (512)
#define HISIGNALLING_MSG_TASK_STACK_SIZE (4096)
/* hisgnalling protocol frame header and tail */
#define HISIGNALLING_MSG_FRAME_HEADER_1 ((hi_u8)0xAA)
#define HISIGNALLING_MSG_FRAME_HEADER_2 ((hi_u8)0x55)
#define HISIGNALLING_MSG_FRAME_TAIL ((hi_u8)0xFF)
/**
* @brief Adapter plate selection
* 使使#define BOARD_SELECT_IS_EXPANSION_BOARD
* 使Robot#define BOARD_SELECT_IS_ROBOT_BOARD#define BOARD_SELECT_IS_EXPANSION_BOARD
**/
#define BOARD_SELECT_IS_EXPANSION_BOARD
#ifdef BOARD_SELECT_IS_EXPANSION_BOARD
#define EXPANSION_BOARD
#else
#define ROBOT_BOARD
#endif
/**
* @brief:this defines for the log module, and HISIGNALING_LOG_TRACE/HISIGNALING_LOG_DEBUG...
* will not participate the compile in the release version
* */
typedef enum {
HISIGNALLING_LEVEL_TRACE = 0,
HISIGNALLING_LEVEL_DEBUG,
HISIGNALLING_LEVEL_INFO,
HISIGNALLING_LEVEL_WARN,
HISIGNALLING_LEVEL_ERROR,
HISIGNALLING_LEVEL_FATAL,
HISIGNALLING_LEVEL_MAX
} HisignallingLogType;
/**
* @brief: use this function to get the hisignalling log level name
*
* @parameter[in]:level, the level to get
*
* @return: the mapped level name
* */
const char *HisignallingLevelNum (HisignallingLogType hisignallingLevel);
/**
* @brief: this is a weak function ,and you could rewrite one
*
* @param fmt: same use as the fmt for printf
*
* @param unfixed: same use for printf
*
* @return: don't care about it
*
* @attention: and the components should not call this function directly, you'd better
*
* call HISIGNALING_LOG groups
*
* */
#define HISIGNALLING_PRINT(fmt, ...) \
do \
{ \
printf(fmt, ##__VA_ARGS__); \
} while (0)
#define HISIGNALLING_LOG(level, fmt, ...) \
do \
{ \
HISIGNALLING_PRINT("<%s>, <%s>, <%d> "fmt" \r\n", \
HisignallingLevelNum((level)), __FUNCTION__, __LINE__, ##__VA_ARGS__); \
} while (0)
#define HISIGNALLING_LOG_TRACE(fmt, ...) \
do \
{ \
HISIGNALLING_LOG (HISIGNALLING_LEVEL_TRACE, fmt, ##__VA_ARGS__); \
} while (0)
#define HISIGNALLING_LOG_DEBUG(fmt, ...) \
do \
{ \
HISIGNALLING_LOG (HISIGNALLING_LEVEL_DEBUG, fmt, ##__VA_ARGS__); \
} while (0)
#define HISIGNALLING_LOG_INFO(fmt, ...) \
do \
{ \
HISIGNALLING_LOG (HISIGNALLING_LEVEL_INFO, fmt, ##__VA_ARGS__); \
} while (0)
#define HISIGNALLING_LOG_WARN(fmt, ...) \
do \
{ \
HISIGNALLING_LOG (HISIGNALLING_LEVEL_WARN, fmt, ##__VA_ARGS__); \
} while (0)
#define HISIGNALLING_LOG_ERROR(fmt, ...) \
do \
{ \
HISIGNALLING_LOG (HISIGNALLING_LEVEL_ERROR, fmt, ##__VA_ARGS__); \
} while (0)
#define HISIGNALLING_LOG_FATAL(fmt, ...) \
do \
{ \
HISIGNALLING_LOG (HISIGNALLING_LEVEL_FATAL, fmt, ##__VA_ARGS__); \
} while (0)
/**
* @brief: use this hisignalling Transmission protocol frame format
*
* @param frameHeader: Transmission protocol frame header
*
* @param hisignallingMsgBuf: Transmission protocol frame buffer
*
* @param hisigallingMsgLen: Transmission protocol frame buffer len
*
* @param endOfFrame: Transmission protocol frame tail
*
* @param hisignallingCrc32Check: Transmission protocol crc32 check
*
* */
typedef struct {
hi_u8 frameHeader[HISGNALLING_MSG_FRAME_HEADER_LEN];
hi_u8 hisignallingMsgBuf[HISIGNALLING_MSG_BUFF_LEN];
hi_u32 hisigallingMsgLen;
hi_u8 endOfFrame;
hi_u32 hisignallingCrc32Check;
}HisignallingProtocalType;
/**
* @brief: use this hisignalling return type
*
* @param HISIGNALLING_RET_VAL_CORRECT: return type is correct
*
* @param HISIGNALLING_RET_VAL_ERROR: return type is error
*
* @param HISIGNALLING_RET_VAL_ERROR: return type is unknown type
* */
typedef enum {
HISIGNALLING_RET_VAL_CORRECT = 0,
HISIGNALLING_RET_VAL_ERROR,
HISGNALLING_RET_VAL_MAX
}HisignallingErrorType;
/**
* @brief: use this hisignalling sample:Access peripheral enumeration type
*
* @param MOTOR_GO_FORWARD: peripheral motor go forward
*
* @param MOTOR_GO_BACK: peripheral motor go back
*
* @param STEERING_ENGINE_MOVEMENT/STEERING_ENGINE_AND_MOTOR_MOVEMENT/STEERING_ENGINE_AND_MOTOR_STOP
* the same use for peripheral
* */
typedef enum {
MOTOR_GO_FORWARD = 0,
MOTOR_GO_BACK,
STEERING_ENGINE_MOVEMENT,
STEERING_ENGINE_AND_MOTOR_MOVEMENT,
STEERING_ENGINE_AND_MOTOR_STOP,
TRASH_CAN_LID_OPEN,
TRASH_CAN_LID_COLSE
}HisignallingDataType;
/**
* @brief:hisignalling protocal Function declaration
**/
hi_u32 hisignallingMsgTask(hi_void);
/**
* @brief:hisignalling uart message receive API
* @param buf: uart receive buffer
* @param len: uart receive buffer len
*/
HisignallingErrorType hisignallingMsgReceive(hi_u8 *buf, hi_u32 len);
/**
* @brief:hisignalling uart send API
* @param buf: uart message send buffer
* @param len: uart message send buffer len
*/
hi_u32 hisignallingMsgSend(hi_void *buf, hi_u32 dataLen);
int SetUartReceiveFlag(void);
#endif /* HISIGNALING_PROTOCOL_H */

@ -0,0 +1,394 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file iot_gpio_ex.h
*
* @brief Declares the extended GPIO interface functions.
*
* These functions are used for settings GPIO pulls and driver strength. \n
*
* @since 1.0
* @version 1.0
*/
#ifndef IOT_GPIO_EX_H
#define IOT_GPIO_EX_H
/**
* @brief Enumerates GPIO pull-up or pull-down settings.
*/
typedef enum {
/** No pull */
IOT_IO_PULL_NONE,
/** Pull-up */
IOT_IO_PULL_UP,
/** Pull-down */
IOT_IO_PULL_DOWN,
/** Maximum value */
IOT_IO_PULL_MAX,
} IotIoPull;
/**
* @ingroup iot_io
*
* GPIO pin ID. CNcomment:IOCNend
*/
typedef enum {
IOT_IO_NAME_GPIO_0, /* <GPIO0 */
IOT_IO_NAME_GPIO_1, /* <GPIO1 */
IOT_IO_NAME_GPIO_2, /* <GPIO2 */
IOT_IO_NAME_GPIO_3, /* <GPIO3 */
IOT_IO_NAME_GPIO_4, /* <GPIO4 */
IOT_IO_NAME_GPIO_5, /* <GPIO5 */
IOT_IO_NAME_GPIO_6, /* <GPIO6 */
IOT_IO_NAME_GPIO_7, /* <GPIO7 */
IOT_IO_NAME_GPIO_8, /* <GPIO8 */
IOT_IO_NAME_GPIO_9, /* <GPIO9 */
IOT_IO_NAME_GPIO_10, /* <GPIO10 */
IOT_IO_NAME_GPIO_11, /* <GPIO11 */
IOT_IO_NAME_GPIO_12, /* <GPIO12 */
IOT_IO_NAME_GPIO_13, /* <GPIO13 */
IOT_IO_NAME_GPIO_14, /* <GPIO14 */
IOT_IO_NAME_SFC_CSN, /* <SFC_CSN */
IOT_IO_NAME_SFC_IO1, /* <SFC_IO1 */
IOT_IO_NAME_SFC_IO2, /* <SFC_IO2 */
IOT_IO_NAME_SFC_IO0, /* <SFC_IO0 */
IOT_IO_NAME_SFC_CLK, /* <SFC_CLK */
IOT_IO_NAME_SFC_IO3, /* <SFC_IO3 */
IOT_IO_NAME_MAX,
} IotIoName;
/**
* @ingroup iot_io
*
* GPIO_0 pin function.CNcomment:GPIO_0CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_0_GPIO,
IOT_IO_FUNC_GPIO_0_UART1_TXD = 2,
IOT_IO_FUNC_GPIO_0_SPI1_CK,
IOT_IO_FUNC_GPIO_0_JTAG_TDO,
IOT_IO_FUNC_GPIO_0_PWM3_OUT,
IOT_IO_FUNC_GPIO_0_I2C1_SDA,
} IotIoFuncGpio0;
/**
* @ingroup iot_io
*
* GPIO_1 pin function.CNcomment:GPIO_1CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_1_GPIO,
IOT_IO_FUNC_GPIO_1_UART1_RXD = 2,
IOT_IO_FUNC_GPIO_1_SPI1_RXD,
IOT_IO_FUNC_GPIO_1_JTAG_TCK,
IOT_IO_FUNC_GPIO_1_PWM4_OUT,
IOT_IO_FUNC_GPIO_1_I2C1_SCL,
IOT_IO_FUNC_GPIO_1_BT_FREQ,
} IotIoFuncGpio1;
/**
* @ingroup iot_io
*
* GPIO_2 pin function.CNcomment:GPIO_2CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_2_GPIO,
IOT_IO_FUNC_GPIO_2_UART1_RTS_N = 2,
IOT_IO_FUNC_GPIO_2_SPI1_TXD,
IOT_IO_FUNC_GPIO_2_JTAG_TRSTN,
IOT_IO_FUNC_GPIO_2_PWM2_OUT,
IOT_IO_FUNC_GPIO_2_SSI_CLK = 7,
} IotIoFuncGpio2;
/**
* @ingroup iot_io
*
* GPIO_3 pin function.CNcomment:GPIO_3CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_3_GPIO,
IOT_IO_FUNC_GPIO_3_UART0_TXD,
IOT_IO_FUNC_GPIO_3_UART1_CTS_N,
IOT_IO_FUNC_GPIO_3_SPI1_CSN,
IOT_IO_FUNC_GPIO_3_JTAG_TDI,
IOT_IO_FUNC_GPIO_3_PWM5_OUT,
IOT_IO_FUNC_GPIO_3_I2C1_SDA,
IOT_IO_FUNC_GPIO_3_SSI_DATA,
} IotIoFuncGpio3;
/**
* @ingroup iot_io
*
* GPIO_4 pin function.CNcomment:GPIO_4CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_4_GPIO,
IOT_IO_FUNC_GPIO_4_UART0_RXD = 2,
IOT_IO_FUNC_GPIO_4_JTAG_TMS = 4,
IOT_IO_FUNC_GPIO_4_PWM1_OUT,
IOT_IO_FUNC_GPIO_4_I2C1_SCL,
} IotIoFuncGpio4;
/**
* @ingroup iot_io
*
* GPIO_5 pin function.CNcomment:GPIO_5CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_5_GPIO,
IOT_IO_FUNC_GPIO_5_UART1_RXD = 2,
IOT_IO_FUNC_GPIO_5_SPI0_CSN,
IOT_IO_FUNC_GPIO_5_PWM2_OUT = 5,
IOT_IO_FUNC_GPIO_5_I2S0_MCLK,
IOT_IO_FUNC_GPIO_5_BT_STATUS,
} IotIoFuncGpio5;
/**
* @ingroup iot_io
*
* GPIO_6 pin function.CNcomment:GPIO_6CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_6_GPIO,
IOT_IO_FUNC_GPIO_6_UART1_TXD = 2,
IOT_IO_FUNC_GPIO_6_SPI0_CK,
IOT_IO_FUNC_GPIO_6_PWM3_OUT = 5,
IOT_IO_FUNC_GPIO_6_I2S0_TX,
IOT_IO_FUNC_GPIO_6_COEX_SWITCH,
} IotIoFuncGpio6;
/**
* @ingroup iot_io
*
* GPIO_7 pin function.CNcomment:GPIO_7CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_7_GPIO,
IOT_IO_FUNC_GPIO_7_UART1_CTS_N = 2,
IOT_IO_FUNC_GPIO_7_SPI0_RXD,
IOT_IO_FUNC_GPIO_7_PWM0_OUT = 5,
IOT_IO_FUNC_GPIO_7_I2S0_BCLK,
IOT_IO_FUNC_GPIO_7_BT_ACTIVE,
} IotIoFuncGpio7;
/**
* @ingroup iot_io
*
* GPIO_8 pin function.CNcomment:GPIO_8CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_8_GPIO,
IOT_IO_FUNC_GPIO_8_UART1_RTS_N = 2,
IOT_IO_FUNC_GPIO_8_SPI0_TXD,
IOT_IO_FUNC_GPIO_8_PWM1_OUT = 5,
IOT_IO_FUNC_GPIO_8_I2S0_WS,
IOT_IO_FUNC_GPIO_8_WLAN_ACTIVE,
} IotIoFuncGpio8;
/**
* @ingroup iot_io
*
* GPIO_9 pin function.CNcomment:GPIO_9CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_9_GPIO,
IOT_IO_FUNC_GPIO_9_I2C0_SCL,
IOT_IO_FUNC_GPIO_9_UART2_RTS_N,
IOT_IO_FUNC_GPIO_9_SDIO_D2,
IOT_IO_FUNC_GPIO_9_SPI0_TXD,
IOT_IO_FUNC_GPIO_9_PWM0_OUT,
IOT_IO_FUNC_GPIO_9_I2S0_MCLK = 7,
} IotIoFuncGpio9;
/**
* @ingroup iot_io
*
* GPIO_10 pin function.CNcomment:GPIO_10CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_10_GPIO,
IOT_IO_FUNC_GPIO_10_I2C0_SDA,
IOT_IO_FUNC_GPIO_10_UART2_CTS_N,
IOT_IO_FUNC_GPIO_10_SDIO_D3,
IOT_IO_FUNC_GPIO_10_SPI0_CK,
IOT_IO_FUNC_GPIO_10_PWM1_OUT,
IOT_IO_FUNC_GPIO_10_I2S0_TX = 7,
} IotIoFuncGpio10;
/**
* @ingroup iot_io
*
* GPIO_11 pin function.CNcomment:GPIO_11CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_11_GPIO,
IOT_IO_FUNC_GPIO_11_UART2_TXD = 2,
IOT_IO_FUNC_GPIO_11_SDIO_CMD,
IOT_IO_FUNC_GPIO_11_SPI0_RXD,
IOT_IO_FUNC_GPIO_11_PWM2_OUT,
IOT_IO_FUNC_GPIO_11_RF_TX_EN_EXT,
IOT_IO_FUNC_GPIO_11_I2S0_RX,
} IotIoFuncGpio11;
/**
* @ingroup iot_io
*
* GPIO_12 pin function.CNcomment:GPIO_12CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_12_GPIO,
IOT_IO_FUNC_GPIO_12_UART2_RXD = 2,
IOT_IO_FUNC_GPIO_12_SDIO_CLK,
IOT_IO_FUNC_GPIO_12_SPI0_CSN,
IOT_IO_FUNC_GPIO_12_PWM3_OUT,
IOT_IO_FUNC_GPIO_12_RF_RX_EN_EXT,
IOT_IO_FUNC_GPIO_12_I2S0_BCLK,
} IotIoFuncGpio12;
/**
* @ingroup iot_io
*
* GPIO_13 pin function.CNcomment:GPIO_13CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_13_SSI_DATA,
IOT_IO_FUNC_GPIO_13_UART0_TXD,
IOT_IO_FUNC_GPIO_13_UART2_RTS_N,
IOT_IO_FUNC_GPIO_13_SDIO_D0,
IOT_IO_FUNC_GPIO_13_GPIO,
IOT_IO_FUNC_GPIO_13_PWM4_OUT,
IOT_IO_FUNC_GPIO_13_I2C0_SDA,
IOT_IO_FUNC_GPIO_13_I2S0_WS,
} IotIoFuncGpio13;
/**
* @ingroup iot_io
*
* GPIO_14 pin function.CNcomment:GPIO_14CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_14_SSI_CLK,
IOT_IO_FUNC_GPIO_14_UART0_RXD,
IOT_IO_FUNC_GPIO_14_UART2_CTS_N,
IOT_IO_FUNC_GPIO_14_SDIO_D1,
IOT_IO_FUNC_GPIO_14_GPIO,
IOT_IO_FUNC_GPIO_14_PWM5_OUT,
IOT_IO_FUNC_GPIO_14_I2C0_SCL,
} IotIoFuncGpio14;
/**
* @ingroup iot_io
*
* SFC_CSN pin function.CNcomment:SFC_CSNCNend
*/
typedef enum {
IOT_IO_FUNC_SFC_CSN_SFC_CSN,
IOT_IO_FUNC_SFC_CSN_SDIO_D2,
IOT_IO_FUNC_SFC_CSN_GPIO9,
IOT_IO_FUNC_SFC_CSN_SPI0_TXD = 4,
} IotIoFuncSfcCsn;
/**
* @ingroup iot_io
*
* SFC_DO pin function.CNcomment:SFC_DOCNend
*/
typedef enum {
IOT_IO_FUNC_SFC_IO_1_SFC_DO,
IOT_IO_FUNC_SFC_IO_1_SDIO_D3,
IOT_IO_FUNC_SFC_IO_1_GPIO10,
IOT_IO_FUNC_SFC_IO_1_SPI0_CK = 4,
} IotIoFuncSfcIo1;
/**
* @ingroup iot_io
*
* SFC_WPN pin function.CNcomment:SFC_WPNCNend
*/
typedef enum {
IOT_IO_FUNC_SFC_IO_2_SFC_WPN,
IOT_IO_FUNC_SFC_IO_2_SDIO_CMD,
IOT_IO_FUNC_SFC_IO_2_GPIO11,
IOT_IO_FUNC_SFC_IO_2_RF_TX_EN_EXT,
IOT_IO_FUNC_SFC_IO_2_SPI0_RXD,
} IotIoFuncSfcIo2;
/**
* @ingroup iot_io
*
* SFC_DI pin function.CNcomment:SFC_DICNend
*/
typedef enum {
IOT_IO_FUNC_SFC_IO_0_SFC_DI,
IOT_IO_FUNC_SFC_IO_0_SDIO_CLK,
IOT_IO_FUNC_SFC_IO_0_GPIO12,
IOT_IO_FUNC_SFC_IO_0_RF_RX_EN_EXT,
IOT_IO_FUNC_SFC_IO_0_SPI0_CSN,
} IotIoFuncSfcIo0;
/**
* @ingroup iot_io
*
* SFC_CLK pin function.CNcomment:SFC_CLKCNend
*/
typedef enum {
IOT_IO_FUNC_SFC_CLK_SFC_CLK,
IOT_IO_FUNC_SFC_CLK_SDIO_D0,
IOT_IO_FUNC_SFC_CLK_GPIO13,
IOT_IO_FUNC_SFC_CLK_SSI_DATA = 4,
} IotIoFuncSfcClk;
/**
* @ingroup iot_io
*
* SFC_HOLDN pin function.CNcomment:SFC_HOLDNCNend
*/
typedef enum {
IOT_IO_FUNC_SFC_IO_3_SFC_HOLDN,
IOT_IO_FUNC_SFC_IO_3_SDIO_D1,
IOT_IO_FUNC_SFC_IO_3_GPIO14,
IOT_IO_FUNC_SFC_IO_3_SSI_CLK = 4,
} IotIoFuncSfcIo3;
/**
* @ingroup iot_io
*
* I/O drive capability.CNcomment:IOCNend
* Note: The HI_IO_NAME_GPIO_0~HI_IO_NAME_GPIO_11 and HI_IO_NAME_GPIO_13~HI_IO_NAME_GPIO_14 driver capabilities are
* optional.The value range is HI_IO_DRIVER_STRENGTH_0~HI_IO_DRIVER_STRENGTH_3, and the other I/O ranges are
* HI_IO_DRIVER_STRENGTH_0~HI_IO_DRIVER_STRENGTH_7.CNcomment::HI_IO_NAME_GPIO_0~HI_IO_NAME_GPIO_11
* HI_IO_NAME_GPIO_13~HI_IO_NAME_GPIO_14HI_IO_DRIVER_STRENGTH_0~HI_IO_DRIVER_STRENGTH_3
* IOHI_IO_DRIVER_STRENGTH_0~HI_IO_DRIVER_STRENGTH_7CNend
*/
typedef enum {
IOT_IO_DRIVER_STRENGTH_0 = 0, /* <Drive strength level 0 (highest).CNcomment:驱动能力0级驱动能力最高CNend */
IOT_IO_DRIVER_STRENGTH_1, /* <Drive strength level 1.CNcomment:驱动能力1级CNend */
IOT_IO_DRIVER_STRENGTH_2, /* <Drive strength level 2.CNcomment:驱动能力2级CNend */
IOT_IO_DRIVER_STRENGTH_3, /* <Drive strength level 3.CNcomment:驱动能力3级CNend */
IOT_IO_DRIVER_STRENGTH_4, /* <Drive strength level 4.CNcomment:驱动能力4级CNend */
IOT_IO_DRIVER_STRENGTH_5, /* <Drive strength level 5.CNcomment:驱动能力5级CNend */
IOT_IO_DRIVER_STRENGTH_6, /* <Drive strength level 6.CNcomment:驱动能力6级CNend */
IOT_IO_DRIVER_STRENGTH_7, /* <Drive strength level 7 (lowest).CNcomment:驱动能力7级驱动能力最低CNend */
IOT_IO_DRIVER_STRENGTH_MAX,
} IotIoDriverStrength;
unsigned int IoSetPull(unsigned int id, IotIoPull val);
unsigned int IoSetFunc(unsigned int id, unsigned char val);
unsigned int TaskMsleep(unsigned int ms);
#endif
/** @} */

@ -0,0 +1,22 @@
# Copyright (c) 2020-2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("led_example") {
sources = [ "led_example.c" ]
include_dirs = [
"//utils/native/lite/include",
"//kernel/liteos_m/kal/cmsis",
"//base/iot_hardware/peripheral/interfaces/kits",
]
}

@ -0,0 +1,83 @@
/*
* Copyright (c) 2020-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#define LED_INTERVAL_TIME_US 300000
#define LED_TASK_STACK_SIZE 512
#define LED_TASK_PRIO 25
#define LED_TEST_GPIO 9 // for hispark_pegasus
enum LedState {
LED_ON = 0,
LED_OFF,
LED_SPARK,
};
enum LedState g_ledState = LED_SPARK;
static void *LedTask(const char *arg)
{
(void)arg;
while (1) {
switch (g_ledState) {
case LED_ON:
IoTGpioSetOutputVal(LED_TEST_GPIO, 1);
usleep(LED_INTERVAL_TIME_US);
break;
case LED_OFF:
IoTGpioSetOutputVal(LED_TEST_GPIO, 0);
usleep(LED_INTERVAL_TIME_US);
break;
case LED_SPARK:
IoTGpioSetOutputVal(LED_TEST_GPIO, 0);
usleep(LED_INTERVAL_TIME_US);
IoTGpioSetOutputVal(LED_TEST_GPIO, 1);
usleep(LED_INTERVAL_TIME_US);
break;
default:
usleep(LED_INTERVAL_TIME_US);
break;
}
}
return NULL;
}
static void LedExampleEntry(void)
{
osThreadAttr_t attr;
IoTGpioInit(LED_TEST_GPIO);
IoTGpioSetDir(LED_TEST_GPIO, IOT_GPIO_DIR_OUT);
attr.name = "LedTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = LED_TASK_STACK_SIZE;
attr.priority = LED_TASK_PRIO;
if (osThreadNew((osThreadFunc_t)LedTask, NULL, &attr) == NULL) {
printf("[LedExample] Failed to create LedTask!\n");
}
}
SYS_RUN(LedExampleEntry);

@ -0,0 +1,40 @@
# Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("AppDemoIot") {
sources = [
"app_demo_iot.c",
"cjson_init.c",
"iot_hmac.c",
"iot_log.c",
"iot_main.c",
"iot_profile.c",
"iot_sta.c",
"hal_iot_gpio_ex.c",
]
include_dirs = [
"./",
"//utils/native/lite/include",
"//kernel/liteos_m/kal/cmsis",
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/lwip_sack/include/lwip",
"//third_party/cJSON",
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/mbedtls/include/mbedtls",
"//foundation/communication/wifi_lite/interfaces/wifiservice",
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/paho.mqtt.c/include/mqtt",
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/libcoap/include/coap2",
]
defines = [ "WITH_LWIP" ]
}

@ -0,0 +1,226 @@
# 腾讯云的微信小程序开发及Hi3861板端互联
## 硬件环境搭建
- 硬件要求Hi3861V100核心板、扩展板硬件搭建如下图所示。
- [Hi3861V100核心板参考HiSpark_WiFi_IoT智能开发套件_原理图硬件资料\原理图\HiSpark_WiFi-IoT_Hi3861_CH340G_VER.B.pdf](http://gitee.com/hihope_iot/embedded-race-hisilicon-track-2022/blob/master/%E7%A1%AC%E4%BB%B6%E8%B5%84%E6%96%99/HiSpark_WiFi_IoT%E6%99%BA%E8%83%BD%E5%AE%B6%E5%B1%85%E5%BC%80%E5%8F%91%E5%A5%97%E4%BB%B6_%E5%8E%9F%E7%90%86%E5%9B%BE.rar)
- [扩展板参考HiSpark_WiFi_IoT智能开发套件_原理图硬件资料\原理图\HiSpark_WiFi-IoT_Hi3861_CH340G_VER.B.pdf](http://gitee.com/hihope_iot/embedded-race-hisilicon-track-2022/blob/master/%E7%A1%AC%E4%BB%B6%E8%B5%84%E6%96%99/HiSpark_WiFi_IoT%E6%99%BA%E8%83%BD%E5%AE%B6%E5%B1%85%E5%BC%80%E5%8F%91%E5%A5%97%E4%BB%B6_%E5%8E%9F%E7%90%86%E5%9B%BE.rar)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/260.jpg)
## 软件介绍
- 1.代码目录结构及相应接口功能介绍
```
vendor_hisilicon/hispark_pegasus/demo/iottencent_demo
├── app_demo_iot.c #IoSetPull();IoSetFunc();TaskMsleep()。
├── BUILD.gn # BUILD.gn文件由三部分内容目标、源文件、头文件路径构成,开发者根据需要填写,static_library中指定业务模块的编译结果为静态库文件led_example开发者根据实际情况完成填写。
| sources中指定静态库.a所依赖的.c文件及其路径若路径中包含"//"则表示绝对路径(此处为代码根路径),若不包含"//"则表示相对路径。include_dirs中指定source所需要依赖的.h文件路径。
├── cjson_init.c #
├── iot_config.h #
├── iot_hmac.c #
├── iot_hmac.h #
├── iot_log.c #
├── iot_log.h #
├── iot_main.c #
├── iot_main.h #
├── iot_profile.c #
├── iot_sta.c #
└── iot_profile.h #
```
- 2.Mqtt协议第三方软件与腾讯云之间的通信
2.1 浏览器搜索腾讯云,在腾讯云界面创建产品和设备,登录腾讯云后搜索“物联网通信”,进入页面后,物联网通信选择立即使用。进入页面后,选择产品列表栏->创建新产品->产品名称xxx,认证方式:密钥认证,点击确定。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8717.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8720.png)
2.2 在产品列表栏进入刚刚创建的新产品->设备列表->添加设备->创建新设备:设备名称,设备备注(选填),使用物联网通信提供密钥->保存->复制保存生成的密钥->开始管理设备(可以看到设备相应信息)。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8721.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8722.png)
2.3 添加设备,同时查看设备相应信息。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/800.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/801.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/802.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/803.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/804.png)
2.4 返回设备列表可以看到设备并未激活,接下来激活设备;下载[MQTT.fx-1.7.1 ](https://www.jensd.de/wordpress/?p=2746)下载完成后打开工具点击设备图标进入到设备界面配置ClientIDusername,password 等参数。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/806.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8730.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8731.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8732.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8733.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8734.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8735.png)
2.5 完成2.3步骤后可以在腾讯云设备列表里面看到设备状态显示已激活开始腾讯云与MQTT工具之间的通信。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8736.png)
2.6 MQTT.fx-1.7.1工具订阅腾讯云的topic腾讯云下发指令。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8737.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8738.png)
2.7 在腾讯云网页端点击“在线调试”。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8739.png)
2.8 可以在MQTT.fx-1.7.1工具中看到腾讯云网页端发过来的消息。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8740.png)
2.9 MQTT.fx-1.7.1工具发布腾讯云到的topic在设备影子中查看发布到腾讯云的消息。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8741.png)
```
{
"type":"update",
"state":{
"reported":{
"light":1,
"motor":1,
"temperature":25,
"humidity":60,
"light_intensity":50
}
},
"version":0,
"clientToken":"clientToken"
}
```
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8742.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8743.png)
- 3.微信小程序开发环境搭建及与腾讯云之间通信
3.1 注册申请小程序账号https://mp.weixin.qq.com/wxopen/waregister?action=step1。
3.2 登录小程序后选择IOT字样的账号在“开发”->“开发设置”页面可以看到小程序的AppID如下图所示详情请查看微信官方文档
https://developers.weixin.qq.com/miniprogram/dev/framework/quickstart/getstart.html#%E7%94%B3%E8%AF%B7%E5%B8%90%E5%8F%B7。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8744.png)
3.3 开发者工具下载与安装https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8745.png)
3.4 下载安装完成后,打开微信开发工具,导入提供的微信小程序软件包[获取微信小程序代码](https://gitee.com/leo593362220/Hi3861OpenHarmony)。并填入自己的APPID,后端服务选择微信云开发。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%87102.jpg)
3.5 使用微信开发者工具打开工程后需要修改project.config.json文件中appid,projectname修改成自己的。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8747.png)
3.6 获取secretId和secretKey在腾讯云->产品列表->搜索栏搜索访问密钥->访问密钥->继续使用->可以看到secretId和secretKey复制在xxxx.txt文件后面需要。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8749.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8750.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8751.png)
3.7 环境ID配置并获取环境ID,复制在xxx.txt文件后面需要。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8752.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8753.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8754.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8755.png)![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8747.png)
3.8 需要修改app.js文件中productId腾讯云上设备信息上产品ID,deviceName腾讯云上设备信息上产品名称,secretId和secretKey(3.6步骤获取到的secretId和secretKey)env3.7步骤获取到的环境ID
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8748.png)
3.9 配置当前云环境
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8756.png)
注意:第一次部署环境,图片里面的上传并部署会变成新建并部署。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8757.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/228.jpg)
等待大概1分钟左右直到出现上传云函数成功注意上传并部署由于网络问题可能会失败看到上传云函数等字样代表上传部署成功这里以iothub-publish为例
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8758.png)
3.10 环境部署完成后,点击编译,然后真机调试会出现如下界面,上面两个都要出现
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8761.png)
- 4.Hi3861V100与微信小程序之间通信
- 将源码./vendor/hisilicon/hispark_pegasus/demo目录下的iottencent_demo整个文件夹及内容复制到源码./applications/sample/wifi-iot/app/下。
```
.
└── applications
└── sample
└── wifi-iot
└── app
└──iottencent_demo
└── 代码
```
- 配置源码./applications/sample/wifi-iot/app/iottencent_demo/iot_config.h中CONFIG_AP_SSIDCONFIG_AP_PWD为WiFi名称和WiFi密码。CONFIG_USER_ID为腾讯云设备信息上MQTT UsernameCONFIG_USER_PWD为腾讯云上设备的MQTT Password,CN_CLIENTID为腾讯云上clientID。
```
#define CONFIG_AP_SSID "XXXXXXXX" // WIFI SSID
#define CONFIG_AP_PWD "XXXXX" // WIFI PWD
/* Tencent iot Cloud user ID , password */
#define CONFIG_USER_ID "XXXXXXXXXXXXX"
#define CONFIG_USER_PWD "XXXXXXXXXXXX"
#define CN_CLIENTID "xxxxxxxx" // Tencent cloud ClientID format: Product ID + device name
```
- 更改源码./applications/sample/wifi-iot/app/iottencent_demo/iot_main.c文件中搜索g_defaultSubscribeTopic字段将腾讯云上的Topic列表中自定义Topic添加到字段里。
```
static const char *g_defaultSubscribeTopic[] = {
"76VQ4ZASTL/mqtt/data",
"76VQ4ZASTL/mqtt/event",
"76VQ4ZASTL/mqtt/control",
};
```
- 更改源码./applications/sample/wifi-iot/app/iottencent_demo/iot_profile.c文件中搜索CN_PROFILE_TOPICFMT_TOPIC字段将腾讯云上的产品名设备名称添加到字段里。
```
#define CN_PROFILE_TOPICFMT_TOPIC "$shadow/operation/xxxxx/XXXX" //xxxx为产品名和设备名称76VQ4ZASTL
```
- 修改源码./applications/sample/wifi-iot/app/BUILD.gn文件在features字段中增加索引使目标模块参与编译。features字段指定业务模块的路径和目标,features字段配置如下。
```
import("//build/lite/config/component/lite_component.gni")
lite_component("app") {
features = [
"iottencent_demo:appDemoIot",
]
}
```
- 工程相关配置完成后,然后编译。
- 5.烧录
- 编译成功后点击DevEco Home->配置工程->hi3861->upload_port->选择对应串口端口号->选择upload_protocol->选择hiburn-serial->点击save保存在保存成功后点击upload进行烧录出现connecting, please reset device..字样复位开发板等待烧录完成。烧录成功后再次点击Hi3861核心板上的“RST”复位键此时开发板的系统会运行起来。
- 注意:一定要断开MQTT工具的连接。
- 微信小程序上选择已连接Wifi,跳过配网->云端互联->看到设备互联界面->点击刷新按钮,运行结果出现如下图代表成功,点击照明,主板灯会亮。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8762.png)

@ -0,0 +1,259 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <hi_task.h>
#include <string.h>
#include <hi_wifi_api.h>
#include <hi_mux.h>
#include <hi_io.h>
#include <hi_gpio.h>
#include "iot_config.h"
#include "iot_log.h"
#include "iot_main.h"
#include "iot_profile.h"
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
/* attribute initiative to report */
#define TAKE_THE_INITIATIVE_TO_REPORT
#define TWO_SECOND (2000)
/* oc request id */
#define CN_COMMADN_INDEX "commands/request_id="
#define WECHAT_SUBSCRIBE_control "chosen_slot"
#define WECHAT_SUBSCRIBE_channel1 "slot_1"
#define WECHAT_SUBSCRIBE_channel2 "slot_2"
#define WECHAT_SUBSCRIBE_channel3 "slot_3"
#define WECHAT_SUBSCRIBE_channel4 "slot_4"
#define topic_data "YT32IOSCAL/Hi38611_mqtt/data"
#define topic_event "YT32IOSCAL/Hi38611_mqtt/event"
#define topic_control "YT32IOSCAL/Hi38611_mqtt/control"
int g_ligthStatus = -1;
int slot1 = 20,slot2 = 20, slot3 = 20, slot4 = 20;
typedef void (*FnMsgCallBack)(hi_gpio_value val);
typedef struct FunctionCallback {
hi_bool stop;
hi_u32 conLost;
hi_u32 queueID;
hi_u32 iotTaskID;
FnMsgCallBack msgCallBack;
}FunctionCallback;
FunctionCallback g_functinoCallback;
/* CPU Sleep time Set */
unsigned int TaskMsleep(unsigned int ms)
{
if (ms <= 0) {
return HI_ERR_FAILURE;
}
return hi_sleep((hi_u32)ms);
}
static void DeviceConfigInit(hi_gpio_value val)
{
hi_io_set_func(HI_IO_NAME_GPIO_9, HI_IO_FUNC_GPIO_9_GPIO);
hi_gpio_set_dir(HI_GPIO_IDX_9, HI_GPIO_DIR_OUT);
hi_gpio_set_ouput_val(HI_GPIO_IDX_9, val);
}
static void engine_control(unsigned int IO){
IoTGpioInit(IO);
IoSetFunc(IO, 0);
IoTGpioSetDir(IO, IOT_GPIO_DIR_OUT);
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE1);
IOT_LOG_DEBUG("Engine at GPIO:%u started!", IO);
hi_udelay(20000);
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE0);
IOT_LOG_DEBUG("Engine at GPIO:%u stopped!", IO);
}
static void engine_start(unsigned int IO){
IoSetFunc(IO, 0);
IoTGpioSetDir(IO, IOT_GPIO_DIR_OUT);
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE1);
IOT_LOG_DEBUG("Engine at GPIO:%u started!", IO);
}
static void engine_stop(unsigned int IO){
IoSetFunc(IO, 0);
IoTGpioSetDir(IO, IOT_GPIO_DIR_OUT);
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE0);
IOT_LOG_DEBUG("Engine at GPIO:%u stopped!", IO);
}
static void engine_reinit(unsigned int IO){
IoTGpioInit(IO);
IoSetFunc(IO, 0);
IoTGpioSetDir(IO, IOT_GPIO_DIR_OUT);
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE0);
IOT_LOG_DEBUG("Engine at GPIO:%u initialized!", IO);
}
static void all_engine_reinit(){
engine_reinit(6);
engine_reinit(7);
engine_reinit(9);
engine_reinit(10);
IOT_LOG_DEBUG("All engines initialized!");
}
static int DeviceMsgCallback(FnMsgCallBack msgCallBack)
{
g_functinoCallback.msgCallBack = msgCallBack;
return 0;
}
static void wechatControlDeviceMsg(hi_gpio_value val)
{
DeviceConfigInit(val);
}
// < this is the callback function, set to the mqtt, and if any messages come, it will be called
// < The payload here is the json string
static void DemoMsgRcvCallBack(int qos, const char *topic, const char *payload)/*定义3861接收到json文件后的操作*/
{
IOT_LOG_DEBUG("RCVMSG:QOS:%d TOPIC:%s PAYLOAD:%s\r\n", qos, topic, payload);
int IO = 0;
/* 云端下发命令后,板端的操作处理 */
//if (strcmp(topic, topic_data)==0){
if (strstr(payload, WECHAT_SUBSCRIBE_control) != NULL) {
all_engine_reinit();
if (strstr(payload, WECHAT_SUBSCRIBE_channel1) != NULL) {
engine_start(6);
hi_udelay(4000000);
engine_stop(6);
slot1--;
wechatControlDeviceMsg(HI_GPIO_VALUE1);
}
else if (strstr(payload, WECHAT_SUBSCRIBE_channel2) != NULL) {
engine_start(7);
hi_udelay(4000000);
engine_stop(7);
slot2--;
wechatControlDeviceMsg(HI_GPIO_VALUE1);
}
else if (strstr(payload, WECHAT_SUBSCRIBE_channel3) != NULL) {
engine_start(2);
hi_udelay(4000000);
engine_stop(2);
slot3--;
wechatControlDeviceMsg(HI_GPIO_VALUE1);
}
else if (strstr(payload, WECHAT_SUBSCRIBE_channel4) != NULL) {
engine_start(10);
hi_udelay(4000000);
engine_stop(10);
slot4--;
wechatControlDeviceMsg(HI_GPIO_VALUE1);
}
}
//}
return HI_NULL;
}
/* publish sample */
hi_void IotPublishSample(int slot1, int slot2, int slot3, int slot4)
{
/* reported attribute */
WeChatProfile weChatProfile = {
.subscribeType = "type",
.status.subState = "state",
.status.subReport = "reported",
.status.reportVersion = "version",
.status.Token = "clientToken",
/* report motor */
.reportAction.subDeviceActionMotor = "slot_1",
.reportAction.motorActionStatus = slot1, /* 0 : motor off */
/* report temperature */
.reportAction.subDeviceActionTemperature = "slot_2",
.reportAction.temperatureData = slot2, /* 30 :temperature data */
/* report humidity */
.reportAction.subDeviceActionHumidity = "slot_3",
.reportAction.humidityActionData = slot3, /* humidity data */
/* report light_intensity */
.reportAction.subDeviceActionLightIntensity = "slot_4",
.reportAction.lightIntensityActionData = slot4, /* 60 : light_intensity */
};
/* report light */
if (g_ligthStatus == HI_TRUE) {
weChatProfile.reportAction.subDeviceActionLight = "light";
weChatProfile.reportAction.lightActionStatus = 1; /* 1: light on */
} else if (g_ligthStatus == HI_FALSE) {
weChatProfile.reportAction.subDeviceActionLight = "light";
weChatProfile.reportAction.lightActionStatus = 0; /* 0: light off */
} else {
weChatProfile.reportAction.subDeviceActionLight = "light";
weChatProfile.reportAction.lightActionStatus = 0; /* 0: light off */
}
/* profile report */
IoTProfilePropertyReport(CONFIG_USER_ID, &weChatProfile);
}
// < this is the demo main task entry,here we will set the wifi/cjson/mqtt ready and
// < wait if any work to do in the while
static hi_void *DemoEntry(const char *arg)
{
WifiStaReadyWait();
cJsonInit();
IoTMain();
/* 云端下发回调 */
IoTSetMsgCallback(DemoMsgRcvCallBack);
/* 主动上报 */
#ifdef TAKE_THE_INITIATIVE_TO_REPORT
while (1) {
/* 用户可以在这调用发布函数进行发布,需要用户自己写调用函数 */
IotPublishSample(slot1,slot2,slot3,slot4); // 发布例程
#endif
TaskMsleep(TWO_SECOND);
}
return NULL;
}
// < This is the demo entry, we create a task here,
// and all the works has been done in the demo_entry
#define CN_IOT_TASK_STACKSIZE 0x1000
#define CN_IOT_TASK_PRIOR 25
#define CN_IOT_TASK_NAME "IOTDEMO"
static void AppDemoIot(void)
{
osThreadAttr_t attr;
IoTWatchDogDisable();
attr.name = "IOTDEMO";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = CN_IOT_TASK_STACKSIZE;
attr.priority = CN_IOT_TASK_PRIOR;
if (osThreadNew((osThreadFunc_t)DemoEntry, NULL, &attr) == NULL) {
printf("[mqtt] Falied to create IOTDEMO!\n");
}
}
SYS_RUN(AppDemoIot);

@ -0,0 +1,38 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdint.h>
#include <cJSON.h>
#include <hi_mem.h>
static void *cJsonMalloc(size_t sz)
{
return hi_malloc(0, sz);
}
static void cJsonFree(const char *p)
{
hi_free(0, p);
}
void cJsonInit(void)
{
cJSON_Hooks hooks;
hooks.malloc_fn = cJsonMalloc;
hooks.free_fn = cJsonFree;
cJSON_InitHooks(&hooks);
return;
}

@ -0,0 +1,46 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "iot_errno.h"
#include "iot_gpio_ex.h"
#include "hi_gpio.h"
#include "hi_io.h"
#include "hi_task.h"
#include "hi_types_base.h"
unsigned int IoSetPull(unsigned int id, IotIoPull val)
{
if (id >= HI_GPIO_IDX_MAX) {
return IOT_FAILURE;
}
return hi_io_set_pull((hi_io_name)id, (hi_io_pull)val);
}
unsigned int IoSetFunc(unsigned int id, unsigned char val)
{
if (id >= HI_GPIO_IDX_MAX) {
return IOT_FAILURE;
}
return hi_io_set_func((hi_io_name)id, val);
}
/*unsigned int TaskMsleep(unsigned int ms)
{
if (ms <= 0) {
return IOT_FAILURE;
}
return hi_sleep((hi_u32)ms);
}*/

@ -0,0 +1,31 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IOT_CONFIG_H
#define IOT_CONFIG_H
// <CONFIG THE LOG
/* if you need the iot log for the development , please enable it, else please comment it */
#define CONFIG_LINKLOG_ENABLE 1
// < CONFIG THE WIFI
/* Please modify the ssid and pwd for the own */
#define CONFIG_AP_SSID "Sidi_iPhone" // WIFI SSID
#define CONFIG_AP_PWD "12345678" // WIFI PWD
/* Tencent iot Cloud user ID , password */
#define CONFIG_USER_ID "YT32IOSCALHi38611_mqtt;12010126;41883;1663689600"
#define CONFIG_USER_PWD "b4168d5d4b65898e6984346c81ad13e1b3f112ab7ce46f65cf29455f4c9e18e8;hmacsha256"
#define CN_CLIENTID "YT32IOSCALHi38611_mqtt" // Tencent cloud ClientID format: Product ID + device name
#endif

@ -0,0 +1,398 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file iot_gpio_ex.h
*
* @brief Declares the extended GPIO interface functions.
*
* These functions are used for settings GPIO pulls and driver strength. \n
*
* @since 1.0
* @version 1.0
*/
#ifndef IOT_GPIO_EX_H
#define IOT_GPIO_EX_H
/**
* @brief Enumerates GPIO pull-up or pull-down settings.
*/
typedef enum {
/** No pull */
IOT_IO_PULL_NONE,
/** Pull-up */
IOT_IO_PULL_UP,
/** Pull-down */
IOT_IO_PULL_DOWN,
/** Maximum value */
IOT_IO_PULL_MAX,
} IotIoPull;
/**
* @ingroup iot_io
*
* GPIO pin ID. CNcomment:IOCNend
*/
typedef enum {
IOT_IO_NAME_GPIO_0, /* <GPIO0 */
IOT_IO_NAME_GPIO_1, /* <GPIO1 */
IOT_IO_NAME_GPIO_2, /* <GPIO2 */
IOT_IO_NAME_GPIO_3, /* <GPIO3 */
IOT_IO_NAME_GPIO_4, /* <GPIO4 */
IOT_IO_NAME_GPIO_5, /* <GPIO5 */
IOT_IO_NAME_GPIO_6, /* <GPIO6 */
IOT_IO_NAME_GPIO_7, /* <GPIO7 */
IOT_IO_NAME_GPIO_8, /* <GPIO8 */
IOT_IO_NAME_GPIO_9, /* <GPIO9 */
IOT_IO_NAME_GPIO_10, /* <GPIO10 */
IOT_IO_NAME_GPIO_11, /* <GPIO11 */
IOT_IO_NAME_GPIO_12, /* <GPIO12 */
IOT_IO_NAME_GPIO_13, /* <GPIO13 */
IOT_IO_NAME_GPIO_14, /* <GPIO14 */
IOT_IO_NAME_SFC_CSN, /* <SFC_CSN */
IOT_IO_NAME_SFC_IO1, /* <SFC_IO1 */
IOT_IO_NAME_SFC_IO2, /* <SFC_IO2 */
IOT_IO_NAME_SFC_IO0, /* <SFC_IO0 */
IOT_IO_NAME_SFC_CLK, /* <SFC_CLK */
IOT_IO_NAME_SFC_IO3, /* <SFC_IO3 */
IOT_IO_NAME_MAX,
} IotIoName;
/**
* @ingroup iot_io
*
* GPIO_0 pin function.CNcomment:GPIO_0CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_0_GPIO,
IOT_IO_FUNC_GPIO_0_UART1_TXD = 2,
IOT_IO_FUNC_GPIO_0_SPI1_CK,
IOT_IO_FUNC_GPIO_0_JTAG_TDO,
IOT_IO_FUNC_GPIO_0_PWM3_OUT,
IOT_IO_FUNC_GPIO_0_I2C1_SDA,
} IotIoFuncGpio0;
/**
* @ingroup iot_io
*
* GPIO_1 pin function.CNcomment:GPIO_1CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_1_GPIO,
IOT_IO_FUNC_GPIO_1_UART1_RXD = 2,
IOT_IO_FUNC_GPIO_1_SPI1_RXD,
IOT_IO_FUNC_GPIO_1_JTAG_TCK,
IOT_IO_FUNC_GPIO_1_PWM4_OUT,
IOT_IO_FUNC_GPIO_1_I2C1_SCL,
IOT_IO_FUNC_GPIO_1_BT_FREQ,
} IotIoFuncGpio1;
/**
* @ingroup iot_io
*
* GPIO_2 pin function.CNcomment:GPIO_2CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_2_GPIO,
IOT_IO_FUNC_GPIO_2_UART1_RTS_N = 2,
IOT_IO_FUNC_GPIO_2_SPI1_TXD,
IOT_IO_FUNC_GPIO_2_JTAG_TRSTN,
IOT_IO_FUNC_GPIO_2_PWM2_OUT,
IOT_IO_FUNC_GPIO_2_SSI_CLK = 7,
} IotIoFuncGpio2;
/**
* @ingroup iot_io
*
* GPIO_3 pin function.CNcomment:GPIO_3CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_3_GPIO,
IOT_IO_FUNC_GPIO_3_UART0_TXD,
IOT_IO_FUNC_GPIO_3_UART1_CTS_N,
IOT_IO_FUNC_GPIO_3_SPI1_CSN,
IOT_IO_FUNC_GPIO_3_JTAG_TDI,
IOT_IO_FUNC_GPIO_3_PWM5_OUT,
IOT_IO_FUNC_GPIO_3_I2C1_SDA,
IOT_IO_FUNC_GPIO_3_SSI_DATA,
} IotIoFuncGpio3;
/**
* @ingroup iot_io
*
* GPIO_4 pin function.CNcomment:GPIO_4CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_4_GPIO,
IOT_IO_FUNC_GPIO_4_UART0_RXD = 2,
IOT_IO_FUNC_GPIO_4_JTAG_TMS = 4,
IOT_IO_FUNC_GPIO_4_PWM1_OUT,
IOT_IO_FUNC_GPIO_4_I2C1_SCL,
} IotIoFuncGpio4;
/**
* @ingroup iot_io
*
* GPIO_5 pin function.CNcomment:GPIO_5CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_5_GPIO,
IOT_IO_FUNC_GPIO_5_UART1_RXD = 2,
IOT_IO_FUNC_GPIO_5_SPI0_CSN,
IOT_IO_FUNC_GPIO_5_PWM2_OUT = 5,
IOT_IO_FUNC_GPIO_5_I2S0_MCLK,
IOT_IO_FUNC_GPIO_5_BT_STATUS,
} IotIoFuncGpio5;
/**
* @ingroup iot_io
*
* GPIO_6 pin function.CNcomment:GPIO_6CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_6_GPIO,
IOT_IO_FUNC_GPIO_6_UART1_TXD = 2,
IOT_IO_FUNC_GPIO_6_SPI0_CK,
IOT_IO_FUNC_GPIO_6_PWM3_OUT = 5,
IOT_IO_FUNC_GPIO_6_I2S0_TX,
IOT_IO_FUNC_GPIO_6_COEX_SWITCH,
} IotIoFuncGpio6;
/**
* @ingroup iot_io
*
* GPIO_7 pin function.CNcomment:GPIO_7CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_7_GPIO,
IOT_IO_FUNC_GPIO_7_UART1_CTS_N = 2,
IOT_IO_FUNC_GPIO_7_SPI0_RXD,
IOT_IO_FUNC_GPIO_7_PWM0_OUT = 5,
IOT_IO_FUNC_GPIO_7_I2S0_BCLK,
IOT_IO_FUNC_GPIO_7_BT_ACTIVE,
} IotIoFuncGpio7;
/**
* @ingroup iot_io
*
* GPIO_8 pin function.CNcomment:GPIO_8CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_8_GPIO,
IOT_IO_FUNC_GPIO_8_UART1_RTS_N = 2,
IOT_IO_FUNC_GPIO_8_SPI0_TXD,
IOT_IO_FUNC_GPIO_8_PWM1_OUT = 5,
IOT_IO_FUNC_GPIO_8_I2S0_WS,
IOT_IO_FUNC_GPIO_8_WLAN_ACTIVE,
} IotIoFuncGpio8;
/**
* @ingroup iot_io
*
* GPIO_9 pin function.CNcomment:GPIO_9CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_9_GPIO,
IOT_IO_FUNC_GPIO_9_I2C0_SCL,
IOT_IO_FUNC_GPIO_9_UART2_RTS_N,
IOT_IO_FUNC_GPIO_9_SDIO_D2,
IOT_IO_FUNC_GPIO_9_SPI0_TXD,
IOT_IO_FUNC_GPIO_9_PWM0_OUT,
IOT_IO_FUNC_GPIO_9_I2S0_MCLK = 7,
} IotIoFuncGpio9;
/**
* @ingroup iot_io
*
* GPIO_10 pin function.CNcomment:GPIO_10CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_10_GPIO,
IOT_IO_FUNC_GPIO_10_I2C0_SDA,
IOT_IO_FUNC_GPIO_10_UART2_CTS_N,
IOT_IO_FUNC_GPIO_10_SDIO_D3,
IOT_IO_FUNC_GPIO_10_SPI0_CK,
IOT_IO_FUNC_GPIO_10_PWM1_OUT,
IOT_IO_FUNC_GPIO_10_I2S0_TX = 7,
} IotIoFuncGpio10;
/**
* @ingroup iot_io
*
* GPIO_11 pin function.CNcomment:GPIO_11CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_11_GPIO,
IOT_IO_FUNC_GPIO_11_UART2_TXD = 2,
IOT_IO_FUNC_GPIO_11_SDIO_CMD,
IOT_IO_FUNC_GPIO_11_SPI0_RXD,
IOT_IO_FUNC_GPIO_11_PWM2_OUT,
IOT_IO_FUNC_GPIO_11_RF_TX_EN_EXT,
IOT_IO_FUNC_GPIO_11_I2S0_RX,
} IotIoFuncGpio11;
/**
* @ingroup iot_io
*
* GPIO_12 pin function.CNcomment:GPIO_12CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_12_GPIO,
IOT_IO_FUNC_GPIO_12_UART2_RXD = 2,
IOT_IO_FUNC_GPIO_12_SDIO_CLK,
IOT_IO_FUNC_GPIO_12_SPI0_CSN,
IOT_IO_FUNC_GPIO_12_PWM3_OUT,
IOT_IO_FUNC_GPIO_12_RF_RX_EN_EXT,
IOT_IO_FUNC_GPIO_12_I2S0_BCLK,
} IotIoFuncGpio12;
/**
* @ingroup iot_io
*
* GPIO_13 pin function.CNcomment:GPIO_13CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_13_SSI_DATA,
IOT_IO_FUNC_GPIO_13_UART0_TXD,
IOT_IO_FUNC_GPIO_13_UART2_RTS_N,
IOT_IO_FUNC_GPIO_13_SDIO_D0,
IOT_IO_FUNC_GPIO_13_GPIO,
IOT_IO_FUNC_GPIO_13_PWM4_OUT,
IOT_IO_FUNC_GPIO_13_I2C0_SDA,
IOT_IO_FUNC_GPIO_13_I2S0_WS,
} IotIoFuncGpio13;
/**
* @ingroup iot_io
*
* GPIO_14 pin function.CNcomment:GPIO_14CNend
*/
typedef enum {
IOT_IO_FUNC_GPIO_14_SSI_CLK,
IOT_IO_FUNC_GPIO_14_UART0_RXD,
IOT_IO_FUNC_GPIO_14_UART2_CTS_N,
IOT_IO_FUNC_GPIO_14_SDIO_D1,
IOT_IO_FUNC_GPIO_14_GPIO,
IOT_IO_FUNC_GPIO_14_PWM5_OUT,
IOT_IO_FUNC_GPIO_14_I2C0_SCL,
} IotIoFuncGpio14;
/**
* @ingroup iot_io
*
* SFC_CSN pin function.CNcomment:SFC_CSNCNend
*/
typedef enum {
IOT_IO_FUNC_SFC_CSN_SFC_CSN,
IOT_IO_FUNC_SFC_CSN_SDIO_D2,
IOT_IO_FUNC_SFC_CSN_GPIO9,
IOT_IO_FUNC_SFC_CSN_SPI0_TXD = 4,
} IotIoFuncSfcCsn;
/**
* @ingroup iot_io
*
* SFC_DO pin function.CNcomment:SFC_DOCNend
*/
typedef enum {
IOT_IO_FUNC_SFC_IO_1_SFC_DO,
IOT_IO_FUNC_SFC_IO_1_SDIO_D3,
IOT_IO_FUNC_SFC_IO_1_GPIO10,
IOT_IO_FUNC_SFC_IO_1_SPI0_CK = 4,
} IotIoFuncSfcIo1;
/**
* @ingroup iot_io
*
* SFC_WPN pin function.CNcomment:SFC_WPNCNend
*/
typedef enum {
IOT_IO_FUNC_SFC_IO_2_SFC_WPN,
IOT_IO_FUNC_SFC_IO_2_SDIO_CMD,
IOT_IO_FUNC_SFC_IO_2_GPIO11,
IOT_IO_FUNC_SFC_IO_2_RF_TX_EN_EXT,
IOT_IO_FUNC_SFC_IO_2_SPI0_RXD,
} IotIoFuncSfcIo2;
/**
* @ingroup iot_io
*
* SFC_DI pin function.CNcomment:SFC_DICNend
*/
typedef enum {
IOT_IO_FUNC_SFC_IO_0_SFC_DI,
IOT_IO_FUNC_SFC_IO_0_SDIO_CLK,
IOT_IO_FUNC_SFC_IO_0_GPIO12,
IOT_IO_FUNC_SFC_IO_0_RF_RX_EN_EXT,
IOT_IO_FUNC_SFC_IO_0_SPI0_CSN,
} IotIoFuncSfcIo0;
/**
* @ingroup iot_io
*
* SFC_CLK pin function.CNcomment:SFC_CLKCNend
*/
typedef enum {
IOT_IO_FUNC_SFC_CLK_SFC_CLK,
IOT_IO_FUNC_SFC_CLK_SDIO_D0,
IOT_IO_FUNC_SFC_CLK_GPIO13,
IOT_IO_FUNC_SFC_CLK_SSI_DATA = 4,
} IotIoFuncSfcClk;
/**
* @ingroup iot_io
*
* SFC_HOLDN pin function.CNcomment:SFC_HOLDNCNend
*/
typedef enum {
IOT_IO_FUNC_SFC_IO_3_SFC_HOLDN,
IOT_IO_FUNC_SFC_IO_3_SDIO_D1,
IOT_IO_FUNC_SFC_IO_3_GPIO14,
IOT_IO_FUNC_SFC_IO_3_SSI_CLK = 4,
} IotIoFuncSfcIo3;
/**
* @ingroup iot_io
*
* I/O drive capability.CNcomment:IOCNend
* Note: The HI_IO_NAME_GPIO_0~HI_IO_NAME_GPIO_11 and HI_IO_NAME_GPIO_13~HI_IO_NAME_GPIO_14 driver capabilities are
* optional.The value range is HI_IO_DRIVER_STRENGTH_0~HI_IO_DRIVER_STRENGTH_3, and the other I/O ranges are
* HI_IO_DRIVER_STRENGTH_0~HI_IO_DRIVER_STRENGTH_7.CNcomment::HI_IO_NAME_GPIO_0~HI_IO_NAME_GPIO_11
* HI_IO_NAME_GPIO_13~HI_IO_NAME_GPIO_14HI_IO_DRIVER_STRENGTH_0~HI_IO_DRIVER_STRENGTH_3
* IOHI_IO_DRIVER_STRENGTH_0~HI_IO_DRIVER_STRENGTH_7CNend
*/
typedef enum {
IOT_IO_DRIVER_STRENGTH_0 = 0, /* <Drive strength level 0 (highest).CNcomment:驱动能力0级驱动能力最高CNend */
IOT_IO_DRIVER_STRENGTH_1, /* <Drive strength level 1.CNcomment:驱动能力1级CNend */
IOT_IO_DRIVER_STRENGTH_2, /* <Drive strength level 2.CNcomment:驱动能力2级CNend */
IOT_IO_DRIVER_STRENGTH_3, /* <Drive strength level 3.CNcomment:驱动能力3级CNend */
IOT_IO_DRIVER_STRENGTH_4, /* <Drive strength level 4.CNcomment:驱动能力4级CNend */
IOT_IO_DRIVER_STRENGTH_5, /* <Drive strength level 5.CNcomment:驱动能力5级CNend */
IOT_IO_DRIVER_STRENGTH_6, /* <Drive strength level 6.CNcomment:驱动能力6级CNend */
IOT_IO_DRIVER_STRENGTH_7, /* <Drive strength level 7 (lowest).CNcomment:驱动能力7级驱动能力最低CNend */
IOT_IO_DRIVER_STRENGTH_MAX,
} IotIoDriverStrength;
unsigned int IoSetPull(unsigned int id, IotIoPull val);
unsigned int IoSetFunc(unsigned int id, unsigned char val);
//unsigned int TaskMsleep(unsigned int ms);
#endif
/** @} */

@ -0,0 +1,95 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This file make use the hmac to make mqtt pwd.
* The method is use the date string to hash the device passwd
* Take care that this implement depends on the hmac of the mbedtls
*/
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include "md.h"
#include "md_internal.h"
#define CN_HMAC256_LEN_MAX (65)
#define CN_HMAC256_LEN 32
#define RIGHT_MOVE_BIT_4 (4)
#define NUMBER_9 (9)
#define DECIMAL_BASE (10)
#define STRING_LEN_TIMES (2)
#define LEN_TIMES (2)
#define OFFSET (1)
// make a byte to 2 ascii hex
static int byte2hexstr(unsigned char *bufin, int len, char *bufout)
{
int i = 0;
unsigned char tmp_l = 0x0;
unsigned char tmp_h = 0;
if ((bufin == NULL)||(len <= 0)||(bufout == NULL)) {
return -1;
}
for (i = 0; i < len; i++) {
tmp_h = (bufin[i] >> RIGHT_MOVE_BIT_4) & 0X0F;
tmp_l = bufin[i] & 0x0F;
bufout[STRING_LEN_TIMES * i] = (tmp_h > NUMBER_9) ?
(tmp_h - DECIMAL_BASE + 'a'):(tmp_h +'0');
bufout[STRING_LEN_TIMES * i + OFFSET] = (tmp_l > NUMBER_9) ?
(tmp_l - DECIMAL_BASE + 'a'):(tmp_l +'0');
}
bufout[STRING_LEN_TIMES * len] = '\0';
return 0;
}
int HmacGeneratePwd(const unsigned char *content, int contentLen, const unsigned char *key,
int keyLen, unsigned char *buf)
{
int ret = -1;
mbedtls_md_context_t mbedtls_md_ctx;
const mbedtls_md_info_t *md_info;
unsigned char hash[CN_HMAC256_LEN];
if ((key == NULL)||(content == NULL)||(buf == NULL)||
(keyLen == 0)||(contentLen == 0)||
(CN_HMAC256_LEN_MAX < (CN_HMAC256_LEN * LEN_TIMES + OFFSET))) {
return ret;
}
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
if ((md_info == NULL)||((size_t)md_info->size > CN_HMAC256_LEN)) {
return ret;
}
mbedtls_md_init(&mbedtls_md_ctx);
ret = mbedtls_md_setup(&mbedtls_md_ctx, md_info, 1);
if (ret != 0) {
mbedtls_md_free(&mbedtls_md_ctx);
return ret;
}
(void)mbedtls_md_hmac_starts(&mbedtls_md_ctx, key, keyLen);
(void)mbedtls_md_hmac_update(&mbedtls_md_ctx, content, contentLen);
(void)mbedtls_md_hmac_finish(&mbedtls_md_ctx, hash);
// <transfer the hash code to the string mode
ret = byte2hexstr(hash, CN_HMAC256_LEN, (char *)buf);
if (ret != 0) {
return ret;
}
return ret;
}

@ -0,0 +1,32 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IOT_HMAC_H
#define IOT_HMAC_H
/**
* This function used to generate the passwd for the mqtt to connect the HW IoT platform
* @param content: This is the content for the hmac,
* and usually it is the device passwd set or get from the Iot Platform
* @param content_len: The length of the content
* @param key: This is the key for the hmac, and usually it is the time used in the client_id:
* the format isyearmonthdatehour:like 1970010100
* @param key_len: The length of the key
* @param buf: used to storage the hmac code
* @param buf_len:the buf length
* @return:0 success while others failed
*/
int HmacGeneratePwd(const unsigned char *content, int contentLen, const unsigned char *key,
int keyLen, unsigned char *buf);
#endif

@ -0,0 +1,50 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <iot_log.h>
static EnIotLogLevel gIoTLogLevel = EN_IOT_LOG_LEVEL_TRACE;
static const char *gIoTLogLevelNames[] = {
"TRACE",
"DEBUG",
"INFO ",
"WARN ",
"ERROR",
"FATAL"
};
int IoTLogLevelSet(EnIotLogLevel level)
{
int ret = -1;
if (level < EN_IOT_LOG_LEVEL_MAX) {
gIoTLogLevel = level;
ret = 0;
}
return ret;
}
EnIotLogLevel IoTLogLevelGet(void)
{
return gIoTLogLevel;
}
const char *IoTLogLevelGetName(EnIotLogLevel logLevel)
{
if (logLevel >= EN_IOT_LOG_LEVEL_MAX) {
return "NULL ";
} else {
return gIoTLogLevelNames[logLevel];
}
}

@ -0,0 +1,122 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IOT_LOG_H_
#define IOT_LOG_H_
/**
* @brief:this defines for the log module,
* and IOT_LOG_TRACE/IOT_LOG_DEBUG will not participate the compile in the release version
*
*
* */
typedef enum {
// < this is used as the trace function,like the function enter and function out
EN_IOT_LOG_LEVEL_TRACE = 0,
// < this is used as the debug, you could add any debug as you wish
EN_IOT_LOG_LEVEL_DEBUG,
// < which means it is import message, and you should known
EN_IOT_LOG_LEVEL_INFO,
// < this is used as the executed result,which means the status is not what we expected
EN_IOT_LOG_LEVEL_WARN,
// < this is used as the executed result,which means the status is not what we expected
EN_IOT_LOG_LEVEL_ERROR,
// < this is used as the parameters input for the api interface, which could not accepted
EN_IOT_LOG_LEVEL_FATAL,
EN_IOT_LOG_LEVEL_MAX,
}EnIotLogLevel;
/**
* @brief:use this function to get the current output log
*
* @return: the current output mask log, defined by en_iot_log_level_t
* */
EnIotLogLevel IoTLogLevelGet(void);
/**
* @brief: use this function to get the debug level name
*
* @parameter[in]:level, the level to get
*
* @return: the mapped level name
* */
const char *IoTLogLevelGetName(EnIotLogLevel logLevel);
/**
* @brief:use this function to set the current output log
*
* @parameter[in] level:defined by en_iot_log_level_t
*
* @return: 0 success while -1 failed
* */
int IoTLogLevelSet(EnIotLogLevel level);
/*
* @brief: this is a weak function ,and you could rewrite one
*
* @param fmt: same use as the fmt for printf
*
* @param unfixed: same use for printf
*
* @return: don't care about it
*
* @attention: and the components should not call this function directly, you'd better
*
* call IOT_LOG groups
*
* */
#ifndef IOT_PRINT
#define IOT_PRINT(fmt, ...) \
do \
{ \
printf(fmt, ##__VA_ARGS__); \
}while (0)
#endif
#ifdef CONFIG_LINKLOG_ENABLE
#define IOT_LOG(level, fmt, ...) \
do \
{ \
IOT_PRINT("[%s][%s] " fmt "\r\n", \
IoTLogLevelGetName((level)), __FUNCTION__, ##__VA_ARGS__); \
} while (0)
#define IOT_LOG_TRACE(fmt, ...) \
do \
{ \
if ((EN_IOT_LOG_LEVEL_TRACE) >= IoTLogLevelGet()) \
{ \
IOT_LOG(EN_IOT_LOG_LEVEL_TRACE, fmt, ##__VA_ARGS__); \
} \
} while (0)
#define IOT_LOG_DEBUG(fmt, ...) \
do \
{ \
if ((EN_IOT_LOG_LEVEL_DEBUG) >= IoTLogLevelGet()) \
{ \
IOT_LOG(EN_IOT_LOG_LEVEL_DEBUG, fmt, ##__VA_ARGS__); \
} \
} while (0)
#else
#define IOT_LOG(level, fmt, ...)
#define IOT_LOG_TRACE(fmt, ...)
#define IOT_LOG_DEBUG(fmt, ...)
#endif
#define IOT_LOG_TRACE(fmt, ...) IOT_LOG(EN_IOT_LOG_LEVEL_TRACE, fmt, ##__VA_ARGS__)
#define IOT_LOG_INFO(fmt, ...) IOT_LOG(EN_IOT_LOG_LEVEL_INFO, fmt, ##__VA_ARGS__)
#define IOT_LOG_WARN(fmt, ...) IOT_LOG(EN_IOT_LOG_LEVEL_WARN, fmt, ##__VA_ARGS__)
#define IOT_LOG_ERROR(fmt, ...) IOT_LOG(EN_IOT_LOG_LEVEL_ERROR, fmt, ##__VA_ARGS__)
#define IOT_LOG_FATAL(fmt, ...) IOT_LOG(EN_IOT_LOG_LEVEL_FATAL, fmt, ##__VA_ARGS__)
#endif /* IOT_LOG_H_ */

@ -0,0 +1,325 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* STEPS:
* 1, CONNECT TO THE IOT SERVER
* 2, SUBSCRIBE THE DEFAULT TOPIC
* 3, WAIT FOR ANY MESSAGE COMES OR ANY MESSAGE TO SEND
*/
#include <securec.h>
#include <hi_task.h>
#include <hi_msg.h>
#include <hi_mem.h>
#include <string.h>
#include <stdbool.h>
#include "iot_config.h"
#include "iot_log.h"
#include "iot_hmac.h"
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_watchdog.h"
#include "MQTTClient.h"
#include "iot_errno.h"
#include "iot_main.h"
#include "iot_gpio.h"
// < this is the configuration head
#define CN_IOT_SERVER "tcp://106.55.124.154:1883" // Tencent iot cloud address
#define CONFIG_COMMAND_TIMEOUT 10000L
#define CN_KEEPALIVE_TIME 50
#define CN_CLEANSESSION 1
#define CN_HMAC_PWD_LEN 65 // < SHA256 IS 32 BYTES AND END APPEND '\0'
#define CN_EVENT_TIME "1970000100"
#define CN_CLIENTID_FMT "%s_0_0_%s" // < This is the cient ID format, deviceID_0_0_TIME
#define CN_QUEUE_WAITTIMEOUT 1000
#define CN_QUEUE_MSGNUM 16
#define CN_QUEUE_MSGSIZE (sizeof(hi_pvoid))
#define CN_TASK_PRIOR 28
#define CN_TASK_STACKSIZE 0X2000
#define CN_TASK_NAME "IoTMain"
typedef enum {
EN_IOT_MSG_PUBLISH = 0,
EN_IOT_MSG_RECV,
}EnIotMsg;
typedef struct {
EnIotMsg type;
int qos;
const char *topic;
const char *payload;
}IoTMsg_t;
typedef struct {
bool stop;
unsigned int conLost;
unsigned int queueID;
unsigned int iotTaskID;
fnMsgCallBack msgCallBack;
MQTTClient_deliveryToken tocken;
}IotAppCb_t;
static IotAppCb_t gIoTAppCb;
static const char *gDefaultSubscribeTopic[] = {
/* Tencent iot cloud topic */
"YT32IOSCAL/Hi38611_mqtt/data",
"YT32IOSCAL/Hi38611_mqtt/event",
"YT32IOSCAL/Hi38611_mqtt/control",
};
#define CN_TOPIC_SUBSCRIBE_NUM (sizeof(gDefaultSubscribeTopic) / sizeof(const char *))
static int MsgRcvCallBack(char *context, char *topic, int topicLen, MQTTClient_message *message)
{
IoTMsg_t *msg;
char *buf;
unsigned int bufSize;
int topiLen = topicLen;
if (topiLen == 0) {
topiLen = strlen(topic);
}
bufSize = topiLen + 1 + message->payloadlen + 1 + sizeof(IoTMsg_t);
buf = hi_malloc(0, bufSize);
if (buf != NULL) {
msg = (IoTMsg_t *)buf;
buf += sizeof(IoTMsg_t);
bufSize -= sizeof(IoTMsg_t);
msg->qos = message->qos;
msg->type = EN_IOT_MSG_RECV;
(void)memcpy_s(buf, bufSize, topic, topiLen);
buf[topiLen] = '\0';
msg->topic = buf;
buf += topiLen + 1;
bufSize -= (topiLen + 1);
(void)memcpy_s(buf, bufSize, message->payload, message->payloadlen);
buf[message->payloadlen] = '\0';
msg->payload = buf;
IOT_LOG_DEBUG("RCVMSG:QOS:%d TOPIC:%s PAYLOAD:%s\r\n", msg->qos, msg->topic, msg->payload);
if (IOT_SUCCESS != osMessageQueuePut(gIoTAppCb.queueID, &msg, 0, CN_QUEUE_WAITTIMEOUT)) {
IOT_LOG_ERROR("Wrie queue failed\r\n");
hi_free(0, msg);
}
}
MQTTClient_freeMessage(&message);
MQTTClient_free(topic);
return 1;
}
// < when the connect lost and this callback will be called
static void ConnLostCallBack(char *context, char *cause)
{
IOT_LOG_DEBUG("Connection lost:caused by:%s\r\n", cause == NULL? "Unknown" : cause);
return;
}
static int MqttProcessQueueMsg(MQTTClient client, IoTMsg_t *msg, MQTTClient_message pubMsg)
{
int ret = 0;
switch (msg->type) {
case EN_IOT_MSG_PUBLISH:
pubMsg.payload = (void *)msg->payload;
pubMsg.payloadlen = (int)strlen(msg->payload);
pubMsg.qos = msg->qos;
pubMsg.retained = 0;
ret = MQTTClient_publishMessage(client, msg->topic, &pubMsg, &gIoTAppCb.tocken);
if (ret != MQTTCLIENT_SUCCESS) {
IOT_LOG_ERROR("MSGSEND:failed\r\n");
}
IOT_LOG_DEBUG("MSGSEND:SUCCESS\r\n");
gIoTAppCb.tocken++;
break;
case EN_IOT_MSG_RECV:
if (gIoTAppCb.msgCallBack != NULL) {
gIoTAppCb.msgCallBack(msg->qos, msg->topic, msg->payload); /*接受信息并进行相应的操作函数体在IoTSetMsgCallback中定义*/
}
break;
default:
break;
}
}
// <use this function to deal all the comming message
static int ProcessQueueMsg(MQTTClient client)
{
unsigned int ret;
unsigned int msgSize;
IoTMsg_t *msg;
unsigned int timeout;
MQTTClient_message pubmsg = MQTTClient_message_initializer;
timeout = CN_QUEUE_WAITTIMEOUT;
do {
msg = NULL;
msgSize = sizeof(hi_pvoid);
ret = osMessageQueueGet(gIoTAppCb.queueID, &msg, &msgSize, timeout);/*得到数据存入msg*/
if (msg != NULL) {
IOT_LOG_DEBUG("QUEUEMSG:QOS:%d TOPIC:%s PAYLOAD:%s\r\n", msg->qos, msg->topic, msg->payload);
MqttProcessQueueMsg(client, msg, pubmsg);
hi_free(0, msg);
}
timeout = 0; // < continous to deal the message without wait here
} while (ret == IOT_SUCCESS);
return 0;
}
int MqttDestory(int ret, MQTTClient client)
{
if (ret != MQTTCLIENT_SUCCESS) {
MQTTClient_destroy(&client);
return -1;
}
return MQTTCLIENT_SUCCESS;
}
static void MainEntryProcess(void)
{
int rc = 0, subQos[CN_TOPIC_SUBSCRIBE_NUM] = {1};
MQTTClient client = NULL;
MQTTClient_connectOptions connOpts = MQTTClient_connectOptions_initializer;
char *clientID = CN_CLIENTID;
char *userID = CONFIG_USER_ID;
char *userPwd = hi_malloc(0, CN_HMAC_PWD_LEN);
if (userPwd == NULL) {
hi_free(0, clientID);
return;
}
userPwd = CONFIG_USER_PWD;
connOpts.keepAliveInterval = CN_KEEPALIVE_TIME;
connOpts.cleansession = CN_CLEANSESSION;
connOpts.username = userID;
connOpts.password = userPwd;
connOpts.MQTTVersion = MQTTVERSION_3_1_1;
IOT_LOG_DEBUG("CLIENTID:%s USERID:%s USERPWD:%s, IOTSERVER:%s\r\n",
clientID, userID, userPwd==NULL?"NULL" : userPwd, CN_IOT_SERVER);
rc = MQTTClient_create(&client, CN_IOT_SERVER, clientID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
if (rc != MQTTCLIENT_SUCCESS) {
if (userPwd != NULL) {
hi_free(0, userPwd);
}
return;
}
rc = MQTTClient_setCallbacks(client, NULL, ConnLostCallBack, MsgRcvCallBack, NULL);
if (MqttDestory(rc, client) != MQTTCLIENT_SUCCESS) {
return;
}
rc = MQTTClient_connect(client, &connOpts);
if (MqttDestory(rc, client) != MQTTCLIENT_SUCCESS) {
return;
}
for (int i = 0; i < CN_TOPIC_SUBSCRIBE_NUM; i++) {
rc = MQTTClient_subscribeMany(client, CN_TOPIC_SUBSCRIBE_NUM,
(char *const *)gDefaultSubscribeTopic, (int *)&subQos[0]);
if (MqttDestory(rc, client) != MQTTCLIENT_SUCCESS) {
return;
}
}
IOT_LOG_DEBUG ("Connect success and Subscribe success\r\n");
while (MQTTClient_isConnected(client)) {
ProcessQueueMsg(client); // < do the job here
MQTTClient_yield(); // < make the keepalive done
}
MQTTClient_disconnect(client, CONFIG_COMMAND_TIMEOUT);
return;
}
/* MQTT processing entry */
static hi_void *MainEntry(char *arg)
{
(void)arg;
while (gIoTAppCb.stop == false) {
MainEntryProcess();
IOT_LOG_DEBUG("The connection lost and we will try another connect\r\n");
hi_sleep(1000); /* 1000: cpu sleep 1000ms */
}
return NULL;
}
static void engine_init(unsigned int IO){
IoTGpioInit(IO);
IoSetFunc(IO, 0);
IoTGpioSetDir(IO, IOT_GPIO_DIR_OUT);
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE0);
IOT_LOG_DEBUG("GPIO:%u initialized!", IO);
}
int IoTMain(void)
{
unsigned int ret = 0;
hi_task_attr attr = {0};
engine_init(6);
engine_init(7);
engine_init(9);
engine_init(10);
gIoTAppCb.queueID = osMessageQueueNew(CN_QUEUE_MSGNUM, CN_QUEUE_MSGSIZE, NULL);
if (ret != IOT_SUCCESS) {
IOT_LOG_ERROR("Create the msg queue Failed\r\n");
}
attr.stack_size = CN_TASK_STACKSIZE;
attr.task_prio = CN_TASK_PRIOR;
attr.task_name = CN_TASK_NAME;
ret = hi_task_create(&gIoTAppCb.iotTaskID, &attr, MainEntry, NULL);
if (ret != IOT_SUCCESS) {
IOT_LOG_ERROR("Create the Main Entry Failed\r\n");
}
return 0;
}
int IoTSetMsgCallback(fnMsgCallBack msgCallback)
{
gIoTAppCb.msgCallBack = msgCallback;/*赋予函数*/
return 0;
}
int IotSendMsg(int qos, const char *topic, const char *payload)
{
int rc = -1;
IoTMsg_t *msg;
char *buf;
unsigned int bufSize;
bufSize = strlen(topic) + 1 +strlen(payload) + 1 + sizeof(IoTMsg_t);
buf = hi_malloc(0, bufSize);
if (buf != NULL) {
msg = (IoTMsg_t *)buf;
buf += sizeof(IoTMsg_t);
bufSize -= sizeof(IoTMsg_t);
msg->qos = qos;
msg->type = EN_IOT_MSG_PUBLISH;
(void)memcpy_s(buf, bufSize, topic, strlen(topic));
buf[strlen(topic)] = '\0';
msg->topic = buf;
buf += strlen(topic) + 1;
bufSize -= (strlen(topic) + 1);
(void)memcpy_s(buf, bufSize, payload, strlen(payload));
buf[strlen(payload)] = '\0';
msg->payload = buf;
IOT_LOG_DEBUG("SNDMSG:QOS:%d TOPIC:%s PAYLOAD:%s\r\n", msg->qos, msg->topic, msg->payload);
if (IOT_SUCCESS != osMessageQueuePut(gIoTAppCb.queueID, &msg, 0, CN_QUEUE_WAITTIMEOUT)) {
IOT_LOG_ERROR("Write queue failed\r\n");
hi_free(0, msg);
} else {
rc = 0;
}
}
return rc;
}

@ -0,0 +1,44 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IOT_MAIN_H
#define IOT_MAIN_H
typedef void (*fnMsgCallBack)(int qos, const char *topic, const char *payload);
/**
* This is the iot main function. Please call this function first
*/
int IoTMain(void);
/**
* Use this function to set the message call back function, when some messages comes,
* the callback will be called, if you don't care about the message, set it to NULL
*/
int IoTSetMsgCallback(fnMsgCallBack msgCallback);
/**
* When you want to send some messages to the iot server(including the response message),
* please call this api
* @param qos: the mqtt qos,:0,1,2
* @param topic: the iot mqtt topic
* @param payload: the mqtt payload
*
* @return 0 success while others failed
*
* @instruction: if success means we write the message to the queue susccess,
* not means communicate with the server success
*/
int IotSendMsg(int qos, const char *topic, const char *payload);
#endif /* IOT_MAIN_H_ */

@ -0,0 +1,336 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <hi_mem.h>
#include <cJSON.h>
#include <string.h>
#include "iot_main.h"
#include "iot_log.h"
#include "iot_config.h"
#include "iot_profile.h"
// < format the report data to json string mode
static cJSON *FormateProflleValue(IoTProfileKV_t *kv)
{
cJSON *ret = NULL;
switch (kv->type) {
case EN_IOT_DATATYPE_INT:
ret = cJSON_CreateNumber(kv->iValue);
break;
case EN_IOT_DATATYPE_LONG:
ret = cJSON_CreateNumber((double)(*(long *)kv->value));
break;
case EN_IOT_DATATYPE_STRING:
ret = cJSON_CreateString((const char *)kv->value);
break;
default:
break;
}
return ret;
}
static cJSON *MakeKvs(IoTProfileKV_t *kvlst)
{
cJSON *root;
cJSON *kv;
IoTProfileKV_t *kvInfo;
// < build a root node
root = cJSON_CreateObject();
if (root == NULL) {
cJSON_Delete(root);
root = NULL;
return root;
}
// < add all the property to the properties
kvInfo = kvlst;
while (kvInfo != NULL) {
kv = FormateProflleValue(kvInfo);
if (kv == NULL) {
if (root != NULL) {
cJSON_Delete(root);
root = NULL;
}
return root;
}
cJSON_AddItemToObject(root, kvInfo->key, kv);
kvInfo = kvInfo->nxt;
}
// < OK, now we return it
return root;
}
#define CN_PROFILE_SERVICE_KEY_SERVICEID "service_id"
#define CN_PROFILE_SERVICE_KEY_PROPERTIIES "properties"
#define CN_PROFILE_SERVICE_KEY_EVENTTIME "event_time"
#define CN_PROFILE_KEY_SERVICES "services"
static cJSON *MakeService(IoTProfileService_t *serviceInfo)
{
cJSON *root;
cJSON *serviceID;
cJSON *properties;
cJSON *eventTime;
// < build a root node
root = cJSON_CreateObject();
if (root == NULL) {
cJSON_Delete(root);
root = NULL;
return root;
}
// < add the serviceID node to the root node
serviceID = cJSON_CreateString(serviceInfo->serviceID);
if (serviceID == NULL) {
if (root != NULL) {
cJSON_Delete(root);
root = NULL;
}
return root;
}
cJSON_AddItemToObjectCS(root, CN_PROFILE_SERVICE_KEY_SERVICEID, serviceID);
// < add the properties node to the root
properties = MakeKvs(serviceInfo->serviceProperty);
if (properties == NULL) {
if (root != NULL) {
cJSON_Delete(root);
root = NULL;
}
return root;
}
cJSON_AddItemToObjectCS(root, CN_PROFILE_SERVICE_KEY_PROPERTIIES, properties);
// < add the event time (optional) to the root
if (serviceInfo->eventTime != NULL) {
eventTime = cJSON_CreateString(serviceInfo->eventTime);
if (eventTime == NULL) {
if (root != NULL) {
cJSON_Delete(root);
root = NULL;
}
return root;
}
cJSON_AddItemToObjectCS(root, CN_PROFILE_SERVICE_KEY_EVENTTIME, eventTime);
}
// < OK, now we return it
cJSON_Delete(properties);
return root;
}
static cJSON *MakeServices(IoTProfileService_t *serviceInfo)
{
cJSON *services = NULL;
cJSON *service;
IoTProfileService_t *serviceTmp;
// < create the services array node
services = cJSON_CreateArray();
if (services == NULL) {
cJSON_Delete(services);
services = NULL;
return services;
}
serviceTmp = serviceInfo;
while (serviceTmp != NULL) {
service = MakeService(serviceTmp);
if (service == NULL) {
if (services != NULL) {
cJSON_Delete(services);
services = NULL;
}
return services;
}
cJSON_AddItemToArray(services, service);
serviceTmp = serviceTmp->nxt;
}
// < now we return the services
return services;
}
// < use this function to make a topic to publish
// < if request_id is needed depends on the fmt
static char *MakeTopic(const char *fmt, const char *deviceID, const char *requestID)
{
int len;
char *ret = NULL;
len = strlen(fmt) + strlen(deviceID);
if (requestID != NULL) {
len += strlen(requestID);
}
ret = hi_malloc(0, len);
if (ret != NULL) {
if (requestID != NULL) {
(void)snprintf_s(ret, len, len, fmt, deviceID, requestID);
} else {
(void)snprintf_s(ret, len, len, fmt, deviceID);
}
}
return ret;
}
#define CN_PROFILE_CMDRESP_KEY_RETCODE "result_code"
#define CN_PROFILE_CMDRESP_KEY_RESPNAME "response_name"
#define CN_PROFILE_CMDRESP_KEY_PARAS "paras"
static char *MakeProfileCmdResp(IoTCmdResp_t *payload)
{
char *ret = NULL;
cJSON *root;
cJSON *retCode;
cJSON *respName;
cJSON *paras;
// < create the root node
root = cJSON_CreateObject();
if (root == NULL) {
cJSON_Delete(root);
return ret;
}
// < create retcode and retdesc and add it to the root
retCode = cJSON_CreateNumber(payload->retCode);
if (retCode == NULL) {
if (root != NULL) {
cJSON_Delete(root);
}
return ret;
}
cJSON_AddItemToObjectCS(root, CN_PROFILE_CMDRESP_KEY_RETCODE, retCode);
if (payload->respName != NULL) {
respName = cJSON_CreateString(payload->respName);
if (respName == NULL) {
if (root != NULL) {
cJSON_Delete(root);
}
return ret;
}
cJSON_AddItemToObjectCS(root, CN_PROFILE_CMDRESP_KEY_RESPNAME, respName);
}
if (payload->paras != NULL) {
paras = MakeKvs(payload->paras);
if (paras == NULL) {
if (root != NULL) {
cJSON_Delete(root);
}
return ret;
}
cJSON_AddItemToObjectCS(root, CN_PROFILE_CMDRESP_KEY_PARAS, paras);
}
// < OK, now we make it to a buffer
ret = cJSON_PrintUnformatted(root);
cJSON_Delete(root);
return ret;
}
static char *MakeProfilePropertyReport(IoTProfileService_t *payload)
{
char *ret = NULL;
cJSON *root;
cJSON *services;
// < create the root node
root = cJSON_CreateObject();
if (root == NULL) {
cJSON_Delete(root);
return ret;
}
// < create the services array node to the root
services = MakeServices(payload);
if (services == NULL) {
if (root != NULL) {
cJSON_Delete(root);
}
return ret;
}
cJSON_AddItemToObjectCS(root, CN_PROFILE_KEY_SERVICES, services);
// < OK, now we make it to a buffer
ret = cJSON_PrintUnformatted(root);
cJSON_Delete(root);
return ret;
}
#define WECHAT_SUBSCRIBE_TYPE "update"
#define WECHAT_SUBSCRIBE_VERSION "1.0.0"
#define WECHAT_SUBSCRIBE_TOKEN "DeviceSubscribe"
static char *MakeProfileReport(WeChatProfile *payload)
{
char *ret = NULL;
cJSON *root;
cJSON *state;
cJSON *reported;
/* create json root node */
root = cJSON_CreateObject();
if (root == NULL) {
return;
}
/* state create */
state = cJSON_CreateObject();
if (state == NULL) {
return;
}
/* reported create */
reported = cJSON_CreateObject();
if (reported == NULL) {
return;
}
/* add root object */
cJSON_AddItemToObject(root, payload->subscribeType, cJSON_CreateString(WECHAT_SUBSCRIBE_TYPE));
cJSON_AddItemToObject(root, payload->status.subState, state);
cJSON_AddItemToObject(state, payload->status.subReport, reported);
cJSON_AddItemToObject(root, payload->status.reportVersion, cJSON_CreateString(WECHAT_SUBSCRIBE_VERSION));
cJSON_AddItemToObject(root, payload->status.Token, cJSON_CreateString(WECHAT_SUBSCRIBE_TOKEN));
/* add reported item */
cJSON_AddNumberToObject(reported, payload->reportAction.subDeviceActionLight,
payload->reportAction.lightActionStatus);
cJSON_AddNumberToObject(reported, payload->reportAction.subDeviceActionMotor,
payload->reportAction.motorActionStatus);
cJSON_AddNumberToObject(reported, payload->reportAction.subDeviceActionTemperature,
payload->reportAction.temperatureData);
cJSON_AddNumberToObject(reported, payload->reportAction.subDeviceActionHumidity,
payload->reportAction.humidityActionData);
cJSON_AddNumberToObject(reported, payload->reportAction.subDeviceActionLightIntensity,
payload->reportAction.lightIntensityActionData);
ret = cJSON_PrintUnformatted(root);
cJSON_Delete(state);
cJSON_Delete(reported);
cJSON_Delete(root);
return ret;
}
#define CN_PROFILE_TOPICFMT_TOPIC "YT32IOSCAL/Hi38611_mqtt/data"
int IoTProfilePropertyReport(char *deviceID, WeChatProfile *payload)
{
int ret = -1;
char *topic;
char *msg;
if ((deviceID == NULL) || (payload== NULL)) {
return ret;
}
topic = MakeTopic(CN_PROFILE_TOPICFMT_TOPIC, deviceID, NULL);
if (topic == NULL) {
return;
}
msg = MakeProfileReport(payload);
if ((topic != NULL) && (msg != NULL)) {
ret = IotSendMsg(0, topic, msg);
}
hi_free(0, topic);
cJSON_free(msg);
return ret;
}

@ -0,0 +1,94 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IOT_PROFILE_H
#define IOT_PROFILE_H
#include <hi_types_base.h>
#include "iot_config.h"
#define OC_BEEP_STATUS_ON ((hi_u8) 0x01)
#define OC_BEEP_STATUS_OFF ((hi_u8) 0x00)
// < enum all the data type for the oc profile
typedef enum {
EN_IOT_DATATYPE_INT = 0,
EN_IOT_DATATYPE_LONG,
EN_IOT_DATATYPE_FLOAT,
EN_IOT_DATATYPE_DOUBLE,
EN_IOT_DATATYPE_STRING, // < must be ended with '\0'
EN_IOT_DATATYPE_LAST,
}IoTDataType_t;
typedef enum {
OC_LED_ON = 1,
OC_LED_OFF
}OcLedValue;
typedef struct {
void *nxt; // < ponit to the next key
const char *key;
const char *value;
hi_u32 iValue;
IoTDataType_t type;
}IoTProfileKV_t;
typedef struct {
void *nxt;
char *serviceID;
char *eventTime;
IoTProfileKV_t *serviceProperty;
}IoTProfileService_t;
typedef struct {
int retCode; // < response code, 0 success while others failed
const char *respName; // < response name
const char *requestID; // < specified by the message command
IoTProfileKV_t *paras; // < the command paras
}IoTCmdResp_t;
typedef struct {
const char *subState;
const char *subReport;
const char *reportVersion;
const char *Token;
}WeChatProfileStatus;
typedef struct {
int lightActionStatus;
int motorActionStatus;
int temperatureData;
int humidityActionData;
int lightIntensityActionData;
const char *subDeviceActionLight;
const char *subDeviceActionMotor;
const char *subDeviceActionTemperature;
const char *subDeviceActionHumidity;
const char *subDeviceActionLightIntensity;
}WeChatProfileReporte;
typedef struct {
const char *subscribeType;
WeChatProfileStatus status;
WeChatProfileReporte reportAction;
}WeChatProfile;
/**
* use this function to report the property to the iot platform
*/
int IoTProfilePropertyReport(char *deviceID, WeChatProfile *payload);
void cJsonInit(void);
void WifiStaReadyWait(void);
#endif

@ -0,0 +1,269 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// < this demo make the wifi to connect to the specified AP
#include <unistd.h>
#include <hi_wifi_api.h>
#include <lwip/ip_addr.h>
#include <lwip/netifapi.h>
#include <hi_types_base.h>
#include <hi_task.h>
#include <hi_mem.h>
#include "iot_config.h"
#include "iot_log.h"
#include "wifi_device.h"
#include "cmsis_os2.h"
#include "wifi_device_config.h"
#include "lwip/api_shell.h"
#define APP_INIT_VAP_NUM 2
#define APP_INIT_USR_NUM 2
static struct netif *gLwipNetif = NULL;
static hi_bool gScanDone = HI_FALSE;
unsigned char wifiStatus = 0;
unsigned char wifiFirstConnecting = 0;
unsigned char wifiSecondConnecting = 0;
unsigned char wifiSecondConnected = 0;
static struct netif* g_iface = NULL;
void WifiStopSta(int netId);
static int WifiStartSta(void);
int cnetId = -1;
int g_connected = 0;
#define WIFI_CONNECT_STATUS ((unsigned char)0x02)
void wifiReconnected(int netId)
{
int recnetId = netId;
if (wifiFirstConnecting == WIFI_CONNECT_STATUS) {
wifiSecondConnecting = HI_TRUE;
wifiFirstConnecting = HI_FALSE;
WifiStopSta(recnetId);
ip4_addr_t ipAddr;
ip4_addr_t ipAny;
IP4_ADDR(&ipAny, 0, 0, 0, 0);
IP4_ADDR(&ipAddr, 0, 0, 0, 0);
recnetId = WifiStartSta();
netifapi_dhcp_start(gLwipNetif);
while (0 == memcmp(&ipAddr, &ipAny, sizeof(ip4_addr_t))) {
IOT_LOG_DEBUG("<Wifi reconnecting>:Wait the DHCP READY");
netifapi_netif_get_addr(gLwipNetif, &ipAddr, NULL, NULL);
hi_sleep(1000); /* 1000: cpu sleep 1000 ms */
}
wifiSecondConnected = HI_FALSE;
wifiFirstConnecting = WIFI_CONNECT_STATUS;
wifiStatus = HI_WIFI_EVT_CONNECTED;
}
}
/* clear netif's ip, gateway and netmask */
static void StaResetAddr(struct netif *lwipNetif)
{
ip4_addr_t st_gw;
ip4_addr_t st_ipaddr;
ip4_addr_t st_netmask;
if (lwipNetif == NULL) {
IOT_LOG_ERROR("hisi_reset_addr::Null param of netdev");
return;
}
IP4_ADDR(&st_gw, 0, 0, 0, 0);
IP4_ADDR(&st_ipaddr, 0, 0, 0, 0);
IP4_ADDR(&st_netmask, 0, 0, 0, 0);
netifapi_netif_set_addr(lwipNetif, &st_ipaddr, &st_netmask, &st_gw);
}
static void WpaEventCB(const hi_wifi_event *hisiEvent)
{
if (hisiEvent == NULL)
return;
IOT_LOG_DEBUG("EVENT_TYPE:%d", hisiEvent->event);
switch (hisiEvent->event) {
case HI_WIFI_EVT_SCAN_DONE:
IOT_LOG_DEBUG("WiFi: Scan results available");
gScanDone = HI_TRUE;
break;
case HI_WIFI_EVT_CONNECTED:
IOT_LOG_DEBUG("WiFi: Connected");
netifapi_dhcp_start(gLwipNetif);
wifiStatus = HI_WIFI_EVT_CONNECTED;
if (wifiSecondConnected) {
wifiSecondConnected = HI_FALSE;
wifiFirstConnecting = WIFI_CONNECT_STATUS;
}
break;
case HI_WIFI_EVT_DISCONNECTED:
IOT_LOG_DEBUG("WiFi: Disconnected");
netifapi_dhcp_stop(gLwipNetif);
StaResetAddr(gLwipNetif);
wifiStatus = HI_WIFI_EVT_DISCONNECTED;
wifiReconnected(cnetId);
break;
case HI_WIFI_EVT_WPS_TIMEOUT:
IOT_LOG_DEBUG("WiFi: wps is timeout");
wifiStatus = HI_WIFI_EVT_WPS_TIMEOUT;
break;
default:
break;
}
}
static int StaStartConnect(void)
{
int ret;
errno_t rc;
hi_wifi_assoc_request assoc_req = {0};
/* copy SSID to assoc_req */
rc = memcpy_s(assoc_req.ssid, HI_WIFI_MAX_SSID_LEN + 1, CONFIG_AP_SSID, strlen(CONFIG_AP_SSID));
if (rc != EOK) {
return -1;
}
/*
* OPEN mode
* for WPA2-PSK mode:
* set assoc_req.auth as HI_WIFI_SECURITY_WPA2PSK,
* then memcpy(assoc_req.key, "12345678", 8).
*/
assoc_req.auth = HI_WIFI_SECURITY_WPA2PSK;
rc = memcpy_s(assoc_req.key, HI_WIFI_MAX_KEY_LEN + 1, CONFIG_AP_PWD, strlen(CONFIG_AP_PWD));
if (rc != EOK) {
return -1;
}
ret = hi_wifi_sta_connect(&assoc_req);
if (ret != HISI_OK) {
return -1;
}
return 0;
}
static void PrintLinkedInfo(WifiLinkedInfo* info)
{
int ret = 0;
if (!info) {
return;
}
static char macAddress[32] = {0};
unsigned char* mac = info->bssid;
if (snprintf_s(macAddress, sizeof(macAddress) + 1, sizeof(macAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]) < 0) { /* mac地址从0,1,2,3,4,5位 */
return;
}
}
static void OnWifiConnectionChanged(int state, WifiLinkedInfo* info)
{
if (!info) {
return;
}
printf("%s %d, state = %d, info = \r\n", __FUNCTION__, __LINE__, state);
PrintLinkedInfo(info);
if (state == WIFI_STATE_AVALIABLE) {
g_connected = 1;
} else {
g_connected = 0;
}
}
static void OnWifiScanStateChanged(int state, int size)
{
printf("%s %d, state = %X, size = %d\r\n", __FUNCTION__, __LINE__, state, size);
}
static WifiEvent g_defaultWifiEventListener = {
.OnWifiConnectionChanged = OnWifiConnectionChanged,
.OnWifiScanStateChanged = OnWifiScanStateChanged
};
static int WifiStartSta(void)
{
WifiDeviceConfig apConfig = {0};
strcpy_s(apConfig.ssid, sizeof(CONFIG_AP_SSID), CONFIG_AP_SSID);
strcpy_s(apConfig.preSharedKey, sizeof(CONFIG_AP_PWD), CONFIG_AP_PWD);
apConfig.securityType = WIFI_SEC_TYPE_PSK;
WifiErrorCode errCode;
int netId = -1;
errCode = RegisterWifiEvent(&g_defaultWifiEventListener);
printf("RegisterWifiEvent: %d\r\n", errCode);
errCode = EnableWifi();
printf("EnableWifi: %d\r\n", errCode);
errCode = AddDeviceConfig(&apConfig, &netId);
printf("AddDeviceConfig: %d\r\n", errCode);
g_connected = 0;
errCode = ConnectTo(netId);
printf("ConnectTo(%d): %d\r\n", netId, errCode);
while (!g_connected) { // wait until connect to AP
osDelay(10); /* 10: os sleep 10ms */
}
printf("g_connected: %d\r\n", g_connected);
g_iface = netifapi_netif_find("wlan0");
if (g_iface) {
err_t ret = netifapi_dhcp_start(g_iface);
printf("netifapi_dhcp_start: %d\r\n", ret);
osDelay(100); // 100: os sleep 100ms wait DHCP server give me IP
ret = netifapi_netif_common(g_iface, dhcp_clients_info_show, NULL);
printf("netifapi_netif_common: %d\r\n", ret);
}
return netId;
}
void WifiStopSta(int netId)
{
int stopNetId = netId;
if (g_iface) {
err_t ret = netifapi_dhcp_stop(g_iface);
printf("netifapi_dhcp_stop: %d\r\n", ret);
}
WifiErrorCode errCode = Disconnect(); // disconnect with your AP
printf("Disconnect: %d\r\n", errCode);
errCode = UnRegisterWifiEvent(&g_defaultWifiEventListener);
printf("UnRegisterWifiEvent: %d\r\n", errCode);
RemoveDevice(stopNetId); // remove AP config
printf("RemoveDevice: %d\r\n", errCode);
errCode = DisableWifi();
printf("DisableWifi: %d\r\n", errCode);
}
void WifiStaReadyWait(void)
{
ip4_addr_t ipAddr;
ip4_addr_t ipAny;
IP4_ADDR(&ipAny, 0, 0, 0, 0);
IP4_ADDR(&ipAddr, 0, 0, 0, 0);
cnetId = WifiStartSta();
IOT_LOG_DEBUG("wifi sta dhcp done");
}

@ -0,0 +1,39 @@
# Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("appDemoIot") {
sources = [
"app_demo_iot.c",
"cjson_init.c",
"iot_hmac.c",
"iot_log.c",
"iot_main.c",
"iot_profile.c",
"iot_sta.c",
]
include_dirs = [
"./",
"//utils/native/lite/include",
"//kernel/liteos_m/kal/cmsis",
"//base/iot_hardware/peripheral/interfaces/kits",
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/lwip_sack/include/lwip",
"//third_party/cJSON",
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/mbedtls/include/mbedtls",
"//foundation/communication/wifi_lite/interfaces/wifiservice",
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/paho.mqtt.c/include/mqtt",
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/libcoap/include/coap2",
]
defines = [ "WITH_LWIP" ]
}

@ -0,0 +1,226 @@
# 腾讯云的微信小程序开发及Hi3861板端互联
## 硬件环境搭建
- 硬件要求Hi3861V100核心板、扩展板硬件搭建如下图所示。
- [Hi3861V100核心板参考HiSpark_WiFi_IoT智能开发套件_原理图硬件资料\原理图\HiSpark_WiFi-IoT_Hi3861_CH340G_VER.B.pdf](http://gitee.com/hihope_iot/embedded-race-hisilicon-track-2022/blob/master/%E7%A1%AC%E4%BB%B6%E8%B5%84%E6%96%99/HiSpark_WiFi_IoT%E6%99%BA%E8%83%BD%E5%AE%B6%E5%B1%85%E5%BC%80%E5%8F%91%E5%A5%97%E4%BB%B6_%E5%8E%9F%E7%90%86%E5%9B%BE.rar)
- [扩展板参考HiSpark_WiFi_IoT智能开发套件_原理图硬件资料\原理图\HiSpark_WiFi-IoT_Hi3861_CH340G_VER.B.pdf](http://gitee.com/hihope_iot/embedded-race-hisilicon-track-2022/blob/master/%E7%A1%AC%E4%BB%B6%E8%B5%84%E6%96%99/HiSpark_WiFi_IoT%E6%99%BA%E8%83%BD%E5%AE%B6%E5%B1%85%E5%BC%80%E5%8F%91%E5%A5%97%E4%BB%B6_%E5%8E%9F%E7%90%86%E5%9B%BE.rar)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/260.jpg)
## 软件介绍
- 1.代码目录结构及相应接口功能介绍
```
vendor_hisilicon/hispark_pegasus/demo/iottencent_demo
├── app_demo_iot.c #IoSetPull();IoSetFunc();TaskMsleep()。
├── BUILD.gn # BUILD.gn文件由三部分内容目标、源文件、头文件路径构成,开发者根据需要填写,static_library中指定业务模块的编译结果为静态库文件led_example开发者根据实际情况完成填写。
| sources中指定静态库.a所依赖的.c文件及其路径若路径中包含"//"则表示绝对路径(此处为代码根路径),若不包含"//"则表示相对路径。include_dirs中指定source所需要依赖的.h文件路径。
├── cjson_init.c #
├── iot_config.h #
├── iot_hmac.c #
├── iot_hmac.h #
├── iot_log.c #
├── iot_log.h #
├── iot_main.c #
├── iot_main.h #
├── iot_profile.c #
├── iot_sta.c #
└── iot_profile.h #
```
- 2.Mqtt协议第三方软件与腾讯云之间的通信
2.1 浏览器搜索腾讯云,在腾讯云界面创建产品和设备,登录腾讯云后搜索“物联网通信”,进入页面后,物联网通信选择立即使用。进入页面后,选择产品列表栏->创建新产品->产品名称xxx,认证方式:密钥认证,点击确定。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8717.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8720.png)
2.2 在产品列表栏进入刚刚创建的新产品->设备列表->添加设备->创建新设备:设备名称,设备备注(选填),使用物联网通信提供密钥->保存->复制保存生成的密钥->开始管理设备(可以看到设备相应信息)。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8721.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8722.png)
2.3 添加设备,同时查看设备相应信息。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/800.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/801.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/802.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/803.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/804.png)
2.4 返回设备列表可以看到设备并未激活,接下来激活设备;下载[MQTT.fx-1.7.1 ](https://www.jensd.de/wordpress/?p=2746)下载完成后打开工具点击设备图标进入到设备界面配置ClientIDusername,password 等参数。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/806.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8730.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8731.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8732.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8733.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8734.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8735.png)
2.5 完成2.3步骤后可以在腾讯云设备列表里面看到设备状态显示已激活开始腾讯云与MQTT工具之间的通信。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8736.png)
2.6 MQTT.fx-1.7.1工具订阅腾讯云的topic腾讯云下发指令。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8737.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8738.png)
2.7 在腾讯云网页端点击“在线调试”。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8739.png)
2.8 可以在MQTT.fx-1.7.1工具中看到腾讯云网页端发过来的消息。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8740.png)
2.9 MQTT.fx-1.7.1工具发布腾讯云到的topic在设备影子中查看发布到腾讯云的消息。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8741.png)
```
{
"type":"update",
"state":{
"reported":{
"light":1,
"motor":1,
"temperature":25,
"humidity":60,
"light_intensity":50
}
},
"version":0,
"clientToken":"clientToken"
}
```
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8742.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8743.png)
- 3.微信小程序开发环境搭建及与腾讯云之间通信
3.1 注册申请小程序账号https://mp.weixin.qq.com/wxopen/waregister?action=step1。
3.2 登录小程序后选择IOT字样的账号在“开发”->“开发设置”页面可以看到小程序的AppID如下图所示详情请查看微信官方文档
https://developers.weixin.qq.com/miniprogram/dev/framework/quickstart/getstart.html#%E7%94%B3%E8%AF%B7%E5%B8%90%E5%8F%B7。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8744.png)
3.3 开发者工具下载与安装https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8745.png)
3.4 下载安装完成后,打开微信开发工具,导入提供的微信小程序软件包[获取微信小程序代码](https://gitee.com/leo593362220/Hi3861OpenHarmony)。并填入自己的APPID,后端服务选择微信云开发。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%87102.jpg)
3.5 使用微信开发者工具打开工程后需要修改project.config.json文件中appid,projectname修改成自己的。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8747.png)
3.6 获取secretId和secretKey在腾讯云->产品列表->搜索栏搜索访问密钥->访问密钥->继续使用->可以看到secretId和secretKey复制在xxxx.txt文件后面需要。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8749.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8750.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8751.png)
3.7 环境ID配置并获取环境ID,复制在xxx.txt文件后面需要。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8752.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8753.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8754.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8755.png)![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8747.png)
3.8 需要修改app.js文件中productId腾讯云上设备信息上产品ID,deviceName腾讯云上设备信息上产品名称,secretId和secretKey(3.6步骤获取到的secretId和secretKey)env3.7步骤获取到的环境ID
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8748.png)
3.9 配置当前云环境
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8756.png)
注意:第一次部署环境,图片里面的上传并部署会变成新建并部署。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8757.png)
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/228.jpg)
等待大概1分钟左右直到出现上传云函数成功注意上传并部署由于网络问题可能会失败看到上传云函数等字样代表上传部署成功这里以iothub-publish为例
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8758.png)
3.10 环境部署完成后,点击编译,然后真机调试会出现如下界面,上面两个都要出现
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8761.png)
- 4.Hi3861V100与微信小程序之间通信
- 将源码./vendor/hisilicon/hispark_pegasus/demo目录下的iottencent_demo整个文件夹及内容复制到源码./applications/sample/wifi-iot/app/下。
```
.
└── applications
└── sample
└── wifi-iot
└── app
└──iottencent_demo
└── 代码
```
- 配置源码./applications/sample/wifi-iot/app/iottencent_demo/iot_config.h中CONFIG_AP_SSIDCONFIG_AP_PWD为WiFi名称和WiFi密码。CONFIG_USER_ID为腾讯云设备信息上MQTT UsernameCONFIG_USER_PWD为腾讯云上设备的MQTT Password,CN_CLIENTID为腾讯云上clientID。
```
#define CONFIG_AP_SSID "XXXXXXXX" // WIFI SSID
#define CONFIG_AP_PWD "XXXXX" // WIFI PWD
/* Tencent iot Cloud user ID , password */
#define CONFIG_USER_ID "XXXXXXXXXXXXX"
#define CONFIG_USER_PWD "XXXXXXXXXXXX"
#define CN_CLIENTID "xxxxxxxx" // Tencent cloud ClientID format: Product ID + device name
```
- 更改源码./applications/sample/wifi-iot/app/iottencent_demo/iot_main.c文件中搜索g_defaultSubscribeTopic字段将腾讯云上的Topic列表中自定义Topic添加到字段里。
```
static const char *g_defaultSubscribeTopic[] = {
"76VQ4ZASTL/mqtt/data",
"76VQ4ZASTL/mqtt/event",
"76VQ4ZASTL/mqtt/control",
};
```
- 更改源码./applications/sample/wifi-iot/app/iottencent_demo/iot_profile.c文件中搜索CN_PROFILE_TOPICFMT_TOPIC字段将腾讯云上的产品名设备名称添加到字段里。
```
#define CN_PROFILE_TOPICFMT_TOPIC "$shadow/operation/xxxxx/XXXX" //xxxx为产品名和设备名称76VQ4ZASTL
```
- 修改源码./applications/sample/wifi-iot/app/BUILD.gn文件在features字段中增加索引使目标模块参与编译。features字段指定业务模块的路径和目标,features字段配置如下。
```
import("//build/lite/config/component/lite_component.gni")
lite_component("app") {
features = [
"iottencent_demo:appDemoIot",
]
}
```
- 工程相关配置完成后,然后编译。
- 5.烧录
- 编译成功后点击DevEco Home->配置工程->hi3861->upload_port->选择对应串口端口号->选择upload_protocol->选择hiburn-serial->点击save保存在保存成功后点击upload进行烧录出现connecting, please reset device..字样复位开发板等待烧录完成。烧录成功后再次点击Hi3861核心板上的“RST”复位键此时开发板的系统会运行起来。
- 注意:一定要断开MQTT工具的连接。
- 微信小程序上选择已连接Wifi,跳过配网->云端互联->看到设备互联界面->点击刷新按钮,运行结果出现如下图代表成功,点击照明,主板灯会亮。
![输入图片说明](https://gitee.com/asd1122/tupian/raw/master/%E5%9B%BE%E7%89%87/%E5%9B%BE%E7%89%8762.png)

@ -0,0 +1,178 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <hi_task.h>
#include <string.h>
#include <hi_wifi_api.h>
#include <hi_mux.h>
#include <hi_io.h>
#include <hi_gpio.h>
#include "iot_config.h"
#include "iot_log.h"
#include "iot_main.h"
#include "iot_profile.h"
#include "ohos_init.h"
#include "cmsis_os2.h"
/* attribute initiative to report */
#define TAKE_THE_INITIATIVE_TO_REPORT
#define ONE_SECOND (1000)
/* oc request id */
#define CN_COMMADN_INDEX "commands/request_id="
#define WECHAT_SUBSCRIBE_LIGHT "light"
#define WECHAT_SUBSCRIBE_LIGHT_ON_STATE "1"
#define WECHAT_SUBSCRIBE_LIGHT_OFF_STATE "0"
int g_ligthStatus = -1;
typedef void (*FnMsgCallBack)(hi_gpio_value val);
typedef struct FunctionCallback {
hi_bool stop;
hi_u32 conLost;
hi_u32 queueID;
hi_u32 iotTaskID;
FnMsgCallBack msgCallBack;
}FunctionCallback;
FunctionCallback g_functinoCallback;
/* CPU Sleep time Set */
unsigned int TaskMsleep(unsigned int ms)
{
if (ms <= 0) {
return HI_ERR_FAILURE;
}
return hi_sleep((hi_u32)ms);
}
static void DeviceConfigInit(hi_gpio_value val)
{
hi_io_set_func(HI_IO_NAME_GPIO_9, HI_IO_FUNC_GPIO_9_GPIO);
hi_gpio_set_dir(HI_GPIO_IDX_9, HI_GPIO_DIR_OUT);
hi_gpio_set_ouput_val(HI_GPIO_IDX_9, val);
}
static int DeviceMsgCallback(FnMsgCallBack msgCallBack)
{
g_functinoCallback.msgCallBack = msgCallBack;
return 0;
}
static void wechatControlDeviceMsg(hi_gpio_value val)
{
DeviceConfigInit(val);
}
// < this is the callback function, set to the mqtt, and if any messages come, it will be called
// < The payload here is the json string
static void DemoMsgRcvCallBack(int qos, const char *topic, const char *payload)
{
IOT_LOG_DEBUG("RCVMSG:QOS:%d TOPIC:%s PAYLOAD:%s\r\n", qos, topic, payload);
/* 云端下发命令后,板端的操作处理 */
if (strstr(payload, WECHAT_SUBSCRIBE_LIGHT) != NULL) {
if (strstr(payload, WECHAT_SUBSCRIBE_LIGHT_OFF_STATE) != NULL) {
wechatControlDeviceMsg(HI_GPIO_VALUE1);
g_ligthStatus = HI_FALSE;
} else {
wechatControlDeviceMsg(HI_GPIO_VALUE0);
g_ligthStatus = HI_TRUE;
}
}
return HI_NULL;
}
/* publish sample */
hi_void IotPublishSample(void)
{
/* reported attribute */
WeChatProfile weChatProfile = {
.subscribeType = "type",
.status.subState = "state",
.status.subReport = "reported",
.status.reportVersion = "version",
.status.Token = "clientToken",
/* report motor */
.reportAction.subDeviceActionMotor = "motor",
.reportAction.motorActionStatus = 0, /* 0 : motor off */
/* report temperature */
.reportAction.subDeviceActionTemperature = "temperature",
.reportAction.temperatureData = 30, /* 30 :temperature data */
/* report humidity */
.reportAction.subDeviceActionHumidity = "humidity",
.reportAction.humidityActionData = 70, /* humidity data */
/* report light_intensity */
.reportAction.subDeviceActionLightIntensity = "light_intensity",
.reportAction.lightIntensityActionData = 60, /* 60 : light_intensity */
};
/* report light */
if (g_ligthStatus == HI_TRUE) {
weChatProfile.reportAction.subDeviceActionLight = "light";
weChatProfile.reportAction.lightActionStatus = 1; /* 1: light on */
} else if (g_ligthStatus == HI_FALSE) {
weChatProfile.reportAction.subDeviceActionLight = "light";
weChatProfile.reportAction.lightActionStatus = 0; /* 0: light off */
} else {
weChatProfile.reportAction.subDeviceActionLight = "light";
weChatProfile.reportAction.lightActionStatus = 0; /* 0: light off */
}
/* profile report */
IoTProfilePropertyReport(CONFIG_USER_ID, &weChatProfile);
}
// < this is the demo main task entry,here we will set the wifi/cjson/mqtt ready and
// < wait if any work to do in the while
static hi_void *DemoEntry(const char *arg)
{
WifiStaReadyWait();
cJsonInit();
IoTMain();
/* 云端下发回调 */
IoTSetMsgCallback(DemoMsgRcvCallBack);
/* 主动上报 */
#ifdef TAKE_THE_INITIATIVE_TO_REPORT
while (1) {
/* 用户可以在这调用发布函数进行发布,需要用户自己写调用函数 */
IotPublishSample(); // 发布例程
#endif
TaskMsleep(ONE_SECOND);
}
return NULL;
}
// < This is the demo entry, we create a task here,
// and all the works has been done in the demo_entry
#define CN_IOT_TASK_STACKSIZE 0x1000
#define CN_IOT_TASK_PRIOR 25
#define CN_IOT_TASK_NAME "IOTDEMO"
static void AppDemoIot(void)
{
osThreadAttr_t attr;
IoTWatchDogDisable();
attr.name = "IOTDEMO";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = CN_IOT_TASK_STACKSIZE;
attr.priority = CN_IOT_TASK_PRIOR;
if (osThreadNew((osThreadFunc_t)DemoEntry, NULL, &attr) == NULL) {
printf("[mqtt] Falied to create IOTDEMO!\n");
}
}
SYS_RUN(AppDemoIot);

@ -0,0 +1,38 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdint.h>
#include <cJSON.h>
#include <hi_mem.h>
static void *cJsonMalloc(size_t sz)
{
return hi_malloc(0, sz);
}
static void cJsonFree(const char *p)
{
hi_free(0, p);
}
void cJsonInit(void)
{
cJSON_Hooks hooks;
hooks.malloc_fn = cJsonMalloc;
hooks.free_fn = cJsonFree;
cJSON_InitHooks(&hooks);
return;
}

@ -0,0 +1,31 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IOT_CONFIG_H
#define IOT_CONFIG_H
// <CONFIG THE LOG
/* if you need the iot log for the development , please enable it, else please comment it */
#define CONFIG_LINKLOG_ENABLE 1
// < CONFIG THE WIFI
/* Please modify the ssid and pwd for the own */
#define CONFIG_AP_SSID "Sidi_iPhone" // WIFI SSID
#define CONFIG_AP_PWD "12345678" // WIFI PWD
/* Tencent iot Cloud user ID , password */
#define CONFIG_USER_ID "YT32IOSCALHi38611_mqtt;12010126;41883;1663689600"
#define CONFIG_USER_PWD "b4168d5d4b65898e6984346c81ad13e1b3f112ab7ce46f65cf29455f4c9e18e8;hmacsha256"
#define CN_CLIENTID "YT32IOSCALHi38611_mqtt" // Tencent cloud ClientID format: Product ID + device name
#endif

@ -0,0 +1,95 @@
/*
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This file make use the hmac to make mqtt pwd.
* The method is use the date string to hash the device passwd
* Take care that this implement depends on the hmac of the mbedtls
*/
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include "md.h"
#include "md_internal.h"
#define CN_HMAC256_LEN_MAX (65)
#define CN_HMAC256_LEN 32
#define RIGHT_MOVE_BIT_4 (4)
#define NUMBER_9 (9)
#define DECIMAL_BASE (10)
#define STRING_LEN_TIMES (2)
#define LEN_TIMES (2)
#define OFFSET (1)
// make a byte to 2 ascii hex
static int byte2hexstr(unsigned char *bufin, int len, char *bufout)
{
int i = 0;
unsigned char tmp_l = 0x0;
unsigned char tmp_h = 0;
if ((bufin == NULL)||(len <= 0)||(bufout == NULL)) {
return -1;
}
for (i = 0; i < len; i++) {
tmp_h = (bufin[i] >> RIGHT_MOVE_BIT_4) & 0X0F;
tmp_l = bufin[i] & 0x0F;
bufout[STRING_LEN_TIMES * i] = (tmp_h > NUMBER_9) ?
(tmp_h - DECIMAL_BASE + 'a'):(tmp_h +'0');
bufout[STRING_LEN_TIMES * i + OFFSET] = (tmp_l > NUMBER_9) ?
(tmp_l - DECIMAL_BASE + 'a'):(tmp_l +'0');
}
bufout[STRING_LEN_TIMES * len] = '\0';
return 0;
}
int HmacGeneratePwd(const unsigned char *content, int contentLen, const unsigned char *key,
int keyLen, unsigned char *buf)
{
int ret = -1;
mbedtls_md_context_t mbedtls_md_ctx;
const mbedtls_md_info_t *md_info;
unsigned char hash[CN_HMAC256_LEN];
if ((key == NULL)||(content == NULL)||(buf == NULL)||
(keyLen == 0)||(contentLen == 0)||
(CN_HMAC256_LEN_MAX < (CN_HMAC256_LEN * LEN_TIMES + OFFSET))) {
return ret;
}
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
if ((md_info == NULL)||((size_t)md_info->size > CN_HMAC256_LEN)) {
return ret;
}
mbedtls_md_init(&mbedtls_md_ctx);
ret = mbedtls_md_setup(&mbedtls_md_ctx, md_info, 1);
if (ret != 0) {
mbedtls_md_free(&mbedtls_md_ctx);
return ret;
}
(void)mbedtls_md_hmac_starts(&mbedtls_md_ctx, key, keyLen);
(void)mbedtls_md_hmac_update(&mbedtls_md_ctx, content, contentLen);
(void)mbedtls_md_hmac_finish(&mbedtls_md_ctx, hash);
// <transfer the hash code to the string mode
ret = byte2hexstr(hash, CN_HMAC256_LEN, (char *)buf);
if (ret != 0) {
return ret;
}
return ret;
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save