Skip to content

Commit

Permalink
Implement packet definitions (#5)
Browse files Browse the repository at this point in the history
* adding MQTT packet control headers and QoS values

* defining packet types

* defining more packet types

* added more packet types

* finished remainder of the packets

* added auth packet

* reformatted
  • Loading branch information
Aaronontheweb authored Apr 12, 2024
1 parent 48373fa commit 863ab50
Show file tree
Hide file tree
Showing 31 changed files with 1,022 additions and 105 deletions.
24 changes: 12 additions & 12 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

</PropertyGroup>

<PropertyGroup Label="NuGetMetaData">
Expand All @@ -21,18 +21,18 @@
<PbmVersion>1.4.0</PbmVersion>
</PropertyGroup>

<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)\README.md" Pack="true" Visible="false" PackagePath="\" />
<None Include="$(MSBuildThisFileDirectory)\LICENSE.md" Pack="true" Visible="false" PackagePath="\" />
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)\README.md" Pack="true" Visible="false" PackagePath="\"/>
<None Include="$(MSBuildThisFileDirectory)\LICENSE.md" Pack="true" Visible="false" PackagePath="\"/>
</ItemGroup>

<PropertyGroup>
<!--<PublishRepositoryUrl>true</PublishRepositoryUrl>-->
<RepositoryUrl>https://github.com/Aaronontheweb/TurboMqtt</RepositoryUrl>
<!-- Optional: Embed source files that are not tracked by the source control manager in the PDB -->
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<!-- Optional: Build symbol package (.snupkg) to distribute the PDB containing Source Link -->
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<!--<PublishRepositoryUrl>true</PublishRepositoryUrl>-->
<RepositoryUrl>https://github.com/Aaronontheweb/TurboMqtt</RepositoryUrl>
<!-- Optional: Embed source files that are not tracked by the source control manager in the PDB -->
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<!-- Optional: Build symbol package (.snupkg) to distribute the PDB containing Source Link -->
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
</Project>
10 changes: 7 additions & 3 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
By accessing code under the [TurboMQTT GitHub Organization](https://github.com/Aaronontheweb/TurboMqtt) (Petabridge, LLC) here, you are agreeing to the following licensing terms. If you do not agree to these terms, do not access TurboMQTT code.
By accessing code under the [TurboMQTT GitHub Organization](https://github.com/Aaronontheweb/TurboMqtt) (Petabridge,
LLC) here, you are agreeing to the following licensing terms. If you do not agree to these terms, do not access
TurboMQTT code.

Your license to TurboMQTT source code and/or binaries is governed by the Reciprocal Public License 1.5 (RPL1.5) license as described here:
Your license to TurboMQTT source code and/or binaries is governed by the Reciprocal Public License 1.5 (RPL1.5) license
as described here:

https://opensource.org/license/rpl-1-5/

If you do not wish to release the source of software you build using TurboMQTT source code and/or binaries under the terms above, you may use TurboMQTT source code and/or binaries under the License Agreement described here:
If you do not wish to release the source of software you build using TurboMQTT source code and/or binaries under the
terms above, you may use TurboMQTT source code and/or binaries under the License Agreement described here:

https://sdkbin.com/publisher/petabridge/product/phobos#license
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@

This is a simple template designed to incorporate local [Akka.NET](https://getakka.net/) into a console application.

See https://github.com/akkadotnet/akkadotnet-templates/blob/dev/docs/ConsoleTemplate.md for complete and current documentation on this template.
See https://github.com/akkadotnet/akkadotnet-templates/blob/dev/docs/ConsoleTemplate.md for complete and current
documentation on this template.
10 changes: 5 additions & 5 deletions TurboMqtt.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TurboMqtt.App", "src\TurboMqtt.App\TurboMqtt.App.csproj", "{EDFEA62C-AF53-4056-A2F2-E37CEA04B24A}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TurboMqtt.Core", "src\TurboMqtt.Core\TurboMqtt.Core.csproj", "{BE905781-3D96-44F5-A230-E06FD5213C1C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -14,9 +14,9 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{EDFEA62C-AF53-4056-A2F2-E37CEA04B24A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EDFEA62C-AF53-4056-A2F2-E37CEA04B24A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EDFEA62C-AF53-4056-A2F2-E37CEA04B24A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EDFEA62C-AF53-4056-A2F2-E37CEA04B24A}.Release|Any CPU.Build.0 = Release|Any CPU
{BE905781-3D96-44F5-A230-E06FD5213C1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BE905781-3D96-44F5-A230-E06FD5213C1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BE905781-3D96-44F5-A230-E06FD5213C1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BE905781-3D96-44F5-A230-E06FD5213C1C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
6 changes: 6 additions & 0 deletions TurboMqtt.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/FileHeader/FileHeaderText/@EntryValue">-----------------------------------------------------------------------
&lt;copyright file="${File.FileName}" company="Petabridge, LLC"&gt;
Copyright (C) ${File.CreatedYear} - ${CurrentDate.Year} Petabridge, LLC &lt;https://petabridge.com&gt;
&lt;/copyright&gt;
-----------------------------------------------------------------------</s:String></wpf:ResourceDictionary>
15 changes: 0 additions & 15 deletions src/TurboMqtt.App/HelloActor.cs

This file was deleted.

29 changes: 0 additions & 29 deletions src/TurboMqtt.App/Program.cs

This file was deleted.

24 changes: 0 additions & 24 deletions src/TurboMqtt.App/TimerActor.cs

This file was deleted.

14 changes: 0 additions & 14 deletions src/TurboMqtt.App/TurboMqtt.App.csproj

This file was deleted.

2 changes: 0 additions & 2 deletions src/TurboMqtt.App/Usings.cs

This file was deleted.

34 changes: 34 additions & 0 deletions src/TurboMqtt.Core/ControlPacketHeaders.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// -----------------------------------------------------------------------
// <copyright file="ControlPacketHeaders.cs" company="Petabridge, LLC">
// Copyright (C) 2024 - 2024 Petabridge, LLC <https://petabridge.com>
// </copyright>
// -----------------------------------------------------------------------

namespace TurboMqtt.Core;

/// <summary>
/// The type of MQTT packet.
/// </summary>
/// <remarks>
/// Aligns to the MQTT 3.1.1 specification: https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html
///
/// Also supports MQTT 5.0.
/// </remarks>
public enum MqttPacketType
{
Connect = 0x10,
ConnAck = 0x20,
Publish = 0x30,
PubAck = 0x40,
PubRec = 0x50,
PubRel = 0x60,
PubComp = 0x70,
Subscribe = 0x80,
SubAck = 0x90,
Unsubscribe = 0xA0,
UnsubAck = 0xB0,
PingReq = 0xC0,
PingResp = 0xD0,
Disconnect = 0xE0,
Auth = 0xF0
}
44 changes: 44 additions & 0 deletions src/TurboMqtt.Core/MqttPubAckReasonCode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// -----------------------------------------------------------------------
// <copyright file="MqttPubAckReasonCode.cs" company="Petabridge, LLC">
// Copyright (C) 2024 - 2024 Petabridge, LLC <https://petabridge.com>
// </copyright>
// -----------------------------------------------------------------------

namespace TurboMqtt.Core;

/// <summary>
/// All possible reason codes for the PubAck packet.
/// </summary>
public enum MqttPubAckReasonCode
{
Success = 0x00,
NoMatchingSubscribers = 0x10,
UnspecifiedError = 0x80,
ImplementationSpecificError = 0x83,
NotAuthorized = 0x87,
TopicNameInvalid = 0x90,
PacketIdentifierInUse = 0x91,
QuotaExceeded = 0x97,
PayloadFormatInvalid = 0x99
}

// add a static helper method that can turn a MqttPubAckReason code into a hard-coded string representation
internal static class MqttPubAckHelpers
{
public static string ReasonCodeToString(MqttPubAckReasonCode reasonCode)
{
return reasonCode switch
{
MqttPubAckReasonCode.Success => "Success",
MqttPubAckReasonCode.NoMatchingSubscribers => "NoMatchingSubscribers",
MqttPubAckReasonCode.UnspecifiedError => "UnspecifiedError",
MqttPubAckReasonCode.ImplementationSpecificError => "ImplementationSpecificError",
MqttPubAckReasonCode.NotAuthorized => "NotAuthorized",
MqttPubAckReasonCode.TopicNameInvalid => "TopicNameInvalid",
MqttPubAckReasonCode.PacketIdentifierInUse => "PacketIdentifierInUse",
MqttPubAckReasonCode.QuotaExceeded => "QuotaExceeded",
MqttPubAckReasonCode.PayloadFormatInvalid => "PayloadFormatInvalid",
_ => throw new ArgumentOutOfRangeException(nameof(reasonCode), reasonCode, null)
};
}
}
31 changes: 31 additions & 0 deletions src/TurboMqtt.Core/NonZeroUInt32.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// -----------------------------------------------------------------------
// <copyright file="NonZeroUInt32.cs" company="Petabridge, LLC">
// Copyright (C) 2024 - 2024 Petabridge, LLC <https://petabridge.com>
// </copyright>
// -----------------------------------------------------------------------

namespace TurboMqtt.Core;

/// <summary>
/// Subscription and packet identifiers must be greater than 0.
/// </summary>
public readonly struct NonZeroUInt32
{
/// <summary>
/// The value of the identifier.
/// </summary>
public uint Value { get; }

public NonZeroUInt32(uint value)
{
if (value == 0)
{
throw new ArgumentOutOfRangeException(nameof(value), "Value must be greater than 0.");
}

Value = value;
}

public static implicit operator uint(NonZeroUInt32 value) => value.Value;
public static implicit operator NonZeroUInt32(uint value) => new(value);
}
76 changes: 76 additions & 0 deletions src/TurboMqtt.Core/PacketTypes/AuthPacket.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// -----------------------------------------------------------------------
// <copyright file="AuthPacket.cs" company="Petabridge, LLC">
// Copyright (C) 2024 - 2024 Petabridge, LLC <https://petabridge.com>
// </copyright>
// -----------------------------------------------------------------------

namespace TurboMqtt.Core.PacketTypes;

/// <summary>
/// Used for authentication exchange or error reporting concerning authentication.
/// </summary>
/// <remarks>
/// This packet is only applicable in MQTT 5.0 and is used both in the initial connection phase and for dynamic re-authentication.
/// </remarks>
public sealed class AuthPacket(string authenticationMethod, AuthReasonCode reasonCode) : MqttPacket
{
// turn the reason code into a ReasonString

public override MqttPacketType PacketType => MqttPacketType.Auth;

/// <summary>
/// The Reason Code for the AUTH packet, which indicates the status of the authentication or any authentication errors.
/// </summary>
public AuthReasonCode ReasonCode { get; } = reasonCode;

// MQTT 5.0 - Optional Properties
/// <summary>
/// Authentication Method, used to specify the method of authentication.
/// </summary>
public string AuthenticationMethod { get; } = authenticationMethod; // Required if Auth Packet is used

/// <summary>
/// Authentication Data, typically containing credentials or challenge/response data, depending on the auth method.
/// </summary>
public ReadOnlyMemory<byte> AuthenticationData { get; set; }

/// <summary>
/// User Properties, available in MQTT 5.0.
/// This is a key-value pair that can be sent multiple times to convey additional information that is not covered by other means.
/// </summary>
public IReadOnlyDictionary<string, string>? UserProperties { get; set; }

/// <summary>
/// Reason String providing additional information about the authentication status.
/// </summary>
public string? ReasonString { get; set; } = reasonCode.ToReasonString();

public override string ToString()
{
return $"Auth: [ReasonCode={ReasonCode}]";
}
}

/// <summary>
/// Enumerates the reason codes applicable to the AUTH packet in MQTT 5.0.
/// </summary>
public enum AuthReasonCode
{
Success = 0x00,
ContinueAuthentication = 0x18,
ReAuthenticate = 0x19
}

internal static class AuthReasonCodeHelpers
{
public static string ToReasonString(this AuthReasonCode reasonCode)
{
return reasonCode switch
{
AuthReasonCode.Success => "Success",
AuthReasonCode.ContinueAuthentication => "Continue Authentication",
AuthReasonCode.ReAuthenticate => "Re-Authenticate",
_ => "Unknown Reason Code"
};
}
}
Loading

0 comments on commit 863ab50

Please sign in to comment.