<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Protocol Design on Michael-F-Bryan</title><link>https://adventures.michaelfbryan.com/tags/protocol-design/</link><description>Recent content in Protocol Design on Michael-F-Bryan</description><generator>Hugo</generator><language>en</language><lastBuildDate>Wed, 26 Aug 2026 15:15:33 +0800</lastBuildDate><atom:link href="https://adventures.michaelfbryan.com/tags/protocol-design/index.xml" rel="self" type="application/rss+xml"/><item><title>Wiring Up Communication</title><link>https://adventures.michaelfbryan.com/posts/wiring-up-communication/</link><pubDate>Thu, 10 Oct 2019 22:58:00 +0800</pubDate><guid>https://adventures.michaelfbryan.com/posts/wiring-up-communication/</guid><description>&lt;p&gt;As we mentioned &lt;a href="https://adventures.michaelfbryan.com/posts/a-better-frontend/#the-next-step"&gt;in the last AiMC post&lt;/a&gt;&#10;, the next task is to wire up&#10;communications between the simulator&amp;rsquo;s backend and frontend.&lt;/p&gt;&#10;&lt;p&gt;As a general rule, our frontend will have two communication regimes:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;When something happens (e.g. a button is pressed or a job starts sending),&#10;the frontend will send a batch of messages to the backend and interpret the&#10;response&lt;/li&gt;&#10;&lt;li&gt;The frontend will continually poll the backend&amp;rsquo;s state in the background&#10;(e.g. at 10Hz)&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;As it is, the &lt;code&gt;Browser&lt;/code&gt; in our WASM code already provides a method for&#10;sending data to the frontend (&lt;a href="https://michael-f-bryan.github.io/adventures-in-motion-control/aimc_sim/struct.Browser.html#method.send_data" class="external-link" target="_blank" rel="noopener"&gt;&lt;code&gt;Browser::send_data()&lt;/code&gt;&lt;/a&gt;&#10;) and&#10;receiving data from the frontend (&lt;a href="https://michael-f-bryan.github.io/adventures-in-motion-control/aimc_sim/struct.App.html#method.on_data_received" class="external-link" target="_blank" rel="noopener"&gt;&lt;code&gt;App::on_data_received()&lt;/code&gt;&lt;/a&gt;&#10;) so&#10;we shouldn&amp;rsquo;t need to write any Rust code.&lt;/p&gt;</description></item><item><title>The Communications System: Part 2</title><link>https://adventures.michaelfbryan.com/posts/comms-part-2/</link><pubDate>Sun, 08 Sep 2019 01:20:00 +0800</pubDate><guid>https://adventures.michaelfbryan.com/posts/comms-part-2/</guid><description>&lt;p&gt;Now we have a mechanism for transferring bytes from the frontend to the&#10;simulator and back again, we need to translate those bytes into higher-level&#10;messages. Luckily each [&lt;code&gt;anpp::Packet&lt;/code&gt;] contains an &lt;a href="https://docs.rs/anpp/1.0.1/anpp/struct.Packet.html#method.id" class="external-link" target="_blank" rel="noopener"&gt;&lt;code&gt;ID&lt;/code&gt; field&lt;/a&gt;&#10; that&#10;is designed specifically for this purpose.&lt;/p&gt;&#10;&lt;p&gt;That lets us do something like this:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// (not real code)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;enum&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Message&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;&amp;#39;a&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Ping,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; StatusCheck,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ProgramChunk {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; chunk_number: &lt;span style="color:#66d9ef"&gt;usize&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; body: &lt;span style="color:#66d9ef"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;&amp;#39;a&lt;/span&gt; [&lt;span style="color:#66d9ef"&gt;u8&lt;/span&gt;],&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;..&lt;/span&gt;.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;UnknownMessageError&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;fn&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;parse_packet&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;&amp;#39;a&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;(pkt: &lt;span style="color:#66d9ef"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;&amp;#39;a&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Packet&lt;/span&gt;) -&amp;gt; Result&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Message&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;&amp;#39;a&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;, UnknownMessageError&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;match&lt;/span&gt; pkt.id() {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; Ok(Message::Ping),&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; Ok(Message::StatusCheck),&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; Ok(&lt;span style="color:#f92672"&gt;..&lt;/span&gt;.),&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; _ &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; Err(UnknownMessageError),&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The top-level &lt;code&gt;App&lt;/code&gt; can handle messages by routing them to the appropriate&#10;system and invoking a message handler.&lt;/p&gt;</description></item><item><title>The Communications System: Part 1</title><link>https://adventures.michaelfbryan.com/posts/comms-part-1/</link><pubDate>Fri, 06 Sep 2019 23:00:00 +0800</pubDate><guid>https://adventures.michaelfbryan.com/posts/comms-part-1/</guid><description>&lt;h2 id="prelude"&gt;&#10; Prelude&#10; &lt;a class="heading-link" href="#prelude"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The &lt;em&gt;Communications&lt;/em&gt; system is arguably one of the most important parts of&#10;our simulator. After all, it&amp;rsquo;s kinda hard to debug a program when you can&amp;rsquo;t&#10;ask it why something isn&amp;rsquo;t working.&lt;/p&gt;&#10;&lt;p&gt;The user will interact with our simulated motion controller via a single&#10;&lt;em&gt;Serial Port&lt;/em&gt;, which we&amp;rsquo;ll be modelling as a simple thing which sends and&#10;receives bytes. Serial ports are a fairly old technology, and have several&#10;drawbacks compared to the Ethernet and TCP protocols that most programmers&#10;are familiar with.&lt;/p&gt;</description></item></channel></rss>