Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Wednesday, November 22, 2017

Arduino Project One: The Arduino program takes shape

Introduction

This week, I created the skeleton of the program for the Arduino stack. I'm not ready to share my source code yet. Let me get the rest of the meat on the skeleton first.

Security

I listed some ideas for my cybersecurity scheme last week. I have incorporated all of the measure I listed into my program. I'm sure there's a hacker out there somewhere who will figure it out. My description here isn't meant as a challenge to them. It's just to inform you of some simple things that worked for me.
  1. I've chosen a port number, out of the 65,535 available, that's easy to remember.
  2. The server will only accept client requests from specified devices, and not from the world at large. Although MAC address spoofing is a thing, this will stop all but the most determined hackers.
  3. The server will use TCP instead of HTTP, trading long and legible transactions for short and incomprehensible ones.
  4. The router autoforward will be tweaked so that only TCP requests via the specified port can get through to the Arduino.
  5. The server uses a challenge-and-response mechanism, like two spies swapping passwords. When a socket is opened and the client's authorization is verified, the server sends the client a randomly-generated numeric sequence. The client must reply with the proper numeric sequence. I intend to keep the details of this algorithm proprietary. Sorry, folks.
  6. It may be necessary to have the server go through the challenge-and-response several times in the life of a connection.

Robustness and Reliability

The terms "robust" and "reliable" are not synonymous. "Reliable" means that the system will not fail during regular operation as a result of stupidity — my stupidity, to be specific. "Robust" means that the system can recover from power failures and loss of Wifi signal all by itself, without any human intervention.

When the Arduino is first powered up, or when it recovers from a power failure, it looks through its list of available Wifi routers and tries each one in turn, until it gets a connection. If it doesn't get a connection at all, then it sets a timer for 10 minutes and tries again. This is because it can take DSL modems and Wifi routers a while to recover from a power failure too, so if it doesn't catch one the first time, it gives it time to reboot.

After it gets a Wifi connection, it sets up a permanent TCP socket to listen for client requests. Although client requests are the whole reason for its existence, they're not very frequent, so it will spend most of its time being idle.

Every 10 minutes or so, it will ping the Wifi router, to verify that it still has the connection. If the ping fails, then the Arduino has lost the connection, so it goes through the power-up sequence again.

When a client requests a connection, the Arduino opens a temporary TCP socket for that client. It will be up to the client to send a TCP query every second or so, unless it's sending a button-push command. It's up to the client, whether it's a webpage or an Android app, to politely say goodbye and close the socket when it exits. (I'm sure that Corona SDK and JavaScript include onExit() event servers, or something similar.)

But it's possible for the remote client to just drop the connection - battery dies, phone gets run over, computer blue-screens, that sort of thing. So the Arduino will set a watchdog timer when it opens the temporary socket. Any query from the client resets the watchdog timer (that's called "kicking the watchdog" in Embedded Programming Land). If the client doesn't send a query for a long time, the watchdog timer expires, the Arduino says goodbye to the client in case the client is listening, and then the Arduino closes the socket.

TCP/IP

I haven't decided whether to allow multiple clients yet. Normally, only my wife and I will be using the app, and very seldom at the same time. It would be crazily rare to have three people trying to control the garage door at once. Still, it would be annoying for one person to open the app on their phone, and the other person try to open it on theirs, and get the equivalent of a busy signal. So I'll probably have to allow multiple clients.

I haven't put in the actual TCP/IP commands yet. That's for later. 

Sensor and Actuator

I haven't wired up the Hall effect sensor, and I haven't written any code for it. And although I haven't actually connected the relay to the garage door opener yet, I have written the relay code, and I've verified that the relay shield plays nicely with the ESP8266 shield.

What's Next

I'll stick with this program until it's finished. Then I'll need to write a server in plain vanilla C, or maybe Python, to test it. Once the program is finished and it works, I'll post the source code.


To read the other postings about this project, click here and scroll to the end.

Saturday, November 11, 2017

Arduino Project One: Corona hits a roadblock

This project has many different facets, and a lot of new things to learn. Development is definitely not linear. It can go in many different directions simultaneously — and that's a good thing, because some of those different directions run into roadblocks.

The Corona Roadblock

For example, there's nothing that says I have to have the webserver running on the Arduino stack before I start working on the Android app. With that in mind, I concentrated on learning Corona this week. Since I once ran a game programming company, I'm familiar with this genre of software. So it seemed like a safe and comfortable place to go.

I downloaded the Corona SDK and worked through the Getting Started tutorial. The last step was to do a live build, installing a development version of your app on your Android device.

Sadly, it was not to be. When I selected File > Build > Android from the Corona Simulator, I got this error message:
Stupid error message.


I selected Yes, and I ended up downloading and installing Java SE Development Kit 9.0.1 for Windows, 64-bit. (It doesn't give you much choice.) After it was installed, I ran Corona and selected File > Build > Android again. Same error message.

I went to the Corona community forums and found this recent thread, which says that Corona SDK 2017.3135 doesn't support the 64-bit JDK. But a fix is coming, and in the meantime, the awesome Corona staff posted a link to the older, 32-bit, Java SE Development Kit 8u151. The word on the Web is that multiple JDKs can exist on my computer at once, so I'll leave 9.0.1 installed.

Corona's not the only game in town. But I'm comfortable with it, with my gaming background. My son has used it successfully and speaks highly of it. And I really don't feel like downloading, installing, and learning yet another development kit. I already have enough new tools to learn. But I went ahead, and downloaded and installed 8u151.

It works! Back in Corona, File > Build > Android built a .apk file for me.

Then I needed to practice installing it on my phone. The Corona Signing and Building page says that if I don't have the Android SDK installed, I can upload the .apk file to a webserver, then download it to my phone, go to the Downloads directory, and simply tap on the .apk file to install it. However, the Signing and Building page also says that I can use the adp install command to install the .apk file directly.

Two problems arose. First, the debug version of the app was so big that it exceeded (what was left of) my daily limit on my webserver, so detouring through the webserver was out of the question for the day. Second, adb is the Android Debug Bridge, which is part of the official Android SDK, and I inferred from the Corona documentation that adb is rather important.

So even though I didn't want to "download, install and learn yet another development kit," that's exactly what I did. First, I mistakenly downloaded and installed the Android Studio IDE. If adb was part of Android Studio IDE, it was hidden very well. I couldn't find it. Then I looked on the Corona debugging page, and it gave some clues on how to download the command-line-only Android SDK tools. That was a relief — if I had to download the entire Android Studio IDE, why was I even bothering with Corona? So I happily uninstalled Android Studio IDE.

According to the debugging page, I needed to install at least the Android SDK Tools (I had to scroll down to the bottom of the page to find them) and Android SDK Platform Tools. It took some sleuthing to find those links. The adb tool is in the Platform Tools, so I had to make sure I had that one.

I unzipped the downloaded files and stored them in C:\Program Files\Android\sdk-tools, in the subdirectories tools and platform-tools.

For a test, I tried installing the StarExplorer app from the Corona SDK "Getting Started" tutorial. It took a couple of tries to execute the adb install command:
C:\Program Files\Android\sdk-tools\platform-tools>adb install -r "\Users\Ray\Documents\Corona Built Apps\StarExplorer.apk"\Users\Ray\Documents\Corona Built Apps...d. 2.8 MB/s (27069109 bytes in 9.069s)        pkg: /data/local/tmp/StarExplorer.apkSuccess
C:\Program Files\Android\sdk-tools\platform-tools>
Finally it was successful - but then I couldn't find the app on the phone. I looked in the Apps pages, but StarExplorer wasn't there. Then I looked for the /data/local/tmp directory using the My Files app and I couldn't find it.

It turned out that I was being impatient. It just took a while for the phone to update its files. After about 20 minutes, I went back to the Apps pages and I found it. The app ran perfectly on my phone.

To make it a little easier the next time I install an app, I added the paths C:\Program Files\Android\sdk-tools\tools\bin and C:\Program Files\Android\sdk-tools\platform-tools to my PATH environmental variable. Now I don't have to type in adb's entire pathname to run it.

So even though it was a real trip down the rabbit hole, collecting and installing all the tools to build and install the app on the phone, it finally worked.

Corona Does Networking!

On the bright side, I did find out this week that Corona has a network library. Reading the API documentation and looking at some examples, I'd say that this will do the trick nicely. 

So What's Next?

Now I can write the app. Once it's completed, I'll go back to the Arduino. I have to do the following:
  1. get the relay clicking
  2. try out those Hall effect sensors
  3. write the webserver and exercise it from my home network
  4. get my DSL modem / Wifi router to passthrough HTTP requests to the Arduino webserver.
  5. exercise the Arduino webserver from outside my home network

What about Internet privacy?

One thing that I haven't thought about until now: I need to research privacy / security measures for the Arduino webserver. I don't want the whole world to know when my garage door is up or down, and I definitely don't want strangers activating it. Moreover, I don't want someone in Uzbekistan hijacking my Android, turning it into a bot, and using it to mount a DDoS attack on an embassy somewhere.


To read the other postings about this project, click here and scroll to the end.