blob: 652c3183865fe4e6337c99ed2d980c3e9f37dc56 [file] [log] [blame]
<html>
<head>
<style type="text/css">
.hll { background-color: #ffffcc }
.c { color: #888888 } /* Comment */
.err { color: #a61717; background-color: #e3d2d2 } /* Error */
.k { color: #008800; font-weight: bold } /* Keyword */
.cm { color: #888888 } /* Comment.Multiline */
.cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.c1 { color: #888888 } /* Comment.Single */
.cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */
.gr { color: #aa0000 } /* Generic.Error */
.gh { color: #333333 } /* Generic.Heading */
.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.go { color: #888888 } /* Generic.Output */
.gp { color: #555555 } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */
.gu { color: #666666 } /* Generic.Subheading */
.gt { color: #aa0000 } /* Generic.Traceback */
.kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.kp { color: #008800 } /* Keyword.Pseudo */
.kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.kt { color: #888888; font-weight: bold } /* Keyword.Type */
.m { color: #0000DD; font-weight: bold } /* Literal.Number */
.s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.na { color: #336699 } /* Name.Attribute */
.nb { color: #003388 } /* Name.Builtin */
.nc { color: #bb0066; font-weight: bold } /* Name.Class */
.no { color: #003366; font-weight: bold } /* Name.Constant */
.nd { color: #555555 } /* Name.Decorator */
.ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.nf { color: #0066bb; font-weight: bold } /* Name.Function */
.nl { color: #336699; font-style: italic } /* Name.Label */
.nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.py { color: #336699; font-weight: bold } /* Name.Property */
.nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.nv { color: #336699 } /* Name.Variable */
.ow { color: #008800 } /* Operator.Word */
.w { color: #bbbbbb } /* Text.Whitespace */
.mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.bp { color: #003388 } /* Name.Builtin.Pseudo */
.vc { color: #336699 } /* Name.Variable.Class */
.vg { color: #dd7700 } /* Name.Variable.Global */
.vi { color: #3333bb } /* Name.Variable.Instance */
.il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
</style>
</head>
<body>
<h1>MQTT 3.1.1 packet formats</h1>
<pre>
<div class="highlight"><pre><a name="MQTTV311.py-pyg.html-1"></a><span class="sd">&quot;&quot;&quot;</span>
<a name="MQTTV311.py-pyg.html-2"></a><span class="sd">*******************************************************************</span>
<a name="MQTTV311.py-pyg.html-3"></a><span class="sd"> Copyright (c) 2013, 2014 IBM Corp.</span>
<a name="MQTTV311.py-pyg.html-4"></a><span class="sd"> </span>
<a name="MQTTV311.py-pyg.html-5"></a><span class="sd"> All rights reserved. This program and the accompanying materials</span>
<a name="MQTTV311.py-pyg.html-6"></a><span class="sd"> are made available under the terms of the Eclipse Public License v1.0</span>
<a name="MQTTV311.py-pyg.html-7"></a><span class="sd"> and Eclipse Distribution License v1.0 which accompany this distribution. </span>
<a name="MQTTV311.py-pyg.html-8"></a><span class="sd"> </span>
<a name="MQTTV311.py-pyg.html-9"></a><span class="sd"> The Eclipse Public License is available at </span>
<a name="MQTTV311.py-pyg.html-10"></a><span class="sd"> http://www.eclipse.org/legal/epl-v10.html</span>
<a name="MQTTV311.py-pyg.html-11"></a><span class="sd"> and the Eclipse Distribution License is available at </span>
<a name="MQTTV311.py-pyg.html-12"></a><span class="sd"> http://www.eclipse.org/org/documents/edl-v10.php.</span>
<a name="MQTTV311.py-pyg.html-13"></a><span class="sd"> </span>
<a name="MQTTV311.py-pyg.html-14"></a><span class="sd"> Contributors:</span>
<a name="MQTTV311.py-pyg.html-15"></a><span class="sd"> Ian Craggs - initial implementation and/or documentation</span>
<a name="MQTTV311.py-pyg.html-16"></a><span class="sd">*******************************************************************</span>
<a name="MQTTV311.py-pyg.html-17"></a>
<a name="MQTTV311.py-pyg.html-18"></a>
<a name="MQTTV311.py-pyg.html-19"></a><span class="sd">Assertions are used to validate incoming data, but are omitted from outgoing packets. This is</span>
<a name="MQTTV311.py-pyg.html-20"></a><span class="sd">so that the tests that use this package can send invalid data for error testing.</span>
<a name="MQTTV311.py-pyg.html-21"></a>
<a name="MQTTV311.py-pyg.html-22"></a><span class="sd">&quot;&quot;&quot;</span>
<a name="MQTTV311.py-pyg.html-23"></a>
<a name="MQTTV311.py-pyg.html-24"></a><span class="kn">import</span> <span class="nn">logging</span>
<a name="MQTTV311.py-pyg.html-25"></a>
<a name="MQTTV311.py-pyg.html-26"></a><span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&#39;MQTT broker&#39;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-27"></a>
<a name="MQTTV311.py-pyg.html-28"></a><span class="c"># Low-level protocol interface</span>
<a name="MQTTV311.py-pyg.html-29"></a>
<a name="MQTTV311.py-pyg.html-30"></a><span class="k">class</span> <span class="nc">MQTTException</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-31"></a> <span class="k">pass</span>
<a name="MQTTV311.py-pyg.html-32"></a>
<a name="MQTTV311.py-pyg.html-33"></a>
<a name="MQTTV311.py-pyg.html-34"></a><span class="c"># Message types</span>
<a name="MQTTV311.py-pyg.html-35"></a><span class="n">CONNECT</span><span class="p">,</span> <span class="n">CONNACK</span><span class="p">,</span> <span class="n">PUBLISH</span><span class="p">,</span> <span class="n">PUBACK</span><span class="p">,</span> <span class="n">PUBREC</span><span class="p">,</span> <span class="n">PUBREL</span><span class="p">,</span> \
<a name="MQTTV311.py-pyg.html-36"></a><span class="n">PUBCOMP</span><span class="p">,</span> <span class="n">SUBSCRIBE</span><span class="p">,</span> <span class="n">SUBACK</span><span class="p">,</span> <span class="n">UNSUBSCRIBE</span><span class="p">,</span> <span class="n">UNSUBACK</span><span class="p">,</span> \
<a name="MQTTV311.py-pyg.html-37"></a><span class="n">PINGREQ</span><span class="p">,</span> <span class="n">PINGRESP</span><span class="p">,</span> <span class="n">DISCONNECT</span> <span class="o">=</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">15</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-38"></a>
<a name="MQTTV311.py-pyg.html-39"></a><span class="n">packetNames</span> <span class="o">=</span> <span class="p">[</span> <span class="s">&quot;reserved&quot;</span><span class="p">,</span> \
<a name="MQTTV311.py-pyg.html-40"></a><span class="s">&quot;Connect&quot;</span><span class="p">,</span> <span class="s">&quot;Connack&quot;</span><span class="p">,</span> <span class="s">&quot;Publish&quot;</span><span class="p">,</span> <span class="s">&quot;Puback&quot;</span><span class="p">,</span> <span class="s">&quot;Pubrec&quot;</span><span class="p">,</span> <span class="s">&quot;Pubrel&quot;</span><span class="p">,</span> \
<a name="MQTTV311.py-pyg.html-41"></a><span class="s">&quot;Pubcomp&quot;</span><span class="p">,</span> <span class="s">&quot;Subscribe&quot;</span><span class="p">,</span> <span class="s">&quot;Suback&quot;</span><span class="p">,</span> <span class="s">&quot;Unsubscribe&quot;</span><span class="p">,</span> <span class="s">&quot;Unsuback&quot;</span><span class="p">,</span> \
<a name="MQTTV311.py-pyg.html-42"></a><span class="s">&quot;Pingreq&quot;</span><span class="p">,</span> <span class="s">&quot;Pingresp&quot;</span><span class="p">,</span> <span class="s">&quot;Disconnect&quot;</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-43"></a>
<a name="MQTTV311.py-pyg.html-44"></a><span class="n">classNames</span> <span class="o">=</span> <span class="p">[</span> <span class="s">&quot;reserved&quot;</span><span class="p">,</span> \
<a name="MQTTV311.py-pyg.html-45"></a><span class="s">&quot;Connects&quot;</span><span class="p">,</span> <span class="s">&quot;Connacks&quot;</span><span class="p">,</span> <span class="s">&quot;Publishes&quot;</span><span class="p">,</span> <span class="s">&quot;Pubacks&quot;</span><span class="p">,</span> <span class="s">&quot;Pubrecs&quot;</span><span class="p">,</span> <span class="s">&quot;Pubrels&quot;</span><span class="p">,</span> \
<a name="MQTTV311.py-pyg.html-46"></a><span class="s">&quot;Pubcomps&quot;</span><span class="p">,</span> <span class="s">&quot;Subscribes&quot;</span><span class="p">,</span> <span class="s">&quot;Subacks&quot;</span><span class="p">,</span> <span class="s">&quot;Unsubscribes&quot;</span><span class="p">,</span> <span class="s">&quot;Unsubacks&quot;</span><span class="p">,</span> \
<a name="MQTTV311.py-pyg.html-47"></a><span class="s">&quot;Pingreqs&quot;</span><span class="p">,</span> <span class="s">&quot;Pingresps&quot;</span><span class="p">,</span> <span class="s">&quot;Disconnects&quot;</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-48"></a>
<a name="MQTTV311.py-pyg.html-49"></a>
<a name="MQTTV311.py-pyg.html-50"></a><span class="k">def</span> <span class="nf">MessageType</span><span class="p">(</span><span class="n">byte</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-51"></a> <span class="k">if</span> <span class="n">byte</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-52"></a> <span class="n">rc</span> <span class="o">=</span> <span class="n">byte</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&gt;&gt;</span> <span class="mi">4</span>
<a name="MQTTV311.py-pyg.html-53"></a> <span class="k">else</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-54"></a> <span class="n">rc</span> <span class="o">=</span> <span class="bp">None</span>
<a name="MQTTV311.py-pyg.html-55"></a> <span class="k">return</span> <span class="n">rc</span>
<a name="MQTTV311.py-pyg.html-56"></a>
<a name="MQTTV311.py-pyg.html-57"></a>
<a name="MQTTV311.py-pyg.html-58"></a><span class="k">def</span> <span class="nf">getPacket</span><span class="p">(</span><span class="n">aSocket</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-59"></a> <span class="s">&quot;receive the next packet&quot;</span>
<a name="MQTTV311.py-pyg.html-60"></a> <span class="n">buf</span> <span class="o">=</span> <span class="n">aSocket</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="c"># get the first byte fixed header</span>
<a name="MQTTV311.py-pyg.html-61"></a> <span class="k">if</span> <span class="n">buf</span> <span class="o">==</span> <span class="n">b</span><span class="s">&quot;&quot;</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-62"></a> <span class="k">return</span> <span class="bp">None</span>
<a name="MQTTV311.py-pyg.html-63"></a> <span class="c"># now get the remaining length</span>
<a name="MQTTV311.py-pyg.html-64"></a> <span class="n">multiplier</span> <span class="o">=</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-65"></a> <span class="n">remlength</span> <span class="o">=</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-66"></a> <span class="k">while</span> <span class="mi">1</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-67"></a> <span class="n">buf</span> <span class="o">+=</span> <span class="n">aSocket</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-68"></a> <span class="n">digit</span> <span class="o">=</span> <span class="n">buf</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-69"></a> <span class="n">remlength</span> <span class="o">+=</span> <span class="p">(</span><span class="n">digit</span> <span class="o">&amp;</span> <span class="mi">127</span><span class="p">)</span> <span class="o">*</span> <span class="n">multiplier</span>
<a name="MQTTV311.py-pyg.html-70"></a> <span class="k">if</span> <span class="n">digit</span> <span class="o">&amp;</span> <span class="mi">128</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-71"></a> <span class="k">break</span>
<a name="MQTTV311.py-pyg.html-72"></a> <span class="n">multiplier</span> <span class="o">*=</span> <span class="mi">128</span>
<a name="MQTTV311.py-pyg.html-73"></a> <span class="c"># receive the remaining length if there is any</span>
<a name="MQTTV311.py-pyg.html-74"></a> <span class="n">rest</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">([])</span>
<a name="MQTTV311.py-pyg.html-75"></a> <span class="k">if</span> <span class="n">remlength</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-76"></a> <span class="k">while</span> <span class="nb">len</span><span class="p">(</span><span class="n">rest</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">remlength</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-77"></a> <span class="n">rest</span> <span class="o">+=</span> <span class="n">aSocket</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="n">remlength</span><span class="o">-</span><span class="nb">len</span><span class="p">(</span><span class="n">rest</span><span class="p">))</span>
<a name="MQTTV311.py-pyg.html-78"></a> <span class="k">return</span> <span class="n">buf</span> <span class="o">+</span> <span class="n">rest</span>
<a name="MQTTV311.py-pyg.html-79"></a>
<a name="MQTTV311.py-pyg.html-80"></a>
<a name="MQTTV311.py-pyg.html-81"></a><span class="k">class</span> <span class="nc">FixedHeaders</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-82"></a>
<a name="MQTTV311.py-pyg.html-83"></a> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">aMessageType</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-84"></a> <span class="bp">self</span><span class="o">.</span><span class="n">MessageType</span> <span class="o">=</span> <span class="n">aMessageType</span>
<a name="MQTTV311.py-pyg.html-85"></a> <span class="bp">self</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="bp">False</span>
<a name="MQTTV311.py-pyg.html-86"></a> <span class="bp">self</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-87"></a> <span class="bp">self</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">=</span> <span class="bp">False</span>
<a name="MQTTV311.py-pyg.html-88"></a> <span class="bp">self</span><span class="o">.</span><span class="n">remainingLength</span> <span class="o">=</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-89"></a>
<a name="MQTTV311.py-pyg.html-90"></a> <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fh</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-91"></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">MessageType</span> <span class="o">==</span> <span class="n">fh</span><span class="o">.</span><span class="n">MessageType</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-92"></a> <span class="bp">self</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-93"></a> <span class="bp">self</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-94"></a> <span class="bp">self</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">==</span> <span class="n">fh</span><span class="o">.</span><span class="n">RETAIN</span> <span class="c"># and \</span>
<a name="MQTTV311.py-pyg.html-95"></a> <span class="c"># self.remainingLength == fh.remainingLength</span>
<a name="MQTTV311.py-pyg.html-96"></a>
<a name="MQTTV311.py-pyg.html-97"></a> <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-98"></a> <span class="s">&quot;return printable representation of our data&quot;</span>
<a name="MQTTV311.py-pyg.html-99"></a> <span class="k">return</span> <span class="n">classNames</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">MessageType</span><span class="p">]</span><span class="o">+</span><span class="s">&#39;(DUP=&#39;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">DUP</span><span class="p">)</span><span class="o">+</span> \
<a name="MQTTV311.py-pyg.html-100"></a> <span class="s">&quot;, QoS=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">QoS</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, Retain=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">RETAIN</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-101"></a>
<a name="MQTTV311.py-pyg.html-102"></a> <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">length</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-103"></a> <span class="s">&quot;pack data into string buffer ready for transmission down socket&quot;</span>
<a name="MQTTV311.py-pyg.html-104"></a> <span class="nb">buffer</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">([(</span><span class="bp">self</span><span class="o">.</span><span class="n">MessageType</span> <span class="o">&lt;&lt;</span> <span class="mi">4</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">DUP</span> <span class="o">&lt;&lt;</span> <span class="mi">3</span><span class="p">)</span> <span class="o">|</span>\
<a name="MQTTV311.py-pyg.html-105"></a> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">QoS</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span><span class="p">)</span> <span class="o">|</span> <span class="bp">self</span><span class="o">.</span><span class="n">RETAIN</span><span class="p">])</span>
<a name="MQTTV311.py-pyg.html-106"></a> <span class="bp">self</span><span class="o">.</span><span class="n">remainingLength</span> <span class="o">=</span> <span class="n">length</span>
<a name="MQTTV311.py-pyg.html-107"></a> <span class="nb">buffer</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">length</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-108"></a> <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-109"></a>
<a name="MQTTV311.py-pyg.html-110"></a> <span class="k">def</span> <span class="nf">encode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-111"></a> <span class="k">assert</span> <span class="mi">0</span> <span class="o">&lt;=</span> <span class="n">x</span> <span class="o">&lt;=</span> <span class="mi">268435455</span>
<a name="MQTTV311.py-pyg.html-112"></a> <span class="nb">buffer</span> <span class="o">=</span> <span class="n">b</span><span class="s">&#39;&#39;</span>
<a name="MQTTV311.py-pyg.html-113"></a> <span class="k">while</span> <span class="mi">1</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-114"></a> <span class="n">digit</span> <span class="o">=</span> <span class="n">x</span> <span class="o">%</span> <span class="mi">128</span>
<a name="MQTTV311.py-pyg.html-115"></a> <span class="n">x</span> <span class="o">//=</span> <span class="mi">128</span>
<a name="MQTTV311.py-pyg.html-116"></a> <span class="k">if</span> <span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-117"></a> <span class="n">digit</span> <span class="o">|=</span> <span class="mh">0x80</span>
<a name="MQTTV311.py-pyg.html-118"></a> <span class="nb">buffer</span> <span class="o">+=</span> <span class="nb">bytes</span><span class="p">([</span><span class="n">digit</span><span class="p">])</span>
<a name="MQTTV311.py-pyg.html-119"></a> <span class="k">if</span> <span class="n">x</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-120"></a> <span class="k">break</span>
<a name="MQTTV311.py-pyg.html-121"></a> <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-122"></a>
<a name="MQTTV311.py-pyg.html-123"></a> <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-124"></a> <span class="s">&quot;unpack data from string buffer into separate fields&quot;</span>
<a name="MQTTV311.py-pyg.html-125"></a> <span class="n">b0</span> <span class="o">=</span> <span class="nb">buffer</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-126"></a> <span class="bp">self</span><span class="o">.</span><span class="n">MessageType</span> <span class="o">=</span> <span class="n">b0</span> <span class="o">&gt;&gt;</span> <span class="mi">4</span>
<a name="MQTTV311.py-pyg.html-127"></a> <span class="bp">self</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="p">((</span><span class="n">b0</span> <span class="o">&gt;&gt;</span> <span class="mi">3</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x01</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-128"></a> <span class="bp">self</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="p">(</span><span class="n">b0</span> <span class="o">&gt;&gt;</span> <span class="mi">1</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x03</span>
<a name="MQTTV311.py-pyg.html-129"></a> <span class="bp">self</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">=</span> <span class="p">(</span><span class="n">b0</span> <span class="o">&amp;</span> <span class="mh">0x01</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-130"></a> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">remainingLength</span><span class="p">,</span> <span class="nb">bytes</span><span class="p">)</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<a name="MQTTV311.py-pyg.html-131"></a> <span class="k">return</span> <span class="nb">bytes</span> <span class="o">+</span> <span class="mi">1</span> <span class="c"># length of fixed header</span>
<a name="MQTTV311.py-pyg.html-132"></a>
<a name="MQTTV311.py-pyg.html-133"></a> <span class="k">def</span> <span class="nf">decode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-134"></a> <span class="n">multiplier</span> <span class="o">=</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-135"></a> <span class="n">value</span> <span class="o">=</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-136"></a> <span class="nb">bytes</span> <span class="o">=</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-137"></a> <span class="k">while</span> <span class="mi">1</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-138"></a> <span class="nb">bytes</span> <span class="o">+=</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-139"></a> <span class="n">digit</span> <span class="o">=</span> <span class="nb">buffer</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-140"></a> <span class="nb">buffer</span> <span class="o">=</span> <span class="nb">buffer</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<a name="MQTTV311.py-pyg.html-141"></a> <span class="n">value</span> <span class="o">+=</span> <span class="p">(</span><span class="n">digit</span> <span class="o">&amp;</span> <span class="mi">127</span><span class="p">)</span> <span class="o">*</span> <span class="n">multiplier</span>
<a name="MQTTV311.py-pyg.html-142"></a> <span class="k">if</span> <span class="n">digit</span> <span class="o">&amp;</span> <span class="mi">128</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-143"></a> <span class="k">break</span>
<a name="MQTTV311.py-pyg.html-144"></a> <span class="n">multiplier</span> <span class="o">*=</span> <span class="mi">128</span>
<a name="MQTTV311.py-pyg.html-145"></a> <span class="k">return</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">bytes</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-146"></a>
<a name="MQTTV311.py-pyg.html-147"></a>
<a name="MQTTV311.py-pyg.html-148"></a><span class="k">def</span> <span class="nf">writeInt16</span><span class="p">(</span><span class="n">length</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-149"></a> <span class="k">return</span> <span class="nb">bytes</span><span class="p">([</span><span class="n">length</span> <span class="o">//</span> <span class="mi">256</span><span class="p">,</span> <span class="n">length</span> <span class="o">%</span> <span class="mi">256</span><span class="p">])</span>
<a name="MQTTV311.py-pyg.html-150"></a>
<a name="MQTTV311.py-pyg.html-151"></a><span class="k">def</span> <span class="nf">readInt16</span><span class="p">(</span><span class="n">buf</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-152"></a> <span class="k">return</span> <span class="n">buf</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">*</span><span class="mi">256</span> <span class="o">+</span> <span class="n">buf</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-153"></a>
<a name="MQTTV311.py-pyg.html-154"></a><span class="k">def</span> <span class="nf">writeUTF</span><span class="p">(</span><span class="n">data</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-155"></a> <span class="c"># data could be a string, or bytes. If string, encode into bytes with utf-8</span>
<a name="MQTTV311.py-pyg.html-156"></a> <span class="k">return</span> <span class="n">writeInt16</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">))</span> <span class="o">+</span> <span class="p">(</span><span class="n">data</span> <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">==</span> <span class="nb">type</span><span class="p">(</span><span class="n">b</span><span class="s">&quot;&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="nb">bytes</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="s">&quot;utf-8&quot;</span><span class="p">))</span>
<a name="MQTTV311.py-pyg.html-157"></a>
<a name="MQTTV311.py-pyg.html-158"></a><span class="k">def</span> <span class="nf">readUTF</span><span class="p">(</span><span class="nb">buffer</span><span class="p">,</span> <span class="n">maxlen</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-159"></a> <span class="k">if</span> <span class="n">maxlen</span> <span class="o">&gt;</span> <span class="mi">2</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-160"></a> <span class="n">length</span> <span class="o">=</span> <span class="n">readInt16</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-161"></a> <span class="k">else</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-162"></a> <span class="k">raise</span> <span class="n">MQTTException</span><span class="p">(</span><span class="s">&quot;Not enough data to read string length&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-163"></a> <span class="n">maxlen</span> <span class="o">-=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-164"></a> <span class="k">if</span> <span class="n">length</span> <span class="o">&gt;</span> <span class="n">maxlen</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-165"></a> <span class="k">raise</span> <span class="n">MQTTException</span><span class="p">(</span><span class="s">&quot;Length delimited string too long&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-166"></a> <span class="n">buf</span> <span class="o">=</span> <span class="nb">buffer</span><span class="p">[</span><span class="mi">2</span><span class="p">:</span><span class="mi">2</span><span class="o">+</span><span class="n">length</span><span class="p">]</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s">&quot;utf-8&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-167"></a> <span class="n">zz</span> <span class="o">=</span> <span class="n">buf</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\x00</span><span class="s">&quot;</span><span class="p">)</span> <span class="c"># look for null in the UTF string</span>
<a name="MQTTV311.py-pyg.html-168"></a> <span class="k">if</span> <span class="n">zz</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-169"></a> <span class="k">raise</span> <span class="n">MQTTException</span><span class="p">(</span><span class="s">&quot;[MQTT-1.4.0-2] Null found in UTF data &quot;</span><span class="o">+</span><span class="n">buf</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-170"></a> <span class="k">if</span> <span class="n">buf</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\uFEFF</span><span class="s">&quot;</span><span class="p">)</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-171"></a> <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-1.2.0-3] U+FEFF in UTF string&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-172"></a> <span class="k">return</span> <span class="n">buf</span>
<a name="MQTTV311.py-pyg.html-173"></a>
<a name="MQTTV311.py-pyg.html-174"></a><span class="k">def</span> <span class="nf">writeBytes</span><span class="p">(</span><span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-175"></a> <span class="k">return</span> <span class="n">writeInt16</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">))</span> <span class="o">+</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-176"></a>
<a name="MQTTV311.py-pyg.html-177"></a><span class="k">def</span> <span class="nf">readBytes</span><span class="p">(</span><span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-178"></a> <span class="n">length</span> <span class="o">=</span> <span class="n">readInt16</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-179"></a> <span class="k">return</span> <span class="nb">buffer</span><span class="p">[</span><span class="mi">2</span><span class="p">:</span><span class="mi">2</span><span class="o">+</span><span class="n">length</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-180"></a>
<a name="MQTTV311.py-pyg.html-181"></a>
<a name="MQTTV311.py-pyg.html-182"></a><span class="k">class</span> <span class="nc">Packets</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-183"></a>
<a name="MQTTV311.py-pyg.html-184"></a> <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-185"></a> <span class="nb">buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-186"></a> <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-187"></a>
<a name="MQTTV311.py-pyg.html-188"></a> <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-189"></a> <span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-190"></a>
<a name="MQTTV311.py-pyg.html-191"></a> <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-192"></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">fh</span> <span class="k">if</span> <span class="n">packet</span> <span class="k">else</span> <span class="bp">False</span>
<a name="MQTTV311.py-pyg.html-193"></a>
<a name="MQTTV311.py-pyg.html-194"></a>
<a name="MQTTV311.py-pyg.html-195"></a><span class="k">class</span> <span class="nc">Connects</span><span class="p">(</span><span class="n">Packets</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-196"></a>
<a name="MQTTV311.py-pyg.html-197"></a> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-198"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">=</span> <span class="n">FixedHeaders</span><span class="p">(</span><span class="n">CONNECT</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-199"></a>
<a name="MQTTV311.py-pyg.html-200"></a> <span class="c"># variable header</span>
<a name="MQTTV311.py-pyg.html-201"></a> <span class="bp">self</span><span class="o">.</span><span class="n">ProtocolName</span> <span class="o">=</span> <span class="s">&quot;MQTT&quot;</span>
<a name="MQTTV311.py-pyg.html-202"></a> <span class="bp">self</span><span class="o">.</span><span class="n">ProtocolVersion</span> <span class="o">=</span> <span class="mi">4</span>
<a name="MQTTV311.py-pyg.html-203"></a> <span class="bp">self</span><span class="o">.</span><span class="n">CleanSession</span> <span class="o">=</span> <span class="bp">True</span>
<a name="MQTTV311.py-pyg.html-204"></a> <span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span> <span class="o">=</span> <span class="bp">False</span>
<a name="MQTTV311.py-pyg.html-205"></a> <span class="bp">self</span><span class="o">.</span><span class="n">WillQoS</span> <span class="o">=</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-206"></a> <span class="bp">self</span><span class="o">.</span><span class="n">WillRETAIN</span> <span class="o">=</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-207"></a> <span class="bp">self</span><span class="o">.</span><span class="n">KeepAliveTimer</span> <span class="o">=</span> <span class="mi">30</span>
<a name="MQTTV311.py-pyg.html-208"></a> <span class="bp">self</span><span class="o">.</span><span class="n">usernameFlag</span> <span class="o">=</span> <span class="bp">False</span>
<a name="MQTTV311.py-pyg.html-209"></a> <span class="bp">self</span><span class="o">.</span><span class="n">passwordFlag</span> <span class="o">=</span> <span class="bp">False</span>
<a name="MQTTV311.py-pyg.html-210"></a>
<a name="MQTTV311.py-pyg.html-211"></a> <span class="c"># Payload</span>
<a name="MQTTV311.py-pyg.html-212"></a> <span class="bp">self</span><span class="o">.</span><span class="n">ClientIdentifier</span> <span class="o">=</span> <span class="s">&quot;&quot;</span> <span class="c"># UTF-8</span>
<a name="MQTTV311.py-pyg.html-213"></a> <span class="bp">self</span><span class="o">.</span><span class="n">WillTopic</span> <span class="o">=</span> <span class="bp">None</span> <span class="c"># UTF-8</span>
<a name="MQTTV311.py-pyg.html-214"></a> <span class="bp">self</span><span class="o">.</span><span class="n">WillMessage</span> <span class="o">=</span> <span class="bp">None</span> <span class="c"># binary</span>
<a name="MQTTV311.py-pyg.html-215"></a> <span class="bp">self</span><span class="o">.</span><span class="n">username</span> <span class="o">=</span> <span class="bp">None</span> <span class="c"># UTF-8</span>
<a name="MQTTV311.py-pyg.html-216"></a> <span class="bp">self</span><span class="o">.</span><span class="n">password</span> <span class="o">=</span> <span class="bp">None</span> <span class="c"># binary</span>
<a name="MQTTV311.py-pyg.html-217"></a>
<a name="MQTTV311.py-pyg.html-218"></a> <span class="k">if</span> <span class="nb">buffer</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-219"></a> <span class="bp">self</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-220"></a>
<a name="MQTTV311.py-pyg.html-221"></a> <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-222"></a> <span class="n">connectFlags</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">([(</span><span class="bp">self</span><span class="o">.</span><span class="n">CleanSession</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span> <span class="o">&lt;&lt;</span> <span class="mi">2</span><span class="p">)</span> <span class="o">|</span> \
<a name="MQTTV311.py-pyg.html-223"></a> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillQoS</span> <span class="o">&lt;&lt;</span> <span class="mi">3</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillRETAIN</span> <span class="o">&lt;&lt;</span> <span class="mi">5</span><span class="p">)</span> <span class="o">|</span> \
<a name="MQTTV311.py-pyg.html-224"></a> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">usernameFlag</span> <span class="o">&lt;&lt;</span> <span class="mi">6</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">passwordFlag</span> <span class="o">&lt;&lt;</span> <span class="mi">7</span><span class="p">)])</span>
<a name="MQTTV311.py-pyg.html-225"></a> <span class="nb">buffer</span> <span class="o">=</span> <span class="n">writeUTF</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ProtocolName</span><span class="p">)</span> <span class="o">+</span> <span class="nb">bytes</span><span class="p">([</span><span class="bp">self</span><span class="o">.</span><span class="n">ProtocolVersion</span><span class="p">])</span> <span class="o">+</span> \
<a name="MQTTV311.py-pyg.html-226"></a> <span class="n">connectFlags</span> <span class="o">+</span> <span class="n">writeInt16</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">KeepAliveTimer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-227"></a> <span class="nb">buffer</span> <span class="o">+=</span> <span class="n">writeUTF</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ClientIdentifier</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-228"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-229"></a> <span class="nb">buffer</span> <span class="o">+=</span> <span class="n">writeUTF</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillTopic</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-230"></a> <span class="nb">buffer</span> <span class="o">+=</span> <span class="n">writeBytes</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillMessage</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-231"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">usernameFlag</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-232"></a> <span class="nb">buffer</span> <span class="o">+=</span> <span class="n">writeUTF</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-233"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">passwordFlag</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-234"></a> <span class="nb">buffer</span> <span class="o">+=</span> <span class="n">writeBytes</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-235"></a> <span class="nb">buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">))</span> <span class="o">+</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-236"></a> <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-237"></a>
<a name="MQTTV311.py-pyg.html-238"></a> <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-239"></a> <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-240"></a> <span class="k">assert</span> <span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">==</span> <span class="n">CONNECT</span>
<a name="MQTTV311.py-pyg.html-241"></a> <span class="n">fhlen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-242"></a> <span class="n">packlen</span> <span class="o">=</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-243"></a> <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">packlen</span>
<a name="MQTTV311.py-pyg.html-244"></a> <span class="n">curlen</span> <span class="o">=</span> <span class="n">fhlen</span> <span class="c"># points to after header + remaining length</span>
<a name="MQTTV311.py-pyg.html-245"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-246"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-247"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-248"></a>
<a name="MQTTV311.py-pyg.html-249"></a> <span class="bp">self</span><span class="o">.</span><span class="n">ProtocolName</span> <span class="o">=</span> <span class="n">readUTF</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">:],</span> <span class="n">packlen</span> <span class="o">-</span> <span class="n">curlen</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-250"></a> <span class="n">curlen</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ProtocolName</span><span class="p">)</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-251"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">ProtocolName</span> <span class="o">==</span> <span class="s">&quot;MQTT&quot;</span><span class="p">,</span> <span class="s">&quot;Wrong protocol name </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">ProtocolName</span>
<a name="MQTTV311.py-pyg.html-252"></a>
<a name="MQTTV311.py-pyg.html-253"></a> <span class="bp">self</span><span class="o">.</span><span class="n">ProtocolVersion</span> <span class="o">=</span> <span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-254"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">ProtocolVersion</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">4</span><span class="p">],</span> <span class="s">&quot;Wrong protocol version </span><span class="si">%d</span><span class="s">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">ProtocolVersion</span>
<a name="MQTTV311.py-pyg.html-255"></a> <span class="n">curlen</span> <span class="o">+=</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-256"></a>
<a name="MQTTV311.py-pyg.html-257"></a> <span class="n">connectFlags</span> <span class="o">=</span> <span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-258"></a> <span class="k">assert</span> <span class="p">(</span><span class="n">connectFlags</span> <span class="o">&amp;</span> <span class="mh">0x01</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-3.1.2-3] reserved connect flag must be 0&quot;</span>
<a name="MQTTV311.py-pyg.html-259"></a> <span class="bp">self</span><span class="o">.</span><span class="n">CleanSession</span> <span class="o">=</span> <span class="p">((</span><span class="n">connectFlags</span> <span class="o">&gt;&gt;</span> <span class="mi">1</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x01</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-260"></a> <span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span> <span class="o">=</span> <span class="p">((</span><span class="n">connectFlags</span> <span class="o">&gt;&gt;</span> <span class="mi">2</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x01</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-261"></a> <span class="bp">self</span><span class="o">.</span><span class="n">WillQoS</span> <span class="o">=</span> <span class="p">(</span><span class="n">connectFlags</span> <span class="o">&gt;&gt;</span> <span class="mi">3</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x03</span>
<a name="MQTTV311.py-pyg.html-262"></a> <span class="bp">self</span><span class="o">.</span><span class="n">WillRETAIN</span> <span class="o">=</span> <span class="p">(</span><span class="n">connectFlags</span> <span class="o">&gt;&gt;</span> <span class="mi">5</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x01</span>
<a name="MQTTV311.py-pyg.html-263"></a> <span class="bp">self</span><span class="o">.</span><span class="n">usernameFlag</span> <span class="o">=</span> <span class="p">((</span><span class="n">connectFlags</span> <span class="o">&gt;&gt;</span> <span class="mi">6</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x01</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-264"></a> <span class="bp">self</span><span class="o">.</span><span class="n">passwordFlag</span> <span class="o">=</span> <span class="p">((</span><span class="n">connectFlags</span> <span class="o">&gt;&gt;</span> <span class="mi">7</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x01</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-265"></a> <span class="n">curlen</span> <span class="o">+=</span><span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-266"></a>
<a name="MQTTV311.py-pyg.html-267"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-268"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillQoS</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">],</span> <span class="s">&quot;[MQTT-3.1.2-12] will qos must not be 3&quot;</span>
<a name="MQTTV311.py-pyg.html-269"></a> <span class="k">else</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-270"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillQoS</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-3.1.2-11] will qos must be 0, if will flag is false&quot;</span>
<a name="MQTTV311.py-pyg.html-271"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillRETAIN</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-3.1.2-13] will retain must be false, if will flag is false&quot;</span>
<a name="MQTTV311.py-pyg.html-272"></a>
<a name="MQTTV311.py-pyg.html-273"></a> <span class="bp">self</span><span class="o">.</span><span class="n">KeepAliveTimer</span> <span class="o">=</span> <span class="n">readInt16</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">:])</span>
<a name="MQTTV311.py-pyg.html-274"></a> <span class="n">curlen</span> <span class="o">+=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-275"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-3.1.3-3] Clientid must be present, and first field&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-276"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-3.1.3-4] Clientid must be Unicode, and between 0 and 65535 bytes long&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-277"></a> <span class="bp">self</span><span class="o">.</span><span class="n">ClientIdentifier</span> <span class="o">=</span> <span class="n">readUTF</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">:],</span> <span class="n">packlen</span> <span class="o">-</span> <span class="n">curlen</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-278"></a> <span class="n">curlen</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ClientIdentifier</span><span class="p">)</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-279"></a>
<a name="MQTTV311.py-pyg.html-280"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-281"></a> <span class="bp">self</span><span class="o">.</span><span class="n">WillTopic</span> <span class="o">=</span> <span class="n">readUTF</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">:],</span> <span class="n">packlen</span> <span class="o">-</span> <span class="n">curlen</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-282"></a> <span class="n">curlen</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillTopic</span><span class="p">)</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-283"></a> <span class="bp">self</span><span class="o">.</span><span class="n">WillMessage</span> <span class="o">=</span> <span class="n">readBytes</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">:])</span>
<a name="MQTTV311.py-pyg.html-284"></a> <span class="n">curlen</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillMessage</span><span class="p">)</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-285"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[[MQTT-3.1.2-9] will topic and will message fields must be present&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-286"></a> <span class="k">else</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-287"></a> <span class="bp">self</span><span class="o">.</span><span class="n">WillTopic</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillMessage</span> <span class="o">=</span> <span class="bp">None</span>
<a name="MQTTV311.py-pyg.html-288"></a>
<a name="MQTTV311.py-pyg.html-289"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">usernameFlag</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-290"></a> <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">curlen</span><span class="o">+</span><span class="mi">2</span><span class="p">,</span> <span class="s">&quot;Buffer too short to read username length&quot;</span>
<a name="MQTTV311.py-pyg.html-291"></a> <span class="bp">self</span><span class="o">.</span><span class="n">username</span> <span class="o">=</span> <span class="n">readUTF</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">:],</span> <span class="n">packlen</span> <span class="o">-</span> <span class="n">curlen</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-292"></a> <span class="n">curlen</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">)</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-293"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-3.1.2-17] username must be in payload if user name flag is 1&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-294"></a> <span class="k">else</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-295"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-3.1.2-16] username must not be in payload if user name flag is 0&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-296"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">passwordFlag</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-3.1.2-20] password flag must be 0 if username flag is 0&quot;</span>
<a name="MQTTV311.py-pyg.html-297"></a>
<a name="MQTTV311.py-pyg.html-298"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">passwordFlag</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-299"></a> <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">curlen</span><span class="o">+</span><span class="mi">2</span><span class="p">,</span> <span class="s">&quot;Buffer too short to read password length&quot;</span>
<a name="MQTTV311.py-pyg.html-300"></a> <span class="bp">self</span><span class="o">.</span><span class="n">password</span> <span class="o">=</span> <span class="n">readBytes</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">:])</span>
<a name="MQTTV311.py-pyg.html-301"></a> <span class="n">curlen</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">)</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-302"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-3.1.2-19] password must be in payload if password flag is 0&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-303"></a> <span class="k">else</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-304"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-3.1.2-16] username must not be in payload if user name flag is 0&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-305"></a>
<a name="MQTTV311.py-pyg.html-306"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">usernameFlag</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">passwordFlag</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-307"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-3.1.3-1] clientid, will topic, will message, username and password all present&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-308"></a>
<a name="MQTTV311.py-pyg.html-309"></a> <span class="k">assert</span> <span class="n">curlen</span> <span class="o">==</span> <span class="n">packlen</span><span class="p">,</span> <span class="s">&quot;Packet is wrong length curlen </span><span class="si">%d</span><span class="s"> != packlen </span><span class="si">%d</span><span class="s">&quot;</span>
<a name="MQTTV311.py-pyg.html-310"></a>
<a name="MQTTV311.py-pyg.html-311"></a>
<a name="MQTTV311.py-pyg.html-312"></a> <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-313"></a> <span class="n">buf</span> <span class="o">=</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, ProtocolName=&quot;</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ProtocolName</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, ProtocolVersion=&quot;</span> <span class="o">+</span>\
<a name="MQTTV311.py-pyg.html-314"></a> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ProtocolVersion</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, CleanSession=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">CleanSession</span><span class="p">)</span> <span class="o">+</span>\
<a name="MQTTV311.py-pyg.html-315"></a> <span class="s">&quot;, WillFlag=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, KeepAliveTimer=&quot;</span> <span class="o">+</span>\
<a name="MQTTV311.py-pyg.html-316"></a> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">KeepAliveTimer</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, ClientId=&quot;</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ClientIdentifier</span><span class="p">)</span> <span class="o">+</span>\
<a name="MQTTV311.py-pyg.html-317"></a> <span class="s">&quot;, usernameFlag=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">usernameFlag</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, passwordFlag=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">passwordFlag</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-318"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-319"></a> <span class="n">buf</span> <span class="o">+=</span> <span class="s">&quot;, WillQoS=&quot;</span> <span class="o">+</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillQoS</span><span class="p">)</span> <span class="o">+</span>\
<a name="MQTTV311.py-pyg.html-320"></a> <span class="s">&quot;, WillRETAIN=&quot;</span> <span class="o">+</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillRETAIN</span><span class="p">)</span> <span class="o">+</span>\
<a name="MQTTV311.py-pyg.html-321"></a> <span class="s">&quot;, WillTopic=&#39;&quot;</span><span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillTopic</span> <span class="o">+</span>\
<a name="MQTTV311.py-pyg.html-322"></a> <span class="s">&quot;&#39;, WillMessage=&#39;&quot;</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillMessage</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;&#39;&quot;</span>
<a name="MQTTV311.py-pyg.html-323"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-324"></a> <span class="n">buf</span> <span class="o">+=</span> <span class="s">&quot;, username=&quot;</span><span class="o">+</span><span class="bp">self</span><span class="o">.</span><span class="n">username</span>
<a name="MQTTV311.py-pyg.html-325"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-326"></a> <span class="n">buf</span> <span class="o">+=</span> <span class="s">&quot;, password=&quot;</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-327"></a> <span class="k">return</span> <span class="n">buf</span><span class="o">+</span><span class="s">&quot;)&quot;</span>
<a name="MQTTV311.py-pyg.html-328"></a>
<a name="MQTTV311.py-pyg.html-329"></a> <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-330"></a> <span class="n">rc</span> <span class="o">=</span> <span class="n">Packets</span><span class="o">.</span><span class="n">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">)</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-331"></a> <span class="bp">self</span><span class="o">.</span><span class="n">ProtocolName</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">ProtocolName</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-332"></a> <span class="bp">self</span><span class="o">.</span><span class="n">ProtocolVersion</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">ProtocolVersion</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-333"></a> <span class="bp">self</span><span class="o">.</span><span class="n">CleanSession</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">CleanSession</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-334"></a> <span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">WillFlag</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-335"></a> <span class="bp">self</span><span class="o">.</span><span class="n">KeepAliveTimer</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">KeepAliveTimer</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-336"></a> <span class="bp">self</span><span class="o">.</span><span class="n">ClientIdentifier</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">ClientIdentifier</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-337"></a> <span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">WillFlag</span>
<a name="MQTTV311.py-pyg.html-338"></a> <span class="k">if</span> <span class="n">rc</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-339"></a> <span class="n">rc</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillQoS</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">WillQoS</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-340"></a> <span class="bp">self</span><span class="o">.</span><span class="n">WillRETAIN</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">WillRETAIN</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-341"></a> <span class="bp">self</span><span class="o">.</span><span class="n">WillTopic</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">WillTopic</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-342"></a> <span class="bp">self</span><span class="o">.</span><span class="n">WillMessage</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">WillMessage</span>
<a name="MQTTV311.py-pyg.html-343"></a> <span class="k">return</span> <span class="n">rc</span>
<a name="MQTTV311.py-pyg.html-344"></a>
<a name="MQTTV311.py-pyg.html-345"></a>
<a name="MQTTV311.py-pyg.html-346"></a><span class="k">class</span> <span class="nc">Connacks</span><span class="p">(</span><span class="n">Packets</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-347"></a>
<a name="MQTTV311.py-pyg.html-348"></a> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">DUP</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">QoS</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">Retain</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">ReturnCode</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-349"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">=</span> <span class="n">FixedHeaders</span><span class="p">(</span><span class="n">CONNACK</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-350"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="n">DUP</span>
<a name="MQTTV311.py-pyg.html-351"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="n">QoS</span>
<a name="MQTTV311.py-pyg.html-352"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">Retain</span> <span class="o">=</span> <span class="n">Retain</span>
<a name="MQTTV311.py-pyg.html-353"></a> <span class="bp">self</span><span class="o">.</span><span class="n">returnCode</span> <span class="o">=</span> <span class="n">ReturnCode</span>
<a name="MQTTV311.py-pyg.html-354"></a> <span class="k">if</span> <span class="nb">buffer</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-355"></a> <span class="bp">self</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-356"></a>
<a name="MQTTV311.py-pyg.html-357"></a> <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-358"></a> <span class="nb">buffer</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">returnCode</span><span class="p">])</span>
<a name="MQTTV311.py-pyg.html-359"></a> <span class="nb">buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">))</span> <span class="o">+</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-360"></a> <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-361"></a>
<a name="MQTTV311.py-pyg.html-362"></a> <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-363"></a> <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">4</span>
<a name="MQTTV311.py-pyg.html-364"></a> <span class="k">assert</span> <span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">==</span> <span class="n">CONNACK</span>
<a name="MQTTV311.py-pyg.html-365"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-366"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span> <span class="o">==</span> <span class="mi">2</span><span class="p">,</span> <span class="s">&quot;Connack packet is wrong length </span><span class="si">%d</span><span class="s">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-367"></a> <span class="k">assert</span> <span class="nb">buffer</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;Reserved byte&quot;</span>
<a name="MQTTV311.py-pyg.html-368"></a> <span class="bp">self</span><span class="o">.</span><span class="n">returnCode</span> <span class="o">=</span> <span class="nb">buffer</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-369"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-370"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-371"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-372"></a>
<a name="MQTTV311.py-pyg.html-373"></a> <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-374"></a> <span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, ReturnCode=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">returnCode</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;)&quot;</span>
<a name="MQTTV311.py-pyg.html-375"></a>
<a name="MQTTV311.py-pyg.html-376"></a> <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-377"></a> <span class="k">return</span> <span class="n">Packets</span><span class="o">.</span><span class="n">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">)</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-378"></a> <span class="bp">self</span><span class="o">.</span><span class="n">returnCode</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">returnCode</span>
<a name="MQTTV311.py-pyg.html-379"></a>
<a name="MQTTV311.py-pyg.html-380"></a>
<a name="MQTTV311.py-pyg.html-381"></a><span class="k">class</span> <span class="nc">Disconnects</span><span class="p">(</span><span class="n">Packets</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-382"></a>
<a name="MQTTV311.py-pyg.html-383"></a> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">DUP</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">QoS</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">Retain</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-384"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">=</span> <span class="n">FixedHeaders</span><span class="p">(</span><span class="n">DISCONNECT</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-385"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="n">DUP</span>
<a name="MQTTV311.py-pyg.html-386"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="n">QoS</span>
<a name="MQTTV311.py-pyg.html-387"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">Retain</span> <span class="o">=</span> <span class="n">Retain</span>
<a name="MQTTV311.py-pyg.html-388"></a> <span class="k">if</span> <span class="nb">buffer</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-389"></a> <span class="bp">self</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-390"></a>
<a name="MQTTV311.py-pyg.html-391"></a> <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-392"></a> <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-393"></a> <span class="k">assert</span> <span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">==</span> <span class="n">DISCONNECT</span>
<a name="MQTTV311.py-pyg.html-394"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-395"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;Disconnect packet is wrong length </span><span class="si">%d</span><span class="s">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-396"></a> <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-3.14.1-1] disconnect reserved bits must be 0&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-397"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-398"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-399"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-400"></a>
<a name="MQTTV311.py-pyg.html-401"></a> <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-402"></a> <span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;)&quot;</span>
<a name="MQTTV311.py-pyg.html-403"></a>
<a name="MQTTV311.py-pyg.html-404"></a>
<a name="MQTTV311.py-pyg.html-405"></a><span class="k">class</span> <span class="nc">Publishes</span><span class="p">(</span><span class="n">Packets</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-406"></a>
<a name="MQTTV311.py-pyg.html-407"></a> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">DUP</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">QoS</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">Retain</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">MsgId</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">TopicName</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">Payload</span><span class="o">=</span><span class="n">b</span><span class="s">&quot;&quot;</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-408"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">=</span> <span class="n">FixedHeaders</span><span class="p">(</span><span class="n">PUBLISH</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-409"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="n">DUP</span>
<a name="MQTTV311.py-pyg.html-410"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="n">QoS</span>
<a name="MQTTV311.py-pyg.html-411"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">Retain</span> <span class="o">=</span> <span class="n">Retain</span>
<a name="MQTTV311.py-pyg.html-412"></a> <span class="c"># variable header</span>
<a name="MQTTV311.py-pyg.html-413"></a> <span class="bp">self</span><span class="o">.</span><span class="n">topicName</span> <span class="o">=</span> <span class="n">TopicName</span>
<a name="MQTTV311.py-pyg.html-414"></a> <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">MsgId</span>
<a name="MQTTV311.py-pyg.html-415"></a> <span class="c"># payload</span>
<a name="MQTTV311.py-pyg.html-416"></a> <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">Payload</span>
<a name="MQTTV311.py-pyg.html-417"></a> <span class="k">if</span> <span class="nb">buffer</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-418"></a> <span class="bp">self</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-419"></a>
<a name="MQTTV311.py-pyg.html-420"></a> <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-421"></a> <span class="nb">buffer</span> <span class="o">=</span> <span class="n">writeUTF</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">topicName</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-422"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-423"></a> <span class="nb">buffer</span> <span class="o">+=</span> <span class="n">writeInt16</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-424"></a> <span class="nb">buffer</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span>
<a name="MQTTV311.py-pyg.html-425"></a> <span class="nb">buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">))</span> <span class="o">+</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-426"></a> <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-427"></a>
<a name="MQTTV311.py-pyg.html-428"></a> <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-429"></a> <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-430"></a> <span class="k">assert</span> <span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">==</span> <span class="n">PUBLISH</span>
<a name="MQTTV311.py-pyg.html-431"></a> <span class="n">fhlen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-432"></a> <span class="n">packlen</span> <span class="o">=</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-433"></a> <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">packlen</span>
<a name="MQTTV311.py-pyg.html-434"></a> <span class="n">curlen</span> <span class="o">=</span> <span class="n">fhlen</span>
<a name="MQTTV311.py-pyg.html-435"></a> <span class="k">try</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-436"></a> <span class="bp">self</span><span class="o">.</span><span class="n">topicName</span> <span class="o">=</span> <span class="n">readUTF</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">fhlen</span><span class="p">:],</span> <span class="n">packlen</span> <span class="o">-</span> <span class="n">curlen</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-437"></a> <span class="k">except</span> <span class="ne">UnicodeDecodeError</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-438"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-3.3.2-1] topic name in publish must be utf-8&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-439"></a> <span class="k">raise</span>
<a name="MQTTV311.py-pyg.html-440"></a> <span class="n">curlen</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">topicName</span><span class="p">)</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-441"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-442"></a> <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">readInt16</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">:])</span>
<a name="MQTTV311.py-pyg.html-443"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-2.3.1-1] packet indentifier must be in publish if QoS is 1 or 2&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-444"></a> <span class="n">curlen</span> <span class="o">+=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-445"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.3.1-1] packet indentifier must be &gt; 0&quot;</span>
<a name="MQTTV311.py-pyg.html-446"></a> <span class="k">else</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-447"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-2.3.1-5] no packet indentifier in publish if QoS is 0&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-448"></a> <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-449"></a> <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">:</span><span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-450"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-451"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-4]&quot;</span>
<a name="MQTTV311.py-pyg.html-452"></a> <span class="k">return</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-453"></a>
<a name="MQTTV311.py-pyg.html-454"></a> <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-455"></a> <span class="n">rc</span> <span class="o">=</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-456"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-457"></a> <span class="n">rc</span> <span class="o">+=</span> <span class="s">&quot;, MsgId=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-458"></a> <span class="n">rc</span> <span class="o">+=</span> <span class="s">&quot;, TopicName=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">topicName</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, Payload=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;)&quot;</span>
<a name="MQTTV311.py-pyg.html-459"></a> <span class="k">return</span> <span class="n">rc</span>
<a name="MQTTV311.py-pyg.html-460"></a>
<a name="MQTTV311.py-pyg.html-461"></a> <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-462"></a> <span class="n">rc</span> <span class="o">=</span> <span class="n">Packets</span><span class="o">.</span><span class="n">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">)</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-463"></a> <span class="bp">self</span><span class="o">.</span><span class="n">topicName</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">topicName</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-464"></a> <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">data</span>
<a name="MQTTV311.py-pyg.html-465"></a> <span class="k">if</span> <span class="n">rc</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-466"></a> <span class="n">rc</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">messageIdentifier</span>
<a name="MQTTV311.py-pyg.html-467"></a> <span class="k">return</span> <span class="n">rc</span>
<a name="MQTTV311.py-pyg.html-468"></a>
<a name="MQTTV311.py-pyg.html-469"></a>
<a name="MQTTV311.py-pyg.html-470"></a><span class="k">class</span> <span class="nc">Pubacks</span><span class="p">(</span><span class="n">Packets</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-471"></a>
<a name="MQTTV311.py-pyg.html-472"></a> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">DUP</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">QoS</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">Retain</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">MsgId</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-473"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">=</span> <span class="n">FixedHeaders</span><span class="p">(</span><span class="n">PUBACK</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-474"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="n">DUP</span>
<a name="MQTTV311.py-pyg.html-475"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="n">QoS</span>
<a name="MQTTV311.py-pyg.html-476"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">Retain</span> <span class="o">=</span> <span class="n">Retain</span>
<a name="MQTTV311.py-pyg.html-477"></a> <span class="c"># variable header</span>
<a name="MQTTV311.py-pyg.html-478"></a> <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">MsgId</span>
<a name="MQTTV311.py-pyg.html-479"></a> <span class="k">if</span> <span class="nb">buffer</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-480"></a> <span class="bp">self</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-481"></a>
<a name="MQTTV311.py-pyg.html-482"></a> <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-483"></a> <span class="nb">buffer</span> <span class="o">=</span> <span class="n">writeInt16</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-484"></a> <span class="nb">buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">))</span> <span class="o">+</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-485"></a> <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-486"></a>
<a name="MQTTV311.py-pyg.html-487"></a> <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-488"></a> <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-489"></a> <span class="k">assert</span> <span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">==</span> <span class="n">PUBACK</span>
<a name="MQTTV311.py-pyg.html-490"></a> <span class="n">fhlen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-491"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span> <span class="o">==</span> <span class="mi">2</span><span class="p">,</span> <span class="s">&quot;Puback packet is wrong length </span><span class="si">%d</span><span class="s">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-492"></a> <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-493"></a> <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">readInt16</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">fhlen</span><span class="p">:])</span>
<a name="MQTTV311.py-pyg.html-494"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-495"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-496"></a> <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-497"></a> <span class="k">return</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-498"></a>
<a name="MQTTV311.py-pyg.html-499"></a> <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-500"></a> <span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, MsgId &quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-501"></a>
<a name="MQTTV311.py-pyg.html-502"></a> <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-503"></a> <span class="k">return</span> <span class="n">Packets</span><span class="o">.</span><span class="n">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">)</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-504"></a> <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">messageIdentifier</span>
<a name="MQTTV311.py-pyg.html-505"></a>
<a name="MQTTV311.py-pyg.html-506"></a>
<a name="MQTTV311.py-pyg.html-507"></a><span class="k">class</span> <span class="nc">Pubrecs</span><span class="p">(</span><span class="n">Packets</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-508"></a>
<a name="MQTTV311.py-pyg.html-509"></a> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">DUP</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">QoS</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">Retain</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">MsgId</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-510"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">=</span> <span class="n">FixedHeaders</span><span class="p">(</span><span class="n">PUBREC</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-511"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="n">DUP</span>
<a name="MQTTV311.py-pyg.html-512"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="n">QoS</span>
<a name="MQTTV311.py-pyg.html-513"></a> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">Retain</span> <span class="o">=</span> <span class="n">Retain</span>
<a name="MQTTV311.py-pyg.html-514"></a> <span class="c"># variable header</span>
<a name="MQTTV311.py-pyg.html-515"></a> <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">MsgId</span>
<a name="MQTTV311.py-pyg.html-516"></a> <span class="k">if</span> <span class="nb">buffer</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-517"></a> <span class="bp">self</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-518"></a>
<a name="MQTTV311.py-pyg.html-519"></a> <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-520"></a> <span class="nb">buffer</span> <span class="o">