I had 10 minutes of fun today learning how to program a barcode scanner. Specifically a "DS9208-1D" which is an omni-directional scanner that is available under numerous brands (we've got a Symbol branded version but Moterola also sell the same device).
Out of the box this scanner doesn't send a carriage return after sending the scanned data. After a seemingly unnecessary amount of Googling I finally found a manual which explains how to do this.
You'll need to print the following pages from the manual:
Page 71 "Prefix/Suffix Values"
Page 72 "Scan Data Transmission Format"
Pages 245 + 246 "Numeric Bar Codes"
Or just print this blog post out.
Start off with page 71 and scan the barcode Scan Suffix 1 (data value 06h). This will put the scanner into a mode which allows for scanning a four digit code which represents a character (or combination of characters).
Appendix E of the manual lists all of these codes and you'll find that 6058 represents "Enter".
Next scan each of the barcodes that represent 6, 0, 5 and 8. You'll hear a confirmation beep that doesn't sound like a normal scan beep.
Finally from page 72 scan the barcode entitled <DATA><SUFFIX 1> (data value 01h).
Open a text editor and do a quick test scan of any barcode and you should see the cursor move to the next line after scanning.
It's been a very long time since I've posted here; 2015 turned out to be an insanely busy year.
SnapCam, the app I've been involved with since late 2014 launched in June. Working on SnapCam has been great fun; I've gotten to work on some really interesting problems and learnt a lot about the world of printing and app development. I've also had the opportunity to build some cool IoT tech with Raspberry PIs and learn an arcane printer programming language (ZPL).
My day job has pretty much taken up all of my time over the past year which in many ways has been incredible for learning and I'm incredibly fortunate to be in a position to have worked on a platform to support an app used by an audience many times larger than I've ever had before.
This year I'm setting some resolutions to try and ensure that I achieve some of the things I've wanted to do for a while:
Blog more; 2015 featured just 3 posts compared to over sixty in 2013.
First create a new Ubuntu server - I've used a $5/month 512mb box but if you're going to use Jenkins for multiple production projects I recommend you use a server with at least 2gb of RAM to keep your builds speedy.
Once the server has powered up then SSH in. We're going to need a few tools installed:
Jenkins runs on port 8080 by default so we're going to setup an Nginx proxy which listens on port 80 and proxies to Jenkins. We'll also point a subdomain at it.
With my DNS provider I setup an DNS A record for jenkins.alexbilbie.com pointing at the IP address of my server.
Next I updated /etc/nginx/sites-enabled/default with the following setup:
Back in Jenkins click on Manage Jenkins then Configure Global Security. Check the Enable security checkbox.
Under Security Realm click on Github Authentication Plugin.
I used the following settings:
GitHub Web URI: https://github.com
GitHub API URI: https://api.github.com
Client ID: (the client ID that Github gave you for your application)
Client Secret: (the client secret that Github gave you for your application)
Under Authorization choose Github Commiter Authorization Strategy.
Update the following:
Admin User Names: (your Github username)
Enable Grant READ permissions for /github-webhook (so that Github can ping your Jenkins install)
Click Save. You'll now be sent to Github to sign-in:
We need to install Composer so whilst SSH-d into the server run the following (as root):
curl -sS https://getcomposer.org/installer | php
mv composer.phar composer
By installing Composer as the jenkins user we can keep it updated easily with Jenkins itself.
Create an SSH key for Jenkins
Jenkins needs an SSH key in order to commit back to Github (if that's what you want). There are two options here, either create a new Github user or add a deploy key to the repository. For this tutorial I'm going to add a deploy key.
As the Jenkins user run the following - ssh-keygen -t rsa -C "jenkins". I opted to not create a password for the key.
Copy the public key (~/.ssh/id_rsa.pub) to your clipboard and add it as a deploy key in your Github repository:
Next let Jenkins know about the private key. Click on Credentials then Global credentials (unrestricted) then Add Credentials.
Choose SSH Username with private key, add a username (I used jenkins) and add the private key (~/.ssh/id_rsa). Click OK.
Add your first job
Click New Item, add Proton as the project name then choose Freestyle project.
Setup the project like so (click on the images for a larger view):
In the project screen you can now click Build Now. If you've copied my config as above you can see in the output for the project that Jenkins will do the following:
Set up a new project workspace
Clone the repository
Run /var/lib/jenkins/bin/composer up
Write the message Finished: SUCCESS
To get Github to automatically trigger a build when a change is pushed go into the repository Settings, then Webhooks and Services, choose then Jenkins (Github plugin) service.
I set the Jenkins hook URL to https://jenkins.alexbilbie.com/github-webhook/.
Now when I push a commit to the develop branch Github will ping Jenkins and automatically trigger a build.
Now that you've got a successful build you can make use of some Jenkins plugins to make Jenkins more useful.
If you want to visualise PHPUnit code coverage then the Clover PHP will ingest a clover.xml file created by PHPUnit and create a graph on the job home page. You can also use it to ensure a minimum amount of coverage or the project will be marked as unstable or even fail the build.
Other plugins that create graphs and logs from PHPUnit and other QA tools include:
Checkstyle (for processing PHP_CodeSniffer logfiles in Checkstyle format)
Crap4J (for processing PHPUnit's Crap4J XML logfile)
DRY (for processing phpcpd logfiles in PMD-CPD format)
JDepend (for processing PHP_Depend logfiles in JDepend format)
xUnit (for processing PHPUnit's JUnit XML logfile)
The HTML Publisher allows you to keep HTML reports generated by your tests and link to them from a job page.
The AnsiColor plugin adds support for ANSI escape sequences, including color, to the build output.
You can report build statuses back to Hipchat, Slack and IRC with respective plugins.
This plugin allows you to run tasks like shell scripts after builds finish - I use it to stop Docker containers that I've used in my builds.
The S3 publisher plugin will create an archive from a successful build and push it to Jenkins (which you could then automatically pull on to you servers to deploy new code).
One of my favourite plugins is the Big Monitor plugin which I have running on a TV (projected from a spare Mac Mini using a Chromecast). This is opposite my desk in the office and I can see all of my jobs and their current status (which of course are always green...).
Jenkins can execute shell scripts as part of build jobs so you can use this to perform pretty much any task you want, from starting Docker containers, keeping Composer up to date (I have a job dedicated to this that runs once a week), API testing, or just about anything else that you manually do on the command line.
There are plugins to automatically build pull requests and you can set up upstream and downstream jobs that are run before and after other jobs.
I use these extensively so when I push to the develop branch of one of my projects I have certain tests run which when they pass automatically merge develop into master. I then have another job which listens to master which then has other tests run and packages up the code into an archive on S3 on success. I then have a final job that is triggered to run an Ansible task to deploy the code on S3 onto all my servers.
One word of advice, once you've got a working Jenkins setup try to keep it that way; I've been burnt numerous times by plugin updates that have broken or significantly slowed down my builds. If that happens you can easily downgrade a plugin inside the plugin manager.
Hopefully you've learnt from this tutorial just how easy it is to get setup and running with Jenkins and I'm sure like me in time you'll find it to be an invaluable part of your development stack.
I'm a little late to writing about this but as reported by Antonio Sanso on his blog he found yet another flaw in well known identity providers' OAuth 2.0 implementations.
The specifics of the attack are the same as the last flaw that was found with Facebook's implementation that I wrote about a while ago; namely that vendors aren't being strict about whitelisting redirect URIs for the authorization (and likely implicit) grant routes.
Antonio discovered that if you registered a client with one redirect URI but crafted a OAuth authorizw URL with a different redirect_uri parameter then vendors were sending the user to the invalid (and non-whitelisted) redirect URI.
In these examples www.attacker.com is the non-whitelisted redirect URI:
Sometime this week I came across a series of blog posts by the taxi company Hailo about how their architecture has changed over time from a simple PHP/Java API to a global infrastructure with over 150 services powering their consumer and operational apps.
I've been very slowly orientating my stack at work (more on that soon) to be made up of a number of discrete services, but since reading the posts above I've become a little bit obsessed with understanding at an even deeper level how to properly build and orchestrate a whole raft of services to power our mobile apps.
At this point I've come to two conclusions. First what I've made works really well so far and I don't want to disrupt that unnecessarily. Also any further splitting out of application functions into individual services needs to be done at a rate which is manageable for the resources we have available at the time and also carefully because we're about to launch our newest app into production.
My second conclusion is I really want and need to add another language to my toolbelt. I've worked with PHP for years now; I'm fast and effective with it but my frustration with the direction of the language vs what I want from it (namely strict scalar type hints and types), it's lacklustre ability to run long running processes and poor concurrency support mean it's starting to work against my needs. I've been playing on and off with other languages and Go and has really captured my imagination so my challenge now is to find the time to learn as much as I can about Go and if I'm confident with this new approach then appropriately introduce it into our stack.