Răsfoiți Sursa

短信猫串口模块:未完成。

Jeff 5 ani în urmă
părinte
comite
7806f02896
40 a modificat fișierele cu 4778 adăugiri și 0 ștergeri
  1. 69 0
      短信猫/sms/SMSTest/ReadMe.txt
  2. 28 0
      短信猫/sms/SMSTest/Resource.h
  3. 79 0
      短信猫/sms/SMSTest/SMSTest.cpp
  4. 32 0
      短信猫/sms/SMSTest/SMSTest.h
  5. 215 0
      短信猫/sms/SMSTest/SMSTest.rc
  6. 304 0
      短信猫/sms/SMSTest/SMSTest.vcproj
  7. 261 0
      短信猫/sms/SMSTest/SMSTestDlg.cpp
  8. 41 0
      短信猫/sms/SMSTest/SMSTestDlg.h
  9. BIN
      短信猫/sms/SMSTest/res/SMSTest.ico
  10. 13 0
      短信猫/sms/SMSTest/res/SMSTest.rc2
  11. 8 0
      短信猫/sms/SMSTest/stdafx.cpp
  12. 60 0
      短信猫/sms/SMSTest/stdafx.h
  13. 26 0
      短信猫/sms/SMSTest/targetver.h
  14. 25 0
      短信猫/sms/sms-17.sln
  15. 26 0
      短信猫/sms/sms.sln
  16. 10 0
      短信猫/sms/sms/AsynSerial.cpp
  17. 31 0
      短信猫/sms/sms/AsynSerial.h
  18. 216 0
      短信猫/sms/sms/CommRS232.cpp
  19. 42 0
      短信猫/sms/sms/CommRS232.h
  20. 10 0
      短信猫/sms/sms/CompletionSerial.cpp
  21. 31 0
      短信猫/sms/sms/CompletionSerial.h
  22. 44 0
      短信猫/sms/sms/ReadMe.txt
  23. 16 0
      短信猫/sms/sms/Resource.h
  24. 901 0
      短信猫/sms/sms/SMSProcess.cpp
  25. 130 0
      短信猫/sms/sms/SMSProcess.h
  26. 781 0
      短信猫/sms/sms/ShortMessageService.cpp
  27. 124 0
      短信猫/sms/sms/ShortMessageService.h
  28. 312 0
      短信猫/sms/sms/SynSerial.cpp
  29. 83 0
      短信猫/sms/sms/SynSerial.h
  30. 13 0
      短信猫/sms/sms/res/sms.rc2
  31. 63 0
      短信猫/sms/sms/sms.cpp
  32. 6 0
      短信猫/sms/sms/sms.def
  33. 27 0
      短信猫/sms/sms/sms.h
  34. 125 0
      短信猫/sms/sms/sms.rc
  35. 311 0
      短信猫/sms/sms/sms.vcproj
  36. 149 0
      短信猫/sms/sms/sms.vcxproj
  37. 94 0
      短信猫/sms/sms/sms.vcxproj.filters
  38. 7 0
      短信猫/sms/sms/stdafx.cpp
  39. 39 0
      短信猫/sms/sms/stdafx.h
  40. 26 0
      短信猫/sms/sms/targetver.h

+ 69 - 0
短信猫/sms/SMSTest/ReadMe.txt

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

+ 28 - 0
短信猫/sms/SMSTest/Resource.h

@@ -0,0 +1,28 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by SMSTest.rc
+//
+#define IDM_ABOUTBOX                    0x0010
+#define IDD_ABOUTBOX                    100
+#define IDS_ABOUTBOX                    101
+#define IDD_SMSTEST_DIALOG              102
+#define IDR_MAINFRAME                   128
+#define COMBOX_COM                      1001
+#define COMBOX_BAUDRATE                 1002
+#define TEXT_SMSC                       1004
+#define IDC_EDIT3                       1005
+#define TEXT_TIMEOUT                    1005
+#define TEXT_RECEIVEPHONE               1006
+#define TEXT_CONTENT                    1007
+#define BTN_CSQ                         1008
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        130
+#define _APS_NEXT_COMMAND_VALUE         32771
+#define _APS_NEXT_CONTROL_VALUE         1009
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif

+ 79 - 0
短信猫/sms/SMSTest/SMSTest.cpp

@@ -0,0 +1,79 @@
+
+// SMSTest.cpp : 定义应用程序的类行为。
+//
+
+#include "stdafx.h"
+#include "SMSTest.h"
+#include "SMSTestDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CSMSTestApp
+
+BEGIN_MESSAGE_MAP(CSMSTestApp, CWinAppEx)
+	ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+
+// CSMSTestApp 构造
+
+CSMSTestApp::CSMSTestApp()
+{
+	// TODO: 在此处添加构造代码,
+	// 将所有重要的初始化放置在 InitInstance 中
+}
+
+
+// 唯一的一个 CSMSTestApp 对象
+
+CSMSTestApp theApp;
+
+
+// CSMSTestApp 初始化
+
+BOOL CSMSTestApp::InitInstance()
+{
+	// 如果一个运行在 Windows XP 上的应用程序清单指定要
+	// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
+	//则需要 InitCommonControlsEx()。否则,将无法创建窗口。
+	INITCOMMONCONTROLSEX InitCtrls;
+	InitCtrls.dwSize = sizeof(InitCtrls);
+	// 将它设置为包括所有要在应用程序中使用的
+	// 公共控件类。
+	InitCtrls.dwICC = ICC_WIN95_CLASSES;
+	InitCommonControlsEx(&InitCtrls);
+
+	CWinAppEx::InitInstance();
+
+	AfxEnableControlContainer();
+
+	// 标准初始化
+	// 如果未使用这些功能并希望减小
+	// 最终可执行文件的大小,则应移除下列
+	// 不需要的特定初始化例程
+	// 更改用于存储设置的注册表项
+	// TODO: 应适当修改该字符串,
+	// 例如修改为公司或组织名
+	SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
+
+	CSMSTestDlg dlg;
+	m_pMainWnd = &dlg;
+	INT_PTR nResponse = dlg.DoModal();
+	if (nResponse == IDOK)
+	{
+		// TODO: 在此放置处理何时用
+		//  “确定”来关闭对话框的代码
+	}
+	else if (nResponse == IDCANCEL)
+	{
+		// TODO: 在此放置处理何时用
+		//  “取消”来关闭对话框的代码
+	}
+
+	// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
+	//  而不是启动应用程序的消息泵。
+	return FALSE;
+}

+ 32 - 0
短信猫/sms/SMSTest/SMSTest.h

@@ -0,0 +1,32 @@
+
+// SMSTest.h : PROJECT_NAME 应用程序的主头文件
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+	#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
+#endif
+
+#include "resource.h"		// 主符号
+
+
+// CSMSTestApp:
+// 有关此类的实现,请参阅 SMSTest.cpp
+//
+
+class CSMSTestApp : public CWinAppEx
+{
+public:
+	CSMSTestApp();
+
+// 重写
+	public:
+	virtual BOOL InitInstance();
+
+// 实现
+
+	DECLARE_MESSAGE_MAP()
+};
+
+extern CSMSTestApp theApp;

+ 215 - 0
短信猫/sms/SMSTest/SMSTest.rc

@@ -0,0 +1,215 @@
+// 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
+
+/////////////////////////////////////////////////////////////////////////////
+// 中文(中华人民共和国) 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\\SMSTest.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\\SMSTest.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOGEX 0, 0, 170, 62
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "关于 SMSTest"
+FONT 9, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+    ICON            IDR_MAINFRAME,IDC_STATIC,14,14,21,20
+    LTEXT           "SMSTest,1.0 版",IDC_STATIC,42,14,114,8,SS_NOPREFIX
+    LTEXT           "Copyright (C) 2018",IDC_STATIC,42,26,114,8
+    DEFPUSHBUTTON   "确定",IDOK,113,41,50,14,WS_GROUP
+END
+
+IDD_SMSTEST_DIALOG DIALOGEX 0, 0, 306, 159
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "短信测试"
+FONT 9, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+    DEFPUSHBUTTON   "发送",IDOK,155,132,50,14
+    PUSHBUTTON      "退出",IDCANCEL,208,132,50,14
+    LTEXT           "端口号:",IDC_STATIC,28,16,28,8
+    COMBOBOX        COMBOX_COM,61,14,69,196,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    LTEXT           "波特率:",IDC_STATIC,157,16,28,8
+    COMBOBOX        COMBOX_BAUDRATE,187,14,69,190,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    LTEXT           "SMSC号码:",IDC_STATIC,17,35,39,8
+    EDITTEXT        TEXT_SMSC,61,32,69,14,ES_AUTOHSCROLL
+    LTEXT           "超时值:",IDC_STATIC,157,35,28,8
+    EDITTEXT        TEXT_TIMEOUT,187,32,69,14,ES_AUTOHSCROLL
+    LTEXT           "接收手机:",IDC_STATIC,21,54,35,8
+    EDITTEXT        TEXT_RECEIVEPHONE,61,51,69,14,ES_AUTOHSCROLL
+    LTEXT           "内容:",IDC_STATIC,34,72,22,8
+    EDITTEXT        TEXT_CONTENT,61,72,197,50,ES_MULTILINE | WS_VSCROLL
+    PUSHBUTTON      "信号强度",BTN_CSQ,186,53,69,14
+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", "SMSTest.exe"
+            VALUE "LegalCopyright", "TODO: (C) <公司名>。保留所有权利。"
+            VALUE "OriginalFilename", "SMSTest.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_ABOUTBOX, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 163
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 55
+    END
+
+    IDD_SMSTEST_DIALOG, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 299
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 152
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE 
+BEGIN
+    IDS_ABOUTBOX            "关于 SMSTest(&A)..."
+END
+
+#endif    // 中文(中华人民共和国) 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\SMSTest.rc2"  // 非 Microsoft Visual C++ 编辑的资源
+#include "l.CHS\afxres.rc"      // 标准组件
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+

+ 304 - 0
短信猫/sms/SMSTest/SMSTest.vcproj

@@ -0,0 +1,304 @@
+<?xml version="1.0" encoding="gb2312"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="SMSTest"
+	ProjectGUID="{CEC0508A-7157-4523-AA0A-86DCBC249FE0}"
+	RootNamespace="SMSTest"
+	Keyword="MFCProj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="..\..\..\..\bin\$(SolutionName)"
+			IntermediateDirectory="$(OutDir)\$(ProjectName)\$(ConfigurationName)"
+			ConfigurationType="1"
+			UseOfMFC="2"
+			CharacterSet="2"
+			>
+			<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="2"
+				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="..\..\..\..\bin\$(SolutionName)"
+			IntermediateDirectory="$(OutDir)\$(ProjectName)\$(ConfigurationName)"
+			ConfigurationType="1"
+			UseOfMFC="2"
+			CharacterSet="2"
+			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="Ô´Îļþ"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\sms\CommRS232.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\sms\ShortMessageService.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\sms\SMSProcess.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\SMSTest.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\SMSTestDlg.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>
+			<File
+				RelativePath="..\sms\SynSerial.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Í·Îļþ"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath="..\sms\CommRS232.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Resource.h"
+				>
+			</File>
+			<File
+				RelativePath="..\sms\ShortMessageService.h"
+				>
+			</File>
+			<File
+				RelativePath="..\sms\SMSProcess.h"
+				>
+			</File>
+			<File
+				RelativePath=".\SMSTest.h"
+				>
+			</File>
+			<File
+				RelativePath=".\SMSTestDlg.h"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.h"
+				>
+			</File>
+			<File
+				RelativePath="..\sms\SynSerial.h"
+				>
+			</File>
+			<File
+				RelativePath=".\targetver.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="×ÊÔ´Îļþ"
+			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\SMSTest.ico"
+				>
+			</File>
+			<File
+				RelativePath=".\SMSTest.rc"
+				>
+			</File>
+			<File
+				RelativePath=".\res\SMSTest.rc2"
+				>
+			</File>
+		</Filter>
+		<File
+			RelativePath=".\ReadMe.txt"
+			>
+		</File>
+	</Files>
+	<Globals>
+		<Global
+			Name="RESOURCE_FILE"
+			Value="SMSTest.rc"
+		/>
+	</Globals>
+</VisualStudioProject>

+ 261 - 0
短信猫/sms/SMSTest/SMSTestDlg.cpp

@@ -0,0 +1,261 @@
+
+// SMSTestDlg.cpp : 实现文件
+//
+
+#include "stdafx.h"
+#include "SMSTest.h"
+#include "SMSTestDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
+
+class CAboutDlg : public CDialog
+{
+public:
+	CAboutDlg();
+
+// 对话框数据
+	enum { IDD = IDD_ABOUTBOX };
+
+	protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
+
+// 实现
+protected:
+	DECLARE_MESSAGE_MAP()
+};
+
+CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
+{
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialog::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
+END_MESSAGE_MAP()
+
+
+// CSMSTestDlg 对话框
+
+
+
+
+CSMSTestDlg::CSMSTestDlg(CWnd* pParent /*=NULL*/)
+	: CDialog(CSMSTestDlg::IDD, pParent)
+{
+	m_bIsOpen = FALSE;
+	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+}
+
+void CSMSTestDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialog::DoDataExchange(pDX);
+	DDX_Control(pDX, COMBOX_COM, m_cbSerialPort);
+	DDX_Control(pDX, COMBOX_BAUDRATE, m_cbBaudrate);
+}
+
+BEGIN_MESSAGE_MAP(CSMSTestDlg, CDialog)
+	ON_WM_SYSCOMMAND()
+	ON_WM_PAINT()
+	ON_WM_QUERYDRAGICON()
+	//}}AFX_MSG_MAP
+	ON_BN_CLICKED(IDOK, &CSMSTestDlg::OnBnClickedOk)
+	ON_BN_CLICKED(BTN_CSQ, &CSMSTestDlg::OnBnClickedCsq)
+END_MESSAGE_MAP()
+
+
+// CSMSTestDlg 消息处理程序
+
+BOOL CSMSTestDlg::OnInitDialog()
+{
+	CDialog::OnInitDialog();
+
+	// 将“关于...”菜单项添加到系统菜单中。
+
+	// IDM_ABOUTBOX 必须在系统命令范围内。
+	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
+	ASSERT(IDM_ABOUTBOX < 0xF000);
+
+	CMenu* pSysMenu = GetSystemMenu(FALSE);
+	if (pSysMenu != NULL)
+	{
+		BOOL bNameValid;
+		CString strAboutMenu;
+		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
+		ASSERT(bNameValid);
+		if (!strAboutMenu.IsEmpty())
+		{
+			pSysMenu->AppendMenu(MF_SEPARATOR);
+			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
+		}
+	}
+
+	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
+	//  执行此操作
+	SetIcon(m_hIcon, TRUE);			// 设置大图标
+	SetIcon(m_hIcon, FALSE);		// 设置小图标
+
+	// TODO: 在此添加额外的初始化代码
+	InitControl();
+
+	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
+}
+
+void CSMSTestDlg::OnSysCommand(UINT nID, LPARAM lParam)
+{
+	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
+	{
+		CAboutDlg dlgAbout;
+		dlgAbout.DoModal();
+	}
+	else
+	{
+		CDialog::OnSysCommand(nID, lParam);
+	}
+}
+
+// 如果向对话框添加最小化按钮,则需要下面的代码
+//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
+//  这将由框架自动完成。
+
+void CSMSTestDlg::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 CSMSTestDlg::OnQueryDragIcon()
+{
+	return static_cast<HCURSOR>(m_hIcon);
+}
+
+void CSMSTestDlg::InitControl()
+{
+	// 串口号;
+	CString strCOM = _T("");
+	for ( int i = 1; i < 30; i++)
+	{
+		strCOM.Format(_T("COM%d"), i);
+		m_cbSerialPort.AddString(strCOM);
+	}
+	m_cbSerialPort.SetCurSel(0);
+
+	// 波特率;
+	const TCHAR *AryBaudRate[] = {
+		_T("1200"),
+		_T("2400"),
+		_T("4800"),
+		_T("9600"),
+		_T("11400"),
+		_T("19200"),
+		_T("38400"),
+		_T("56000"),
+		_T("57600"),
+		_T("115200"),
+		_T("128000"),
+		_T("256000"),
+		NULL
+	};
+
+	for ( int i = 0; AryBaudRate[i] != NULL; i++ )
+	{
+		m_cbBaudrate.AddString(AryBaudRate[i]);
+	}
+	m_cbBaudrate.SetCurSel(0);
+
+	// SMCM号码;
+	SetDlgItemText(TEXT_SMSC, _T("13352667321"));
+	// 发送内容;
+	SetDlgItemText(TEXT_CONTENT, _T("Test"));
+}
+
+void CSMSTestDlg::OnBnClickedOk()
+{
+	// TODO: 在此添加控件通知处理程序代码
+#if 0
+	if ( !m_bIsOpen )
+	{
+		if (SMSProcess::SMS_INIT(6, 115200, 8, 0, 1, 1, 1000, 67) == 0)
+			m_bIsOpen = TRUE;
+	}
+
+	if (!m_bIsOpen)
+		return;
+
+	CString strPhone = _T("");
+	CString strContent = _T("");
+	TCHAR szErrorMsg[100] = {0};
+	GetDlgItemText(TEXT_RECEIVEPHONE, strPhone);
+	GetDlgItemText(TEXT_CONTENT, strContent);
+	SMSProcess::SMS_SENDMSG(strPhone, strContent, szErrorMsg);
+#else
+	if ( !m_sms.IsOpen() )
+	{
+		if ( !m_sms.OpenSerialPort(6, 115200, 8, 0, 1, 1, 1000) )
+		{
+			return;
+		}
+
+		m_sms.InitGSM();
+	}
+
+	SM_PARAM smParam = {0};
+	smParam.nIndex = 0;
+	m_sms.InvertNumbers(_T("8615089231318"), (TCHAR*)smParam.SCA, _tcslen(_T("8615089231318")));
+	_stprintf((TCHAR*)smParam.TPA, _T(""));
+	_stprintf((TCHAR*)smParam.TP_SCTS, _T(""));
+	_stprintf((TCHAR*)smParam.TP_UD, _T(""));
+	smParam.TP_PID = 0;
+	smParam.TP_DCS = 0;
+	m_sms.SendShortMessage(&smParam);
+
+#endif
+}
+
+void CSMSTestDlg::OnBnClickedCsq()
+{
+#if 0
+	if ( !m_bIsOpen )
+	{
+		if (SMSProcess::SMS_INIT(6, 115200, 8, 0, 1, 1, 1000, 67) == 0)
+			m_bIsOpen = TRUE;
+	}
+#else
+	if ( !m_sms.IsOpen() )
+	{
+		if ( !m_sms.OpenSerialPort(6, 115200, 8, 0, 1, 1, 1000) )
+		{
+			return;
+		}
+	}
+
+#endif
+}

+ 41 - 0
短信猫/sms/SMSTest/SMSTestDlg.h

@@ -0,0 +1,41 @@
+
+// SMSTestDlg.h : 头文件
+//
+
+#pragma once
+#include "afxwin.h"
+#include "..\sms\ShortMessageService.h"
+
+// CSMSTestDlg 对话框
+class CSMSTestDlg : public CDialog
+{
+// 构造
+public:
+	CSMSTestDlg(CWnd* pParent = NULL);	// 标准构造函数
+
+// 对话框数据
+	enum { IDD = IDD_SMSTEST_DIALOG };
+
+	protected:
+	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持
+
+
+// 实现
+protected:
+	HICON m_hIcon;
+
+	// 生成的消息映射函数
+	virtual BOOL OnInitDialog();
+	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
+	afx_msg void OnPaint();
+	afx_msg HCURSOR OnQueryDragIcon();
+	DECLARE_MESSAGE_MAP()
+public:
+	BOOL m_bIsOpen;
+	CShortMessageService m_sms;
+	void InitControl();
+	afx_msg void OnBnClickedOk();
+	CComboBox m_cbSerialPort;
+	CComboBox m_cbBaudrate;
+	afx_msg void OnBnClickedCsq();
+};

BIN
短信猫/sms/SMSTest/res/SMSTest.ico


+ 13 - 0
短信猫/sms/SMSTest/res/SMSTest.rc2

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

+ 8 - 0
短信猫/sms/SMSTest/stdafx.cpp

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

+ 60 - 0
短信猫/sms/SMSTest/stdafx.h

@@ -0,0 +1,60 @@
+
+// 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
+
+#include <afxcontrolbars.h>     // 功能区和控件条的 MFC 支持
+
+
+
+
+#include "..\sms\SMSProcess.h"
+
+
+
+
+#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
+
+

+ 26 - 0
短信猫/sms/SMSTest/targetver.h

@@ -0,0 +1,26 @@
+
+#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
+

+ 25 - 0
短信猫/sms/sms-17.sln

@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27130.2010
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sms", "sms\sms.vcxproj", "{00431A09-2ADE-45D9-BF19-4AC06027B710}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{00431A09-2ADE-45D9-BF19-4AC06027B710}.Debug|Win32.ActiveCfg = Debug|Win32
+		{00431A09-2ADE-45D9-BF19-4AC06027B710}.Debug|Win32.Build.0 = Debug|Win32
+		{00431A09-2ADE-45D9-BF19-4AC06027B710}.Release|Win32.ActiveCfg = Release|Win32
+		{00431A09-2ADE-45D9-BF19-4AC06027B710}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {3D10E5FF-CE1F-4DAE-B879-FF95E3DA62C6}
+	EndGlobalSection
+EndGlobal

+ 26 - 0
短信猫/sms/sms.sln

@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sms", "sms\sms.vcproj", "{00431A09-2ADE-45D9-BF19-4AC06027B710}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SMSTest", "SMSTest\SMSTest.vcproj", "{CEC0508A-7157-4523-AA0A-86DCBC249FE0}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{00431A09-2ADE-45D9-BF19-4AC06027B710}.Debug|Win32.ActiveCfg = Debug|Win32
+		{00431A09-2ADE-45D9-BF19-4AC06027B710}.Debug|Win32.Build.0 = Debug|Win32
+		{00431A09-2ADE-45D9-BF19-4AC06027B710}.Release|Win32.ActiveCfg = Release|Win32
+		{00431A09-2ADE-45D9-BF19-4AC06027B710}.Release|Win32.Build.0 = Release|Win32
+		{CEC0508A-7157-4523-AA0A-86DCBC249FE0}.Debug|Win32.ActiveCfg = Debug|Win32
+		{CEC0508A-7157-4523-AA0A-86DCBC249FE0}.Debug|Win32.Build.0 = Debug|Win32
+		{CEC0508A-7157-4523-AA0A-86DCBC249FE0}.Release|Win32.ActiveCfg = Release|Win32
+		{CEC0508A-7157-4523-AA0A-86DCBC249FE0}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 10 - 0
短信猫/sms/sms/AsynSerial.cpp

@@ -0,0 +1,10 @@
+#include "StdAfx.h"
+#include "AsynSerial.h"
+
+CAsynSerial::CAsynSerial(void)
+{
+}
+
+CAsynSerial::~CAsynSerial(void)
+{
+}

+ 31 - 0
短信猫/sms/sms/AsynSerial.h

@@ -0,0 +1,31 @@
+/************************************************************************/
+/*  Copyright (C), 2016-2020, [Home], 保留所有权利;
+/*  模 块 名:异步串口模块;
+/*  描    述:;
+/*
+/*  版    本:[V];	
+/*  作    者:[Home];
+/*  日    期:[12/20/2017];
+/*
+/*
+/*  注    意:;
+/*
+/*  修改记录:[Home];
+/*  修改日期:;
+/*  修改版本:;
+/*  修改内容:;
+/************************************************************************/
+
+#ifndef __ASYN_SERIAL__
+#define __ASYN_SERIAL__
+
+#pragma once
+
+class CAsynSerial
+{
+public:
+	CAsynSerial(void);
+	virtual ~CAsynSerial(void);
+};
+
+#endif // __ASYN_SERIAL__

+ 216 - 0
短信猫/sms/sms/CommRS232.cpp

@@ -0,0 +1,216 @@
+#include "StdAfx.h"
+#include "CommRS232.h"
+
+CCommRS232::CCommRS232(void)
+{
+	m_hComm = NULL;
+	m_bOpened = FALSE;
+	m_byCommPort = 1;
+	m_dwBaudRate = BAUD_9600;
+	m_bySize = 8;
+	m_byParity = 0;
+	m_byStopBits = 1;
+	m_byStartAddr = 1;
+	m_nInterval = 1000;
+}
+
+CCommRS232::~CCommRS232(void)
+{
+	if ( m_hComm != NULL && m_hComm != INVALID_HANDLE_VALUE )
+		CloseHandle(m_hComm);
+
+	m_hComm = NULL;
+	m_bOpened = FALSE;
+}
+
+BOOL CCommRS232::InitComm( IN CONST BYTE& byCommPort, IN CONST DWORD& dwBaudRate, IN CONST BYTE& bySize, IN CONST BYTE& byParity, IN CONST BYTE& byStopBits, IN CONST BYTE& byStartAddr, IN CONST INT& nInterval )
+{
+	ASSERT(byCommPort);
+	m_byCommPort = byCommPort;
+	m_dwBaudRate = dwBaudRate;
+	m_bySize = bySize;
+	m_byParity = byParity;
+	m_byStopBits = byStopBits;
+	m_byStartAddr = byStartAddr;
+	m_nInterval = nInterval;
+
+	// 关闭串口句柄;
+	m_bOpened = FALSE;
+	if ( m_hComm != NULL && m_hComm != INVALID_HANDLE_VALUE )
+	{
+		CloseHandle(m_hComm);
+	}
+	m_hComm = NULL;
+
+	DCB dcb;
+	COMMTIMEOUTS timeout;
+	BOOL bResult = FALSE;
+
+	TCHAR szTmp[MAX_PATH] = _T("\\\\.\\com");
+	TCHAR szPort[5] = {0};
+
+	_ltot_s(byCommPort, szPort, 10);
+	_tcscat_s(szTmp, szPort);
+
+	// 以独占方式打开串口;
+	m_hComm = CreateFile(szTmp, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, NULL , NULL);
+	if( m_hComm == INVALID_HANDLE_VALUE) 
+	{
+		//LOG4C_NO_FILENUM((LOG_NOTICE,"打开串口失败:%s",szTmp));
+		return FALSE;
+	}
+
+	// SetupComm设置缓冲区大小;
+	bResult = SetupComm(m_hComm, 1024, 1024);
+	ASSERT(bResult);
+	if( !bResult )
+		return FALSE;
+
+	// 在串口读写之前,清除缓冲区;
+	bResult = PurgeComm(m_hComm, PURGE_TXCLEAR|PURGE_RXCLEAR);
+	ASSERT(bResult);
+	if(!bResult)
+		return FALSE;
+
+	//////////////////////////////////////////////////////////////////////////
+	// GetCommState获取设备控制块状态;
+	bResult = GetCommState(m_hComm, &dcb);
+	ASSERT(bResult);
+	if(!bResult)
+		return FALSE;
+
+	dcb.Parity = byParity;
+	if(dcb.Parity == NOPARITY)
+		dcb.fParity = FALSE;
+	else
+		dcb.fParity = TRUE;
+
+	dcb.BaudRate = dwBaudRate;
+	dcb.ByteSize = bySize;
+	dcb.StopBits = byStopBits;
+	if(dcb.ByteSize == 8)
+		dcb.StopBits = ONESTOPBIT;
+
+	// SetCommState设置设备的控制块状态;
+	bResult = SetCommState(m_hComm, &dcb);
+	ASSERT(bResult);
+	if(!bResult)
+		return FALSE;
+
+	//////////////////////////////////////////////////////////////////////////
+	// 获取设备的超时值;
+	bResult = GetCommTimeouts(m_hComm, &timeout);
+	ASSERT(bResult);
+	if(!bResult)
+		return FALSE;
+
+	timeout.ReadIntervalTimeout = MAXDWORD;
+	timeout.ReadTotalTimeoutMultiplier = 0;
+	timeout.ReadTotalTimeoutConstant = 0;
+	timeout.WriteTotalTimeoutMultiplier = 0;
+	timeout.WriteTotalTimeoutConstant = 0;
+
+	// 设置设备的超时值;
+	bResult = SetCommTimeouts(m_hComm,&timeout);
+	ASSERT(bResult);
+	if(!bResult)
+		return FALSE;
+
+	m_bOpened = TRUE;
+
+	return TRUE;
+}
+
+BOOL CCommRS232::CloseComm()
+{
+	BOOL bRet = FALSE;
+	if ( m_hComm != NULL && m_hComm != INVALID_HANDLE_VALUE )
+		bRet = CloseHandle(m_hComm);
+
+	if ( bRet == FALSE )
+		return FALSE;
+
+	m_hComm = NULL;
+	m_bOpened = FALSE;
+
+	return TRUE;
+}
+
+INT CCommRS232::Write(IN BYTE *pWirteBuf, IN CONST INT& nWriteSize)
+{
+	if ( !m_bOpened ) return 0;
+	if ( m_hComm == NULL || m_hComm == INVALID_HANDLE_VALUE )
+		return 0;
+
+	DWORD dwBytesWritten = 0;	// 实际写入的字节数;
+	if ( WriteFile( m_hComm, pWirteBuf, nWriteSize, &dwBytesWritten, NULL) )
+	{
+		return dwBytesWritten;
+	}
+
+	return 0;
+}
+
+INT CCommRS232::Read(IN BYTE *pReadBuf, IN CONST INT& nReadSize)
+{
+	if ( m_hComm == NULL || m_hComm == INVALID_HANDLE_VALUE )
+	{
+		//LOG4C_NO_FILENUM((LOG_NOTICE,"串口句柄空"));
+		return 0;
+	}
+
+	if ( pReadBuf == NULL || !::AfxIsValidAddress(pReadBuf, nReadSize, FALSE) )
+	{
+		//LOG4C_NO_FILENUM((LOG_NOTICE,"缓冲区指针无效"));
+		return 0;
+	}
+
+	if ( !m_bOpened ) 
+	{
+		//LOG4C_NO_FILENUM((LOG_NOTICE,"串口状态无效"));
+		return 0;
+	}
+
+	BOOL bResult = FALSE;
+	DWORD dwBytesRead = 0;
+	DWORD dwErrorFlags = 0;
+
+	// ReadFile前,使用ClearCommError清除错误;
+	COMSTAT ComStat;
+	ClearCommError(m_hComm, &dwErrorFlags, &ComStat);
+
+	DWORD dwTick = GetTickCount();
+	while ( ComStat.cbInQue <= 0 )
+	{// cbInQue表示输入缓冲区的字节数; 
+		if ( GetTickCount() - dwTick > 3000)
+			break;
+		ClearCommError(m_hComm, &dwErrorFlags, &ComStat);
+		Sleep(100);
+	}
+
+	if ( ComStat.cbInQue <= 0 )
+	{
+		//LOG4C_NO_FILENUM((LOG_NOTICE,"串口无返回"));
+		return 0;
+	}
+
+	dwBytesRead = (DWORD) ComStat.cbInQue;
+	if ( nReadSize < (INT)dwBytesRead )
+	{
+		dwBytesRead = (DWORD)nReadSize;
+	}
+
+	if ( ReadFile(m_hComm, pReadBuf, dwBytesRead, &dwBytesRead, NULL) )
+	{
+		//LOG4C_NO_FILENUM((LOG_NOTICE,"读:%s,%d", pReadBuf, dwBytesRead));
+		return (INT)dwBytesRead;
+	}
+
+	DWORD dwError;
+	dwError = GetLastError();
+	CString strMsg;
+	strMsg.Format("ReadFile Error! ErrorCode = %d", dwError);
+	//LOG4C_NO_FILENUM((LOG_NOTICE,"串口读失败:%s",strMsg));
+
+	return 0;
+}

+ 42 - 0
短信猫/sms/sms/CommRS232.h

@@ -0,0 +1,42 @@
+#ifndef __COMMRS232_20160221__
+#define __COMMRS232_20160221__
+
+#pragma once
+
+class CCommRS232
+{
+public:
+	CCommRS232(void);
+	~CCommRS232(void);
+
+private:
+	HANDLE		m_hComm;		// 串口句柄;
+	
+	BOOL		m_bOpened;		// 串口是否打开;
+	BYTE		m_byCommPort;	// 串口号;(1-255)
+	DWORD		m_dwBaudRate;	// 波特率;
+	BYTE		m_bySize;		// 数据位(4-8);
+	BYTE		m_byParity;		// 校验位(0-4,分别:None、Odd、Even、Mark、Space);
+	BYTE		m_byStopBits;	// 停止位(也叫结束位,0,1,2 = 1, 1.5, 2);
+	BYTE		m_byStartAddr;	// 起始地址;
+	INT			m_nInterval;	// 间隔时间,毫秒;
+
+	BOOL InitComm();
+	BOOL CloseComm();
+
+public:
+	BOOL InitComm(
+		IN CONST BYTE& byCommPort,		// 串口号;
+		IN CONST DWORD& dwBaudRate,		// 波特率;
+		IN CONST BYTE& bySize,			// 数据位;
+		IN CONST BYTE& byParity,		// 校验位;
+		IN CONST BYTE& byStopBits,		// 停止位;
+		IN CONST BYTE& byStartAddr,		// 起始地址;
+		IN CONST INT& nInterval			// 间隔时间;
+		);
+
+	virtual INT Write(IN BYTE *pWirteBuf, IN CONST INT& nWriteSize);
+	virtual INT Read(IN BYTE *pReadBuf, IN CONST INT& nReadSize);
+};
+
+#endif // __COMMRS232_20160221__

+ 10 - 0
短信猫/sms/sms/CompletionSerial.cpp

@@ -0,0 +1,10 @@
+#include "StdAfx.h"
+#include "CompletionSerial.h"
+
+CCompletionSerial::CCompletionSerial(void)
+{
+}
+
+CCompletionSerial::~CCompletionSerial(void)
+{
+}

+ 31 - 0
短信猫/sms/sms/CompletionSerial.h

@@ -0,0 +1,31 @@
+/************************************************************************/
+/*  Copyright (C), 2016-2020, [Home], 保留所有权利;
+/*  模 块 名:完成端口串口模块;
+/*  描    述:;
+/*
+/*  版    本:[V];	
+/*  作    者:[Home];
+/*  日    期:[12/20/2017];
+/*
+/*
+/*  注    意:;
+/*
+/*  修改记录:[Home];
+/*  修改日期:;
+/*  修改版本:;
+/*  修改内容:;
+/************************************************************************/
+
+#ifndef __COMPLETION_SERIAL__
+#define __COMPLETION_SERIAL__
+
+#pragma once
+
+class CCompletionSerial
+{
+public:
+	CCompletionSerial(void);
+	~CCompletionSerial(void);
+};
+
+#endif // __COMPLETION_SERIAL__

+ 44 - 0
短信猫/sms/sms/ReadMe.txt

@@ -0,0 +1,44 @@
+========================================================================
+    MICROSOFT 基础类库 : sms 项目概述
+========================================================================
+
+
+应用程序向导已为您创建了此 sms DLL。此 DLL 不仅演示 Microsoft 基础类的基本使用方法,还可作为您编写 DLL 的起点。
+
+本文件概要介绍组成 sms DLL 的每个文件的内容。
+
+sms.vcproj
+    这是使用应用程序向导生成的 VC++ 项目的主项目文件,
+    其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
+
+sms.h
+    这是 DLL 的主头文件。它声明了 CsmsApp 类。
+
+sms.cpp
+    这是主 DLL 源文件。它包含 CsmsApp 类。
+
+sms.rc
+    这是程序使用的所有 Microsoft Windows 资源的列表。它包括 RES 子目录中存储的图标、位图和光标。此文件可以直接在 Microsoft Visual C++ 中进行编辑。
+
+res\sms.rc2
+    此文件包含不在 Microsoft Visual C++ 中进行编辑的资源。您应该将不可由资源编辑器编辑的所有资源放在此文件中。
+
+sms.def
+    此文件包含在 Microsoft Windows 中运行所必需的 DLL 的有关信息。它定义了 DLL 的名称和说明等参数,而且还从 DLL 导出函数。
+
+/////////////////////////////////////////////////////////////////////////////
+其他标准文件:
+
+StdAfx.h, StdAfx.cpp
+    这些文件用于生成名为 sms.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。
+
+Resource.h
+    这是标准头文件,可用于定义新的资源 ID。
+    Microsoft Visual C++ 将读取并更新此文件。
+
+/////////////////////////////////////////////////////////////////////////////
+其他注释:
+
+应用程序向导使用“TODO:”来指示应添加或自定义的源代码部分。
+
+/////////////////////////////////////////////////////////////////////////////

+ 16 - 0
短信猫/sms/sms/Resource.h

@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by sms.rc
+//
+
+// жÔÏóµÄÏÂÒ»×éĬÈÏÖµ
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+
+#define _APS_NEXT_RESOURCE_VALUE	1000
+#define _APS_NEXT_CONTROL_VALUE		1000
+#define _APS_NEXT_SYMED_VALUE		1000
+#define _APS_NEXT_COMMAND_VALUE		32771
+#endif
+#endif

+ 901 - 0
短信猫/sms/sms/SMSProcess.cpp

@@ -0,0 +1,901 @@
+#include "StdAfx.h"
+#include "SMSProcess.h"
+
+namespace SMSProcess
+{
+	//////////////////////////////////////////////////////////////////////////
+	CCommRS232 *_pSMSComm = NULL;
+	CRITICAL_SECTION _csRS232;
+	INT _nMaxSMSChar = 70;		// 短信猫一条短信最大支持的字符个数;
+	const INT MAX_SIZE = 512;
+	int g_nCMGFStatus = 0;//保存现在的传输格式 发送短信用0 接收短信用1;
+
+	HANDLE _hSMSReceiveThread = NULL;
+	HANDLE _hCtrlEvent = NULL;
+
+	int g_nMakeCall = 0;				// 发送后是否先拔打电话提醒
+
+	PFCALLBACK  gEnalbeAlarmCallBack = NULL;
+#define PDU_MAXNUMLEN		70		// 最大号码长度;
+#define PDU_MAXUNICODELEN	70		// pdu Unicode的最大长度;
+#define NUM_NAT	0x81				// 非国际号码前缀	phone number type for non- '+'(national) numbers	
+#define NUM_INT	0x91				// 国际号码前缀		phone number type for numbers prefixed by '+'(international)
+
+	//--------------------------------------------------------------------------------
+	// FOR gsm sms 
+#define GSM_MAX_WAIT_TIME		12000	//发送短消息时的最长等待时间
+#define GSM_RESPONSE_NORESPONSE	0	//无响应
+#define GSM_RESPONSE_OK			1	//正确返回
+#define GSM_RESPONSE_ERROR		2	//返回错误信息,含错误代码
+#define GSM_RESPONSE_UNKNOWN	3	//返回无法确定的信息
+#define GSM_CMS_ERROR	0	//CMS Error -- Message service error
+#define GSM_CME_ERROR	1	//CME Error
+#define NOP 183				//非可见字符
+
+#define MAX_WRITE_STR_LEN       3840		
+#define MAX_READ_STR_LEN		512//256
+#define MIN_READ_STR_LEN		6
+#define MAX_TMPSTR_LEN			512//256
+
+	void SwapChars(IN OUT TCHAR *szNumber);
+	char ACharToBChar(char c);
+	CString DeleteEnterForStr(CString sData);
+	int MyCharCount(const char* szMsg);
+	INT Str2PDU_Unicode(const TCHAR *szMsg, TCHAR *szPDU);
+	BOOL GetValidResponse(const TCHAR *szBuff, int nCount, TCHAR *szResponse);
+	int GSMResponse(const TCHAR *szBuff, int nCount, int &nErrorType, int &nErrorCode);
+	int SendSMS(const char *szNo, const char *szMsg, char* szEvent);
+	int ReceiveSms(int iIndex, char* strTelFrom, char* strTime, char* strReceiveMsg, int nCharSize);
+	char* PickSegTxt(const char* pMsgAll, char* szSeg, int nSize);
+	void TransformPDUPhone(IN CONST TCHAR *szPhone, OUT TCHAR* szPDUPhone, IN CONST INT& nPDUPhoneLen);
+	void TransformPDUMsg(IN CONST TCHAR *szPhone, IN CONST TCHAR* szMsg, IN BOOL bNeedReport, OUT TCHAR* szPduContent, IN CONST INT& nContLen);
+	DWORD WINAPI SMSReceiveThread(LPVOID lpParameter);
+	//////////////////////////////////////////////////////////////////////////
+	/************************************************************************/
+	/*  函数:SwapChars[2/22/2016 IT];
+	/*  描述:奇数位和偶数位字符交换( 13823652665F --> 3128632566F5, 用于电话号码编码);
+	/*  参数:;
+	/*  	[IN]szTelNumber:需要转换的电话号码;
+	/*  返回:void;
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	void SwapChars(IN OUT TCHAR *szTelNumber)
+	{
+		if (szTelNumber == NULL)
+			return;
+
+		TCHAR ch;
+		INT nLength = (INT)_tcslen(szTelNumber);
+		for (INT nIndex = 0; nIndex < nLength - 1; nIndex += 2)
+		{
+			ch = szTelNumber[nIndex];
+			szTelNumber[nIndex] = szTelNumber[nIndex + 1];
+			szTelNumber[nIndex + 1] = ch;
+		}
+	}
+
+	/************************************************************************/
+	/*  函数:TransformPDUPhone[2/22/2016 IT];
+	/*  描述:将电话号码转换为GSM PDU格式;
+	/*  参数:;
+	/*  	[IN]szPhone:需要转换的电话号码;
+	/*  	[OUT]szPDUPhone:转换后的PDU电话号码;
+	/*  返回:void;
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	void TransformPduTelNumber(IN CONST TCHAR *szTelNumber, OUT TCHAR* szPduTelNumber, IN CONST INT& nPduTelNumber)
+	{
+		if (szTelNumber == NULL)
+			return;
+
+		if (szPduTelNumber == NULL || nPduTelNumber == 0)
+			return;
+
+		INT nType = 0;
+		TCHAR szTemp[PDU_MAXNUMLEN] = { 0 };
+		INT nLen = (INT)_tcslen(szTelNumber);
+
+		if (szTelNumber[0] == _T('+'))
+		{
+			_tcsncpy_s(szTemp, szTelNumber + 1, PDU_MAXNUMLEN);
+			nType = NUM_INT;
+			nLen--;
+		}
+		else
+		{
+			_tcsncpy_s(szTemp, szTelNumber, PDU_MAXNUMLEN);
+			nType = NUM_NAT;
+		}
+
+		if (_tcslen(szTemp) % 2)
+		{
+			_tcscat_s(szTemp, _T("F"));
+		}
+
+		SwapChars(szTemp);
+
+		_stprintf_s(szPduTelNumber, nPduTelNumber, _T("%02X%02X%s"), nLen, nType, szTemp);
+	}
+
+	/************************************************************************/
+	/*  函数:TransformPDUMsg[2/22/2016 IT];
+	/*  描述:将短消息(包括电话号码、文本)转换为GSM PDU格式;
+	/*  参数:;
+	/*  	[IN]szPhone :需要转换的电话号码;
+	/*  	[IN]szMsg :需要转换的短信消息文本;
+	/*  	[IN] bNeedReport:是否需要提供信息报告;
+	/*  	[OUT] szPduContent:转换后的GSM PDU文本;
+	/*  	[IN] nContLen:szPduContent缓冲区大小;
+	/*  返回:void;
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	void TransformPduMsg(IN CONST TCHAR *szTelNumber, IN CONST TCHAR* szMsg, IN BOOL bNeedReport, OUT TCHAR* szPduContent, IN CONST INT& nContLen)
+	{
+		INT nType = 0;
+		INT nCodingScheme = 0;
+
+		TCHAR szPduTelNumber[PDU_MAXNUMLEN] = { 0 };
+		TransformPduTelNumber(szTelNumber, szPduTelNumber, PDU_MAXNUMLEN);
+
+		nType = 0X10 + 0X01;	// 0x11 -- 0001 0001;
+		if (bNeedReport)
+		{
+			nType += 0X20;		// 0x20 -- 0010 0000;
+		}
+
+		nCodingScheme = 0X08;	// 0x08 -- 0000 1000 -- 16bit UCS2;
+		TCHAR szPduMsg[1024] = { 0 };
+		Str2PDU_Unicode(szMsg, szPduMsg);
+
+		_stprintf_s(szPduContent, nContLen, _T("00%02X00%s00%02X00%02X%s"),
+			//00 - 默认短消息中心;
+			nType,// FO;
+			//00 - TP-MO;
+			szPduTelNumber,
+			//00 - TP-PID;
+			nCodingScheme,
+			//00 - TP-VP;
+			_tcslen(szPduMsg) / 2,
+			szPduMsg);
+	}
+
+	/************************************************************************/
+	/*  函数:Str2PDU_Unicode[2/22/2016 IT];
+	/*  描述:将普通文本转换为gsm需要的unicode编码格式(可用于中、英文模式);
+	/*  参数:;
+	/*  	[IN] szMsg:需要转换的字符串文本;
+	/*  	[OUT] szPDU:转换后的pdu unicode文本;
+	/*  	[IN/OUT] :;
+	/*  返回:int		<=0 表示转换失败,否则为unicode字符长度;
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	INT Str2PDU_Unicode(IN CONST TCHAR *szMsg, TCHAR *szPDU)
+	{
+		WCHAR wszPDU[PDU_MAXUNICODELEN];
+
+		int nCount = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szMsg, (int)_tcslen(szMsg), wszPDU, PDU_MAXUNICODELEN);
+		if (nCount < 1)
+		{
+			return 0;
+		}
+
+		for (int i = 0; i < nCount; i++)
+		{
+			wsprintf(szPDU + i * 4, _T("%4.4X"), wszPDU[i]);
+		}
+
+		return nCount;
+	}
+
+	/************************************************************************/
+	/*  函数:GSMResponse[2/22/2016 IT];
+	/*  描述:根据GSM模块返回的数据判断GSM模块当前的状态;
+	/*  参数:;
+	/*  	[IN] szBuff:串口收到的数据;
+	/*  	[IN] nCount:数据的个数;
+	/*  	[OUT] nErrorType:如果返回错误信息,返回的错误类型 0 - CME error, 1 - CMS error;
+	/*  	[OUT] nErrorCode:如果返回错误信息,返回的错误代码;
+	/*  	[IN/OUT] :;
+	/*  返回:int
+	/*			GSM_RESPONSE_NORESPONSE	0	//无响应;
+	/*			GSM_RESPONSE_OK			1	//正确返回
+	/*			GSM_RESPONSE_ERROR		2	//返回错误信息,含错误代码
+	/*			GSM_RESPONSE_UNKNOWN	3	//返回无法确定的信息
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	int GSMResponse(const char *szBuff, int nCount, int &nErrorType, int &nErrorCode)
+	{
+		if (nCount == 0)
+		{
+			return GSM_RESPONSE_NORESPONSE;
+		}
+
+		if (nCount < MIN_READ_STR_LEN)
+		{
+			return GSM_RESPONSE_UNKNOWN;
+		}
+
+		char szResponse[MAX_TMPSTR_LEN];
+
+		//获取信息正文
+		if (!GetValidResponse(szBuff, nCount, szResponse))
+		{
+			return GSM_RESPONSE_UNKNOWN;
+		}
+
+		if (szResponse[0] == 'O' && szResponse[1] == 'K' || strstr(szBuff, "OK") != NULL)
+		{
+			return GSM_RESPONSE_OK;
+		}
+
+		if (szResponse[5] == 'E' &&
+			szResponse[6] == 'R' &&
+			szResponse[7] == 'R' &&
+			szResponse[8] == 'O' &&
+			szResponse[9] == 'R')
+		{
+			//Get error type
+			if (szResponse[3] == 'E')
+			{
+				nErrorType = GSM_CME_ERROR;
+			}
+			else
+			{
+				nErrorType = GSM_CMS_ERROR;
+			}
+
+			//get error code
+			TCHAR szErrorCode[8];
+			_tcsncpy_s(szErrorCode, szResponse + 12, strlen(szResponse) - 12);
+			szErrorCode[strlen(szResponse) - 12] = '\0';
+			nErrorCode = atoi(szErrorCode);
+
+			return GSM_RESPONSE_ERROR;
+		}// end if (szResponse...)
+
+		return GSM_RESPONSE_UNKNOWN;
+	}
+
+	/************************************************************************/
+	/*  函数:GetValidResponse[2/22/2016 IT];
+	/*  描述:对串口返回的数据进行处理 1.判断是否有效 2.去掉首尾多余信息 3.返回有意义的数据;
+	/*  参数:;
+	/*  	[IN] szBuff:串口收到的数据;
+	/*  	[IN] nCount:数据的个数;
+	/*  	[OUT] szResponse:返回的(关键)正文信息;
+	/*  	[IN/OUT] :;
+	/*  返回:BOOL		成功为TRUE,否则FALSE;
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	BOOL GetValidResponse(const char *szBuff, int nCount, char *szResponse)
+	{
+		if (nCount < 6)
+		{
+			return FALSE;
+		}
+
+		//	if (	szBuff[nCount-1] != 0x0A ||
+		//		szBuff[nCount-2] != 0x0D )
+		//	{
+		//		return FALSE;
+		//	}
+
+		INT i = 0;
+		for (i = nCount - 3; i > 0; i--)
+		{
+			if (szBuff[i] == 0x0A && szBuff[i - 1] == 0x0D)
+			{
+				break;
+			}//end if
+		}//end for
+
+		if (i < 1)
+		{
+			return FALSE;
+		}
+
+		strncpy(szResponse, szBuff + i + 1, nCount - 2 - (i + 1)); // _tcsncpy_s
+		szResponse[nCount - 2 - (i + 1)] = '\0';
+		return TRUE;
+	}
+
+	//============================================================================================
+	/************************************************************************/
+	/*  函数:[2/22/2016 IT];
+	/*  描述:;
+	/*  参数:;
+	/*  	[IN] :;
+	/*  	[OUT] :;
+	/*  	[IN/OUT] :;
+	/*  返回:void;
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	int SendSMS(const char *szNo, const char *szMsg, char* szEvent)
+	{
+		EnterCriticalSection(&_csRS232);
+		if (g_nCMGFStatus == 1)
+		{// 如果是TEXT模式,改中PDU模式;
+			char szBuf[MAX_SIZE] = { 0 };
+			g_nCMGFStatus = 0;
+			strcpy(szBuf, "AT+CMGF=0\r");
+			int nLen = _pSMSComm->Write((BYTE *)szBuf, (int)strlen(szBuf));
+			nLen = _pSMSComm->Read((BYTE *)szBuf, MAX_SIZE - 1);
+		}
+
+		char WriteBuff[MAX_WRITE_STR_LEN + 1] = { 0 };
+		char ReadBuff[MAX_READ_STR_LEN + 1] = { 0 };
+		int iOffset = 0;
+		int iDataLength = 0;
+		char szTmp[MAX_TMPSTR_LEN + 1] = { 0 };
+		int nTmp;
+
+		char szPDU[512];
+		TransformPduMsg(szNo, szMsg, FALSE, szPDU, 512);
+
+		sprintf(WriteBuff, "AT+CMGS=");
+		iOffset += 8;
+		sprintf(WriteBuff + iOffset, "%03d", strlen(szPDU) / 2 - 1);
+		iOffset = (int)strlen(WriteBuff);
+		WriteBuff[iOffset] = 0x0d;
+		iOffset++;
+
+		//LOG4C_HEX_DUMP((LOG_NOTICE, WriteBuff, iOffset));
+		INT nReturnSize = _pSMSComm->Write((BYTE*)WriteBuff, iOffset);
+		nReturnSize = _pSMSComm->Read((BYTE*)szTmp, MAX_READ_STR_LEN);
+		//LOG4C_HEX_DUMP((LOG_NOTICE, szTmp, nReturnSize));
+
+		iOffset = 0;
+		sprintf(WriteBuff + iOffset, szPDU);
+		iOffset += (int)strlen(szPDU);
+		WriteBuff[iOffset++] = 0x1a;
+		//LOG4C_HEX_DUMP((LOG_NOTICE, WriteBuff, iOffset));
+		nReturnSize = _pSMSComm->Write((BYTE*)WriteBuff, iOffset);
+
+		int nErrorType, nErrorCode;					//发送错误类型、编码
+		int nResponse = GSM_RESPONSE_NORESPONSE;	//发送结果
+		Sleep(3000);//发送完短信时等待3秒发送
+		do
+		{
+			nTmp = _pSMSComm->Read((BYTE*)szTmp, MAX_READ_STR_LEN);
+			//LOG4C_HEX_DUMP((LOG_NOTICE, szTmp, nTmp));
+			if (nTmp > 0 && iDataLength < MAX_READ_STR_LEN)
+			{
+				strncpy(ReadBuff + iDataLength, szTmp, nTmp);
+				iDataLength += nTmp;
+			}
+			else
+				break;
+		} while (1);
+		nResponse = GSMResponse(ReadBuff, iDataLength, nErrorType, nErrorCode);
+
+		switch (nResponse)
+		{
+		case GSM_RESPONSE_OK:
+			sprintf(szEvent, "Send OK!");
+			//LOG4C_NO_FILENUM((LOG_NOTICE,"发送结果:%s", szEvent))
+			return 0;
+			break;
+		case GSM_RESPONSE_NORESPONSE:
+			sprintf(szEvent, "GSM Modem No Response! Please Check The Connection!");
+			//LOG4C_NO_FILENUM((LOG_NOTICE,"发送结果:%s", szEvent))
+			return ERR_CODE_SMS_GSM_NO_RESPONSE;
+			break;
+
+		case GSM_RESPONSE_ERROR:
+			sprintf(szEvent, "Send fail! The card maybe has little money, Please recharge!");
+			//LOG4C_NO_FILENUM((LOG_NOTICE,"发送结果:%s", szEvent))
+			return ERR_CODE_SMS_GSM_ERROR_RESPONSE;
+			break;
+
+		case GSM_RESPONSE_UNKNOWN:
+			sprintf(szEvent, "Send Timeout. The Message may Send OK!");
+			//LOG4C_NO_FILENUM((LOG_NOTICE,"发送结果:%s", szEvent))
+			return ERR_CODE_SMS_GSM_UNKOWN_RESPONSE;
+		default:
+			sprintf(szEvent, "Send Timeout. The Message may Send OK!");
+			//LOG4C_NO_FILENUM((LOG_NOTICE,"发送结果:%s", szEvent))
+			return ERR_CODE_SMS_GSM_UNKOWN_RESPONSE;
+		}//end switch
+
+
+		LeaveCriticalSection(&_csRS232);
+
+		return ERR_CODE_SMS_GSM_UNKOWN_RESPONSE;
+	}
+
+	/************************************************************************/
+	/*  函数:[2/22/2016 IT];
+	/*  描述:;
+	/*  参数:;
+	/*  	[IN] :;
+	/*  	[OUT] :;
+	/*  	[IN/OUT] :;
+	/*  返回:void;
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	int ReceiveSms(int iIndex, char* strTelFrom, char* strTime, char* strReceiveMsg, int nCharSize)
+	{
+		EnterCriticalSection(&_csRS232);
+
+		int nRet = -1;//0:关闭报警 1:恢复正常
+		int nLen = 0;
+		char szBuf[MAX_SIZE] = { 0 };
+		//
+		if (g_nCMGFStatus == 0)
+		{
+			g_nCMGFStatus = 1;
+			strcpy(szBuf, "AT+CMGF=1\r");
+			nLen = _pSMSComm->Write((BYTE *)szBuf, (int)strlen(szBuf));
+			nLen = _pSMSComm->Read((BYTE *)szBuf, MAX_SIZE - 1);
+		}
+
+		sprintf(szBuf, "AT+CMGR=%d\r", iIndex);
+		nLen = _pSMSComm->Write((BYTE *)szBuf, (int)strlen(szBuf));
+		nLen = _pSMSComm->Read((BYTE *)szBuf, 511);
+
+		if (nLen < 50)//没有短信
+		{
+			LeaveCriticalSection(&_csRS232);
+			return nRet;
+		}
+
+		CString str;
+
+		int nReaded = 0;
+		int nTelServiceType = 0x91;
+		int nTelType = 0x91;
+		char szTelService[512] = { 0 };
+		char szTel[512] = { 0 };
+		char szTime[512] = { 0 };
+		char szWideBuf[512] = { 0 };
+		char szReceiAscii[512] = { 0 };
+		char *pData = strstr(szBuf, "+CMGR:");
+		char *pOK = strstr(szBuf, "\r\nOK\r\n");
+		if (pData != NULL && pOK != NULL && pOK > pData)
+		{
+			//pOK[0] = 0;
+			memset(pOK, 0, strlen("\r\nOK\r\n"));
+			char* pTemp = pData + 6;//strlen("+CMGR:") = 6;
+			nReaded = atoi(pTemp);//短信已读取标志和类型
+			pTemp = strstr(pTemp, "\r\n");
+			str.Format("%s", pTemp);
+
+			str = DeleteEnterForStr(str);
+			str = str.MakeLower();
+
+			if (str == "open")
+				nRet = 1;
+			if (str == "close")
+				nRet = 0;
+		}
+		//清除
+		//if(strlen(strTelFrom) > 0)
+		{
+			sprintf(szBuf, "AT+CMGD=%d\r", iIndex);
+			nLen = _pSMSComm->Write((BYTE *)szBuf, (int)strlen(szBuf));
+			nLen = _pSMSComm->Read((BYTE *)szBuf, MAX_SIZE - 1);
+		}
+
+		LeaveCriticalSection(&_csRS232);
+
+		return nRet;//return strlen(strTelFrom) > 0;
+	}
+
+	/************************************************************************/
+	/*  函数:[2/22/2016 IT];
+	/*  描述:;
+	/*  参数:;
+	/*  	[IN] :;
+	/*  	[OUT] :;
+	/*  	[IN/OUT] :;
+	/*  返回:void;
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	DWORD WINAPI SMSReceiveThread(LPVOID lpParameter)
+	{
+		do
+		{
+			char sTelFrom[MAX_SIZE], sTime[MAX_SIZE], sReceiveMsg[MAX_SIZE];
+			int nRet = ReceiveSms(1, sTelFrom, sTime, sReceiveMsg, MAX_SIZE);
+			if (nRet == 1)
+			{
+				gEnalbeAlarmCallBack(nRet);
+			}
+			else if (nRet == 0)
+			{
+				gEnalbeAlarmCallBack(nRet);
+			}
+
+		} while (WaitForSingleObject(_hCtrlEvent, 2000L) == WAIT_TIMEOUT);
+
+		return 0;
+	}
+
+	//删除字符串中的换行
+	/************************************************************************/
+	/*  函数:[2/22/2016 IT];
+	/*  描述:;
+	/*  参数:;
+	/*  	[IN] :;
+	/*  	[OUT] :;
+	/*  	[IN/OUT] :;
+	/*  返回:void;
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	CString DeleteEnterForStr(CString sData)
+	{
+		CString sRet;
+
+		int   iLen = sData.GetLength();
+		char*   pc = new   char[iLen];
+		memset(pc, 0, iLen);
+		int   j = 0;
+		for (int i = 0; i < iLen; i++)
+		{
+			if ((sData[i] == 0x0D) || (sData[i] == 0x0A))
+				continue;
+			pc[j++] = sData[i];
+		}
+
+		sRet.Format("%s", pc);
+		delete[]   pc;
+
+		return sRet;
+	}
+
+	//////////////////////////////////////////////////////////////////////////
+	/************************************************************************/
+	/*  函数:[2/22/2016 IT];
+	/*  描述:;
+	/*  参数:;
+	/*  	[IN] :;
+	/*  	[OUT] :;
+	/*  	[IN/OUT] :;
+	/*  返回:void;
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	int MyCharCount(const char* szMsg)
+	{
+		int i = 0;
+		int nCharCount = 0;
+		while (szMsg[i] != 0)
+		{
+			if (szMsg[i] & 0x80)
+			{
+				ASSERT(szMsg[i + 1] & 0x80);
+				if (szMsg[i + 1] & 0x80)
+					i++;
+			}
+			i++;
+			nCharCount++;
+		}
+		return nCharCount;
+	}
+
+	/************************************************************************/
+	/*  函数:[2/22/2016 IT];
+	/*  描述:;
+	/*  参数:;
+	/*  	[IN] :;
+	/*  	[OUT] :;
+	/*  	[IN/OUT] :;
+	/*  返回:void;
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	char ACharToBChar(char c)
+	{
+		if (c >= '0' && c <= '9')
+			c = c - '0';
+		else if (c >= 'A' && c <= 'F')
+			c = c - 'A' + 10;
+		else if (c >= 'a' && c <= 'f')
+			c = c - 'a' + 10;
+		return c;
+	}
+
+	/************************************************************************/
+	/*  函数:[2/22/2016 IT];
+	/*  描述:;
+	/*  参数:;
+	/*  	[IN] :;
+	/*  	[OUT] :;
+	/*  	[IN/OUT] :;
+	/*  返回:void;
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	char* PickSegTxt(const char* pMsgAll, char* szSeg, int nSize)
+	{
+		char* pRtn = NULL;
+		int i = 0;
+		int nCharCount = 0;
+		while (pMsgAll[i] != 0)
+		{
+			if (pMsgAll[i] & 0x80)
+			{
+				ASSERT(pMsgAll[i + 1] & 0x80);
+				if (pMsgAll[i + 1] & 0x80)
+					i++;
+			}
+			i++;
+			nCharCount++;
+			if (pMsgAll[i] == 0 || //已经到了结束符
+				nCharCount == nSize || //大小已经达到
+				nCharCount == nSize - 1 && (pMsgAll[i] & 0x80)) //或者只差最后一个字节并且后续的一个字节为汉字
+			{
+				memcpy(szSeg, pMsgAll, i);
+				szSeg[i] = 0;
+				if (pMsgAll[i] != 0)
+					pRtn = (char*)(pMsgAll + i);
+				break;
+			}
+		}
+		return pRtn;
+	}
+
+	//////////////////////////////////////////////////////////////////////////
+	INT SMS_INIT(IN CONST BYTE& byCommPort, IN CONST DWORD& dwBaudRate, IN CONST BYTE& bySize, IN CONST BYTE& byParity, IN CONST BYTE& byStopBits, IN CONST BYTE& byStartAddr, IN CONST INT& nInterval, IN CONST INT& nMaxSMSChar)
+	{
+		_nMaxSMSChar = nMaxSMSChar;
+		if (_pSMSComm == NULL)
+		{
+			_pSMSComm = new CCommRS232;
+			if (!_pSMSComm->InitComm(byCommPort, dwBaudRate, bySize, byParity, byStopBits, byStartAddr, nInterval))
+			{
+				delete _pSMSComm;
+				_pSMSComm = NULL;
+				return ERR_CODE_SMS_OPEN_COMM;
+			}
+		}
+
+		// 设置成PDU模式;
+		TCHAR szBuf[MAX_SIZE] = _T("AT+CMGF=0\r");
+		INT nReturnSize = _pSMSComm->Write((BYTE*)szBuf, (INT)_tcslen(szBuf));
+
+		memset(szBuf, 0, MAX_SIZE);
+		nReturnSize = _pSMSComm->Read((BYTE*)szBuf, MAX_SIZE - 1);
+		if (nReturnSize)
+		{
+			if (_tcsstr(szBuf, _T("OK")) == NULL)
+			{
+				delete _pSMSComm;
+				_pSMSComm = NULL;
+				return -1;
+			}
+		}
+		else
+		{
+			delete _pSMSComm;
+			_pSMSComm = NULL;
+			return -1;
+		}
+
+#if 0
+		// 把卡里的第一条短信删掉;
+		_tcscpy_s(szBuf, _T("AT+CMGD=1\r"));
+		nReturnSize = _pSMSComm->Write((BYTE*)szBuf, (INT)_tcslen(szBuf));
+
+		memset(szBuf, 0, MAX_SIZE);
+		nReturnSize = _pSMSComm->Read((BYTE*)szBuf, MAX_SIZE - 1);
+#endif
+		InitializeCriticalSection(&_csRS232);
+
+		return 0;
+	}
+
+	VOID SMS_UNINIT()
+	{
+		// 结束线程;
+		if (_hCtrlEvent)
+			SetEvent(_hCtrlEvent);
+
+		if (_hSMSReceiveThread)
+		{
+			WaitForSingleObject(_hSMSReceiveThread, INFINITE);
+			CloseHandle(_hSMSReceiveThread);
+			_hSMSReceiveThread = NULL;
+		}
+
+		if (_hCtrlEvent)
+			CloseHandle(_hCtrlEvent);
+		_hCtrlEvent = NULL;
+
+		DeleteCriticalSection(&_csRS232);
+
+		// 清理串口句柄;
+		if (_pSMSComm)
+		{
+			delete _pSMSComm;
+			_pSMSComm = NULL;
+		}
+	}
+
+	INT SMS_SENDMSG(IN CONST TCHAR *pTel, IN CONST TCHAR *pContent, IN TCHAR *pErrorMsg)
+	{
+		if (pContent == NULL || pTel == NULL)
+			return -1;
+
+		INT nRet = 0;
+		BOOL bRet = FALSE;
+		AFX_MANAGE_STATE(AfxGetStaticModuleState());
+
+		CString strMsg = pContent;
+		if (MyCharCount(strMsg) < 70)
+		{
+			nRet = SendSMS(pTel, strMsg, pErrorMsg);
+		}
+		else
+		{
+			char* szMsg2 = new char[strlen(strMsg) + 1];
+			strcpy(szMsg2, strMsg);
+			char* pMsgSegLeft = (char*)szMsg2;
+			bRet = TRUE;
+			while (1)
+			{
+				char szMsgSegSend[255] = { 0 };
+				int nMaxCharCanSend = _nMaxSMSChar;		// 最大能够发送的字符,暂固定为70
+				pMsgSegLeft = PickSegTxt(pMsgSegLeft, szMsgSegSend, nMaxCharCanSend);
+				nRet = SendSMS(pTel, szMsgSegSend, pErrorMsg);
+				if (!nRet)
+				{
+					bRet = FALSE;
+					break;
+				}
+				if (pMsgSegLeft == NULL)
+					break;
+			}
+			delete[]szMsg2;
+		}
+		if (bRet && g_nMakeCall == 1)
+		{
+			//拨号通知用户留心短信(拨号20秒)
+			char WriteBuff[MAX_WRITE_STR_LEN + 1] = { 0 };
+			char ReadBuff[MAX_READ_STR_LEN + 1] = { 0 };
+			sprintf(WriteBuff, "ATD%s;\r", pTel);
+			int iOffset = (int)strlen(WriteBuff);
+
+			_pSMSComm->Write((BYTE *)WriteBuff, iOffset);
+			int nLen = _pSMSComm->Read((BYTE *)ReadBuff, MAX_READ_STR_LEN);
+			COleDateTime timeStart = COleDateTime::GetCurrentTime();
+			while (1)
+			{
+#ifndef _DEBUG
+				//CString strToStop;
+				//if(GetTempVar("ToStop", strToStop) && strToStop == "1")
+				//	break;
+#endif
+				COleDateTimeSpan span = COleDateTime::GetCurrentTime() - timeStart;
+				if (span.GetTotalSeconds() > 20)
+					break;
+			}
+			sprintf(WriteBuff, "ATH\r");
+			iOffset = (int)strlen(WriteBuff);
+			_pSMSComm->Write((BYTE *)WriteBuff, iOffset);
+			nLen = _pSMSComm->Read((BYTE *)ReadBuff, MAX_READ_STR_LEN);
+		}
+
+		return nRet;
+	}
+
+	/************************************************************************/
+	/*  函数:SMS_GETCSQ[12/21/2017 Home];
+	/*  描述:获取短信猫信息强度(AT+CSQ指令);
+	/*  参数:;
+	/*  	[IN] :;
+	/*  	[OUT] :;
+	/*  	[IN/OUT] :;
+	/*  返回:CSQ<0-10>,n 表示信号不足 CSQ<11-31>,n 表示信号充足 CSQ<大于99>,n 表示信号不足;
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	BOOL SMS_GETCSQ(int iMin, int iMax, int &iNowData)
+	{
+		bool bRet = false;
+
+		EnterCriticalSection(&_csRS232);
+
+		char szBuf[MAX_SIZE] = { 0 };
+		//取号码
+		strcpy(szBuf, "AT+CSQ\r");
+		int nLen = _pSMSComm->Write((BYTE *)szBuf, (int)strlen(szBuf));
+		memset(szBuf, 0, sizeof(szBuf));
+		nLen = _pSMSComm->Read((BYTE *)szBuf, MAX_SIZE - 1);
+
+		CString str;
+		str.Format("%s", szBuf);
+		int nPos = str.Find("CSQ: ");
+		str = str.Mid(nPos + 5, 2);
+
+		iNowData = atoi(str);
+		if (iNowData >= iMin && iNowData <= iMax)
+			bRet = true;
+
+		LeaveCriticalSection(&_csRS232);
+
+		return bRet;
+	}
+
+	INT SMS_SetCallBack(PFCALLBACK Func)
+	{
+		if (Func == NULL || gEnalbeAlarmCallBack != NULL)
+			return 0;
+
+		gEnalbeAlarmCallBack = Func;
+
+		_hCtrlEvent = ::CreateEvent(NULL, TRUE, 0, 0);
+
+		DWORD dwReceiveSmsThreadId;
+		_hSMSReceiveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SMSReceiveThread, NULL, 0, &dwReceiveSmsThreadId);
+
+		return 0;
+	}
+
+};

+ 130 - 0
短信猫/sms/sms/SMSProcess.h

@@ -0,0 +1,130 @@
+#ifndef __SMSPROCESS_20160221__
+#define __SMSPROCESS_20160221__
+
+#include "CommRS232.h"
+
+#pragma once
+
+typedef int (WINAPI *PFCALLBACK)( BOOL bEnableAlarm );//true 恢复正常 false 报警不打电话不发短信;
+
+namespace SMSProcess
+{
+	// SMS 错误代码定义;
+	enum __ERROR_CODE_SMS
+	{
+		ERR_CODE_SMS_OPEN_COMM				= 80201	,			// 打开短信猫串口失败;
+		ERR_CODE_SMS_GSM_NO_RESPONSE		= 80202 ,			// 短信猫没有响应;
+		ERR_CODE_SMS_GSM_ERROR_RESPONSE		= 80203 ,			// 发送失败可能是卡里没钱;
+		ERR_CODE_SMS_GSM_UNKOWN_RESPONSE	= 80204 ,			// 未知响应,也有可能发送成功;
+	};
+
+	INT	SMS_INIT(
+		IN CONST BYTE& byCommPort,		// 串口号;
+		IN CONST DWORD& dwBaudRate,		// 波特率;
+		IN CONST BYTE& bySize,			// 数据位;
+		IN CONST BYTE& byParity,		// 校验位;
+		IN CONST BYTE& byStopBits,		// 停止位;
+		IN CONST BYTE& byStartAddr,		// 起始地址;
+		IN CONST INT& nInterval,		// 间隔时间;
+		IN CONST INT& nMaxSMSChar		// 短信猫一条短信最大支持的字符个数;
+		);
+
+	VOID SMS_UNINIT();
+
+	INT	SMS_SENDMSG(
+		IN CONST TCHAR *pTel,					// 手机号码;
+		IN CONST TCHAR *pContent,				// 发送内容;
+		IN TCHAR *pErrorMsg						// 错误消息;
+		);
+
+	// 获取短信猫信息强度;
+	BOOL SMS_GETCSQ(int iMin,int iMax,int &iNowData);
+	INT SMS_SetCallBack(PFCALLBACK Func);
+};
+
+#endif // __SMSPROCESS_20160221__
+
+
+/************************************************************************/
+/* 
+一.连接短信猫设备, 发送AT指令, 返回OK表示连接成功;
+二.检测短信猫信息号强度, 发送AT+CSQ指令, 返回整数1在 11-31间表示信号充足;
+三.设置短信格式: 指令AT+CMGF=1表示TEXT模式,只能英文短信; 指令AT+CMGF=0 表示PDU模式,能发送中文短信;
+
+A.AT+CMGF=1模式发送英文短信=>
+AT+CMGS=<接收短信的手机号码> , 回车等待返回
+然后直接发送内容即可;
+
+B.AT+CMGF=0模式发送中文短信=>
+假如接收号码为: +8613501337830
+发送的短信内容: 工作愉快!
+短信中心号码: +8613800100500
+
+1.短信中心号码处理, 用addr表示:
+a->短信中心号码的处理: 用字符串表示addr="+8613800100500", 去掉"+"号,
+看看长度是否为偶数, 如果不是, 最后添加"F", 结果即addr="8613800100500F"
+
+b->将短信中心号码奇数位和偶数位交换, 结果即addr="683108100005F0"
+
+c->将短信中心号码前面加上字符"91", 表示国际化的意思, 结果即addr="91683108100005F0"
+
+d->计算出"91683108100005F0"的字符长度, 结果除2, 格式化成2位的16进制字符串
+长度=16, 即 16/2=8 转成16进制字符=>"08", 并将"08"添加到短信中心号码中, 
+结果即:addr="0891683108100005F0"
+
+2.接收短信号码处理, 用phone表示:
+a->接收短信号码的处理: 用字符串表示phone="+8613501337830", 去掉"+"号,
+看看长度是否为偶数, 如果不是, 最后添加"F", 结果即phone="8613902433649"
+
+b->将接收短信号码奇数位和偶数位交换, 结果即phone="683109423346F9"
+
+3.短信内容处理, 用msg表示:
+a->将字符串转成Unicode编码, 例如"工作愉快!"的Unicode编码为msg="5DE54F5C61095FEBFF01";
+b->将转成Unicode编码后的字符串长度除2, 即 20/2=10, 转成16进制字符串即"0A", 并添加到Unicode编码前,
+结果即:msg="0A5DE54F5C61095FEBFF01"
+
+4.组合123
+a->接收短信号码前加上字符串"11000D91"
+(
+1100:固定字符;
+0D:手机号码长度的16进制表示, 不算"+"号码;
+91:表示短信发送到手机91, 若要发送到小灵通则改为81
+)
+即phone="11000D91"+phone;
+phone="11000D91683109423346F9";
+
+b->接收短信号码后加上"000800"和短信内容, "000800"为固定内容;
+即phone = phone + "000800" + msg
+即 11000D91683109423346F9 + 000800 + 0A5DE54F5C61095FEBFF01
+phone = 11000D91683109423346F90008000A5DE54F5C61095FEBFF01
+
+c.phone 长度除以2,格式化成2位的十进制数字符串
+
+即 "11000D91683109423346F90008000A5DE54F5C61095FEBFF01" => 50/2 => "25"
+
+5.所以,要发送的内容为:
+发:AT
+收:OK
+发:AT+CMGF=0
+收:OK
+发:AT+CMGS=25
+收:>
+发:addr+phone→ //→为发送符(ctrl+z,十六进制0x1A)
+
+收:+CMGS: 54 OK
+
+6、如果返回不是ERROR,恭喜你,发送成功了
+
+四、几个要注意的问题
+
+1、发送的指令用0x0D结尾,注意不是通常认为的0x0D,0x0A。
+
+特别是在发送PDU短信的AT+CMGS=25命令时,
+
+一定只能以0x0D结尾。
+
+2、在发送短信内容时,以0x1A(代表ctrl+Z的虚拟键值)结尾。
+
+3、用AT+CMEE=1命令,可以在短信猫返回ERROR时带上原因,这样方便调试。
+*/
+/************************************************************************/

+ 781 - 0
短信猫/sms/sms/ShortMessageService.cpp

@@ -0,0 +1,781 @@
+#include "StdAfx.h"
+#include "ShortMessageService.h"
+
+CShortMessageService::CShortMessageService(void)
+{
+}
+
+CShortMessageService::~CShortMessageService(void)
+{
+}
+
+/************************************************************************/
+/*  函数:[8/28/2018 Home];
+/*  描述:;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/*  注意:;
+/*  示例:;
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+BOOL CShortMessageService::InitGSM()
+{
+	// 应答串;
+	TCHAR szAns[128] = {0};
+
+	// 测试是否有GSM-MODEM存在;
+	WriteComm((LPBYTE)_T("AT\r\n"), 4);
+	Sleep(200);
+	ReadComm((LPBYTE)szAns, 128);
+
+	if ( strstr(szAns, _T("OK")) == NULL)
+	{
+		WriteComm((LPBYTE)_T("AT\r\n"), 3);
+		Sleep(200);
+		ReadComm((LPBYTE)szAns, 128);
+		if ( strstr(szAns, _T("OK")) == NULL)
+			return FALSE;
+	}
+
+	// ECHO OFF
+	WriteComm((LPBYTE)_T("ATE0\r"), 5);
+	ReadComm((LPBYTE)szAns, 128);
+
+	// PDU模式;
+	WriteComm((LPBYTE)_T("AT+CMGF=0\r"), 10);
+	ReadComm((LPBYTE)szAns, 128);
+
+	WriteComm((LPBYTE)_T("AT+CSMS=1\r"), 10);
+	ReadComm((LPBYTE)szAns, 128);
+
+	WriteComm((LPBYTE)_T("AT+CNMI=2\r"), 12);
+	ReadComm((LPBYTE)szAns, 128);
+
+	return TRUE;
+}
+
+/************************************************************************/
+/*  函数:[8/27/2018 Home];
+/*  描述:;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/*  注意:;
+/*  示例:;
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+BOOL CShortMessageService::SendShortMessage(IN SM_PARAM *sm_param)
+{
+	// PDU字符串长度;
+	int nPduLen = 0;
+	// SMSC号码长度;
+	unsigned char nSmscLen = 0;
+	// 串口收到的数据长度;
+	int nReceveLen = 0;
+	// 命令串;
+	char szCmd[16] = {0};
+	// PDU串;
+	char szPdu[512] = {0};
+	// 应答串;
+	char szAns[128] = {0};
+
+	// 根据PDU参数,编码PDU串;
+	nPduLen = EncodePdu(sm_param, (LPBYTE)szPdu, 512);
+	// 以Ctrl+Z结束;
+	strcat(szPdu, _T("/x01A"));
+
+	// 取PDU串中的SMSC信息长度;
+	HexString2Byte(szPdu, 2, &nSmscLen, 1);
+	// 加上长度字节本身;
+	nSmscLen++;
+
+	// 命令中的长度,不包括SMSC信息长度,以数据字节计;
+	sprintf(szCmd, _T("AT+CMGS=%d/r"), nPduLen/2 - nSmscLen); // 生成命令;
+	
+	// 发送串口命令;
+	WriteComm((LPBYTE)szCmd, strlen(szCmd));
+
+	// 读取数据;
+	nReceveLen = ReadComm((LPBYTE)szAns, 128);
+
+	// 根据是否找到"/r/n"决定成功与否;
+	if ( nReceveLen == 4 && strncmp(szAns, _T("/r/n>"), 4) == 0 )
+	{
+		// 继续发送PDU串;
+		WriteComm((LPBYTE)szPdu, strlen(szPdu));
+		nReceveLen = ReadComm((LPBYTE)szAns, 128);
+
+		// 根据能否找到"+CMS ERROR"决定成功与否;
+		if ( nReceveLen > 0 && strncmp(szAns, _T("+CMS ERROR"), 10) != 0)
+			return TRUE;
+	}
+
+	return FALSE;
+}
+
+/************************************************************************/
+/*  函数:[8/27/2018 Home];
+/*  描述:;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/*  注意:;
+/*  示例:;
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+int CShortMessageService::SendShortMessage(IN LPCTSTR lpSentPhone, IN LPCTSTR lpSendMsg)
+{
+	return 0;
+}
+
+/************************************************************************/
+/*  函数:[12/26/2017 Home];
+/*  描述:将正常顺序的电话号码奇偶位颠倒( 若长度为奇数, 先补"F"凑成偶数后, 再颠倒 );
+/*  参数:;
+/*  	[IN] lpSrcTelephone:源电话号码, 即可颠倒的号码;
+/*  	[OUT] lpDstTelephone:奇偶位颠倒后的号码;
+/*  	[IN/OUT] :;
+/*  返回:返回lpDstTelephone的长度;
+/*  注意:;
+/*  示例:"8615089231318" -> "8615089231318F" -> "685180291331F8";
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+int CShortMessageService::InvertNumbers(IN LPCTSTR lpSrcTelephone, OUT LPTSTR lpDstTelephone, IN int nTelephoneLen /* = 0*/)
+{
+	// 参数校验;
+	if (lpSrcTelephone == NULL || lpSrcTelephone[0] == '\0' || lpDstTelephone == NULL)
+		return -1;
+
+	TCHAR ch;
+	nTelephoneLen = (nTelephoneLen != 0 ? nTelephoneLen : _tcslen(lpSrcTelephone));
+	// 奇偶位颠倒;
+	for (int i = 0; i < nTelephoneLen; i += 2)
+	{
+		ch = *lpSrcTelephone++;
+		*lpDstTelephone++ = *lpSrcTelephone++;	// 注意,如果长度奇数,末尾字符越界;
+		*lpDstTelephone++ = ch;
+	}
+
+	// 号码长度是否为奇数;
+	if (nTelephoneLen & 1)
+	{
+		// 补'F';
+		*(lpDstTelephone - 2) = _T('F');
+		// 长度加1;
+		nTelephoneLen++;
+	}
+
+	// 以\0结尾;
+	lpDstTelephone = '\0';
+
+	// 返回目标字符串长度;
+	return nTelephoneLen;
+}
+
+/************************************************************************/
+/*  函数:[12/26/2017 Home];
+/*  描述:将奇偶位颠倒的手机号码转为正常顺序的手机号;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/*  注意:;
+/*  示例:"685180291331F8" -> "8615089231318";
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+int CShortMessageService::SerializeNumbers(IN LPCTSTR lpSrcTelephone, OUT LPTSTR lpDstTelephone, IN int nTelephoneLen /* = 0 */)
+{
+	// 参数校验;
+	if (lpSrcTelephone == NULL || lpSrcTelephone[0] == '\0' || lpDstTelephone == NULL)
+		return -1;
+
+	TCHAR ch;
+	nTelephoneLen = (nTelephoneLen != 0 ? nTelephoneLen : _tcslen(lpSrcTelephone));
+	// 奇偶位颠倒;
+	for (int i = 0; i < nTelephoneLen; i += 2)
+	{
+		ch = *lpSrcTelephone++;
+		*lpDstTelephone++ = *(lpSrcTelephone++);
+		*lpDstTelephone++ = ch;
+	}
+
+	// 末尾是否奇数;
+	if (nTelephoneLen & 1)
+	{
+		// 去除'F';
+		*lpDstTelephone--;
+		// 长度减1;
+		nTelephoneLen--;
+	}
+
+	// 结束符;
+	*lpDstTelephone = '\0';
+
+	// 返回颠倒后的长度;
+	return nTelephoneLen;
+}
+
+/************************************************************************/
+/*  函数:[8/26/2018 Home];
+/*  描述:将字符串的每个字节转成2位16进制字符的字符串;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/*  注意:;
+/*  示例:{0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01} --> "C8329BFD0E01";
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+int CShortMessageService::Byte2HexString(IN LPCTSTR lpSrcText, IN const int & nSrcTextLen, OUT LPBYTE lpDstText, IN const int & nDstTextLen)
+{
+	// 0x0-0xF的字符查找表;
+	const char tab[] = "0123456789ABCDEF";
+
+	for (int i = 0; i < nSrcTextLen; i++)
+	{
+		// 输出低4位;
+		*lpDstText++ = tab[*lpSrcText >> 4];
+
+		// 输出高4位;
+		*lpDstText++ = tab[*lpSrcText & 0x0f];
+
+		lpSrcText++;
+	}
+
+	// 结束符;
+	*lpDstText = '\0';
+
+	// 返回目标字符串长度;
+	return nSrcTextLen * 2;
+}
+
+/************************************************************************/
+/*  函数:[8/26/2018 Home];
+/*  描述:将16进制(高低位组成)的每2位字符转成一个字节的字符串;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/*  注意:;
+/*  示例:"C8329BFD0E01" --> {0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01}   ;
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+int CShortMessageService::HexString2Byte(IN LPCTSTR lpSrcText, IN const int & nSrcTextLen, OUT LPBYTE lpDstText, IN const int & nDstTextLen)
+{
+	for (int i = 0; i < nSrcTextLen; i += 2)
+	{
+		// 输出高4位;
+		if (*lpSrcText >= '0' && *lpSrcText <= 9)
+		{
+			*lpDstText = (*lpSrcText - '0') << 4;
+		}
+		else
+		{
+			*lpDstText = (*lpSrcText - 'A' + 10) << 4;
+		}
+
+		lpSrcText++;
+		// 输出低4位;
+		if (*lpSrcText >= '0' && *lpSrcText <= 9)
+		{
+			*lpDstText |= *lpSrcText - '0';
+		}
+		else
+		{
+			*lpDstText |= *lpSrcText - 'A' + 10;
+		}
+
+		lpSrcText++;
+		lpDstText++;
+	}
+
+	// 返回目标数据长度;
+	return nSrcTextLen / 2;
+}
+
+/************************************************************************/
+/*  函数:[12/27/2017 Development];
+/*  描述:7-Bit编码;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/*  注意:;
+/*  示例:;
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+int CShortMessageService::Encode7bit(IN LPCTSTR lpSrcText, IN const int &nSrcTextLen, OUT LPBYTE lpDstText, IN const int& nDstTextLen)
+{
+	if (lpSrcText == NULL || lpSrcText[0] == '\0' || nDstTextLen <= 0)
+		return -1;
+
+	// 目标字符串长度;
+	int nDstLen = 0;
+	// 源字符串长度;
+	int nSrcLen = 0;
+	// 当前正在处理的组内字符的字节序号,范围0-7;
+	int nChar = 0;
+	// 上一字节残余数据;
+	BYTE byLeft = 0;
+
+	// 将源字符串每8个字节分为一组,压缩成7个字节;
+	// 循环该处理过程,直到源字符串被处理完;
+	// 如果分组不到8字节,也能正确处理;
+	while (nSrcLen < nSrcTextLen)
+	{
+		// 取源字符串的计数值的最低3位;
+		nChar = nSrcLen & 7;
+
+		// 处理源字符串的每个字节;
+		if (nChar == 0)
+		{
+			// 组内第一个字节,只是保存起来,待处理下一字节时使用;
+			byLeft = *lpSrcText;
+		}
+		else
+		{
+			// 组内其他字节,将其右边部分与残余数据相加,得到一个目标编码字节;
+			*lpDstText = (*lpSrcText << (8 - nChar)) | byLeft;
+			// 将该字节剩下的左边部分, 作为残余数据保存起来;
+			byLeft = *lpSrcText >> nChar;
+			// 修改目标串的指针和计数值;
+			lpDstText++;
+			nDstLen++;
+		}
+
+		// 修改源串的指针和计数值;
+		lpSrcText++;
+		nSrcLen++;
+	}
+
+	// 返回目标串长度;
+	return nDstLen;
+}
+
+/************************************************************************/
+/*  函数:[1/8/2018 Jeff];
+/*  描述:7-bit解码;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/*  注意:;
+/*  示例:;
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+int CShortMessageService::Decode7bit(IN LPCTSTR lpSrcText, IN const int &nSrcTextLen, OUT LPBYTE lpDstText, IN const int& nDstTextLen)
+{
+	if (lpSrcText == NULL || lpSrcText[0] == '\0' || nDstTextLen <= 0)
+		return -1;
+
+	// 目标字符串长度;
+	int nDstLen = 0;
+	// 源字符串长度;
+	int nSrcLen = 0;
+	// 当前正在处理的组内字符的字节序号,范围0-6;
+	int nByte = 0;
+	// 上一字节残余数据;
+	BYTE byLeft = 0;
+
+	// 将源数据每7个字节分为一组,解压成8个字节;
+	// 循环该处理过程,直到源字符串被处理完;
+	// 如果分组不到7字节,也能正确处理;
+	while (nSrcLen < nSrcTextLen)
+	{
+		// 将源字节右边部分与残余数据相加,去掉最高低,得到一个目标解码字节;
+		*lpDstText = ((*lpSrcText << nByte) | byLeft) & 0x7F;
+
+		// 将该字节剩下的左边部分,作为残余数据保存起来;
+		byLeft = *lpSrcText >> (7 - nByte);
+
+		// 修改目标串的指针和计数值;
+		lpDstText++;
+		nDstLen++;
+
+		// 修改字节计数值;
+		nByte++;
+		// 到了一组的最后一个字节;
+		if (nByte == 7)
+		{
+			// 额外得到一个目标解码字节;
+			*lpDstText = byLeft;
+			// 修改目标串的指针和计数值;
+			lpDstText++;
+			nDstLen++;
+			// 组内字节序号和残余数据初始化;
+			nByte = 0;
+			byLeft = 0;
+		}
+
+		// 修改源串的指针和计数值;
+		lpSrcText++;
+		nSrcLen++;
+	}
+
+	*lpDstText = 0;
+
+	// 返回目标串长度;
+	return nDstLen;
+}
+
+
+/************************************************************************/
+/*  函数:[1/8/2018 Jeff];
+/*  描述:8-Bit编码;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:返回目标编码字符串长度;
+/*  注意:;
+/*  示例:;
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+int CShortMessageService::Encode8bit(IN LPCTSTR lpSrcText, IN const int &nSrcTextLen, OUT LPBYTE lpDstText, IN const int& nDstTextLen)
+{
+	// 简单复制;
+	memcpy(lpDstText, lpSrcText, nSrcTextLen);
+
+	return nSrcTextLen;
+}
+
+
+/************************************************************************/
+/*  函数:[1/8/2018 Jeff];
+/*  描述:8-bit解码;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/*  注意:;
+/*  示例:;
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+int CShortMessageService::Decode8bit(IN LPCTSTR lpSrcText, IN const int &nSrcTextLen, OUT LPBYTE lpDstText, IN const int& nDstTextLen)
+{
+	// 简单复制;
+	memcpy(lpDstText, lpSrcText, nSrcTextLen);
+	// 结束符;
+	*lpDstText = '\0';
+
+	return nSrcTextLen;
+}
+
+/************************************************************************/
+/*  函数:[8/26/2018 Home];
+/*  描述:PDU编码,用于编制、发送短信;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/*  注意:;
+/*  示例:;
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+int CShortMessageService::EncodePdu(IN const SM_PARAM *pSMParam, OUT LPBYTE lpDstText, IN const int& nDstTextLen)
+{
+	// 目标字符串长度;
+	int nDstLen = 0;
+	// 源字符串长度;
+	int nSrcLen = 0;
+	// 缓冲区;
+	unsigned char szBuf[256] = {0};
+
+	/*  SMSC地址信息段; */
+	// SMSC地址字符串的长度;
+	nSrcLen = strlen((char*)pSMParam->SCA);	
+	// SMSC地址信息长度;
+	szBuf[0] = (char)((nSrcLen & 1) == 0 ? nSrcLen : nSrcLen + 1)/2 + 1;
+	// 暂时固定:使用国际格式号码;
+	szBuf[1] = 0x91;	
+	// 转换2个字节到目标PDU字符串中;
+	nDstLen = Byte2HexString((char*)szBuf, 2, lpDstText + nDstLen, nDstTextLen);
+	// 转换SMSC到目标PDU字符串中;
+	nDstLen += InvertNumbers((char*)pSMParam->SCA, (char*)lpDstText + nDstLen, nSrcLen);
+
+	/* TPDU段基本参数、目标址等 */
+	// TP-DA地址字符串的长度;
+	nSrcLen = strlen((char*)pSMParam->TPA);
+	// 是发送短信(TP-MTI=01),TP-VP用相对格式(TP-VPF=10) 
+	szBuf[0] = 0X11;
+	// TP-MR = 0;
+	szBuf[1] = 0;
+	// 目标地址数字个数(TP-DA地址字符串真实长度);
+	szBuf[2] = (char)nSrcLen;
+	// 暂时固定:使用国际格式号码;
+	szBuf[3] = 0x91;
+	// 转换4个字节到目标PDU字符串中;
+	nDstLen += Byte2HexString((char*)szBuf, 4, lpDstText + nDstLen, nDstTextLen);
+	// 转换SMSC到目标PDU字符串中;
+	nDstLen += InvertNumbers((char*)pSMParam->TPA, (char*)lpDstText + nDstLen, nSrcLen);
+
+	/* TPDU段协议标识、编码方式、用户信息等 */
+	// TP_UD(用户信息)字符串的长度;
+	nSrcLen = strlen((char*)pSMParam->TP_UD);
+	// 协议标识(TP-PID);
+	szBuf[0] = pSMParam->TP_PID;
+	// 用户信息编码方式(TP-DCS) ;
+	szBuf[1] = pSMParam->TP_DCS;
+	// 有效期(TP-VP)为5分钟;
+	szBuf[2] = 0;
+	if ( pSMParam->TP_DCS == GSM_7BIT )
+	{// 7-bit编码;
+		// 编码前长度; 
+		szBuf[3] = nSrcLen;
+		 // 转换TP-DA到目标PDU串;
+		nSrcLen = Encode7bit((char*)pSMParam->TP_UD, 161/*魔数*/, &szBuf[4], nSrcLen+1) + 4;
+	}
+	else if ( pSMParam->TP_DCS == GSM_UCS2 )
+	{// UCS2编码;
+		// 转换TP-DA到目标PDU串;
+		szBuf[3] = EncodeUcs2((char*)pSMParam->TP_UD, 161, &szBuf[4], nSrcLen);
+		 // nSrcLen等于该段数据长度
+		nSrcLen = szBuf[3] + 4;
+	}
+	else if ( pSMParam->TP_DCS == GSM_8BIT )
+	{// 8-bit编码;
+		// 转换TP-DA到目标PDU串;
+		szBuf[3] = EncodeUcs2((char*)pSMParam->TP_UD, 161, &szBuf[4], nSrcLen);
+		// nSrcLen等于该段数据长度
+		nSrcLen = szBuf[3] + 4;
+	}
+
+	// 转换该段数据到目标PDU字符串中;
+	nDstLen += Byte2HexString((char*)szBuf, 4, lpDstText + nDstLen, nSrcLen);
+
+	// 返回目标字符串长度;
+	return nDstLen;
+}
+
+int CShortMessageService::EncodePdu(IN LPCTSTR lpSrcText, IN const int & nSrcTextLen, OUT LPBYTE lpDstText, IN const int & nDstTextLen)
+{
+	return 0;
+}
+
+/************************************************************************/
+/*  函数:[8/26/2018 Home];
+/*  描述:PDU编码,用于接收、阅读短信;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/*  注意:;
+/*  示例:;
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+int CShortMessageService::DecodePdu(IN LPCTSTR lpSrcText, IN const int &nSrcTextLen, OUT SM_PARAM *pSMParam)
+{
+	// 目标PDU字符串长度;
+	int nDstLen = 0;
+	// 临时字节变量;
+	unsigned char ch;
+	// 缓冲区;
+	unsigned char szBuf[256] = {0};
+
+	/* SMSC地址信息段 */
+	// 取长度;
+	HexString2Byte(lpSrcText, 2/*截取长度*/, &ch, 1);
+	// SMSC号码长度;
+	ch = (ch - 1)*2;
+	// 后移4位;
+	lpSrcText += 4;
+	// 转换SMSC号码到目标PDU串;
+	SerializeNumbers(lpSrcText, (char*)pSMParam->SCA, ch);
+	lpSrcText += ch;
+
+	/* TPDU段基本参数、回复地址等 */ 
+	// 取基本参数 ; 
+	HexString2Byte(lpSrcText, 2, &ch, 1);
+	lpSrcText += 2;
+	if ( ch & 0x80)
+	{
+		// 包含回复地址,取回复地址信息;
+		HexString2Byte(lpSrcText, 2, &ch, 1);	// 取长度;
+		// 调整奇偶性;
+		if ( ch & 1 )
+			ch += 1;
+		lpSrcText += 4;
+
+		// 取TP-RA号码;
+		SerializeNumbers(lpSrcText, (char*)pSMParam->TPA, ch);
+		lpSrcText += ch;
+	}
+
+	/* TPDU段协议标识、编码方式、用户信息等 */
+	// 取协议标识(TP-PID) ;
+	HexString2Byte(lpSrcText, 2, &pSMParam->TP_PID, 1);
+	lpSrcText += 2;
+
+	// 取编码方式(TP-DCS) ;
+	HexString2Byte(lpSrcText, 2, &pSMParam->TP_DCS, 1);
+	lpSrcText += 2;
+
+	// 服务时间戳字符串(TP_SCTS)  ;
+	SerializeNumbers(lpSrcText, (char*)&pSMParam->TP_SCTS, 14);
+	lpSrcText += 14;
+
+	// 用户信息长度(TP-UDL)   ;
+	HexString2Byte(lpSrcText, 2, &ch, 1);
+	lpSrcText += 2;
+
+	if ( pSMParam->TP_DCS == GSM_7BIT )
+	{//7-bit解码;
+		// 格式转换;
+		nDstLen = HexString2Byte(lpSrcText, (ch & 7) ? ch * 7/4 +2 : ch *7/4, szBuf, 256);
+		// 转换到TP-UD中;
+		Decode7bit((char*)szBuf, nDstLen, pSMParam->TP_UD, 161);
+		nDstLen = ch;
+	}
+	else if ( pSMParam->TP_DCS == GSM_UCS2 )
+	{//UCS2解码;
+		// 格式转换;
+		nDstLen = HexString2Byte(lpSrcText, ch * 2, szBuf, 256);
+		// 转换成TP-UD中;
+		nDstLen = DecodeUcs2((char*)szBuf, nDstLen, pSMParam->TP_UD, 161);
+	}
+	else 
+	{// 8-bit解码;
+		// 格式转换;
+		nDstLen = HexString2Byte(lpSrcText, ch * 2, szBuf, 256);
+		// 转换到TP-UD中;
+		nDstLen = Decode8bit((char*)szBuf, nDstLen, pSMParam->TP_UD, 161);
+	}
+
+	// 返回目标字符串长度;
+	return nDstLen;
+}
+
+int CShortMessageService::DecodePdu(IN LPCTSTR lpSrcText, IN const int & nSrcTextLen, OUT LPBYTE lpDstText, IN const int & nDstTextLen)
+{
+	return 0;
+}
+
+
+/************************************************************************/
+/*  函数:[1/8/2018 Jeff];
+/*  描述:UCS2编码;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/*  注意:;
+/*  示例:;
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+int CShortMessageService::EncodeUcs2(IN LPCTSTR lpSrcText, IN const int &nSrcTextLen, OUT LPBYTE lpDstText, IN const int& nDstTextLen)
+{
+	// 宽字符长度;
+	int nDstLength = 0;
+	// 宽字符缓存区;
+	WCHAR wchar[128] = { 0 };
+
+	// 多字节->unicode; 
+	nDstLength = MultiByteToWideChar(CP_ACP, 0, lpSrcText, nSrcTextLen, wchar, 128);
+
+	// 高低字节对调;
+	for (int i = 0; i < nDstLength; i++)
+	{
+		*lpDstText++ = wchar[i] >> 8;	// 先输出高位字节;
+		*lpDstText++ = wchar[i] & 0xff;	// 再输出低位字节;
+	}
+
+	// 返回目标编码串长度;
+	return nDstLength * 2;
+}
+
+/************************************************************************/
+/*  函数:[1/8/2018 Jeff];
+/*  描述:UCS2解码;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/*  注意:;
+/*  示例:;
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+int CShortMessageService::DecodeUcs2(IN LPCTSTR lpSrcText, IN const int &nSrcTextLen, OUT LPBYTE lpDstText, IN const int& nDstTextLen)
+{
+	// 宽字符长度;
+	int nDstLength = 0;
+	// 宽字符缓存区;
+	WCHAR wchar[128] = { 0 };
+
+	// 高低字节对调, 拼成unicode;
+	for (int i = 0; i < nSrcTextLen / 2; i++)
+	{
+		wchar[i] = *lpSrcText++ << 8;	// 先输出高位字节;
+		wchar[i] |= *lpSrcText++;		// 再输出低位字节;
+	}
+
+	// 转成unicode;
+	nDstLength = WideCharToMultiByte(CP_ACP, 0, wchar, nSrcTextLen / 2, (char*)lpDstText, 160, NULL, NULL);
+
+	// 添加结束符;
+	lpDstText[nDstLength] = '\0';
+
+	// 返回目标编码串长度;
+	return nDstLength;
+}

+ 124 - 0
短信猫/sms/sms/ShortMessageService.h

@@ -0,0 +1,124 @@
+/************************************************************************/
+/*  函数:[12/26/2017 Home];
+/*  描述:;
+/*  参数:;
+/*  	[IN] :;
+/*  	[OUT] :;
+/*  	[IN/OUT] :;
+/*  返回:void;
+/*  注意:;
+/*  示例:;
+/*
+/*  修改:;
+/*  日期:;
+/*  内容:;
+/************************************************************************/
+
+#ifndef __SMS_HEADER__
+#define __SMS_HEADER__
+
+#include "SynSerial.h"
+
+#pragma once
+
+// 用户信息编码方式;
+#define GSM_7BIT	0
+#define GSM_8BIT	4
+#define GSM_UCS2	8
+
+// 应答状态;
+#define GSM_WAIT	0	// 等待,不确定;
+#define GSM_OK		1	// ok;
+#define GSM_ERR		-1	// ERROR
+
+// 编码常量;
+#define CONST91		"91"
+#define CONSTF		"F"
+#define CONSTLEN	1024
+#define CONST0		0
+
+// 短信消息结构,编码/解码使用;
+typedef struct
+{
+	// 短信消息服务中心号码(SMSC地址);
+	BYTE SCA[16];
+	// 目标号码或回复号码(TP-DA或TP-RA)
+	BYTE TPA[16];
+	// 用户信息协议标识(TP-PID);
+	BYTE TP_PID;
+	// 用户编码方式(TP-DCS);
+	BYTE TP_DCS;
+	// 服务时间戳字符串(TP-SCTS),接收时用到;
+	BYTE TP_SCTS[16];
+	// 原始用户信息(编码前或解码后的TP-UD);
+	BYTE TP_UD[161];
+	// 短信消息序号,在读取时用到;
+	BYTE nIndex;
+}SM_PARAM;
+
+typedef struct {
+	int		len;
+	char	data[16384];
+}SM_BUFF;
+
+class CShortMessageService:public CSynSerial
+{
+public:
+	CShortMessageService(void);
+	virtual ~CShortMessageService(void);
+
+public:
+	// 初始化pdu环境;
+	BOOL InitGSM();
+	// 发送短信;
+	BOOL SendShortMessage(IN SM_PARAM *sm_param);
+	int SendShortMessage(IN LPCTSTR lpSentPhone, IN LPCTSTR lpSendMsg);
+	// 接收短信;
+	int ReceiveMessage(SM_PARAM *sm_param, int nIndex);
+	// 接收所有未读新短信;
+	int ReceiveUnreadMessage(SM_PARAM *sm_param);
+	// 接收所有未读新短信;
+	int ReceiveAllMessage(SM_PARAM *sm_param);
+	// 删除所有短信;
+	bool DeleteAllMessage();
+	// 删除指定序号短信;
+	bool DeleteMessage(int nIndex);
+	// 设置是否关回显,并缺省设置为PDU模式;
+	bool SetSendModule(BOOL bLoopback);
+
+	// 设置短信中心号码;
+	BOOL SetCenterNumber(IN LPCTSTR lpCenterNumber);
+	// 获取短信中心号码;
+	BOOL GetCenterNumber(OUT LPTSTR lpCenterNumber);
+
+public:
+	// 手机号码奇偶对换;
+	int InvertNumbers(IN LPCTSTR lpSrcTelephone, OUT LPTSTR lpDstTelephone, IN int nTelephoneLen = 0);
+	// 手机号码序列化;
+	int SerializeNumbers(IN LPCTSTR lpSrcTelephone, OUT LPTSTR lpDstTelephone, IN int nTelephoneLen = 0);
+
+	// 编码Ucs2; 
+	int EncodeUcs2(IN LPCTSTR lpSrcText, IN const int &nSrcTextLen, OUT LPBYTE lpDstText, IN const int& nDstTextLen);
+	// 解码Ucs2;
+	int DecodeUcs2(IN LPCTSTR lpSrcText, IN const int &nSrcTextLen, OUT LPBYTE lpDstText, IN const int& nDstTextLen);
+
+	// 将字节转成16进制字符;
+	int Byte2HexString(IN LPCTSTR lpSrcText, IN const int &nSrcTextLen, OUT LPBYTE lpDstText, IN const int& nDstTextLen);
+	// 将16进制字符串转成字节;
+	int HexString2Byte(IN LPCTSTR lpSrcText, IN const int &nSrcTextLen, OUT LPBYTE lpDstText, IN const int& nDstTextLen);
+
+	// 编码7Bit
+	int Encode7bit(IN LPCTSTR lpSrcText, IN const int &nSrcTextLen, OUT LPBYTE lpDstText, IN const int& nDstTextLen);
+	int Decode7bit(IN LPCTSTR lpSrcText, IN const int &nSrcTextLen, OUT LPBYTE lpDstText, IN const int& nDstTextLen);
+
+	int Encode8bit(IN LPCTSTR lpSrcText, IN const int &nSrcTextLen, OUT LPBYTE lpDstText, IN const int& nDstTextLen);
+	int Decode8bit(IN LPCTSTR lpSrcText, IN const int &nSrcTextLen, OUT LPBYTE lpDstText, IN const int& nDstTextLen);
+
+	int EncodePdu(IN const SM_PARAM *pSMParam, OUT LPBYTE lpDstText, IN const int& nDstTextLen);
+	int DecodePdu(IN LPCTSTR lpSrcText, IN const int &nSrcTextLen, OUT SM_PARAM *pSMParam);
+
+	int EncodePdu(IN LPCTSTR lpSrcText, IN const int &nSrcTextLen, OUT LPBYTE lpDstText, IN const int& nDstTextLen);
+	int DecodePdu(IN LPCTSTR lpSrcText, IN const int &nSrcTextLen, OUT LPBYTE lpDstText, IN const int& nDstTextLen);
+};
+
+#endif // __SMS_HEADER__

+ 312 - 0
短信猫/sms/sms/SynSerial.cpp

@@ -0,0 +1,312 @@
+#include "StdAfx.h"
+#include "SynSerial.h"
+
+CSynSerial::CSynSerial(void) :m_hSerialPort(NULL)
+, m_dwInQueue(1024)
+, m_dwOutQueue(1024)
+{
+	memset(&m_dcb, 0, sizeof(DCB));
+	memset(&m_cts, 0, sizeof(COMMTIMEOUTS));
+	memset(&m_szSerialPort, 0, sizeof(TCHAR)*MAX_PORT_LEN);
+}
+
+CSynSerial::~CSynSerial(void)
+{
+	CloseSerialPort();
+}
+
+BOOL CSynSerial::OpenSerialPort(IN CONST BYTE & byCommPort, IN CONST DWORD & dwBaudRate, IN CONST BYTE & bySize, IN CONST BYTE & byParity, IN CONST BYTE & byStopBits, IN CONST BYTE & byStartAddr, IN CONST INT & nInterval)
+{
+	ASSERT(byCommPort);
+	CloseSerialPort();
+
+	_stprintf_s(m_szSerialPort, _T("\\\\.\\com%d"), (int)byCommPort);
+	m_hSerialPort = CreateFile(m_szSerialPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, NULL, NULL);
+	if (m_hSerialPort == INVALID_HANDLE_VALUE)
+	{
+		// 打开串口失败;
+		DWORD dwError = GetLastError();
+		return FALSE;
+	}
+
+	BOOL bResult = FALSE;
+	// SetupComm设置缓冲区大小;
+	bResult = SetupComm(m_hSerialPort, m_dwInQueue, m_dwOutQueue);
+	if (!bResult)
+	{
+		DWORD dwError = GetLastError();
+		return FALSE;
+	}
+
+	// 在串口读写之前,清除缓冲区;
+	bResult = PurgeComm(m_hSerialPort, PURGE_TXCLEAR | PURGE_RXCLEAR);
+	if (!bResult)
+	{
+		DWORD dwError = GetLastError();
+		return FALSE;
+	}
+
+	// GetCommState获取设备控制块状态;
+	memset(&m_dcb, 0, sizeof(DCB));
+	bResult = GetCommState(m_hSerialPort, &m_dcb);
+	if (!bResult)
+	{
+		DWORD dwError = GetLastError();
+		return FALSE;
+	}
+
+	m_dcb.Parity = byParity;
+	if (m_dcb.Parity == NOPARITY)
+		m_dcb.fParity = FALSE;
+	else
+		m_dcb.fParity = TRUE;
+
+	m_dcb.BaudRate = dwBaudRate;
+	m_dcb.ByteSize = bySize;
+	m_dcb.StopBits = byStopBits;
+	if (m_dcb.ByteSize == 8)
+		m_dcb.StopBits = ONESTOPBIT;
+
+	// SetCommState设置设备的控制块状态;
+	memset(&m_cts, 0, sizeof(COMMTIMEOUTS));
+	bResult = SetCommState(m_hSerialPort, &m_dcb);
+	if (!bResult)
+	{
+		DWORD dwError = GetLastError();
+		return FALSE;
+	}
+
+	// 获取设备的超时值;
+	bResult = GetCommTimeouts(m_hSerialPort, &m_cts);
+	if (!bResult)
+	{
+		DWORD dwError = GetLastError();
+		return FALSE;
+	}
+
+	// 两字符之间最大的延时,设置0表示参数不起作用;
+	m_cts.ReadIntervalTimeout = MAXDWORD;
+	m_cts.ReadTotalTimeoutMultiplier = 0;
+	m_cts.ReadTotalTimeoutConstant = 0;
+	m_cts.WriteTotalTimeoutMultiplier = 0;
+	m_cts.WriteTotalTimeoutConstant = 0;
+
+	// 设置设备的超时值;
+	bResult = SetCommTimeouts(m_hSerialPort, &m_cts);
+	if (!bResult)
+	{
+		DWORD dwError = GetLastError();
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+BOOL CSynSerial::ReOpenSerialPort()
+{
+	ASSERT(_tcslen(m_szSerialPort));
+	CloseSerialPort();
+
+	m_hSerialPort = CreateFile(m_szSerialPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, NULL, NULL);
+	if (m_hSerialPort == INVALID_HANDLE_VALUE)
+	{
+		// 打开串口失败;
+		DWORD dwError = GetLastError();
+		return FALSE;
+	}
+
+	BOOL bResult = FALSE;
+	// SetupComm设置缓冲区大小;
+	bResult = SetupComm(m_hSerialPort, m_dwInQueue, m_dwOutQueue);
+	if (!bResult)
+	{
+		DWORD dwError = GetLastError();
+		return FALSE;
+	}
+
+	// 在串口读写之前,清除缓冲区;
+	bResult = PurgeComm(m_hSerialPort, PURGE_TXCLEAR | PURGE_RXCLEAR);
+	if (!bResult)
+	{
+		DWORD dwError = GetLastError();
+		return FALSE;
+	}
+
+	// SetCommState设置设备的控制块状态;
+	memset(&m_cts, 0, sizeof(COMMTIMEOUTS));
+	bResult = SetCommState(m_hSerialPort, &m_dcb);
+	if (!bResult)
+	{
+		DWORD dwError = GetLastError();
+		return FALSE;
+	}
+
+	// 设置设备的超时值;
+	bResult = SetCommTimeouts(m_hSerialPort, &m_cts);
+	if (!bResult)
+	{
+		DWORD dwError = GetLastError();
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+void CSynSerial::CloseSerialPort()
+{
+	if (m_hSerialPort != NULL && m_hSerialPort != INVALID_HANDLE_VALUE)
+		CloseHandle(m_hSerialPort);
+	m_hSerialPort = NULL;
+}
+
+BOOL CSynSerial::SetSerialPort(IN CONST DWORD & dwBaudRate, IN CONST BYTE & byByteSize, IN CONST BYTE & byParity, IN CONST BYTE & byStopBits, IN CONST BYTE & byStartAddr, IN CONST DWORD & dwInQueue, IN CONST DWORD & dwOutQueue)
+{
+	if (!IsOpen())
+		return FALSE;
+
+	BOOL bResult = FALSE;
+	// GetCommState获取设备控制块状态;
+	memset(&m_dcb, 0, sizeof(DCB));
+	bResult = GetCommState(m_hSerialPort, &m_dcb);
+	if (!bResult)
+	{
+		DWORD dwError = GetLastError();
+		return FALSE;
+	}
+
+	m_dcb.Parity = byParity;
+	if (m_dcb.Parity == NOPARITY)
+		m_dcb.fParity = FALSE;
+	else
+		m_dcb.fParity = TRUE;
+
+	m_dcb.BaudRate = dwBaudRate;
+	m_dcb.ByteSize = byByteSize;
+	m_dcb.StopBits = byStopBits;
+	if (m_dcb.ByteSize == 8)
+		m_dcb.StopBits = ONESTOPBIT;
+
+	// SetCommState设置设备的控制块状态;
+	memset(&m_cts, 0, sizeof(COMMTIMEOUTS));
+	bResult = SetCommState(m_hSerialPort, &m_dcb);
+	if (!bResult)
+	{
+		DWORD dwError = GetLastError();
+		return FALSE;
+	}
+
+	// 获取设备的超时值;
+	bResult = GetCommTimeouts(m_hSerialPort, &m_cts);
+	if (!bResult)
+	{
+		DWORD dwError = GetLastError();
+		return FALSE;
+	}
+
+	// 两字符之间最大的延时,设置0表示参数不起作用;
+	m_cts.ReadIntervalTimeout = MAXDWORD;
+	m_cts.ReadTotalTimeoutMultiplier = 0;
+	m_cts.ReadTotalTimeoutConstant = 0;
+	m_cts.WriteTotalTimeoutMultiplier = 0;
+	m_cts.WriteTotalTimeoutConstant = 0;
+
+	// 设置设备的超时值;
+	bResult = SetCommTimeouts(m_hSerialPort, &m_cts);
+	if (!bResult)
+	{
+		DWORD dwError = GetLastError();
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+void CSynSerial::SetSerialDCB(IN CONST DCB & dcb)
+{
+}
+
+void CSynSerial::SetSerialCommTimeouts(IN CONST COMMTIMEOUTS & commTimeouts)
+{
+}
+
+DWORD CSynSerial::WriteComm(IN BYTE * pWirteBuf, IN CONST INT32 & nWriteSize)
+{
+	if (!IsOpen())
+		return 0;
+
+	if (pWirteBuf == NULL || !::AfxIsValidAddress(pWirteBuf, nWriteSize, FALSE))
+	{
+		return 0;
+	}
+	
+	DWORD dwErrorFlags;
+	DWORD dwBytesWritten = 0;	// 实际写入的字节数;
+	// 写前, 清除错误;
+	COMSTAT ComStat;
+	ClearCommError(m_hSerialPort, &dwErrorFlags, &ComStat);	
+
+	if ( !WriteFile(m_hSerialPort, pWirteBuf, nWriteSize, &dwBytesWritten, NULL) )
+	{
+		DWORD dwError = GetLastError();
+	}
+
+	// 写完后,清空缓存区;
+	PurgeComm(m_hSerialPort, PURGE_TXABORT |PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
+
+	// 返回写入字节数;
+	return dwBytesWritten;
+}
+
+DWORD CSynSerial::ReadComm(IN BYTE * pReadBuf, IN CONST DWORD & dwReadSize)
+{
+	if (!IsOpen())
+		return 0;
+
+	if (pReadBuf == NULL || !::AfxIsValidAddress(pReadBuf, dwReadSize, FALSE))
+	{
+		return 0;
+	}
+
+	DWORD dwBytesRead = 0;
+	DWORD dwErrorFlags = 0;
+
+	// ReadFile前,使用ClearCommError清除错误;
+	COMSTAT ComStat;
+	ClearCommError(m_hSerialPort, &dwErrorFlags, &ComStat);
+
+#if 1
+	// 使用ClearCommError来读取缓存区接受到的字节时, 
+	// 可能受系统线程调试或硬件延时, cbInQue为空, 
+	// 这里要用while延时获取;
+	DWORD dwTick = GetTickCount();
+	while (ComStat.cbInQue == 0)
+	{// cbInQue表示输入缓冲区的字节数; 
+		Sleep(100);
+		if (GetTickCount() - dwTick > 3000)
+			break;
+		ClearCommError(m_hSerialPort, &dwErrorFlags, &ComStat);		
+	}
+
+	if (ComStat.cbInQue == 0)
+	{
+		// 串口无数据返回;
+		return 0;
+	}
+#endif
+
+	dwBytesRead = ComStat.cbInQue;
+	if (dwReadSize < dwBytesRead)
+	{
+		dwBytesRead = dwReadSize;
+	}
+
+	if (ReadFile(m_hSerialPort, pReadBuf, dwBytesRead, &dwBytesRead, NULL))
+	{
+		return (INT)dwBytesRead;
+	}
+
+	// 读完后,清空缓存区;
+	PurgeComm(m_hSerialPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
+
+	return dwBytesRead;
+}

+ 83 - 0
短信猫/sms/sms/SynSerial.h

@@ -0,0 +1,83 @@
+/************************************************************************/
+/*  Copyright (C), 2016-2020, [Home], 保留所有权利;
+/*  模 块 名:同步串口模块;
+/*  描    述:;
+/*
+/*  版    本:[V];
+/*  作    者:[Home];
+/*  日    期:[12/20/2017];
+/*
+/*
+/*  注    意:;
+/*
+/*  修改记录:[Home];
+/*  修改日期:;
+/*  修改版本:;
+/*  修改内容:;
+/************************************************************************/
+
+#ifndef __SYN_SERIAL__
+#define __SYN_SERIAL__
+
+#pragma once
+
+#define MAX_PORT_LEN 10
+
+class CSynSerial
+{
+public:
+	CSynSerial(void);
+	virtual ~CSynSerial(void);
+
+private:
+	DCB		m_dcb;
+	HANDLE	m_hSerialPort;
+	COMMTIMEOUTS	m_cts;
+
+	// 串口号(1~255);
+	TCHAR	m_szSerialPort[MAX_PORT_LEN];
+	// 输入缓存大小(byte);
+	DWORD	m_dwInQueue;
+	// 输出缓存大小(byte);
+	DWORD	m_dwOutQueue;
+
+public:
+	inline BOOL IsOpen() const {
+		return (m_hSerialPort == NULL || m_hSerialPort == INVALID_HANDLE_VALUE) ? FALSE : TRUE;
+	}
+
+	// 打开串口;
+	BOOL OpenSerialPort(
+		IN CONST BYTE& byCommPort,		// 串口号;
+		IN CONST DWORD& dwBaudRate,		// 波特率;
+		IN CONST BYTE& bySize,			// 数据位;
+		IN CONST BYTE& byParity,		// 校验位;
+		IN CONST BYTE& byStopBits,		// 停止位;
+		IN CONST BYTE& byStartAddr,		// 起始地址;
+		IN CONST INT& nInterval			// 间隔时间;
+	);
+	// 重装打开串口;
+	BOOL ReOpenSerialPort();
+	// 关闭串口;
+	void CloseSerialPort();
+	// 设置串口参数;
+	BOOL SetSerialPort(
+		IN CONST DWORD& dwBaudRate,		// 波特率;
+		IN CONST BYTE& byByteSize,		// 数据位;
+		IN CONST BYTE& byParity,		// 校验位;
+		IN CONST BYTE& byStopBits,		// 停止位;
+		IN CONST BYTE& byStartAddr,		// 起始地址;
+		IN CONST DWORD& dwInQueue,		// 输入缓存;
+		IN CONST DWORD& dwOutQueue		// 输出缓存;
+		);
+
+	// 设置dcb参数;
+	void SetSerialDCB(IN CONST DCB &dcb);
+	// 设置commtimeouts参数;
+	void SetSerialCommTimeouts(IN CONST COMMTIMEOUTS &commTimeouts);
+
+	virtual DWORD WriteComm(IN BYTE *pWirteBuf, IN CONST INT32& nWriteSize);
+	virtual DWORD ReadComm(IN BYTE *pReadBuf, IN CONST DWORD& nReadSize);
+};
+
+#endif // __SYN_SERIAL__

+ 13 - 0
短信猫/sms/sms/res/sms.rc2

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

+ 63 - 0
短信猫/sms/sms/sms.cpp

@@ -0,0 +1,63 @@
+// sms.cpp : 定义 DLL 的初始化例程。
+//
+
+#include "stdafx.h"
+#include "sms.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+//
+//TODO: 如果此 DLL 相对于 MFC DLL 是动态链接的,
+//		则从此 DLL 导出的任何调入
+//		MFC 的函数必须将 AFX_MANAGE_STATE 宏添加到
+//		该函数的最前面。
+//
+//		例如:
+//
+//		extern "C" BOOL PASCAL EXPORT ExportedFunction()
+//		{
+//			AFX_MANAGE_STATE(AfxGetStaticModuleState());
+//			// 此处为普通函数体
+//		}
+//
+//		此宏先于任何 MFC 调用
+//		出现在每个函数中十分重要。这意味着
+//		它必须作为函数中的第一个语句
+//		出现,甚至先于所有对象变量声明,
+//		这是因为它们的构造函数可能生成 MFC
+//		DLL 调用。
+//
+//		有关其他详细信息,
+//		请参阅 MFC 技术说明 33 和 58。
+//
+
+// CsmsApp
+
+BEGIN_MESSAGE_MAP(CsmsApp, CWinApp)
+END_MESSAGE_MAP()
+
+
+// CsmsApp 构造
+
+CsmsApp::CsmsApp()
+{
+	// TODO: 在此处添加构造代码,
+	// 将所有重要的初始化放置在 InitInstance 中
+}
+
+
+// 唯一的一个 CsmsApp 对象
+
+CsmsApp theApp;
+
+
+// CsmsApp 初始化
+
+BOOL CsmsApp::InitInstance()
+{
+	CWinApp::InitInstance();
+
+	return TRUE;
+}

+ 6 - 0
短信猫/sms/sms/sms.def

@@ -0,0 +1,6 @@
+; sms.def : 声明 DLL 的模块参数。
+
+LIBRARY      "sms"
+
+EXPORTS
+    ; 此处可以是显式导出

+ 27 - 0
短信猫/sms/sms/sms.h

@@ -0,0 +1,27 @@
+// sms.h : sms DLL 的主头文件
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+	#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
+#endif
+
+#include "resource.h"		// 主符号
+
+
+// CsmsApp
+// 有关此类实现的信息,请参阅 sms.cpp
+//
+
+class CsmsApp : public CWinApp
+{
+public:
+	CsmsApp();
+
+// 重写
+public:
+	virtual BOOL InitInstance();
+
+	DECLARE_MESSAGE_MAP()
+};

+ 125 - 0
短信猫/sms/sms/sms.rc

@@ -0,0 +1,125 @@
+// Microsoft Visual C++ 生成的资源脚本。
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// 从 TEXTINCLUDE 2 资源生成。
+//
+#ifndef APSTUDIO_INVOKED
+#include "targetver.h"
+#endif
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+#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\\sms.rc2""  // 非 Microsoft Visual C++ 编辑的资源\r\n"
+#ifndef _AFXDLL
+    "#include ""l.CHS\\afxres.rc""  	// 标准组件\r\n"
+#endif
+    "#endif\r\n"
+    "\0"
+END
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // APSTUDIO_INVOKED
+
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
+LANGUAGE 4, 2
+#pragma code_page(936)
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// 版本
+//
+
+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 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+	BLOCK "StringFileInfo"
+	BEGIN
+        BLOCK "080403a8"
+		BEGIN
+            VALUE "CompanyName", "TODO: <公司名>"
+            VALUE "FileDescription", "TODO: <文件说明>"
+			VALUE "FileVersion",     "1.0.0.1"
+			VALUE "InternalName",    "sms.dll"
+            VALUE "LegalCopyright", "TODO: (C) <公司名>。保留所有权利。"
+			VALUE "OriginalFilename","sms.dll"
+            VALUE "ProductName", "TODO: <产品名>"
+			VALUE "ProductVersion",  "1.0.0.1"
+		END
+	END
+	BLOCK "VarFileInfo"
+	BEGIN
+		VALUE "Translation", 0x0804, 936
+    END
+END
+
+#endif
+#ifndef APSTUDIO_INVOKED
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// 从 TEXTINCLUDE 3 资源生成。
+//
+#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\\sms.rc2"  // 非 Microsoft Visual C++ 编辑的资源
+#ifndef _AFXDLL
+#include "l.CHS\\afxres.rc"  	// 标准组件
+#endif
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // 不是 APSTUDIO_INVOKED
+

+ 311 - 0
短信猫/sms/sms/sms.vcproj

@@ -0,0 +1,311 @@
+<?xml version="1.0" encoding="gb2312"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="sms"
+	ProjectGUID="{00431A09-2ADE-45D9-BF19-4AC06027B710}"
+	RootNamespace="sms"
+	Keyword="MFCDLLProj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="..\..\..\..\bin\$(SolutionName)"
+			IntermediateDirectory="$(OutDir)\$(ProjectName)\$(ConfigurationName)"
+			ConfigurationType="2"
+			UseOfMFC="2"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="_DEBUG"
+				MkTypLibCompatible="false"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;_USRDLL"
+				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="2"
+				ModuleDefinitionFile=".\sms.def"
+				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="..\..\..\..\bin\$(SolutionName)"
+			IntermediateDirectory="$(OutDir)\$(ProjectName)\$(ConfigurationName)"
+			ConfigurationType="2"
+			UseOfMFC="2"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="false"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;_USRDLL"
+				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"
+				ModuleDefinitionFile=".\sms.def"
+				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="源文件"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\CommRS232.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\ShortMessageService.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\sms.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\sms.def"
+				>
+			</File>
+			<File
+				RelativePath=".\SMSProcess.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="头文件"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\CommRS232.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Resource.h"
+				>
+			</File>
+			<File
+				RelativePath=".\ShortMessageService.h"
+				>
+			</File>
+			<File
+				RelativePath=".\sms.h"
+				>
+			</File>
+			<File
+				RelativePath=".\SMSProcess.h"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.h"
+				>
+			</File>
+			<File
+				RelativePath=".\targetver.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="资源文件"
+			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=".\sms.rc"
+				>
+			</File>
+			<File
+				RelativePath=".\res\sms.rc2"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="串口"
+			>
+			<File
+				RelativePath=".\AsynSerial.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\AsynSerial.h"
+				>
+			</File>
+			<File
+				RelativePath=".\CompletionSerial.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\CompletionSerial.h"
+				>
+			</File>
+			<File
+				RelativePath=".\SynSerial.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\SynSerial.h"
+				>
+			</File>
+		</Filter>
+		<File
+			RelativePath=".\ReadMe.txt"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

+ 149 - 0
短信猫/sms/sms/sms.vcxproj

@@ -0,0 +1,149 @@
+<?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>{00431A09-2ADE-45D9-BF19-4AC06027B710}</ProjectGuid>
+    <RootNamespace>sms</RootNamespace>
+    <Keyword>MFCDLLProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v141</PlatformToolset>
+    <UseOfMfc>Dynamic</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v141</PlatformToolset>
+    <UseOfMfc>Dynamic</UseOfMfc>
+    <CharacterSet>MultiByte</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.27130.2010</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir>$(Configuration)\</IntDir>
+    <LinkIncremental>true</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>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;%(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>
+      <ModuleDefinitionFile>.\sms.def</ModuleDefinitionFile>
+      <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>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <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>
+      <ModuleDefinitionFile>.\sms.def</ModuleDefinitionFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="AsynSerial.cpp" />
+    <ClCompile Include="CommRS232.cpp" />
+    <ClCompile Include="CompletionSerial.cpp" />
+    <ClCompile Include="ShortMessageService.cpp" />
+    <ClCompile Include="sms.cpp" />
+    <ClCompile Include="SMSProcess.cpp" />
+    <ClCompile Include="stdafx.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="SynSerial.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="res\sms.rc2" />
+    <None Include="sms.def" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="AsynSerial.h" />
+    <ClInclude Include="CommRS232.h" />
+    <ClInclude Include="CompletionSerial.h" />
+    <ClInclude Include="Resource.h" />
+    <ClInclude Include="ShortMessageService.h" />
+    <ClInclude Include="sms.h" />
+    <ClInclude Include="SMSProcess.h" />
+    <ClInclude Include="stdafx.h" />
+    <ClInclude Include="SynSerial.h" />
+    <ClInclude Include="targetver.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="sms.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="ReadMe.txt" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 94 - 0
短信猫/sms/sms/sms.vcxproj.filters

@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="源文件">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="头文件">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="资源文件">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
+    </Filter>
+    <Filter Include="串口">
+      <UniqueIdentifier>{b29d3ca6-ae2e-4ba3-a4d4-59122c736963}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="CommRS232.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="sms.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="SMSProcess.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="stdafx.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="AsynSerial.cpp">
+      <Filter>串口</Filter>
+    </ClCompile>
+    <ClCompile Include="CompletionSerial.cpp">
+      <Filter>串口</Filter>
+    </ClCompile>
+    <ClCompile Include="SynSerial.cpp">
+      <Filter>串口</Filter>
+    </ClCompile>
+    <ClCompile Include="ShortMessageService.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="sms.def">
+      <Filter>源文件</Filter>
+    </None>
+    <None Include="res\sms.rc2">
+      <Filter>资源文件</Filter>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="CommRS232.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="Resource.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="sms.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="SMSProcess.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="stdafx.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="targetver.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="AsynSerial.h">
+      <Filter>串口</Filter>
+    </ClInclude>
+    <ClInclude Include="CompletionSerial.h">
+      <Filter>串口</Filter>
+    </ClInclude>
+    <ClInclude Include="SynSerial.h">
+      <Filter>串口</Filter>
+    </ClInclude>
+    <ClInclude Include="ShortMessageService.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="sms.rc">
+      <Filter>资源文件</Filter>
+    </ResourceCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="ReadMe.txt" />
+  </ItemGroup>
+</Project>

+ 7 - 0
短信猫/sms/sms/stdafx.cpp

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

+ 39 - 0
短信猫/sms/sms/stdafx.h

@@ -0,0 +1,39 @@
+// stdafx.h : 标准系统包含文件的包含文件,
+// 或是经常使用但不常更改的
+// 特定于项目的包含文件
+
+#pragma once
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN            // 从 Windows 头中排除极少使用的资料
+#endif
+
+#include "targetver.h"
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // 某些 CString 构造函数将是显式的
+
+#include <afxwin.h>         // MFC 核心组件和标准组件
+#include <afxext.h>         // MFC 扩展
+
+#ifndef _AFX_NO_OLE_SUPPORT
+#include <afxole.h>         // MFC OLE 类
+#include <afxodlgs.h>       // MFC OLE 对话框类
+#include <afxdisp.h>        // MFC 自动化类
+#endif // _AFX_NO_OLE_SUPPORT
+
+#ifndef _AFX_NO_DB_SUPPORT
+#include <afxdb.h>                      // MFC ODBC 数据库类
+#endif // _AFX_NO_DB_SUPPORT
+
+#ifndef _AFX_NO_DAO_SUPPORT
+#include <afxdao.h>                     // MFC DAO 数据库类
+#endif // _AFX_NO_DAO_SUPPORT
+
+#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
+
+

+ 26 - 0
短信猫/sms/sms/targetver.h

@@ -0,0 +1,26 @@
+
+#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
+