// Copyright 2020-2026 The NATS Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // Adapted from server/mqtt.go in the NATS server Go source. namespace ZB.MOM.NatsNet.Server.Mqtt; // References to "spec" here are from https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.pdf /// /// MQTT control packet type byte values. /// Mirrors the mqttPacket* constants in server/mqtt.go. /// internal static class MqttPacket { public const byte Connect = 0x10; public const byte ConnectAck = 0x20; public const byte Pub = 0x30; public const byte PubAck = 0x40; public const byte PubRec = 0x50; public const byte PubRel = 0x60; public const byte PubComp = 0x70; public const byte Sub = 0x80; public const byte SubAck = 0x90; public const byte Unsub = 0xA0; public const byte UnsubAck = 0xB0; public const byte Ping = 0xC0; public const byte PingResp = 0xD0; public const byte Disconnect = 0xE0; public const byte Mask = 0xF0; public const byte FlagMask = 0x0F; } /// /// MQTT CONNECT packet flag byte values. /// Mirrors the mqttConnFlag* constants in server/mqtt.go. /// internal static class MqttConnectFlag { public const byte Reserved = 0x01; public const byte CleanSession = 0x02; public const byte WillFlag = 0x04; public const byte WillQoS = 0x18; public const byte WillRetain = 0x20; public const byte PasswordFlag = 0x40; public const byte UsernameFlag = 0x80; } /// /// MQTT PUBLISH packet flag byte values. /// Mirrors the mqttPubFlag* and mqttPubQoS* constants in server/mqtt.go. /// internal static class MqttPubFlag { public const byte Retain = 0x01; public const byte QoS = 0x06; public const byte Dup = 0x08; public const byte QoS1 = 0x1 << 1; public const byte QoS2 = 0x2 << 1; } /// /// MQTT CONNACK return codes. /// Mirrors the mqttConnAckRC* constants in server/mqtt.go. /// internal static class MqttConnAckRc { public const byte Accepted = 0x00; public const byte UnacceptableProtocol = 0x01; public const byte IdentifierRejected = 0x02; public const byte ServerUnavailable = 0x03; public const byte BadUserOrPassword = 0x04; public const byte NotAuthorized = 0x05; public const byte QoS2WillRejected = 0x10; } /// /// Miscellaneous MQTT protocol constants. /// Mirrors the remaining scalar constants in server/mqtt.go. /// internal static class MqttConst { /// Maximum control packet payload size (0xFFFFFFF). public const int MaxPayloadSize = 0xFFFFFFF; /// MQTT topic level separator character ('/'). public const char TopicLevelSep = '/'; /// Single-level wildcard character ('+'). public const char SingleLevelWildcard = '+'; /// Multi-level wildcard character ('#'). public const char MultiLevelWildcard = '#'; /// Reserved topic prefix character ('$'). public const char ReservedPrefix = '$'; /// MQTT protocol level byte (v3.1.1 = 0x04). public const byte ProtoLevel = 0x04; /// SUBACK failure return code (0x80). public const byte SubAckFailure = 0x80; /// Fixed flags byte in SUBSCRIBE packets (0x02). public const byte SubscribeFlags = 0x02; /// Fixed flags byte in UNSUBSCRIBE packets (0x02). public const byte UnsubscribeFlags = 0x02; /// /// Suffix appended to the SID of subscriptions created for MQTT '#' wildcard /// at the upper level. Mirrors mqttMultiLevelSidSuffix. /// public const string MultiLevelSidSuffix = " fwc"; /// Initial byte allocation for publish headers (overestimate). public const int InitialPubHeader = 16; /// Default maximum number of pending QoS-1 acks per session. public const int DefaultMaxAckPending = 1024; /// Absolute upper limit on cumulative MaxAckPending across all session subscriptions. public const int MaxAckTotalLimit = 0xFFFF; /// WebSocket path for MQTT connections. public const string WsPath = "/mqtt"; /// Marker character for deleted retained messages (used in flag field). public const char RetainedFlagDelMarker = '-'; } /// /// MQTT-internal NATS subject / stream / consumer name constants. /// Mirrors the string constants in server/mqtt.go that define JetStream stream names, /// subject prefixes, and JSA reply tokens. /// internal static class MqttTopics { // ------------------------------------------------------------------------- // Top-level MQTT subject prefix // ------------------------------------------------------------------------- /// Prefix used for all internal MQTT subjects. public const string Prefix = "$MQTT."; /// /// Prefix for NATS subscriptions used as JS consumer delivery subjects. /// MQTT clients must not subscribe to subjects starting with this prefix. /// public const string SubPrefix = Prefix + "sub."; // ------------------------------------------------------------------------- // JetStream stream names // ------------------------------------------------------------------------- /// Stream name for MQTT QoS >0 messages on a given account. public const string MsgsStreamName = "$MQTT_msgs"; /// Subject prefix for messages in the MQTT messages stream. public const string MsgsStreamSubjectPrefix = Prefix + "msgs."; /// Stream name for MQTT retained messages. public const string RetainedMsgsStreamName = "$MQTT_rmsgs"; /// Subject prefix for messages in the retained messages stream. public const string RetainedMsgsStreamSubject = Prefix + "rmsgs."; /// Stream name for MQTT session state. public const string SessStreamName = "$MQTT_sess"; /// Subject prefix for session state messages. public const string SessStreamSubjectPrefix = Prefix + "sess."; /// Name prefix used when creating per-account session streams. public const string SessionsStreamNamePrefix = "$MQTT_sess_"; /// Stream name for incoming QoS-2 messages. public const string QoS2IncomingMsgsStreamName = "$MQTT_qos2in"; /// Subject prefix for incoming QoS-2 messages. public const string QoS2IncomingMsgsStreamSubjectPrefix = Prefix + "qos2.in."; /// Stream name for outgoing MQTT QoS messages (PUBREL). public const string OutStreamName = "$MQTT_out"; /// Subject prefix for outgoing MQTT messages. public const string OutSubjectPrefix = Prefix + "out."; /// Subject prefix for PUBREL messages. public const string PubRelSubjectPrefix = Prefix + "out.pubrel."; /// Subject prefix for PUBREL delivery subjects. public const string PubRelDeliverySubjectPrefix = Prefix + "deliver.pubrel."; /// Durable consumer name prefix for PUBREL. public const string PubRelConsumerDurablePrefix = "$MQTT_PUBREL_"; // ------------------------------------------------------------------------- // JSA reply subject prefix and token constants // ------------------------------------------------------------------------- /// Prefix of the reply subject for JS API requests. public const string JsaRepliesPrefix = Prefix + "JSA."; // Token position indices within a JSA reply subject. public const int JsaIdTokenPos = 3; public const int JsaTokenPos = 4; public const int JsaClientIdPos = 5; // JSA operation token values. public const string JsaStreamCreate = "SC"; public const string JsaStreamUpdate = "SU"; public const string JsaStreamLookup = "SL"; public const string JsaStreamDel = "SD"; public const string JsaConsumerCreate = "CC"; public const string JsaConsumerLookup = "CL"; public const string JsaConsumerDel = "CD"; public const string JsaMsgStore = "MS"; public const string JsaMsgLoad = "ML"; public const string JsaMsgDelete = "MD"; public const string JsaSessPersist = "SP"; public const string JsaRetainedMsgDel = "RD"; public const string JsaStreamNames = "SN"; // ------------------------------------------------------------------------- // NATS header names injected into re-encoded PUBLISH messages // ------------------------------------------------------------------------- /// Header that indicates the message originated from MQTT and stores published QoS. public const string NatsHeader = "Nmqtt-Pub"; /// Header storing the original MQTT topic for retained messages. public const string NatsRetainedMessageTopic = "Nmqtt-RTopic"; /// Header storing the origin of a retained message. public const string NatsRetainedMessageOrigin = "Nmqtt-ROrigin"; /// Header storing the flags of a retained message. public const string NatsRetainedMessageFlags = "Nmqtt-RFlags"; /// Header storing the source of a retained message. public const string NatsRetainedMessageSource = "Nmqtt-RSource"; /// Header indicating a PUBREL message and storing the packet identifier. public const string NatsPubRelHeader = "Nmqtt-PubRel"; /// Header storing the original MQTT subject in re-encoded PUBLISH messages. public const string NatsHeaderSubject = "Nmqtt-Subject"; /// Header storing the subject mapping in re-encoded PUBLISH messages. public const string NatsHeaderMapped = "Nmqtt-Mapped"; // ------------------------------------------------------------------------- // Sparkplug B constants // ------------------------------------------------------------------------- public const string SparkbNBirth = "NBIRTH"; public const string SparkbDBirth = "DBIRTH"; public const string SparkbNDeath = "NDEATH"; public const string SparkbDDeath = "DDEATH"; }