原始导入
This commit is contained in:
commit
ce44e595ff
240
Plane.Sdk3.sln
Normal file
240
Plane.Sdk3.sln
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 14
|
||||||
|
VisualStudioVersion = 14.0.25420.1
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "PlaneGcsSdk_Shared", "PlaneGcsSdk_Shared\PlaneGcsSdk_Shared.shproj", "{2BE393DC-21A4-48B3-83FD-F21CBE8B038B}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlaneGcsSdk_UWP", "PlaneGcsSdk_UWP\PlaneGcsSdk_UWP.csproj", "{B0226F52-8D27-4C05-8C04-536E0BCC3B99}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlaneGcsSdk_Private_NET45", "PlaneGcsSdk_Private_NET45\PlaneGcsSdk_Private_NET45.csproj", "{2CE7006F-C1DF-4A15-9E68-A63A3255FE88}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlaneGcsSdk_Private_NET46", "PlaneGcsSdk_Private_NET46\PlaneGcsSdk_Private_NET46.csproj", "{0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlaneGcsSdk_NET46", "PlaneGcsSdk_NET46\PlaneGcsSdk_NET46.csproj", "{331C28E1-5BA3-42CE-8A4A-BC468E692FED}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlaneGcsSdk.Contract", "PlaneGcsSdk.Contract\PlaneGcsSdk.Contract.csproj", "{18ECD88E-5D74-43E8-8BC2-D28F6DB13A47}"
|
||||||
|
EndProject
|
||||||
|
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "PlaneGcsSdk.Contract_Shared", "PlaneGcsSdk.Contract_Shared\PlaneGcsSdk.Contract_Shared.shproj", "{695733D7-99FF-4707-8C89-474E949CADCB}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlaneGcsSdk.Contract_Private", "PlaneGcsSdk.Contract_Private\PlaneGcsSdk.Contract_Private.csproj", "{47141894-ECE3-48CA-8DCF-CA751BDA231E}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlaneGcsSdk.Contract.EhNetUWP", "PlaneGcsSdk.Contract.EhNetUWP\PlaneGcsSdk.Contract.EhNetUWP.csproj", "{D7D21B2B-6F73-4939-B720-FE51DA1C04C0}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlaneGcsSdk.Contract.DtuClient_UWP", "PlaneGcsSdk.Contract.DtuClient_UWP\PlaneGcsSdk.Contract.DtuClient_UWP.csproj", "{2079C6FC-8EBA-4BD8-A965-EC9FB473C314}"
|
||||||
|
EndProject
|
||||||
|
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "PlaneGcsSdk.Contract.DtuClient_Shared", "PlaneGcsSdk.Contract.DtuClient_Shared\PlaneGcsSdk.Contract.DtuClient_Shared.shproj", "{83D6BB5F-1643-4B9F-B3E4-D4D08CEA2733}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlaneGcsSdk.Contract.DtuClient_NET", "PlaneGcsSdk.Contract.DtuClient_NET\PlaneGcsSdk.Contract.DtuClient_NET.csproj", "{089FA525-1773-47A5-8A0A-832AB179E2D9}"
|
||||||
|
EndProject
|
||||||
|
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PLClass", "..\myPLClass\ClassLibrary2\PLClass.vbproj", "{92E63872-4938-4F0C-9FD8-BDFE3388EEB3}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Contract", "Contract", "{4617084D-65A3-4354-B97F-1DF9254AA183}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Implementation", "Implementation", "{CDCDFD04-CD05-4CAA-BBA4-6166A5119495}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Document", "Document", "{CD21427C-22BF-4D7C-86EF-23B1E594A7B7}"
|
||||||
|
ProjectSection(SolutionItems) = preProject
|
||||||
|
README_Private.md = README_Private.md
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||||
|
PlaneGcsSdk_Shared\PlaneGcsSdk_Shared.projitems*{0111eb6e-72e3-499c-a3ba-022f5bbc4caf}*SharedItemsImports = 4
|
||||||
|
PlaneGcsSdk.Contract.DtuClient_Shared\PlaneGcsSdk.Contract.DtuClient_Shared.projitems*{089fa525-1773-47a5-8a0a-832ab179e2d9}*SharedItemsImports = 4
|
||||||
|
PlaneGcsSdk.Contract_Shared\PlaneGcsSdk.Contract_Shared.projitems*{18ecd88e-5d74-43e8-8bc2-d28f6db13a47}*SharedItemsImports = 4
|
||||||
|
PlaneGcsSdk.Contract.DtuClient_Shared\PlaneGcsSdk.Contract.DtuClient_Shared.projitems*{2079c6fc-8eba-4bd8-a965-ec9fb473c314}*SharedItemsImports = 4
|
||||||
|
PlaneGcsSdk_Shared\PlaneGcsSdk_Shared.projitems*{2be393dc-21a4-48b3-83fd-f21cbe8b038b}*SharedItemsImports = 13
|
||||||
|
PlaneGcsSdk_Shared\PlaneGcsSdk_Shared.projitems*{2ce7006f-c1df-4a15-9e68-a63a3255fe88}*SharedItemsImports = 4
|
||||||
|
PlaneGcsSdk_Shared\PlaneGcsSdk_Shared.projitems*{331c28e1-5ba3-42ce-8a4a-bc468e692fed}*SharedItemsImports = 4
|
||||||
|
PlaneGcsSdk.Contract_Shared\PlaneGcsSdk.Contract_Shared.projitems*{47141894-ece3-48ca-8dcf-ca751bda231e}*SharedItemsImports = 4
|
||||||
|
PlaneGcsSdk.Contract_Shared\PlaneGcsSdk.Contract_Shared.projitems*{695733d7-99ff-4707-8c89-474e949cadcb}*SharedItemsImports = 13
|
||||||
|
PlaneGcsSdk.Contract.DtuClient_Shared\PlaneGcsSdk.Contract.DtuClient_Shared.projitems*{83d6bb5f-1643-4b9f-b3e4-d4d08cea2733}*SharedItemsImports = 13
|
||||||
|
PlaneGcsSdk_Shared\PlaneGcsSdk_Shared.projitems*{b0226f52-8d27-4c05-8c04-536e0bcc3b99}*SharedItemsImports = 4
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|ARM = Debug|ARM
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|ARM = Release|ARM
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{B0226F52-8D27-4C05-8C04-536E0BCC3B99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{B0226F52-8D27-4C05-8C04-536E0BCC3B99}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{B0226F52-8D27-4C05-8C04-536E0BCC3B99}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||||
|
{B0226F52-8D27-4C05-8C04-536E0BCC3B99}.Debug|ARM.Build.0 = Debug|ARM
|
||||||
|
{B0226F52-8D27-4C05-8C04-536E0BCC3B99}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{B0226F52-8D27-4C05-8C04-536E0BCC3B99}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{B0226F52-8D27-4C05-8C04-536E0BCC3B99}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{B0226F52-8D27-4C05-8C04-536E0BCC3B99}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{B0226F52-8D27-4C05-8C04-536E0BCC3B99}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{B0226F52-8D27-4C05-8C04-536E0BCC3B99}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{B0226F52-8D27-4C05-8C04-536E0BCC3B99}.Release|ARM.ActiveCfg = Release|ARM
|
||||||
|
{B0226F52-8D27-4C05-8C04-536E0BCC3B99}.Release|ARM.Build.0 = Release|ARM
|
||||||
|
{B0226F52-8D27-4C05-8C04-536E0BCC3B99}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{B0226F52-8D27-4C05-8C04-536E0BCC3B99}.Release|x64.Build.0 = Release|x64
|
||||||
|
{B0226F52-8D27-4C05-8C04-536E0BCC3B99}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{B0226F52-8D27-4C05-8C04-536E0BCC3B99}.Release|x86.Build.0 = Release|x86
|
||||||
|
{2CE7006F-C1DF-4A15-9E68-A63A3255FE88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{2CE7006F-C1DF-4A15-9E68-A63A3255FE88}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{2CE7006F-C1DF-4A15-9E68-A63A3255FE88}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||||
|
{2CE7006F-C1DF-4A15-9E68-A63A3255FE88}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||||
|
{2CE7006F-C1DF-4A15-9E68-A63A3255FE88}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{2CE7006F-C1DF-4A15-9E68-A63A3255FE88}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{2CE7006F-C1DF-4A15-9E68-A63A3255FE88}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{2CE7006F-C1DF-4A15-9E68-A63A3255FE88}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{2CE7006F-C1DF-4A15-9E68-A63A3255FE88}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{2CE7006F-C1DF-4A15-9E68-A63A3255FE88}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{2CE7006F-C1DF-4A15-9E68-A63A3255FE88}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||||
|
{2CE7006F-C1DF-4A15-9E68-A63A3255FE88}.Release|ARM.Build.0 = Release|Any CPU
|
||||||
|
{2CE7006F-C1DF-4A15-9E68-A63A3255FE88}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{2CE7006F-C1DF-4A15-9E68-A63A3255FE88}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{2CE7006F-C1DF-4A15-9E68-A63A3255FE88}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{2CE7006F-C1DF-4A15-9E68-A63A3255FE88}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||||
|
{0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||||
|
{0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||||
|
{0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Release|ARM.Build.0 = Release|Any CPU
|
||||||
|
{0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{331C28E1-5BA3-42CE-8A4A-BC468E692FED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{331C28E1-5BA3-42CE-8A4A-BC468E692FED}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{331C28E1-5BA3-42CE-8A4A-BC468E692FED}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||||
|
{331C28E1-5BA3-42CE-8A4A-BC468E692FED}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||||
|
{331C28E1-5BA3-42CE-8A4A-BC468E692FED}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{331C28E1-5BA3-42CE-8A4A-BC468E692FED}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{331C28E1-5BA3-42CE-8A4A-BC468E692FED}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{331C28E1-5BA3-42CE-8A4A-BC468E692FED}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{331C28E1-5BA3-42CE-8A4A-BC468E692FED}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{331C28E1-5BA3-42CE-8A4A-BC468E692FED}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{331C28E1-5BA3-42CE-8A4A-BC468E692FED}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||||
|
{331C28E1-5BA3-42CE-8A4A-BC468E692FED}.Release|ARM.Build.0 = Release|Any CPU
|
||||||
|
{331C28E1-5BA3-42CE-8A4A-BC468E692FED}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{331C28E1-5BA3-42CE-8A4A-BC468E692FED}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{331C28E1-5BA3-42CE-8A4A-BC468E692FED}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{331C28E1-5BA3-42CE-8A4A-BC468E692FED}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{18ECD88E-5D74-43E8-8BC2-D28F6DB13A47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{18ECD88E-5D74-43E8-8BC2-D28F6DB13A47}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{18ECD88E-5D74-43E8-8BC2-D28F6DB13A47}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||||
|
{18ECD88E-5D74-43E8-8BC2-D28F6DB13A47}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||||
|
{18ECD88E-5D74-43E8-8BC2-D28F6DB13A47}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{18ECD88E-5D74-43E8-8BC2-D28F6DB13A47}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{18ECD88E-5D74-43E8-8BC2-D28F6DB13A47}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{18ECD88E-5D74-43E8-8BC2-D28F6DB13A47}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{18ECD88E-5D74-43E8-8BC2-D28F6DB13A47}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{18ECD88E-5D74-43E8-8BC2-D28F6DB13A47}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{18ECD88E-5D74-43E8-8BC2-D28F6DB13A47}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||||
|
{18ECD88E-5D74-43E8-8BC2-D28F6DB13A47}.Release|ARM.Build.0 = Release|Any CPU
|
||||||
|
{18ECD88E-5D74-43E8-8BC2-D28F6DB13A47}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{18ECD88E-5D74-43E8-8BC2-D28F6DB13A47}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{18ECD88E-5D74-43E8-8BC2-D28F6DB13A47}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{18ECD88E-5D74-43E8-8BC2-D28F6DB13A47}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{47141894-ECE3-48CA-8DCF-CA751BDA231E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{47141894-ECE3-48CA-8DCF-CA751BDA231E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{47141894-ECE3-48CA-8DCF-CA751BDA231E}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||||
|
{47141894-ECE3-48CA-8DCF-CA751BDA231E}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||||
|
{47141894-ECE3-48CA-8DCF-CA751BDA231E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{47141894-ECE3-48CA-8DCF-CA751BDA231E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{47141894-ECE3-48CA-8DCF-CA751BDA231E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{47141894-ECE3-48CA-8DCF-CA751BDA231E}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{47141894-ECE3-48CA-8DCF-CA751BDA231E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{47141894-ECE3-48CA-8DCF-CA751BDA231E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{47141894-ECE3-48CA-8DCF-CA751BDA231E}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||||
|
{47141894-ECE3-48CA-8DCF-CA751BDA231E}.Release|ARM.Build.0 = Release|Any CPU
|
||||||
|
{47141894-ECE3-48CA-8DCF-CA751BDA231E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{47141894-ECE3-48CA-8DCF-CA751BDA231E}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{47141894-ECE3-48CA-8DCF-CA751BDA231E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{47141894-ECE3-48CA-8DCF-CA751BDA231E}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{D7D21B2B-6F73-4939-B720-FE51DA1C04C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{D7D21B2B-6F73-4939-B720-FE51DA1C04C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D7D21B2B-6F73-4939-B720-FE51DA1C04C0}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||||
|
{D7D21B2B-6F73-4939-B720-FE51DA1C04C0}.Debug|ARM.Build.0 = Debug|ARM
|
||||||
|
{D7D21B2B-6F73-4939-B720-FE51DA1C04C0}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{D7D21B2B-6F73-4939-B720-FE51DA1C04C0}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{D7D21B2B-6F73-4939-B720-FE51DA1C04C0}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{D7D21B2B-6F73-4939-B720-FE51DA1C04C0}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{D7D21B2B-6F73-4939-B720-FE51DA1C04C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D7D21B2B-6F73-4939-B720-FE51DA1C04C0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{D7D21B2B-6F73-4939-B720-FE51DA1C04C0}.Release|ARM.ActiveCfg = Release|ARM
|
||||||
|
{D7D21B2B-6F73-4939-B720-FE51DA1C04C0}.Release|ARM.Build.0 = Release|ARM
|
||||||
|
{D7D21B2B-6F73-4939-B720-FE51DA1C04C0}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{D7D21B2B-6F73-4939-B720-FE51DA1C04C0}.Release|x64.Build.0 = Release|x64
|
||||||
|
{D7D21B2B-6F73-4939-B720-FE51DA1C04C0}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{D7D21B2B-6F73-4939-B720-FE51DA1C04C0}.Release|x86.Build.0 = Release|x86
|
||||||
|
{2079C6FC-8EBA-4BD8-A965-EC9FB473C314}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{2079C6FC-8EBA-4BD8-A965-EC9FB473C314}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{2079C6FC-8EBA-4BD8-A965-EC9FB473C314}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||||
|
{2079C6FC-8EBA-4BD8-A965-EC9FB473C314}.Debug|ARM.Build.0 = Debug|ARM
|
||||||
|
{2079C6FC-8EBA-4BD8-A965-EC9FB473C314}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{2079C6FC-8EBA-4BD8-A965-EC9FB473C314}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{2079C6FC-8EBA-4BD8-A965-EC9FB473C314}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{2079C6FC-8EBA-4BD8-A965-EC9FB473C314}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{2079C6FC-8EBA-4BD8-A965-EC9FB473C314}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{2079C6FC-8EBA-4BD8-A965-EC9FB473C314}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{2079C6FC-8EBA-4BD8-A965-EC9FB473C314}.Release|ARM.ActiveCfg = Release|ARM
|
||||||
|
{2079C6FC-8EBA-4BD8-A965-EC9FB473C314}.Release|ARM.Build.0 = Release|ARM
|
||||||
|
{2079C6FC-8EBA-4BD8-A965-EC9FB473C314}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{2079C6FC-8EBA-4BD8-A965-EC9FB473C314}.Release|x64.Build.0 = Release|x64
|
||||||
|
{2079C6FC-8EBA-4BD8-A965-EC9FB473C314}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{2079C6FC-8EBA-4BD8-A965-EC9FB473C314}.Release|x86.Build.0 = Release|x86
|
||||||
|
{089FA525-1773-47A5-8A0A-832AB179E2D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{089FA525-1773-47A5-8A0A-832AB179E2D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{089FA525-1773-47A5-8A0A-832AB179E2D9}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||||
|
{089FA525-1773-47A5-8A0A-832AB179E2D9}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||||
|
{089FA525-1773-47A5-8A0A-832AB179E2D9}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{089FA525-1773-47A5-8A0A-832AB179E2D9}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{089FA525-1773-47A5-8A0A-832AB179E2D9}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{089FA525-1773-47A5-8A0A-832AB179E2D9}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{089FA525-1773-47A5-8A0A-832AB179E2D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{089FA525-1773-47A5-8A0A-832AB179E2D9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{089FA525-1773-47A5-8A0A-832AB179E2D9}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||||
|
{089FA525-1773-47A5-8A0A-832AB179E2D9}.Release|ARM.Build.0 = Release|Any CPU
|
||||||
|
{089FA525-1773-47A5-8A0A-832AB179E2D9}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{089FA525-1773-47A5-8A0A-832AB179E2D9}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{089FA525-1773-47A5-8A0A-832AB179E2D9}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{089FA525-1773-47A5-8A0A-832AB179E2D9}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{92E63872-4938-4F0C-9FD8-BDFE3388EEB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{92E63872-4938-4F0C-9FD8-BDFE3388EEB3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{92E63872-4938-4F0C-9FD8-BDFE3388EEB3}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||||
|
{92E63872-4938-4F0C-9FD8-BDFE3388EEB3}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||||
|
{92E63872-4938-4F0C-9FD8-BDFE3388EEB3}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{92E63872-4938-4F0C-9FD8-BDFE3388EEB3}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{92E63872-4938-4F0C-9FD8-BDFE3388EEB3}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{92E63872-4938-4F0C-9FD8-BDFE3388EEB3}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{92E63872-4938-4F0C-9FD8-BDFE3388EEB3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{92E63872-4938-4F0C-9FD8-BDFE3388EEB3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{92E63872-4938-4F0C-9FD8-BDFE3388EEB3}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||||
|
{92E63872-4938-4F0C-9FD8-BDFE3388EEB3}.Release|ARM.Build.0 = Release|Any CPU
|
||||||
|
{92E63872-4938-4F0C-9FD8-BDFE3388EEB3}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{92E63872-4938-4F0C-9FD8-BDFE3388EEB3}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{92E63872-4938-4F0C-9FD8-BDFE3388EEB3}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{92E63872-4938-4F0C-9FD8-BDFE3388EEB3}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(NestedProjects) = preSolution
|
||||||
|
{2BE393DC-21A4-48B3-83FD-F21CBE8B038B} = {CDCDFD04-CD05-4CAA-BBA4-6166A5119495}
|
||||||
|
{B0226F52-8D27-4C05-8C04-536E0BCC3B99} = {CDCDFD04-CD05-4CAA-BBA4-6166A5119495}
|
||||||
|
{2CE7006F-C1DF-4A15-9E68-A63A3255FE88} = {CDCDFD04-CD05-4CAA-BBA4-6166A5119495}
|
||||||
|
{0111EB6E-72E3-499C-A3BA-022F5BBC4CAF} = {CDCDFD04-CD05-4CAA-BBA4-6166A5119495}
|
||||||
|
{331C28E1-5BA3-42CE-8A4A-BC468E692FED} = {CDCDFD04-CD05-4CAA-BBA4-6166A5119495}
|
||||||
|
{18ECD88E-5D74-43E8-8BC2-D28F6DB13A47} = {4617084D-65A3-4354-B97F-1DF9254AA183}
|
||||||
|
{695733D7-99FF-4707-8C89-474E949CADCB} = {4617084D-65A3-4354-B97F-1DF9254AA183}
|
||||||
|
{47141894-ECE3-48CA-8DCF-CA751BDA231E} = {4617084D-65A3-4354-B97F-1DF9254AA183}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
75
PlaneGcsSdk.Contract.DtuClient_NET/EhNetLoginMgr_Net.cs
Normal file
75
PlaneGcsSdk.Contract.DtuClient_NET/EhNetLoginMgr_Net.cs
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
using PLClass;
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PlaneGcsSdk.Contract.DtuClient
|
||||||
|
{
|
||||||
|
partial class EhNetLoginMgr
|
||||||
|
{
|
||||||
|
#region Fileds
|
||||||
|
private PLNet _PLNet;
|
||||||
|
private PLNet.LoginState _loginState;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Private Methods
|
||||||
|
private void InstanceEhNetObject()
|
||||||
|
{
|
||||||
|
_PLNet = new PLNet(AsyncOperationManager.CreateOperation(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task EhNetStart(string ehNetServerIp, string username, string pwd)
|
||||||
|
{
|
||||||
|
_PLNet.Start(ehNetServerIp, username, pwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CheckIfLogined()
|
||||||
|
{
|
||||||
|
return _loginState == PLNet.LoginState.LoginOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetLoginStatus()
|
||||||
|
{
|
||||||
|
_loginState = PLNet.LoginState.LoginNoUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SendCommandToDtuServer(string msg)
|
||||||
|
{
|
||||||
|
_PLNet.SendCommand(DtuServerUsername, msg);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Event Handlers
|
||||||
|
private void _ehNet_Login(PLNet.LoginState loginState)
|
||||||
|
{
|
||||||
|
_loginState = loginState;
|
||||||
|
if (_loginState == PLNet.LoginState.LoginOk)
|
||||||
|
{
|
||||||
|
NickName = _PLNet.MyNick;
|
||||||
|
_loginEnNet.Set();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//private void _ehNet_ExceptionThrown(object sender, PLNet.UWP.ExceptionThrownEventArgs e)
|
||||||
|
//{
|
||||||
|
// RaiseExceptionThrown(e.Exception);
|
||||||
|
//}
|
||||||
|
|
||||||
|
private void _ehNet_DiscoveredOneUser(PLNet.UserProperty userProperty)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _ehNet_Disconnect(PLNet e)
|
||||||
|
{
|
||||||
|
_loginState = PLNet.LoginState.LoginOtherError;
|
||||||
|
NickName = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _ehNet_CommandArrival(string friendID, string msg)
|
||||||
|
{
|
||||||
|
AcceptProtocolCommand(friendID, msg);
|
||||||
|
Console.WriteLine(msg);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{089FA525-1773-47A5-8A0A-832AB179E2D9}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>PlaneGcsSdk.Contract.DtuClient_NET</RootNamespace>
|
||||||
|
<AssemblyName>PlaneGcsSdk.Contract.DtuClient_NET</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="EhNetLoginMgr_Net.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\myPLClass\ClassLibrary2\PLClass.vbproj">
|
||||||
|
<Project>{92e63872-4938-4f0c-9fd8-bdfe3388eeb3}</Project>
|
||||||
|
<Name>PLClass</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\PlaneGcsSdk.Contract\PlaneGcsSdk.Contract.csproj">
|
||||||
|
<Project>{18ecd88e-5d74-43e8-8bc2-d28f6db13a47}</Project>
|
||||||
|
<Name>PlaneGcsSdk.Contract</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\PlaneGcsSdk.Contract_Private\PlaneGcsSdk.Contract_Private.csproj">
|
||||||
|
<Project>{47141894-ece3-48ca-8dcf-ca751bda231e}</Project>
|
||||||
|
<Name>PlaneGcsSdk.Contract_Private</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\PlaneGcsSdk_Private_NET45\PlaneGcsSdk_Private_NET45.csproj">
|
||||||
|
<Project>{2ce7006f-c1df-4a15-9e68-a63a3255fe88}</Project>
|
||||||
|
<Name>PlaneGcsSdk_Private_NET45</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="..\PlaneGcsSdk.Contract.DtuClient_Shared\PlaneGcsSdk.Contract.DtuClient_Shared.projitems" Label="Shared" />
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// 有关程序集的一般信息由以下
|
||||||
|
// 控制。更改这些特性值可修改
|
||||||
|
// 与程序集关联的信息。
|
||||||
|
[assembly: AssemblyTitle("PlaneGcsSdk.Contract.DtuClient_NET")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("PlaneGcsSdk.Contract.DtuClient_NET")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
//将 ComVisible 设置为 false 将使此程序集中的类型
|
||||||
|
//对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
|
||||||
|
//请将此类型的 ComVisible 特性设置为 true。
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||||
|
[assembly: Guid("089fa525-1773-47a5-8a0a-832ab179e2d9")]
|
||||||
|
|
||||||
|
// 程序集的版本信息由下列四个值组成:
|
||||||
|
//
|
||||||
|
// 主版本
|
||||||
|
// 次版本
|
||||||
|
// 生成号
|
||||||
|
// 修订号
|
||||||
|
//
|
||||||
|
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
|
||||||
|
// 方法是按如下所示使用“*”: :
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
@ -0,0 +1,71 @@
|
|||||||
|
using Plane.Communication;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PlaneGcsSdk.Contract.DtuClient
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 基于PLNet的用户登录体系的Udp连接实体类。
|
||||||
|
/// <para>具体登陆流程:1,利用用户名和密码登陆PLNet,获取随机码;2,利用随机码登陆Dtu透传服务器;</para>
|
||||||
|
/// </summary>
|
||||||
|
public partial class BasedOnEhNetUdpDtuServiceConnection : UdpThroughDtuServiceConnection
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
public int _randCode;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 基于PLNet的用户登录体系的Udp连接实体类。
|
||||||
|
/// <para>具体登陆流程:1,利用用户名和密码登陆PLNet,获取随机码;2,利用随机码登陆Dtu透传服务器;</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dtuServiceIp"></param>
|
||||||
|
/// <param name="dtuServicePort"></param>
|
||||||
|
/// <param name="randCode">用户随机数</param>
|
||||||
|
public BasedOnEhNetUdpDtuServiceConnection(string dtuServiceIp, int dtuServicePort, int randCode)
|
||||||
|
: base(dtuServiceIp, dtuServicePort)
|
||||||
|
{
|
||||||
|
FLAG_DTU_HANDSHAKE_HEAD = "ehnetrnd";
|
||||||
|
_randCode = randCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override byte[] ConstructHandShakeDatagramToDTUService()
|
||||||
|
{
|
||||||
|
return Encoding.ASCII.GetBytes($"{FLAG_DTU_HANDSHAKE_HEAD}{_randCode}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分析由DTU服务端返回的握手包
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="buffer"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected override DTUHandShakeResult AnalyzeHandShakeDatagramFromDTUService(byte[] buffer)
|
||||||
|
{
|
||||||
|
var strResult = Encoding.ASCII.GetString(buffer);//返回的格式为“ehnetrndxxxx”
|
||||||
|
if (strResult.StartsWith(FLAG_DTU_HANDSHAKE_HEAD))
|
||||||
|
{
|
||||||
|
return DTUHandShakeResult.Successful;
|
||||||
|
}
|
||||||
|
return DTUHandShakeResult.Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<int> ReadAsync(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
var iRet = await base.ReadAsync(buffer, offset, count);
|
||||||
|
//解密数据
|
||||||
|
buffer.DecryptByKey((byte)(_randCode % byte.MaxValue), offset, count);
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Task WriteAsync(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
//加密数据
|
||||||
|
buffer.EncryptByKey((byte)(_randCode % byte.MaxValue), offset, count);
|
||||||
|
var iRet = base.WriteAsync(buffer, offset, count);
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
#if !NETFX_CORE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace EHangGcsSdk.Contract.DtuClient
|
||||||
|
{
|
||||||
|
public partial class BasedOnEhNetUdpDtuServiceConnection
|
||||||
|
{
|
||||||
|
private TcpClient _tcpClient;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 登陆到EhNet,获取随机码后再登陆Dtu透传服务端。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override async Task OpenAsync()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Close()
|
||||||
|
{
|
||||||
|
_tcpClient.Close();
|
||||||
|
base.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
11
PlaneGcsSdk.Contract.DtuClient_Shared/CopterEntity.cs
Normal file
11
PlaneGcsSdk.Contract.DtuClient_Shared/CopterEntity.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace PlaneGcsSdk.Contract.DtuClient
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 表示飞机实体类
|
||||||
|
/// </summary>
|
||||||
|
public class CopterEntity
|
||||||
|
{
|
||||||
|
public string ID { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
}
|
68
PlaneGcsSdk.Contract.DtuClient_Shared/DataEncryptHelper.cs
Normal file
68
PlaneGcsSdk.Contract.DtuClient_Shared/DataEncryptHelper.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
namespace PlaneGcsSdk.Contract.DtuClient
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 进行数据透传时利用随机码对MavLink数据包进行加密和解密的辅助类。
|
||||||
|
/// </summary>
|
||||||
|
public static class DataEncryptHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 对数据进行加密处理。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
/// <param name="key">密钥</param>
|
||||||
|
/// <param name="offset"></param>
|
||||||
|
/// <param name="size"></param>
|
||||||
|
public static void EncryptByKey(this byte[] data, byte key, int offset = 0, int size = -1)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
if (size == -1)
|
||||||
|
{
|
||||||
|
count = data.Length - offset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
count = size + offset;
|
||||||
|
}
|
||||||
|
for (var i = offset; i < count; i++)
|
||||||
|
{
|
||||||
|
//下面算法实现高低位调转
|
||||||
|
var ch = data[i];
|
||||||
|
ch >>= 4;
|
||||||
|
data[i] <<= 4;
|
||||||
|
data[i] |= ch;
|
||||||
|
|
||||||
|
//根据Key进行异或处理
|
||||||
|
//data[i] ^= key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 对数据进行解密处理。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
public static void DecryptByKey(this byte[] data, byte key, int offset = 0, int size = -1)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
if (size == -1)
|
||||||
|
{
|
||||||
|
count = data.Length - offset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
count = size + offset;
|
||||||
|
}
|
||||||
|
for (var i = offset; i < count; i++)
|
||||||
|
{
|
||||||
|
//根据Key进行异或处理
|
||||||
|
//data[i] ^= key;
|
||||||
|
|
||||||
|
//下面算法实现高低位调转
|
||||||
|
var ch = data[i];
|
||||||
|
ch >>= 4;
|
||||||
|
data[i] <<= 4;
|
||||||
|
data[i] |= ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
278
PlaneGcsSdk.Contract.DtuClient_Shared/EhNetLoginMgr.cs
Normal file
278
PlaneGcsSdk.Contract.DtuClient_Shared/EhNetLoginMgr.cs
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PlaneGcsSdk.Contract.DtuClient
|
||||||
|
{
|
||||||
|
public partial class EhNetLoginMgr
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
private AutoResetEvent _loginEnNet;
|
||||||
|
private AutoResetEvent _sendRndCodeSignal;
|
||||||
|
private AutoResetEvent _sendBindCopterIDSignal;
|
||||||
|
private AutoResetEvent _sendUpdHandshakeSignal;
|
||||||
|
private AutoResetEvent _requestCopterListSignal;
|
||||||
|
private const string Protocol_SendRandCode = "J001"; //表示向服务器请求“发送随机码”的协议号
|
||||||
|
private const string Protocol_SendRandCode_Reply = "J002"; //表示服务端返回“请求发送随机码”的应答协议号
|
||||||
|
private const string Protocol_BindCopterID = "J003"; //表示向服务器请求“绑定飞机”的协议号
|
||||||
|
private const string Protocol_BindCopterID_Reply = "J004"; //表示服务端返回“请求绑定飞机”的应答协议号
|
||||||
|
private const string Protocol_RequestCopterList = "J007"; //表示向服务器请求“飞机列表”的请求协议号
|
||||||
|
private const string Protocol_ReceivedCopterItem = "J008"; //表示服务端返回“飞机列表中的一个飞机”的推送协议号
|
||||||
|
private const string Protocol_RecievedCopterInvailed = "J206";//表示由服务端通告“您所绑定的飞机已无效”的推送协议好
|
||||||
|
|
||||||
|
private string _errorCode; //请求过程由服务端返回的错误码的缓存变量
|
||||||
|
private string _errorCodeForRequestCopterList; //专为缓存“请求飞机列表”结果的错误号变量
|
||||||
|
private const string ErrorCode_Succeed = "0000"; //表示执行成功的错误码
|
||||||
|
private const string ErrorCode_EndCopterList = "0003"; //表示服务端返回“飞机列表完毕”的协议号
|
||||||
|
private CopterEntity _nextCopter; //当前请求的飞机实体
|
||||||
|
private string _usersname; //当前登录的账号
|
||||||
|
private const string DtuServerUsername = "10000"; // 在PLNet登陆体系里Dtu服务端的用户名
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
/// <summary>
|
||||||
|
/// 在PLNet登陆体系里的用户别名
|
||||||
|
/// </summary>
|
||||||
|
public string NickName { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// PLNet服务端的IP
|
||||||
|
/// </summary>
|
||||||
|
public string ServerIp { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// PLNet服务端的监听端口
|
||||||
|
/// </summary>
|
||||||
|
public int ServerPort { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 表示当前所处的PLNet-Dtu连接状态(比如已登录PLNet,但没有建立Dtu透传管道)
|
||||||
|
/// </summary>
|
||||||
|
public ProcessStep ProcessSetp { get; protected set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 登陆后获得的随机码
|
||||||
|
/// </summary>
|
||||||
|
public int RandCode { get; protected set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 用于建立透传管道的Udp端口。
|
||||||
|
/// </summary>
|
||||||
|
public const int DTU_USER_PORT = 5250;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前已绑定的飞机变为无效状态的事件
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler CopterLost;
|
||||||
|
|
||||||
|
public EhNetLoginMgr()
|
||||||
|
{
|
||||||
|
_loginEnNet = new AutoResetEvent(false);
|
||||||
|
_sendBindCopterIDSignal = new AutoResetEvent(false);
|
||||||
|
_sendRndCodeSignal = new AutoResetEvent(false);
|
||||||
|
_sendUpdHandshakeSignal = new AutoResetEvent(false);
|
||||||
|
_requestCopterListSignal = new AutoResetEvent(false);
|
||||||
|
|
||||||
|
InstanceEhNetObject();
|
||||||
|
_PLNet.CommandArrival += _ehNet_CommandArrival;
|
||||||
|
_PLNet.Disconnect += _ehNet_Disconnect;
|
||||||
|
_PLNet.DiscoveredOneUser += _ehNet_DiscoveredOneUser;
|
||||||
|
//_ehNet.ExceptionThrown += _ehNet_ExceptionThrown;
|
||||||
|
_PLNet.Login += _ehNet_Login;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_PLNet.CommandArrival -= _ehNet_CommandArrival;
|
||||||
|
_PLNet.Disconnect -= _ehNet_Disconnect;
|
||||||
|
_PLNet.DiscoveredOneUser -= _ehNet_DiscoveredOneUser;
|
||||||
|
//_ehNet.ExceptionThrown -= _ehNet_ExceptionThrown;
|
||||||
|
_PLNet.Login -= _ehNet_Login;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Public Methods
|
||||||
|
/// <summary>
|
||||||
|
/// 登陆到PLNet网络(第三个参数决定是否在登陆成功后发起获取飞机列表的请求)。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="username"></param>
|
||||||
|
/// <param name="pwd"></param>
|
||||||
|
/// <param name="gotCopterCallBack">获得得到的飞机事件</param>
|
||||||
|
public async Task Login(string username, string pwd, string ehNetServerIp,
|
||||||
|
Action<CopterEntity> gotCopterCallBack = null)
|
||||||
|
{
|
||||||
|
if (CheckIfLogined())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_usersname = username;
|
||||||
|
await Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await EhNetStart(ehNetServerIp, username, pwd);
|
||||||
|
if (!_loginEnNet.WaitOne(TimeSpan.FromSeconds(10)))
|
||||||
|
{
|
||||||
|
throw new Exception("登陆无响应失败!");
|
||||||
|
}
|
||||||
|
ProcessSetp = ProcessStep.EhNetLogin;
|
||||||
|
if (!string.IsNullOrEmpty(_PLNet.MyRND))
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
int.TryParse(_PLNet.MyRND, out value);
|
||||||
|
RandCode = value;
|
||||||
|
//发送随机码到Dtu服务端
|
||||||
|
await SendCommandToDtuServer($"{Protocol_SendRandCode};{username};{_PLNet.MyRND}");
|
||||||
|
if (!_sendRndCodeSignal.WaitOne(TimeSpan.FromSeconds(10)))
|
||||||
|
{
|
||||||
|
throw new Exception("发送随机码超时!");
|
||||||
|
}
|
||||||
|
else if (_errorCode != ErrorCode_Succeed)
|
||||||
|
{
|
||||||
|
throw new Exception("发送随机码失败:" + _errorCode);
|
||||||
|
}
|
||||||
|
ProcessSetp = ProcessStep.SendRandCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gotCopterCallBack != null)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
await SendCommandToDtuServer($"{Protocol_RequestCopterList};{username};{index}");
|
||||||
|
if (_requestCopterListSignal.WaitOne(TimeSpan.FromSeconds(10)))
|
||||||
|
{
|
||||||
|
if (_errorCodeForRequestCopterList == ErrorCode_Succeed)
|
||||||
|
{
|
||||||
|
if (_nextCopter != null)
|
||||||
|
{
|
||||||
|
gotCopterCallBack.Invoke(_nextCopter);
|
||||||
|
}
|
||||||
|
//加1后继续请求
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
else if (_errorCodeForRequestCopterList == ErrorCode_EndCopterList)
|
||||||
|
{
|
||||||
|
//正常结束请求
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception($"请求获取飞机列表错误:{_errorCode}!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception("请求获取飞机列表超时!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 退出PLNet网络
|
||||||
|
/// </summary>
|
||||||
|
public void Logout()
|
||||||
|
{
|
||||||
|
_PLNet.Close();
|
||||||
|
ResetLoginStatus();
|
||||||
|
ProcessSetp = ProcessStep.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取飞机列表
|
||||||
|
/// </summary>
|
||||||
|
public async Task GetCopterList(Action<CopterEntity> gotCopterCallBack)
|
||||||
|
{
|
||||||
|
await Task.Run(async () =>
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
await SendCommandToDtuServer($"{Protocol_RequestCopterList};{_usersname};{index}");
|
||||||
|
if (_requestCopterListSignal.WaitOne(TimeSpan.FromSeconds(10)))
|
||||||
|
{
|
||||||
|
if (_errorCodeForRequestCopterList == ErrorCode_Succeed)
|
||||||
|
{
|
||||||
|
if (_nextCopter != null)
|
||||||
|
{
|
||||||
|
gotCopterCallBack.Invoke(_nextCopter);
|
||||||
|
}
|
||||||
|
//加1后继续请求
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
else if (_errorCodeForRequestCopterList == ErrorCode_EndCopterList)
|
||||||
|
{
|
||||||
|
//正常结束请求
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//throw new Exception($"请求获取飞机列表错误:{_errorCode}!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//throw new Exception("请求获取飞机列表超时!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 申请绑定飞机
|
||||||
|
/// </summary>
|
||||||
|
public async Task AssignBindingCopter(string copterID)
|
||||||
|
{
|
||||||
|
//向Dtu服务端申请绑定飞机
|
||||||
|
await SendCommandToDtuServer($"{Protocol_BindCopterID};{_usersname};{copterID}");
|
||||||
|
if (!_sendBindCopterIDSignal.WaitOne(TimeSpan.FromSeconds(10)))
|
||||||
|
{
|
||||||
|
throw new Exception("申请绑定超时!");
|
||||||
|
}
|
||||||
|
else if (_errorCode != ErrorCode_Succeed)
|
||||||
|
{
|
||||||
|
throw new Exception("申请绑定失败:" + _errorCode);
|
||||||
|
}
|
||||||
|
ProcessSetp = ProcessStep.AssignCopter;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Private Methods
|
||||||
|
private void AcceptProtocolCommand(string userIDFrom, string msg)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(msg) && userIDFrom == DtuServerUsername)
|
||||||
|
{
|
||||||
|
var strList = msg.Split(';');
|
||||||
|
if (strList.Length >= 3)
|
||||||
|
{
|
||||||
|
switch (strList[0])
|
||||||
|
{
|
||||||
|
case Protocol_SendRandCode_Reply:
|
||||||
|
_errorCode = strList[2];
|
||||||
|
_sendRndCodeSignal.Set();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Protocol_BindCopterID_Reply:
|
||||||
|
_errorCode = strList[2];
|
||||||
|
_sendBindCopterIDSignal.Set();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Protocol_ReceivedCopterItem:
|
||||||
|
_errorCodeForRequestCopterList = strList[2];
|
||||||
|
if (strList.Length >= 5)
|
||||||
|
{
|
||||||
|
_nextCopter = new CopterEntity { ID = strList[3], Name = strList[4] };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_nextCopter = null;
|
||||||
|
}
|
||||||
|
_requestCopterListSignal.Set();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Protocol_RecievedCopterInvailed:
|
||||||
|
CopterLost?.Invoke(this, EventArgs.Empty);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||||
|
<HasSharedItems>true</HasSharedItems>
|
||||||
|
<SharedGUID>83d6bb5f-1643-4b9f-b3e4-d4d08cea2733</SharedGUID>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Label="Configuration">
|
||||||
|
<Import_RootNamespace>EHangGcsSdk.Contract.DtuClient_Shared</Import_RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)BasedOnEhNetUdpDtuServiceConnection.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)CopterEntity.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)DataEncryptHelper.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)EhNetLoginMgr.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)ProcessStep.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>83d6bb5f-1643-4b9f-b3e4-d4d08cea2733</ProjectGuid>
|
||||||
|
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
|
||||||
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
|
||||||
|
<PropertyGroup />
|
||||||
|
<Import Project="PlaneGcsSdk.Contract.DtuClient_Shared.projitems" Label="Shared" />
|
||||||
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
|
||||||
|
</Project>
|
29
PlaneGcsSdk.Contract.DtuClient_Shared/ProcessStep.cs
Normal file
29
PlaneGcsSdk.Contract.DtuClient_Shared/ProcessStep.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
namespace PlaneGcsSdk.Contract.DtuClient
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 与DTU服务端建立通信的流程枚举
|
||||||
|
/// </summary>
|
||||||
|
public enum ProcessStep
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 默认值
|
||||||
|
/// </summary>
|
||||||
|
None,
|
||||||
|
/// <summary>
|
||||||
|
/// 【第一步】已登陆PLNet服务端
|
||||||
|
/// </summary>
|
||||||
|
EhNetLogin,
|
||||||
|
/// <summary>
|
||||||
|
/// 【第二步】已发送登陆随机码到DTU服务端
|
||||||
|
/// </summary>
|
||||||
|
SendRandCode,
|
||||||
|
/// <summary>
|
||||||
|
/// 【第三步】已向DTU服务端绑定飞机
|
||||||
|
/// </summary>
|
||||||
|
AssignCopter,
|
||||||
|
/// <summary>
|
||||||
|
/// 【第四步】已向DTU建立飞控透传管道
|
||||||
|
/// </summary>
|
||||||
|
HandShakeToDTU,
|
||||||
|
}
|
||||||
|
}
|
75
PlaneGcsSdk.Contract.DtuClient_UWP/EhNetLoginMgr_UWP.cs
Normal file
75
PlaneGcsSdk.Contract.DtuClient_UWP/EhNetLoginMgr_UWP.cs
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
using PlaneGcsSdk.Contract.EhNetUWP;
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PlaneGcsSdk.Contract.DtuClient
|
||||||
|
{
|
||||||
|
partial class EhNetLoginMgr
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
private PLNet _PLNet;
|
||||||
|
private LoginState _loginState;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Private Methods
|
||||||
|
private void InstanceEhNetObject()
|
||||||
|
{
|
||||||
|
_PLNet = new PLNet();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task EhNetStart(string ehNetServerIp, string username, string pwd)
|
||||||
|
{
|
||||||
|
await _PLNet.Start(ehNetServerIp, username, pwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CheckIfLogined()
|
||||||
|
{
|
||||||
|
return _loginState == LoginState.LoginOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetLoginStatus()
|
||||||
|
{
|
||||||
|
_loginState = LoginState.LoginNoUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SendCommandToDtuServer(string msg)
|
||||||
|
{
|
||||||
|
await _PLNet.SendCommand(DtuServerUsername, msg);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Event Handlers
|
||||||
|
private void _ehNet_Login(object sender, LoginEventArgs e)
|
||||||
|
{
|
||||||
|
_loginState = e.LoginState;
|
||||||
|
if (_loginState == LoginState.LoginOk)
|
||||||
|
{
|
||||||
|
NickName = _PLNet.MyNick;
|
||||||
|
_loginEnNet.Set();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//private void _ehNet_ExceptionThrown(object sender, PLNet.UWP.ExceptionThrownEventArgs e)
|
||||||
|
//{
|
||||||
|
// RaiseExceptionThrown(e.Exception);
|
||||||
|
//}
|
||||||
|
|
||||||
|
private void _ehNet_DiscoveredOneUser(object sender, DiscoveredOneUserEventArgs e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _ehNet_Disconnect(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
_loginState = LoginState.LoginOtherError;
|
||||||
|
NickName = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _ehNet_CommandArrival(object sender, CommandArrivalEventArgs e)
|
||||||
|
{
|
||||||
|
AcceptProtocolCommand(e.FriendID, e.CmdMessage);
|
||||||
|
Debug.WriteLine(e.CmdMessage);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,141 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{2079C6FC-8EBA-4BD8-A965-EC9FB473C314}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>PlaneGcsSdk.Contract.DtuClient</RootNamespace>
|
||||||
|
<AssemblyName>PlaneGcsSdk.Contract.DtuClient</AssemblyName>
|
||||||
|
<DefaultLanguage>zh-CN</DefaultLanguage>
|
||||||
|
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||||
|
<TargetPlatformVersion>10.0.10586.0</TargetPlatformVersion>
|
||||||
|
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
|
||||||
|
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
|
||||||
|
<PlatformTarget>ARM</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\ARM\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>ARM</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
|
||||||
|
<PlatformTarget>ARM</PlatformTarget>
|
||||||
|
<OutputPath>bin\ARM\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>ARM</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<OutputPath>bin\x64\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<OutputPath>bin\x86\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<!-- A reference to the entire .Net Framework and Windows SDK are automatically included -->
|
||||||
|
<None Include="project.json" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="EhNetLoginMgr_UWP.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Content Include="Properties\PlaneGcsSdk.Contract.DtuClient.rd.xml" />
|
||||||
|
<Content Include="Readme.txt" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\PlaneGcsSdk.Contract.EhNetUWP\PlaneGcsSdk.Contract.EhNetUWP.csproj">
|
||||||
|
<Project>{d7d21b2b-6f73-4939-b720-fe51da1c04c0}</Project>
|
||||||
|
<Name>PlaneGcsSdk.Contract.EhNetUWP</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\PlaneGcsSdk.Contract\PlaneGcsSdk.Contract.csproj">
|
||||||
|
<Project>{18ecd88e-5d74-43e8-8bc2-d28f6db13a47}</Project>
|
||||||
|
<Name>PlaneGcsSdk.Contract</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\PlaneGcsSdk_UWP\PlaneGcsSdk_UWP.csproj">
|
||||||
|
<Project>{b0226f52-8d27-4c05-8c04-536e0bcc3b99}</Project>
|
||||||
|
<Name>PlaneGcsSdk_UWP</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="..\PlaneGcsSdk.Contract.DtuClient_Shared\PlaneGcsSdk.Contract.DtuClient_Shared.projitems" Label="Shared" />
|
||||||
|
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||||
|
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
@ -0,0 +1,29 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("PlaneGcsSdk.Contract.DtuClient")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("PlaneGcsSdk.Contract.DtuClient")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
|
[assembly: ComVisible(false)]
|
@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
This file contains Runtime Directives, specifications about types your application accesses
|
||||||
|
through reflection and other dynamic code patterns. Runtime Directives are used to control the
|
||||||
|
.NET Native optimizer and ensure that it does not remove code accessed by your library. If your
|
||||||
|
library does not do any reflection, then you generally do not need to edit this file. However,
|
||||||
|
if your library reflects over types, especially types passed to it or derived from its types,
|
||||||
|
then you should write Runtime Directives.
|
||||||
|
|
||||||
|
The most common use of reflection in libraries is to discover information about types passed
|
||||||
|
to the library. Runtime Directives have three ways to express requirements on types passed to
|
||||||
|
your library.
|
||||||
|
|
||||||
|
1. Parameter, GenericParameter, TypeParameter, TypeEnumerableParameter
|
||||||
|
Use these directives to reflect over types passed as a parameter.
|
||||||
|
|
||||||
|
2. SubTypes
|
||||||
|
Use a SubTypes directive to reflect over types derived from another type.
|
||||||
|
|
||||||
|
3. AttributeImplies
|
||||||
|
Use an AttributeImplies directive to indicate that your library needs to reflect over
|
||||||
|
types or methods decorated with an attribute.
|
||||||
|
|
||||||
|
For more information on writing Runtime Directives for libraries, please visit
|
||||||
|
http://go.microsoft.com/fwlink/?LinkID=391919
|
||||||
|
-->
|
||||||
|
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
|
||||||
|
<Library Name="PlaneGcsSdk.Contract.DtuClient">
|
||||||
|
|
||||||
|
<!-- add directives for your library here -->
|
||||||
|
|
||||||
|
</Library>
|
||||||
|
</Directives>
|
2
PlaneGcsSdk.Contract.DtuClient_UWP/Readme.txt
Normal file
2
PlaneGcsSdk.Contract.DtuClient_UWP/Readme.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
本项目:
|
||||||
|
1,实现PLNet-Dtu的登陆逻辑的IConnection;
|
16
PlaneGcsSdk.Contract.DtuClient_UWP/project.json
Normal file
16
PlaneGcsSdk.Contract.DtuClient_UWP/project.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"uap10.0": {}
|
||||||
|
},
|
||||||
|
"runtimes": {
|
||||||
|
"win10-arm": {},
|
||||||
|
"win10-arm-aot": {},
|
||||||
|
"win10-x86": {},
|
||||||
|
"win10-x86-aot": {},
|
||||||
|
"win10-x64": {},
|
||||||
|
"win10-x64-aot": {}
|
||||||
|
}
|
||||||
|
}
|
33
PlaneGcsSdk.Contract.EhNetUWP/CommandArrivalEventArgs.cs
Normal file
33
PlaneGcsSdk.Contract.EhNetUWP/CommandArrivalEventArgs.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
namespace PlaneGcsSdk.Contract.EhNetUWP
|
||||||
|
{
|
||||||
|
public class CommandArrivalEventArgs
|
||||||
|
{
|
||||||
|
private string _friendid;
|
||||||
|
public string FriendID
|
||||||
|
{
|
||||||
|
get { return _friendid; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_friendid != value)
|
||||||
|
_friendid = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string _cmdmessage;
|
||||||
|
public string CmdMessage
|
||||||
|
{
|
||||||
|
get { return _cmdmessage; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_cmdmessage != value)
|
||||||
|
_cmdmessage = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandArrivalEventArgs(string fid,string msg)
|
||||||
|
{
|
||||||
|
FriendID = fid;
|
||||||
|
CmdMessage = msg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
285
PlaneGcsSdk.Contract.EhNetUWP/DBCSEncoding.cs
Normal file
285
PlaneGcsSdk.Contract.EhNetUWP/DBCSEncoding.cs
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PlaneGcsSdk.Contract.EhNetUWP
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 在UWP平台下支持GB2312、Big5编码的字符编码类。
|
||||||
|
/// </summary>
|
||||||
|
public sealed class DBCSEncoding : Encoding
|
||||||
|
{
|
||||||
|
private const char LEAD_BYTE_CHAR = '\uFFFE';
|
||||||
|
private char[] _dbcsToUnicode = null;
|
||||||
|
private ushort[] _unicodeToDbcs = null;
|
||||||
|
private string _webName = null;
|
||||||
|
private static Dictionary<string, Tuple<char[], ushort[]>> _cache = null;
|
||||||
|
|
||||||
|
static DBCSEncoding()
|
||||||
|
{
|
||||||
|
if (!BitConverter.IsLittleEndian)
|
||||||
|
throw new PlatformNotSupportedException("Not supported big endian platform.");
|
||||||
|
|
||||||
|
_cache = new Dictionary<string, Tuple<char[], ushort[]>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private DBCSEncoding() { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 支持GB2312和Big5编码
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">“gb2312”或“big5”</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async Task<DBCSEncoding> GetDBCSEncoding(string name)
|
||||||
|
{
|
||||||
|
name = name.ToLower();
|
||||||
|
DBCSEncoding encoding = new DBCSEncoding();
|
||||||
|
encoding._webName = name;
|
||||||
|
if (_cache.ContainsKey(name))
|
||||||
|
{
|
||||||
|
var tuple = _cache[name];
|
||||||
|
encoding._dbcsToUnicode = tuple.Item1;
|
||||||
|
encoding._unicodeToDbcs = tuple.Item2;
|
||||||
|
return encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
var dbcsToUnicode = new char[0x10000];
|
||||||
|
var unicodeToDbcs = new ushort[0x10000];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* According to many feedbacks, add this automatic function for finding resource in revision 1.0.0.1.
|
||||||
|
* We suggest that use the old method as below if you understand how to embed the resource.
|
||||||
|
* Please make sure the *.bin file was correctly embedded if throw an exception at here.
|
||||||
|
*/
|
||||||
|
//using (Stream stream = typeof(DBCSEncoding).Assembly.GetManifestResourceStream(typeof(DBCSEncoding).Namespace + "." + name + ".bin"))
|
||||||
|
//using (Stream stream = typeof(DBCSEncoding).Assembly.GetManifestResourceStream(typeof(DBCSEncoding).Assembly.GetManifestResourceNames().Single(s => s.EndsWith("." + name + ".bin"))))
|
||||||
|
using (Stream stream = await GetInstall(name))
|
||||||
|
using (BinaryReader reader = new BinaryReader(stream))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 0xffff; i++)
|
||||||
|
{
|
||||||
|
ushort u = reader.ReadUInt16();
|
||||||
|
unicodeToDbcs[i] = u;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 0xffff; i++)
|
||||||
|
{
|
||||||
|
ushort u = reader.ReadUInt16();
|
||||||
|
dbcsToUnicode[i] = (char)u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_cache[name] = new Tuple<char[], ushort[]>(dbcsToUnicode, unicodeToDbcs);
|
||||||
|
encoding._dbcsToUnicode = dbcsToUnicode;
|
||||||
|
encoding._unicodeToDbcs = unicodeToDbcs;
|
||||||
|
return encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetByteCount(char[] chars, int index, int count)
|
||||||
|
{
|
||||||
|
int byteCount = 0;
|
||||||
|
ushort u;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
for (int i = 0; i < count; index++, byteCount++, i++)
|
||||||
|
{
|
||||||
|
c = chars[index];
|
||||||
|
u = _unicodeToDbcs[c];
|
||||||
|
if (u > 0xff)
|
||||||
|
byteCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return byteCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
|
||||||
|
{
|
||||||
|
int byteCount = 0;
|
||||||
|
ushort u;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
for (int i = 0; i < charCount; charIndex++, byteIndex++, byteCount++, i++)
|
||||||
|
{
|
||||||
|
c = chars[charIndex];
|
||||||
|
u = _unicodeToDbcs[c];
|
||||||
|
if (u == 0 && c != 0)
|
||||||
|
{
|
||||||
|
bytes[byteIndex] = 0x3f; // 0x3f == '?'
|
||||||
|
}
|
||||||
|
else if (u < 0x100)
|
||||||
|
{
|
||||||
|
bytes[byteIndex] = (byte)u;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bytes[byteIndex] = (byte)((u >> 8) & 0xff);
|
||||||
|
byteIndex++;
|
||||||
|
byteCount++;
|
||||||
|
bytes[byteIndex] = (byte)(u & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return byteCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetCharCount(byte[] bytes, int index, int count)
|
||||||
|
{
|
||||||
|
return GetCharCount(bytes, index, count, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
|
||||||
|
{
|
||||||
|
return GetChars(bytes, byteIndex, byteCount, chars, charIndex, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetMaxByteCount(int charCount)
|
||||||
|
{
|
||||||
|
if (charCount < 0)
|
||||||
|
throw new ArgumentOutOfRangeException("charCount");
|
||||||
|
long count = charCount + 1;
|
||||||
|
count *= 2;
|
||||||
|
if (count > int.MaxValue)
|
||||||
|
throw new ArgumentOutOfRangeException("charCount");
|
||||||
|
return (int)count;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetMaxCharCount(int byteCount)
|
||||||
|
{
|
||||||
|
if (byteCount < 0)
|
||||||
|
throw new ArgumentOutOfRangeException("byteCount");
|
||||||
|
long count = byteCount + 3;
|
||||||
|
if (count > int.MaxValue)
|
||||||
|
throw new ArgumentOutOfRangeException("byteCount");
|
||||||
|
return (int)count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Decoder GetDecoder()
|
||||||
|
{
|
||||||
|
return new DBCSDecoder(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string WebName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _webName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex, DBCSDecoder decoder)
|
||||||
|
{
|
||||||
|
int charCount = 0;
|
||||||
|
ushort u;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
for (int i = 0; i < byteCount; byteIndex++, charIndex++, charCount++, i++)
|
||||||
|
{
|
||||||
|
u = 0;
|
||||||
|
if (decoder != null && decoder.pendingByte != 0)
|
||||||
|
{
|
||||||
|
u = decoder.pendingByte;
|
||||||
|
decoder.pendingByte = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u = (ushort)(u << 8 | bytes[byteIndex]);
|
||||||
|
c = _dbcsToUnicode[u];
|
||||||
|
if (c == LEAD_BYTE_CHAR)
|
||||||
|
{
|
||||||
|
if (i < byteCount - 1)
|
||||||
|
{
|
||||||
|
byteIndex++;
|
||||||
|
i++;
|
||||||
|
u = (ushort)(u << 8 | bytes[byteIndex]);
|
||||||
|
c = _dbcsToUnicode[u];
|
||||||
|
}
|
||||||
|
else if (decoder == null)
|
||||||
|
{
|
||||||
|
c = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
decoder.pendingByte = bytes[byteIndex];
|
||||||
|
return charCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (c == 0 && u != 0)
|
||||||
|
chars[charIndex] = '?';
|
||||||
|
else
|
||||||
|
chars[charIndex] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return charCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetCharCount(byte[] bytes, int index, int count, DBCSDecoder decoder)
|
||||||
|
{
|
||||||
|
int charCount = 0;
|
||||||
|
ushort u;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
for (int i = 0; i < count; index++, charCount++, i++)
|
||||||
|
{
|
||||||
|
u = 0;
|
||||||
|
if (decoder != null && decoder.pendingByte != 0)
|
||||||
|
{
|
||||||
|
u = decoder.pendingByte;
|
||||||
|
decoder.pendingByte = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u = (ushort)(u << 8 | bytes[index]);
|
||||||
|
c = _dbcsToUnicode[u];
|
||||||
|
if (c == LEAD_BYTE_CHAR)
|
||||||
|
{
|
||||||
|
if (i < count - 1)
|
||||||
|
{
|
||||||
|
index++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else if (decoder != null)
|
||||||
|
{
|
||||||
|
decoder.pendingByte = bytes[index];
|
||||||
|
return charCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return charCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async static Task<Stream> GetInstall(string name)
|
||||||
|
{
|
||||||
|
//此处只是简单的获取到gb2312.bin文件
|
||||||
|
//name = "gb2312";
|
||||||
|
var folderInstall = Windows.ApplicationModel.Package.Current.InstalledLocation;//获取安装包的位置
|
||||||
|
var folder = await folderInstall.GetFolderAsync("EncodingBins");
|
||||||
|
var file = await folder.GetFileAsync(name + ".bin"); //获取gb2312.bin
|
||||||
|
Stream stream = await file.OpenStreamForReadAsync(); //获取文件流
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class DBCSDecoder : Decoder
|
||||||
|
{
|
||||||
|
private DBCSEncoding _encoding = null;
|
||||||
|
|
||||||
|
public DBCSDecoder(DBCSEncoding encoding)
|
||||||
|
{
|
||||||
|
_encoding = encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetCharCount(byte[] bytes, int index, int count)
|
||||||
|
{
|
||||||
|
return _encoding.GetCharCount(bytes, index, count, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
|
||||||
|
{
|
||||||
|
return _encoding.GetChars(bytes, byteIndex, byteCount, chars, charIndex, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte pendingByte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
PlaneGcsSdk.Contract.EhNetUWP/DiscoveredOneUserEventArgs.cs
Normal file
14
PlaneGcsSdk.Contract.EhNetUWP/DiscoveredOneUserEventArgs.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace PlaneGcsSdk.Contract.EhNetUWP
|
||||||
|
{
|
||||||
|
public class DiscoveredOneUserEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public DiscoveredOneUserEventArgs(UserProperty userpro)
|
||||||
|
{
|
||||||
|
userproperty = userpro;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserProperty userproperty { get; set; }
|
||||||
|
}
|
||||||
|
}
|
1
PlaneGcsSdk.Contract.EhNetUWP/EncodingBins/Readme.txt
Normal file
1
PlaneGcsSdk.Contract.EhNetUWP/EncodingBins/Readme.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Gb2312和Big5编码的库,请确保此文件夹及文件存在于运行根目录中;
|
BIN
PlaneGcsSdk.Contract.EhNetUWP/EncodingBins/big5.bin
Normal file
BIN
PlaneGcsSdk.Contract.EhNetUWP/EncodingBins/big5.bin
Normal file
Binary file not shown.
After Width: | Height: | Size: 256 KiB |
BIN
PlaneGcsSdk.Contract.EhNetUWP/EncodingBins/gb2312.bin
Normal file
BIN
PlaneGcsSdk.Contract.EhNetUWP/EncodingBins/gb2312.bin
Normal file
Binary file not shown.
After Width: | Height: | Size: 256 KiB |
15
PlaneGcsSdk.Contract.EhNetUWP/ExceptionThrownEventArgs.cs
Normal file
15
PlaneGcsSdk.Contract.EhNetUWP/ExceptionThrownEventArgs.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace PlaneGcsSdk.Contract.EhNetUWP
|
||||||
|
{
|
||||||
|
public class ExceptionThrownEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public ExceptionThrownEventArgs(Exception ex)
|
||||||
|
{
|
||||||
|
Exception = ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Exception Exception { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
13
PlaneGcsSdk.Contract.EhNetUWP/LoginEventArgs.cs
Normal file
13
PlaneGcsSdk.Contract.EhNetUWP/LoginEventArgs.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace PlaneGcsSdk.Contract.EhNetUWP
|
||||||
|
{
|
||||||
|
public class LoginEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public LoginEventArgs(LoginState loginstate)
|
||||||
|
{
|
||||||
|
LoginState = loginstate;
|
||||||
|
}
|
||||||
|
public LoginState LoginState { get; set; }
|
||||||
|
}
|
||||||
|
}
|
738
PlaneGcsSdk.Contract.EhNetUWP/PLNet.cs
Normal file
738
PlaneGcsSdk.Contract.EhNetUWP/PLNet.cs
Normal file
@ -0,0 +1,738 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Windows.Networking.Sockets;
|
||||||
|
using System.IO;
|
||||||
|
using Windows.Storage.Streams;
|
||||||
|
using Windows.Networking;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Security.Cryptography.Core;
|
||||||
|
using Windows.Security.Cryptography;
|
||||||
|
|
||||||
|
namespace PlaneGcsSdk.Contract.EhNetUWP
|
||||||
|
{
|
||||||
|
public class PLNet
|
||||||
|
{
|
||||||
|
#region Properties
|
||||||
|
public StreamOBJ MyStreamObj;
|
||||||
|
/// <summary>
|
||||||
|
/// 连接的IP
|
||||||
|
/// </summary>
|
||||||
|
public string ServerIP { get; protected set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 连接的端口
|
||||||
|
/// </summary>
|
||||||
|
public int TCPPort { get; protected set; }
|
||||||
|
public bool IsClosing { get; protected set; }
|
||||||
|
public bool IsOpen { get; protected set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 真实名
|
||||||
|
/// </summary>
|
||||||
|
public string MyNick { get; protected set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 获取登录随机码
|
||||||
|
/// </summary>
|
||||||
|
public string MyRND { get { return sMyTempRnd; } }
|
||||||
|
/// <summary>
|
||||||
|
/// 发送文件列表
|
||||||
|
/// </summary>
|
||||||
|
public List<FileOBJ> SendFileList { get; protected set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 接收文件列表
|
||||||
|
/// </summary>
|
||||||
|
public List<FileOBJ> RevFileList { get; protected set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 用户列表
|
||||||
|
/// </summary>
|
||||||
|
public List<UserProperty> FriendList { get; protected set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 发送流列表
|
||||||
|
/// </summary>
|
||||||
|
public List<StreamOBJ> SendStreamList { get; protected set; }
|
||||||
|
public List<StreamOBJ> RevStreamList { get; protected set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Fields
|
||||||
|
string sMyTempRnd; //登录随机数
|
||||||
|
bool LoginFlag = false; //登录状态
|
||||||
|
string sMyID; //登录用户名
|
||||||
|
string sMyPassword; //登录密码
|
||||||
|
|
||||||
|
string sMyIP; //用户IP
|
||||||
|
Encoding _enconding;
|
||||||
|
int iStreamID = -1;
|
||||||
|
int iFileID = 0;
|
||||||
|
|
||||||
|
protected StreamSocket _socket; //连接对象
|
||||||
|
protected IInputStream _inputStream;
|
||||||
|
protected Stream _outputStream;
|
||||||
|
protected bool _canFlush = true;
|
||||||
|
protected const uint READ_BUFFER_SIZE = 2047;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Events
|
||||||
|
public event EventHandler<LoginEventArgs> Login;
|
||||||
|
public event EventHandler<DiscoveredOneUserEventArgs> DiscoveredOneUser;
|
||||||
|
public event EventHandler RefreshFriendListCompleted;
|
||||||
|
public event EventHandler<UserStateChangeEventArgs> UserStateChange;
|
||||||
|
public event EventHandler Disconnect;
|
||||||
|
public event EventHandler<CommandArrivalEventArgs> CommandArrival;
|
||||||
|
public event EventHandler<ExceptionThrownEventArgs> ExceptionThrown;
|
||||||
|
public event EventHandler<StartSendFileEventArgs> StartSendFile;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public PLNet()
|
||||||
|
{
|
||||||
|
FriendList = new List<UserProperty>();
|
||||||
|
SendFileList = new List<FileOBJ>();
|
||||||
|
RevFileList = new List<FileOBJ>();
|
||||||
|
SendStreamList = new List<StreamOBJ>();
|
||||||
|
RevStreamList = new List<StreamOBJ>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Public Methods
|
||||||
|
/// <summary>
|
||||||
|
/// 建立连接
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sServerIP"></param>
|
||||||
|
/// <param name="sUsername"></param>
|
||||||
|
/// <param name="sPassword"></param>
|
||||||
|
/// <param name="md5Password"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task Start(string sServerIP, string sUsername, string sPassword, string md5Password = null)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
IsClosing = false;
|
||||||
|
|
||||||
|
if (_enconding == null)
|
||||||
|
{
|
||||||
|
_enconding = await DBCSEncoding.GetDBCSEncoding("GB2312");
|
||||||
|
}
|
||||||
|
|
||||||
|
sMyID = sUsername;
|
||||||
|
if (md5Password == null)
|
||||||
|
sMyPassword = GetStrMd5Hash(sMyID + sPassword);
|
||||||
|
else
|
||||||
|
sMyPassword = md5Password;
|
||||||
|
|
||||||
|
ServerIP = sServerIP; //登录用户的IP地址
|
||||||
|
TCPPort = 52510; //登录用户的端口
|
||||||
|
|
||||||
|
_socket = new StreamSocket(); //创建连接对象
|
||||||
|
await _socket.ConnectAsync(new HostName(ServerIP), TCPPort.ToString()).AsTask().ConfigureAwait(false); //执行连接操作
|
||||||
|
|
||||||
|
IsOpen = true;
|
||||||
|
_inputStream = _socket.InputStream;
|
||||||
|
_outputStream = _socket.OutputStream.AsStreamForWrite();
|
||||||
|
await Task.Run(() => TCPClientThread());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关闭连接
|
||||||
|
/// </summary>
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
IsClosing = true;
|
||||||
|
IsOpen = false;
|
||||||
|
_inputStream?.Dispose();
|
||||||
|
_outputStream?.Dispose();
|
||||||
|
_socket?.Dispose();
|
||||||
|
if (SendFileList != null)
|
||||||
|
SendFileList.Clear();
|
||||||
|
if (RevFileList != null)
|
||||||
|
RevFileList.Clear();
|
||||||
|
Disconnect?.Invoke(this, EventArgs.Empty); //触发事件Disconnect
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送命令
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="friendIDs"></param>
|
||||||
|
/// <param name="msg"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task SendCommand(string friendIDs, string msg)
|
||||||
|
{
|
||||||
|
string commandtext = "*" + friendIDs + "|" + msg;
|
||||||
|
await SendCmd(commandtext);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送数据流,给多个用户同时发送数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="friendIDs"></param>
|
||||||
|
/// <param name="myData"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task SendStream(string friendIDs, byte[] myData)
|
||||||
|
{
|
||||||
|
string[] myFriends = friendIDs.Split(',');
|
||||||
|
for (int i = 0; i < myFriends.Length; i++)
|
||||||
|
{
|
||||||
|
iStreamID += 1;
|
||||||
|
MyStreamObj = new StreamOBJ();
|
||||||
|
MyStreamObj.StreamID = iStreamID;
|
||||||
|
MyStreamObj.StreamData = myData;
|
||||||
|
MyStreamObj.RevUserID = myFriends[i];
|
||||||
|
SendStreamList.Add(MyStreamObj);
|
||||||
|
string streamtext = "*" + myFriends[i] + "|SB|" + MyStreamObj.StreamID.ToString() + "|" + MyStreamObj.StreamData.Length.ToString();
|
||||||
|
await SendCmd(streamtext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送普通文件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="friendID"></param>
|
||||||
|
/// <param name="sFilenames"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task SendFileCommon(string friendID, string[] sFilenames)
|
||||||
|
{
|
||||||
|
string filetype = "F";
|
||||||
|
await SendFileCommon(friendID, sFilenames, filetype);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送图片文件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="friendID"></param>
|
||||||
|
/// <param name="sFilenames"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task SendPicture(string friendID, string[] sFilenames)
|
||||||
|
{
|
||||||
|
string filetype = "P";
|
||||||
|
await SendFileCommon(friendID, sFilenames, filetype);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送视频文件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="friendID"></param>
|
||||||
|
/// <param name="sFilenames"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task SendVideo(string friendID, string[] sFilenames)
|
||||||
|
{
|
||||||
|
string filetype = "V";
|
||||||
|
await SendFileCommon(friendID, sFilenames, filetype);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送文件公共函数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="friendID"></param>
|
||||||
|
/// <param name="sFilenames"></param>
|
||||||
|
/// <param name="filetype"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task SendFileCommon(string friendID, string[] sFilenames, string filetype)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < sFilenames.Length; i++)
|
||||||
|
{
|
||||||
|
FileOBJ tmpFileObj = new FileOBJ();
|
||||||
|
tmpFileObj.FileID = iFileID;
|
||||||
|
iFileID += 1;
|
||||||
|
FileInfo MyFileInfo = new FileInfo(sFilenames[i]);
|
||||||
|
tmpFileObj.Filename = MyFileInfo.Name;
|
||||||
|
tmpFileObj.FilePath = MyFileInfo.DirectoryName;
|
||||||
|
tmpFileObj.FileLength = MyFileInfo.Length;
|
||||||
|
tmpFileObj.FileModDate = filetype + MyFileInfo.LastWriteTime.ToString(); //filetype表示发送文件的类型
|
||||||
|
tmpFileObj.RevUserID = friendID;
|
||||||
|
tmpFileObj.State = FileState.WaitConfim;
|
||||||
|
tmpFileObj.tmpFileStream = new FileStream(sFilenames[i], FileMode.Open, FileAccess.Read);
|
||||||
|
SendFileList.Add(tmpFileObj);
|
||||||
|
StartSendFile?.Invoke(this, new StartSendFileEventArgs(SendFileList.Count - 1));
|
||||||
|
string filetext = "FB" + friendID + "|" + tmpFileObj.FileID.ToString() + "|" + tmpFileObj.Filename + "|" + tmpFileObj.FileLength.ToString() + "|" + tmpFileObj.FileModDate;
|
||||||
|
await SendCmd(filetext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送数据公共函数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cmdStr"></param>
|
||||||
|
/// <param name="addBytes"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task SendCmd(string cmdStr, byte[] addBytes = null)
|
||||||
|
{
|
||||||
|
byte[] tmpSendbytes = null;
|
||||||
|
tmpSendbytes = _enconding.GetBytes(cmdStr);
|
||||||
|
int nret;
|
||||||
|
int strLen = LenB(cmdStr);
|
||||||
|
if (addBytes == null)
|
||||||
|
{
|
||||||
|
tmpSendbytes = BitConverter.GetBytes((ushort)strLen);
|
||||||
|
Array.Resize(ref tmpSendbytes, strLen + 2);
|
||||||
|
nret = _enconding.GetBytes(cmdStr, 0, cmdStr.Length, tmpSendbytes, 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byte[] tmpBytes;
|
||||||
|
long allLenth = strLen + addBytes.Length;
|
||||||
|
tmpBytes = BitConverter.GetBytes(allLenth);
|
||||||
|
Array.Resize(ref tmpBytes, strLen + 2);
|
||||||
|
nret = _enconding.GetBytes(cmdStr, 0, cmdStr.Length, tmpBytes, 2);
|
||||||
|
tmpSendbytes = AddByte(tmpBytes, addBytes);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (tmpSendbytes != null)
|
||||||
|
{
|
||||||
|
await _outputStream.WriteAsync(tmpSendbytes, 0, tmpSendbytes.Length).ConfigureAwait(false);
|
||||||
|
if (_canFlush)
|
||||||
|
{
|
||||||
|
await _outputStream.FlushAsync().ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_canFlush = false;
|
||||||
|
Close();
|
||||||
|
ExceptionThrown?.Invoke(this, new ExceptionThrownEventArgs(ex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Private Methods
|
||||||
|
/// <summary>
|
||||||
|
/// 启动一个接收数据的线程
|
||||||
|
/// </summary>
|
||||||
|
private async void TCPClientThread()
|
||||||
|
{
|
||||||
|
uint i; //接收到的数据的长度
|
||||||
|
byte[] byteBuffer = null; //暂存接收到的数据
|
||||||
|
int comLength;
|
||||||
|
bool ReadFlag = false;
|
||||||
|
bool nRet;
|
||||||
|
byte[] Tmpbyte;
|
||||||
|
|
||||||
|
IBuffer tempbuf = new Windows.Storage.Streams.Buffer(READ_BUFFER_SIZE); //建立一个buffer
|
||||||
|
await _inputStream.ReadAsync(tempbuf, READ_BUFFER_SIZE, InputStreamOptions.Partial);
|
||||||
|
i = tempbuf.Length;
|
||||||
|
byteBuffer = new byte[i];
|
||||||
|
tempbuf.CopyTo(byteBuffer); //将数据输出
|
||||||
|
|
||||||
|
while (i != 0)
|
||||||
|
{
|
||||||
|
if (byteBuffer.Length > 3)
|
||||||
|
{
|
||||||
|
comLength = BitConverter.ToUInt16(byteBuffer, 0);
|
||||||
|
if (LoginFlag == false && comLength > 70)
|
||||||
|
{
|
||||||
|
#region
|
||||||
|
if (byteBuffer.Length >= 2)
|
||||||
|
{
|
||||||
|
byte[] firstchar = new byte[1];
|
||||||
|
firstchar[0] = byteBuffer[1];
|
||||||
|
if (_enconding.GetString(firstchar) != "L")
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ReadFlag = true;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#region
|
||||||
|
if (byteBuffer.Length >= comLength + 1)
|
||||||
|
{
|
||||||
|
Tmpbyte = MidByte(byteBuffer, 3, comLength); //截取字节
|
||||||
|
if (Tmpbyte.Length < 4)
|
||||||
|
nRet = false;
|
||||||
|
nRet = await ProcessData(Tmpbyte);
|
||||||
|
if (nRet == true)
|
||||||
|
{
|
||||||
|
byteBuffer = RightByte(byteBuffer, byteBuffer.Length - comLength - 2); //截取字节
|
||||||
|
if (byteBuffer.Length <= 0)
|
||||||
|
ReadFlag = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ReadFlag = true;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ReadFlag = true;
|
||||||
|
}
|
||||||
|
if (ReadFlag == true)
|
||||||
|
{
|
||||||
|
#region
|
||||||
|
ReadFlag = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tempbuf = new Windows.Storage.Streams.Buffer(READ_BUFFER_SIZE); //建立一个buffer
|
||||||
|
await _inputStream.ReadAsync(tempbuf, READ_BUFFER_SIZE, InputStreamOptions.Partial);
|
||||||
|
i = tempbuf.Length;
|
||||||
|
byte[] addbyte = new byte[i];
|
||||||
|
tempbuf.CopyTo(addbyte);
|
||||||
|
byteBuffer = AddByte(byteBuffer, addbyte);
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理接收到的数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tmpbyte"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private async Task<bool> ProcessData(byte[] tmpbyte)
|
||||||
|
{
|
||||||
|
string recestr = _enconding.GetString(tmpbyte); //这里本应是GBK编码
|
||||||
|
UserProperty tmpUserinfo = new UserProperty();
|
||||||
|
int tmpIndex;
|
||||||
|
|
||||||
|
switch (recestr[0])
|
||||||
|
{
|
||||||
|
case 'R':
|
||||||
|
sMyTempRnd = recestr.Substring(1);
|
||||||
|
await SendCmd("L" + sMyID + "|" + GetStrMd5Hash(sMyPassword + sMyTempRnd));
|
||||||
|
sMyTempRnd = sMyTempRnd.Substring(0, sMyTempRnd.Length - 1);
|
||||||
|
break;
|
||||||
|
case 'U': //收到用户信息
|
||||||
|
string sUserinfo = recestr.Substring(1);
|
||||||
|
switch (sUserinfo[0])
|
||||||
|
{
|
||||||
|
#region
|
||||||
|
case 'A': //用户列表
|
||||||
|
#region
|
||||||
|
sUserinfo = sUserinfo.Substring(1);
|
||||||
|
tmpUserinfo.UserID = Fin(1, sUserinfo, "|");
|
||||||
|
tmpUserinfo.UserNick = Fin(2, sUserinfo, "|");
|
||||||
|
tmpUserinfo.UserIndex = FriendList.Count;
|
||||||
|
tmpUserinfo.UserMessage = new List<String>();
|
||||||
|
FriendList.Add(tmpUserinfo);
|
||||||
|
DiscoveredOneUser?.Invoke(this, new DiscoveredOneUserEventArgs(tmpUserinfo));
|
||||||
|
#endregion
|
||||||
|
break;
|
||||||
|
case 'O': //用户上线
|
||||||
|
#region
|
||||||
|
sUserinfo = sUserinfo.Substring(1);
|
||||||
|
tmpIndex = GetUserIndexByID(Fin(1, sUserinfo, "|"));
|
||||||
|
if (tmpIndex >= 0)
|
||||||
|
{
|
||||||
|
tmpUserinfo = FriendList[tmpIndex]; //修改用户在线状态
|
||||||
|
tmpUserinfo.UserOnline = true;
|
||||||
|
FriendList[tmpIndex] = tmpUserinfo;
|
||||||
|
UserStateChange?.Invoke(this, new UserStateChangeEventArgs(tmpUserinfo));
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
break;
|
||||||
|
case 'F': //用户下线
|
||||||
|
#region
|
||||||
|
sUserinfo = sUserinfo.Substring(1);
|
||||||
|
string tmpFriendID = Fin(1, sUserinfo, "|");
|
||||||
|
tmpIndex = GetUserIndexByID(tmpFriendID);
|
||||||
|
if (tmpIndex >= 0)
|
||||||
|
{
|
||||||
|
tmpUserinfo = FriendList[tmpIndex];
|
||||||
|
tmpUserinfo.UserOnline = false;
|
||||||
|
FriendList[tmpIndex] = tmpUserinfo;
|
||||||
|
//处理发送文件残留
|
||||||
|
for (int i = 0; i < SendFileList.Count; i--)
|
||||||
|
{
|
||||||
|
if (SendFileList[i].RevUserID == tmpFriendID)
|
||||||
|
{
|
||||||
|
SendFileList[i].tmpFileStream.Dispose();
|
||||||
|
SendFileList.RemoveAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int j = 0; j < RevFileList.Count; j--)
|
||||||
|
{
|
||||||
|
if (RevFileList[j].RevUserID == tmpFriendID)
|
||||||
|
{
|
||||||
|
RevFileList[j].tmpFileStream.Dispose();
|
||||||
|
RevFileList.RemoveAt(j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UserStateChange?.Invoke(this, new UserStateChangeEventArgs(tmpUserinfo));
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
break;
|
||||||
|
case 'C': //被别人添加为好友时会收到
|
||||||
|
break;
|
||||||
|
case 'E':
|
||||||
|
RefreshFriendListCompleted?.Invoke(this, EventArgs.Empty);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'L': //登陆
|
||||||
|
recestr = recestr.Substring(1);
|
||||||
|
switch (recestr[0])
|
||||||
|
{
|
||||||
|
#region
|
||||||
|
case 'P':
|
||||||
|
Login?.Invoke(this, new LoginEventArgs(LoginState.LoginPwdError));
|
||||||
|
break;
|
||||||
|
case 'O':
|
||||||
|
LoginFlag = true;
|
||||||
|
MyNick = recestr.Substring(1).Split('|')[0];
|
||||||
|
Login?.Invoke(this, new LoginEventArgs(LoginState.LoginOk));
|
||||||
|
await SendCmd("UG");
|
||||||
|
break;
|
||||||
|
case 'U':
|
||||||
|
Login?.Invoke(this, new LoginEventArgs(LoginState.LoginNoUser));
|
||||||
|
break;
|
||||||
|
case 'E':
|
||||||
|
Login?.Invoke(this, new LoginEventArgs(LoginState.LoginOtherError));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '*': //收到命令,格式为: *+FriendID+|+Msg
|
||||||
|
string tmpStr = recestr.Substring(1);
|
||||||
|
string tmpstr2 = Fin(2, tmpStr, "|");
|
||||||
|
switch (tmpstr2[0])
|
||||||
|
{
|
||||||
|
#region
|
||||||
|
case 'S':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
string friendid = Fin(1, tmpStr, "|");
|
||||||
|
string msgcontent = tmpStr.Substring(tmpStr.IndexOf("|") + 1);
|
||||||
|
CommandArrival?.Invoke(this, new CommandArrivalEventArgs(friendid, msgcontent));
|
||||||
|
break;
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int LenB(string str)
|
||||||
|
{
|
||||||
|
return _enconding.GetBytes(str).Count();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个字节数组中的某些字节,从start个字节开始,获取length个字节,第几个是从1开始的
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tbyte"></param>
|
||||||
|
/// <param name="start"></param>
|
||||||
|
/// <param name="length"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private byte[] MidByte(byte[] tbyte, int start, int length)
|
||||||
|
{
|
||||||
|
byte[] tmpMidByte = new byte[length];
|
||||||
|
//for (int i = 0; i < length; i++)
|
||||||
|
//{
|
||||||
|
// tmpMidByte[i] = tbyte[i + start - 1];
|
||||||
|
//}
|
||||||
|
for (int i = start - 1; i <= length - 1 + start - 1; i++)
|
||||||
|
{
|
||||||
|
tmpMidByte[i - (start - 1)] = tbyte[i];
|
||||||
|
}
|
||||||
|
return tmpMidByte;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取某个字节数组的后面的字节,获取length个字节
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tbyte"></param>
|
||||||
|
/// <param name="length"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private byte[] RightByte(byte[] tbyte, int length)
|
||||||
|
{
|
||||||
|
byte[] temRightByte = new byte[length];
|
||||||
|
temRightByte = MidByte(tbyte, tbyte.Length - length + 1, length);
|
||||||
|
return temRightByte;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取某个字节数组的前面的字节,获取length个字节
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tbyte"></param>
|
||||||
|
/// <param name="length"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private byte[] LeftByte(byte[] tbyte, int length)
|
||||||
|
{
|
||||||
|
byte[] temLeftByte = new byte[length];
|
||||||
|
temLeftByte = MidByte(tbyte, 1, length);
|
||||||
|
return temLeftByte;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 拼接两个字节,将addbyte加在srcbyte后面
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="srcbyte"></param>
|
||||||
|
/// <param name="addbyte"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private byte[] AddByte(byte[] srcbyte, byte[] addbyte)
|
||||||
|
{
|
||||||
|
byte[] resultbyte = new byte[srcbyte.Length + addbyte.Length];
|
||||||
|
for (int i = 0; i < srcbyte.Length; i++)
|
||||||
|
{
|
||||||
|
resultbyte[i] = srcbyte[i];
|
||||||
|
}
|
||||||
|
for (int j = 0; j < addbyte.Length; j++)
|
||||||
|
{
|
||||||
|
resultbyte[j + srcbyte.Length] = addbyte[j];
|
||||||
|
}
|
||||||
|
return resultbyte;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据ID获取列表中序号
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tmpUserID"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected int GetUserIndexByID(string tmpUserID)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < FriendList.Count; i++)
|
||||||
|
{
|
||||||
|
if (FriendList.ElementAt(i).UserID == tmpUserID)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分割字符串,第Xnum个字符,字符串为SrcStr,分割特征为SpStr
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="xnum"></param>
|
||||||
|
/// <param name="srcStr"></param>
|
||||||
|
/// <param name="spStr"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private string Fin(int xnum, string srcStr, string spStr)
|
||||||
|
{
|
||||||
|
string[] tmpStr;
|
||||||
|
char[] FF = new char[1];
|
||||||
|
FF[0] = spStr[0];
|
||||||
|
tmpStr = srcStr.Split(FF);
|
||||||
|
if ((xnum > 0) && (xnum <= tmpStr.Length))
|
||||||
|
return tmpStr[xnum - 1];
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算字符串的MD5哈希值,输入为字符串strtohash,输出为字符串strHash
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="strtohash"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private string GetStrMd5Hash(string strtohash)
|
||||||
|
{
|
||||||
|
|
||||||
|
byte[] tmpbyte = _enconding.GetBytes(strtohash);
|
||||||
|
|
||||||
|
IBuffer buffMsg = CryptographicBuffer.CreateFromByteArray(tmpbyte);
|
||||||
|
|
||||||
|
HashAlgorithmProvider objAlgProv = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5);
|
||||||
|
|
||||||
|
IBuffer tmpbuffer = objAlgProv.HashData(buffMsg);
|
||||||
|
|
||||||
|
uint i = tmpbuffer.Length;
|
||||||
|
byte[] mybyte = new byte[i];
|
||||||
|
tmpbuffer.CopyTo(mybyte);
|
||||||
|
|
||||||
|
CryptographicBuffer.CopyToByteArray(tmpbuffer, out mybyte);
|
||||||
|
|
||||||
|
StringBuilder sBuilder = new StringBuilder();
|
||||||
|
for (int k = 0; k < mybyte.Length; k++)
|
||||||
|
{
|
||||||
|
sBuilder.Append(mybyte[k].ToString("x2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
string strHash = sBuilder.ToString();
|
||||||
|
|
||||||
|
return strHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
#region Nested Type
|
||||||
|
/// <summary>
|
||||||
|
/// 用户信息结构体
|
||||||
|
/// </summary>
|
||||||
|
public struct UserProperty
|
||||||
|
{
|
||||||
|
public string UserID;
|
||||||
|
public string UserNick;
|
||||||
|
public string UserIP;
|
||||||
|
public int UserIndex;
|
||||||
|
public bool UserOnline;
|
||||||
|
public List<string> UserMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 文件状态
|
||||||
|
/// </summary>
|
||||||
|
public enum FileState
|
||||||
|
{
|
||||||
|
WaitConfim,
|
||||||
|
StartSend, //开始发送,等待确认
|
||||||
|
Sending, //正在发送中
|
||||||
|
reSend, //断点续传中
|
||||||
|
SendError, //发送错误
|
||||||
|
Completed, //发送完成
|
||||||
|
LoginOtherError, //其他错
|
||||||
|
StartReveice, //开始接收,等待数据
|
||||||
|
Receiving, //接收中
|
||||||
|
ReReceiving, //断点续传中
|
||||||
|
ReceiveError
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 登录状态
|
||||||
|
/// </summary>
|
||||||
|
public enum LoginState
|
||||||
|
{
|
||||||
|
LoginPwdError, //密码错
|
||||||
|
LoginOk, //登陆成功
|
||||||
|
LoginNoUser, //用户不存在
|
||||||
|
LoginOtherError, //其他错
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 文件结构体
|
||||||
|
/// </summary>
|
||||||
|
public struct FileOBJ
|
||||||
|
{
|
||||||
|
public string Filename;
|
||||||
|
public string FilePath;
|
||||||
|
public long FileLength;
|
||||||
|
public string FileModDate;
|
||||||
|
public int FileID;
|
||||||
|
public string SendUserID;
|
||||||
|
public string RevUserID;
|
||||||
|
public FileStream tmpFileStream;
|
||||||
|
public FileState State;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 数据流结构体
|
||||||
|
/// </summary>
|
||||||
|
public struct StreamOBJ
|
||||||
|
{
|
||||||
|
public byte[] StreamData;
|
||||||
|
public ulong CurrPos;
|
||||||
|
public int StreamID;
|
||||||
|
public ulong Length;
|
||||||
|
public string SendUserID;
|
||||||
|
public string RevUserID;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
@ -0,0 +1,141 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{D7D21B2B-6F73-4939-B720-FE51DA1C04C0}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>PlaneGcsSdk.Contract.EhNetUWP</RootNamespace>
|
||||||
|
<AssemblyName>PlaneGcsSdk.Contract.EhNetUWP</AssemblyName>
|
||||||
|
<DefaultLanguage>zh-CN</DefaultLanguage>
|
||||||
|
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||||
|
<TargetPlatformVersion>10.0.10586.0</TargetPlatformVersion>
|
||||||
|
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
|
||||||
|
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
|
||||||
|
<PlatformTarget>ARM</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\ARM\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>ARM</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
|
||||||
|
<PlatformTarget>ARM</PlatformTarget>
|
||||||
|
<OutputPath>bin\ARM\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>ARM</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<OutputPath>bin\x64\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<OutputPath>bin\x86\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<!-- A reference to the entire .Net Framework and Windows SDK are automatically included -->
|
||||||
|
<Content Include="EncodingBins\big5.bin">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="EncodingBins\gb2312.bin">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<None Include="project.json" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="CommandArrivalEventArgs.cs" />
|
||||||
|
<Compile Include="DBCSEncoding.cs" />
|
||||||
|
<Compile Include="DiscoveredOneUserEventArgs.cs" />
|
||||||
|
<Compile Include="PLNet.cs" />
|
||||||
|
<Compile Include="ExceptionThrownEventArgs.cs" />
|
||||||
|
<Compile Include="LoginEventArgs.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="StartSendFileEventArgs.cs" />
|
||||||
|
<Compile Include="UserStateChangeEventArgs.cs" />
|
||||||
|
<Content Include="EncodingBins\Readme.txt" />
|
||||||
|
<Content Include="Properties\PlaneGcsSdk.Contract.EhNetUWP.rd.xml" />
|
||||||
|
<Content Include="Readme.txt" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup />
|
||||||
|
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||||
|
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
29
PlaneGcsSdk.Contract.EhNetUWP/Properties/AssemblyInfo.cs
Normal file
29
PlaneGcsSdk.Contract.EhNetUWP/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("PlaneGcsSdk.Contract.EhNetUWP")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("PlaneGcsSdk.Contract.EhNetUWP")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
|
[assembly: ComVisible(false)]
|
@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
This file contains Runtime Directives, specifications about types your application accesses
|
||||||
|
through reflection and other dynamic code patterns. Runtime Directives are used to control the
|
||||||
|
.NET Native optimizer and ensure that it does not remove code accessed by your library. If your
|
||||||
|
library does not do any reflection, then you generally do not need to edit this file. However,
|
||||||
|
if your library reflects over types, especially types passed to it or derived from its types,
|
||||||
|
then you should write Runtime Directives.
|
||||||
|
|
||||||
|
The most common use of reflection in libraries is to discover information about types passed
|
||||||
|
to the library. Runtime Directives have three ways to express requirements on types passed to
|
||||||
|
your library.
|
||||||
|
|
||||||
|
1. Parameter, GenericParameter, TypeParameter, TypeEnumerableParameter
|
||||||
|
Use these directives to reflect over types passed as a parameter.
|
||||||
|
|
||||||
|
2. SubTypes
|
||||||
|
Use a SubTypes directive to reflect over types derived from another type.
|
||||||
|
|
||||||
|
3. AttributeImplies
|
||||||
|
Use an AttributeImplies directive to indicate that your library needs to reflect over
|
||||||
|
types or methods decorated with an attribute.
|
||||||
|
|
||||||
|
For more information on writing Runtime Directives for libraries, please visit
|
||||||
|
http://go.microsoft.com/fwlink/?LinkID=391919
|
||||||
|
-->
|
||||||
|
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
|
||||||
|
<Library Name="PlaneGcsSdk.Contract.EhNetUWP">
|
||||||
|
|
||||||
|
<!-- add directives for your library here -->
|
||||||
|
|
||||||
|
</Library>
|
||||||
|
</Directives>
|
4
PlaneGcsSdk.Contract.EhNetUWP/Readme.txt
Normal file
4
PlaneGcsSdk.Contract.EhNetUWP/Readme.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
本项目:
|
||||||
|
1,实现了数据按字节加密的类;
|
||||||
|
2,实现了GBK/GB2312/Big5编解码;
|
||||||
|
3,移植了PLNet(.Net)模块;
|
14
PlaneGcsSdk.Contract.EhNetUWP/StartSendFileEventArgs.cs
Normal file
14
PlaneGcsSdk.Contract.EhNetUWP/StartSendFileEventArgs.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace PlaneGcsSdk.Contract.EhNetUWP
|
||||||
|
{
|
||||||
|
public class StartSendFileEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public StartSendFileEventArgs(int streamindex)
|
||||||
|
{
|
||||||
|
StreamIndex = streamindex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int StreamIndex { get; set; }
|
||||||
|
}
|
||||||
|
}
|
14
PlaneGcsSdk.Contract.EhNetUWP/UserStateChangeEventArgs.cs
Normal file
14
PlaneGcsSdk.Contract.EhNetUWP/UserStateChangeEventArgs.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace PlaneGcsSdk.Contract.EhNetUWP
|
||||||
|
{
|
||||||
|
public class UserStateChangeEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public UserStateChangeEventArgs(UserProperty friendinfo)
|
||||||
|
{
|
||||||
|
FriendInfo = friendinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserProperty FriendInfo { get; set; }
|
||||||
|
}
|
||||||
|
}
|
16
PlaneGcsSdk.Contract.EhNetUWP/project.json
Normal file
16
PlaneGcsSdk.Contract.EhNetUWP/project.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"uap10.0": {}
|
||||||
|
},
|
||||||
|
"runtimes": {
|
||||||
|
"win10-arm": {},
|
||||||
|
"win10-arm-aot": {},
|
||||||
|
"win10-x86": {},
|
||||||
|
"win10-x86-aot": {},
|
||||||
|
"win10-x64": {},
|
||||||
|
"win10-x64-aot": {}
|
||||||
|
}
|
||||||
|
}
|
52
PlaneGcsSdk.Contract/PlaneGcsSdk.Contract.csproj
Normal file
52
PlaneGcsSdk.Contract/PlaneGcsSdk.Contract.csproj
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{18ECD88E-5D74-43E8-8BC2-D28F6DB13A47}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>Plane</RootNamespace>
|
||||||
|
<AssemblyName>PlaneGcsSdk.Contract</AssemblyName>
|
||||||
|
<DefaultLanguage>en-US</DefaultLanguage>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
|
<TargetFrameworkProfile>Profile111</TargetFrameworkProfile>
|
||||||
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>TRACE;DEBUG;PORTABLE;NETFX_CORE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE;PORTABLE;NETFX_CORE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<DocumentationFile>bin\Release\PlaneGcsSdk.Contract.xml</DocumentationFile>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<!-- A reference to the entire .NET Framework is automatically included -->
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="..\PlaneGcsSdk.Contract_Shared\PlaneGcsSdk.Contract_Shared.projitems" Label="Shared" />
|
||||||
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
30
PlaneGcsSdk.Contract/Properties/AssemblyInfo.cs
Normal file
30
PlaneGcsSdk.Contract/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using System.Resources;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("PlaneGcsSdk.Contract")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("Plane, Inc.")]
|
||||||
|
[assembly: AssemblyProduct("PlaneGcsSdk.Contract")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
[assembly: NeutralResourcesLanguage("en")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
public class DataStreamReceivedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public DataStreamReceivedEventArgs(DataStreamType dataStreamType)
|
||||||
|
{
|
||||||
|
DataStreamType = dataStreamType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataStreamType DataStreamType { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
9
PlaneGcsSdk.Contract_Private/Copters/DataStreamType.cs
Normal file
9
PlaneGcsSdk.Contract_Private/Copters/DataStreamType.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
public enum DataStreamType : byte
|
||||||
|
{
|
||||||
|
SYS_STATUS = 1, // MAVLINK_MSG_ID_SYS_STATUS,
|
||||||
|
GPS_RAW_INT = 24, // MAVLINK_MSG_ID_GPS_RAW_INT,
|
||||||
|
RC_CHANNELS_RAW = 35 // MAVLINK_MSG_ID_RC_CHANNELS_RAW
|
||||||
|
}
|
||||||
|
}
|
20
PlaneGcsSdk.Contract_Private/Copters/ICopterActions.cs
Normal file
20
PlaneGcsSdk.Contract_Private/Copters/ICopterActions.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
public partial interface ICopterActions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 开始画圈。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task CircleAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// // 林俊清, 20160122, 不明确。目测是发送重启命令,在刷固件之前用到。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bootloaderMode"></param>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task RebootAsync(bool bootloaderMode = false);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{47141894-ECE3-48CA-8DCF-CA751BDA231E}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>Plane</RootNamespace>
|
||||||
|
<AssemblyName>PlaneGcsSdk.Contract_Private</AssemblyName>
|
||||||
|
<DefaultLanguage>en-US</DefaultLanguage>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
|
<TargetFrameworkProfile>Profile111</TargetFrameworkProfile>
|
||||||
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>TRACE;DEBUG;PORTABLE;NETFX_CORE;PRIVATE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE;PORTABLE;NETFX_CORE;PRIVATE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<DocumentationFile>bin\Release\PlaneGcsSdk.Contract_Private.xml</DocumentationFile>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<!-- A reference to the entire .NET Framework is automatically included -->
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Copters\DataStreamReceivedEventArgs.cs" />
|
||||||
|
<Compile Include="Copters\DataStreamType.cs" />
|
||||||
|
<Compile Include="Copters\ICopterActions.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="..\PlaneGcsSdk.Contract_Shared\PlaneGcsSdk.Contract_Shared.projitems" Label="Shared" />
|
||||||
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
30
PlaneGcsSdk.Contract_Private/Properties/AssemblyInfo.cs
Normal file
30
PlaneGcsSdk.Contract_Private/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using System.Resources;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("PlaneGcsSdk.Contract_Private")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("Plane, Inc.")]
|
||||||
|
[assembly: AssemblyProduct("PlaneGcsSdk.Contract_Private")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
[assembly: NeutralResourcesLanguage("en")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Plane.Communication
|
||||||
|
{
|
||||||
|
public class ConnectionEstablishedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public ConnectionEstablishedEventArgs(IConnection connection, string remoteAddress)
|
||||||
|
{
|
||||||
|
this.Connection = connection;
|
||||||
|
RemoteAddress = remoteAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IConnection Connection { get; private set; }
|
||||||
|
|
||||||
|
public string RemoteAddress { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Plane.Communication
|
||||||
|
{
|
||||||
|
public class ExceptionThrownEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public ExceptionThrownEventArgs(Exception ex)
|
||||||
|
{
|
||||||
|
Exception = ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Exception Exception { get; set; }
|
||||||
|
}
|
||||||
|
}
|
50
PlaneGcsSdk.Contract_Shared/Communication/IConnection.cs
Normal file
50
PlaneGcsSdk.Contract_Shared/Communication/IConnection.cs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Plane.Communication
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 定义与远程主机通信的方法。
|
||||||
|
/// </summary>
|
||||||
|
public interface IConnection
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 在不宜抛出的异常发生时引发的事件。
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<ExceptionThrownEventArgs> ExceptionThrown;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个值,指示通信是否已开启。
|
||||||
|
/// </summary>
|
||||||
|
bool IsOpen { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关闭通信。
|
||||||
|
/// </summary>
|
||||||
|
void Close();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开启通信。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>表示此异步操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task OpenAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步读取数据。顺利完成时将正好读取 <paramref name="count"/> 个字节。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="buffer">存放数据的缓冲区。</param>
|
||||||
|
/// <param name="offset">起始下标。</param>
|
||||||
|
/// <param name="count">要读取的字节数。</param>
|
||||||
|
/// <returns>包含成功读取的字节数的 <see cref="Task{TResult}"/> 实例。此数目在操作顺利完成时保证与 <paramref name="count"/> 等,否则为 0。</returns>
|
||||||
|
Task<int> ReadAsync(byte[] buffer, int offset, int count);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步写入数据。会抛异常。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="buffer">存放数据的缓冲区。</param>
|
||||||
|
/// <param name="offset">起始下标。</param>
|
||||||
|
/// <param name="count">要写入的字节数。</param>
|
||||||
|
/// <returns>表示此异步操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task WriteAsync(byte[] buffer, int offset, int count);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Plane.CopterControllers
|
||||||
|
{
|
||||||
|
[Flags]
|
||||||
|
public enum CopterControllerTypes : byte
|
||||||
|
{
|
||||||
|
AvatarController = 0x1,
|
||||||
|
MicroController = 0x2,
|
||||||
|
KeyboardController = 0x4,
|
||||||
|
FlyToController = 0x8
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
namespace Plane.CopterControllers
|
||||||
|
{
|
||||||
|
public interface ICopterController
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置一个值,指示是否激活此控制器。
|
||||||
|
/// </summary>
|
||||||
|
bool IsEnabled { get; set; }
|
||||||
|
|
||||||
|
CopterControllerTypes Type { get; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
namespace Plane.CopterControllers
|
||||||
|
{
|
||||||
|
public interface ICopterControllerManager
|
||||||
|
{
|
||||||
|
bool IsControllingRollPitchUsingAvatar { get; }
|
||||||
|
|
||||||
|
void EnableCopterControllers(CopterControllerTypes controllerTypes);
|
||||||
|
|
||||||
|
bool IsControllerEnabled(CopterControllerTypes controllerType);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
namespace Plane.CopterControllers
|
||||||
|
{
|
||||||
|
public enum SpeedType
|
||||||
|
{
|
||||||
|
SpeedSlow,
|
||||||
|
SpeedFast
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
using Plane.Copters;
|
||||||
|
|
||||||
|
namespace Plane.CopterManagement
|
||||||
|
{
|
||||||
|
public interface ICopterFactory
|
||||||
|
{
|
||||||
|
ICopter CreateBluetoothCopter(string hostName, string name = "GHOSTDRONE");
|
||||||
|
|
||||||
|
IFakeCopter CreateFakeCopter(string id = "FakeCopter", string name = "Linjq's Drone");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
using Plane.Communication;
|
||||||
|
using Plane.Copters;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Plane.CopterManagement
|
||||||
|
{
|
||||||
|
public interface ICopterManager : ICopterActionsSharedByCopterManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取 <see cref="ICopter"/> 实例的动态集合。
|
||||||
|
/// </summary>
|
||||||
|
ObservableCollection<ICopter> AllCopters { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取单个 <see cref="ICopter"/> 实例。用 <see cref="EmptyCopter.Instance"/> 代替 null,使用时不必判断是否为 null。
|
||||||
|
/// </summary>
|
||||||
|
ICopter Copter { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个值,指示是否正在搜寻飞行器。
|
||||||
|
/// </summary>
|
||||||
|
bool IsSearching { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取被选中的 <see cref="ICopter"/> 实例的动态集合。
|
||||||
|
/// </summary>
|
||||||
|
ObservableCollection<ICopter> SelectedCopters { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加或更新 <see cref="ICopter"/> 实例。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">飞行器的唯一 ID。</param>
|
||||||
|
/// <param name="name">飞行器的名字。</param>
|
||||||
|
/// <param name="connection">用于通信的 <see cref="IConnection"/> 实例。</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task AddOrUpdateCopterAsync(string id, string name, IConnection connection);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查飞行器的状态,判断是否允许 FlyTo,若允许,飞往指定位置。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lat">目的地纬度。</param>
|
||||||
|
/// <param name="lng">目的地经度。</param>
|
||||||
|
/// <returns>若允许并执行了 FlyTo,返回 true;否则返回 false。</returns>
|
||||||
|
Task<bool> CheckStatusAndFlyToAsync(double lat, double lng);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 连接一个新的 <see cref="ICopter"/> 实例。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="copter">要连接的 <see cref="ICopter"/> 实例。</param>
|
||||||
|
/// <returns>表示此异步操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task ConnectAsync(ICopter copter);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开始搜索并连接飞行器。
|
||||||
|
/// </summary>
|
||||||
|
void StartSearching();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 停止搜索飞行器。
|
||||||
|
/// </summary>
|
||||||
|
void StopSearching();
|
||||||
|
}
|
||||||
|
}
|
27
PlaneGcsSdk.Contract_Shared/Copters/Constants.cs
Normal file
27
PlaneGcsSdk.Contract_Shared/Copters/Constants.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
public static class Constants
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 最高加速度,单位为 m/s2。
|
||||||
|
/// </summary>
|
||||||
|
public const float MAX_ACCEL = 10f;
|
||||||
|
|
||||||
|
public const ushort MAX_CHANNEL = 1900,
|
||||||
|
MIN_CHANNEL = 1100,
|
||||||
|
MAX_CHANNEL_DELTA = 370,
|
||||||
|
HOVER_CHANNEL = 1500,
|
||||||
|
MAX_HOVER_CHANNEL = MAX_CHANNEL - MAX_CHANNEL_DELTA,
|
||||||
|
MIN_HOVER_CHANNEL = MIN_CHANNEL + MAX_CHANNEL_DELTA;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 飞行过程中的最大倾斜角度。
|
||||||
|
/// </summary>
|
||||||
|
public const float MAX_TILT_IN_FLIGHT = 45;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最高速度,单位为 m/s。
|
||||||
|
/// </summary>
|
||||||
|
public const float MAX_VEL = 5f;
|
||||||
|
}
|
||||||
|
}
|
27
PlaneGcsSdk.Contract_Shared/Copters/CopterCommand.cs
Normal file
27
PlaneGcsSdk.Contract_Shared/Copters/CopterCommand.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
public enum CopterCommand
|
||||||
|
{
|
||||||
|
StartMovingForward,
|
||||||
|
StartMovingBack,
|
||||||
|
StartMovingLeft,
|
||||||
|
StartMovingRight,
|
||||||
|
StartMovingUp,
|
||||||
|
StartMovingDown,
|
||||||
|
StartRotatingAnticlockwise,
|
||||||
|
StartRotatingClockwise,
|
||||||
|
StopMovingForward,
|
||||||
|
StopMovingBack,
|
||||||
|
StopMovingLeft,
|
||||||
|
StopMovingRight,
|
||||||
|
StopMovingUp,
|
||||||
|
StopMovingDown,
|
||||||
|
StopRotatingAnticlockwise,
|
||||||
|
StopRotatingClockwise,
|
||||||
|
Unlock,
|
||||||
|
Lock,
|
||||||
|
TakeOff,
|
||||||
|
ReturnToLaunch,
|
||||||
|
Land
|
||||||
|
}
|
||||||
|
}
|
16
PlaneGcsSdk.Contract_Shared/Copters/CopterState.cs
Normal file
16
PlaneGcsSdk.Contract_Shared/Copters/CopterState.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
public enum CopterState
|
||||||
|
{
|
||||||
|
Locked,
|
||||||
|
Initialized,
|
||||||
|
TakingOff,
|
||||||
|
FloatMode,
|
||||||
|
HoverMode,
|
||||||
|
CommandMode,
|
||||||
|
Circling,
|
||||||
|
Following,
|
||||||
|
Returning,
|
||||||
|
Landing
|
||||||
|
}
|
||||||
|
}
|
38
PlaneGcsSdk.Contract_Shared/Copters/FlightCommand.cs
Normal file
38
PlaneGcsSdk.Contract_Shared/Copters/FlightCommand.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 在自动飞行任务中使用的命令枚举,指定飞行器应执行的动作。
|
||||||
|
/// </summary>
|
||||||
|
public enum FlightCommand : ushort
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 命令飞行器飞往指定位置。
|
||||||
|
/// </summary>
|
||||||
|
Waypoint = 16,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 命令飞行器在指定位置盘旋指定圈数。
|
||||||
|
/// </summary>
|
||||||
|
LoiterTurns = 18,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 命令飞行器在指定位置盘旋指定时间。
|
||||||
|
/// </summary>
|
||||||
|
LoiterTime = 19,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 命令飞行器返航。
|
||||||
|
/// </summary>
|
||||||
|
ReturnToLaunch = 20,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 命令飞行器降落。
|
||||||
|
/// </summary>
|
||||||
|
Land = 21,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 命令飞行器起飞。
|
||||||
|
/// </summary>
|
||||||
|
TakeOff = 22
|
||||||
|
}
|
||||||
|
}
|
17
PlaneGcsSdk.Contract_Shared/Copters/GpsFixType.cs
Normal file
17
PlaneGcsSdk.Contract_Shared/Copters/GpsFixType.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
public enum GpsFixType : byte
|
||||||
|
{
|
||||||
|
NoFix = 0,
|
||||||
|
Fix2D = 2,
|
||||||
|
Fix3D = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ByteExtensions
|
||||||
|
{
|
||||||
|
public static GpsFixType ToGpsFixType(this byte value)
|
||||||
|
{
|
||||||
|
return value == 1 ? GpsFixType.NoFix : (GpsFixType)value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
public class HeartbeatReceivedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public HeartbeatReceivedEventArgs(ulong count)
|
||||||
|
{
|
||||||
|
Count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong Count { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
28
PlaneGcsSdk.Contract_Shared/Copters/IAttitude.cs
Normal file
28
PlaneGcsSdk.Contract_Shared/Copters/IAttitude.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 定义用于获取三维空间中飞行器姿态的属性。
|
||||||
|
/// </summary>
|
||||||
|
public interface IAttitude
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取机头方向,其范围为 [0, 360)。
|
||||||
|
/// </summary>
|
||||||
|
short Heading { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取俯仰角度,其范围为 (-180, 180],正常飞行中的范围为 [-45, 45]。
|
||||||
|
/// </summary>
|
||||||
|
float Pitch { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取横滚角度,其范围为 (-180, 180],正常飞行中的范围为 [-45, 45]。
|
||||||
|
/// </summary>
|
||||||
|
float Roll { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取偏航角度,其范围为 (-180, 180]。
|
||||||
|
/// </summary>
|
||||||
|
float Yaw { get; }
|
||||||
|
}
|
||||||
|
}
|
8
PlaneGcsSdk.Contract_Shared/Copters/ICopter.cs
Normal file
8
PlaneGcsSdk.Contract_Shared/Copters/ICopter.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
public partial interface ICopter : ICopterStatus, ICopterEvents, ICopterActions, ICopterCommunication, INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
124
PlaneGcsSdk.Contract_Shared/Copters/ICopterActions.cs
Normal file
124
PlaneGcsSdk.Contract_Shared/Copters/ICopterActions.cs
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 定义用于操纵飞行器的属性和方法。
|
||||||
|
/// </summary>
|
||||||
|
public partial interface ICopterActions : ICopterActionsSharedByCopterManager, ICopterMissionActions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置目标通道 1。
|
||||||
|
/// </summary>
|
||||||
|
ushort? DesiredChannel1 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置目标通道 2。
|
||||||
|
/// </summary>
|
||||||
|
ushort? DesiredChannel2 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置目标通道 3。
|
||||||
|
/// </summary>
|
||||||
|
ushort? DesiredChannel3 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置目标通道 4。
|
||||||
|
/// </summary>
|
||||||
|
ushort? DesiredChannel4 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置目标通道 5。
|
||||||
|
/// </summary>
|
||||||
|
ushort? DesiredChannel5 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置目标通道 6。
|
||||||
|
/// </summary>
|
||||||
|
ushort? DesiredChannel6 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置目标通道 7。
|
||||||
|
/// </summary>
|
||||||
|
ushort? DesiredChannel7 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置目标通道 8。
|
||||||
|
/// </summary>
|
||||||
|
ushort? DesiredChannel8 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置目标偏航。
|
||||||
|
/// </summary>
|
||||||
|
float? DesiredYaw { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个值,指示飞行器是否正处于紧急悬停状态。
|
||||||
|
/// </summary>
|
||||||
|
bool IsEmergencyHoverActive { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开启与飞行器之间的连接。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>表示此异步操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task ConnectAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 跟随。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="target">目标。</param>
|
||||||
|
/// <param name="keepYawDifference">设为 true 进保持偏航角度差,设为 false 时将保持两者在空间中的相对位置。</param>
|
||||||
|
/// <param name="keepFacingTarget">是否保持机头面对目标。</param>
|
||||||
|
void Follow(IVisibleStatus target, bool keepYawDifference = false, bool keepFacingTarget = true, bool keep3DRelativeLocations = false);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 向飞行器请求数据。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task GetCopterDataAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取参数的值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="paramName">参数名。</param>
|
||||||
|
/// <param name="millisecondsTimeout">超时时间,单位为毫秒。</param>
|
||||||
|
/// <returns>表示参数获取异步操作的 <see cref="Task{TResult}"/>,其结果即为参数的值。</returns>
|
||||||
|
/// <exception cref="System.TimeoutException">操作超时。</exception>
|
||||||
|
Task<float> GetParamAsync(string paramName, int millisecondsTimeout = Timeout.Infinite);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 把所有通道设置为目标值。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task SetChannelsAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用各个目标值属性设置通道和偏航。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task SetMobileControlAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置参数,返回的 <see cref="Task"/> 实例在确认设置成功后完成。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="paramName">参数名。</param>
|
||||||
|
/// <param name="value">值。</param>
|
||||||
|
/// <param name="millisecondsTimeout">超时时间,单位为毫秒。</param>
|
||||||
|
/// <returns>表示异步设置参数操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
/// <exception cref="System.TimeoutException">操作超时。</exception>
|
||||||
|
Task SetParamAsync(string paramName, float value, int millisecondsTimeout = Timeout.Infinite);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开始对频。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task StartPairingAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 停止对频。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task StopPairingAsync();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,130 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
public interface ICopterActionsSharedByCopterManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 断开与飞行器之间的连接。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>表示此异步操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task DisconnectAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 切换到 <see cref="CopterState.FloatMode"/> 并向各个控制通道发中间值。飞行器可能受风等外力影响而在水平方向上飘动。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task FloatAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使飞行器飞往水平面上指定的点。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lat">纬度。</param>
|
||||||
|
/// <param name="lng">经度。</param>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task FlyToAsync(double lat, double lng);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使飞行器飞往指定的点。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lat">纬度。</param>
|
||||||
|
/// <param name="lng">经度。</param>
|
||||||
|
/// <param name="alt">相对于解锁点的高度。</param>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task FlyToAsync(double lat, double lng, float alt);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 切换到 <see cref="CopterState.HoverMode"/> 并悬停。此操作需要使用 GPS 定位,卫星数不足导致定位不准时非常危险。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task HoverAsync();
|
||||||
|
|
||||||
|
Task GuidAsync();
|
||||||
|
/// <summary>
|
||||||
|
/// 降落。此操作需要使用 GPS 定位,卫星数不足导致定位不准时非常危险。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task LandAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 锁定飞行器(停止电机转动)。在调用之前务必判断高度及让软件使用者确认!
|
||||||
|
/// </summary>
|
||||||
|
Task LockAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返航。此操作需要使用 GPS 定位,卫星数不足导致定位不准时非常危险。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task ReturnToLaunchAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用指定的值设置通道。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ch1">通道 1 的目标值。</param>
|
||||||
|
/// <param name="ch2">通道 2 的目标值。</param>
|
||||||
|
/// <param name="ch3">通道 3 的目标值。</param>
|
||||||
|
/// <param name="ch4">通道 4 的目标值。</param>
|
||||||
|
/// <param name="ch5">通道 5 的目标值。</param>
|
||||||
|
/// <param name="ch6">通道 6 的目标值。</param>
|
||||||
|
/// <param name="ch7">通道 7 的目标值。</param>
|
||||||
|
/// <param name="ch8">通道 8 的目标值。</param>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task SetChannelsAsync(ushort? ch1 = null, ushort? ch2 = null, ushort? ch3 = null, ushort? ch4 = null, ushort? ch5 = null, ushort? ch6 = null, ushort? ch7 = null, ushort? ch8 = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用指定的值设置通道和偏航。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ch1">通道 1 的目标值。</param>
|
||||||
|
/// <param name="ch2">通道 2 的目标值。</param>
|
||||||
|
/// <param name="ch3">通道 3 的目标值。</param>
|
||||||
|
/// <param name="ch4">通道 4 的目标值。目前此参数无效(20160119)。</param>
|
||||||
|
/// <param name="ch5">通道 5 的目标值。</param>
|
||||||
|
/// <param name="ch6">通道 6 的目标值。</param>
|
||||||
|
/// <param name="ch7">通道 7 的目标值。</param>
|
||||||
|
/// <param name="ch8">通道 8 的目标值。</param>
|
||||||
|
/// <param name="yaw">偏航的目标值</param>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task SetMobileControlAsync(ushort? ch1 = null, ushort? ch2 = null, ushort? ch3 = null, ushort? ch4 = null, ushort? ch5 = null, ushort? ch6 = null, ushort? ch7 = null, ushort? ch8 = null, float? yaw = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 进入紧急悬停状态。此状态需要使用 GPS 定位,卫星数不足导致定位不准时非常危险。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task StartEmergencyHoverAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开始根据各个目标属性(如 <see cref="DesiredChannel1"/>)控制飞行器。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="millisecondsInterval">发送控制命令的时间间距,若为 null,将由 SDK 决定。</param>
|
||||||
|
void StartMobileControl(int? millisecondsInterval = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 停止紧急悬停。
|
||||||
|
/// </summary>
|
||||||
|
void StopEmergencyHover();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 停止根据各个目标属性(如 <see cref="DesiredChannel1"/>)控制飞行器。
|
||||||
|
/// </summary>
|
||||||
|
void StopMobileControl();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自动起飞到预定高度。此操作需要使用 GPS 定位,卫星数不足导致定位不准时非常危险。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task TakeOffAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自动解锁并起飞到指定高度。此操作需要使用 GPS 定位,卫星数不足导致定位不准时非常危险。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="alt">目标高度。</param>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task TakeOffAsync(float alt);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解锁飞行器。螺旋桨将开始转动,但飞行器不会起飞。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
Task UnlockAsync();
|
||||||
|
}
|
||||||
|
}
|
15
PlaneGcsSdk.Contract_Shared/Copters/ICopterCommunication.cs
Normal file
15
PlaneGcsSdk.Contract_Shared/Copters/ICopterCommunication.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using Plane.Communication;
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 定义与通信相关的属性。
|
||||||
|
/// </summary>
|
||||||
|
public interface ICopterCommunication
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置用于与飞行器通信的 <see cref="IConnection"/> 实例。
|
||||||
|
/// </summary>
|
||||||
|
IConnection Connection { get; set; }
|
||||||
|
}
|
||||||
|
}
|
57
PlaneGcsSdk.Contract_Shared/Copters/ICopterEvents.cs
Normal file
57
PlaneGcsSdk.Contract_Shared/Copters/ICopterEvents.cs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 定义飞行器代理对象的事件。
|
||||||
|
/// </summary>
|
||||||
|
public partial interface ICopterEvents
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 在高度变化时发生。
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler AltitudeChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在姿态变化时发生。
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler AttitudeChanged;
|
||||||
|
|
||||||
|
#if PRIVATE
|
||||||
|
/// <summary>
|
||||||
|
/// 在收到数据流时发生。
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<DataStreamReceivedEventArgs> DataStreamReceived;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在收到心跳时发生。
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<HeartbeatReceivedEventArgs> HeartbeatReceived;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在位置变化时发生。
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler LocationChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在收到自动飞行任务详情时发生。
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<MissionItemReceivedEventArgs> MissionItemReceived;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在对频完成(成功或失败)时发生。
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<PairingCompletedEventArgs> PairingCompleted;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在收到传感器数据时发生。
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler SensorDataReceived;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在收到系统状态信息时发生。
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<SystemStatusReceivedEventArgs> SystemStatusReceived;
|
||||||
|
}
|
||||||
|
}
|
23
PlaneGcsSdk.Contract_Shared/Copters/ICopterMissionActions.cs
Normal file
23
PlaneGcsSdk.Contract_Shared/Copters/ICopterMissionActions.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
public interface ICopterMissionActions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 查询任务序列。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="millisecondsTimeout">超时时间。</param>
|
||||||
|
/// <returns>飞行器返回的任务序列。</returns>
|
||||||
|
Task<IEnumerable<IMission>> RequestMissionListAsync(int millisecondsTimeout = 10000);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 写入任务序列。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="missions">任务序列。</param>
|
||||||
|
/// <param name="millisecondsTimeout">超时时间。</param>
|
||||||
|
/// <returns>若写入成功,返回 true;否则返回 false。</returns>
|
||||||
|
Task<bool> WriteMissionListAsync(IEnumerable<IMission> missions, int millisecondsTimeout = 10000);
|
||||||
|
}
|
||||||
|
}
|
176
PlaneGcsSdk.Contract_Shared/Copters/ICopterStatus.cs
Normal file
176
PlaneGcsSdk.Contract_Shared/Copters/ICopterStatus.cs
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
using Plane.Geography;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 定义用于获取飞行器状态的属性。
|
||||||
|
/// </summary>
|
||||||
|
public partial interface ICopterStatus : IVisibleStatus
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前空速,单位为 m/s。
|
||||||
|
/// </summary>
|
||||||
|
float AirSpeed { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取剩余电量百分比,其范围为 [0, 100]。
|
||||||
|
/// </summary>
|
||||||
|
byte BatteryPer { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取通道 1 的值。该值在飞控中用于改变飞行器横滚姿态,从而控制其左右方向的移动。有效范围为 [1100, 1900]。小于 1500 时使飞行器向左倾斜,大于 1500 时使飞行器向右倾斜。
|
||||||
|
/// </summary>
|
||||||
|
ushort Channel1 { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取通道 2 的值。该值在飞控中用于改变飞行器俯仰姿态,从而控制其前后方向的移动。有效范围为 [1100, 1900]。小于 1500 时使飞行器向前倾斜,大于 1500 时使飞行器向后倾斜。
|
||||||
|
/// </summary>
|
||||||
|
ushort Channel2 { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取通道 3 的值。该值在飞控中用于改变飞行器油门,从而控制其上下方向的移动。有效范围为 [1100, 1900]。在能够定高的模式(如 ALT_HOLD、LOITER)下,小于 1500 时使飞行器下降,大于 1500 时使飞行器上升。
|
||||||
|
/// </summary>
|
||||||
|
ushort Channel3 { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取通道 4 的值。该值在飞控中用于使飞行器改变机头方向。有效范围为 [1100, 1900]。小于 1500 时使飞行器逆时针旋转,大于 1500 时使飞行器顺时针旋转。
|
||||||
|
/// </summary>
|
||||||
|
ushort Channel4 { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取通道 5 的值。其作用未定义。
|
||||||
|
/// </summary>
|
||||||
|
ushort Channel5 { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取通道 6 的值。该值在飞控中用于控制相机正对的方向。有效范围为 [1100, 1900]。小于 1500 时使相机逆时针旋转,大于 1500 时使相机顺时针旋转。
|
||||||
|
/// </summary>
|
||||||
|
ushort Channel6 { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取通道 7 的值。该值在飞控中用于控制相机俯仰姿态。有效范围为 [1100, 1900]。小于 1500 时使相机向后旋转,大于 1500 时使相机向前旋转。
|
||||||
|
/// </summary>
|
||||||
|
ushort Channel7 { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取通道 8 的值。其作用未定义。
|
||||||
|
/// </summary>
|
||||||
|
ushort Channel8 { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取海拔。
|
||||||
|
/// </summary>
|
||||||
|
float Elevation { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取固件版本。
|
||||||
|
/// </summary>
|
||||||
|
int? FirmwareVersion { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取固件版本的文本形式。
|
||||||
|
/// </summary>
|
||||||
|
string FirmwareVersionText { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取在三维空间中的飞行距离。
|
||||||
|
/// </summary>
|
||||||
|
double FlightDistance { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取在水平面上的飞行距离。
|
||||||
|
/// </summary>
|
||||||
|
double FlightDistance2D { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取飞行时间。
|
||||||
|
/// </summary>
|
||||||
|
TimeSpan FlightTimeSpan { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取 GPS 锁定状态。
|
||||||
|
/// </summary>
|
||||||
|
GpsFixType GpsFixType { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取 GPS HDOP(horizontal dilution of position),单位为米。
|
||||||
|
/// </summary>
|
||||||
|
float GpsHdop { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前地速,单位为 m/s。
|
||||||
|
/// </summary>
|
||||||
|
float GroundSpeed { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个值,指示是否切过 GPS 模式。
|
||||||
|
/// </summary>
|
||||||
|
bool HasSwitchedToGpsMode { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取收到心跳的总数。
|
||||||
|
/// </summary>
|
||||||
|
ulong HeartbeatCount { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取飞行器的标识。
|
||||||
|
/// </summary>
|
||||||
|
string Id { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个值,指示是否确定飞行器与地面站正常连接。在实现中,一般根据对心跳包的接收情况判断。
|
||||||
|
/// </summary>
|
||||||
|
bool IsAbsolutelyConnected { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个值,指示是否正在检查飞行器与地面站的连接以确定通信正常。在实现中,一般在建立连接后设为 true,在收到飞行器发回的数据后设为 false。
|
||||||
|
/// </summary>
|
||||||
|
bool IsCheckingConnection { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个值,指示飞行器与地面站之间的连接是否正常。
|
||||||
|
/// </summary>
|
||||||
|
bool IsConnected { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个值,指示当前的 GPS 定位是否足够精确。
|
||||||
|
/// </summary>
|
||||||
|
bool IsGpsAccurate { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个值,指示飞行器是否已解锁。
|
||||||
|
/// </summary>
|
||||||
|
bool IsUnlocked { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取任务总数。
|
||||||
|
/// </summary>
|
||||||
|
ushort? MissionCount { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取飞行器的 GPS 卫星数。
|
||||||
|
/// </summary>
|
||||||
|
byte SatCount { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前所处状态。
|
||||||
|
/// </summary>
|
||||||
|
CopterState State { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取飞控发回的消息,如起飞失败原因。
|
||||||
|
/// </summary>
|
||||||
|
string StatusText { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取起飞点。
|
||||||
|
/// </summary>
|
||||||
|
ILocation TakeOffPoint { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前电池电压,单位为伏特。
|
||||||
|
/// </summary>
|
||||||
|
float Voltage { get; }
|
||||||
|
}
|
||||||
|
}
|
27
PlaneGcsSdk.Contract_Shared/Copters/IFakeCopter.cs
Normal file
27
PlaneGcsSdk.Contract_Shared/Copters/IFakeCopter.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 包含 <see cref="ICopter"/> 的所有功能,并提供用于模拟和调试的额外方法。
|
||||||
|
/// </summary>
|
||||||
|
public interface IFakeCopter : ICopter
|
||||||
|
{
|
||||||
|
void SetProperties(
|
||||||
|
string id = null, //"Junqing's Drone",
|
||||||
|
double? latitude = null, //23.14973333,
|
||||||
|
double? longitude = null, //113.40974166,
|
||||||
|
float? altitude = null, //0,
|
||||||
|
string name = null, //"林俊清的飞行器",
|
||||||
|
byte? batteryPer = null, //10,
|
||||||
|
short? heading = null, //33,
|
||||||
|
bool? isConnected = null, //true,
|
||||||
|
float? pitch = null, //-70,
|
||||||
|
float? roll = null, //28,
|
||||||
|
byte? satCount = null, //6,
|
||||||
|
float? groundSpeed = null, //3.333,
|
||||||
|
double? flightDistance = null, //100.388,
|
||||||
|
double? flightDistance2D = null, // 100.88,
|
||||||
|
TimeSpan? flightTimeSpan = null);
|
||||||
|
}
|
||||||
|
}
|
53
PlaneGcsSdk.Contract_Shared/Copters/IMission.cs
Normal file
53
PlaneGcsSdk.Contract_Shared/Copters/IMission.cs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 定义自动飞行任务的属性。
|
||||||
|
/// </summary>
|
||||||
|
public interface IMission
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置相对于起飞点的高度。
|
||||||
|
/// </summary>
|
||||||
|
float Altitude { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置飞行命令。
|
||||||
|
/// </summary>
|
||||||
|
FlightCommand Command { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置纬度。
|
||||||
|
/// </summary>
|
||||||
|
double Latitude { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置经度。
|
||||||
|
/// </summary>
|
||||||
|
double Longitude { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置参数 1。通常用来指定判断为到达的最大半径,单位为米。
|
||||||
|
/// </summary>
|
||||||
|
float Param1 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置参数 2。通常用来指定停留时间,单位为毫秒。
|
||||||
|
/// </summary>
|
||||||
|
float Param2 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置参数 3。通常用来指定盘旋半径,单位为米,正数表示顺时针,负数表示逆时针。
|
||||||
|
/// </summary>
|
||||||
|
float Param3 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置参数 4。通常用来指定机头方向,单位为角度,北方为 0,东方为 90,范围为 [0, 360)。
|
||||||
|
/// </summary>
|
||||||
|
float Param4 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置序号。
|
||||||
|
/// </summary>
|
||||||
|
ushort Sequence { get; set; }
|
||||||
|
}
|
||||||
|
}
|
15
PlaneGcsSdk.Contract_Shared/Copters/IVisibleStatus.cs
Normal file
15
PlaneGcsSdk.Contract_Shared/Copters/IVisibleStatus.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using Plane.Geography;
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 定义物体可见的状态。
|
||||||
|
/// </summary>
|
||||||
|
public interface IVisibleStatus : ILocation, IAttitude
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取名称。
|
||||||
|
/// </summary>
|
||||||
|
string Name { get; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
public class MessageCreatedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public string Message { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
public class MissionItemReceivedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public MissionItemReceivedEventArgs(IMission mission)
|
||||||
|
{
|
||||||
|
Mission = mission;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取任务详情。
|
||||||
|
/// </summary>
|
||||||
|
public IMission Mission { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
414
PlaneGcsSdk.Contract_Shared/Copters/PLObservableObject.cs
Normal file
414
PlaneGcsSdk.Contract_Shared/Copters/PLObservableObject.cs
Normal file
@ -0,0 +1,414 @@
|
|||||||
|
#define CMNATTR
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
|
||||||
|
// ReSharper disable RedundantUsingDirective
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
// ReSharper restore RedundantUsingDirective
|
||||||
|
|
||||||
|
#if CMNATTR
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A base class for objects of which the properties must be observable (based on MvvmLight's ObservableObject).
|
||||||
|
/// </summary>
|
||||||
|
//// [ClassInfo(typeof(ViewModelBase))]
|
||||||
|
public class PLObservableObject : INotifyPropertyChanged /*, INotifyPropertyChanging*/
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 与 UI 线程关联的 <see cref="SynchronizationContext"/> 实例。
|
||||||
|
/// </summary>
|
||||||
|
protected SynchronizationContext _uiSyncContext;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建 <see cref="EHObservableObject"/> 的实例。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uiSyncContext"></param>
|
||||||
|
public PLObservableObject(SynchronizationContext uiSyncContext)
|
||||||
|
{
|
||||||
|
_uiSyncContext = uiSyncContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs after a property value changes.
|
||||||
|
/// </summary>
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides access to the PropertyChanged event handler to derived classes.
|
||||||
|
/// </summary>
|
||||||
|
protected PropertyChangedEventHandler PropertyChangedHandler
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return PropertyChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !PORTABLE && !SL4 && !WINDOWS_UWP
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs before a property value changes.
|
||||||
|
/// </summary>
|
||||||
|
public event PropertyChangingEventHandler PropertyChanging;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides access to the PropertyChanging event handler to derived classes.
|
||||||
|
/// </summary>
|
||||||
|
protected PropertyChangingEventHandler PropertyChangingHandler
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return PropertyChanging;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that a property name exists in this ViewModel. This method
|
||||||
|
/// can be called before the property is used, for instance before
|
||||||
|
/// calling RaisePropertyChanged. It avoids errors when a property name
|
||||||
|
/// is changed but some places are missed.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>This method is only active in DEBUG mode.</remarks>
|
||||||
|
/// <param name="propertyName">The name of the property that will be
|
||||||
|
/// checked.</param>
|
||||||
|
[Conditional("DEBUG")]
|
||||||
|
[DebuggerStepThrough]
|
||||||
|
public void VerifyPropertyName(string propertyName)
|
||||||
|
{
|
||||||
|
var myType = GetType();
|
||||||
|
|
||||||
|
#if NETFX_CORE
|
||||||
|
if (!string.IsNullOrEmpty(propertyName)
|
||||||
|
&& myType.GetRuntimeProperty(propertyName) == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Property not found", propertyName);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (!string.IsNullOrEmpty(propertyName)
|
||||||
|
&& myType.GetProperty(propertyName) == null)
|
||||||
|
{
|
||||||
|
#if !SILVERLIGHT
|
||||||
|
var descriptor = this as ICustomTypeDescriptor;
|
||||||
|
|
||||||
|
if (descriptor != null)
|
||||||
|
{
|
||||||
|
if (descriptor.GetProperties()
|
||||||
|
.Cast<PropertyDescriptor>()
|
||||||
|
.Any(property => property.Name == propertyName))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
throw new ArgumentException("Property not found", propertyName);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !PORTABLE && !SL4 && !WINDOWS_UWP
|
||||||
|
#if CMNATTR
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the PropertyChanging event if needed.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>If the propertyName parameter
|
||||||
|
/// does not correspond to an existing property on the current class, an
|
||||||
|
/// exception is thrown in DEBUG configuration only.</remarks>
|
||||||
|
/// <param name="propertyName">(optional) The name of the property that
|
||||||
|
/// changed.</param>
|
||||||
|
[SuppressMessage(
|
||||||
|
"Microsoft.Design",
|
||||||
|
"CA1030:UseEventsWhereAppropriate",
|
||||||
|
Justification = "This cannot be an event")]
|
||||||
|
protected virtual void RaisePropertyChanging(
|
||||||
|
[CallerMemberName] string propertyName = null)
|
||||||
|
#else
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the PropertyChanging event if needed.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>If the propertyName parameter
|
||||||
|
/// does not correspond to an existing property on the current class, an
|
||||||
|
/// exception is thrown in DEBUG configuration only.</remarks>
|
||||||
|
/// <param name="propertyName">The name of the property that
|
||||||
|
/// changed.</param>
|
||||||
|
[SuppressMessage(
|
||||||
|
"Microsoft.Design",
|
||||||
|
"CA1030:UseEventsWhereAppropriate",
|
||||||
|
Justification = "This cannot be an event")]
|
||||||
|
protected virtual void RaisePropertyChanging(
|
||||||
|
string propertyName)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
VerifyPropertyName(propertyName);
|
||||||
|
|
||||||
|
var handler = PropertyChanging;
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
handler(this, new PropertyChangingEventArgs(propertyName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CMNATTR
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the PropertyChanged event if needed.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>If the propertyName parameter
|
||||||
|
/// does not correspond to an existing property on the current class, an
|
||||||
|
/// exception is thrown in DEBUG configuration only.</remarks>
|
||||||
|
/// <param name="propertyName">(optional) The name of the property that
|
||||||
|
/// changed.</param>
|
||||||
|
[SuppressMessage(
|
||||||
|
"Microsoft.Design",
|
||||||
|
"CA1030:UseEventsWhereAppropriate",
|
||||||
|
Justification = "This cannot be an event")]
|
||||||
|
protected virtual void RaisePropertyChanged(
|
||||||
|
[CallerMemberName] string propertyName = null)
|
||||||
|
#else
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the PropertyChanged event if needed.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>If the propertyName parameter
|
||||||
|
/// does not correspond to an existing property on the current class, an
|
||||||
|
/// exception is thrown in DEBUG configuration only.</remarks>
|
||||||
|
/// <param name="propertyName">The name of the property that
|
||||||
|
/// changed.</param>
|
||||||
|
[SuppressMessage(
|
||||||
|
"Microsoft.Design",
|
||||||
|
"CA1030:UseEventsWhereAppropriate",
|
||||||
|
Justification = "This cannot be an event")]
|
||||||
|
protected virtual void RaisePropertyChanged(
|
||||||
|
string propertyName)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
VerifyPropertyName(propertyName);
|
||||||
|
|
||||||
|
var handler = PropertyChanged;
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
#if NETFX_CORE
|
||||||
|
var e = new PropertyChangedEventArgs(propertyName);
|
||||||
|
if (SynchronizationContext.Current == _uiSyncContext) handler(this, e);
|
||||||
|
else _uiSyncContext.Post(() => handler(this, e));
|
||||||
|
#else
|
||||||
|
handler(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !PORTABLE && !SL4 && !WINDOWS_UWP
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the PropertyChanging event if needed.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of the property that
|
||||||
|
/// changes.</typeparam>
|
||||||
|
/// <param name="propertyExpression">An expression identifying the property
|
||||||
|
/// that changes.</param>
|
||||||
|
[SuppressMessage(
|
||||||
|
"Microsoft.Design",
|
||||||
|
"CA1030:UseEventsWhereAppropriate",
|
||||||
|
Justification = "This cannot be an event")]
|
||||||
|
[SuppressMessage(
|
||||||
|
"Microsoft.Design",
|
||||||
|
"CA1006:GenericMethodsShouldProvideTypeParameter",
|
||||||
|
Justification = "This syntax is more convenient than other alternatives.")]
|
||||||
|
protected virtual void RaisePropertyChanging<T>(Expression<Func<T>> propertyExpression)
|
||||||
|
{
|
||||||
|
var handler = PropertyChanging;
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
var propertyName = GetPropertyName(propertyExpression);
|
||||||
|
handler(this, new PropertyChangingEventArgs(propertyName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the PropertyChanged event if needed.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of the property that
|
||||||
|
/// changed.</typeparam>
|
||||||
|
/// <param name="propertyExpression">An expression identifying the property
|
||||||
|
/// that changed.</param>
|
||||||
|
[SuppressMessage(
|
||||||
|
"Microsoft.Design",
|
||||||
|
"CA1030:UseEventsWhereAppropriate",
|
||||||
|
Justification = "This cannot be an event")]
|
||||||
|
[SuppressMessage(
|
||||||
|
"Microsoft.Design",
|
||||||
|
"CA1006:GenericMethodsShouldProvideTypeParameter",
|
||||||
|
Justification = "This syntax is more convenient than other alternatives.")]
|
||||||
|
protected virtual void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression)
|
||||||
|
{
|
||||||
|
var handler = PropertyChanged;
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
var propertyName = GetPropertyName(propertyExpression);
|
||||||
|
#if NETFX_CORE
|
||||||
|
var e = new PropertyChangedEventArgs(propertyName);
|
||||||
|
if (SynchronizationContext.Current == _uiSyncContext) handler(this, e);
|
||||||
|
else _uiSyncContext.Post(() => handler(this, e));
|
||||||
|
#else
|
||||||
|
handler(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extracts the name of a property from an expression.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of the property.</typeparam>
|
||||||
|
/// <param name="propertyExpression">An expression returning the property's name.</param>
|
||||||
|
/// <returns>The name of the property returned by the expression.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException">If the expression is null.</exception>
|
||||||
|
/// <exception cref="ArgumentException">If the expression does not represent a property.</exception>
|
||||||
|
[SuppressMessage(
|
||||||
|
"Microsoft.Design",
|
||||||
|
"CA1011:ConsiderPassingBaseTypesAsParameters",
|
||||||
|
Justification = "This syntax is more convenient than the alternatives."),
|
||||||
|
SuppressMessage(
|
||||||
|
"Microsoft.Design",
|
||||||
|
"CA1006:DoNotNestGenericTypesInMemberSignatures",
|
||||||
|
Justification = "This syntax is more convenient than the alternatives.")]
|
||||||
|
protected static string GetPropertyName<T>(Expression<Func<T>> propertyExpression)
|
||||||
|
{
|
||||||
|
if (propertyExpression == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("propertyExpression");
|
||||||
|
}
|
||||||
|
|
||||||
|
var body = propertyExpression.Body as MemberExpression;
|
||||||
|
|
||||||
|
if (body == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Invalid argument", "propertyExpression");
|
||||||
|
}
|
||||||
|
|
||||||
|
var property = body.Member as PropertyInfo;
|
||||||
|
|
||||||
|
if (property == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Argument is not a property", "propertyExpression");
|
||||||
|
}
|
||||||
|
|
||||||
|
return property.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Assigns a new value to the property. Then, raises the
|
||||||
|
/// PropertyChanged event if needed.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of the property that
|
||||||
|
/// changed.</typeparam>
|
||||||
|
/// <param name="propertyExpression">An expression identifying the property
|
||||||
|
/// that changed.</param>
|
||||||
|
/// <param name="field">The field storing the property's value.</param>
|
||||||
|
/// <param name="newValue">The property's value after the change
|
||||||
|
/// occurred.</param>
|
||||||
|
/// <returns>True if the PropertyChanged event has been raised,
|
||||||
|
/// false otherwise. The event is not raised if the old
|
||||||
|
/// value is equal to the new value.</returns>
|
||||||
|
[SuppressMessage(
|
||||||
|
"Microsoft.Design",
|
||||||
|
"CA1006:DoNotNestGenericTypesInMemberSignatures",
|
||||||
|
Justification = "This syntax is more convenient than the alternatives."),
|
||||||
|
SuppressMessage(
|
||||||
|
"Microsoft.Design",
|
||||||
|
"CA1045:DoNotPassTypesByReference",
|
||||||
|
MessageId = "1#",
|
||||||
|
Justification = "This syntax is more convenient than the alternatives.")]
|
||||||
|
protected bool Set<T>(
|
||||||
|
Expression<Func<T>> propertyExpression,
|
||||||
|
ref T field,
|
||||||
|
T newValue)
|
||||||
|
{
|
||||||
|
if (EqualityComparer<T>.Default.Equals(field, newValue))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !PORTABLE && !SL4 && !WINDOWS_UWP
|
||||||
|
RaisePropertyChanging(propertyExpression);
|
||||||
|
#endif
|
||||||
|
field = newValue;
|
||||||
|
RaisePropertyChanged(propertyExpression);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Assigns a new value to the property. Then, raises the
|
||||||
|
/// PropertyChanged event if needed.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of the property that
|
||||||
|
/// changed.</typeparam>
|
||||||
|
/// <param name="propertyName">The name of the property that
|
||||||
|
/// changed.</param>
|
||||||
|
/// <param name="field">The field storing the property's value.</param>
|
||||||
|
/// <param name="newValue">The property's value after the change
|
||||||
|
/// occurred.</param>
|
||||||
|
/// <returns>True if the PropertyChanged event has been raised,
|
||||||
|
/// false otherwise. The event is not raised if the old
|
||||||
|
/// value is equal to the new value.</returns>
|
||||||
|
[SuppressMessage(
|
||||||
|
"Microsoft.Design",
|
||||||
|
"CA1045:DoNotPassTypesByReference",
|
||||||
|
MessageId = "1#",
|
||||||
|
Justification = "This syntax is more convenient than the alternatives.")]
|
||||||
|
protected bool Set<T>(
|
||||||
|
string propertyName,
|
||||||
|
ref T field,
|
||||||
|
T newValue)
|
||||||
|
{
|
||||||
|
if (EqualityComparer<T>.Default.Equals(field, newValue))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !PORTABLE && !SL4 && !WINDOWS_UWP
|
||||||
|
RaisePropertyChanging(propertyName);
|
||||||
|
#endif
|
||||||
|
field = newValue;
|
||||||
|
|
||||||
|
// ReSharper disable ExplicitCallerInfoArgument
|
||||||
|
RaisePropertyChanged(propertyName);
|
||||||
|
// ReSharper restore ExplicitCallerInfoArgument
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CMNATTR
|
||||||
|
/// <summary>
|
||||||
|
/// Assigns a new value to the property. Then, raises the
|
||||||
|
/// PropertyChanged event if needed.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of the property that
|
||||||
|
/// changed.</typeparam>
|
||||||
|
/// <param name="field">The field storing the property's value.</param>
|
||||||
|
/// <param name="newValue">The property's value after the change
|
||||||
|
/// occurred.</param>
|
||||||
|
/// <param name="propertyName">(optional) The name of the property that
|
||||||
|
/// changed.</param>
|
||||||
|
/// <returns>True if the PropertyChanged event has been raised,
|
||||||
|
/// false otherwise. The event is not raised if the old
|
||||||
|
/// value is equal to the new value.</returns>
|
||||||
|
protected bool Set<T>(
|
||||||
|
ref T field,
|
||||||
|
T newValue,
|
||||||
|
[CallerMemberName] string propertyName = null)
|
||||||
|
{
|
||||||
|
return Set(propertyName, ref field, newValue);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
public class PairingCompletedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public PairingCompletedEventArgs(bool isSuccessful, int rxId, int txId)
|
||||||
|
{
|
||||||
|
IsSuccessful = isSuccessful;
|
||||||
|
RxID = rxId;
|
||||||
|
TxID = txId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsSuccessful { get; set; }
|
||||||
|
|
||||||
|
public int RxID { get; set; }
|
||||||
|
|
||||||
|
public int TxID { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
public class SystemStatusReceivedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public SystemStatusReceivedEventArgs(bool gpsBadHealth, bool gyroBadHealth, bool accelBadHealth, bool compassBadHealth, bool barometerBadHealth)
|
||||||
|
{
|
||||||
|
GpsBadHealth = gpsBadHealth;
|
||||||
|
GyroBadHealth = gyroBadHealth;
|
||||||
|
AccelBadHealth = accelBadHealth;
|
||||||
|
CompassBadHealth = compassBadHealth;
|
||||||
|
BarometerBadHealth = barometerBadHealth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AccelBadHealth { get; private set; }
|
||||||
|
|
||||||
|
public bool BarometerBadHealth { get; private set; }
|
||||||
|
|
||||||
|
public bool CompassBadHealth { get; private set; }
|
||||||
|
|
||||||
|
public bool GpsBadHealth { get; private set; }
|
||||||
|
|
||||||
|
public bool GyroBadHealth { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
23
PlaneGcsSdk.Contract_Shared/Copters/VisibleStatus.cs
Normal file
23
PlaneGcsSdk.Contract_Shared/Copters/VisibleStatus.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using Plane.Geography;
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
public class VisibleStatus : IVisibleStatus
|
||||||
|
{
|
||||||
|
public float Altitude { get; set; }
|
||||||
|
|
||||||
|
public short Heading => (short)Yaw.NormalizeDirection();
|
||||||
|
|
||||||
|
public double Latitude { get; set; }
|
||||||
|
|
||||||
|
public double Longitude { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public float Pitch { get; set; }
|
||||||
|
|
||||||
|
public float Roll { get; set; }
|
||||||
|
|
||||||
|
public float Yaw { get; set; }
|
||||||
|
}
|
||||||
|
}
|
301
PlaneGcsSdk.Contract_Shared/Geography/GeographyUtils.cs
Normal file
301
PlaneGcsSdk.Contract_Shared/Geography/GeographyUtils.cs
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Plane.Geography
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 提供地理相关计算的方法。
|
||||||
|
/// </summary>
|
||||||
|
public static class GeographyUtils
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 米数转换为纬度跨度时需要乘的常数。
|
||||||
|
/// </summary>
|
||||||
|
public const double METERS_TO_LAT_SPAN = 1 / (GLOBE_CIRCUMFERENCE / 360);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 角度转换为弧度时需要乘的常数。
|
||||||
|
/// </summary>
|
||||||
|
private const double DEG_TO_RAD = Math.PI / 180;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 地球的半径。
|
||||||
|
/// </summary>
|
||||||
|
private const double EARTH_RADIUS = 6371000;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前星球的周长。
|
||||||
|
/// </summary>
|
||||||
|
private const double GLOBE_CIRCUMFERENCE = GLOBE_RADIUS * 2 * Math.PI;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前星球的半径。
|
||||||
|
/// </summary>
|
||||||
|
private const double GLOBE_RADIUS = EARTH_RADIUS;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算从 (lat1, lng1) 到 (lat2, lng2) 的方向,单位为弧度。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lat1">第一个点的纬度。</param>
|
||||||
|
/// <param name="lng1">第一个点的经度。</param>
|
||||||
|
/// <param name="lat2">第二个点的纬度。</param>
|
||||||
|
/// <param name="lng2">第二个点的经度。</param>
|
||||||
|
/// <returns>点 1 到点 2 的方向。</returns>
|
||||||
|
public static double CalcDirection2D(double lat1, double lng1, double lat2, double lng2)
|
||||||
|
{
|
||||||
|
return Math.Atan2((lng2 - lng1) / CalcMetersToLngSpan(lat1), (lat2 - lat1) / METERS_TO_LAT_SPAN).NormalizeDirectionRad();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算空间中两点间的距离,单位为米。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="l1">点 1。</param>
|
||||||
|
/// <param name="l2">点 2。</param>
|
||||||
|
/// <returns>空间中两点间的距离,单位为米。</returns>
|
||||||
|
public static double CalcDistance(ILocation l1, ILocation l2)
|
||||||
|
{
|
||||||
|
return CalcDistance(l1.Latitude, l1.Longitude, l1.Altitude, l2.Latitude, l2.Longitude, l2.Altitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算空间中两点之间的距离,单位为米。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lat1">纬度 1。</param>
|
||||||
|
/// <param name="lng1">经度 1。</param>
|
||||||
|
/// <param name="alt1">高度 1。</param>
|
||||||
|
/// <param name="lat2">纬度 2。</param>
|
||||||
|
/// <param name="lng2">经度 2。</param>
|
||||||
|
/// <param name="alt2">高度 2。</param>
|
||||||
|
/// <returns>空间中两点之间的距离,单位为米。</returns>
|
||||||
|
public static double CalcDistance(double lat1, double lng1, double alt1, double lat2, double lng2, double alt2)
|
||||||
|
{
|
||||||
|
// generally used geo measurement function
|
||||||
|
// var R = 6378.137; // Radius of earth in KM
|
||||||
|
|
||||||
|
var dLat = (lat2 - lat1) * Math.PI / 180;
|
||||||
|
var dLon = (lng2 - lng1) * Math.PI / 180;
|
||||||
|
var a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2)
|
||||||
|
+ Math.Cos(lat1 * Math.PI / 180) * Math.Cos(lat2 * Math.PI / 180) * Math.Sin(dLon / 2) * Math.Sin(dLon / 2);
|
||||||
|
var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
|
||||||
|
var d = GLOBE_RADIUS * c;
|
||||||
|
return Math.Sqrt(Math.Pow((alt2 - alt1), 2) + Math.Pow(d, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算二维平面上两个位置之间的距离,单位为米。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="l1">位置 1。</param>
|
||||||
|
/// <param name="l2">位置 2。</param>
|
||||||
|
/// <returns>空间中两点间的距离。</returns>
|
||||||
|
public static double CalcDistance2D(ILocation2D l1, ILocation2D l2)
|
||||||
|
=> CalcDistance2D(l1.Latitude, l1.Longitude, l2.Latitude, l2.Longitude);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算二维平面上两个位置之间的距离,单位为米。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lat1">纬度 1。</param>
|
||||||
|
/// <param name="lng1">经度 1。</param>
|
||||||
|
/// <param name="lat2">纬度 2。</param>
|
||||||
|
/// <param name="lng2">经度 2。</param>
|
||||||
|
/// <returns>计算二维平面上两个位置之间的距离,单位为米。</returns>
|
||||||
|
public static double CalcDistance2D(double lat1, double lng1, double lat2, double lng2)
|
||||||
|
=> CalcDistance(lat1, lng1, 0, lat2, lng2, 0);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算在水平面上从指定点往指定方向移动指定距离后所在的点。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lat1">出发点的纬度。</param>
|
||||||
|
/// <param name="lng1">出发点的经度。</param>
|
||||||
|
/// <param name="directionDegrees">移动方向,单位为角度。</param>
|
||||||
|
/// <param name="distance">移动距离。</param>
|
||||||
|
/// <returns>从指定点往指定方向移动指定距离后所在的点。</returns>
|
||||||
|
public static Tuple<double, double> CalcLatLngSomeMetersAway2D(double lat1, double lng1, float directionDegrees, float distance)
|
||||||
|
{
|
||||||
|
var direction = directionDegrees.DegToRad();
|
||||||
|
return Tuple.Create(
|
||||||
|
lat1 + distance * Math.Cos(direction) * METERS_TO_LAT_SPAN,
|
||||||
|
lng1 + distance * Math.Sin(direction) * CalcMetersToLngSpan(lat1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算在水平面上从指定点往指定方向移动指定距离后所在的点。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="loc1">出发点。</param>
|
||||||
|
/// <param name="directionDegrees">移动方向,单位为角度。</param>
|
||||||
|
/// <param name="distance">移动距离。</param>
|
||||||
|
/// <returns>从指定点往指定方向移动指定距离后所在的点。</returns>
|
||||||
|
public static ILocation2D CalcLatLngSomeMetersAway2D(ILocation2D loc1, float directionDegrees, float distance)
|
||||||
|
{
|
||||||
|
var direction = directionDegrees.DegToRad();
|
||||||
|
return new PLLocation(
|
||||||
|
loc1.Latitude + distance * Math.Cos(direction) * METERS_TO_LAT_SPAN,
|
||||||
|
loc1.Longitude + distance * Math.Sin(direction) * CalcMetersToLngSpan(loc1.Latitude),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算在指定纬度上,米数转换为经度跨度时需要乘的值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="latitude">纬度。</param>
|
||||||
|
/// <returns>在指定纬度上,米数转换为经度跨度时需要乘的值。</returns>
|
||||||
|
public static double CalcMetersToLngSpan(double latitude)
|
||||||
|
{
|
||||||
|
return METERS_TO_LAT_SPAN / Math.Cos(latitude * DEG_TO_RAD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检测同一水平面上(忽略高度)的两条线段是否相交。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="l1">线段 A 端点 1。</param>
|
||||||
|
/// <param name="l2">线段 A 端点 2。</param>
|
||||||
|
/// <param name="l3">线段 B 端点 1。</param>
|
||||||
|
/// <param name="l4">线段 B 端点 2。</param>
|
||||||
|
/// <returns>若相交,返回 true;否则返回 false。</returns>
|
||||||
|
public static bool CheckCrossing2D(ILocation2D l1, ILocation2D l2, ILocation2D l3, ILocation2D l4)
|
||||||
|
=> CheckCrossing2D(l1.Latitude, l1.Longitude, l2.Latitude, l2.Longitude, l3.Latitude, l3.Longitude, l4.Latitude, l4.Longitude);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检测同一水平面上的两条线段是否相交。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="latA1">线段 A 端点 1 的纬度。</param>
|
||||||
|
/// <param name="lngA1">线段 A 端点 1 的经度。</param>
|
||||||
|
/// <param name="latA2">线段 A 端点 2 的纬度。</param>
|
||||||
|
/// <param name="lngA2">线段 A 端点 2 的经度。</param>
|
||||||
|
/// <param name="latB1">线段 B 端点 1 的纬度。</param>
|
||||||
|
/// <param name="lngB1">线段 B 端点 1 的经度。</param>
|
||||||
|
/// <param name="latB2">线段 B 端点 2 的纬度。</param>
|
||||||
|
/// <param name="lngB2">线段 B 端点 2 的经度。</param>
|
||||||
|
/// <returns>若相交,返回 true;否则返回 false。</returns>
|
||||||
|
public static bool CheckCrossing2D(double latA1, double lngA1, double latA2, double lngA2,
|
||||||
|
double latB1, double lngB1, double latB2, double lngB2)
|
||||||
|
{
|
||||||
|
// 线段 A(x1, y1) - B(x2, y2), 所在直线 L1 方程为 F(x, y) = 0;
|
||||||
|
// 线段 C(x3, y3) - D(x4, y4), 所在直线 L2 方程为 G(x, y) = 0;
|
||||||
|
// 思路:
|
||||||
|
// (即问题的充要条件)
|
||||||
|
// (点 A 与点 B 在直线 L2 两侧) AND (点 C 与点 D 在直线 L1 两侧);
|
||||||
|
// 方法:
|
||||||
|
// 如果点 P(Xp, Yp) 不在直线 a * x + b * y + c = 0 上, 则 a* Xp + b * Yp + c <> 0;
|
||||||
|
// 如果用两个点的坐标代入同一直线方程 a * x + b * y + c 计算出的值异号, 则两点在直线两侧;
|
||||||
|
// 解法:
|
||||||
|
// (G(x1, y1) * G(x2, y2) < 0) AND (F(x3, y3) * F(x4, y4) < 0)
|
||||||
|
|
||||||
|
// 斜截式 y = kx + b
|
||||||
|
// 即 kx - y + b = 0
|
||||||
|
|
||||||
|
var k1 = (latA2 - latA1) / (lngA2 - lngA1);
|
||||||
|
var b1 = latA1 - k1 * lngA1;
|
||||||
|
|
||||||
|
var k2 = (latB2 - latB1) / (lngB2 - lngB1);
|
||||||
|
var b2 = latB1 - k2 * lngB1;
|
||||||
|
|
||||||
|
return k2 * lngA1 - latA1 + b2 > 0 != k2 * lngA2 - latA2 + b2 > 0 &&
|
||||||
|
k1 * lngB1 - latB1 + b1 > 0 != k1 * lngB2 - latB2 + b1 > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 把角度转换为弧度。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">角度值。</param>
|
||||||
|
/// <returns>弧度值。</returns>
|
||||||
|
public static double DegToRad(this float value)
|
||||||
|
{
|
||||||
|
return value * DEG_TO_RAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 把角度转换为弧度。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">角度值。</param>
|
||||||
|
/// <returns>弧度值。</returns>
|
||||||
|
public static double DegToRad(this double value)
|
||||||
|
{
|
||||||
|
return value * DEG_TO_RAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 把角度转换为弧度。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">角度值。</param>
|
||||||
|
/// <returns>弧度值。</returns>
|
||||||
|
public static double DegToRad(this short value)
|
||||||
|
{
|
||||||
|
return value * DEG_TO_RAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 把指示方向的角度数限制在 [0, 360)。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">指示方向的角度数。</param>
|
||||||
|
/// <returns>等价的在标准范围内的角度。</returns>
|
||||||
|
public static float NormalizeDirection(this float value)
|
||||||
|
{
|
||||||
|
while (value < 0)
|
||||||
|
{
|
||||||
|
value += 360;
|
||||||
|
}
|
||||||
|
while (value >= 360)
|
||||||
|
{
|
||||||
|
value -= 360;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 把指示方向的角度值限制在 [0, 360)。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">指示方向的角度值。</param>
|
||||||
|
/// <returns>等价的在标准范围内的角度。</returns>
|
||||||
|
public static double NormalizeDirection(this double value)
|
||||||
|
{
|
||||||
|
while (value < 0)
|
||||||
|
{
|
||||||
|
value += 360;
|
||||||
|
}
|
||||||
|
while (value >= 360)
|
||||||
|
{
|
||||||
|
value -= 360;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 把指示方向的弧度值限制在 [0, 2PI)。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">指示方向的弧度值。</param>
|
||||||
|
/// <returns>等价的在标准范围内的弧度。</returns>
|
||||||
|
public static double NormalizeDirectionRad(this double value)
|
||||||
|
{
|
||||||
|
while (value < 0)
|
||||||
|
{
|
||||||
|
value += Math.PI * 2;
|
||||||
|
}
|
||||||
|
while (value >= Math.PI * 2)
|
||||||
|
{
|
||||||
|
value -= Math.PI * 2;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 把弧度转换为角度。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">弧度值。</param>
|
||||||
|
/// <returns>角度值。</returns>
|
||||||
|
public static double RadToDeg(this float value)
|
||||||
|
{
|
||||||
|
return value / DEG_TO_RAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 把弧度转换为角度。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">弧度值。</param>
|
||||||
|
/// <returns>角度值。</returns>
|
||||||
|
public static double RadToDeg(this double value)
|
||||||
|
{
|
||||||
|
return value / DEG_TO_RAD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
PlaneGcsSdk.Contract_Shared/Geography/ILocation.cs
Normal file
13
PlaneGcsSdk.Contract_Shared/Geography/ILocation.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
namespace Plane.Geography
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 定义可用于确定一个固定的星球上的空间中的一个点的属性。
|
||||||
|
/// </summary>
|
||||||
|
public interface ILocation : ILocation2D
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取相对高度。
|
||||||
|
/// </summary>
|
||||||
|
float Altitude { get; }
|
||||||
|
}
|
||||||
|
}
|
15
PlaneGcsSdk.Contract_Shared/Geography/ILocation2D.cs
Normal file
15
PlaneGcsSdk.Contract_Shared/Geography/ILocation2D.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
namespace Plane.Geography
|
||||||
|
{
|
||||||
|
public interface ILocation2D
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取纬度。
|
||||||
|
/// </summary>
|
||||||
|
double Latitude { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取经度。
|
||||||
|
/// </summary>
|
||||||
|
double Longitude { get; }
|
||||||
|
}
|
||||||
|
}
|
80
PlaneGcsSdk.Contract_Shared/Geography/LocationExtensions.cs
Normal file
80
PlaneGcsSdk.Contract_Shared/Geography/LocationExtensions.cs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
namespace Plane.Geography
|
||||||
|
{
|
||||||
|
public static class LocationExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 计算在二维平面上从 <paramref name="l1"/> 到 <paramref name="l2"/> 的方向,单位为弧度。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="l1">出发点。</param>
|
||||||
|
/// <param name="l2">目标点。</param>
|
||||||
|
/// <returns>点 1 到点 2 的方向。</returns>
|
||||||
|
public static double CalcDirection2D(this ILocation2D l1, ILocation2D l2)
|
||||||
|
=> GeographyUtils.CalcDirection2D(l1.Latitude, l1.Longitude, l2.Latitude, l2.Longitude);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算在二维平面上从 <paramref name="l1"/> 到 (<paramref name="lat2"/>, <paramref name="lng2"/>) 的方向,单位为弧度。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="l1">出发点。</param>
|
||||||
|
/// <param name="lat2">目标点的纬度。</param>
|
||||||
|
/// <param name="lng2">目标点的经度。</param>
|
||||||
|
/// <returns>点 1 到点 2 的方向。</returns>
|
||||||
|
public static double CalcDirection2D(this ILocation2D l1, double lat2, double lng2)
|
||||||
|
=> GeographyUtils.CalcDirection2D(l1.Latitude, l1.Longitude, lat2, lng2);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算空间中两点间的距离,单位为米。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="l1">点 1。</param>
|
||||||
|
/// <param name="l2">点 2。</param>
|
||||||
|
/// <returns>空间中两点间的距离。</returns>
|
||||||
|
public static double CalcDistance(this ILocation l1, ILocation l2)
|
||||||
|
=> GeographyUtils.CalcDistance(l1, l2);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算空间中两点间的距离,单位为米。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="l1">点 1。</param>
|
||||||
|
/// <param name="lat2">点 2 的纬度。</param>
|
||||||
|
/// <param name="lng2">点 2 的经度。</param>
|
||||||
|
/// <param name="alt2">点 2 的高度。</param>
|
||||||
|
/// <returns>空间中两点间的距离。</returns>
|
||||||
|
public static double CalcDistance(this ILocation l1, double lat2, double lng2, double alt2)
|
||||||
|
=> GeographyUtils.CalcDistance(l1.Latitude, l1.Longitude, l1.Altitude, lat2, lng2, alt2);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算二维平面上两个位置之间的距离,单位为米。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="l1">位置 1。</param>
|
||||||
|
/// <param name="l2">位置 2。</param>
|
||||||
|
/// <returns>平面上两点间的距离。</returns>
|
||||||
|
public static double CalcDistance2D(this ILocation2D l1, ILocation2D l2)
|
||||||
|
=> GeographyUtils.CalcDistance2D(l1, l2);
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算二维平面上两个位置之间的距离,单位为米。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lat2">点 2 的纬度。</param>
|
||||||
|
/// <param name="lng2">点 2 的经度。</param>
|
||||||
|
/// <returns>平面上两点间的距离。</returns>
|
||||||
|
public static double CalcDistance2D(this ILocation2D l1, double lat2, double lng2)
|
||||||
|
=> GeographyUtils.CalcDistance2D(l1.Latitude, l1.Longitude, lat2, lng2);
|
||||||
|
/// <summary>
|
||||||
|
/// 计算在水平面上从指定点往指定方向移动指定距离后所在的点。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="loc1">出发点。</param>
|
||||||
|
/// <param name="directionDegrees">移动方向,单位为角度。</param>
|
||||||
|
/// <param name="distance">移动距离。</param>
|
||||||
|
/// <returns>从指定点往指定方向移动指定距离后所在的点。</returns>
|
||||||
|
public static ILocation2D CalcLatLngSomeMetersAway2D(this ILocation2D loc1, float directionDegrees, float distance)
|
||||||
|
=> GeographyUtils.CalcLatLngSomeMetersAway2D(loc1, directionDegrees, distance);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 判断一个 <see cref="ILocation"/> 实例是否被认为是空值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="loc"><see cref="ILocation"/> 实例。</param>
|
||||||
|
/// <returns>若给定的位置被认为是空值,返回 true;否则返回 false。</returns>
|
||||||
|
public static bool IsNullOrEmpty(this ILocation loc)
|
||||||
|
=> loc == null || (loc.Latitude == 0 && loc.Longitude == 0 && loc.Altitude == 0);
|
||||||
|
}
|
||||||
|
}
|
56
PlaneGcsSdk.Contract_Shared/Geography/PLLocation.cs
Normal file
56
PlaneGcsSdk.Contract_Shared/Geography/PLLocation.cs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace Plane.Geography
|
||||||
|
{
|
||||||
|
[DebuggerDisplay("lat: {Latitude}, lng: {Longitude}, alt: {Altitude}")]
|
||||||
|
public class PLLocation : ILocation
|
||||||
|
{
|
||||||
|
public PLLocation()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public PLLocation(ILocation locToCopy)
|
||||||
|
: this(locToCopy.Latitude, locToCopy.Longitude, locToCopy.Altitude)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public PLLocation(double lat, double lng, float alt)
|
||||||
|
{
|
||||||
|
Latitude = lat;
|
||||||
|
Longitude = lng;
|
||||||
|
Altitude = alt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float Altitude { get; set; }
|
||||||
|
|
||||||
|
public double Latitude { get; set; }
|
||||||
|
|
||||||
|
public double Longitude { get; set; }
|
||||||
|
|
||||||
|
public PLLocation AddAltitude(float altToAdd)
|
||||||
|
{
|
||||||
|
Altitude += altToAdd;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PLLocation AddLatitude(double latToAdd)
|
||||||
|
{
|
||||||
|
Latitude += latToAdd;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PLLocation AddLatLngAlt(double latToAdd, double lngToAdd, float altToAdd)
|
||||||
|
{
|
||||||
|
Latitude += latToAdd;
|
||||||
|
Longitude += lngToAdd;
|
||||||
|
Altitude += altToAdd;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PLLocation AddLongitude(double lngToAdd)
|
||||||
|
{
|
||||||
|
Longitude += lngToAdd;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
PlaneGcsSdk.Contract_Shared/MathExtensions.cs
Normal file
31
PlaneGcsSdk.Contract_Shared/MathExtensions.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Plane
|
||||||
|
{
|
||||||
|
public static class MathExtensions
|
||||||
|
{
|
||||||
|
public static bool IsInRange<T>(this T value, T min, T max) where T : struct, IComparable<T>
|
||||||
|
{
|
||||||
|
if (min.CompareTo(max) > 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"The {nameof(min)} argument ({min}) must be less than or equal to the {nameof(max)} argument ({max}).");
|
||||||
|
}
|
||||||
|
return value.CompareTo(min) >= 0 && value.CompareTo(max) <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T Limit<T>(this T value, T? min = null, T? max = null) where T : struct, IComparable<T>
|
||||||
|
{
|
||||||
|
if (min.HasValue && max.HasValue && min.Value.CompareTo(max.Value) > 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"The {nameof(min)} argument ({min}) must be less than or equal to the {nameof(max)} argument ({max}).");
|
||||||
|
}
|
||||||
|
if (!min.HasValue && !max.HasValue)
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"The {nameof(min)} argument and the {nameof(max)} argument are both missing.");
|
||||||
|
}
|
||||||
|
if (min.HasValue && value.CompareTo(min.Value) < 0) return min.Value;
|
||||||
|
if (max.HasValue && value.CompareTo(max.Value) > 0) return max.Value;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
using Plane.Copters;
|
||||||
|
|
||||||
|
namespace Plane.Messaging
|
||||||
|
{
|
||||||
|
public class CopterAltitudeChangedMessage : CopterMessageBase
|
||||||
|
{
|
||||||
|
public CopterAltitudeChangedMessage(ICopter copter) : base(copter)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
using Plane.Copters;
|
||||||
|
|
||||||
|
namespace Plane.Messaging
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 在飞行器姿态变化时发出的消息。
|
||||||
|
/// </summary>
|
||||||
|
public class CopterAttitudeChangedMessage : CopterMessageBase
|
||||||
|
{
|
||||||
|
public CopterAttitudeChangedMessage(ICopter copter) : base(copter)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
using Plane.Copters;
|
||||||
|
|
||||||
|
namespace Plane.Messaging
|
||||||
|
{
|
||||||
|
public class CopterConnectedMessage : CopterMessageBase
|
||||||
|
{
|
||||||
|
public CopterConnectedMessage(ICopter copter) : base(copter)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
using Plane.Copters;
|
||||||
|
|
||||||
|
namespace Plane.Messaging
|
||||||
|
{
|
||||||
|
public class CopterHeartbeatReceivedMessage : CopterMessageBase
|
||||||
|
{
|
||||||
|
public CopterHeartbeatReceivedMessage(ICopter copter) : base(copter)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
using Plane.Copters;
|
||||||
|
|
||||||
|
namespace Plane.Messaging
|
||||||
|
{
|
||||||
|
public class CopterLocationChangedMessage : CopterMessageBase
|
||||||
|
{
|
||||||
|
public CopterLocationChangedMessage(ICopter copter) : base(copter)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
PlaneGcsSdk.Contract_Shared/Messaging/CopterMessageBase.cs
Normal file
14
PlaneGcsSdk.Contract_Shared/Messaging/CopterMessageBase.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using Plane.Copters;
|
||||||
|
|
||||||
|
namespace Plane.Messaging
|
||||||
|
{
|
||||||
|
public class CopterMessageBase
|
||||||
|
{
|
||||||
|
public CopterMessageBase(ICopter copter)
|
||||||
|
{
|
||||||
|
Copter = copter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICopter Copter { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
using Plane.Copters;
|
||||||
|
|
||||||
|
namespace Plane.Messaging
|
||||||
|
{
|
||||||
|
public class CopterPairingCompletedMessage : CopterMessageBase
|
||||||
|
{
|
||||||
|
public CopterPairingCompletedMessage(ICopter copter, bool isSuccessful) : base(copter)
|
||||||
|
{
|
||||||
|
this.IsSuccessful = isSuccessful;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsSuccessful { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
using Plane.Copters;
|
||||||
|
|
||||||
|
namespace Plane.Messaging
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 通过注册 <see cref="CopterPropertyChangedMessage"/> 来监视未关联到特定 Message 的属性。
|
||||||
|
/// </summary>
|
||||||
|
public class CopterPropertyChangedMessage : CopterMessageBase
|
||||||
|
{
|
||||||
|
public CopterPropertyChangedMessage(ICopter copter, string propertyName) : base(copter)
|
||||||
|
{
|
||||||
|
PropertyName = propertyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string PropertyName { get; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
namespace Plane.Messaging
|
||||||
|
{
|
||||||
|
public class FlyToRequestAcceptedMessage
|
||||||
|
{
|
||||||
|
public FlyToRequestAcceptedMessage(RequestFlyToMessage request)
|
||||||
|
{
|
||||||
|
this.Request = request;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestFlyToMessage Request { get; }
|
||||||
|
}
|
||||||
|
}
|
36
PlaneGcsSdk.Contract_Shared/Messaging/IPLMessenger.cs
Normal file
36
PlaneGcsSdk.Contract_Shared/Messaging/IPLMessenger.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Plane.Messaging
|
||||||
|
{
|
||||||
|
public interface IPLMessenger
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Registers a recipient for a type of message TMessage. The action
|
||||||
|
/// parameter will be executed when a corresponding message is sent.
|
||||||
|
/// <para>Registering a recipient does not create a hard reference to it,
|
||||||
|
/// so if this recipient is deleted, no memory leak is caused.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TMessage">The type of message that the recipient registers
|
||||||
|
/// for.</typeparam>
|
||||||
|
/// <param name="recipient">The recipient that will receive the messages.</param>
|
||||||
|
/// <param name="action">The action that will be executed when a message
|
||||||
|
/// of type TMessage is sent.</param>
|
||||||
|
void Register<TMessage>(object recipient, Action<TMessage> action);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends a message to registered recipients. The message will
|
||||||
|
/// reach all recipients that registered for this message type
|
||||||
|
/// using one of the Register methods.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TMessage">The type of message that will be sent.</typeparam>
|
||||||
|
/// <param name="message">The message to send to registered recipients.</param>
|
||||||
|
void Send<TMessage>(TMessage message);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unregisters a messager recipient completely. After this method
|
||||||
|
/// is executed, the recipient will not receive any messages anymore.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="recipient">The recipient that must be unregistered.</param>
|
||||||
|
void Unregister(object recipient);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
namespace Plane.Messaging
|
||||||
|
{
|
||||||
|
public class LandingStateAcceptsAvatarChangedMessage
|
||||||
|
{
|
||||||
|
public LandingStateAcceptsAvatarChangedMessage(bool landingStateAcceptsAvatar)
|
||||||
|
{
|
||||||
|
LandingStateAcceptsAvatar = landingStateAcceptsAvatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool LandingStateAcceptsAvatar { get; }
|
||||||
|
}
|
||||||
|
}
|
15
PlaneGcsSdk.Contract_Shared/Messaging/RequestFlyToMessage.cs
Normal file
15
PlaneGcsSdk.Contract_Shared/Messaging/RequestFlyToMessage.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
namespace Plane.Messaging
|
||||||
|
{
|
||||||
|
public class RequestFlyToMessage
|
||||||
|
{
|
||||||
|
public RequestFlyToMessage(double lat, double lng)
|
||||||
|
{
|
||||||
|
Latitude = lat;
|
||||||
|
Longitude = lng;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double Latitude { get; set; }
|
||||||
|
|
||||||
|
public double Longitude { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
namespace Plane.Messaging
|
||||||
|
{
|
||||||
|
public class RequestUpdateAttitudeMessage
|
||||||
|
{
|
||||||
|
public RequestUpdateAttitudeMessage(float rollDegrees, float pitchDegrees, float? yawDegrees)
|
||||||
|
{
|
||||||
|
this.RollDegrees = rollDegrees;
|
||||||
|
this.PitchDegrees = pitchDegrees;
|
||||||
|
this.YawDegrees = yawDegrees;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取绕 X 轴的旋转(以度为单位)。
|
||||||
|
/// </summary>
|
||||||
|
public float PitchDegrees { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取绕 Y 轴的旋转(以度为单位)。
|
||||||
|
/// </summary>
|
||||||
|
public float RollDegrees { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取绕 Z 轴的旋转(以度为单位,正北 0,正东 90,范围为 [0, 360))。
|
||||||
|
/// </summary>
|
||||||
|
public float? YawDegrees { get; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||||
|
<HasSharedItems>true</HasSharedItems>
|
||||||
|
<SharedGUID>695733d7-99ff-4707-8c89-474e949cadcb</SharedGUID>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Label="Configuration">
|
||||||
|
<Import_RootNamespace>Plane</Import_RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Communication\ConnectionEstablishedEventArgs.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Communication\ExceptionThrownEventArgs.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Communication\IConnection.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)CopterControllers\CopterControllerTypes.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)CopterControllers\ICopterController.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)CopterControllers\ICopterControllerManager.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)CopterControllers\SpeedType.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)CopterManagement\ICopterFactory.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)CopterManagement\ICopterManager.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\Constants.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\CopterCommand.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\CopterState.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\PLObservableObject.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\FlightCommand.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\GpsFixType.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\HeartbeatReceivedEventArgs.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\IAttitude.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\ICopter.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\ICopterActions.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\ICopterActionsSharedByCopterManager.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\ICopterCommunication.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\ICopterEvents.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\ICopterMissionActions.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\ICopterStatus.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\IFakeCopter.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\IMission.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\IVisibleStatus.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\MessageCreatedEventArgs.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\MissionItemReceivedEventArgs.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\PairingCompletedEventArgs.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\SystemStatusReceivedEventArgs.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Copters\VisibleStatus.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Geography\PLLocation.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Geography\GeographyUtils.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Geography\ILocation.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Geography\ILocation2D.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Geography\LocationExtensions.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)MathExtensions.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Messaging\CopterAltitudeChangedMessage.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Messaging\CopterAttitudeChangedMessage.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Messaging\CopterConnectedMessage.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Messaging\CopterHeartbeatReceivedMessage.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Messaging\CopterLocationChangedMessage.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Messaging\CopterMessageBase.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Messaging\CopterPairingCompletedMessage.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Messaging\CopterPropertyChangedMessage.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Messaging\FlyToRequestAcceptedMessage.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Messaging\IPLMessenger.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Messaging\LandingStateAcceptsAvatarChangedMessage.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Messaging\RequestFlyToMessage.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Messaging\RequestUpdateAttitudeMessage.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)SynchronizationContextExtensions.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>695733d7-99ff-4707-8c89-474e949cadcb</ProjectGuid>
|
||||||
|
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
|
||||||
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
|
||||||
|
<PropertyGroup />
|
||||||
|
<Import Project="PlaneGcsSdk.Contract_Shared.projitems" Label="Shared" />
|
||||||
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
|
||||||
|
</Project>
|
@ -0,0 +1,32 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace Plane
|
||||||
|
{
|
||||||
|
public static class SynchronizationContextExtensions
|
||||||
|
{
|
||||||
|
public static void Post(this SynchronizationContext syncContext, Action action)
|
||||||
|
{
|
||||||
|
if (SynchronizationContext.Current == syncContext)
|
||||||
|
{
|
||||||
|
action();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
syncContext.Post(state => action(), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Send(this SynchronizationContext syncContext, Action action)
|
||||||
|
{
|
||||||
|
if (SynchronizationContext.Current == syncContext)
|
||||||
|
{
|
||||||
|
action();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
syncContext.Send(state => action(), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
62
PlaneGcsSdk_NET46/PlaneGcsSdk_NET46.csproj
Normal file
62
PlaneGcsSdk_NET46/PlaneGcsSdk_NET46.csproj
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{331C28E1-5BA3-42CE-8A4A-BC468E692FED}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>Plane</RootNamespace>
|
||||||
|
<AssemblyName>PlaneGcsSdk_NET46</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<DocumentationFile>bin\Release\PlaneGcsSdk_NET46.xml</DocumentationFile>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="WindowsBase" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\PlaneGcsSdk.Contract\PlaneGcsSdk.Contract.csproj">
|
||||||
|
<Project>{18ecd88e-5d74-43e8-8bc2-d28f6db13a47}</Project>
|
||||||
|
<Name>PlaneGcsSdk.Contract</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="..\PlaneGcsSdk_Shared\PlaneGcsSdk_Shared.projitems" Label="Shared" />
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
36
PlaneGcsSdk_NET46/Properties/AssemblyInfo.cs
Normal file
36
PlaneGcsSdk_NET46/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// 有关程序集的一般信息由以下
|
||||||
|
// 控制。更改这些特性值可修改
|
||||||
|
// 与程序集关联的信息。
|
||||||
|
[assembly: AssemblyTitle("PlaneGcsSdk_NET46")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("Plane, Inc.")]
|
||||||
|
[assembly: AssemblyProduct("PlaneGcsSdk_NET46")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2015")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
//将 ComVisible 设置为 false 将使此程序集中的类型
|
||||||
|
//对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
|
||||||
|
//请将此类型的 ComVisible 特性设置为 true。
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||||
|
[assembly: Guid("331c28e1-5ba3-42ce-8a4a-bc468e692fed")]
|
||||||
|
|
||||||
|
// 程序集的版本信息由下列四个值组成:
|
||||||
|
//
|
||||||
|
// 主版本
|
||||||
|
// 次版本
|
||||||
|
// 生成号
|
||||||
|
// 修订号
|
||||||
|
//
|
||||||
|
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
|
||||||
|
// 方法是按如下所示使用“*”: :
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
public abstract partial class CopterImplSharedPart : PLObservableObject
|
||||||
|
{
|
||||||
|
public Task CircleAsync()
|
||||||
|
{
|
||||||
|
return SetModeAsync(FlightMode.CIRCLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
PlaneGcsSdk_Private_NET45/Copters/FakeCopter.Private.cs
Normal file
18
PlaneGcsSdk_Private_NET45/Copters/FakeCopter.Private.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
public partial class FakeCopter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// // 林俊清, 20160122, 不明确。目测是发送重启命令,在刷固件之前用到。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bootloaderMode"></param>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
public Task RebootAsync(bool bootloaderMode = false)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
PlaneGcsSdk_Private_NET45/Copters/PLCopter.Private.cs
Normal file
22
PlaneGcsSdk_Private_NET45/Copters/PLCopter.Private.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Plane.Copters
|
||||||
|
{
|
||||||
|
public partial class PLCopter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 暴露内部的 <see cref="PlaneCopter"/> 实例。
|
||||||
|
/// </summary>
|
||||||
|
public PlaneCopter InternalCopter { get { return _internalCopter; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// // 林俊清, 20160122, 不明确。目测是发送重启命令,在刷固件之前用到。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bootloaderMode"></param>
|
||||||
|
/// <returns>表示此命令异步发送操作的 <see cref="Task"/> 实例。</returns>
|
||||||
|
public Task RebootAsync(bool bootloaderMode = false)
|
||||||
|
{
|
||||||
|
return _internalCopter.RebootAsync(bootloaderMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user