<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>software | Craig Hesling</title><link>https://new.craighesling.com/tag/software/</link><atom:link href="https://new.craighesling.com/tag/software/index.xml" rel="self" type="application/rss+xml"/><description>software</description><generator>Wowchemy (https://wowchemy.com)</generator><language>en-us</language><lastBuildDate>Mon, 04 Feb 2019 14:06:12 -0500</lastBuildDate><image><url>https://new.craighesling.com/media/icon_hud2fdbe3c21f96e183bc7961971f91459_788_512x512_fill_lanczos_center_3.png</url><title>software</title><link>https://new.craighesling.com/tag/software/</link></image><item><title>Insecure Temp WiFi Networks</title><link>https://new.craighesling.com/post/insecure-temp-wifi-networks/</link><pubDate>Mon, 04 Feb 2019 14:06:12 -0500</pubDate><guid>https://new.craighesling.com/post/insecure-temp-wifi-networks/</guid><description>&lt;h2 id="introduction-of-problem">Introduction of Problem&lt;/h2>
&lt;p>After traveling to SF and connecting to numerous free WiFi networks, I have
returned back to Pittsburgh and realized that my laptop still likes to connect
to unsecured xfinitywifi over my normal house network.
This would be the same deal if my laptop happen to see another insecure network
named SFO-AIRPORT-FREE-WIFI or the hotel&amp;rsquo;s free WiFi network.&lt;/p>
&lt;p>I understand that I could drop the connection priority of these insecure/free
networks in the network manager, but it still exposes a human centric
security flaw.&lt;/p>
&lt;p>The concern is that, by default, the Gnome network manager places newly connected WiFi network at the top of the preferred networks priority list.
So, if your laptop sees these newly connected networks in the same vicinity as your older home network, they connect to the temporary network instead of your trusted home network.
This wouldn&amp;rsquo;t be a serious issue if it weren&amp;rsquo;t for the fact that these temporary networks do not require any authentication. Anyone can create a network with the same name and no authentication and BOOM, your laptop connects.&lt;/p>
&lt;h2 id="tldr">TL;DR&lt;/h2>
&lt;p>I will just jump right to my point. I feel you should have an easy option to specify an expiration for a WiFi network, on connection.
The purpose would be to make sure your laptop will not connect to it after your trip or outing to Starbucks.&lt;/p>
&lt;p>An even easier half-way solution, would be to automatically drop the priority
of insecure networks to the very lowest.
The hope is that you laptop would always prefer you secure authenticated networks over a rouge insecure network, although I suspect this may not always be the case.&lt;/p>
&lt;h2 id="accidental-experiment">Accidental Experiment&lt;/h2>
&lt;p>I have been more cognizant of this issue ever since my little accidental experiment.&lt;/p>
&lt;p>While on campus, I configured a RaspberryPi to connect to my school&amp;rsquo;s insecure
WiFi network named &lt;code>CMU&lt;/code>. This was happening before the school offered their secure
option called &lt;code>CMU-SECURE&lt;/code>. I was never a fan of lugging around a monitor+keyboard, so I would interact with the Pi over ssh.
I then returned home and realized that I hadn&amp;rsquo;t configured it with my home WiFi network.
At the moment, I really didn&amp;rsquo;t feel like grabbing a monitor+keyboard or ripping out the SD card to write a new network. So, I simply created a guest WiFi network named &lt;code>CMU&lt;/code>, so that it would just connect. The plan was to have it connect and then add my WiFi network to the wpa_supplicant.conf.
It worked perfectly, but one might say that it worked a bit too well.&lt;/p>
&lt;p>I found the RPi&amp;rsquo;s IP in the DHCP Lease log, but I also found tons of other mysterious devices that I hadn&amp;rsquo;t ever seen before. Since I live near many other CMU students, I immediately realized that my neighbors laptops had automatically jumped on my CMU network.&lt;/p>
&lt;p>This obviously exposes an issue, where saved insecure networks can be used to grab traffic from unsuspecting devices. Not good! You might assume you traffic is broadcasted for anyone at Starbucks, but you assume it is safe(er) at your house.&lt;/p>
&lt;p>We can fix this issue.&lt;/p>
&lt;h2 id="call-to-action">Call to action&lt;/h2>
&lt;p>Calling on all Gnome, Windows, Android, and OSX developers.&lt;/p>
&lt;p>Please add an option to make WiFi networks temporary and have expiration dates.
It would be nice to check a box and specify an expiration date during the first
connect stage.&lt;/p>
&lt;p>At the very least, please make insecure networks the automatic lowest priority.
If this already has a solution that I am not aware of, please comment below.&lt;/p></description></item><item><title>Let's Encrypt Root CA Cert</title><link>https://new.craighesling.com/post/lets-encrypt-root-ca/</link><pubDate>Sat, 13 Oct 2018 00:00:00 +0000</pubDate><guid>https://new.craighesling.com/post/lets-encrypt-root-ca/</guid><description>&lt;h2 id="overview--explination">Overview / Explination&lt;/h2>
&lt;p>Since Let&amp;rsquo;s Encrypt&amp;rsquo;s own root certificate authority, &lt;code>ISRG Root X1&lt;/code>, is still quite new and not commonly trusted.
To get around this issue, Let&amp;rsquo;s Encrypt&amp;rsquo;s intermediate has be graciously cross-signed by IdentTrust&amp;rsquo;s root certificate authority &lt;code>DST Root CA X3&lt;/code>, which is commonly trusted by clients.&lt;/p>
&lt;p>What this means is that most certificates issued by Let&amp;rsquo;s Encrypt have an origin of trust from IdentTrust&amp;rsquo;s root CA.&lt;/p>
&lt;p>Take for example the OpenChirp MQTT server. We can use &lt;code>openssl s_client&lt;/code> to inspect the certificate presented to the user.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">openssl s_client -connect mqtt.openchirp.io:8883
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">verify return:1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">depth=1 C = US, O = Let&amp;#39;s Encrypt, CN = Let&amp;#39;s Encrypt Authority X3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">verify return:1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">depth=0 CN = mqtt.openchirp.io
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">verify return:1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">---
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Certificate chain
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 0 s:/CN=mqtt.openchirp.io
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> i:/C=US/O=Let&amp;#39;s Encrypt/CN=Let&amp;#39;s Encrypt Authority X3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 1 s:/C=US/O=Let&amp;#39;s Encrypt/CN=Let&amp;#39;s Encrypt Authority X3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> i:/O=Digital Signature Trust Co./CN=DST Root CA X3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">---
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">...
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The beginning of the output shows the root is &lt;code>CN = DST Root CA X3&lt;/code>, which doesn&amp;rsquo;t look like Let&amp;rsquo;s Encrypt&amp;rsquo;s own &lt;code>ISRG Root X1&lt;/code>.&lt;/p>
&lt;p>So, if you need to present the root CA cert to some program (for verification), you need to present IdentTrust&amp;rsquo;s root CA cert. See the next section to learn how to grab a usable x509 PEM formatted cert.&lt;/p>
&lt;h2 id="grab-cert-and-convert">Grab Cert and Convert&lt;/h2>
&lt;p>If we want to present the trusted root CA cert for a Let&amp;rsquo;s Encrypt issued certificate, we need to present the IdentTrust root CA cert. More specifically, we need to reference the &lt;code>TrustID X3&lt;/code> root cert.
The only problem with this is that IdentTrust only offers their certificate in PKCS7 binary format (&lt;code>.p7b&lt;/code>), which is unusable in a lot of reasonable applications. We need x509 PEM format.&lt;/p>
&lt;p>The following instructions will show how to compose the x509 &lt;code>.pem&lt;/code> file for the &lt;code>DST Root CA X3&lt;/code> cert.&lt;/p>
&lt;h3 id="tldr">TLDR&lt;/h3>
&lt;p>At the time of writing this, the following wget line was capable of grabbing the &lt;code>TrustID X3&lt;/code> cert in p7b format.
The next openssl would convert that &lt;code>.p7b&lt;/code> file to an x509 &lt;code>.pem&lt;/code> file for normal use.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">wget https://www.identrust.com/node/935 -O trustidrootx3_chain.p7b
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">openssl pkcs7 -inform DER -in trustidrootx3_chain.p7b -print_certs -outform PEM -out trustidrootx3_chain.pem
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>You can then use the &lt;code>trustidrootx3_chain.pem&lt;/code> as the CAfile parameter of client programs.&lt;/p>
&lt;h3 id="fallback-instructions">Fallback Instructions&lt;/h3>
&lt;p>If the above commands failed, you can download the PKCS7 binary file (&lt;code>.p7b&lt;/code>) file from the IdentTrust &lt;a href="https://www.identrust.com/support/downloads" target="_blank" rel="noopener">download page&lt;/a> bellow.&lt;/p>
&lt;p>To convert that PKCS7 binary file to x509 PEM, use the following openssl command:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">openssl pkcs7 -inform DER -in &amp;lt;THE_DOWNLOADED_P7B_CERT&amp;gt; -print_certs -outform PEM -out trustidrootx3_chain.pem
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>You can then use the &lt;code>trustidrootx3_chain.pem&lt;/code> as the CAfile parameter of client programs.&lt;/p>
&lt;h2 id="example-usage-of-x509-pem">Example Usage of x509 PEM&lt;/h2>
&lt;h3 id="mosquitto-client">Mosquitto Client&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">mosquitto_sub -v -i monitor&lt;span class="nv">$RANDOM&lt;/span> -h mqtt.openchirp.io -p &lt;span class="m">8883&lt;/span> --cafile ./trustidrootx3_chain.pem -u &amp;lt;USER&amp;gt; -p &amp;lt;TOKEN&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="links">Links&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="https://letsencrypt.org/certificates/" target="_blank" rel="noopener">Let&amp;rsquo;s Encrypt Certificates and Explination&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.identrust.com/support/downloads" target="_blank" rel="noopener">IdentTrust Download&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>SafetyFast</title><link>https://new.craighesling.com/project/safetyfast/</link><pubDate>Sun, 03 Jun 2018 07:46:59 -0500</pubDate><guid>https://new.craighesling.com/project/safetyfast/</guid><description>&lt;p>Put thread-safety first, with the performance of safety last.&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="https://new.craighesling.com/img/SafetyFast_Preview.png" alt="Example SafetyFast Atomic usage" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>This is a Go library that implements synchronization primitives over
&lt;a href="https://en.wikipedia.org/wiki/Transactional_Synchronization_Extensions" target="_blank" rel="noopener">Intel TSX&lt;/a> (Intel&amp;rsquo;s hardware transactional primitives).
The library exposes interfaces to make use of Intel HLE and Intel RTM.&lt;/p>
&lt;h1 id="usage-patterns">Usage Patterns&lt;/h1>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">go get github.com/linux4life798/safetyfast
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="rtm-context">RTM Context&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-go" data-lang="go">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">package&lt;/span> &lt;span class="nx">main&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="s">&amp;#34;github.com/linux4life798/safetyfast&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">func&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">r&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">safetyfast&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">NewRTMContexDefault&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">r&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Atomic&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kd">func&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">btc&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Touch&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">index&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c1">// Any action
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="hle-spin-lock">HLE Spin Lock&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-go" data-lang="go">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">package&lt;/span> &lt;span class="nx">main&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;sync&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;github.com/linux4life798/safetyfast&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">func&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">var&lt;/span> &lt;span class="nx">m&lt;/span> &lt;span class="nx">sync&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Locker&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nb">new&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">safetyfast&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">SpinHLEMutex&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">m&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Lock&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">btc&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Touch&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">index&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c1">// Any action
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">m&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Unlock&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h1 id="poster">Poster&lt;/h1>
&lt;a href="https://craighesling.com/files/SafetyFast_Poster.pdf">Download PDF&lt;/a>
&lt;p>A preview of the PDF should appear below. If it does not show up soon, please refresh the page.&lt;/p>
&lt;iframe src="https://docs.google.com/gview?url=https%3a%2f%2fcraighesling.com%2ffiles%2fSafetyFast_Poster.pdf&amp;embedded=true" style="width:100%; height:600px;" frameborder="0">
This browser does not support PDFs. Please download the PDF to view it: &lt;a href="https://craighesling.com/files/SafetyFast_Poster.pdf">Download PDF&lt;/a>
&lt;/iframe>
&lt;h2 id="links">Links&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://github.com/linux4life798/safetyfast" target="_blank" rel="noopener">SafetyFast on Github&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://en.wikipedia.org/wiki/Transactional_Synchronization_Extensions" target="_blank" rel="noopener">Intel TSX&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>GOBF</title><link>https://new.craighesling.com/post/gobf/</link><pubDate>Fri, 04 May 2018 00:00:00 +0000</pubDate><guid>https://new.craighesling.com/post/gobf/</guid><description>&lt;h2 id="intro">Intro&lt;/h2>
&lt;p>I have always been fascinated by compilers.
I think the idea of representing one language&amp;rsquo;s structure inside
of another language is just downright cool.
Furthermore, the ability to analyze another language and optimize it really peaks my interest.&lt;/p>
&lt;p>Recently, I worked on a project that would allow you to more precisely manage
which processor core a set of Goroutines would run on.
The idea was that Goroutines that communicate more than they process independently
would benefit from sharing that same processor core&amp;rsquo;s cache. I called them
M-Groups. The implementation called for modifying the &lt;code>runtime&lt;/code> package
and the Go scheduler.
While ripping through the Go internals, I stumbled upon quite a bit of the Go
compiler code, including the SSA library. As I ripped into it more,
I started to form an itch to make my own compiler of some kind.&lt;/p>
&lt;p>Fast forward a few months and I found myself staring at some examples of
my favorite simple esoteric language, &lt;a href="https://en.wikipedia.org/wiki/Brainfuck" target="_blank" rel="noopener">BF&lt;/a>.
BF is the perfect language to write a compiler / optimizer for because of its
extremely minimal syntax.
It only has 8 possible syntax items(called commands), &lt;code>&amp;lt;&amp;gt;+-.,[]&lt;/code>, but
those simple syntax items quickly form complex programs
(not in the sense of awesome functionality).&lt;/p>
&lt;p>Here is Hello World in BF&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-brainfuck" data-lang="brainfuck">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">++++++++&lt;/span>&lt;span class="k">[&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">++++&lt;/span>&lt;span class="k">[&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">++&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">+++&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">+++&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">+&lt;/span>&lt;span class="nv">&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/span>&lt;span class="nb">-&lt;/span>&lt;span class="k">]&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">+&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">+&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">-&lt;/span>&lt;span class="nv">&amp;gt;&amp;gt;&lt;/span>&lt;span class="nb">+&lt;/span>&lt;span class="k">[&lt;/span>&lt;span class="nv">&amp;lt;&lt;/span>&lt;span class="k">]&lt;/span>&lt;span class="nv">&amp;lt;&lt;/span>&lt;span class="nb">-&lt;/span>&lt;span class="k">]&lt;/span>&lt;span class="nv">&amp;gt;&amp;gt;&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">---&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nb">+++++++&lt;/span>&lt;span class="nt">..&lt;/span>&lt;span class="nb">+++&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nv">&amp;gt;&amp;gt;&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nv">&amp;lt;&lt;/span>&lt;span class="nb">-&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nv">&amp;lt;&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nb">+++&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nb">------&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nb">--------&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nv">&amp;gt;&amp;gt;&lt;/span>&lt;span class="nb">+&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">++&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="c">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="gobf-overview">GOBF Overview&lt;/h2>
&lt;p>Introducing GOBF, an interpreter/optimizer/compiler/code_generator for the BF language.
It has two primary modes of operation, interpreting/running (as-is) and
converting BF to optimized Go code.&lt;/p>
&lt;h3 id="interpreting">Interpreting&lt;/h3>
&lt;p>Interpreting and running was the first mode of operation that really just
served to solidify my understanding of the BF language.
It simply sets up a virtual environment for the BF program and acts on each
syntax item as they come. There is no optimization here.&lt;/p>
&lt;h3 id="optimizing--compiling">Optimizing / Compiling&lt;/h3>
&lt;p>Next, I wanted to focus on how I would be able to generate super fast
binaries from my BF programs.
I considered lots of approaches, but the two most prominent ones were to
directly assemble a binary from the BF commands and convert BF to equivalent Go code.&lt;/p>
&lt;p>Directly assemble an x86 binary from the the BF commands seems like a natural
extension, since BF forces the programmer to act somewhat like a state machine.
The downside to this approach is that it would lack portability and would loose
out on further architectural optimizations that are found in modern compilers.&lt;/p>
&lt;p>I ultimately chose the ladder solution, where I convert the BF commands into
equivalent Go code.
Although it seems like a bulky implementation strategy, the program&amp;rsquo;s
functionality is quite limited and we gain the builtin compiler inlining.&lt;/p>
&lt;p>I have designed GOBF to parse BF programs and generate a internal
intermediate representation(IR) that resembles a tree.
The next major observation that BF contains lots of repetitive actions,
like &lt;code>++++++++&lt;/code>, which increments the local accumulator eight times, only to
save the value &lt;code>8&lt;/code>.
These repetitive actions can easily be smashed into a single operation, which
can yield massive speedups.
The GOBF optimizer traverses the IR tree and coalesces these
repetitive actions into a more descriptive single action.&lt;/p>
&lt;p>When the optimizer finishes, GOBF generates Go code from the IR
and optionally compiles it.&lt;/p>
&lt;h2 id="benchmarking">Benchmarking&lt;/h2>
&lt;p>I ran some of the typical BF programs you can find on the internet.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>BF Program&lt;/th>
&lt;th>Run Time&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>mandelbrot.b&lt;/td>
&lt;td>8.162s&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>hanoi.b&lt;/td>
&lt;td>5.401s&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>helloworld.b&lt;/td>
&lt;td>0.003s&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;div class="alert alert-note">
&lt;div>
Running on an Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
&lt;/div>
&lt;/div>
&lt;h2 id="future-work">Future Work&lt;/h2>
&lt;p>I would like to create a reverse code generator that takes a high-level
language, such as Go, and generates BF.&lt;/p>
&lt;h3 id="links">Links&lt;/h3>
&lt;p>&lt;a href="https://github.com/linux4life798/gobf" target="_blank" rel="noopener">GOBF on Github&lt;/a>&lt;/p></description></item><item><title>Web Development</title><link>https://new.craighesling.com/post/webdev/</link><pubDate>Wed, 13 Dec 2017 01:53:28 -0500</pubDate><guid>https://new.craighesling.com/post/webdev/</guid><description>&lt;p>I&amp;rsquo;m really starting to get the hang of this web development thing.
First Angular 1, then Angular 5, and now Hugo.&lt;/p></description></item><item><title>dproto</title><link>https://new.craighesling.com/project/dproto/</link><pubDate>Sun, 03 Dec 2017 07:46:59 -0500</pubDate><guid>https://new.craighesling.com/project/dproto/</guid><description>&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="https://new.craighesling.com/img/dproto_initialization.jpg" alt="Basic dproto usage" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>An on the fly Google protobuf decoder/encoder library.&lt;/p>
&lt;h2 id="summary">Summary&lt;/h2>
&lt;p>This library allows you to use Protobufs (Google Protocol Buffers) without needing to
generate protobuf code and compile it into your project.
This means you don&amp;rsquo;t need to compile .proto files.&lt;/p>
&lt;p>This library is designed for marshaling and unmarshalling protobufs in a &lt;em>dynamic&lt;/em> way.
It is designed to interface with any standard protobuf library and is tested against
the official protobuf C++ and Golang bindings, in addition to the C
&lt;a href="https://github.com/nanopb/nanopb" target="_blank" rel="noopener">Nanopdb&lt;/a> library.&lt;/p>
&lt;p>The intent of this library was to allow creating long running services that can
interpret and interface with clients using new/unknown protobuf messages.&lt;/p>
&lt;p>The basic idea is that you construct a &lt;code>ProtoFieldMap&lt;/code> that contains any protobuf
field number to protobuf type associations you are interested in and then you
call &lt;code>DecodeBUffer&lt;/code> on the protobuf payload.
&lt;code>DecodeBuffer&lt;/code> returns an array of &lt;code>FieldValue&lt;/code>s that it decoded from the payload.
Each &lt;code>FieldValue&lt;/code> specifies the protobuf field number and value decoded as a Golang
primitive(must be inside a &lt;code>interface{}&lt;/code>).&lt;/p>
&lt;h2 id="example-usage">Example Usage&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-go" data-lang="go">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Encodes and Decodes a protobuf buffer that would interface with
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// a .proto file message containing &amp;#34;bool status =1;&amp;#34; and
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// &amp;#34;int64 intensity = 2;&amp;#34;.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kd">func&lt;/span> &lt;span class="nf">ExampleNewProtoFieldMap&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Setup the ProtoFieldMap to interface with the
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// following .proto file:
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// message LightStatus {
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// bool status = 1;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// int64 intensity = 2;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// }
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Setup a FieldMap that holds the type-fieldnumber association
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// This is effectively the information held in a .proto file
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">fm&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">dproto&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">NewProtoFieldMap&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Add Protobuf bool as field 1 (&amp;#34;bool status = 1;&amp;#34;)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">!&lt;/span>&lt;span class="nx">fm&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">descriptor&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">FieldDescriptorProto_TYPE_BOOL&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">panic&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Failed to add bool field 1&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Add Protobuf int64 as field 2 (&amp;#34;int64 intensity = 2;&amp;#34;)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">!&lt;/span>&lt;span class="nx">fm&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">descriptor&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">FieldDescriptorProto_TYPE_INT64&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">panic&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Failed to add bool field 1&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Provide some values for our &amp;#34;status&amp;#34; and &amp;#34;intensity&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">values&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="p">[]&lt;/span>&lt;span class="nx">dproto&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">FieldValue&lt;/span>&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">dproto&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">FieldValue&lt;/span>&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Field&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// status field number
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">Value&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">bool&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">dproto&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">FieldValue&lt;/span>&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Field&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// intensity field number
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">Value&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">int64&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Encode out values into the protobuf message described in fm
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">bytes&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">fm&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">EncodeBuffer&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">values&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="kc">nil&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">panic&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Error Encoding: &amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">err&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Error&lt;/span>&lt;span class="p">())&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">fmt&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Printf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;ProtobufBinary: [ %# x ]\n&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">bytes&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Decode all protobuf fields
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">decodedValues&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">fm&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">DecodeBuffer&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">bytes&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="kc">nil&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">panic&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Error Decoding: &amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">err&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Error&lt;/span>&lt;span class="p">())&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="nx">_&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">val&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="k">range&lt;/span> &lt;span class="nx">decodedValues&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">fmt&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Printf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;%v: %v\n&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">val&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Field&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">val&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Value&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Unordered output:
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// ProtobufBinary: [ 0x08 0x01 0x10 0x0a ]
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// 1: true
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// 2: 10
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="links">Links&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://github.com/linux4life798/dproto" target="_blank" rel="noopener">Dproto on Github&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://developers.google.com/protocol-buffers/" target="_blank" rel="noopener">Google Protobufs&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Easybits Serialization Service</title><link>https://new.craighesling.com/project/easybits/</link><pubDate>Sun, 03 Dec 2017 07:46:59 -0500</pubDate><guid>https://new.craighesling.com/project/easybits/</guid><description>&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="https://new.craighesling.com/img/easybits_config_example3.png" alt="Example Easybits device configuration" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;h2 id="summary">Summary&lt;/h2>
&lt;p>Easybits is an on-the-fly Google protobuf stream decoder/encoder for
&lt;a href="https://new.craighesling.com/project/openchirp/">OpenChirp&lt;/a>.
This service is one of the core services that an embedded device may
need in it&amp;rsquo;s OpenChirp data pipeline.&lt;/p>
&lt;p>The idea is that your device would use Google Protobufs to serialize
(and deserialize) it&amp;rsquo;s data and sends it to OpenChirp.
The Easybits service is then invoked, which deserializes your data and
publishes human readable values back to OpenChirp.&lt;/p>
&lt;p>Easybits just needs the user to describe what protobuf types were declared
and where to place the data.&lt;/p>
&lt;h2 id="how-it-works">How it works&lt;/h2>
&lt;p>Google Protobufs are great for creating compact serialized data packets for
typical sensor values.&lt;/p>
&lt;p>Protobufs requires you to create a &lt;code>.proto&lt;/code> file that
describes what data you intend to send back and forth. It then compiles this
&lt;code>.proto&lt;/code> file into a set of language specific interface files, which
containing functions and objects to represent and aggregate your data.&lt;/p>
&lt;blockquote>
&lt;p>Here is an example &lt;code>.proto&lt;/code> file description for a smart light bulb.&lt;/p>
&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-protobuf" data-lang="protobuf">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// SmartBulb.proto
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">syntax&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s">&amp;#34;proto3&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="kd">message&lt;/span> &lt;span class="nc">LightStatus&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="kt">bool&lt;/span> &lt;span class="n">status&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="kt">int64&lt;/span> &lt;span class="n">intensity&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Due to this native language integration, protobufs are easy for end users to
pack up and send data messages, but it is non-trivial to create long running
services that can interpret all possible custom protobuf messages, without
recompilation.&lt;/p>
&lt;p>To get around the Protobuf constraint of recompiling for every new protobuf
message, Easybits uses &lt;a href="https://new.craighesling.com/project/dproto/">dproto&lt;/a> to adapt to new user
described messages, without even restarting.&lt;/p>
&lt;h2 id="links">Links&lt;/h2>
&lt;p>&lt;a href="https://github.com/OpenChirp/easybits-service" target="_blank" rel="noopener">Easybits on Github&lt;/a>&lt;/p></description></item><item><title>OpenChirp</title><link>https://new.craighesling.com/project/openchirp/</link><pubDate>Sun, 03 Dec 2017 07:46:59 -0500</pubDate><guid>https://new.craighesling.com/project/openchirp/</guid><description>
&lt;div class="gallery">
&lt;a data-fancybox="gallery-main" data-caption="Gateway 1" href="https://new.craighesling.com/project/openchirp/GSIA_GW_hu8af566d35e172a1448aad7b439b9ad98_1089158_1920x0_resize_q75_lanczos.jpg">
&lt;img alt="GSIA_GW.jpg" src="https://new.craighesling.com/project/openchirp/GSIA_GW_hu8af566d35e172a1448aad7b439b9ad98_1089158_1920x0_resize_q15_lanczos.jpg">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="OpenChirp Logo" href="https://new.craighesling.com/project/openchirp/OCStickerDark.svg">
&lt;img alt="OCStickerDark.svg" src="https://new.craighesling.com/project/openchirp/OCStickerDark.svg">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="A gateway up-close" href="https://new.craighesling.com/project/openchirp/OnGround_Wean_GW_hu2ae3da5a428bf1047e2250f9a743cb87_3037040_3024x0_resize_q75_lanczos.jpg">
&lt;img alt="OnGround_Wean_GW.jpg" src="https://new.craighesling.com/project/openchirp/OnGround_Wean_GW_hu2ae3da5a428bf1047e2250f9a743cb87_3037040_3024x0_resize_q15_lanczos.jpg">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="Gateway 2" href="https://new.craighesling.com/project/openchirp/SouthCraig_GW_hu3c1fbb5776c28c3856df7474a5b76c50_1314334_3120x0_resize_q75_lanczos.jpg">
&lt;img alt="SouthCraig_GW.jpg" src="https://new.craighesling.com/project/openchirp/SouthCraig_GW_hu3c1fbb5776c28c3856df7474a5b76c50_1314334_3120x0_resize_q15_lanczos.jpg">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="Gateway 3" href="https://new.craighesling.com/project/openchirp/Wean_GW_hu9b7bdac86ca23d1aa5a7028c80665157_715377_3120x0_resize_q75_lanczos.jpg">
&lt;img alt="Wean_GW.jpg" src="https://new.craighesling.com/project/openchirp/Wean_GW_hu9b7bdac86ca23d1aa5a7028c80665157_715377_3120x0_resize_q15_lanczos.jpg">
&lt;/a>
&lt;/div>
&lt;h2 id="summary">Summary&lt;/h2>
&lt;p>We are creating a community-driven low-power wireless connectivity solution for
IoT.&lt;/p>
&lt;h2 id="my-contributions">My Contributions&lt;/h2>
&lt;ul>
&lt;li>Designed, built, and installed outdoor gateways&lt;/li>
&lt;li>Created custom Debian packages for gateway software and configuration - &lt;a href="https://github.com/OpenChirp/ocgw" target="_blank" rel="noopener">ocgw&lt;/a>&lt;/li>
&lt;li>Created gateway system monitoring service - &lt;a href="https://github.com/OpenChirp/sysmonitor-device" target="_blank" rel="noopener">SysMonitor Device&lt;/a>&lt;/li>
&lt;li>Created the Golang framework for Users, Devices, and Services - &lt;a href="https://github.com/OpenChirp/framework" target="_blank" rel="noopener">framework&lt;/a> and &lt;a href="https://github.com/OpenChirp/example-service" target="_blank" rel="noopener">Example Service&lt;/a>&lt;/li>
&lt;li>Created the LoRaWAN integration service&lt;/li>
&lt;li>Created data serialization/deserialization services - &lt;a href="https://github.com/OpenChirp/bytetranslator-service" target="_blank" rel="noopener">ByteTranslator Service&lt;/a> and &lt;a href="https://new.craighesling.com/project/easybits">Easybits Service&lt;/a>&lt;/li>
&lt;li>Created prototype trigger service - &lt;a href="https://github.com/OpenChirp/trigger-service" target="_blank" rel="noopener">Trigger Service&lt;/a>&lt;/li>
&lt;li>Designed and built ultra low-power LoRaWAN client devices - &lt;a href="https://new.craighesling.com/project/lorabug">The LoRaBug&lt;/a>&lt;/li>
&lt;li>Created the hardware abstraction layer and adapted the necessary firmware stacks for the LoRaBug - &lt;a href="https://new.craighesling.com/project/lorabug/#software">LoRaBug Software&lt;/a>&lt;/li>
&lt;li>Created serial bootloader tool to flash the LoRaBug over micro USB - &lt;a href="https://new.craighesling.com/post/cc2538-cc26xx-bootloader/">ccbootutil&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>Checkout the &lt;a href="http://OpenChirp.io" target="_blank" rel="noopener">OpenChirp.io Website&lt;/a>&lt;/p></description></item><item><title>System Monitor Device (for OpenChirp)</title><link>https://new.craighesling.com/post/sysmonitor-device/</link><pubDate>Mon, 06 Nov 2017 00:00:00 +0000</pubDate><guid>https://new.craighesling.com/post/sysmonitor-device/</guid><description>&lt;h2 id="summary">Summary&lt;/h2>
&lt;h2 id="how-it-works">How it works&lt;/h2>
&lt;h2 id="links">Links&lt;/h2>
&lt;p>&lt;a href="https://github.com/OpenChirp/sysmonitor-device" target="_blank" rel="noopener">sysmonitor-device on Github&lt;/a>&lt;/p></description></item><item><title>TI CC2538/CC26xx Serial Bootloader Utility on Linux</title><link>https://new.craighesling.com/post/cc2538-cc26xx-bootloader/</link><pubDate>Tue, 11 Apr 2017 11:30:41 -0500</pubDate><guid>https://new.craighesling.com/post/cc2538-cc26xx-bootloader/</guid><description>&lt;p>If you have ever been curious about using the TI CC2650 and other similar SimpleLink devices&amp;rsquo; serial bootloader, wonder no longer.&lt;/p>
&lt;p>I recently implemented the TI CC2538/CC26xx Serial Bootloader protocol in a Go library, called &lt;a href="https://github.com/OpenChirp/ccboot" target="_blank" rel="noopener">ccboot&lt;/a>.
This simply uses standard IO operations that can be used with a generic serial library.&lt;/p>
&lt;p>Since a library is no fun without a command line interface, I have also implemented &lt;a href="https://github.com/OpenChirp/ccbootutil" target="_blank" rel="noopener">ccbootutil&lt;/a>, which exposes most of the low level bootloader primitives(which can be shell scripted) and has a complete program sequence that reads ELF binaries, flashes, and resets the chip. You simply run the following command and ccbootutil did the rest:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">cbootutil /dev/ttyUSB0 prgm YourCompiledProgramInStandardELFFormat.out
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>When implementing ccbootutil, I used a Go serial port interface library that indicated that it should work cross platform, so Windows and OSX users should not feel left out of the command line and scriptable goodness.&lt;/p>
&lt;p>I have compiled the utility for each of the platforms in the repository &lt;a href="https://github.com/OpenChirp/ccbootutil/tree/master/builds" target="_blank" rel="noopener">builds/&lt;/a> directory.&lt;/p>
&lt;h2 id="notes">Notes&lt;/h2>
&lt;ul>
&lt;li>I have found that the serial bootloader can flash the CC2650 faster than an XDS110 over cJTAG.&lt;/li>
&lt;li>TI Smart RF Flash Programmer 2 certainly works, but is strictly for Windows and is not scriptable.&lt;/li>
&lt;/ul>
&lt;h2 id="links">Links&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://github.com/OpenChirp/ccbootutil" target="_blank" rel="noopener">https://github.com/OpenChirp/ccbootutil&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/OpenChirp/ccboot" target="_blank" rel="noopener">https://github.com/OpenChirp/ccboot&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>Please let me know if you find any issues. Happy coding!&lt;/p></description></item><item><title>The LoRaBug</title><link>https://new.craighesling.com/project/lorabug/</link><pubDate>Sat, 03 Dec 2016 07:46:59 -0500</pubDate><guid>https://new.craighesling.com/project/lorabug/</guid><description>
&lt;div class="gallery">
&lt;a data-fancybox="gallery-main" data-caption="Fully built LoRaBugs with the environmental sensor board v1" href="https://new.craighesling.com/project/lorabug/Fully_Enclosed_hue365703db40798d641f7c145346ab307_1531989_4160x0_resize_q75_lanczos.jpg">
&lt;img alt="Fully_Enclosed.jpg" src="https://new.craighesling.com/project/lorabug/Fully_Enclosed_hue365703db40798d641f7c145346ab307_1531989_4160x0_resize_q15_lanczos.jpg">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="Altium 3D rendering" href="https://new.craighesling.com/project/lorabug/LoRaBugBoardV3.1_3D_hu78434072f4b03f97a69451697241d2b9_446129_1030x0_resize_q75_lanczos_3.png">
&lt;img alt="LoRaBugBoardV3.1_3D.png" src="https://new.craighesling.com/project/lorabug/LoRaBugBoardV3.1_3D_hu78434072f4b03f97a69451697241d2b9_446129_1030x0_resize_q20_lanczos_3.png">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="The extremely low power consumption of the LoRaBug while sleep" href="https://new.craighesling.com/project/lorabug/LoRaBug_Exteme_Sleep_hua80e3be80af02d69f9ee4704be305725_1356728_4160x0_resize_q75_lanczos.jpg">
&lt;img alt="LoRaBug_Exteme_Sleep.jpg" src="https://new.craighesling.com/project/lorabug/LoRaBug_Exteme_Sleep_hua80e3be80af02d69f9ee4704be305725_1356728_4160x0_resize_q15_lanczos.jpg">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="The LoRaBug controlling LED accent lighting" href="https://new.craighesling.com/project/lorabug/LoRaBug_LED_Controller_hu1b844f0a393381480f4920e09890ee47_1248524_3088x0_resize_q75_lanczos.jpg">
&lt;img alt="LoRaBug_LED_Controller.jpg" src="https://new.craighesling.com/project/lorabug/LoRaBug_LED_Controller_hu1b844f0a393381480f4920e09890ee47_1248524_3088x0_resize_q15_lanczos.jpg">
&lt;/a>
&lt;/div>
&lt;h2 id="summary">Summary&lt;/h2>
&lt;p>The LoRaBug is a general purpose low-power sensor platform.
It tightly integrates an ARM Cortex M3 based MCU, BLE, and a LoRa radio.&lt;/p>
&lt;p>Checkout the &lt;a href="https://github.com/OpenChirp/LoRaBug" target="_blank" rel="noopener">Github repository&lt;/a> for more
detail.&lt;/p>
&lt;h2 id="key-features">Key Features&lt;/h2>
&lt;ul>
&lt;li>TI CC2650 MCU/Transciever - ARM Cortex M3, Bluetooth+BLE, and 2.4GHz 802.15.4&lt;/li>
&lt;li>Semtech SX1276 radio - 137MHz to 1020MHz supporting LoRa, FSK, GFSK, MSK, GMSK, and OOK&lt;/li>
&lt;li>Micro USB - Bootloading and Console&lt;/li>
&lt;li>Onboard 500mA 3.3V regulator&lt;/li>
&lt;/ul>
&lt;h2 id="software">Software&lt;/h2>
&lt;ul>
&lt;li>I have adapted the HAL of the official LoRaWAN stack for the CC2650 with TI-RTOS - &lt;a href="https://github.com/OpenChirp/LoRaMac-node/tree/lorabug" target="_blank" rel="noopener">LoRaWAN MAC&lt;/a>&lt;/li>
&lt;li>A spinoff from my example firmware can be found - &lt;a href="https://github.com/OpenChirp/LoRaBug_Firmware" target="_blank" rel="noopener">LoRaBug_Firmware&lt;/a>.&lt;/li>
&lt;li>I have created a cross-platform serial bootloader tool that allows you to flash the LoRaBug using just a micro usb cable - &lt;a href="https://new.craighesling.com/post/cc2538-cc26xx-bootloader/">ccbootutil&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="schematic-and-board">Schematic and Board&lt;/h2>
&lt;a href="https://cdn.rawgit.com/OpenChirp/LoRaBug/ec3e2fa6/Info/LoRaBugBoardV3.1.pdf">Download PDF&lt;/a>
&lt;p>A preview of the PDF should appear below. If it does not show up soon, please refresh the page.&lt;/p>
&lt;iframe src="https://docs.google.com/gview?url=https%3a%2f%2fcdn.rawgit.com%2fOpenChirp%2fLoRaBug%2fec3e2fa6%2fInfo%2fLoRaBugBoardV3.1.pdf&amp;embedded=true" style="width:100%; height:600px;" frameborder="0">
This browser does not support PDFs. Please download the PDF to view it: &lt;a href="https://cdn.rawgit.com/OpenChirp/LoRaBug/ec3e2fa6/Info/LoRaBugBoardV3.1.pdf">Download PDF&lt;/a>
&lt;/iframe></description></item><item><title>MASH Android App</title><link>https://new.craighesling.com/project/mash/</link><pubDate>Sun, 29 May 2016 00:00:00 +0000</pubDate><guid>https://new.craighesling.com/project/mash/</guid><description>&lt;h2 id="an-android-mortrio-dashboard">An Android Mortr.io Dashboard&lt;/h2>
&lt;div class="gallery">
&lt;a data-fancybox="gallery-main" data-caption="Device Control View" href="https://new.craighesling.com/project/mash/MASH_Device_Control_hu3dbef4594faa034b5f10d88e367cfe2e_61613_1440x0_resize_q75_lanczos_3.png">
&lt;img alt="MASH_Device_Control.png" src="https://new.craighesling.com/project/mash/MASH_Device_Control_hu3dbef4594faa034b5f10d88e367cfe2e_61613_200x0_resize_q20_lanczos_3.png">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="Device Data View" href="https://new.craighesling.com/project/mash/MASH_Device_Data_hu25c96676170b8765f2815e8e0d19a809_60421_1440x0_resize_q75_lanczos_3.png">
&lt;img alt="MASH_Device_Data.png" src="https://new.craighesling.com/project/mash/MASH_Device_Data_hu25c96676170b8765f2815e8e0d19a809_60421_200x0_resize_q20_lanczos_3.png">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="Locations View" href="https://new.craighesling.com/project/mash/MASH_Locations_hud0845b8b46620cd957b7054bbaa484e3_75665_1440x0_resize_q75_lanczos_3.png">
&lt;img alt="MASH_Locations.png" src="https://new.craighesling.com/project/mash/MASH_Locations_hud0845b8b46620cd957b7054bbaa484e3_75665_200x0_resize_q20_lanczos_3.png">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="App Sidebar" href="https://new.craighesling.com/project/mash/MASH_Sidebar_hu84f12fa63ff9c32ec90217dc6e33f13b_297727_1440x0_resize_q75_lanczos_3.png">
&lt;img alt="MASH_Sidebar.png" src="https://new.craighesling.com/project/mash/MASH_Sidebar_hu84f12fa63ff9c32ec90217dc6e33f13b_297727_200x0_resize_q20_lanczos_3.png">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="Example Sub-Location" href="https://new.craighesling.com/project/mash/MASH_SubLocation_hube20356a663f8d19ef1f100caac68ab3_93761_1440x0_resize_q75_lanczos_3.png">
&lt;img alt="MASH_SubLocation.png" src="https://new.craighesling.com/project/mash/MASH_SubLocation_hube20356a663f8d19ef1f100caac68ab3_93761_200x0_resize_q20_lanczos_3.png">
&lt;/a>
&lt;/div>
&lt;a href="https://craighesling.com/files/MASH_Presentation.pdf">Download PDF&lt;/a>
&lt;p>A preview of the PDF should appear below. If it does not show up soon, please refresh the page.&lt;/p>
&lt;iframe src="https://docs.google.com/gview?url=https%3a%2f%2fcraighesling.com%2ffiles%2fMASH_Presentation.pdf&amp;embedded=true" style="width:100%; height:600px;" frameborder="0">
This browser does not support PDFs. Please download the PDF to view it: &lt;a href="https://craighesling.com/files/MASH_Presentation.pdf">Download PDF&lt;/a>
&lt;/iframe>
&lt;h1 id="mortrio-software-stack">Mortr.io Software Stack&lt;/h1>
&lt;div class="gallery">
&lt;a data-fancybox="gallery-mortr_io" data-caption="The Mortr.io Software Stack" href="https://new.craighesling.com/project/mash/Mortr_io_Stack_hu9f153c27d7185c5c00f25c0cd71703d6_100557_960x0_resize_q75_lanczos.jpg">
&lt;img alt="Mortr_io_Stack.jpg" src="https://new.craighesling.com/project/mash/Mortr_io_Stack_hu9f153c27d7185c5c00f25c0cd71703d6_100557_960x0_resize_q75_lanczos.jpg">
&lt;/a>
&lt;/div></description></item><item><title>FORK</title><link>https://new.craighesling.com/project/fork/</link><pubDate>Mon, 24 Aug 2015 07:46:59 -0500</pubDate><guid>https://new.craighesling.com/project/fork/</guid><description>
&lt;div class="gallery">
&lt;a data-fancybox="gallery-main" data-caption="Demo of FORK in action" href="https://new.craighesling.com/project/fork/Demo_Above_Door_huba63cdbc048425c7b1b45ad6eb08ee98_565969_556x0_resize_q75_lanczos_3.png">
&lt;img alt="FORK Above Door" src="https://new.craighesling.com/project/fork/Demo_Above_Door_huba63cdbc048425c7b1b45ad6eb08ee98_565969_556x0_resize_q75_lanczos_3.png">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="This is what FORK sees" href="https://new.craighesling.com/project/fork/Demo_Debug_hu0c6c2ba13650b11eb071086e24444393_354108_1316x0_resize_q75_lanczos_3.png">
&lt;img alt="What FORK sees" src="https://new.craighesling.com/project/fork/Demo_Debug_hu0c6c2ba13650b11eb071086e24444393_354108_1316x0_resize_q75_lanczos_3.png">
&lt;/a>
&lt;/div>
&lt;h1 id="fine-grained-occupancy-estimator-using-kinect-fork">Fine grained Occupancy estimatoR using Kinect (FORK)&lt;/h1>
&lt;p>This project focused on developing a prototype system to explore the potential of using depth sensors to detect, estimate, identify, and track occupants in buildings.
The FORK system uses a cheaper and lower power ARM processor for real-time processing, instead of using a high-power and high-cost computer, like an XBOX or an Intel Core i7 based machine.
Unlike other camera based approaches, FORK is much less privacy invasive (even if the sensor is compromised) through its use of depth sensing and local processing.&lt;/p>
&lt;h1 id="my-contributions">My Contributions&lt;/h1>
&lt;ul>
&lt;li>Researched/sourced the embedded platform with USB 3.0 support and that was capable of real-time processing&lt;/li>
&lt;li>Packaged the dependencies and environment needed for fast Debian deployment&lt;/li>
&lt;li>Created the C++ XMPP Mortr.io interface for background data offloading&lt;/li>
&lt;li>Created tools to remotely monitor and control multiple FORK nodes&lt;/li>
&lt;/ul>
&lt;h2 id="embedded-hardware">Embedded Hardware&lt;/h2>
&lt;p>We settled on an ODROID XU4, which hosts a Samsung Exynos 5 Octa 5422 SoC.
This Samsung SoC was the deciding factor in choosing the XU4 due its USB 3.0
support and its powerful Mali-T628 MP6 GPU.&lt;/p>
&lt;div class="gallery">
&lt;a data-fancybox="gallery-hardware" data-caption="The ODROID XU3 from the first ARM version of FORK" href="https://new.craighesling.com/project/fork/ODROID_Open_hub36866bd3ee67792cce830ae74d3dd3e_118973_711x0_resize_q75_lanczos.jpg">
&lt;img alt="ODROID XU3 Opened Case" src="https://new.craighesling.com/project/fork/ODROID_Open_hub36866bd3ee67792cce830ae74d3dd3e_118973_711x0_resize_q20_lanczos.jpg">
&lt;/a>
&lt;a data-fancybox="gallery-hardware" data-caption="An XBOX Kinnect used in FORK" href="https://new.craighesling.com/project/fork/XBOX_Kinnect_Annotated_hu6e26a41ee06d80d78d587cacd6942dde_182793_927x0_resize_q75_lanczos_3.png">
&lt;img alt="XBOX Kinnect" src="https://new.craighesling.com/project/fork/XBOX_Kinnect_Annotated_hu6e26a41ee06d80d78d587cacd6942dde_182793_927x0_resize_q75_lanczos_3.png">
&lt;/a>
&lt;/div>
&lt;h2 id="debian-packages">Debian Packages&lt;/h2>
&lt;div class="gallery">
&lt;a data-fancybox="gallery-packages" data-caption="Package_OpenCL.png" href="https://new.craighesling.com/project/fork/Package_OpenCL_hud847012266f6b053d1af04ccc29fee6a_5443_139x0_resize_q75_lanczos_3.png">
&lt;img alt="Package_OpenCL.png" src="https://new.craighesling.com/project/fork/Package_OpenCL_hud847012266f6b053d1af04ccc29fee6a_5443_139x0_resize_q20_lanczos_3.png">
&lt;/a>
&lt;a data-fancybox="gallery-packages" data-caption="Package_OpenCL_Headers.png" href="https://new.craighesling.com/project/fork/Package_OpenCL_Headers_hu08c17460700befa95b16b03c95852f59_5578_136x0_resize_q75_lanczos_3.png">
&lt;img alt="Package_OpenCL_Headers.png" src="https://new.craighesling.com/project/fork/Package_OpenCL_Headers_hu08c17460700befa95b16b03c95852f59_5578_136x0_resize_q20_lanczos_3.png">
&lt;/a>
&lt;a data-fancybox="gallery-packages" data-caption="Package_Rules.png" href="https://new.craighesling.com/project/fork/Package_Rules_hue560d7f4069287b912034a5f8fb7091c_5149_108x0_resize_q75_lanczos_3.png">
&lt;img alt="Package_Rules.png" src="https://new.craighesling.com/project/fork/Package_Rules_hue560d7f4069287b912034a5f8fb7091c_5149_108x0_resize_q20_lanczos_3.png">
&lt;/a>
&lt;/div></description></item><item><title>Enlighten</title><link>https://new.craighesling.com/project/enlighten/</link><pubDate>Sat, 14 Feb 2015 07:46:59 -0500</pubDate><guid>https://new.craighesling.com/project/enlighten/</guid><description>&lt;p>This project focused on sending data to a mobile device using the camera.&lt;/p>
&lt;p>Through the use of an off the shelf smart bulb, we were able to send location
specific bits of data to an iPhone.&lt;/p>
&lt;div class="gallery">
&lt;a data-fancybox="gallery-main" data-caption="Inside the smart bulb with JTAG connected" href="https://new.craighesling.com/project/enlighten/Enlighten_Inside_Board_hu18d60940e909fe52203d28c8b5a70580_823519_4160x0_resize_q75_lanczos.jpg">
&lt;img alt="" src="https://new.craighesling.com/project/enlighten/Enlighten_Inside_Board_hu18d60940e909fe52203d28c8b5a70580_823519_4160x0_resize_q20_lanczos.jpg">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="The smart bulb through a phone camera" href="https://new.craighesling.com/project/enlighten/Enlighten_LIFX_Running_hu5cbed9a727713d205bf9f81fb63a9f39_2908474_3120x0_resize_q75_lanczos.jpg">
&lt;img alt="" src="https://new.craighesling.com/project/enlighten/Enlighten_LIFX_Running_hu5cbed9a727713d205bf9f81fb63a9f39_2908474_3120x0_resize_q20_lanczos.jpg">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="iPhone App Splash Screen" href="https://new.craighesling.com/project/enlighten/Enlighten_Phone_App_hu824670d008daf1bb0b8a57dfc985cafb_27523_196x0_resize_q75_lanczos_3.png">
&lt;img alt="" src="https://new.craighesling.com/project/enlighten/Enlighten_Phone_App_hu824670d008daf1bb0b8a57dfc985cafb_27523_196x0_resize_q20_lanczos_3.png">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="MCU Board Annotated" href="https://new.craighesling.com/project/enlighten/MCU_Board_Diagram_hu064719642517c0de8b7e0d5c695ad3f3_41619_960x0_resize_q75_lanczos.jpg">
&lt;img alt="" src="https://new.craighesling.com/project/enlighten/MCU_Board_Diagram_hu064719642517c0de8b7e0d5c695ad3f3_41619_960x0_resize_q20_lanczos.jpg">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="Modified smart bulb" href="https://new.craighesling.com/project/enlighten/Enlighten_Final_Product_1_hu7c4a5bd842465f6bdee680653eafb857_2294736_4160x0_resize_q75_lanczos.jpg">
&lt;img alt="Modified smart bulb" src="https://new.craighesling.com/project/enlighten/Enlighten_Final_Product_1_hu7c4a5bd842465f6bdee680653eafb857_2294736_4160x0_resize_q20_lanczos.jpg">
&lt;/a>
&lt;a data-fancybox="gallery-main" data-caption="featured.jpg" href="https://new.craighesling.com/project/enlighten/featured_hu0e8df1772398e2093fadaac1901fbd84_401591_3120x0_resize_q75_lanczos.jpg">
&lt;img alt="featured.jpg" src="https://new.craighesling.com/project/enlighten/featured_hu0e8df1772398e2093fadaac1901fbd84_401591_3120x0_resize_q20_lanczos.jpg">
&lt;/a>
&lt;/div>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/eOzUnAXzWbc" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div>
&lt;h1 id="hardware">Hardware&lt;/h1>
&lt;p>We have chosen the $80 LIFX multicolored LED smart bulb.
It has two ARM Cortex-M3 processors onboard to handle WiFI and 802.15.4 radios.
What makes this bulb more appropriate for the project, as compared to the &amp;ldquo;CREE Connected&amp;rdquo; or the &amp;ldquo;Connected by TCP&amp;rdquo; bulb, is the fact that the onboard LED driver circuit is directly connected to the MCU IO pin and is capable of being PWM controlled.
This allows us to send data using nothing other than frequency modulated light.
The CREE and TCP bubs use a continuous current LED driver circuit that cannot be used without hardware modifications.&lt;/p>
&lt;h1 id="software">Software&lt;/h1>
&lt;p>The iPhone app used the Apple® Cocoa™ Touch library and OpenCV.&lt;/p>
&lt;h1 id="links">Links&lt;/h1>
&lt;!-- Checkout the [Enlighten website](https://www.ece.cmu.edu/~ece549/spring15/team10/website/) -->
&lt;ul>
&lt;li>Checkout the original &lt;a href="https://web.archive.org/web/20150920164554/https://www.ece.cmu.edu/~ece549/spring15/team10/website/" target="_blank" rel="noopener">Enlighten website&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/gr3co/enlighten" target="_blank" rel="noopener">Enlighten GitHub&lt;/a>&lt;/li>
&lt;/ul></description></item></channel></rss>