diff --git a/Client/Client.csproj b/Client/Client.csproj new file mode 100644 index 0000000..8efc40a --- /dev/null +++ b/Client/Client.csproj @@ -0,0 +1,12 @@ + + + + Exe + netcoreapp3.1 + + + + + + + diff --git a/Client/Program.cs b/Client/Program.cs new file mode 100644 index 0000000..500983c --- /dev/null +++ b/Client/Program.cs @@ -0,0 +1,20 @@ +using System; + +namespace Client +{ + using System.Threading.Tasks; + using CoAP; + + class Program + { + static async Task Main(string[] args) + { + var client = new CoapClient(new Uri("coap://127.0.0.1:5683/abc/def/ghi")); + while (true) + { + client.Get(); + await Task.Delay(TimeSpan.FromSeconds(5)).ConfigureAwait(false); + } + } + } +} diff --git a/CoAP.Example/CoAP.Client/CoAP.Client.DNX.xproj b/CoAP.Example/CoAP.Client/CoAP.Client.DNX.xproj deleted file mode 100644 index 8ddf65e..0000000 --- a/CoAP.Example/CoAP.Client/CoAP.Client.DNX.xproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - beab76e9-75ce-497a-af4f-c649fbdaa63e - CoAP.Client.DNX - ..\artifacts\obj\$(MSBuildProjectName) - ..\artifacts\bin\$(MSBuildProjectName)\ - - - 2.0 - - - True - - - \ No newline at end of file diff --git a/CoAP.Example/CoAP.Client/CoAP.Client.NET40.csproj b/CoAP.Example/CoAP.Client/CoAP.Client.NET40.csproj deleted file mode 100644 index 99efefb..0000000 --- a/CoAP.Example/CoAP.Client/CoAP.Client.NET40.csproj +++ /dev/null @@ -1,55 +0,0 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {30223FF5-4DCB-45B8-9B06-61EB9FBF9FA8} - Exe - Properties - CoAP.Examples - CoAPClient - v4.0 - 512 - - - - true - full - false - bin\Debug\NET40\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\NET40\ - TRACE - prompt - 4 - - - - - - - - - - - {45DB1E45-4831-4E4A-BB1E-AE92EEA182E3} - CoAP.NET40 - - - - - \ No newline at end of file diff --git a/CoAP.Example/CoAP.Client/CoAP.Client.csproj b/CoAP.Example/CoAP.Client/CoAP.Client.csproj deleted file mode 100644 index d9181d3..0000000 --- a/CoAP.Example/CoAP.Client/CoAP.Client.csproj +++ /dev/null @@ -1,54 +0,0 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {30223FF5-4DCB-45B8-9B06-61EB9FBF9FA8} - Exe - Properties - CoAP.Examples - CoAPClient - v2.0 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - {45DB1E45-4831-4E4A-BB1E-AE92EEA182E3} - CoAP.NET - - - - - \ No newline at end of file diff --git a/CoAP.Example/CoAP.Client/ExampleClient.cs b/CoAP.Example/CoAP.Client/ExampleClient.cs deleted file mode 100644 index df52797..0000000 --- a/CoAP.Example/CoAP.Client/ExampleClient.cs +++ /dev/null @@ -1,229 +0,0 @@ -using System; -using System.Collections.Generic; -using CoAP.Util; - -#if DNX451 -using Common.Logging; -using Common.Logging.Configuration; - -namespace CoAP.Client.DNX -{ - // DNX entry point - public class Program - { - public void Main(string[] args) - { - NameValueCollection console_props = new NameValueCollection(); - console_props["showDateTime"] = "true"; - console_props["level"] = "Debug"; - LogManager.Adapter = new Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter(console_props); - CoAP.Examples.ExampleClient.Main(args); - } - } -} -#endif - -namespace CoAP.Examples -{ - - // .NET 2, .NET 4 entry point - class ExampleClient - { - public static void Main(String[] args) - { - String method = null; - Uri uri = null; - String payload = null; - Boolean loop = false; - Boolean byEvent = true; - - if (args.Length == 0) - PrintUsage(); - - Int32 index = 0; - foreach (String arg in args) - { - if (arg[0] == '-') - { - if (arg.Equals("-l")) - loop = true; - if (arg.Equals("-e")) - byEvent = true; - else - Console.WriteLine("Unknown option: " + arg); - } - else - { - switch (index) - { - case 0: - method = arg.ToUpper(); - break; - case 1: - try - { - uri = new Uri(arg); - } - catch (Exception ex) - { - Console.WriteLine("Failed parsing URI: " + ex.Message); - Environment.Exit(1); - } - break; - case 2: - payload = arg; - break; - default: - Console.WriteLine("Unexpected argument: " + arg); - break; - } - index++; - } - } - - if (method == null || uri == null) - PrintUsage(); - - Request request = NewRequest(method); - if (request == null) - { - Console.WriteLine("Unknown method: " + method); - Environment.Exit(1); - } - - if ("OBSERVE".Equals(method)) - { - request.MarkObserve(); - loop = true; - } - else if ("DISCOVER".Equals(method) && - (String.IsNullOrEmpty(uri.AbsolutePath) || uri.AbsolutePath.Equals("/"))) - { - uri = new Uri(uri, "/.well-known/core"); - } - - request.URI = uri; - request.SetPayload(payload, MediaType.TextPlain); - - // uncomment the next line if you want to specify a draft to use - // request.EndPoint = CoAP.Net.EndPointManager.Draft13; - - Console.WriteLine(Utils.ToString(request)); - - try - { - if (byEvent) - { - request.Respond += delegate(Object sender, ResponseEventArgs e) - { - Response response = e.Response; - if (response == null) - { - Console.WriteLine("Request timeout"); - } - else - { - Console.WriteLine(Utils.ToString(response)); - Console.WriteLine("Time (ms): " + response.RTT); - } - if (!loop) - Environment.Exit(0); - }; - request.Send(); - while (true) - { - Console.ReadKey(); - } - } - else - { - // uncomment the next line if you need retransmission disabled. - // request.AckTimeout = -1; - - request.Send(); - - do - { - Console.WriteLine("Receiving response..."); - - Response response = null; - response = request.WaitForResponse(); - - if (response == null) - { - Console.WriteLine("Request timeout"); - break; - } - else - { - Console.WriteLine(Utils.ToString(response)); - Console.WriteLine("Time elapsed (ms): " + response.RTT); - - if (response.ContentType == MediaType.ApplicationLinkFormat) - { - IEnumerable links = LinkFormat.Parse(response.PayloadString); - if (links == null) - { - Console.WriteLine("Failed parsing link format"); - Environment.Exit(1); - } - else - { - Console.WriteLine("Discovered resources:"); - foreach (var link in links) - { - Console.WriteLine(link); - } - } - } - } - } while (loop); - } - } - catch (Exception ex) - { - Console.WriteLine("Failed executing request: " + ex.Message); - Console.WriteLine(ex); - Environment.Exit(1); - } - } - - private static Request NewRequest(String method) - { - switch (method) - { - case "POST": - return Request.NewPost(); - case "PUT": - return Request.NewPut(); - case "DELETE": - return Request.NewDelete(); - case "GET": - case "DISCOVER": - case "OBSERVE": - return Request.NewGet(); - default: - return null; - } - } - - private static void PrintUsage() - { - Console.WriteLine("CoAP.NET Example Client"); - Console.WriteLine(); - Console.WriteLine("Usage: CoAPClient [-e] [-l] method uri [payload]"); - Console.WriteLine(" method : { GET, POST, PUT, DELETE, DISCOVER, OBSERVE }"); - Console.WriteLine(" uri : The CoAP URI of the remote endpoint or resource."); - Console.WriteLine(" payload : The data to send with the request."); - Console.WriteLine("Options:"); - Console.WriteLine(" -e : Receives responses by the Responded event."); - Console.WriteLine(" -l : Loops for multiple responses."); - Console.WriteLine(" (automatic for OBSERVE and separate responses)"); - Console.WriteLine(); - Console.WriteLine("Examples:"); - Console.WriteLine(" CoAPClient DISCOVER coap://localhost"); - Console.WriteLine(" CoAPClient POST coap://localhost/storage data"); - Environment.Exit(0); - } - } -} diff --git a/CoAP.Example/CoAP.Client/Properties/AssemblyInfo.cs b/CoAP.Example/CoAP.Client/Properties/AssemblyInfo.cs deleted file mode 100644 index 3b051fa..0000000 --- a/CoAP.Example/CoAP.Client/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// 有关程序集的常规信息通过以下 -// 特性集控制。更改这些特性值可修改 -// 与程序集关联的信息。 -[assembly: AssemblyTitle("CoAP Client")] -[assembly: AssemblyDescription("A sample of CoAP client to show how the CoAP framework in C# works")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("SmeshLink Technology")] -[assembly: AssemblyProduct("CoAP.NET")] -[assembly: AssemblyCopyright("Copyright © SmeshLink 2011-2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// 将 ComVisible 设置为 false 使此程序集中的类型 -// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型, -// 则将该类型上的 ComVisible 特性设置为 true。 -[assembly: ComVisible(false)] - -// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID -[assembly: Guid("24a48ec6-9e93-491d-8916-5cbba26b658d")] - -// 程序集的版本信息由下面四个值组成: -// -// 主版本 -// 次版本 -// 内部版本号 -// 修订号 -// -// 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, -// 方法是按如下所示使用“*”: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.13.*")] -[assembly: AssemblyFileVersion("0.13")] diff --git a/CoAP.Example/CoAP.Client/README.md b/CoAP.Example/CoAP.Client/README.md deleted file mode 100644 index b5939ac..0000000 --- a/CoAP.Example/CoAP.Client/README.md +++ /dev/null @@ -1,5 +0,0 @@ -CoAP.Client - A CoAP Example Client -=================================== - -This project demonstrates how to access remote CoAP resource -with CoAP **[Request] (Request.cs)**. diff --git a/CoAP.Example/CoAP.Client/project.json b/CoAP.Example/CoAP.Client/project.json deleted file mode 100644 index 40e7ad5..0000000 --- a/CoAP.Example/CoAP.Client/project.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "version": "1.0.0-*", - "description": "CoAP.Client.DNX Console Application", - "authors": [ "sgnezdov" ], - "tags": [ "" ], - "projectUrl": "", - "licenseUrl": "", - - "dependencies": { - "CoAP.NET": "1.0.0-*" - }, - - "commands": { - "CoAP.Client.DNX": "run" - }, - - "frameworks": { - "dnx451": { - "dependencies": { - } - } - } -} diff --git a/CoAP.Example/CoAP.Proxy/CoAP.Proxy.NET40.csproj b/CoAP.Example/CoAP.Proxy/CoAP.Proxy.NET40.csproj deleted file mode 100644 index ed6e1a3..0000000 --- a/CoAP.Example/CoAP.Proxy/CoAP.Proxy.NET40.csproj +++ /dev/null @@ -1,61 +0,0 @@ - - - - Debug - x86 - 8.0.30703 - 2.0 - {96DBCEFE-CE81-4592-9101-9A3659BEC488} - Exe - Properties - CoAP.Examples - CoAPProxy - v4.0 - 512 - - - - x86 - true - full - false - bin\Debug\NET40\ - TRACE;DEBUG - prompt - 4 - - - x86 - pdbonly - true - bin\Release\NET40\ - TRACE - prompt - 4 - - - - - - - - - - - {45DB1E45-4831-4E4A-BB1E-AE92EEA182E3} - CoAP.NET40 - - - {B8D6E88E-890B-4220-B994-C5EC7B19D282} - CoAP.Proxy.NET40 - - - - - \ No newline at end of file diff --git a/CoAP.Example/CoAP.Proxy/CoAP.Proxy.csproj b/CoAP.Example/CoAP.Proxy/CoAP.Proxy.csproj deleted file mode 100644 index 4816ec8..0000000 --- a/CoAP.Example/CoAP.Proxy/CoAP.Proxy.csproj +++ /dev/null @@ -1,60 +0,0 @@ - - - - Debug - x86 - 8.0.30703 - 2.0 - {96DBCEFE-CE81-4592-9101-9A3659BEC488} - Exe - Properties - CoAP.Examples - CoAPProxy - v2.0 - 512 - - - x86 - true - full - false - bin\Debug\ - TRACE;DEBUG - prompt - 4 - - - x86 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - {45DB1E45-4831-4E4A-BB1E-AE92EEA182E3} - CoAP.NET - - - {B8D6E88E-890B-4220-B994-C5EC7B19D282} - CoAP.Proxy - - - - - \ No newline at end of file diff --git a/CoAP.Example/CoAP.Proxy/Program.cs b/CoAP.Example/CoAP.Proxy/Program.cs deleted file mode 100644 index 50f5a9a..0000000 --- a/CoAP.Example/CoAP.Proxy/Program.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using CoAP.Proxy; -using CoAP.Proxy.Resources; -using CoAP.Server; -using CoAP.Server.Resources; - -namespace CoAP.Examples -{ - class Program - { - static void Main(string[] args) - { - ForwardingResource coap2coap = new ProxyCoapClientResource("coap2coap"); - ForwardingResource coap2http = new ProxyHttpClientResource("coap2http"); - - // Create CoAP Server on PORT with proxy resources form CoAP to CoAP and HTTP - CoapServer coapServer = new CoapServer(CoapConfig.Default.DefaultPort); - coapServer.Add(coap2coap); - coapServer.Add(coap2http); - coapServer.Add(new TargetResource("target")); - coapServer.Start(); - - ProxyHttpServer httpServer = new ProxyHttpServer(CoapConfig.Default.HttpPort); - httpServer.ProxyCoapResolver = new DirectProxyCoAPResolver(coap2coap); - - Console.WriteLine("Press any key to exit."); - Console.ReadKey(); - } - - class TargetResource : Resource - { - private Int32 _counter; - - public TargetResource(String name) - : base(name) - { } - - protected override void DoGet(CoapExchange exchange) - { - exchange.Respond("Response " + (++_counter) + " from resource " + Name); - } - } - } -} diff --git a/CoAP.Example/CoAP.Proxy/Properties/AssemblyInfo.cs b/CoAP.Example/CoAP.Proxy/Properties/AssemblyInfo.cs deleted file mode 100644 index 4e9a207..0000000 --- a/CoAP.Example/CoAP.Proxy/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// 有关程序集的常规信息通过以下 -// 特性集控制。更改这些特性值可修改 -// 与程序集关联的信息。 -[assembly: AssemblyTitle("CoAP Proxy")] -[assembly: AssemblyDescription("A sample of CoAP server to show how the CoAP framework in C# works")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("SmeshLink Technology")] -[assembly: AssemblyProduct("CoAP.NET")] -[assembly: AssemblyCopyright("Copyright © SmeshLink 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// 将 ComVisible 设置为 false 使此程序集中的类型 -// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型, -// 则将该类型上的 ComVisible 特性设置为 true。 -[assembly: ComVisible(false)] - -// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID -[assembly: Guid("6840ab81-4a69-45b0-bcbc-65cab6b9756b")] - -// 程序集的版本信息由下面四个值组成: -// -// 主版本 -// 次版本 -// 内部版本号 -// 修订号 -// -// 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, -// 方法是按如下所示使用“*”: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.13.*")] -[assembly: AssemblyFileVersion("0.13")] diff --git a/CoAP.Example/CoAP.Server/CoAP.Server.NET40.csproj b/CoAP.Example/CoAP.Server/CoAP.Server.NET40.csproj deleted file mode 100644 index a98f16e..0000000 --- a/CoAP.Example/CoAP.Server/CoAP.Server.NET40.csproj +++ /dev/null @@ -1,71 +0,0 @@ - - - - Debug - x86 - 8.0.30703 - 2.0 - {05CC2E5E-B663-4560-844C-C8E52ED1C9D1} - Exe - Properties - CoAP.Examples - CoAPServer - v4.0 - 512 - - - - x86 - true - full - false - bin\Debug\NET40\ - TRACE;DEBUG - prompt - 4 - - - x86 - pdbonly - true - bin\Release\NET40\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - PreserveNewest - - - - - {45DB1E45-4831-4E4A-BB1E-AE92EEA182E3} - CoAP.NET40 - - - - - \ No newline at end of file diff --git a/CoAP.Example/CoAP.Server/CoAP.Server.csproj b/CoAP.Example/CoAP.Server/CoAP.Server.csproj deleted file mode 100644 index bf63ffd..0000000 --- a/CoAP.Example/CoAP.Server/CoAP.Server.csproj +++ /dev/null @@ -1,70 +0,0 @@ - - - - Debug - x86 - 8.0.30703 - 2.0 - {05CC2E5E-B663-4560-844C-C8E52ED1C9D1} - Exe - Properties - CoAP.Examples - CoAPServer - v2.0 - 512 - - - x86 - true - full - false - bin\Debug\ - TRACE;DEBUG - prompt - 4 - - - x86 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - {45DB1E45-4831-4E4A-BB1E-AE92EEA182E3} - CoAP.NET - - - - - PreserveNewest - - - - - \ No newline at end of file diff --git a/CoAP.Example/CoAP.Server/ExampleServer.cs b/CoAP.Example/CoAP.Server/ExampleServer.cs deleted file mode 100644 index a7ab97d..0000000 --- a/CoAP.Example/CoAP.Server/ExampleServer.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using CoAP.Examples.Resources; -using CoAP.Server; - -namespace CoAP.Examples -{ - public class ExampleServer - { - public static void Main(String[] args) - { - CoapServer server = new CoapServer(); - - server.Add(new HelloWorldResource("hello")); - server.Add(new FibonacciResource("fibonacci")); - server.Add(new StorageResource("storage")); - server.Add(new ImageResource("image")); - server.Add(new MirrorResource("mirror")); - server.Add(new LargeResource("large")); - server.Add(new CarelessResource("careless")); - server.Add(new SeparateResource("separate")); - server.Add(new TimeResource("time")); - - try - { - server.Start(); - - Console.Write("CoAP server [{0}] is listening on", server.Config.Version); - - foreach (var item in server.EndPoints) - { - Console.Write(" "); - Console.Write(item.LocalEndPoint); - } - Console.WriteLine(); - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - } - - Console.WriteLine("Press any key to exit."); - Console.ReadKey(); - } - } -} diff --git a/CoAP.Example/CoAP.Server/Properties/AssemblyInfo.cs b/CoAP.Example/CoAP.Server/Properties/AssemblyInfo.cs deleted file mode 100644 index 4d02b4f..0000000 --- a/CoAP.Example/CoAP.Server/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// 有关程序集的常规信息通过以下 -// 特性集控制。更改这些特性值可修改 -// 与程序集关联的信息。 -[assembly: AssemblyTitle("CoAP Server")] -[assembly: AssemblyDescription("A sample of CoAP server to show how the CoAP framework in C# works")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("SmeshLink Technology")] -[assembly: AssemblyProduct("CoAP.NET")] -[assembly: AssemblyCopyright("Copyright © SmeshLink 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// 将 ComVisible 设置为 false 使此程序集中的类型 -// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型, -// 则将该类型上的 ComVisible 特性设置为 true。 -[assembly: ComVisible(false)] - -// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID -[assembly: Guid("319a1e78-2ba9-49f4-838d-76d050cd5913")] - -// 程序集的版本信息由下面四个值组成: -// -// 主版本 -// 次版本 -// 内部版本号 -// 修订号 -// -// 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, -// 方法是按如下所示使用“*”: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.13.*")] -[assembly: AssemblyFileVersion("0.13")] diff --git a/CoAP.Example/CoAP.Server/README.md b/CoAP.Example/CoAP.Server/README.md deleted file mode 100644 index d179a2b..0000000 --- a/CoAP.Example/CoAP.Server/README.md +++ /dev/null @@ -1,4 +0,0 @@ -CoAP.Server - A CoAP Example Server -=================================== - -This project demonstrates how to build a CoAP server with CoAP.NET. diff --git a/CoAP.Example/CoAP.Server/Resources/CarelessResource.cs b/CoAP.Example/CoAP.Server/Resources/CarelessResource.cs deleted file mode 100644 index 4a67278..0000000 --- a/CoAP.Example/CoAP.Server/Resources/CarelessResource.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using CoAP.Server.Resources; - -namespace CoAP.Examples.Resources -{ - /// - /// Represents a resource that forgets to return a separate response. - /// - class CarelessResource : Resource - { - public CarelessResource(String name) - : base(name) - { - Attributes.Title = "This resource will ACK anything, but never send a separate response"; - Attributes.AddResourceType("SepararateResponseTester"); - } - - protected override void DoGet(CoapExchange exchange) - { - // Accept the request to promise the client this request will be acted. - exchange.Accept(); - - // ... and then do nothing. Pretty mean... - } - } -} diff --git a/CoAP.Example/CoAP.Server/Resources/FibonacciResource.cs b/CoAP.Example/CoAP.Server/Resources/FibonacciResource.cs deleted file mode 100644 index a73e7b6..0000000 --- a/CoAP.Example/CoAP.Server/Resources/FibonacciResource.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using CoAP.Server.Resources; - -namespace CoAP.Examples.Resources -{ - /// - /// This resource computes the Fibonacci numbers and therefore needs - /// a lot of computing power to respond to a request. Use the query ?n=20 to - /// compute the 20. Fibonacci number, e.g.: coap://localhost:5683/fibonacci?n=20. - /// - class FibonacciResource : Resource - { - public FibonacciResource(String name) - : base(name) - { } - - protected override void DoGet(CoapExchange exchange) - { - Int32? n = null; - foreach (String query in exchange.Request.UriQueries) - { - String[] tmp = query.Split('='); - if (tmp.Length != 2 || tmp[0] != "n") - continue; - n = Int32.Parse(tmp[1]); - } - if (n.HasValue) - exchange.Respond("Fibonacci(" + n.Value + ") = " + Fibonacci(n.Value)); - else - exchange.Respond("Missing n in query"); - } - - private UInt64 Fibonacci(Int32 n) - { - return Fibs(n)[1]; - } - - private UInt64[] Fibs(Int32 n) - { - if (n == 1) - return new[] { 0UL, 1UL }; - UInt64[] fibs = Fibs(n - 1); - return new[] { fibs[1], fibs[0] + fibs[1] }; - } - } -} diff --git a/CoAP.Example/CoAP.Server/Resources/HelloWorldResource.cs b/CoAP.Example/CoAP.Server/Resources/HelloWorldResource.cs deleted file mode 100644 index 9f9a897..0000000 --- a/CoAP.Example/CoAP.Server/Resources/HelloWorldResource.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using CoAP.Server.Resources; - -namespace CoAP.Examples.Resources -{ - /// - /// This resource responds with a kind "hello world" to GET requests. - /// - class HelloWorldResource : Resource - { - public HelloWorldResource(String name) - : base(name) - { - Attributes.Title = "GET a friendly greeting!"; - Attributes.AddResourceType("HelloWorldDisplayer"); - } - - protected override void DoGet(CoapExchange exchange) - { - exchange.Respond("Hello World!"); - } - } -} diff --git a/CoAP.Example/CoAP.Server/Resources/ImageResource.cs b/CoAP.Example/CoAP.Server/Resources/ImageResource.cs deleted file mode 100644 index 71db733..0000000 --- a/CoAP.Example/CoAP.Server/Resources/ImageResource.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.IO; -using CoAP.Server.Resources; - -namespace CoAP.Examples.Resources -{ - class ImageResource : Resource - { - private Int32[] _supported = new Int32[] { - MediaType.ImageJpeg, - MediaType.ImagePng - }; - - public ImageResource(String name) - : base(name) - { - Attributes.Title = "GET an image with different content-types"; - Attributes.AddResourceType("Image"); - - foreach (Int32 item in _supported) - { - Attributes.AddContentType(item); - } - - Attributes.MaximumSizeEstimate = 18029; - } - - protected override void DoGet(CoapExchange exchange) - { - String file = "data\\image\\"; - Int32 ct = MediaType.ImagePng; - Request request = exchange.Request; - - if ((ct = MediaType.NegotiationContent(ct, _supported, request.GetOptions(OptionType.Accept))) - == MediaType.Undefined) - { - exchange.Respond(StatusCode.NotAcceptable); - } - else - { - file += "image." + MediaType.ToFileExtension(ct); - if (File.Exists(file)) - { - Byte[] data = null; - - try - { - data = File.ReadAllBytes(file); - } - catch (Exception ex) - { - exchange.Respond(StatusCode.InternalServerError, "IO error"); - Console.WriteLine(ex.Message); - } - - Response response = new Response(StatusCode.Content); - response.Payload = data; - response.ContentType = ct; - exchange.Respond(response); - } - else - { - exchange.Respond(StatusCode.InternalServerError, "Image file not found"); - } - } - } - } -} diff --git a/CoAP.Example/CoAP.Server/Resources/LargeResource.cs b/CoAP.Example/CoAP.Server/Resources/LargeResource.cs deleted file mode 100644 index 8e006be..0000000 --- a/CoAP.Example/CoAP.Server/Resources/LargeResource.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Text; -using CoAP.Server.Resources; - -namespace CoAP.Examples.Resources -{ - class LargeResource : Resource - { - static String payload; - - static LargeResource() - { - payload = new StringBuilder() - .Append("/-------------------------------------------------------------\\\r\n") - .Append("| RESOURCE BLOCK NO. 1 OF 8 |\r\n") - .Append("| [each line contains 64 bytes] |\r\n") - .Append("\\-------------------------------------------------------------/\r\n") - .Append("/-------------------------------------------------------------\\\r\n") - .Append("| RESOURCE BLOCK NO. 2 OF 8 |\r\n") - .Append("| [each line contains 64 bytes] |\r\n") - .Append("\\-------------------------------------------------------------/\r\n") - .Append("/-------------------------------------------------------------\\\r\n") - .Append("| RESOURCE BLOCK NO. 3 OF 8 |\r\n") - .Append("| [each line contains 64 bytes] |\r\n") - .Append("\\-------------------------------------------------------------/\r\n") - .Append("/-------------------------------------------------------------\\\r\n") - .Append("| RESOURCE BLOCK NO. 4 OF 8 |\r\n") - .Append("| [each line contains 64 bytes] |\r\n") - .Append("\\-------------------------------------------------------------/\r\n") - .Append("/-------------------------------------------------------------\\\r\n") - .Append("| RESOURCE BLOCK NO. 5 OF 8 |\r\n") - .Append("| [each line contains 64 bytes] |\r\n") - .Append("\\-------------------------------------------------------------/\r\n") - .Append("/-------------------------------------------------------------\\\r\n") - .Append("| RESOURCE BLOCK NO. 6 OF 8 |\r\n") - .Append("| [each line contains 64 bytes] |\r\n") - .Append("\\-------------------------------------------------------------/\r\n") - .Append("/-------------------------------------------------------------\\\r\n") - .Append("| RESOURCE BLOCK NO. 7 OF 8 |\r\n") - .Append("| [each line contains 64 bytes] |\r\n") - .Append("\\-------------------------------------------------------------/\r\n") - .Append("/-------------------------------------------------------------\\\r\n") - .Append("| RESOURCE BLOCK NO. 8 OF 8 |\r\n") - .Append("| [each line contains 64 bytes] |\r\n") - .Append("\\-------------------------------------------------------------/\r\n") - .ToString(); - } - - public LargeResource(String name) - : base(name) - { - Attributes.Title = "This is a large resource for testing block-wise transfer"; - Attributes.AddResourceType("BlockWiseTransferTester"); - } - - protected override void DoGet(CoapExchange exchange) - { - exchange.Respond(payload); - } - - protected override void DoPost(CoAP.Server.Resources.CoapExchange exchange) - { - exchange.Respond(payload); - } - - protected override void DoPut(CoAP.Server.Resources.CoapExchange exchange) - { - exchange.Respond(payload); - } - } -} diff --git a/CoAP.Example/CoAP.Server/Resources/MirrorResource.cs b/CoAP.Example/CoAP.Server/Resources/MirrorResource.cs deleted file mode 100644 index e5ac31f..0000000 --- a/CoAP.Example/CoAP.Server/Resources/MirrorResource.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Text; -using CoAP.Net; -using CoAP.Server.Resources; - -namespace CoAP.Examples.Resources -{ - /// - /// This resource responds with the data from a request in its payload. This - /// resource responds to GET, POST, PUT and DELETE requests. - /// - class MirrorResource : Resource - { - public MirrorResource(String name) - : base(name) - { } - - public override void HandleRequest(Exchange exchange) - { - Request request = exchange.Request; - StringBuilder buffer = new StringBuilder(); - buffer.Append("resource ").Append(Uri).Append(" received request") - .Append("\n").Append("Code: ").Append(request.Code) - .Append("\n").Append("Source: ").Append(request.Source) - .Append("\n").Append("Type: ").Append(request.Type) - .Append("\n").Append("MID: ").Append(request.ID) - .Append("\n").Append("Token: ").Append(request.TokenString) - //.Append("\n").Append(request.Options) - ; - Response response = new Response(StatusCode.Content); - response.PayloadString = buffer.ToString(); - exchange.SendResponse(response); - } - } -} diff --git a/CoAP.Example/CoAP.Server/Resources/SeparateResource.cs b/CoAP.Example/CoAP.Server/Resources/SeparateResource.cs deleted file mode 100644 index 6dfc811..0000000 --- a/CoAP.Example/CoAP.Server/Resources/SeparateResource.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Threading; -using CoAP.Server.Resources; - -namespace CoAP.Examples.Resources -{ - /// - /// Represents a resource that returns a response in a separate CoAP message. - /// - class SeparateResource : Resource - { - public SeparateResource(String name) - : base(name) - { - Attributes.Title = "GET a response in a separate CoAP Message"; - Attributes.AddResourceType("SepararateResponseTester"); - } - - protected override void DoGet(CoapExchange exchange) - { - // Accept the request to promise the client this request will be acted. - exchange.Accept(); - - // Do sth. time-consuming - Thread.Sleep(2000); - - // Now respond the previous request. - Response response = new Response(StatusCode.Content); - response.PayloadString = "This message was sent by a separate response.\n" + - "Your client will need to acknowledge it, otherwise it will be retransmitted."; - - exchange.Respond(response); - } - } -} diff --git a/CoAP.Example/CoAP.Server/Resources/StorageResource.cs b/CoAP.Example/CoAP.Server/Resources/StorageResource.cs deleted file mode 100644 index 8255937..0000000 --- a/CoAP.Example/CoAP.Server/Resources/StorageResource.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using CoAP.Server.Resources; - -namespace CoAP.Examples.Resources -{ - class StorageResource : Resource - { - private String _content; - - public StorageResource(String name) - : base(name) - { } - - protected override void DoGet(CoapExchange exchange) - { - if (_content != null) - { - exchange.Respond(_content); - } - else - { - String subtree = LinkFormat.Serialize(this, null); - exchange.Respond(StatusCode.Content, subtree, MediaType.ApplicationLinkFormat); - } - } - - protected override void DoPost(CoapExchange exchange) - { - String payload = exchange.Request.PayloadString; - if (payload == null) - payload = String.Empty; - String[] parts = payload.Split('\\'); - String[] path = parts[0].Split('/'); - IResource resource = Create(new LinkedList(path)); - - Response response = new Response(StatusCode.Created); - response.LocationPath = resource.Uri; - exchange.Respond(response); - } - - protected override void DoPut(CoapExchange exchange) - { - _content = exchange.Request.PayloadString; - exchange.Respond(StatusCode.Changed); - } - - protected override void DoDelete(CoapExchange exchange) - { - this.Delete(); - exchange.Respond(StatusCode.Deleted); - } - - private IResource Create(LinkedList path) - { - String segment; - - do - { - if (path.Count == 0) - return this; - segment = path.First.Value; - path.RemoveFirst(); - } while (segment.Length == 0 || segment.Equals("/")); - - StorageResource resource = new StorageResource(segment); - Add(resource); - return resource.Create(path); - } - } -} diff --git a/CoAP.Example/CoAP.Server/Resources/TimeResource.cs b/CoAP.Example/CoAP.Server/Resources/TimeResource.cs deleted file mode 100644 index c2bf94b..0000000 --- a/CoAP.Example/CoAP.Server/Resources/TimeResource.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Threading; -using CoAP.Server.Resources; - -namespace CoAP.Examples.Resources -{ - class TimeResource : Resource - { - private Timer _timer; - private DateTime _now; - - public TimeResource(String name) - : base(name) - { - Attributes.Title = "GET the current time"; - Attributes.AddResourceType("CurrentTime"); - Observable = true; - - _timer = new Timer(Timed, null, 0, 2000); - } - - private void Timed(Object o) - { - _now = DateTime.Now; - Changed(); - } - - protected override void DoGet(CoapExchange exchange) - { - exchange.Respond(StatusCode.Content, _now.ToString(), MediaType.TextPlain); - } - } -} diff --git a/CoAP.NET/BlockOption.cs b/CoAP.NET/BlockOption.cs deleted file mode 100644 index 3cab12b..0000000 --- a/CoAP.NET/BlockOption.cs +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2011-2012, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; - -namespace CoAP -{ - /// - /// This class describes the block options of the CoAP messages - /// - public class BlockOption : Option - { - /// - /// Initializes a block option. - /// - /// The type of the option - public BlockOption(OptionType type) : base(type) - { - this.IntValue = 0; - } - - /// - /// Initializes a block option. - /// - /// The type of the option - /// Block number - /// Block size - /// More flag - public BlockOption(OptionType type, Int32 num, Int32 szx, Boolean m) : base(type) - { - this.IntValue = Encode(num, szx, m); - } - - /// - /// Sets block params. - /// - /// Block number - /// Block size - /// More flag - public void SetValue(Int32 num, Int32 szx, Boolean m) - { - this.IntValue = Encode(num, szx, m); - } - - /// - /// Gets or sets the block number. - /// - public Int32 NUM - { - get { return this.IntValue >> 4; } - set { SetValue(value, SZX, M); } - } - - /// - /// Gets or sets the block size. - /// - public Int32 SZX - { - get { return this.IntValue & 0x7; } - set { SetValue(NUM, value, M); } - } - - /// - /// Gets or sets the more flag. - /// - public Boolean M - { - get { return (this.IntValue >> 3 & 0x1) != 0; } - set { SetValue(NUM, SZX, value); } - } - - /// - /// Gets the decoded block size in bytes (B). - /// - public Int32 Size - { - get { return DecodeSZX(this.SZX); } - } - - /// - /// - /// - /// - public override String ToString() - { - return String.Format("{0}{1} ({2}B/block [{3}])", NUM, M ? "+" : String.Empty, Size, SZX); - } - - /// - /// Gets the real block size which is 2 ^ (SZX + 4). - /// - /// - /// - public static Int32 DecodeSZX(Int32 szx) - { - return 1 << (szx + 4); - } - - /// - /// Converts a block size into the corresponding SZX. - /// - /// - /// - public static Int32 EncodeSZX(Int32 blockSize) - { - if (blockSize < 16) - return 0; - if (blockSize > 1024) - return 6; - return (Int32)(Math.Log(blockSize) / Math.Log(2)) - 4; - } - - /// - /// Checks whether the given SZX is valid or not. - /// - /// - /// - public static Boolean ValidSZX(Int32 szx) - { - return (szx >= 0 && szx <= 6); - } - - private static Int32 Encode(Int32 num, Int32 szx, Boolean m) - { - Int32 value = 0; - value |= (szx & 0x7); - value |= (m ? 1 : 0) << 3; - value |= num << 4; - return value; - } - } -} diff --git a/CoAP.NET/Channel/DataReceivedEventArgs.cs b/CoAP.NET/Channel/DataReceivedEventArgs.cs deleted file mode 100644 index 2bc2a6c..0000000 --- a/CoAP.NET/Channel/DataReceivedEventArgs.cs +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2011-2014, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; - -namespace CoAP.Channel -{ - /// - /// Provides data for event. - /// - public class DataReceivedEventArgs : EventArgs - { - readonly Byte[] _data; - readonly System.Net.EndPoint _endPoint; - - /// - /// - public DataReceivedEventArgs(Byte[] data, System.Net.EndPoint endPoint) - { - _data = data; - _endPoint = endPoint; - } - - /// - /// Gets the received bytes. - /// - public Byte[] Data { get { return _data; } } - - /// - /// Gets the where the data is received from. - /// - public System.Net.EndPoint EndPoint { get { return _endPoint; } } - } -} diff --git a/CoAP.NET/Channel/IChannel.cs b/CoAP.NET/Channel/IChannel.cs deleted file mode 100644 index e82cfe7..0000000 --- a/CoAP.NET/Channel/IChannel.cs +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2011-2014, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; - -namespace CoAP.Channel -{ - /// - /// Represents a channel where bytes data can flow through. - /// - public interface IChannel : IDisposable - { - /// - /// Gets the local endpoint of this channel. - /// - System.Net.EndPoint LocalEndPoint { get; } - /// - /// Occurs when some bytes are received in this channel. - /// - event EventHandler DataReceived; - /// - /// Starts this channel. - /// - void Start(); - /// - /// Stops this channel. - /// - void Stop(); - /// - /// Sends data through this channel. This method should be non-blocking. - /// - /// the bytes to send - /// the target endpoint - void Send(Byte[] data, System.Net.EndPoint ep); - } -} diff --git a/CoAP.NET/Channel/IPAddressExtensions.cs b/CoAP.NET/Channel/IPAddressExtensions.cs deleted file mode 100644 index f0d97a6..0000000 --- a/CoAP.NET/Channel/IPAddressExtensions.cs +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2011-2014, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; -using System.Net; -using System.Net.Sockets; - -namespace CoAP.Channel -{ - /// - /// Extension methods for . - /// - public static class IPAddressExtensions - { - /// - /// Checks whether the IP address is an IPv4-mapped IPv6 address. - /// - /// the object to check - /// true if the IP address is an IPv4-mapped IPv6 address; otherwise, false. - public static Boolean IsIPv4MappedToIPv6(IPAddress address) - { - if (address.AddressFamily != AddressFamily.InterNetworkV6) - return false; - Byte[] bytes = address.GetAddressBytes(); - for (Int32 i = 0; i < 10; i++) - { - if (bytes[i] != 0) - return false; - } - return bytes[10] == 0xff && bytes[11] == 0xff; - } - - /// - /// Maps the object to an IPv4 address. - /// - /// the object - /// An IPv4 address. - public static IPAddress MapToIPv4(IPAddress address) - { - if (address.AddressFamily == AddressFamily.InterNetwork) - return address; - Byte[] bytes = address.GetAddressBytes(); - Int64 newAddress = (UInt32)(bytes[12] & 0xff) | (UInt32)(bytes[13] & 0xff) << 8 | (UInt32)(bytes[14] & 0xff) << 16 | (UInt32)(bytes[15] & 0xff) << 24; - return new IPAddress(newAddress); - } - - /// - /// Maps the object to an IPv6 address. - /// - /// the object - /// An IPv6 address. - public static IPAddress MapToIPv6(IPAddress address) - { - if (address.AddressFamily == AddressFamily.InterNetworkV6) - return address; - Byte[] bytes = address.GetAddressBytes(); - Byte[] newAddress = new Byte[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, bytes[0], bytes[1], bytes[2], bytes[3] }; - return new IPAddress(newAddress); - } - } -} diff --git a/CoAP.NET/Channel/UDPChannel.NET20.cs b/CoAP.NET/Channel/UDPChannel.NET20.cs deleted file mode 100644 index 54e5f93..0000000 --- a/CoAP.NET/Channel/UDPChannel.NET20.cs +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2011-2014, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; -using System.Net; -using System.Net.Sockets; - -namespace CoAP.Channel -{ - public partial class UDPChannel - { - private UDPSocket NewUDPSocket(AddressFamily addressFamily, Int32 bufferSize) - { - return new UDPSocket(addressFamily, bufferSize); - } - - private void BeginReceive(UDPSocket socket) - { - if (_running == 0) - return; - - System.Net.EndPoint remoteEP = new IPEndPoint( - socket.Socket.AddressFamily == AddressFamily.InterNetwork ? - IPAddress.Any : IPAddress.IPv6Any, 0); - - try - { - socket.Socket.BeginReceiveFrom(socket.Buffer, 0, socket.Buffer.Length, - SocketFlags.None, ref remoteEP, ReceiveCallback, socket); - } - catch (ObjectDisposedException) - { - // do nothing - } - catch (Exception ex) - { - EndReceive(socket, ex); - } - } - - private void ReceiveCallback(IAsyncResult ar) - { - UDPSocket socket = (UDPSocket)ar.AsyncState; - System.Net.EndPoint remoteEP = new IPEndPoint( - socket.Socket.AddressFamily == AddressFamily.InterNetwork ? - IPAddress.Any : IPAddress.IPv6Any, 0); - - Int32 count = 0; - try - { - count = socket.Socket.EndReceiveFrom(ar, ref remoteEP); - } - catch (ObjectDisposedException) - { - // do nothing - return; - } - catch (Exception ex) - { - EndReceive(socket, ex); - return; - } - - EndReceive(socket, socket.Buffer, 0, count, remoteEP); - } - - private void BeginSend(UDPSocket socket, Byte[] data, System.Net.EndPoint destination) - { - try - { - socket.Socket.BeginSendTo(data, 0, data.Length, SocketFlags.None, destination, SendCallback, socket); - } - catch (ObjectDisposedException) - { - // do nothing - } - catch (Exception ex) - { - EndSend(socket, ex); - } - } - - private void SendCallback(IAsyncResult ar) - { - UDPSocket socket = (UDPSocket)ar.AsyncState; - - Int32 written; - try - { - written = socket.Socket.EndSendTo(ar); - } - catch (ObjectDisposedException) - { - // do nothing - return; - } - catch (Exception ex) - { - EndSend(socket, ex); - return; - } - - EndSend(socket, written); - } - - partial class UDPSocket - { - public readonly Byte[] Buffer; - - public UDPSocket(AddressFamily addressFamily, Int32 bufferSize) - { - Socket = new Socket(addressFamily, SocketType.Dgram, ProtocolType.Udp); - Buffer = new Byte[bufferSize]; - } - - public void Dispose() - { - Socket.Close(); - } - } - } -} diff --git a/CoAP.NET/Channel/UDPChannel.NET40.cs b/CoAP.NET/Channel/UDPChannel.NET40.cs deleted file mode 100644 index 0351b8a..0000000 --- a/CoAP.NET/Channel/UDPChannel.NET40.cs +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2011-2014, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; -using System.Net; -using System.Net.Sockets; - -namespace CoAP.Channel -{ - public partial class UDPChannel - { - private UDPSocket NewUDPSocket(AddressFamily addressFamily, Int32 bufferSize) - { - return new UDPSocket(addressFamily, bufferSize, SocketAsyncEventArgs_Completed); - } - - private void BeginReceive(UDPSocket socket) - { - if (_running == 0) - return; - - if (socket.ReadBuffer.RemoteEndPoint == null) - { - socket.ReadBuffer.RemoteEndPoint = socket.Socket.Connected ? - socket.Socket.RemoteEndPoint : - new IPEndPoint(socket.Socket.AddressFamily == AddressFamily.InterNetwork ? - IPAddress.Any : IPAddress.IPv6Any, 0); - } - - Boolean willRaiseEvent; - try - { - willRaiseEvent = socket.Socket.ReceiveFromAsync(socket.ReadBuffer); - } - catch (ObjectDisposedException) - { - // do nothing - return; - } - catch (Exception ex) - { - EndReceive(socket, ex); - return; - } - - if (!willRaiseEvent) - { - ProcessReceive(socket.ReadBuffer); - } - } - - private void BeginSend(UDPSocket socket, Byte[] data, System.Net.EndPoint destination) - { - socket.SetWriteBuffer(data, 0, data.Length); - socket.WriteBuffer.RemoteEndPoint = destination; - - Boolean willRaiseEvent; - try - { - willRaiseEvent = socket.Socket.SendToAsync(socket.WriteBuffer); - } - catch (ObjectDisposedException) - { - // do nothing - return; - } - catch (Exception ex) - { - EndSend(socket, ex); - return; - } - - if (!willRaiseEvent) - { - ProcessSend(socket.WriteBuffer); - } - } - - private void ProcessReceive(SocketAsyncEventArgs e) - { - UDPSocket socket = (UDPSocket)e.UserToken; - - if (e.SocketError == SocketError.Success) - { - EndReceive(socket, e.Buffer, e.Offset, e.BytesTransferred, e.RemoteEndPoint); - } - else if (e.SocketError != SocketError.OperationAborted - && e.SocketError != SocketError.Interrupted) - { - EndReceive(socket, new SocketException((Int32)e.SocketError)); - } - } - - private void ProcessSend(SocketAsyncEventArgs e) - { - UDPSocket socket = (UDPSocket)e.UserToken; - - if (e.SocketError == SocketError.Success) - { - EndSend(socket, e.BytesTransferred); - } - else - { - EndSend(socket, new SocketException((Int32)e.SocketError)); - } - } - - void SocketAsyncEventArgs_Completed(Object sender, SocketAsyncEventArgs e) - { - switch (e.LastOperation) - { - case SocketAsyncOperation.ReceiveFrom: - ProcessReceive(e); - break; - case SocketAsyncOperation.SendTo: - ProcessSend(e); - break; - } - } - - partial class UDPSocket - { - public readonly SocketAsyncEventArgs ReadBuffer; - public readonly SocketAsyncEventArgs WriteBuffer; - readonly Byte[] _writeBuffer; - private Boolean _isOuterBuffer; - - public UDPSocket(AddressFamily addressFamily, Int32 bufferSize, - EventHandler completed) - { - Socket = new Socket(addressFamily, SocketType.Dgram, ProtocolType.Udp); - ReadBuffer = new SocketAsyncEventArgs(); - ReadBuffer.SetBuffer(new Byte[bufferSize], 0, bufferSize); - ReadBuffer.Completed += completed; - ReadBuffer.UserToken = this; - - _writeBuffer = new Byte[bufferSize]; - WriteBuffer = new SocketAsyncEventArgs(); - WriteBuffer.SetBuffer(_writeBuffer, 0, bufferSize); - WriteBuffer.Completed += completed; - WriteBuffer.UserToken = this; - } - - public void SetWriteBuffer(Byte[] data, Int32 offset, Int32 count) - { - if (count > _writeBuffer.Length) - { - WriteBuffer.SetBuffer(data, offset, count); - _isOuterBuffer = true; - } - else - { - if (_isOuterBuffer) - { - WriteBuffer.SetBuffer(_writeBuffer, 0, _writeBuffer.Length); - _isOuterBuffer = false; - } - Buffer.BlockCopy(data, offset, _writeBuffer, 0, count); - WriteBuffer.SetBuffer(0, count); - } - } - - public void Dispose() - { - Socket.Close(); - ReadBuffer.Dispose(); - WriteBuffer.Dispose(); - } - } - } -} diff --git a/CoAP.NET/Channel/UDPChannel.cs b/CoAP.NET/Channel/UDPChannel.cs deleted file mode 100644 index e4fdb03..0000000 --- a/CoAP.NET/Channel/UDPChannel.cs +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright (c) 2011-2014, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; -using System.Collections.Concurrent; -using System.Net; -using System.Net.Sockets; - -namespace CoAP.Channel -{ - /// - /// Channel via UDP protocol. - /// - public partial class UDPChannel : IChannel - { - /// - /// Default size of buffer for receiving packet. - /// - public const Int32 DefaultReceivePacketSize = 4096; - private Int32 _receiveBufferSize; - private Int32 _sendBufferSize; - private Int32 _receivePacketSize = DefaultReceivePacketSize; - private Int32 _port; - private System.Net.EndPoint _localEP; - private UDPSocket _socket; - private UDPSocket _socketBackup; - private Int32 _running; - private Int32 _writing; - private readonly ConcurrentQueue _sendingQueue = new ConcurrentQueue(); - - /// - public event EventHandler DataReceived; - - /// - /// Initializes a UDP channel with a random port. - /// - public UDPChannel() - : this(0) - { - } - - /// - /// Initializes a UDP channel with the given port, both on IPv4 and IPv6. - /// - public UDPChannel(Int32 port) - { - _port = port; - } - - /// - /// Initializes a UDP channel with the specific endpoint. - /// - public UDPChannel(System.Net.EndPoint localEP) - { - _localEP = localEP; - } - - /// - public System.Net.EndPoint LocalEndPoint - { - get - { - return _socket == null - ? (_localEP ?? new IPEndPoint(IPAddress.IPv6Any, _port)) - : _socket.Socket.LocalEndPoint; - } - } - - /// - /// Gets or sets the . - /// - public Int32 ReceiveBufferSize - { - get { return _receiveBufferSize; } - set { _receiveBufferSize = value; } - } - - /// - /// Gets or sets the . - /// - public Int32 SendBufferSize - { - get { return _sendBufferSize; } - set { _sendBufferSize = value; } - } - - /// - /// Gets or sets the size of buffer for receiving packet. - /// The default value is . - /// - public Int32 ReceivePacketSize - { - get { return _receivePacketSize; } - set { _receivePacketSize = value; } - } - - /// - public void Start() - { - if (System.Threading.Interlocked.CompareExchange(ref _running, 1, 0) > 0) - return; - - if (_localEP == null) - { - try - { - _socket = SetupUDPSocket(AddressFamily.InterNetworkV6, _receivePacketSize + 1); // +1 to check for > ReceivePacketSize - } - catch (SocketException e) - { - if (e.SocketErrorCode == SocketError.AddressFamilyNotSupported) - _socket = null; - else - throw e; - } - - if (_socket == null) - { - // IPv6 is not supported, use IPv4 instead - _socket = SetupUDPSocket(AddressFamily.InterNetwork, _receivePacketSize + 1); - _socket.Socket.Bind(new IPEndPoint(IPAddress.Any, _port)); - } - else - { - try - { - // Enable IPv4-mapped IPv6 addresses to accept both IPv6 and IPv4 connections in a same socket. - _socket.Socket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, 0); - } - catch - { - // IPv4-mapped address seems not to be supported, set up a separated socket of IPv4. - _socketBackup = SetupUDPSocket(AddressFamily.InterNetwork, _receivePacketSize + 1); - } - - _socket.Socket.Bind(new IPEndPoint(IPAddress.IPv6Any, _port)); - if (_socketBackup != null) - _socketBackup.Socket.Bind(new IPEndPoint(IPAddress.Any, _port)); - } - } - else - { - _socket = SetupUDPSocket(_localEP.AddressFamily, _receivePacketSize + 1); - _socket.Socket.Bind(_localEP); - } - - if (_receiveBufferSize > 0) - { - _socket.Socket.ReceiveBufferSize = _receiveBufferSize; - if (_socketBackup != null) - _socketBackup.Socket.ReceiveBufferSize = _receiveBufferSize; - } - if (_sendBufferSize > 0) - { - _socket.Socket.SendBufferSize = _sendBufferSize; - if (_socketBackup != null) - _socketBackup.Socket.SendBufferSize = _sendBufferSize; - } - - BeginReceive(); - } - - /// - public void Stop() - { - if (System.Threading.Interlocked.Exchange(ref _running, 0) == 0) - return; - - if (_socket != null) - { - _socket.Dispose(); - _socket = null; - } - if (_socketBackup != null) - { - _socketBackup.Dispose(); - _socketBackup = null; - } - } - - /// - public void Send(Byte[] data, System.Net.EndPoint ep) - { - RawData raw = new RawData(); - raw.Data = data; - raw.EndPoint = ep; - _sendingQueue.Enqueue(raw); - if (System.Threading.Interlocked.CompareExchange(ref _writing, 1, 0) > 0) - return; - BeginSend(); - } - - /// - public void Dispose() - { - Stop(); - } - - private void BeginReceive() - { - if (_running > 0) - { - BeginReceive(_socket); - - if (_socketBackup != null) - BeginReceive(_socketBackup); - } - } - - private void EndReceive(UDPSocket socket, Byte[] buffer, Int32 offset, Int32 count, System.Net.EndPoint ep) - { - if (count > 0) - { - Byte[] bytes = new Byte[count]; - Buffer.BlockCopy(buffer, 0, bytes, 0, count); - - if (ep.AddressFamily == AddressFamily.InterNetworkV6) - { - IPEndPoint ipep = (IPEndPoint)ep; - if (IPAddressExtensions.IsIPv4MappedToIPv6(ipep.Address)) - ep = new IPEndPoint(IPAddressExtensions.MapToIPv4(ipep.Address), ipep.Port); - } - - FireDataReceived(bytes, ep); - } - - BeginReceive(socket); - } - - private void EndReceive(UDPSocket socket, Exception ex) - { - // TODO may log exception? - BeginReceive(socket); - } - - private void FireDataReceived(Byte[] data, System.Net.EndPoint ep) - { - EventHandler h = DataReceived; - if (h != null) - h(this, new DataReceivedEventArgs(data, ep)); - } - - private void BeginSend() - { - if (_running == 0) - return; - - RawData raw; - if (!_sendingQueue.TryDequeue(out raw)) - { - System.Threading.Interlocked.Exchange(ref _writing, 0); - return; - } - - UDPSocket socket = _socket; - IPEndPoint remoteEP = (IPEndPoint)raw.EndPoint; - - if (remoteEP.AddressFamily == AddressFamily.InterNetwork) - { - if (_socketBackup != null) - { - // use the separated socket of IPv4 to deal with IPv4 conversions. - socket = _socketBackup; - } - else if (_socket.Socket.AddressFamily == AddressFamily.InterNetworkV6) - { - remoteEP = new IPEndPoint(IPAddressExtensions.MapToIPv6(remoteEP.Address), remoteEP.Port); - } - } - - BeginSend(socket, raw.Data, remoteEP); - } - - private void EndSend(UDPSocket socket, Int32 bytesTransferred) - { - BeginSend(); - } - - private void EndSend(UDPSocket socket, Exception ex) - { - // TODO may log exception? - BeginSend(); - } - - private UDPSocket SetupUDPSocket(AddressFamily addressFamily, Int32 bufferSize) - { - UDPSocket socket = NewUDPSocket(addressFamily, bufferSize); - - // do not throw SocketError.ConnectionReset by ignoring ICMP Port Unreachable - const Int32 SIO_UDP_CONNRESET = -1744830452; - try - { - socket.Socket.IOControl(SIO_UDP_CONNRESET, new Byte[] { 0 }, null); - } - catch (Exception e) - { - // ignore - } - return socket; - } - - partial class UDPSocket : IDisposable - { - public readonly Socket Socket; - } - - class RawData - { - public Byte[] Data; - public System.Net.EndPoint EndPoint; - } - } -} diff --git a/CoAP.NET/CoAP.NET.DNX.xproj b/CoAP.NET/CoAP.NET.DNX.xproj deleted file mode 100644 index b92cda3..0000000 --- a/CoAP.NET/CoAP.NET.DNX.xproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - 5c1902a3-a1c7-432c-bcc2-3669ce1ec376 - CoAP.NET.DNX - ..\artifacts\obj\$(MSBuildProjectName) - ..\artifacts\bin\$(MSBuildProjectName)\ - - - 2.0 - - - - \ No newline at end of file diff --git a/CoAP.NET/CoAP.NET.csproj b/CoAP.NET/CoAP.NET.csproj deleted file mode 100644 index 2672d5f..0000000 --- a/CoAP.NET/CoAP.NET.csproj +++ /dev/null @@ -1,167 +0,0 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {45DB1E45-4831-4E4A-BB1E-AE92EEA182E3} - Library - Properties - CoAP - CoAP.NET - v2.0 - 512 - - - - true - full - false - bin\Debug\NET20\ - TRACE;DEBUG;COAPALL - prompt - 4 - true - - - pdbonly - true - bin\Release\NET20\ - TRACE;COAPALL - prompt - 4 - bin\Release\NET20\CoAP.NET.XML - true - - - true - - - coapnet.snk - - - - lib\NET20\Common.Logging.dll - - - lib\NET20\Common.Logging.Core.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/CoAP.NET/CoAP.NET.iOS.csproj b/CoAP.NET/CoAP.NET.iOS.csproj deleted file mode 100644 index e28cde5..0000000 --- a/CoAP.NET/CoAP.NET.iOS.csproj +++ /dev/null @@ -1,96 +0,0 @@ - - - - Debug - AnyCPU - 10.0.0 - 2.0 - {2DD6EC50-507A-4891-9EB9-847907BD5F1D} - {6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Library - CoAP.NET.iOS - Resources - CoAP.NET.iOS - - - true - full - false - bin\Debug - TRACE;DEBUG;COAPALL - prompt - 4 - false - - - full - true - bin\Release - prompt - 4 - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/CoAP.NET/CoAP.NET40.csproj b/CoAP.NET/CoAP.NET40.csproj deleted file mode 100644 index 7333e40..0000000 --- a/CoAP.NET/CoAP.NET40.csproj +++ /dev/null @@ -1,157 +0,0 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {45DB1E45-4831-4E4A-BB1E-AE92EEA182E3} - Library - Properties - CoAP - CoAP.NET - v4.0 - 512 - - - - true - full - false - bin\Debug\NET40\ - TRACE;DEBUG;COAPALL - prompt - 4 - - - pdbonly - true - bin\Release\NET40\ - TRACE;COAPALL - prompt - 4 - bin\Release\NET40\CoAP.NET.XML - - - true - - - coapnet.snk - - - - ..\packages\Common.Logging.3.0.0\lib\net40\Common.Logging.dll - - - ..\packages\Common.Logging.Core.3.0.0\lib\net40\Common.Logging.Core.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/CoAP.NET/CoapClient.cs b/CoAP.NET/CoapClient.cs deleted file mode 100644 index 45c7968..0000000 --- a/CoAP.NET/CoapClient.cs +++ /dev/null @@ -1,556 +0,0 @@ -/* - * Copyright (c) 2011-2015, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; -using System.Collections.Generic; -using CoAP.Log; -using CoAP.Net; -using CoAP.Observe; - -namespace CoAP -{ - /// - /// Provides convenient methods for accessing CoAP resources. - /// - public class CoapClient - { - private static ILogger log = LogManager.GetLogger(typeof(CoapClient)); - private static readonly IEnumerable EmptyLinks = new WebLink[0]; - private Uri _uri; - private ICoapConfig _config; - private IEndPoint _endpoint; - private MessageType _type = MessageType.CON; - private Int32 _blockwise; - private Int32 _timeout = System.Threading.Timeout.Infinite; - - /// - /// Occurs when a response has arrived. - /// - public event EventHandler Respond; - /// - /// Occurs if an exception is thrown while executing a request. - /// - public event EventHandler Error; - - /// - /// Instantiates with default config. - /// - public CoapClient() - : this(null, null) - { } - - /// - /// Instantiates with default config. - /// - /// the Uri of remote resource - public CoapClient(Uri uri) - : this(uri, null) - { } - - /// - /// Instantiates. - /// - /// the config - public CoapClient(ICoapConfig config) - : this(null, config) - { } - - /// - /// Instantiates. - /// - /// the Uri of remote resource - /// the config - public CoapClient(Uri uri, ICoapConfig config) - { - _uri = uri; - _config = config ?? CoapConfig.Default; - } - - /// - /// Gets or sets the destination URI of this client. - /// - public Uri Uri - { - get { return _uri; } - set { _uri = value; } - } - - /// - /// Gets or sets the endpoint this client is supposed to use. - /// - public IEndPoint EndPoint - { - get { return _endpoint; } - set { _endpoint = value; } - } - - /// - /// Gets or sets the timeout how long synchronous method calls will wait - /// until they give up and return anyways. The default value is . - /// - public Int32 Timeout - { - get { return _timeout; } - set { _timeout = value; } - } - - /// - /// Let the client use Confirmable requests. - /// - public CoapClient UseCONs() - { - _type = MessageType.CON; - return this; - } - - /// - /// Let the client use Non-Confirmable requests. - /// - public CoapClient UseNONs() - { - _type = MessageType.NON; - return this; - } - - /// - /// Let the client use early negotiation for the blocksize - /// (16, 32, 64, 128, 256, 512, or 1024). Other values will - /// be matched to the closest logarithm dualis. - /// - public CoapClient UseEarlyNegotiation(Int32 size) - { - _blockwise = size; - return this; - } - - /// - /// Let the client use late negotiation for the block size (default). - /// - public CoapClient UseLateNegotiation() - { - _blockwise = 0; - return this; - } - - /// - /// Performs a CoAP ping. - /// - /// success of the ping - public Boolean Ping() - { - return Ping(_timeout); - } - - /// - /// Performs a CoAP ping and gives up after the given number of milliseconds. - /// - /// the time to wait for a pong in milliseconds - /// success of the ping - public Boolean Ping(Int32 timeout) - { - try - { - Request request = new Request(Code.Empty, true); - request.Token = CoapConstants.EmptyToken; - request.URI = Uri; - request.Send().WaitForResponse(timeout); - return request.IsRejected; - } - catch (System.Threading.ThreadInterruptedException) - { - /* ignore */ - } - return false; - } - - /// - /// Discovers remote resources. - /// - /// the descoverd representing remote resources, or null if no response - public IEnumerable Discover() - { - return Discover(null); - } - - /// - /// Discovers remote resources. - /// - /// the query to filter resources - /// the descoverd representing remote resources, or null if no response - public IEnumerable Discover(String query) - { - Request discover = Prepare(Request.NewGet()); - discover.ClearUriPath().ClearUriQuery().UriPath = CoapConstants.DefaultWellKnownURI; - if (!String.IsNullOrEmpty(query)) - discover.UriQuery = query; - Response links = discover.Send().WaitForResponse(_timeout); - if (links == null) - // if no response, return null (e.g., timeout) - return null; - else if (links.ContentFormat != MediaType.ApplicationLinkFormat) - return EmptyLinks; - else - return LinkFormat.Parse(links.PayloadString); - } - - /// - /// Sends a GET request and blocks until the response is available. - /// - /// the CoAP response - public Response Get() - { - return Send(Request.NewGet()); - } - - /// - /// Sends a GET request with the specified Accept option and blocks - /// until the response is available. - /// - /// the Accept option - /// the CoAP response - public Response Get(Int32 accept) - { - return Send(Accept(Request.NewGet(), accept)); - } - - /// - /// Sends a GET request asynchronizely. - /// - /// the callback when a response arrives - /// the callback when an error occurs - public void GetAsync(Action done = null, Action fail = null) - { - SendAsync(Request.NewGet(), done, fail); - } - - /// - /// Sends a GET request with the specified Accept option asynchronizely. - /// - /// the Accept option - /// the callback when a response arrives - /// the callback when an error occurs - public void GetAsync(Int32 accept, Action done = null, Action fail = null) - { - SendAsync(Accept(Request.NewGet(), accept), done, fail); - } - - public Response Post(String payload, Int32 format = MediaType.TextPlain) - { - return Send((Request)Request.NewPost().SetPayload(payload, format)); - } - - public Response Post(String payload, Int32 format, Int32 accept) - { - return Send(Accept((Request)Request.NewPost().SetPayload(payload, format), accept)); - } - - public Response Post(Byte[] payload, Int32 format) - { - return Send((Request)Request.NewPost().SetPayload(payload, format)); - } - - public Response Post(Byte[] payload, Int32 format, Int32 accept) - { - return Send(Accept((Request)Request.NewPost().SetPayload(payload, format), accept)); - } - - public void PostAsync(String payload, - Action done = null, Action fail = null) - { - PostAsync(payload, MediaType.TextPlain, done, fail); - } - - public void PostAsync(String payload, Int32 format, - Action done = null, Action fail = null) - { - SendAsync((Request)Request.NewPost().SetPayload(payload, format), done, fail); - } - - public void PostAsync(String payload, Int32 format, Int32 accept, - Action done = null, Action fail = null) - { - SendAsync(Accept((Request)Request.NewPost().SetPayload(payload, format), accept), done, fail); - } - - public void PostAsync(Byte[] payload, Int32 format, - Action done = null, Action fail = null) - { - SendAsync((Request)Request.NewPost().SetPayload(payload, format), done, fail); - } - - public void PostAsync(Byte[] payload, Int32 format, Int32 accept, - Action done = null, Action fail = null) - { - SendAsync(Accept((Request)Request.NewPost().SetPayload(payload, format), accept), done, fail); - } - - public Response Put(String payload, Int32 format = MediaType.TextPlain) - { - return Send((Request)Request.NewPut().SetPayload(payload, format)); - } - - public Response Put(Byte[] payload, Int32 format, Int32 accept) - { - return Send(Accept((Request)Request.NewPut().SetPayload(payload, format), accept)); - } - - public Response PutIfMatch(String payload, Int32 format, params Byte[][] etags) - { - return Send(IfMatch((Request)Request.NewPut().SetPayload(payload, format), etags)); - } - - public Response PutIfMatch(Byte[] payload, Int32 format, params Byte[][] etags) - { - return Send(IfMatch((Request)Request.NewPut().SetPayload(payload, format), etags)); - } - - public Response PutIfNoneMatch(String payload, Int32 format) - { - return Send(IfNoneMatch((Request)Request.NewPut().SetPayload(payload, format))); - } - - public Response PutIfNoneMatch(Byte[] payload, Int32 format) - { - return Send(IfNoneMatch((Request)Request.NewPut().SetPayload(payload, format))); - } - - public void PutAsync(String payload, - Action done = null, Action fail = null) - { - PutAsync(payload, MediaType.TextPlain, done, fail); - } - - public void PutAsync(String payload, Int32 format, - Action done = null, Action fail = null) - { - SendAsync((Request)Request.NewPut().SetPayload(payload, format), done, fail); - } - - public void PutAsync(Byte[] payload, Int32 format, Int32 accept, - Action done = null, Action fail = null) - { - SendAsync(Accept((Request)Request.NewPut().SetPayload(payload, format), accept), done, fail); - } - - /// - /// Sends a DELETE request and waits for the response. - /// - /// the CoAP response - public Response Delete() - { - return Send(Request.NewDelete()); - } - - /// - /// Sends a DELETE request asynchronizely. - /// - /// the callback when a response arrives - /// the callback when an error occurs - public void DeleteAsync(Action done = null, Action fail = null) - { - SendAsync(Request.NewDelete(), done, fail); - } - - public Response Validate(params Byte[][] etags) - { - return Send(ETags(Request.NewGet(), etags)); - } - - public CoapObserveRelation Observe(Action notify = null, Action error = null) - { - return Observe(Request.NewGet().MarkObserve(), notify, error); - } - - public CoapObserveRelation Observe(Int32 accept, Action notify = null, Action error = null) - { - return Observe(Accept(Request.NewGet().MarkObserve(), accept), notify, error); - } - - public CoapObserveRelation ObserveAsync(Action notify = null, Action error = null) - { - return ObserveAsync(Request.NewGet().MarkObserve(), notify, error); - } - - public CoapObserveRelation ObserveAsync(Int32 accept, Action notify = null, Action error = null) - { - return ObserveAsync(Accept(Request.NewGet().MarkObserve(), accept), notify, error); - } - - public Response Send(Request request) - { - return Prepare(request).Send().WaitForResponse(_timeout); - } - - public void SendAsync(Request request, Action done = null, Action fail = null) - { - request.Respond += (o, e) => Deliver(done, e); - request.Rejected += (o, e) => Fail(fail, FailReason.Rejected); - request.TimedOut += (o, e) => Fail(fail, FailReason.TimedOut); - - Prepare(request).Send(); - } - - protected Request Prepare(Request request) - { - return Prepare(request, GetEffectiveEndpoint(request)); - } - - protected Request Prepare(Request request, IEndPoint endpoint) - { - request.Type = _type; - request.URI = _uri; - - if (_blockwise != 0) - request.SetBlock2(BlockOption.EncodeSZX(_blockwise), false, 0); - - if (endpoint != null) - request.EndPoint = endpoint; - - return request; - } - - /// - /// Gets the effective endpoint that the specified request - /// is supposed to be sent over. - /// - protected IEndPoint GetEffectiveEndpoint(Request request) - { - if (_endpoint != null) - return _endpoint; - else - return EndPointManager.Default; - // TODO secure coap - } - - private CoapObserveRelation Observe(Request request, Action notify, Action error) - { - CoapObserveRelation relation = ObserveAsync(request, notify, error); - Response response = relation.Request.WaitForResponse(_timeout); - if (response == null || !response.HasOption(OptionType.Observe)) - relation.Canceled = true; - relation.Current = response; - return relation; - } - - private CoapObserveRelation ObserveAsync(Request request, Action notify, Action error) - { - IEndPoint endpoint = GetEffectiveEndpoint(request); - CoapObserveRelation relation = new CoapObserveRelation(request, endpoint, _config); - - request.Respond += (o, e) => - { - Response resp = e.Response; - lock (relation) - { - if (relation.Orderer.IsNew(resp)) - { - relation.Current = resp; - Deliver(notify, e); - } - else - { - if (log.IsDebugEnabled) - log.Debug("Dropping old notification: " + resp); - } - } - }; - Action fail = r => - { - relation.Canceled = true; - Fail(error, r); - }; - request.Rejected += (o, e) => fail(FailReason.Rejected); - request.TimedOut += (o, e) => fail(FailReason.TimedOut); - - Prepare(request, endpoint).Send(); - return relation; - } - - private void Deliver(Action act, ResponseEventArgs e) - { - if (act != null) - act(e.Response); - EventHandler h = Respond; - if (h != null) - h(this, e); - } - - private void Fail(Action fail, FailReason reason) - { - if (fail != null) - fail(reason); - EventHandler h = Error; - if (h != null) - h(this, new ErrorEventArgs(reason)); - } - - static Request Accept(Request request, Int32 accept) - { - request.Accept = accept; - return request; - } - - static Request IfMatch(Request request, params Byte[][] etags) - { - foreach (Byte[] etag in etags) - { - request.AddIfMatch(etag); - } - return request; - } - - static Request IfNoneMatch(Request request) - { - request.IfNoneMatch = true; - return request; - } - - static Request ETags(Request request, params Byte[][] etags) - { - foreach (Byte[] etag in etags) - { - request.AddETag(etag); - } - return request; - } - - /// - /// Provides details about errors. - /// - public enum FailReason - { - /// - /// The request has been rejected. - /// - Rejected, - /// - /// The request has been timed out. - /// - TimedOut - } - - /// - /// Provides event args for errors. - /// - public class ErrorEventArgs : EventArgs - { - internal ErrorEventArgs(FailReason reason) - { - this.Reason = reason; - } - - /// - /// Gets the reason why failed. - /// - public FailReason Reason { get; private set; } - } - } -} diff --git a/CoAP.NET/CoapConfig.cs b/CoAP.NET/CoapConfig.cs deleted file mode 100644 index a9d01f0..0000000 --- a/CoAP.NET/CoapConfig.cs +++ /dev/null @@ -1,517 +0,0 @@ -/* - * Copyright (c) 2011-2015, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; -using System.Collections.Specialized; -using System.ComponentModel; -using System.IO; - -namespace CoAP -{ - /// - /// Default implementation of . - /// - public partial class CoapConfig : ICoapConfig - { - private static ICoapConfig _default; - - public static ICoapConfig Default - { - get - { - if (_default == null) - { - lock (typeof(CoapConfig)) - { - if (_default == null) - _default = LoadConfig(); - } - } - return _default; - } - } - - private Int32 _port; - private Int32 _securePort = CoapConstants.DefaultSecurePort; - private Int32 _httpPort = 8080; - private Int32 _ackTimeout = CoapConstants.AckTimeout; - private Double _ackRandomFactor = CoapConstants.AckRandomFactor; - private Double _ackTimeoutScale = 2D; - private Int32 _maxRetransmit = CoapConstants.MaxRetransmit; - private Int32 _maxMessageSize = 1024; - private Int32 _defaultBlockSize = CoapConstants.DefaultBlockSize; - private Int32 _blockwiseStatusLifetime = 10 * 60 * 1000; // ms - private Boolean _useRandomIDStart = true; - private Boolean _useRandomTokenStart = true; - private String _deduplicator = CoAP.Deduplication.DeduplicatorFactory.MarkAndSweepDeduplicator; - private Int32 _cropRotationPeriod = 2000; // ms - private Int32 _exchangeLifetime = 247 * 1000; // ms - private Int64 _markAndSweepInterval = 10 * 1000; // ms - private Int64 _notificationMaxAge = 128 * 1000; // ms - private Int64 _notificationCheckIntervalTime = 24 * 60 * 60 * 1000; // ms - private Int32 _notificationCheckIntervalCount = 100; // ms - private Int32 _notificationReregistrationBackoff = 2000; // ms - private Int32 _channelReceiveBufferSize; - private Int32 _channelSendBufferSize; - private Int32 _channelReceivePacketSize = 2048; - - /// - /// Instantiate. - /// - public CoapConfig() - { - _port = Spec.DefaultPort; - } - - /// - public String Version - { - get { return Spec.Name; } - } - - /// - public Int32 DefaultPort - { - get { return _port; } - set - { - if (_port != value) - { - _port = value; - NotifyPropertyChanged("DefaultPort"); - } - } - } - - /// - public Int32 DefaultSecurePort - { - get { return _securePort; } - set - { - if (_securePort != value) - { - _securePort = value; - NotifyPropertyChanged("DefaultSecurePort"); - } - } - } - - /// - public Int32 HttpPort - { - get { return _httpPort; } - set - { - if (_httpPort != value) - { - _httpPort = value; - NotifyPropertyChanged("HttpPort"); - } - } - } - - /// - public Int32 AckTimeout - { - get { return _ackTimeout; } - set - { - if (_ackTimeout != value) - { - _ackTimeout = value; - NotifyPropertyChanged("AckTimeout"); - } - } - } - - /// - public Double AckRandomFactor - { - get { return _ackRandomFactor; } - set - { - if (_ackRandomFactor != value) - { - _ackRandomFactor = value; - NotifyPropertyChanged("AckRandomFactor"); - } - } - } - - /// - public Double AckTimeoutScale - { - get { return _ackTimeoutScale; } - set - { - if (_ackTimeoutScale != value) - { - _ackTimeoutScale = value; - NotifyPropertyChanged("AckTimeoutScale"); - } - } - } - - /// - public Int32 MaxRetransmit - { - get { return _maxRetransmit; } - set - { - if (_maxRetransmit != value) - { - _maxRetransmit = value; - NotifyPropertyChanged("MaxRetransmit"); - } - } - } - - /// - public Int32 MaxMessageSize - { - get { return _maxMessageSize; } - set - { - if (_maxMessageSize != value) - { - _maxMessageSize = value; - NotifyPropertyChanged("MaxMessageSize"); - } - } - } - - /// - public Int32 DefaultBlockSize - { - get { return _defaultBlockSize; } - set - { - if (_defaultBlockSize != value) - { - _defaultBlockSize = value; - NotifyPropertyChanged("DefaultBlockSize"); - } - } - } - - /// - public Int32 BlockwiseStatusLifetime - { - get { return _blockwiseStatusLifetime; } - set - { - if (_blockwiseStatusLifetime != value) - { - _blockwiseStatusLifetime = value; - NotifyPropertyChanged("BlockwiseStatusLifetime"); - } - } - } - - /// - public Boolean UseRandomIDStart - { - get { return _useRandomIDStart; } - set - { - if (_useRandomIDStart != value) - { - _useRandomIDStart = value; - NotifyPropertyChanged("UseRandomIDStart"); - } - } - } - - /// - public Boolean UseRandomTokenStart - { - get { return _useRandomTokenStart; } - set - { - if (_useRandomTokenStart != value) - { - _useRandomTokenStart = value; - NotifyPropertyChanged("UseRandomTokenStart"); - } - } - } - - /// - public String Deduplicator - { - get { return _deduplicator; } - set - { - if (_deduplicator != value) - { - _deduplicator = value; - NotifyPropertyChanged("Deduplicator"); - } - } - } - - /// - public Int32 CropRotationPeriod - { - get { return _cropRotationPeriod; } - set - { - if (_cropRotationPeriod != value) - { - _cropRotationPeriod = value; - NotifyPropertyChanged("CropRotationPeriod"); - } - } - } - - /// - public Int32 ExchangeLifetime - { - get { return _exchangeLifetime; } - set - { - if (_exchangeLifetime != value) - { - _exchangeLifetime = value; - NotifyPropertyChanged("ExchangeLifetime"); - } - } - } - - /// - public Int64 MarkAndSweepInterval - { - get { return _markAndSweepInterval; } - set - { - if (_markAndSweepInterval != value) - { - _markAndSweepInterval = value; - NotifyPropertyChanged("MarkAndSweepInterval"); - } - } - } - - /// - public Int64 NotificationMaxAge - { - get { return _notificationMaxAge; } - set - { - if (_notificationMaxAge != value) - { - _notificationMaxAge = value; - NotifyPropertyChanged("NotificationMaxAge"); - } - } - } - - /// - public Int64 NotificationCheckIntervalTime - { - get { return _notificationCheckIntervalTime; } - set - { - if (_notificationCheckIntervalTime != value) - { - _notificationCheckIntervalTime = value; - NotifyPropertyChanged("NotificationCheckIntervalTime"); - } - } - } - - /// - public Int32 NotificationCheckIntervalCount - { - get { return _notificationCheckIntervalCount; } - set - { - if (_notificationCheckIntervalCount != value) - { - _notificationCheckIntervalCount = value; - NotifyPropertyChanged("NotificationCheckIntervalCount"); - } - } - } - - /// - public Int32 NotificationReregistrationBackoff - { - get { return _notificationReregistrationBackoff; } - set - { - if (_notificationReregistrationBackoff != value) - { - _notificationReregistrationBackoff = value; - NotifyPropertyChanged("NotificationReregistrationBackoff"); - } - } - } - - /// - public Int32 ChannelReceiveBufferSize - { - get { return _channelReceiveBufferSize; } - set - { - if (_channelReceiveBufferSize != value) - { - _channelReceiveBufferSize = value; - NotifyPropertyChanged("ChannelReceiveBufferSize"); - } - } - } - - /// - public Int32 ChannelSendBufferSize - { - get { return _channelSendBufferSize; } - set - { - if (_channelSendBufferSize != value) - { - _channelSendBufferSize = value; - NotifyPropertyChanged("ChannelSendBufferSize"); - } - } - } - - /// - public Int32 ChannelReceivePacketSize - { - get { return _channelReceivePacketSize; } - set - { - if (_channelReceivePacketSize != value) - { - _channelReceivePacketSize = value; - NotifyPropertyChanged("ChannelReceivePacketSize"); - } - } - } - - /// - public void Load(String configFile) - { - String[] lines = File.ReadAllLines(configFile); - NameValueCollection nvc = new NameValueCollection(lines.Length, StringComparer.OrdinalIgnoreCase); - foreach (String line in lines) - { - String[] tmp = line.Split(new Char[] { '=' }, 2); - if (tmp.Length == 2) - nvc[tmp[0]] = tmp[1]; - } - - DefaultPort = GetInt32(nvc, "DefaultPort", "DEFAULT_COAP_PORT", DefaultPort); - DefaultSecurePort = GetInt32(nvc, "DefaultSecurePort", "DEFAULT_COAPS_PORT", DefaultSecurePort); - HttpPort = GetInt32(nvc, "HttpPort", "HTTP_PORT", HttpPort); - AckTimeout = GetInt32(nvc, "AckTimeout", "ACK_TIMEOUT", AckTimeout); - AckRandomFactor = GetDouble(nvc, "AckRandomFactor", "ACK_RANDOM_FACTOR", AckRandomFactor); - AckTimeoutScale = GetDouble(nvc, "AckTimeoutScale", "ACK_TIMEOUT_SCALE", AckTimeoutScale); - MaxRetransmit = GetInt32(nvc, "MaxRetransmit", "MAX_RETRANSMIT", MaxRetransmit); - MaxMessageSize = GetInt32(nvc, "MaxMessageSize", "MAX_MESSAGE_SIZE", MaxMessageSize); - DefaultBlockSize = GetInt32(nvc, "DefaultBlockSize", "DEFAULT_BLOCK_SIZE", DefaultBlockSize); - UseRandomIDStart = GetBoolean(nvc, "UseRandomIDStart", "USE_RANDOM_MID_START", UseRandomIDStart); - UseRandomTokenStart = GetBoolean(nvc, "UseRandomTokenStart", "USE_RANDOM_TOKEN_START", UseRandomTokenStart); - Deduplicator = GetString(nvc, "Deduplicator", "DEDUPLICATOR", Deduplicator); - CropRotationPeriod = GetInt32(nvc, "CropRotationPeriod", "CROP_ROTATION_PERIOD", CropRotationPeriod); - ExchangeLifetime = GetInt32(nvc, "ExchangeLifetime", "EXCHANGE_LIFETIME", ExchangeLifetime); - MarkAndSweepInterval = GetInt64(nvc, "MarkAndSweepInterval", "MARK_AND_SWEEP_INTERVAL", MarkAndSweepInterval); - NotificationMaxAge = GetInt64(nvc, "NotificationMaxAge", "NOTIFICATION_MAX_AGE", NotificationMaxAge); - NotificationCheckIntervalTime = GetInt64(nvc, "NotificationCheckIntervalTime", "NOTIFICATION_CHECK_INTERVAL", NotificationCheckIntervalTime); - NotificationCheckIntervalCount = GetInt32(nvc, "NotificationCheckIntervalCount", "NOTIFICATION_CHECK_INTERVAL_COUNT", NotificationCheckIntervalCount); - NotificationReregistrationBackoff = GetInt32(nvc, "NotificationReregistrationBackoff", "NOTIFICATION_REREGISTRATION_BACKOFF", NotificationReregistrationBackoff); - ChannelReceiveBufferSize = GetInt32(nvc, "ChannelReceiveBufferSize", "UDP_CONNECTOR_RECEIVE_BUFFER", ChannelReceiveBufferSize); - ChannelSendBufferSize = GetInt32(nvc, "ChannelSendBufferSize", "UDP_CONNECTOR_SEND_BUFFER", ChannelSendBufferSize); - ChannelReceivePacketSize = GetInt32(nvc, "ChannelReceivePacketSize", "UDP_CONNECTOR_DATAGRAM_SIZE", ChannelReceivePacketSize); - } - - /// - public void Store(String configFile) - { - using (StreamWriter w = new StreamWriter(configFile)) - { - w.Write("DefaultPort="); w.WriteLine(DefaultPort); - w.Write("DefaultSecurePort="); w.WriteLine(DefaultSecurePort); - w.Write("HttpPort="); w.WriteLine(HttpPort); - w.Write("AckTimeout="); w.WriteLine(AckTimeout); - w.Write("AckRandomFactor="); w.WriteLine(AckRandomFactor); - w.Write("AckTimeoutScale="); w.WriteLine(AckTimeoutScale); - w.Write("MaxRetransmit="); w.WriteLine(MaxRetransmit); - w.Write("MaxMessageSize="); w.WriteLine(MaxMessageSize); - w.Write("DefaultBlockSize="); w.WriteLine(DefaultBlockSize); - w.Write("UseRandomIDStart="); w.WriteLine(UseRandomIDStart); - w.Write("UseRandomTokenStart="); w.WriteLine(UseRandomTokenStart); - w.Write("Deduplicator="); w.WriteLine(Deduplicator); - w.Write("CropRotationPeriod="); w.WriteLine(CropRotationPeriod); - w.Write("ExchangeLifetime="); w.WriteLine(ExchangeLifetime); - w.Write("MarkAndSweepInterval="); w.WriteLine(MarkAndSweepInterval); - w.Write("NotificationMaxAge="); w.WriteLine(NotificationMaxAge); - w.Write("NotificationCheckIntervalTime="); w.WriteLine(NotificationCheckIntervalTime); - w.Write("NotificationCheckIntervalCount="); w.WriteLine(NotificationCheckIntervalCount); - w.Write("NotificationReregistrationBackoff="); w.WriteLine(NotificationReregistrationBackoff); - w.Write("ChannelReceiveBufferSize="); w.WriteLine(ChannelReceiveBufferSize); - w.Write("ChannelSendBufferSize="); w.WriteLine(ChannelSendBufferSize); - w.Write("ChannelReceivePacketSize="); w.WriteLine(ChannelReceivePacketSize); - } - } - - private static String GetString(NameValueCollection nvc, String key1, String key2, String defaultValue) - { - return nvc[key1] ?? nvc[key2] ?? defaultValue; - } - - private static Int32 GetInt32(NameValueCollection nvc, String key1, String key2, Int32 defaultValue) - { - String value = GetString(nvc, key1, key2, null); - Int32 result; - return !String.IsNullOrEmpty(value) && Int32.TryParse(value, out result) ? result : defaultValue; - } - - private static Int64 GetInt64(NameValueCollection nvc, String key1, String key2, Int64 defaultValue) - { - String value = GetString(nvc, key1, key2, null); - Int64 result; - return !String.IsNullOrEmpty(value) && Int64.TryParse(value, out result) ? result : defaultValue; - } - - private static Double GetDouble(NameValueCollection nvc, String key1, String key2, Double defaultValue) - { - String value = GetString(nvc, key1, key2, null); - Double result; - return !String.IsNullOrEmpty(value) && Double.TryParse(value, out result) ? result : defaultValue; - } - - private static Boolean GetBoolean(NameValueCollection nvc, String key1, String key2, Boolean defaultValue) - { - String value = GetString(nvc, key1, key2, null); - Boolean result; - return !String.IsNullOrEmpty(value) && Boolean.TryParse(value, out result) ? result : defaultValue; - } - - private static ICoapConfig LoadConfig() - { - // TODO may have configuration file here - return new CoapConfig(); - } - - /// - public event PropertyChangedEventHandler PropertyChanged; - - private void NotifyPropertyChanged(String propertyName) - { - PropertyChangedEventHandler handler = PropertyChanged; - if (handler != null) - handler(this, new PropertyChangedEventArgs(propertyName)); - } - } -} diff --git a/CoAP.NET/CoapConstants.cs b/CoAP.NET/CoapConstants.cs deleted file mode 100644 index fdf8b3a..0000000 --- a/CoAP.NET/CoapConstants.cs +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2011-2012, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; - -namespace CoAP -{ - /// - /// Constants defined for CoAP protocol - /// - public static class CoapConstants - { - /// - /// RFC 7252 CoAP version. - /// - public const Int32 Version = 0x01; - /// - /// The CoAP URI scheme. - /// - public const String UriScheme = "coap"; - /// - /// The CoAPS URI scheme. - /// - public const String SecureUriScheme = "coaps"; - /// - /// The default CoAP port for normal CoAP communication (not secure). - /// - public const Int32 DefaultPort = 5683; - /// - /// The default CoAP port for secure CoAP communication (coaps). - /// - public const Int32 DefaultSecurePort = 5684; - /// - /// The initial time (ms) for a CoAP message - /// - public const Int32 AckTimeout = 2000; - /// - /// The initial timeout is set - /// to a random number between RESPONSE_TIMEOUT and (RESPONSE_TIMEOUT * - /// RESPONSE_RANDOM_FACTOR) - /// - public const Double AckRandomFactor = 1.5D; - /// - /// The max time that a message would be retransmitted - /// - public const Int32 MaxRetransmit = 4; - /// - /// Default block size used for block-wise transfers - /// - public const Int32 DefaultBlockSize = 512; - public const Int32 MessageCacheSize = 32; - public const Int32 ReceiveBufferSize = 4096; - public const Int32 DefaultOverallTimeout = 100000; - /// - /// Default URI for wellknown resource - /// - public const String DefaultWellKnownURI = "/.well-known/core"; - public const Int32 TokenLength = 8; - public const Int32 DefaultMaxAge = 60; - /// - /// The number of notifications until a CON notification will be used. - /// - public const Int32 ObservingRefreshInterval = 10; - - public static readonly Byte[] EmptyToken = new Byte[0]; - - /// - /// The lowest value of a request code. - /// - public const Int32 RequestCodeLowerBound = 1; - - /// - /// The highest value of a request code. - /// - public const Int32 RequestCodeUpperBound = 31; - - /// - /// The lowest value of a response code. - /// - public const Int32 ResponseCodeLowerBound = 64; - - /// - /// The highest value of a response code. - /// - public const Int32 ResponseCodeUpperBound = 191; - } -} diff --git a/CoAP.NET/CoapObserveRelation.cs b/CoAP.NET/CoapObserveRelation.cs deleted file mode 100644 index df3a48d..0000000 --- a/CoAP.NET/CoapObserveRelation.cs +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2011-2015, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; -using CoAP.Net; -using CoAP.Observe; - -namespace CoAP -{ - /// - /// Represents a CoAP observe relation between a CoAP client and a resource on a server. - /// Provides a simple API to check whether a relation has successfully established and - /// to cancel or refresh the relation. - /// - public class CoapObserveRelation - { - readonly ICoapConfig _config; - readonly Request _request; - readonly IEndPoint _endpoint; - private Boolean _canceled; - private Response _current; - private ObserveNotificationOrderer _orderer; - - public CoapObserveRelation(Request request, IEndPoint endpoint, ICoapConfig config) - { - _config = config; - _request = request; - _endpoint = endpoint; - _orderer = new ObserveNotificationOrderer(config); - - request.Reregistering += OnReregister; - } - - public Request Request - { - get { return _request; } - } - - public Response Current - { - get { return _current; } - set { _current = value; } - } - - public ObserveNotificationOrderer Orderer - { - get { return _orderer; } - } - - public Boolean Canceled - { - get { return _canceled; } - set { _canceled = value; } - } - - public void ReactiveCancel() - { - _request.IsCancelled = true; - _canceled = true; - } - - public void ProactiveCancel() - { - Request cancel = Request.NewGet(); - // copy options, but set Observe to cancel - cancel.SetOptions(_request.GetOptions()); - cancel.MarkObserveCancel(); - // use same Token - cancel.Token = _request.Token; - cancel.Destination = _request.Destination; - - // dispatch final response to the same message observers - cancel.CopyEventHandler(_request); - - cancel.Send(_endpoint); - // cancel old ongoing request - _request.IsCancelled = true; - _canceled = true; - } - - private void OnReregister(Object sender, ReregisterEventArgs e) - { - // TODO: update request in observe handle for correct cancellation? - //_request = e.RefreshRequest; - - // reset orderer to accept any sequence number since server might have rebooted - _orderer = new ObserveNotificationOrderer(_config); - } - } -} diff --git a/CoAP.NET/Code.cs b/CoAP.NET/Code.cs deleted file mode 100644 index 1be9f2c..0000000 --- a/CoAP.NET/Code.cs +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Copyright (c) 2011-2015, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; - -namespace CoAP -{ - /// - /// This class describes the CoAP Code Registry as defined in - /// draft-ietf-core-coap-08, section 11.1 - /// - public class Code - { - public const Int32 Empty = 0; - - public const Int32 SuccessCode = 2; - public const Int32 ClientErrorCode = 4; - public const Int32 ServerErrorCode = 5; - - #region Method Codes - - /// - /// The GET method - /// - public const Int32 GET = 1; - /// - /// The POST method - /// - public const Int32 POST = 2; - /// - /// The PUT method - /// - public const Int32 PUT = 3; - /// - /// The DELETE method - /// - public const Int32 DELETE = 4; - - #endregion - - #region Response Codes - - /// - /// 2.01 Created - /// - public const Int32 Created = 65; - /// - /// 2.02 Deleted - /// - public const Int32 Deleted = 66; - /// - /// 2.03 Valid - /// - public const Int32 Valid = 67; - /// - /// 2.04 Changed - /// - public const Int32 Changed = 68; - /// - /// 2.05 Content - /// - public const Int32 Content = 69; - /// - /// 2.?? Continue - /// - public const Int32 Continue = 95; - /// - /// 4.00 Bad Request - /// - public const Int32 BadRequest = 128; - /// - /// 4.01 Unauthorized - /// - public const Int32 Unauthorized = 129; - /// - /// 4.02 Bad Option - /// - public const Int32 BadOption = 130; - /// - /// 4.03 Forbidden - /// - public const Int32 Forbidden = 131; - /// - /// 4.04 Not Found - /// - public const Int32 NotFound = 132; - /// - /// 4.05 Method Not Allowed - /// - public const Int32 MethodNotAllowed = 133; - /// - /// 4.06 Not Acceptable - /// - public const Int32 NotAcceptable = 134; - /// - /// 4.08 Request Entity Incomplete (draft-ietf-core-block) - /// - public const Int32 RequestEntityIncomplete = 136; - /// - /// - /// - public const Int32 PreconditionFailed = 140; - /// - /// 4.13 Request Entity Too Large - /// - public const Int32 RequestEntityTooLarge = 141; - /// - /// 4.15 Unsupported Media Type - /// - public const Int32 UnsupportedMediaType = 143; - /// - /// 5.00 Internal Server Error - /// - public const Int32 InternalServerError = 160; - /// - /// 5.01 Not Implemented - /// - public const Int32 NotImplemented = 161; - /// - /// 5.02 Bad Gateway - /// - public const Int32 BadGateway = 162; - /// - /// 5.03 Service Unavailable - /// - public const Int32 ServiceUnavailable = 163; - /// - /// 5.04 Gateway Timeout - /// - public const Int32 GatewayTimeout = 164; - /// - /// 5.05 Proxying Not Supported - /// - public const Int32 ProxyingNotSupported = 165; - - #endregion - - public static Int32 GetResponseClass(Int32 code) - { - return (code >> 5) & 0x7; - } - - /// - /// Checks whether a code indicates a request - /// - /// The code to be checked - /// True iff the code indicates a request - public static Boolean IsRequest(Int32 code) - { - return (code >= 1) && (code <= 31); - } - - /// - /// Checks whether a code indicates a response - /// - /// The code to be checked - /// True iff the code indicates a response - public static Boolean IsResponse(Int32 code) - { - return (code >= 64) && (code <= 191); - } - - /// - /// Checks whether a code represents a success code. - /// - public static Boolean IsSuccess(Int32 code) - { - return code >= 64 && code < 96; - } - - /// - /// Checks whether a code is valid - /// - /// The code to be checked - /// True iff the code is valid - public static Boolean IsValid(Int32 code) - { - // allow unknown custom codes - return (code >= 0) && (code <= 255); - } - - /// - /// Returns a string representation of the code - /// - /// The code to be described - /// A string describing the code - public static String ToString(Int32 code) - { - switch (code) - { - case Empty: - return "Empty Message"; - case GET: - return "GET"; - case POST: - return "POST"; - case PUT: - return "PUT"; - case DELETE: - return "DELETE"; - case Created: - return "2.01 Created"; - case Deleted: - return "2.02 Deleted"; - case Valid: - return "2.03 Valid"; - case Changed: - return "2.04 Changed"; - case Content: - return "2.05 Content"; - case BadRequest: - return "4.00 Bad Request"; - case Unauthorized: - return "4.01 Unauthorized"; - case BadOption: - return "4.02 Bad Option"; - case Forbidden: - return "4.03 Forbidden"; - case NotFound: - return "4.04 Not Found"; - case MethodNotAllowed: - return "4.05 Method Not Allowed"; - case NotAcceptable: - return "4.06 Not Acceptable"; - case RequestEntityIncomplete: - return "4.08 Request Entity Incomplete"; - case PreconditionFailed: - return "4.12 Precondition Failed"; - case RequestEntityTooLarge: - return "4.13 Request Entity Too Large"; - case UnsupportedMediaType: - return "4.15 Unsupported Media Type"; - case InternalServerError: - return "5.00 Internal Server Error"; - case NotImplemented: - return "5.01 Not Implemented"; - case BadGateway: - return "5.02 Bad Gateway"; - case ServiceUnavailable: - return "5.03 Service Unavailable"; - case GatewayTimeout: - return "5.04 Gateway Timeout"; - case ProxyingNotSupported: - return "5.05 Proxying Not Supported"; - default: - break; - } - - if (IsValid(code)) - { - if (IsRequest(code)) - { - return String.Format("Unknown Request [code {0}]", code); - } - else if (IsResponse(code)) - { - return String.Format("Unknown Response [code {0}]", code); - } - else - { - return String.Format("Reserved [code {0}]", code); - } - } - else - { - return String.Format("Invalid Message [code {0}]", code); - } - } - } - - /// - /// Methods of request - /// - public enum Method - { - /// - /// GET method - /// - GET = 1, - /// - /// POST method - /// - POST = 2, - /// - /// PUT method - /// - PUT = 3, - /// - /// DELETE method - /// - DELETE = 4 - } - - /// - /// Response status codes. - /// - public enum StatusCode - { - /// - /// 2.01 Created - /// - Created = 65, - /// - /// 2.02 Deleted - /// - Deleted = 66, - /// - /// 2.03 Valid - /// - Valid = 67, - /// - /// 2.04 Changed - /// - Changed = 68, - /// - /// 2.05 Content - /// - Content = 69, - /// - /// 2.?? Continue - /// - Continue = 95, - /// - /// 4.00 Bad Request - /// - BadRequest = 128, - /// - /// 4.01 Unauthorized - /// - Unauthorized = 129, - /// - /// 4.02 Bad Option - /// - BadOption = 130, - /// - /// 4.03 Forbidden - /// - Forbidden = 131, - /// - /// 4.04 Not Found - /// - NotFound = 132, - /// - /// 4.05 Method Not Allowed - /// - MethodNotAllowed = 133, - /// - /// 4.06 Not Acceptable - /// - NotAcceptable = 134, - /// - /// 4.08 Request Entity Incomplete (draft-ietf-core-block) - /// - RequestEntityIncomplete = 136, - /// - /// - /// - PreconditionFailed = 140, - /// - /// 4.13 Request Entity Too Large - /// - RequestEntityTooLarge = 141, - /// - /// 4.15 Unsupported Media Type - /// - UnsupportedMediaType = 143, - /// - /// 5.00 Internal Server Error - /// - InternalServerError = 160, - /// - /// 5.01 Not Implemented - /// - NotImplemented = 161, - /// - /// 5.02 Bad Gateway - /// - BadGateway = 162, - /// - /// 5.03 Service Unavailable - /// - ServiceUnavailable = 163, - /// - /// 5.04 Gateway Timeout - /// - GatewayTimeout = 164, - /// - /// 5.05 Proxying Not Supported - /// - ProxyingNotSupported = 165 - } -} diff --git a/CoAP.NET/Codec/DatagramReader.cs b/CoAP.NET/Codec/DatagramReader.cs deleted file mode 100644 index 6b33583..0000000 --- a/CoAP.NET/Codec/DatagramReader.cs +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2011-2014, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; -using System.IO; - -namespace CoAP.Codec -{ - /// - /// This class describes the functionality to read raw network-ordered datagrams on bit-level. - /// - public class DatagramReader - { - private MemoryStream _stream; - private Byte _currentByte; - private Int32 _currentBitIndex; - - /// - /// Initializes a new DatagramReader object - /// - /// The byte array to read from - public DatagramReader(Byte[] buffer) - { - _stream = new MemoryStream(buffer, false); - _currentByte = 0; - _currentBitIndex = -1; - } - - /// - /// Reads a sequence of bits from the stream - /// - /// The number of bits to read - /// An integer containing the bits read - public Int32 Read(Int32 numBits) - { - Int32 bits = 0; // initialize all bits to zero - for (Int32 i = numBits - 1; i >= 0; i--) - { - // check whether new byte needs to be read - if (_currentBitIndex < 0) - { - ReadCurrentByte(); - } - - // test current bit - Boolean bit = (_currentByte >> _currentBitIndex & 1) != 0; - if (bit) - { - // set bit at i-th position - bits |= (1 << i); - } - - // decrease current bit index - --_currentBitIndex; - } - return bits; - } - - /// - /// Reads a sequence of bytes from the stream - /// - /// The number of bytes to read - /// The sequence of bytes read from the stream - public Byte[] ReadBytes(Int32 count) - { - // for negative count values, read all bytes left - if (count < 0) - count = (Int32)(_stream.Length - _stream.Position); - - Byte[] bytes = new Byte[count]; - - // are there bits left to read in buffer? - if (_currentBitIndex >= 0) - { - for (Int32 i = 0; i < count; i++) - { - bytes[i] = (Byte)Read(8); - } - } - else - { - _stream.Read(bytes, 0, bytes.Length); - } - - return bytes; - } - - /// - /// Reads the next byte from the stream. - /// - public Byte ReadNextByte() - { - return ReadBytes(1)[0]; - } - - /// - /// Reads the complete sequence of bytes left in the stream - /// - /// The sequence of bytes left in the stream - public Byte[] ReadBytesLeft() - { - return ReadBytes(-1); - } - - /// - /// Checks if there are remaining bytes to read. - /// - public Boolean BytesAvailable - { - get { return _stream.Length - _stream.Position > 0; } - } - - private void ReadCurrentByte() - { - Int32 val = _stream.ReadByte(); - - if (val >= 0) - _currentByte = (Byte)val; - else - // EOF - _currentByte = 0; - - // reset current bit index - _currentBitIndex = 7; - } - } -} diff --git a/CoAP.NET/Codec/DatagramWriter.cs b/CoAP.NET/Codec/DatagramWriter.cs deleted file mode 100644 index 8872624..0000000 --- a/CoAP.NET/Codec/DatagramWriter.cs +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2011-2014, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; -using System.IO; -using CoAP.Log; - -namespace CoAP.Codec -{ - /// - /// This class describes the functionality to write raw network-ordered datagrams on bit-level. - /// - public class DatagramWriter - { - private static ILogger log = LogManager.GetLogger(typeof(DatagramWriter)); - - private MemoryStream _stream; - private Byte _currentByte; - private Int32 _currentBitIndex; - - /// - /// Initializes a new DatagramWriter object - /// - public DatagramWriter() - { - _stream = new MemoryStream(); - _currentByte = 0; - _currentBitIndex = 7; - } - - /// - /// Writes a sequence of bits to the stream - /// - /// An integer containing the bits to write - /// The number of bits to write - public void Write(Int32 data, Int32 numBits) - { - if (numBits < 32 && data >= (1 << numBits)) - { - if (log.IsWarnEnabled) - log.Warn(String.Format("Truncating value {0} to {1}-bit integer", data, numBits)); - } - - for (Int32 i = numBits - 1; i >= 0; i--) - { - // test bit - Boolean bit = (data >> i & 1) != 0; - if (bit) - { - // set bit in current byte - _currentByte |= (Byte)(1 << _currentBitIndex); - } - - // decrease current bit index - --_currentBitIndex; - - // check if current byte can be written - if (_currentBitIndex < 0) - { - WriteCurrentByte(); - } - } - } - - /// - /// Writes a sequence of bytes to the stream - /// - /// The sequence of bytes to write - public void WriteBytes(Byte[] bytes) - { - // check if anything to do at all - if (bytes == null) - return; - - // are there bits left to write in buffer? - if (_currentBitIndex < 7) - { - for (int i = 0; i < bytes.Length; i++) - { - Write(bytes[i], 8); - } - } - else - { - // if bit buffer is empty, call can be delegated - // to byte stream to increase - _stream.Write(bytes, 0, bytes.Length); - } - } - - /// - /// Writes one byte to the stream. - /// - public void WriteByte(Byte b) - { - WriteBytes(new Byte[] { b }); - } - - /// - /// Returns a byte array containing the sequence of bits written - /// - /// The byte array containing the written bits - public Byte[] ToByteArray() - { - WriteCurrentByte(); - Byte[] byteArray = _stream.ToArray(); - _stream.Position = 0; - return byteArray; - } - - private void WriteCurrentByte() - { - if (_currentBitIndex < 7) - { - _stream.WriteByte(_currentByte); - _currentByte = 0; - _currentBitIndex = 7; - } - } - } -} diff --git a/CoAP.NET/Codec/IMessageDecoder.cs b/CoAP.NET/Codec/IMessageDecoder.cs deleted file mode 100644 index 7d760cf..0000000 --- a/CoAP.NET/Codec/IMessageDecoder.cs +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2011-2014, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; - -namespace CoAP.Codec -{ - /// - /// Provides methods to parse incoming byte arrays to messages. - /// - public interface IMessageDecoder - { - /// - /// Checks if the decoding message is wellformed. - /// - Boolean IsWellFormed { get; } - /// - /// Checks if the decoding message is a reply. - /// - Boolean IsReply { get; } - /// - /// Checks if the decoding message is a request. - /// - Boolean IsRequest { get; } - /// - /// Checks if the decoding message is a response. - /// - Boolean IsResponse { get; } - /// - /// Checks if the decoding message is an empty message. - /// - Boolean IsEmpty { get; } - /// - /// Gets the version of the decoding message. - /// - Int32 Version { get; } - /// - /// Gets the id of the decoding message. - /// - Int32 ID { get; } - /// - /// Decodes as a . - /// - /// the decoded request - Request DecodeRequest(); - /// - /// Decodes as a . - /// - /// the decoded response - Response DecodeResponse(); - /// - /// Decodes as a . - /// - /// the decoded empty message - EmptyMessage DecodeEmptyMessage(); - /// - /// Decodes as a CoAP message. - /// - /// the decoded message, or null if not be recognized. - Message Decode(); - } -} diff --git a/CoAP.NET/Codec/IMessageEncoder.cs b/CoAP.NET/Codec/IMessageEncoder.cs deleted file mode 100644 index 6a3bbdc..0000000 --- a/CoAP.NET/Codec/IMessageEncoder.cs +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2011-2014, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; - -namespace CoAP.Codec -{ - /// - /// Provides methods to serialize outgoing messages to byte arrays. - /// - public interface IMessageEncoder - { - /// - /// Encodes a request into a bytes array. - /// - /// the request to encode - /// the encoded bytes - Byte[] Encode(Request request); - /// - /// Encodes a response into a bytes array. - /// - /// the response to encode - /// the encoded bytes - Byte[] Encode(Response response); - /// - /// Encodes an empty message into a bytes array. - /// - /// the empty message to encode - /// the encoded bytes - Byte[] Encode(EmptyMessage message); - /// - /// Encodes a CoAP message into a bytes array. - /// - /// the message to encode - /// - /// the encoded bytes, or null if the message can not be encoded, - /// i.e. the message is not a , a or an . - /// - Byte[] Encode(Message message); - } -} diff --git a/CoAP.NET/Codec/MessageDecoder.cs b/CoAP.NET/Codec/MessageDecoder.cs deleted file mode 100644 index f86ce2c..0000000 --- a/CoAP.NET/Codec/MessageDecoder.cs +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2011-2014, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; - -namespace CoAP.Codec -{ - /// - /// Base class for message decoders. - /// - public abstract class MessageDecoder : IMessageDecoder - { - /// - /// the bytes reader - /// - protected DatagramReader m_reader; - /// - /// the version of the decoding message - /// - protected Int32 m_version; - /// - /// the type of the decoding message - /// - protected MessageType m_type; - /// - /// the length of token - /// - protected Int32 m_tokenLength; - /// - /// the code of the decoding message - /// - protected Int32 m_code; - /// - /// the id of the decoding message - /// - protected Int32 m_id; - - /// - /// Instantiates. - /// - /// the bytes array to decode - public MessageDecoder(Byte[] data) - { - m_reader = new DatagramReader(data); - } - - /// - /// Reads protocol headers. - /// - protected abstract void ReadProtocol(); - - /// - public abstract Boolean IsWellFormed { get; } - - /// - public Boolean IsReply - { - get { return m_type == MessageType.ACK || m_type == MessageType.RST; } - } - - /// - public virtual Boolean IsRequest - { - get - { - return m_code >= CoapConstants.RequestCodeLowerBound && - m_code <= CoapConstants.RequestCodeUpperBound; - } - } - - /// - public virtual Boolean IsResponse - { - get - { - return m_code >= CoapConstants.ResponseCodeLowerBound && - m_code <= CoapConstants.ResponseCodeUpperBound; - } - } - - /// - public Boolean IsEmpty - { - get { return m_code == Code.Empty; } - } - - /// - public Int32 Version - { - get { return m_version; } - } - - /// - public Int32 ID - { - get { return m_id; } - } - - /// - public Request DecodeRequest() - { - System.Diagnostics.Debug.Assert(IsRequest); - Request request = new Request((Method)m_code); - request.Type = m_type; - request.ID = m_id; - ParseMessage(request); - return request; - } - - /// - public Response DecodeResponse() - { - System.Diagnostics.Debug.Assert(IsResponse); - Response response = new Response((StatusCode)m_code); - response.Type = m_type; - response.ID = m_id; - ParseMessage(response); - return response; - } - - /// - public EmptyMessage DecodeEmptyMessage() - { - System.Diagnostics.Debug.Assert(!IsRequest && !IsResponse); - EmptyMessage message = new EmptyMessage(m_type); - message.Type = m_type; - message.ID = m_id; - ParseMessage(message); - return message; - } - - /// - public Message Decode() - { - if (IsRequest) - return DecodeRequest(); - else if (IsResponse) - return DecodeResponse(); - else if (IsEmpty) - return DecodeEmptyMessage(); - else - return null; - } - - /// - /// Parses the rest data other than protocol headers into the given message. - /// - /// - protected abstract void ParseMessage(Message message); - } -} diff --git a/CoAP.NET/Codec/MessageEncoder.cs b/CoAP.NET/Codec/MessageEncoder.cs deleted file mode 100644 index 539a1e2..0000000 --- a/CoAP.NET/Codec/MessageEncoder.cs +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2011-2014, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; - -namespace CoAP.Codec -{ - /// - /// Base class for message encoders. - /// - public abstract class MessageEncoder : IMessageEncoder - { - /// - public Byte[] Encode(Request request) - { - DatagramWriter writer = new DatagramWriter(); - Serialize(writer, request, request.Code); - return writer.ToByteArray(); - } - - /// - public Byte[] Encode(Response response) - { - DatagramWriter writer = new DatagramWriter(); - Serialize(writer, response, response.Code); - return writer.ToByteArray(); - } - - /// - public Byte[] Encode(EmptyMessage message) - { - DatagramWriter writer = new DatagramWriter(); - Serialize(writer, message, Code.Empty); - return writer.ToByteArray(); - } - - /// - public Byte[] Encode(Message message) - { - if (message.IsRequest) - return Encode((Request)message); - else if (message.IsResponse) - return Encode((Response)message); - else if (message is EmptyMessage) - return Encode((EmptyMessage)message); - else - return null; - } - - /// - /// Serializes a message. - /// - /// the writer - /// the message to write - /// the code - protected abstract void Serialize(DatagramWriter writer, Message message, Int32 code); - } -} diff --git a/CoAP.NET/Deduplication/CropRotation.cs b/CoAP.NET/Deduplication/CropRotation.cs deleted file mode 100644 index 2b8a204..0000000 --- a/CoAP.NET/Deduplication/CropRotation.cs +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2011-2014, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; -using System.Collections.Concurrent; -using System.Timers; -using CoAP.Log; -using CoAP.Net; - -namespace CoAP.Deduplication -{ - class CropRotation : IDeduplicator, IDisposable - { - private ConcurrentDictionary[] _maps; - private Int32 _first; - private Int32 _second; - private Timer _timer; - - public CropRotation(ICoapConfig config) - { - _maps = new ConcurrentDictionary[3]; - _maps[0] = new ConcurrentDictionary(); - _maps[1] = new ConcurrentDictionary(); - _maps[2] = new ConcurrentDictionary(); - _first = 0; - _second = 1; - _timer = new Timer(config.CropRotationPeriod); - _timer.Elapsed += Rotation; - } - - private void Rotation(Object sender, ElapsedEventArgs e) - { - Int32 third = _first; - _first = _second; - _second = (_second + 1) % 3; - _maps[third].Clear(); - } - - /// - public void Start() - { - _timer.Start(); - } - - /// - public void Stop() - { - _timer.Stop(); - Clear(); - } - - /// - public void Clear() - { - _maps[0].Clear(); - _maps[1].Clear(); - _maps[2].Clear(); - } - - /// - public Exchange FindPrevious(Exchange.KeyID key, Exchange exchange) - { - Int32 f = _first, s = _second; - Exchange prev = null; - - _maps[f].AddOrUpdate(key, exchange, (k, v) => - { - prev = v; - return exchange; - }); - if (prev != null || f == s) - return prev; - - prev = _maps[s].AddOrUpdate(key, exchange, (k, v) => - { - prev = v; - return exchange; - }); - return prev; - } - - /// - public Exchange Find(Exchange.KeyID key) - { - Int32 f = _first, s = _second; - Exchange prev; - if (_maps[f].TryGetValue(key, out prev) || f == s) - return prev; - _maps[s].TryGetValue(key, out prev); - return prev; - } - - /// - public void Dispose() - { - _timer.Dispose(); - } - } -} diff --git a/CoAP.NET/Deduplication/DeduplicatorFactory.cs b/CoAP.NET/Deduplication/DeduplicatorFactory.cs deleted file mode 100644 index c3fa6c6..0000000 --- a/CoAP.NET/Deduplication/DeduplicatorFactory.cs +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2011-2014, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; -using CoAP.Log; - -namespace CoAP.Deduplication -{ - static class DeduplicatorFactory - { - static readonly ILogger log = LogManager.GetLogger(typeof(DeduplicatorFactory)); - public const String MarkAndSweepDeduplicator = "MarkAndSweep"; - public const String CropRotationDeduplicator = "CropRotation"; - public const String NoopDeduplicator = "Noop"; - - public static IDeduplicator CreateDeduplicator(ICoapConfig config) - { - String type = config.Deduplicator; - if (String.Equals(MarkAndSweepDeduplicator, type, StringComparison.OrdinalIgnoreCase) - || String.Equals("DEDUPLICATOR_MARK_AND_SWEEP", type, StringComparison.OrdinalIgnoreCase)) - return new SweepDeduplicator(config); - else if (String.Equals(CropRotationDeduplicator, type, StringComparison.OrdinalIgnoreCase) - || String.Equals("DEDUPLICATOR_CROP_ROTATIO", type, StringComparison.OrdinalIgnoreCase)) - return new CropRotation(config); - else if (!String.Equals(NoopDeduplicator, type, StringComparison.OrdinalIgnoreCase) - && !String.Equals("NO_DEDUPLICATOR", type, StringComparison.OrdinalIgnoreCase)) - { - if (log.IsWarnEnabled) - log.Warn("Unknown deduplicator type: " + type); - } - return new NoopDeduplicator(); - } - } -} diff --git a/CoAP.NET/Deduplication/IDeduplicator.cs b/CoAP.NET/Deduplication/IDeduplicator.cs deleted file mode 100644 index c016988..0000000 --- a/CoAP.NET/Deduplication/IDeduplicator.cs +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2011-2014, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using CoAP.Net; - -namespace CoAP.Deduplication -{ - /// - /// Provides methods to detect duplicates. - /// Notice that CONs and NONs can be duplicates. - /// - public interface IDeduplicator - { - /// - /// Starts. - /// - void Start(); - /// - /// Stops. - /// - void Stop(); - /// - /// Clears the state of this deduplicator. - /// - void Clear(); - /// - /// Checks if the specified key is already associated with a previous - /// exchange and otherwise associates the key with the exchange specified. - /// - /// - /// - /// the previous exchange associated with the specified key, - /// or null if there was no mapping for the key - Exchange FindPrevious(Exchange.KeyID key, Exchange exchange); - Exchange Find(Exchange.KeyID key); - } -} diff --git a/CoAP.NET/Deduplication/NoopDeduplicator.cs b/CoAP.NET/Deduplication/NoopDeduplicator.cs deleted file mode 100644 index 6bb697a..0000000 --- a/CoAP.NET/Deduplication/NoopDeduplicator.cs +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2011-2014, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using CoAP.Net; - -namespace CoAP.Deduplication -{ - /// - /// A dummy implementation that does no deduplication. - /// - class NoopDeduplicator : IDeduplicator - { - /// - public void Start() - { - // do nothing - } - - /// - public void Stop() - { - // do nothing - } - - /// - public void Clear() - { - // do nothing - } - - /// - public Exchange FindPrevious(Exchange.KeyID key, Exchange exchange) - { - return null; - } - - /// - public Exchange Find(Exchange.KeyID key) - { - return null; - } - } -} diff --git a/CoAP.NET/Deduplication/SweepDeduplicator.cs b/CoAP.NET/Deduplication/SweepDeduplicator.cs deleted file mode 100644 index 3bed004..0000000 --- a/CoAP.NET/Deduplication/SweepDeduplicator.cs +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2011-2014, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Timers; -using CoAP.Log; -using CoAP.Net; - -namespace CoAP.Deduplication -{ - class SweepDeduplicator : IDeduplicator - { - static readonly ILogger log = LogManager.GetLogger(typeof(SweepDeduplicator)); - - private ConcurrentDictionary _incommingMessages - = new ConcurrentDictionary(); - private Timer _timer; - private ICoapConfig _config; - - public SweepDeduplicator(ICoapConfig config) - { - _config = config; - _timer = new Timer(config.MarkAndSweepInterval); - _timer.Elapsed += Sweep; - } - - private void Sweep(Object sender, ElapsedEventArgs e) - { - if (log.IsDebugEnabled) - log.Debug("Start Mark-And-Sweep with " + _incommingMessages.Count + " entries"); - - DateTime oldestAllowed = DateTime.Now.AddMilliseconds(-_config.ExchangeLifetime); - List keysToRemove = new List(); - foreach (KeyValuePair pair in _incommingMessages) - { - if (pair.Value.Timestamp < oldestAllowed) - { - if (log.IsDebugEnabled) - log.Debug("Mark-And-Sweep removes " + pair.Key); - keysToRemove.Add(pair.Key); - } - } - if (keysToRemove.Count > 0) - { - Exchange ex; - foreach (Exchange.KeyID key in keysToRemove) - { - _incommingMessages.TryRemove(key, out ex); - } - } - } - - /// - public void Start() - { - _timer.Start(); - } - - /// - public void Stop() - { - _timer.Stop(); - Clear(); - } - - /// - public void Clear() - { - _incommingMessages.Clear(); - } - - /// - public Exchange FindPrevious(Exchange.KeyID key, Exchange exchange) - { - Exchange prev = null; - _incommingMessages.AddOrUpdate(key, exchange, (k, v) => - { - prev = v; - return exchange; - }); - return prev; - } - - /// - public Exchange Find(Exchange.KeyID key) - { - Exchange prev; - _incommingMessages.TryGetValue(key, out prev); - return prev; - } - - /// - public void Dispose() - { - _timer.Dispose(); - } - } -} diff --git a/CoAP.NET/EmptyMessage.cs b/CoAP.NET/EmptyMessage.cs deleted file mode 100644 index 83966f3..0000000 --- a/CoAP.NET/EmptyMessage.cs +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2011-2014, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; - -namespace CoAP -{ - /// - /// Represents an empty CoAP message. An empty message has either - /// the ACK or RST. - /// - public class EmptyMessage : Message - { - /// - /// Instantiates a new empty message. - /// - public EmptyMessage(MessageType type) - : base(type, CoAP.Code.Empty) - { } - - /// - /// Create a new acknowledgment for the specified message. - /// - /// the message to acknowledge - /// the acknowledgment - public static EmptyMessage NewACK(Message message) - { - EmptyMessage ack = new EmptyMessage(MessageType.ACK); - ack.ID = message.ID; - ack.Token = CoapConstants.EmptyToken; - ack.Destination = message.Source; - return ack; - } - - /// - /// Create a new reset message for the specified message. - /// - /// the message to reject - /// the reset - public static EmptyMessage NewRST(Message message) - { - EmptyMessage rst = new EmptyMessage(MessageType.RST); - rst.ID = message.ID; - rst.Token = CoapConstants.EmptyToken; - rst.Destination = message.Source; - return rst; - } - } -} diff --git a/CoAP.NET/EndPoint/Resources/RemoteResource.cs b/CoAP.NET/EndPoint/Resources/RemoteResource.cs deleted file mode 100644 index 28aecb8..0000000 --- a/CoAP.NET/EndPoint/Resources/RemoteResource.cs +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2011-2012, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; - -namespace CoAP.EndPoint.Resources -{ - public class RemoteResource : Resource - { - public RemoteResource(String resourceIdentifier) - : base(resourceIdentifier) - { } - - public static RemoteResource NewRoot(String linkFormat) - { - return LinkFormat.Deserialize(linkFormat); - } - - /// - /// Creates a resouce instance with proper subtype. - /// - /// - protected override Resource CreateInstance(String name) - { - return new RemoteResource(name); - } - - protected override void DoCreateSubResource(Request request, String newIdentifier) - { - } - } -} diff --git a/CoAP.NET/EndPoint/Resources/Resource.cs b/CoAP.NET/EndPoint/Resources/Resource.cs deleted file mode 100644 index 4cb5ad3..0000000 --- a/CoAP.NET/EndPoint/Resources/Resource.cs +++ /dev/null @@ -1,524 +0,0 @@ -/* - * Copyright (c) 2011-2012, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; -using System.Collections.Generic; -using System.Text; -using CoAP.Log; -using CoAP.Util; - -namespace CoAP.EndPoint.Resources -{ - /// - /// This class describes the functionality of a CoAP resource. - /// - public abstract class Resource : IComparable - { - private static ILogger log = LogManager.GetLogger(typeof(Resource)); - - private Int32 _totalSubResourceCount; - private String _resourceIdentifier; - private HashSet _attributes; - private Resource _parent; - private SortedDictionary _subResources; - private Boolean _hidden; - - /// - /// Initialize a resource. - /// - /// The identifier of this resource - public Resource(String resourceIdentifier) : this(resourceIdentifier, false) { } - - /// - /// Initialize a resource. - /// - /// The identifier of this resource - /// True if this resource is hidden - public Resource(String resourceIdentifier, Boolean hidden) - { - this._resourceIdentifier = resourceIdentifier; - this._hidden = hidden; - this._attributes = new HashSet(); - } - - /// - /// Gets the URI of this resource. - /// - public String Path - { - get - { - StringBuilder sb = new StringBuilder(); - sb.Append(Name); - if (_parent == null) - sb.Append("/"); - else - { - Resource res = _parent; - while (res != null) - { - sb.Insert(0, "/"); - sb.Insert(0, res.Name); - res = res._parent; - } - } - return sb.ToString(); - } - } - - public String Name - { - get { return _resourceIdentifier; } - set { _resourceIdentifier = value; } - } - - public ICollection Attributes - { - get { return _attributes; } - } - - public IList GetAttributes(String name) - { - List list = new List(); - foreach (LinkAttribute attr in Attributes) - { - if (attr.Name.Equals(name)) - list.Add(attr); - } - return list.AsReadOnly(); - } - - public Boolean SetAttribute(LinkAttribute attr) - { - // Adds depending on the Link Format rules - return LinkFormat.AddAttribute(Attributes, attr); - } - - public Boolean ClearAttribute(String name) - { - Boolean cleared = false; - foreach (LinkAttribute attr in GetAttributes(name)) - { - cleared |= _attributes.Remove(attr); - } - return cleared; - } - - public Boolean Hidden - { - get { return _hidden; } - set { _hidden = value; } - } - - public IList ResourceTypes - { - get - { - return GetStringValues(GetAttributes(LinkFormat.ResourceType)); - } - } - - /// - /// Gets or sets the type attribute of this resource. - /// - public String ResourceType - { - get - { - IList attrs = GetAttributes(LinkFormat.ResourceType); - return attrs.Count == 0 ? null : attrs[0].StringValue; - } - set - { - SetAttribute(new LinkAttribute(LinkFormat.ResourceType, value)); - } - } - - /// - /// Gets or sets the title attribute of this resource. - /// - public String Title - { - get - { - IList attrs = GetAttributes(LinkFormat.Title); - return attrs.Count == 0 ? null : attrs[0].StringValue; - } - set - { - ClearAttribute(LinkFormat.Title); - SetAttribute(new LinkAttribute(LinkFormat.Title, value)); - } - } - - public IList InterfaceDescriptions - { - get - { - return GetStringValues(GetAttributes(LinkFormat.InterfaceDescription)); - } - } - - /// - /// Gets or sets the interface description attribute of this resource. - /// - public String InterfaceDescription - { - get - { - IList attrs = GetAttributes(LinkFormat.InterfaceDescription); - return attrs.Count == 0 ? null : attrs[0].StringValue; - } - set - { - SetAttribute(new LinkAttribute(LinkFormat.InterfaceDescription, value)); - } - } - - public IList GetContentTypeCodes - { - get - { - return GetIntValues(GetAttributes(LinkFormat.ContentType)); - } - } - - /// - /// Gets or sets the content type code attribute of this resource. - /// - public Int32 ContentTypeCode - { - get - { - IList attrs = GetAttributes(LinkFormat.ContentType); - return attrs.Count == 0 ? 0 : attrs[0].IntValue; - } - set - { - SetAttribute(new LinkAttribute(LinkFormat.ContentType, value)); - } - } - - /// - /// Gets or sets the maximum size estimate attribute of this resource. - /// - public Int32 MaximumSizeEstimate - { - get - { - IList attrs = GetAttributes(LinkFormat.MaxSizeEstimate); - return attrs.Count == 0 ? -1 : attrs[0].IntValue; - } - set - { - SetAttribute(new LinkAttribute(LinkFormat.MaxSizeEstimate, value)); - } - } - - /// - /// Gets or sets the observable attribute of this resource. - /// - public Boolean Observable - { - get - { - return GetAttributes(LinkFormat.Observable).Count > 0; - } - set - { - if (value) - SetAttribute(new LinkAttribute(LinkFormat.Observable, value)); - else - ClearAttribute(LinkFormat.Observable); - } - } - - /// - /// Gets the total count of sub-resources, including children and children's children... - /// - public Int32 TotalSubResourceCount - { - get { return _totalSubResourceCount; } - } - - /// - /// Gets the count of sub-resources of this resource. - /// - public Int32 SubResourceCount - { - get { return null == _subResources ? 0 : _subResources.Count; } - } - - /// - /// Removes this resource from its parent. - /// - public void Remove() - { - if (_parent != null) - _parent.RemoveSubResource(this); - } - - /// - /// Gets sub-resources of this resource. - /// - /// - public Resource[] GetSubResources() - { - if (null == _subResources) - return new Resource[0]; - - Resource[] resources = new Resource[_subResources.Count]; - this._subResources.Values.CopyTo(resources, 0); - return resources; - } - - public Resource GetResource(String path) - { - return GetResource(path, false); - } - - public Resource GetResource(String path, Boolean last) - { - if (String.IsNullOrEmpty(path)) - return this; - - // find root for absolute path - if (path.StartsWith("/")) - { - Resource root = this; - while (root._parent != null) - root = root._parent; - path = path.Equals("/") ? null : path.Substring(1); - return root.GetResource(path); - } - - Int32 pos = path.IndexOf('/'); - String head = null, tail = null; - - // note: "some/resource/" addresses a resource "" under "resource" - if (pos == -1) - { - head = path; - } - else - { - head = path.Substring(0, pos); - tail = path.Substring(pos + 1); - } - - if (SubResources.ContainsKey(head)) - return SubResources[head].GetResource(tail, last); - else if (last) - return this; - else - return null; - } - - private SortedDictionary SubResources - { - get - { - if (_subResources == null) - _subResources = new SortedDictionary(); - return _subResources; - } - } - - /// - /// Adds a resource as a sub-resource of this resource. - /// - /// The sub-resource to be added - public void AddSubResource(Resource resource) - { - if (null == resource) - throw new ArgumentNullException("resource"); - - // no absolute paths allowed, use root directly - while (resource.Name.StartsWith("/")) - { - if (_parent != null) - { - if (log.IsWarnEnabled) - log.Warn("Adding absolute path only allowed for root: made relative " + resource.Name); - } - resource.Name = resource.Name.Substring(1); - } - - // get last existing resource along path - Resource baseRes = GetResource(resource.Name, true); - - String path = this.Path; - if (!path.EndsWith("/")) - path += "/"; - path += resource.Name; - - path = path.Substring(baseRes.Path.Length); - if (path.StartsWith("/")) - path = path.Substring(1); - - if (path.Length == 0) - { - // resource replaces base - if (log.IsInfoEnabled) - log.Info("Replacing resource " + baseRes.Path); - foreach (Resource sub in baseRes.GetSubResources()) - { - sub._parent = resource; - resource.SubResources[sub.Name] = sub; - } - resource._parent = baseRes._parent; - baseRes._parent.SubResources[baseRes.Name] = resource; - } - else - { - // resource is added to base - - String[] segments = path.Split('/'); - if (segments.Length > 1) - { - if (log.IsDebugEnabled) - log.Debug("Splitting up compound resource " + resource.Name); - resource.Name = segments[segments.Length - 1]; - - // insert middle segments - Resource sub = null; - for (Int32 i = 0; i < segments.Length - 1; i++) - { - sub = baseRes.CreateInstance(segments[i]); - sub.Hidden = true; - baseRes.AddSubResource(sub); - baseRes = sub; - } - } - else - resource.Name = path; - - resource._parent = baseRes; - baseRes.SubResources[resource.Name] = resource; - - if (log.IsDebugEnabled) - log.Debug("Add resource " + resource.Name); - } - - // update number of sub-resources in the tree - Resource p = resource._parent; - while (p != null) - { - p._totalSubResourceCount++; - p = p._parent; - } - } - - /// - /// Removes a sub-resource from this resource by its identifier. - /// - /// the path of the sub-resource to remove - public void RemoveSubResource(String resourcePath) - { - RemoveSubResource(GetResource(resourcePath)); - } - - /// - /// Removes a sub-resource from this resource. - /// - /// the sub-resource to remove - public void RemoveSubResource(Resource resource) - { - if (null == resource) - return; - - if (SubResources.Remove(resource._resourceIdentifier)) - { - Resource p = resource._parent; - while (p != null) - { - p._totalSubResourceCount--; - p = p._parent; - } - - resource._parent = null; - } - } - - public void CreateSubResource(Request request, String newIdentifier) - { - DoCreateSubResource(request, newIdentifier); - } - - public Int32 CompareTo(Resource other) - { - return Path.CompareTo(other.Path); - } - - public override String ToString() - { - StringBuilder sb = new StringBuilder(); - Print(sb, 0); - return sb.ToString(); - } - - private void Print(StringBuilder sb, Int32 indent) - { - for (Int32 i = 0; i < indent; i++) - sb.Append(" "); - sb.AppendFormat("+[{0}]",_resourceIdentifier); - - String title = Title; - if (title != null) - sb.AppendFormat(" {0}", title); - sb.AppendLine(); - - foreach (LinkAttribute attr in Attributes) - { - if (attr.Name.Equals(LinkFormat.Title)) - continue; - for (Int32 i = 0; i < indent + 3; i++) - sb.Append(" "); - sb.AppendFormat("- "); - attr.Serialize(sb); - sb.AppendLine(); - } - - if (_subResources != null) - foreach (Resource sub in _subResources.Values) - { - sub.Print(sb, indent + 2); - } - } - - /// - /// Creates a resouce instance with proper subtype. - /// - /// - protected abstract Resource CreateInstance(String name); - protected abstract void DoCreateSubResource(Request request, String newIdentifier); - - private static IList GetStringValues(IEnumerable attributes) - { - List list = new List(); - foreach (LinkAttribute attr in attributes) - { - list.Add(attr.StringValue); - } - return list; - } - - private static IList GetIntValues(IEnumerable attributes) - { - List list = new List(); - foreach (LinkAttribute attr in attributes) - { - list.Add(attr.IntValue); - } - return list; - } - } -} diff --git a/CoAP.NET/ICoapConfig.cs b/CoAP.NET/ICoapConfig.cs deleted file mode 100644 index 35efc9a..0000000 --- a/CoAP.NET/ICoapConfig.cs +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2011-2015, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; - -namespace CoAP -{ - /// - /// Provides configuration for CoAP communication. - /// - public partial interface ICoapConfig : System.ComponentModel.INotifyPropertyChanged - { - /// - /// Gets the version of CoAP protocol. - /// - String Version { get; } - /// - /// Gets the default CoAP port for normal CoAP communication (not secure). - /// - Int32 DefaultPort { get; } - /// - /// Gets the default CoAP port for secure CoAP communication (coaps). - /// - Int32 DefaultSecurePort { get; } - /// - /// Gets the port which HTTP proxy is on. - /// - Int32 HttpPort { get; } - - Int32 AckTimeout { get; } - Double AckRandomFactor { get; } - Double AckTimeoutScale { get; } - Int32 MaxRetransmit { get; } - - Int32 MaxMessageSize { get; } - /// - /// Gets the default preferred size of block in blockwise transfer. - /// - Int32 DefaultBlockSize { get; } - Int32 BlockwiseStatusLifetime { get; } - Boolean UseRandomIDStart { get; } - Boolean UseRandomTokenStart { get; } - - Int64 NotificationMaxAge { get; } - Int64 NotificationCheckIntervalTime { get; } - Int32 NotificationCheckIntervalCount { get; } - Int32 NotificationReregistrationBackoff { get; } - - String Deduplicator { get; } - Int32 CropRotationPeriod { get; } - Int32 ExchangeLifetime { get; } - Int64 MarkAndSweepInterval { get; } - - Int32 ChannelReceiveBufferSize { get; } - Int32 ChannelSendBufferSize { get; } - Int32 ChannelReceivePacketSize { get; } - - /// - /// Loads configuration from a config properties file. - /// - void Load(String configFile); - - /// - /// Stores the configuration in a config properties file. - /// - void Store(String configFile); - } -} diff --git a/CoAP.NET/LinkAttribute.cs b/CoAP.NET/LinkAttribute.cs deleted file mode 100644 index 75d590d..0000000 --- a/CoAP.NET/LinkAttribute.cs +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2011-2013, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; -using System.Text; -using CoAP.Log; - -namespace CoAP -{ - /// - /// Class for linkformat attributes. - /// - public class LinkAttribute : IComparable - { - private static readonly ILogger log = LogManager.GetLogger(typeof(LinkAttribute)); - - private String _name; - private Object _value; - - /// - /// Initializes an attribute. - /// - public LinkAttribute(String name, Object value) - { - _name = name; - _value = value; - } - - /// - /// Gets the name of this attribute. - /// - public String Name - { - get { return _name; } - } - - /// - /// Gets the value of this attribute. - /// - public Object Value - { - get { return _value; } - } - - /// - /// Gets the int value of this attribute. - /// - public Int32 IntValue - { - get { return (_value is Int32) ? (Int32)_value : -1; } - } - - /// - /// Gets the string value of this attribute. - /// - public String StringValue - { - get { return (_value is String) ? (String)_value : null; } - } - - /// - /// Serializes this attribute into its string representation. - /// - /// - public void Serialize(StringBuilder builder) - { - // check if there's something to write - if (_name != null && _value != null) - { - if (_value is Boolean) - { - // flag attribute - if ((Boolean)_value) - builder.Append(_name); - } - else - { - // name-value-pair - builder.Append(_name); - builder.Append('='); - if (_value is String) - { - builder.Append('"'); - builder.Append((String)_value); - builder.Append('"'); - } - else if (_value is Int32) - { - builder.Append(((Int32)_value)); - } - else - { - if (log.IsErrorEnabled) - log.Error(String.Format("Serializing attribute of unexpected type: {0} ({1})", _name, _value.GetType().Name)); - } - } - } - } - - /// - public override String ToString() - { - return String.Format("name: {0} value: {1}", _name, _value); - } - - /// - public Int32 CompareTo(LinkAttribute other) - { - Int32 ret = _name.CompareTo(other.Name); - if (ret == 0) - { - if (_value is String) - return StringValue.CompareTo(other.StringValue); - else if (_value is Int32) - return IntValue.CompareTo(other.IntValue); - } - return ret; - } - } -} diff --git a/CoAP.NET/LinkFormat.cs b/CoAP.NET/LinkFormat.cs deleted file mode 100644 index 3a575b6..0000000 --- a/CoAP.NET/LinkFormat.cs +++ /dev/null @@ -1,494 +0,0 @@ -/* - * Copyright (c) 2011-2014, Longxiang He , - * SmeshLink Technology Co. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY. - * - * This file is part of the CoAP.NET, a CoAP framework in C#. - * Please see README for more information. - */ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Text.RegularExpressions; -using CoAP.EndPoint.Resources; -using CoAP.Log; -using CoAP.Server.Resources; -using CoAP.Util; -using Resource = CoAP.EndPoint.Resources.Resource; - -namespace CoAP -{ - /// - /// This class provides link format definitions as specified in - /// draft-ietf-core-link-format-06 - /// - public static class LinkFormat - { - /// - /// Name of the attribute Resource Type - /// - public static readonly String ResourceType = "rt"; - /// - /// Name of the attribute Interface Description - /// - public static readonly String InterfaceDescription = "if"; - /// - /// Name of the attribute Content Type - /// - public static readonly String ContentType = "ct"; - /// - /// Name of the attribute Max Size Estimate - /// - public static readonly String MaxSizeEstimate = "sz"; - /// - /// Name of the attribute Title - /// - public static readonly String Title = "title"; - /// - /// Name of the attribute Observable - /// - public static readonly String Observable = "obs"; - /// - /// Name of the attribute link - /// - public static readonly String Link = "href"; - - /// - /// The string as the delimiter between resources - /// - public static readonly String Delimiter = ","; - /// - /// The string to separate attributes - /// - public static readonly String Separator = ";"; - - public static readonly Regex DelimiterRegex = new Regex("\\s*" + Delimiter + "+\\s*"); - public static readonly Regex SeparatorRegex = new Regex("\\s*" + Separator + "+\\s*"); - - public static readonly Regex ResourceNameRegex = new Regex("<[^>]*>"); - public static readonly Regex WordRegex = new Regex("\\w+"); - public static readonly Regex QuotedString = new Regex("\\G\".*?\""); - public static readonly Regex Cardinal = new Regex("\\G\\d+"); - static readonly Regex EqualRegex = new Regex("="); - static readonly Regex BlankRegex = new Regex("\\s"); - - private static ILogger log = LogManager.GetLogger(typeof(LinkFormat)); - - public static String Serialize(IResource root) - { - return Serialize(root, null); - } - - public static String Serialize(IResource root, IEnumerable queries) - { - StringBuilder linkFormat = new StringBuilder(); - - foreach (IResource child in root.Children) - { - SerializeTree(child, queries, linkFormat); - } - - if (linkFormat.Length > 1) - linkFormat.Remove(linkFormat.Length - 1, 1); - - return linkFormat.ToString(); - } - - public static IEnumerable Parse(String linkFormat) - { - if (!String.IsNullOrEmpty(linkFormat)) - { - Scanner scanner = new Scanner(linkFormat); - String path = null; - while ((path = scanner.Find(ResourceNameRegex)) != null) - { - path = path.Substring(1, path.Length - 2); - WebLink link = new WebLink(path); - - String attr = null; - while (scanner.Find(DelimiterRegex, 1) == null && - (attr = scanner.Find(WordRegex)) != null) - { - if (scanner.Find(EqualRegex, 1) == null) - { - // flag attribute without value - link.Attributes.Add(attr); - } - else - { - String value = null; - if ((value = scanner.Find(QuotedString)) != null) - { - // trim " " - value = value.Substring(1, value.Length - 2); - if (Title.Equals(attr)) - link.Attributes.Add(attr, value); - else - foreach (String part in BlankRegex.Split(value)) - link.Attributes.Add(attr, part); - } - else if ((value = scanner.Find(WordRegex)) != null) - { - link.Attributes.Set(attr, value); - } - else if ((value = scanner.Find(Cardinal)) != null) - { - link.Attributes.Set(attr, value); - } - } - } - - yield return link; - } - } - - yield break; - } - - private static void SerializeTree(IResource resource, IEnumerable queries, StringBuilder sb) - { - if (resource.Visible && Matches(resource, queries)) - { - SerializeResource(resource, sb); - sb.Append(","); - } - - // sort by resource name - List childrens = new List(resource.Children); - childrens.Sort(delegate(IResource r1, IResource r2) { return String.Compare(r1.Name, r2.Name); }); - - foreach (IResource child in childrens) - { - SerializeTree(child, queries, sb); - } - } - - private static void SerializeResource(IResource resource, StringBuilder sb) - { - sb.Append("<") - .Append(resource.Path) - .Append(resource.Name) - .Append(">"); - SerializeAttributes(resource.Attributes, sb); - } - - private static void SerializeAttributes(ResourceAttributes attributes, StringBuilder sb) - { - List keys = new List(attributes.Keys); - keys.Sort(); - foreach (String name in keys) - { - List values = new List(attributes.GetValues(name)); - if (values.Count == 0) - continue; - sb.Append(Separator); - SerializeAttribute(name, values, sb); - } - } - - private static void SerializeAttribute(String name, IEnumerable values, StringBuilder sb) - { - String delimiter = "="; - Boolean quotes = false; - - sb.Append(name); - - using (IEnumerator it = values.GetEnumerator()) - { - if (!it.MoveNext() || String.IsNullOrEmpty(it.Current)) - return; - - sb.Append(delimiter); - - String first = it.Current; - Boolean more = it.MoveNext(); - if (more || !IsNumber(first)) - { - sb.Append('"'); - quotes = true; - } - - sb.Append(first); - while (more) - { - sb.Append(' '); - sb.Append(it.Current); - more = it.MoveNext(); - } - - if (quotes) - sb.Append('"'); - } - } - - private static Boolean IsNumber(String value) - { - if (String.IsNullOrEmpty(value)) - return false; - foreach (Char c in value) - { - if (!Char.IsNumber(c)) - return false; - } - return true; - } - - public static String Serialize(Resource resource, IEnumerable