tag:blogger.com,1999:blog-81405075835113531212024-03-12T00:51:42.522-04:00RyanFX's BlogGadgets, Electronics, Code, Android, and Fun!Unknownnoreply@blogger.comBlogger6125tag:blogger.com,1999:blog-8140507583511353121.post-83683236250765819472014-04-27T11:59:00.001-04:002014-04-27T11:59:05.578-04:00Nexus 7 Poor Wireless (Wi-Fi) SignalThis is not your typical post, but I struggled enough with this that I assumed others could benefit from it as well.<br />
<br />
I have a first gen Nexus 7 (N7) and had extremely bad Wi-Fi signal / reception over the past few months. Not only was the signal bad, the throughput was miserable (5 mbps). I purchased a TRENDnet <a href="http://www.amazon.com/gp/product/B00B0CQCCC/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B00B0CQCCC&linkCode=as2&tag=personagadget-20">TEW-811DRU</a> which I flashed DD-WRT onto and installed it as an additional access point to help alleviate the problem. It barely helped. I played around with wireless channels, frequencies (2.4 vs 5.0), and more. Nothing would make it better despite the router being 8 feet from the tablet.<br />
<br />
Eventually I discovered the problem, which seems to be a bit common in these generations. As with most tablets, the 7 has been dropped a time or two. It turns out that the Wi-Fi antenna is actually connected from the main unit to the rear case. On my 7, the upper left corner of the case was actually snapped open about a 1/16th of an inch. Pressing the case back in (I had to press fairly hard) <b>instantly</b> fixed all of the wireless signal problems.<br />
<br />
So there you have it. If you are having terrible wireless reception or signal issues, check your case and make sure it's fully snapped in. It may be an easier fix than you thought!Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8140507583511353121.post-3473207351609343122013-11-29T02:38:00.002-05:002013-11-30T11:59:56.723-05:002013 Prius C Factory Rear View Backup Camera Installation<h3>
Background and problem</h3>
I recently took a new job and had to buy an additional car as my wife had the only one for the family. My one request for this vehicle was that it had a backup camera, as I parallel park with the finesse of a drunken bull.<br />
<br />
Due to one other requirement (it needed to be super short in length as I have a tandem garage) I wound up with a Prius C. Of course the Prius did not come with a backup camera, nor was it even offered, at least in the great US of A (In Australia it's an option!). Due to this, I opted to purchase the "three" trim, which comes with a 6-7 inch color display in which I hoped to mod to facilitate my original requirement.<br />
<br />
I did some Googling and found posts on the <a href="http://priuschat.com/forum/">PriusChat forums</a> regarding some success in getting aftermarket cameras hooked up to the factory head unit. One user I'd like to particularly thank, Mik1, gave a <a href="http://priuschat.com/threads/rearview-camera.110133/page-6#post-1602412">write up on his installation</a>. I used this as a guide for most of my install, including the pins on the wiring harness, how to remove the body panels, etc.<br />
<br />
What I did change, however, was how the camera was getting power. Some users on PriusChat were successful in powering their cameras from the powered output on the head unit marked 5.5-6.5v in his write up (I measured this as 6.33V). It's important to note that this output gets activated whenever the car is in reverse, or when the car is searching for the camera. Many were unsuccessful in getting this low voltage to work and it seemed to be heavily dependent on what camera was selected as almost all cameras are rated for 12v. In addition to the hit or miss nature of the cameras, I didn't want to run any sort of substantial power draw from the head unit anyways. With little documentation from Toyota (at least that I have access to) about how much current can be safely drawn from the head unit, I wanted to find a safer approach.<br />
<br />
A common technique of hooking up rear view cameras in vehicles is to tap the reverse light power. It's an extremely simple solution that works extremely well... almost always. It outputs 12v, and only does so when the car is actually in reverse, so the camera won't be powered on all the time. So what's the catch? This head unit in particular outputs voltage for 60 seconds after the car starts up to "search" for an installed camera. If it does not detect video signal during that time frame, it will not attempt to display the camera feed when you eventually do shift into reverse. This means that you <u>can</u> hook into the reverse lights to power your camera, but in order to use it, you would have to shift into reverse every time you start your car within the first 60 seconds... just in case you want to use your camera later that trip. This would lower the <a href="http://en.wikipedia.org/wiki/Wife_acceptance_factor">WAF</a> of the project well below acceptable thresholds. At least in my household.<br />
<br />
Some users were having success in tapping into a blue wire in the rear of the car attached to the wiper motor but this is problematic because it is a switched power source, which means that your camera is now powered on for the duration of each and every trip. A 5-6 hour trip would put the wear and tear of a normal year on the camera, assuming you would be using it for about a minute every day.<br />
<br />
<h3>
Solution</h3>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgj8GV72vjDUO0nwvC3SvjNk9-ynBdNiwnVUTVXawhM2J0tTCYj_MJPCLuiyIsNDGEv3TZ8Vv9Uz90im7dzAyF_yPqFIRq0VpwKpWrSJpBexF0BTKIof5E-Ssnxv5dzfpMc_HnmrOIsTY4/s1600/IMG_20131123_143302.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgj8GV72vjDUO0nwvC3SvjNk9-ynBdNiwnVUTVXawhM2J0tTCYj_MJPCLuiyIsNDGEv3TZ8Vv9Uz90im7dzAyF_yPqFIRq0VpwKpWrSJpBexF0BTKIof5E-Ssnxv5dzfpMc_HnmrOIsTY4/s640/IMG_20131123_143302.jpg" width="640" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<b>It probably goes without saying, but please do not work on anything you do not feel comfortable doing. I can't guarantee how this will affect your warranty, so please use this as a reference rather than a how-to or tutorial. There is no shame in paying a professional ;)</b></div>
<div>
<br /></div>
<div>
I decided to power the camera from the 12v supply going to the cigarette lighter, or "12v auxiliary power outlet" if your conscience tells you that's a better name. This circuit has more than enough capacity to power a little camera. In addition, I purchased a solid state relay that has an opto-isolator built in, which means you can safely connect the 12v supply and 6.33v supply from the head unit to the same device without fear of blowing anything out. The only other parts you'll need is a resistor, some wiring, connectors, and the camera itself.</div>
<div>
<br /></div>
<div>
Parts:</div>
<div>
<ul>
<li><a href="http://dx.com/p/195275?Utm_rid=27583318&Utm_source=affiliate">Eagleeyes EC-TH103</a> - Great lux rating (think night vision), IP67 waterproofing, and resolution, all for under 30 dollars</li>
<li><a href="http://dx.com/p/238639?Utm_rid=27583318&Utm_source=affiliate">SSR-25DD</a> - Solid state relay meant for DC signal and DC switching (careful, as many are made for AC switching). The signal current required is extremely low ( less than 15ma) and can handle up to 25 amps. We'll be using a fraction of an amp.</li>
<li><a href="http://www.amazon.com/gp/product/B001768788/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B001768788&linkCode=as2&tag=personagadget-20">Male connectors</a> - Make sure you have a wire crimper - cheap ones are available everywhere.</li>
<li><a href="http://www.amazon.com/gp/product/B000EIO86A/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B000EIO86A&linkCode=as2&tag=personagadget-20">Female connectors</a></li>
<li><a href="http://www.amazon.com/gp/product/B00152RH4O/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B00152RH4O&linkCode=as2&tag=personagadget-20">3M T-taps</a> - These are really nice. You can tap on a wire and connect / disconnect to it at will by inserting a male connector (the ones listed above work great for this)</li>
<li><a href="http://www.pololu.com/product/1924">JR Connector pack</a> - Used to connect the your wiring into the factory Toyota harness.</li>
<li><a href="http://www.amazon.com/gp/product/B007SVHFXO/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B007SVHFXO&linkCode=as2&tag=personagadget-20">Resistor pack</a> - You really don't need all of these resistors, but it's a great assortment if you do projects, and you almost certainly won't need to order more next time you need a resistor!</li>
<li><a href="http://www.amazon.com/gp/product/B0017HX5DE/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B0017HX5DE&linkCode=as2&tag=personagadget-20">Molding remover</a> - Makes your life infinitely easier when trying to remove trim / fasteners in the car.</li>
<li><a href="http://www.amazon.com/gp/product/B000HAB7ZU/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B000HAB7ZU&linkCode=as2&tag=personagadget-20">Wire</a></li>
</ul>
<div>
<br /></div>
</div>
<div>
Follow Mik1's guide to taking apart the car and running wiring. I ran four cables from the head unit to the back of the car, two will transport video, two will be 12v+ and 12v-.<br />
<br />
The only thing I did substantially different was at the very end of his guide he recommends using wire to pull off the fasteners on the hatch. You can use one of the handy dandy molding removers instead.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPj4unOYIfQaSS4iUXfBU272ZUuQVJl-aaILA9kaHkCioaio7qOZrpSxmrHSMSCM8R4jO93l3e8hQcHYfxhQmyHYbpnEv4A4VmFPxRASCc6lMTHRIvtdOGADpW4MbB4Rg2lVB3uMk_Ynw/s1600/IMG_20131109_164250.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPj4unOYIfQaSS4iUXfBU272ZUuQVJl-aaILA9kaHkCioaio7qOZrpSxmrHSMSCM8R4jO93l3e8hQcHYfxhQmyHYbpnEv4A4VmFPxRASCc6lMTHRIvtdOGADpW4MbB4Rg2lVB3uMk_Ynw/s400/IMG_20131109_164250.jpg" width="300" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq4ImxmSL6uw4PX-GNDwMOKNQt8flYZqCQNmXBxxavip0JZlMhxtdRD8xGDi5qoExUvyX9zjsdVBAxXE0tyy87mhcujkQ_vJHyYnfJDJRs1-W6Y40u3gJwCyJGw8rNd5lezbEz-JClsgU/s1600/IMG_20131109_164258.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq4ImxmSL6uw4PX-GNDwMOKNQt8flYZqCQNmXBxxavip0JZlMhxtdRD8xGDi5qoExUvyX9zjsdVBAxXE0tyy87mhcujkQ_vJHyYnfJDJRs1-W6Y40u3gJwCyJGw8rNd5lezbEz-JClsgU/s400/IMG_20131109_164258.jpg" width="300" /></a></div>
<br />
<br />
<br />
<h2>
Relay</h2>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXoAtvHZtrtX3x0_81s8g_Ls8pkf0hueVWZApauMJ-yWU2W4J4KLpQjcf8vcM3DVJlO5PGDlebq45zPujSiAFo5__qWxbZb7O9XM7Oip3kwcJsrZe1FHDBecXWcBrpdT3TMGt3wsBb2L8/s1600/dc_relay.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXoAtvHZtrtX3x0_81s8g_Ls8pkf0hueVWZApauMJ-yWU2W4J4KLpQjcf8vcM3DVJlO5PGDlebq45zPujSiAFo5__qWxbZb7O9XM7Oip3kwcJsrZe1FHDBecXWcBrpdT3TMGt3wsBb2L8/s320/dc_relay.jpg" width="320" /></a></div>
<br />
<br />
<ul>
<li>Solder or crimp a wire together with a 470 ohm resistor and connect it to the 6.33v+ from the head unit, to terminal 3 on the relay.</li>
<li>Connect a plain old wire from the 6.33v- on the head unit to terminal 4. This, with terminal 3, will serve as your relay signal, allowing power through the switched side when the car enters reverse, or when the car searches for the camera's presence. The resistor limits the amount of current output by the head unit to help ensure that you don't overload it (we'll be drawing 13mA).</li>
<li>Connect a T-tap on each of the two wires connecting to the cigarette outlet while you're behind the dash (you can't miss them, just peel back the black tape). Connect the positive wire to terminal 2, then connect terminal 1 to your camera's 12v+ supply. Connect your camera's ground to the other T-tap and you're done with the power!</li>
</ul>
</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinuOLm_7Tt12qmUHj30tXpxTrQpIcPySCrrRI2ecERl9KtqVOOTrja6JgfS3AJej1McEN2VUavWszWT8DFhJTqqliLtyGMzdMkohyphenhyphencqsN2alVDWGG-4oWQd4fBu5c8WSR3UEcr97EA11k/s1600/IMG_20131117_150734.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinuOLm_7Tt12qmUHj30tXpxTrQpIcPySCrrRI2ecERl9KtqVOOTrja6JgfS3AJej1McEN2VUavWszWT8DFhJTqqliLtyGMzdMkohyphenhyphencqsN2alVDWGG-4oWQd4fBu5c8WSR3UEcr97EA11k/s640/IMG_20131117_150734.jpg" width="480" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Connect your camera's video signal wires (two of the four wires you ran to the back of the car) to the appropriate pins on the head unit harness marked as video in and video ground in Mik1's write up. Alternatively you can make use of the video cable provided with the camera and snip off the RCA connector.</div>
<div>
<br /></div>
<div>
At this point you should be able to start your car, put it in reverse, and see a camera image on your display! Here's mine while the camera was in my front seat.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXN4ymfSgoVIAGzYX-7c5GRhaZVK-mZ0JNcwBePN_cI3xJz50ZNAOQEyyXEvfY36LINKmNuD6S4q5dfoJYskwXXpa5Ct3ic48bx2H6g8fEfpH_kPu0h6x1Iva7d_0EJW7BQ6tgu_OjRYs/s1600/IMG_20131120_181513.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXN4ymfSgoVIAGzYX-7c5GRhaZVK-mZ0JNcwBePN_cI3xJz50ZNAOQEyyXEvfY36LINKmNuD6S4q5dfoJYskwXXpa5Ct3ic48bx2H6g8fEfpH_kPu0h6x1Iva7d_0EJW7BQ6tgu_OjRYs/s640/IMG_20131120_181513.jpg" width="640" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
You'll need to mount the camera in the plastic piece of trim that's attached to the hatch opening button. It's attached with a few bolts accessible from the inside of the car and is really the easiest part of the install! Drill a small hole through the hatch itself underneath this trim to run the wiring inside and then smear some silicone caulk in the hole the prevent any water form leaking in.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXGlvzt71IPnJEO0l67bDULnJo9_qRKmqTenYOb9R3vmXdgVx5sHDMa6f2WyMCCgToWaXQfzrPYdByp-lXGersWS9s77EvySqw0_Ce0UQUyXT62TW94NqQmW3VXeiSOFvBOe9TcUf5nfQ/s1600/IMG_20131120_230058.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXGlvzt71IPnJEO0l67bDULnJo9_qRKmqTenYOb9R3vmXdgVx5sHDMa6f2WyMCCgToWaXQfzrPYdByp-lXGersWS9s77EvySqw0_Ce0UQUyXT62TW94NqQmW3VXeiSOFvBOe9TcUf5nfQ/s640/IMG_20131120_230058.jpg" width="640" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Mount the relay wherever you'd like and tape everything up so it's nice and secure - you're done!</div>
Unknownnoreply@blogger.com8tag:blogger.com,1999:blog-8140507583511353121.post-39541749671159476842013-07-01T23:42:00.002-04:002013-07-06T18:39:37.274-04:00How to stop a thread in JavaStopping threads in Java are one of those things in life that are extremely easy in practice yet conceptually unintuitive. There are also several ways of doing so which adds to the confusion. This article outlines the three major patterns.<br />
<br />
<a name='more'></a><br />
<h3>
Additional resources</h3>
<div>
If you are looking for further reading, I highly recommend <a href="http://www.amazon.com/gp/product/0321349601/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321349601&linkCode=as2&tag=personagadget-20"><b>Java Concurrency in Practice</b></a>. It is a fantastic book that highlights many common developer pitfalls and demonstrates great, reusable patterns for multithreaded applications.<br />
<br />
<br />
<br /></div>
First we'll cover the absolute <u><b>WRONG</b></u> way that you should <u><b>NEVER</b></u> use!<br />
<br />
<pre class="prettyprint">package com.blogspot.ryanfx;
public class WrongRunnable implements Runnable{
private static long SLEEP = 5000;
@Override
public void run() {
for (long count = 0; count < SLEEP; count++){
System.out.println("Waiting... " + count);
}
}
public static void main(String[] args) throws InterruptedException{
Thread myThread = new Thread(new WrongRunnable());
myThread.start();
myThread.sleep(1);
myThread.stop();
}
}
</pre>
<br />
In the above example a new <i>Thread</i> is instantiated with our <i>Runnable</i>. This <i>Thread</i> is then started which begins execution of whatever is inside the overridden <i>run()</i> method. The main thread is put to sleep for 1 millisecond and then the new thread is stopped. While this looks perfectly reasonable and acceptable by all stretches of the imagination, it's actually a terrible, terrible thing to do. <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#stop()">Thread#stop()</a> is a deprecated method and for very good reasons. It's analogous to <i>kill -9</i> in the sense that it doesn't do a very good job with cleaning up after itself. It can leave your program in an extremely inconsistent state and and wreck havoc on <a href="http://en.wikipedia.org/wiki/Mutual_exclusion">locks or mutexes</a>. Oracle (Sun then) even says <a href="http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html">not to use it</a>! <br />
<br />
You may be asking yourself "Well if we can't <i>stop()</i> the thread, how are we going to stop the thread!?" <br />
<br />
Long story short, you <i>return</i>. Below is an example of such a pattern.<br />
<b><br /></b>
<br />
<pre class="prettyprint">package com.blogspot.ryanfx;
public class FlagRunnable implements Runnable{
private volatile boolean exit = false;
private static long SLEEP = 5000;
@Override
public void run() {
for (long count = 0; count < SLEEP; count++){
System.out.println("Waiting... " + SLEEP);
if (exit == true){
return;
}
}
}
public void requestExit(){
exit = true;
}
public static void main(String[] args) throws InterruptedException{
FlagRunnable myRunnable = new FlagRunnable();
Thread myThread = new Thread(myRunnable);
myThread.start();
myThread.sleep(1);
myRunnable.requestExit();
}
}
</pre>
<br />
In the above example we again create a <i>Runnable</i> and a new <i>Thread</i>. What's different is that we have introduced a new variable called <i>exit</i>. Every iteration of the loop inside <i>run()</i>, <i>exit</i> is evaluated. If <i>exit</i> is ever <i>true</i>, we <i>return</i> which signals to the JVM that this <i>Thread</i> has now completed. The JVM begins cleaning up any loose structures and it properly stops execution of the <i>Thread</i>. You may have noticed that boolean is declared <i>volatile</i>. What this does is give a hint to the compiler that certain optimizations cannot be taken because this variable is modified by external threads. If this were not used the value of <i>exit</i> could be cached and reused for some time before its changed state is detected. Once the main thread has slept for 1 millisecond it calls the <i>requestExit()</i> method in our <i>Runnable</i> to signal a shutdown. The very next time the loop in <i>run()</i> iterates, it <i>return</i>s. While this is a perfectly acceptable pattern there are often times where this shouldn't be used. Imagine instead of calling <i>System.out</i> we were instead calling a very long running method such as network IO. When <i>requestExit()</i> is invoked, we are guaranteed to not iterate more times in the loop, but it may take quite some time before the <i>Thread</i> actually finishes. Additionally, adding in exit flags exit conditionals becomes repetitive in all of your threaded classes.<br />
<br />
<pre class="prettyprint">package com.blogspot.ryanfx;
public class NativeRunnable implements Runnable{
private static long SLEEP = 5000;
@Override
public void run() {
for (long count = 0; count < SLEEP; count++){
System.out.println("Waiting... " + SLEEP);
if (Thread.isInterrupted()){
return;
}
}
}
public void requestExit(){
exit = true;
}
public static void main(String[] args) throws InterruptedException{
Thread myThread = new Thread(new WrongRunnable());
myThread.start();
myThread.sleep(1);
myThread.interrupt();
}
}
</pre>
<br />
This last version uses functionality built into java called <i><a href="http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html">Interrupts</a></i>. A <i>Thread</i> can signal to a <i>Thread</i> (another one, or itself) that it should begin termination with the call <i><a href="http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#interrupt()">interrupt()</a></i>. In this example, every iteration of the loop performs a test to see if it has been interrupted. If it has been interrupted, the thread calls <i>return</i> and the JVM cleans it up. You may notice that some commonly called methods such as <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#sleep(long)">Thread#sleep()</a> and <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/Process.html#waitFor()">Process#waitFor()</a> declare that they throw <i>InterruptedException</i>. This means they support being stopped with the <i>interrupt()</i> method call and you can terminate their execution early. An important note is that we have not added any additional flags or methods to our <i>Runnable</i>. No additional work is required on our part! Another advantage to using this method is more timely termination of your threads. Imagine instead of <i>System.out.println("Waiting... " + SLEEP);</i> we did <i>MyDownloader.download(somehugefile.zip)</i>. Using the flag method instead of this method would not support interrupting the download, however it would prevent it from downloading again the next iteration of the for-loop.<br />
<br />
<b>Beware of one catch with the above method!</b><br />
<b><br /></b>
When <i>isInterrupted()</i> is called the interrupted flag on the <i>Thread</i> is reset. This means if you <i>interrupt()</i> a <i>Thread</i> and then then do not take action, the next call to isInterrupted will return false (unless <i>interrupt()</i> has been called yet again)<br />
<div>
<br />
<br />
<br /></div>
Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-8140507583511353121.post-986465083558061342013-06-28T00:12:00.001-04:002013-06-28T08:59:36.391-04:00Lists, Sets, And Maps, Oh My!Choosing the correct data structure can be a challenge, even for experienced developers. If you're here, you may be wondering:<br />
<br />
<ul>
<li>What kind of data structure should I use for my current task?</li>
<li>When should I use a List?</li>
<li>What about a Set?</li>
<li>What is a Map and why should I care?</li>
</ul>
<br />
<a name='more'></a><br />
<br />
<h1>
<u>Resources</u></h1>
<br />
If you want to learn more about what you read below, I highly recommend one of the following two resources:<br />
<br />
<ul>
<li><a href="http://www.amazon.com/gp/product/0672324539/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=0672324539&linkCode=as2&tag=personagadget-20">Data Structures and Algorithms in Java (2nd Edition)</a> - It is useful as a reference for school, or even preparing for interviews! It covers the fundamentals of Java data structures.</li>
<li><a href="http://www.amazon.com/gp/product/0321356683/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=0321356683&linkCode=as2&tag=personagadget-20">Effective Java (2nd Edition)</a> - A fantastic book covering best practices in Java. This book is best suited for anyone in the intermediate to advanced level of coding.</li>
</ul>
<br />
<h1>
<u>Lists</u></h1>
<div>
<u><br /></u></div>
<i>Lists</i> are quite possibly the most commonly used collection in any programming language. They are easy to insert data into, easy to retrieve data out of, and let's face in...they're convenient! For the most part, they accomplish everything we need, in an acceptable time frame.<br />
<br />
<i>However</i><br />
<i><br /></i>
Many developers use <i>Lists</i> when they simply want to represent a collection of something, even though a different data structure might do a better job.<br />
<br />
<h1>
When are Lists Useful?</h1>
<div>
<br /></div>
<ul>
<li> Your data needs to be accessed or inserted in an orderly fashion</li>
</ul>
Accessing ordered data is an extremely common need. Whether you keep track of a queue of messages, movies in a recently watched playlist, or requests for your widget factory, they all have one thing in common. They need to be ordered.<br />
<br />
<div>
<ul>
<li>Your data needs to be accessed with an index</li>
</ul>
<div>
What does this mean? You can think of the List's index as an offset into your List. You can get the first person waiting in line, or the sixth turn necessary to drive to the supermarket.<br />
<br />
<h1>
<b><u>Sets</u></b></h1>
<div>
<b><u><br /></u></b></div>
<div>
<i>Sets</i> are probably my "go-to" data structure. The majority of <i>Set</i> implementations provide constant time <a href="https://en.wikipedia.org/wiki/Big_O_notation">big O</a> for <i>add</i>, <i>remove</i>, and <i>contains</i>. This means that whether the set contains 1 or 1000 stored objects, it takes just as long to perform the operation. Contrast that to a <i>List</i> where the <i>contains</i> function runs in linear time. As the List grows, the iterator spends more time hunting over the entire collection.</div>
<div>
<br /></div>
<div>
<i>Sets</i> give you advantages over <i>Lists</i>, pending that you are okay with two traits</div>
</div>
</div>
<div>
<ul>
<li>The presence of an entity is what matters, not the quantity</li>
</ul>
<div>
By definition sets do not allow duplicates. As long as this is acceptable, <i>Sets</i> are generally a better choice than Lists. This can be both a blessing and a curse depending on how it's used.<br />
<br />
<ul>
<li>Data is unordered</li>
</ul>
<div>
What does being unordered mean? The order in which data are inserted is not necessarily the order in which it will be retrieved. Sure, there are implementations of <i>Sets</i> that also keep an internal <i>List</i> to maintain ordering such as a <i>LinkedHashSet</i>, but that is implementation specific and adds overhead.<br />
<br /></div>
</div>
</div>
<div>
<div>
<h1>
When are Sets Useful?</h1>
</div>
</div>
<div>
<br /></div>
<div>
Sets should be used for situations like keeping track of registered users, a collection of visited cities, and a collection of e-books that you can sell. In all of these scenarios, quantity and order are irrelevant. In the e-book example, you as the seller would like to know what books you <i>can</i> sell, but you don't have an inventory count. You never run out of downloadable e-books (unless you're doing something wrong!). Implementations of a <i>Set</i> such as <i>HashSet</i> will let us look for the existence of an entity nearly instantaneously ( big O(1) ), regardless of the size of the <i>Set</i>!<br />
<br />
<h1>
<u>Maps</u></h1>
</div>
<div>
<u><br /></u></div>
<div>
<i>Maps</i> are a unique data structure that let you query its contents via a unique identifier (the "key") and retrieve data associated with that key (the "value"). This lets you retrieve a piece of data given a piece of data. Imagine there exists a <i>Map<String, Book></i> where the key is of type <i>String</i> and the value is of type <i>Book</i>. This <i>Map</i> can be queried with an identifier, likely an ISBN, and the <i>Book</i> object itself would be returned. This happens in O(1) time in implementations like <i>HashMap</i>, which means lookups are extremely fast. Imagine a <i>List</i> with 2 million <i>Books</i> - how long would it take to find the <i>Book</i> you want? Maybe as little as one try, maybe as many as 2 million tries!</div>
<div>
<br /></div>
<h1>
When are Maps useful?</h1>
<div>
<br /></div>
<div>
Maps are useful when you need very fast insertion, deletion, and retrieval of data. They are perfect for scenarios where you know a little bit about the data you want (the key) and want more! (the value). As long as one element of your data can serve as a unique key they are wildly fast and extremely efficient structures.</div>
Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-8140507583511353121.post-7810525367352967352013-06-19T23:58:00.000-04:002014-09-11T12:56:20.408-04:00Raspberry Pi Powered, Android Controlled, Tomcat Serviced, Remote Garage Door Opener (Whew!)A few months ago I had left for a business trip and couldn't remember if I had closed the garage door. Nearly all of us have done this at one point in our lives. I promised myself this would never happen again, and a new project was spawned!<br />
<br />
<a name='more'></a><br />
<h3>
<u>Project Overview</u></h3>
<div>
While some plug and play solutions exist such as the <a href="http://www.amazon.com/gp/product/B005FT4N2M/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=B005FT4N2M&linkCode=as2&tag=personagadget-20">Liftmaster 828LM</a>, I wanted to make my own out of curiosity.</div>
<div>
<br /></div>
<div>
The project consists of two components, both of which are entirely open source:</div>
<div>
<ul>
<li>An Android application which posts commands to a web service. The Android application retrieves an authorization token from Google and sends it along with the requested command.</li>
<ul>
<li><a href="https://github.com/ryanfx/GarageAndroid" rel="nofollow" target="_blank">https://github.com/ryanfx/GarageAndroid</a></li>
</ul>
<li>The web service which listens for commands and credentials. These credentials are posted to Google to verify they are authentic. Once the user is verified, the command is executed.</li>
<ul>
<li><a href="https://github.com/ryanfx/GarageWebService" rel="nofollow" target="_blank">https://github.com/ryanfx/GarageWebService</a></li>
</ul>
</ul>
</div>
<br />
I will be giving an overview of the project, but it is by no means a step-by-step tutorial. There have been similar projects online, but I couldn't find any with detailed code on both sides (client + server). This should be a good reference for anyone who wants to do things like:<br />
<br />
<ul>
<li>Run Tomcat on their Raspberry Pi</li>
<li>Authenticate users with Google's OAuth 2 (both getting the token and authenticating the token)</li>
<li>Interact with the GPIO pins of the Raspberry Pi directly in Java</li>
<li>See how a basic Service to Activity (interaction / communication) model can look like in Android. I find this to be one of the most common questions asked by new developers</li>
</ul>
<br />
<div>
<ul>
</ul>
</div>
<div>
<h3>
<u>Demonstration:</u></h3>
<div>
<u><br /></u></div>
<div>
This is a quick video of the whole project in use. Note the status of the door is stated on the home screen of the application so there is never any doubt whether it is open or closed!</div>
<br />
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="https://i3.ytimg.com/s_vi/fYYyDbdqMPU/default.jpg?sqp=CMiu_o0F&rs=AOn4CLBDY-ICm_akYWXkrAX3jhDkIdsaSQ" height="266" width="320"><param name="movie" value="http://www.youtube.com/v/fYYyDbdqMPU?version=3&f=user_uploads&c=google-webdrive-0&app=youtube_gdata" /><param name="bgcolor" value="#FFFFFF" /><param name="allowFullScreen" value="true" /><embed width="320" height="266" src="http://www.youtube.com/v/fYYyDbdqMPU?version=3&f=user_uploads&c=google-webdrive-0&app=youtube_gdata" type="application/x-shockwave-flash" allowfullscreen="true"></embed></object></div>
</div>
<br />
<br />
<h3>
<u>Hardware</u></h3>
<div>
<ul>
<li><a href="http://www.amazon.com/gp/product/B009SQQF9C/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B009SQQF9C&linkCode=as2&tag=personagadget-20" target="_blank">Raspberry Pi Model B</a> - It can act as the web service and physically interface with the garage door all in one device (rather than purchasing something like an <a href="http://www.amazon.com/gp/product/B006H06TVG/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B006H06TVG&linkCode=as2&tag=personagadget-20" target="_blank">Arduino</a>, which would need a more powerful computer sitting in front of it to run the web service). Less is more.</li>
<li><a href="http://www.amazon.com/gp/product/B003MTTJOY/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B003MTTJOY&linkCode=as2&tag=personagadget-20" target="_blank">Edimax EW-7811Un USB Wi-Fi N Dongle</a> - Since I don't have CAT6 run out to my garage door opener (yet), I had to accept using Wi-Fi which I generally avoid at all costs. The chipset in this dongle (RTL8188CUS) is compatible right out of the box with the Raspberry Pi.</li>
<li><a href="http://www.amazon.com/gp/product/B0009SUF08/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B0009SUF08&linkCode=as2&tag=personagadget-20" target="_blank">Magnetic Switch</a> - This is to determine whether the garage is opened or closed. This particular switch is fantastic for one reason; depending on which contact points you hook up to, it can be made either normally open or normally closed.</li>
<li><a href="http://www.amazon.com/gp/product/B0057OC5O8/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B0057OC5O8&linkCode=as2&tag=personagadget-20" target="_blank">Sainsmart Relay Module</a> - Great little board that has relay isolation components already built into it. Separates the power supply from the signal with an optocoupler which protects your other components when the coil's magnetic field collapses.</li>
<li><a href="http://www.amazon.com/gp/product/B003UC4FSS/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B003UC4FSS&linkCode=as2&tag=personagadget-20" target="_blank">Resistors</a> - Miscellaneous resistors. Supplied link is a great pack that gives you a little bit of everything for home projects.</li>
<li>Wiring of your choice.</li>
</ul>
<div>
<br /></div>
</div>
<h3>
<u>
Design requirements</u></h3>
<ul>
<li>Control (toggle) the garage remotely, whether 5 feet away, or 5 countries away</li>
<li>Check the state of the garage door, without needing to toggle / close it</li>
<li>Do so from within an Android application</li>
<ul>
<li>Use Google as the application's authenticator</li>
<li>Take advantage of Android's <a href="http://developer.android.com/reference/android/accounts/AccountManager.html" target="_blank">AccountManager</a></li>
</ul>
<li>Be accessible via HTTP so it could be extended to any platform in the future such as iPhone, iPad, or a simple web browser</li>
<ul>
<li>Run HTTPS so eavesdropping / replay attacks would not be possible</li>
<li>Use an unsigned TLS certificate. There is no need to pay for one if you are the developer!</li>
</ul>
<li><a href="http://en.wikipedia.org/wiki/Wife_acceptance_factor" target="_blank">WAF</a> needs to be high.</li>
<ul>
<li>Low cost</li>
<li>Must not affect normal operation of the door</li>
</ul>
<li>No pre-built solutions</li>
<ul>
<li>Rarely demonstratively secure</li>
<li>Not extensible</li>
<li>Not fun =P</li>
</ul>
</ul>
<br />
<br />
<br />
<h1>
<u>Web Service
</u></h1>
<div>
The web service is responsible for listening for requests over the network. This performs the following actions upon receiving a request:</div>
<div>
<ol>
<li>Authenticates the request with <a href="https://developers.google.com/accounts/docs/OAuth2" target="_blank">Google OAuth 2.0</a> with an subclass of <a href="http://tomcat.apache.org/tomcat-7.0-doc/api/index.html" target="_blank">RealmBase</a>, <a href="https://github.com/ryanfx/GarageWebService/blob/master/src/com/blogspot/ryanfx/auth/GoogleRealm.java" target="_blank">GoogleRealm</a>.</li>
<li>Authorizes the user with a local file containing a line delineated list of valid users</li>
<li>If there was a successful authentication and authorization, perform the required action, namely:</li>
<ul>
<li>Toggle the garage</li>
<li>Get the state of the garage</li>
</ul>
</ol>
<h3>
<u>
Libraries Used</u></h3>
</div>
<div>
<ol>
<li><a href="http://pi4j.com/" target="_blank">Pi4J</a> - Java bindings which allows interaction with the GPIO pins on the Raspberry Pi. Being Tomcat is the web server, Pi4J was a perfect complement.</li>
<li><a href="https://code.google.com/p/json-simple/" target="_blank">json-simple</a> - Java library which parses and extracts JSON messages.</li>
</ol>
<h3>
<u>Security</u></h3>
</div>
<div>
The application is protected with an implementation of a <a href="http://tomcat.apache.org/tomcat-7.0-doc/realm-howto.html" target="_blank">Realm</a>. This implementation is dubbed "GoogleRealm" and validates Google authorization tokens, as well as validates that the returned email account exists in a local file. When Tomcat handles an HTTP request for a protected resource (defined in web.xml), it calls the overridden authenticate method inside of GoogleRealm method with two Strings. These strings are passed in by the defined implementation of <a href="http://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/Authenticator.html" target="_blank">Authenticator</a>, also defined inside web.xml. An Authenticator's job in the scope of Tomcat is to take a <a href="http://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/connector/Request.html" target="_blank">Request</a> and send the passed credentials to the defined Realm. Making a custom Authenticator allows one to receive credentials from a request by any means. In other words, it abstracts how credentials are retrieved in the request from how they are authenticated.<br />
<br />
In this application, the <a href="http://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/authenticator/BasicAuthenticator.html" target="_blank">BasicAuthenticator</a> is used to retrieve credentials. You may have been able to guess that BasicAuthenticator retrieves the username and password from <a href="http://en.wikipedia.org/wiki/Basic_access_authentication" target="_blank">HTTP basic access authentication</a>. The username field contains the Google authorization token and the password field contains a shared secret among all users. The authorization token is requested with the scope <i>oauth2:https://www.googleapis.com/auth/userinfo.email </i>which, when posted to Google, allows the verifier to view the email address of the account that the authentication token is associated with.<br />
<br />
I originally did not have this shared password in place but I soon realized that there was a security vulnerability in the application. Any service that you authenticate with using your Google account could post its own authorization token to your garage door opener and open your garage. In computer security, this is called the <a href="http://en.wikipedia.org/wiki/Confused_deputy_problem" target="_blank">confused deputy problem</a>. This can be mitigated by requiring an additional secret with all authorized users. With a shared secret, third party sites need an additional piece of information that only authorized users posses.<br />
<br />
Once the user's request is authenticated it is then checked for authorization against a line delineated local file which has a list of email addresses allowed to interact with the application. If that email exists, the proper <a href="http://docs.oracle.com/javase/6/docs/api/java/security/Principal.html" target="_blank">Principal</a> is then added to the request session and passed to servlet routing.<br />
<br />
<h3>
<u>Garage Interface</u></h3>
</div>
<div>
The garage interface and GPIO control was the simplest part of the application, thanks to the Pi4j library. All of the wiring below below, are the pinouts used for application inside of <a href="https://github.com/ryanfx/GarageWebService/blob/master/src/com/blogspot/ryanfx/garage/GarageDoorGPIO.java" target="_blank">GarageDoorGPIO</a>. Note that <a href="http://pi4j.com/faq.html#pin-numbering">Pi4J does not use pin numbers as their identifiers</a>, and instead uses the more abstract method that <a href="https://projects.drogon.net/raspberry-pi/wiringpi/pins/">WiringPi uses</a>.<br />
<br /></div>
<div>
<ul>
<li>Toggling the garage</li>
<ul>
<li>The garage door was fairly straight forward to interact with physically. I had a wall mounted control which toggles the garage door when two wires are shorted together (this is the behavior of most any door).</li>
<li>When this module is activated, the garage is toggled. This module is controlled via the following wires: (<i>Note - make sure you know which revision of the Raspberry Pi you have as their pins have changed!)</i></li>
<ul>
<li>5V - Pin 02 on the Raspberry Pi diagram below (upper right pin) to label G on the relay diagram. This powers the relay coil.</li>
<li>3.3V - Pin 17 (fifth from the bottom, left row) to label F. This provides 3.3V as a signal current to the relay.</li>
<li>0V - Pin 25 to label E. This grounds the 5V supply. Note that the 5V and 0V are isolated via an optocoupler from the 3.3V connection(The schematic can be <a href="http://www.thesunrain.com/Amazon/2%20relay%20board/2-ch%20relay%20module.pdf">found here</a>.)</li>
<li>GPIO - Pin 11 (GPIO 17) to label B. This is going to be configured as an <i>OUTPUT</i> pin, and set <i>LOW</i>, which will activate the relay.</li>
<li>The two top most screw-down relay holes (in the upper left) are what will be connected to each other when the relay triggers. These two wires will need to be run to your garage door in a manufacturer / model dependent fashion.</li>
</ul>
</ul>
</ul>
<div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlk0512KnBfWm9aD-uNrgyJ1jHH2ZtJiOq57BQVQ1W7AQzUi7E7QiFDT3Tz6XzC8wWkqYK3hU2KdaJqy0d0BGomD5-kdEfk5VKtst4t6kj_Mtmr14pFD-hGr5WWio0f8-a21XOluCsumA/s1600/GPIOs.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlk0512KnBfWm9aD-uNrgyJ1jHH2ZtJiOq57BQVQ1W7AQzUi7E7QiFDT3Tz6XzC8wWkqYK3hU2KdaJqy0d0BGomD5-kdEfk5VKtst4t6kj_Mtmr14pFD-hGr5WWio0f8-a21XOluCsumA/s640/GPIOs.png" height="640" width="276" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">From <a href="http://elinux.org/Rpi_Low-level_peripherals">http://elinux.org/Rpi_Low-level_peripherals</a></td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqyO0CMfLxRUkvUZM4LWInES9dvadPsyr0TG8tgIoDXUACxlxMC_XGP56DSYdBvYyw9h2EtjeXT5BKgB19-MJKWq4ARd7NI3Rq44EvB3ruCWBf2yksEDIuCzYRe7mD6YxBDUI5cpiXFyM/s1600/sainsmart.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqyO0CMfLxRUkvUZM4LWInES9dvadPsyr0TG8tgIoDXUACxlxMC_XGP56DSYdBvYyw9h2EtjeXT5BKgB19-MJKWq4ARd7NI3Rq44EvB3ruCWBf2yksEDIuCzYRe7mD6YxBDUI5cpiXFyM/s400/sainsmart.JPG" height="400" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Notated relay board</td></tr>
</tbody></table>
</div>
<ul>
<li>Checking the garage state</li>
<ul>
<li>This was accomplished with the magnetic switch listed above. One half of the switch is connected to the swinging door, the other half is attached to the door frame. In this case half of it was attached to the wall above the garage door, and half of it was attached to the garage door itself. When the garage door is closed, these two halves are within about a 1/4 inch of each other.</li>
<li>Make a wire with an inline 1k ohm resistor (to prevent accidentally blowing out a GPIO pin).</li>
<ul>
<li>3.3V - Connect this wire from Pin 1 on the Raspberry Pi and connect it to one side of the magnetic switch mentioned above (red, or white wire in diagram below)</li>
<li>Connect a wire from the opposite side of the magnetic switch and run it to pin 12 (GPIO 18).</li>
<li>When the door is closed, this circuit should be closed.</li>
</ul>
</ul>
</ul>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRSt0gHZoxHnQKfDBqX35oKd8unENtPlc0lo8pBfGZRnqINzmlqmo7CtAJZeOoePI3_YZZxqR8ft3p6Nm7P-IpPC1_nfaPOLYjkYgWywupf3G4Bw2-KQ0fE3JsxsYQIsEwKMwn70Ie0Vw/s1600/IMG_6477.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRSt0gHZoxHnQKfDBqX35oKd8unENtPlc0lo8pBfGZRnqINzmlqmo7CtAJZeOoePI3_YZZxqR8ft3p6Nm7P-IpPC1_nfaPOLYjkYgWywupf3G4Bw2-KQ0fE3JsxsYQIsEwKMwn70Ie0Vw/s400/IMG_6477.JPG" height="266" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">This is the magnetic switch. The front side (closest in this picture) is attached to the moving door, the rear side is screwed into the wall. When they come within about 1/4 inch of each other, it toggles.<br />
<br />
<br />
<br /></td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG20wGALu8alkupd-1nlDDQPPlJqpAKbiSw3qEhUnyVoOPs_GUdT5dtgXlSAMSP7g8-swJFFpGOrV1Zqa9uEGd_No_hsz2goYM_3IXZqFAYJPHUHShYLj1Pm0UHm96jORh6Yp4MeCLIp8/s1600/garage+wiring.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG20wGALu8alkupd-1nlDDQPPlJqpAKbiSw3qEhUnyVoOPs_GUdT5dtgXlSAMSP7g8-swJFFpGOrV1Zqa9uEGd_No_hsz2goYM_3IXZqFAYJPHUHShYLj1Pm0UHm96jORh6Yp4MeCLIp8/s400/garage+wiring.PNG" height="400" width="266" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Sorry for the mediocre picture... it's mounted on top of the opener.</td></tr>
</tbody></table>
<div>
<br /></div>
<h1>
<u>Android Application</u></h1>
</div>
<div>
<u><br /></u></div>
<div>
<div>
<h3>
<u>Architecture:</u></h3>
</div>
<div>
The architecture of the application is very simple. Clicking an action button in the UI triggers an IntentService to run. These IntentService(s) are run in the background on a worker thread already, so we don't need to worry about spawning off threads on our own. When the Service is completed, it fires off a broadcast. If the main Activity is active at this point, a Toast is generated for the user which states what the result of their action was.<br />
<br /></div>
</div>
<h3>
<u>Overview:</u></h3>
<div>
<u><br /></u></div>
<div>
The controller for this application is written for the Android platform. This could have been a web application but I wanted to use the AccoutManager on Android so the setup was as seamless as possible to any end user (no need to enter account information). The first time a user account is selected and an action button is clicked, an authorization prompt pops up for the user. This allows the application to get a token which can prove the account's identity.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqv-JAwIT6oOjS0reBfMUMShlWWaOzaim3vL_Ry9pyKj8cOUcWUpPUhT9zUx_dBGMANEUgVi4fGB86sjSyas1lImSKcKdD-NCuFrNXECJK0dN14vf1PT5drg1Rxj1nxxgLxq0peG2lSQk/s1600/authorize.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqv-JAwIT6oOjS0reBfMUMShlWWaOzaim3vL_Ry9pyKj8cOUcWUpPUhT9zUx_dBGMANEUgVi4fGB86sjSyas1lImSKcKdD-NCuFrNXECJK0dN14vf1PT5drg1Rxj1nxxgLxq0peG2lSQk/s320/authorize.PNG" height="320" width="275" /></a></div>
<br />
<br />
There are three interaction points in the application that this token is used for:</div>
<div>
<ul>
<li>Toggle the garage (actuate the relay which in turns activates the door)</li>
<li>Close the the garage (toggles the garage if it is not in a closed state)</li>
<li>Display the status of the garage (open / closed)</li>
</ul>
</div>
<div>
<br /></div>
<h3>
<u>
Security:</u></h3>
<div>
The security of the Android application lies in its use of HTTPS. I did not want to create my own domain and pay for a signed TLS certificate, so instead, I made an SSLSocketFactory factory (<a href="https://github.com/ryanfx/GarageAndroid/blob/master/src/com/blogspot/ryanfx/security/GarageSSLSocketFactory.java" target="_blank">GarageSSLSocketFactory</a>). This is described in good detail <a href="http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html" target="_blank">here</a>. What this does is initialize the application's SSLContext to use your own default key store for acceptable certificates. This includes your own self-signed certificates and allows you to have secure communication without the need for paying for a signed certificate, or doing something <a href="http://stackoverflow.com/questions/2642777/trusting-all-certificates-using-httpclient-over-https" target="_blank">really, really, bad</a>. All you need is a dynamic DNS domain, assuming you do not have a reserved WAN IP address.<br />
<br />
<h3>
<b><u>UI:</u></b></h3>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhou9KIRlDQpD7_berUnJM_S0LH_hV8l451W4nu8ye1r568tSpucl1hhNxLnNWZ8aiNGFiuobTwgntQ0AkZSWEMQZSNb7TmRlcKZOyheFKc1eA4baipi_ByVWaRfTIIhWGhSIE1w2UBI5Q/s1600/main.PNG" imageanchor="1" style="display: inline !important; margin-left: auto; margin-right: auto; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhou9KIRlDQpD7_berUnJM_S0LH_hV8l451W4nu8ye1r568tSpucl1hhNxLnNWZ8aiNGFiuobTwgntQ0AkZSWEMQZSNb7TmRlcKZOyheFKc1eA4baipi_ByVWaRfTIIhWGhSIE1w2UBI5Q/s320/main.PNG" height="320" width="275" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Main screen</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdlAd9Hx306uzZNmkaj_kM_NiuDkVN9iDlnEHxiI9xplnIu33QM2f-ljwAPtNjdFFFlpnjAWLJJuHRY27ESOnutZnrsHrQNAxWeQxiVpN1MzsSnJzHvXrifKtlcxZ0yjPrDqogqZpUwyw/s1600/settings.PNG" imageanchor="1" style="display: inline !important; margin-left: auto; margin-right: auto; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdlAd9Hx306uzZNmkaj_kM_NiuDkVN9iDlnEHxiI9xplnIu33QM2f-ljwAPtNjdFFFlpnjAWLJJuHRY27ESOnutZnrsHrQNAxWeQxiVpN1MzsSnJzHvXrifKtlcxZ0yjPrDqogqZpUwyw/s320/settings.PNG" height="320" width="275" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Configuration Screen (accessible by hitting menu button)</td></tr>
</tbody></table>
<br /></div>
<div>
<h1>
<u>Configuration</u></h1>
</div>
<div>
<ol>
<li>Download the <a href="https://github.com/ryanfx/" target="_blank">GarageWebService and GarageAndroid</a> from Github. (If you've downloaded it in the past, make sure you update your repository to fix a classpath error.</li>
</ol>
<ol>
<li>On a spare computer (other than the RPi) install <a href="http://www.eclipse.org/downloads/packages/eclipse-ide-java-developers/keplersr1">Eclipse for Java Developers</a></li>
<ol>
<li>Click Help -> Install new Software</li>
<li>Select Work with Kepler - http://download.eclipse.org/releases/kepler</li>
<ol>
<li>Install Eclipse Java EE Developer Tools, Eclipse Java Web Developer Tools, JST Server Adapters, JST Server Adapters Extensions, then restart Eclipse</li>
</ol>
<li>New->Other->Web->Dynamic Web Project -- Name it GarageWebService</li>
<ol>
<li>Select target runtime if it already exists, or click new runtime if you don't have one.</li>
<li>Click Apache Tomcat v7.0 - Check create new local server</li>
<li>Click download and install (If you don't already have it)</li>
<li>Close eclipse</li>
</ol>
<li>copy src + WebContent from downloaded GarageWebService and override the current src + WebContent in the workspace project (probably {homedir}/workspace/GarageWebService)</li>
<ol>
<li>Reopen eclipse, right click in the navigator pane on the left and click refresh</li>
</ol>
<li>Open GoogleRealm.java and change the password if desired. This password protects your garage door from being used from another service that has some permission on your Google account (such as stackoverflow)</li>
<li>Highlight the files GoogleRealm.java, GoogleUtil.java, and UserDAO.java</li>
<ol>
<li>Right click on one of the highlighted files-> export -> Java -> JAR file and name it GoogleAuth.jar</li>
</ol>
<li></li>
<li>Now right click on the project itself, export -> Web -> war file and name it GarageDoor.war (important the name + case is exactly this)</li>
</ol>
<li>Install the <a href="http://www.raspberrypi.org/downloads">Raspian</a> distribution on your RPi, then enable SSH for terminal access. We do not need a graphical interface</li>
<ol>
<li>Transfer GoogleAuth.war to the Rpi</li>
<li><i>sudo apt-get update and sudo apt-get upgrade</i></li>
<li><i>sudo apt-get install tomcat7 tomcat7-admin</i></li>
<ol>
<li></li>
<li>edit /etc/default/tomcat7 and change the following two variables</li>
<ol>
<li>TOMCAT7_USER=root</li>
<li>JAVA_HOME=/usr/lib/jvm/jdk-7-oracle-armhf</li>
</ol>
</ol>
<li>Change to a directory for downloading files (we will now be installing wiringPi)</li>
<li><i>git clone git://git.drogon.net/wiringPi</i></li>
<ol>
<li><i>cd wiringPi</i></li>
<li><i>git pull origin</i></li>
<li><i>sudo ./build</i></li>
</ol>
<li>Now we'll add ourselves as a valid tomcat user</li>
<ol>
<li><i>sudo nano /etc/tomcat7/tomcat-users.xml</i></li>
<ol>
<li>Add the following line, right above the last line, </tomcat-users></li>
<li><user username="ryanfx" password="asecretpassword" roles="manager-gui"/></li>
<li>Replace ryanfx and asecretpassword with whatever you'd like</li>
</ol>
</ol>
<li>Generating an SSL certificate</li>
<ol>
<li>We will generate a certificate using RSA and name the store garagessl</li>
<ol>
<li><i>keytool -genkey -alias garage -keyalg RSA -keystore garagessl</i></li>
<li>For the question <i style="font-style: italic;">"w</i></li>
<li style="display: inline !important;"><i>hat is your first and last name?" </i></li>
enter the external IP address or dyn-dns name that your RPi will be using eg. www.mydyndnsname.com
<li>Everything else can be blank, but enter y when it confirms that all the information is correct.</li>
<li>Let it generate a new certificate for a few minutes, then hit enter when it asks you for a new password</li>
<li>Change permissions and move it to someplace that tomcat can read it</li>
<ol>
<li><i>sudo chown root:tomcat7 garagessl</i></li>
<li><i>sudo mv garagessl /etc/tomcat7</i></li>
</ol>
</ol>
<li>Configure Tomcat to read the certificate</li>
<ol>
<li>sudo nano /etc/tomcat7/server.xml</li>
<li>Copy the following below the connector element already active running on port 8080, and comment out the one running on port 8080</li>
<br /><Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"<br /> maxThreads="150" scheme="https" secure="true"<br /> clientAuth="false" sslProtocol="TLS" <br /> keystoreFile="/etc/tomcat7/garagessl"<br /> keystorePass="thepasswordyouused" /></ol>
<li>We'll copy the GarageAuth jar to the Java library folder</li>
<ol>
<li><i>sudo mv GoogleAuth.jar /usr/share/java/</i></li>
<li>Find the json simple jar inside the web service package you downloaded and move it as well. We need to do this because security realm's use Tomcat's (Catalina's) classloader, not your webapp's.</li>
<ol>
<li><i>sudo mv json_simple-1.1.jar /usr/share/java/</i></li>
</ol>
<li>Create softlinks so tomcat has access to them</li>
<ol>
<li><i>cd /usr/share/tomcat7/lib/</i></li>
<li><i>sudo ln -s ../../java/GoogleAuth.jar .</i></li>
<li><i>sudo ln -s ../../java/json_simple-1.1.jar .</i></li>
</ol>
</ol>
<li>Add users that will be able to authorize with your new service</li>
<ol>
<li><i>sudo nano /root/garage_users</i></li>
<li>Add a single line to the file, whatever the gmail address is that you will be authenticating with.</li>
</ol>
<li>Restart Tomcat <i>sudo /etc/init.d/tomcat7 restart</i></li>
<li></li>
<li style="display: inline !important;">Open a browser on the Eclipse machine and go to https://192.168.11.30:8443/ replacing the IP address with whatever IP address your Rpi has pulled. </li>
<li style="display: inline !important;">You should get a "certificate untrusted" error. If you've reached this point, everything is good!</li>
<li>Upload the GarageDoor.war to the raspberry pi's Tomcat. In this example, visit https://192.168.11.30:8443/manager/html</li>
<li>Click start to start it</li>
<li>Now we will get the public certificate the server is issuing and store it in PEM format. Replace the IP address to whatever the RPi has.</li>
<ol>
<li><i>echo | openssl s_client -connect 192.168.11.30:8443 2>&1 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > mycert.pem</i></li>
</ol>
<li>You now have the PEM encoded certificate of your server. We will now download bouncy castle jars to generate a keystore (do not download past version 146 - Android will not play nice with anything newer)</li>
<li><i>wget http://www.bouncycastle.org/download/bcprov-jdk15on-146.jar</i></li>
<li>We will now generate the keystore (enter a password when prompted to protect your keystore and enter yes to trust this certificate)</li>
<ol>
<li><i>keytool -import -v -trustcacerts -alias 0 -file <(openssl x509 -in ./mycert.pem) -keystore mystore.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath ./bcprov-jdk15on-146.jar</i></li>
</ol>
<li>Copy mystore.bks to the machine which has eclipse</li>
<li>Open eclipse</li>
<li>Install android ADT (http://developer.android.com/sdk/installing/installing-adt.html)</li>
<li>Import -> Android -> Existing Android Code Into Workspace</li>
<li>Create a new folder called raw inside of the res folder</li>
<li>Move your mystore.bks file into this new folder</li>
<li>Change the password in GarageSSLSocketFactory.java to reflect the password used during the keytool command</li>
<li>Right click the Project -> export -> Android -> Export Android Application</li>
<li>Install the application to your phone</li>
<li>Open the app, go to settings, fill in host / port / account information</li>
<li>Fill in the server password (the one you wrote in GoogleRealm.java)</li>
<li><b>You're done!</b></li>
</ol>
</ol>
</ol>
</div>
Unknownnoreply@blogger.com122tag:blogger.com,1999:blog-8140507583511353121.post-79631795048931077222013-06-09T16:45:00.003-04:002013-06-16T01:19:25.526-04:00Personal GadgetryIf you're an engineer, you frequently want to do many things just a <i>little</i> bit differently than others... just because you can. Your side projects are generally overly complex and accomplish what others perceive as minuscule, but that doesn't stop you! This blog will contain those types of completed projects.Unknownnoreply@blogger.com0