Lately, I've been seeing a lot of "mobile tags" crop up in advertisements. Mobile tags are small, square two-dimensional barcodes that you can scan with the camera on your smartphone, and they work very much like links on a web page—except that they're in printed ads. You point your phone at the barcode, and the phone opens up a browser window to the site. Brilliant!
After I learned about the mobile tag, the next question in my mind was, "What type of barcode is that?" Followed immediately by, "How can I make it from RPG?" In this article, I show you how to use Google Charts to generate a Quick Response (QR) code mobile tag from RPG.
Barcode technology has provided a way of sending data from a hard copy to software for a long time now. So what's new and exciting about mobile tagging? The main thing (in my mind, at least) is the ubiquity. It seems that everywhere I look, I see someone with a smartphone. Because smartphones can be barcode scanners, that means that millions of people are walking around with barcode scanners in their pockets!
Mobile tagging is already being used for advertisements. For example, if you're sitting on the subway reading an advertisement, and you want to know more, you can scan the mobile tag on the advertisement, and it takes you to a website where you can read more about it.
The same technology can be used on products. Indeed, it already is! You can scan a mobile tag (or, with some apps, even a UPC/EAN code) and learn more about a product you have at home or see on a shelf in a store. Some apps give you a price comparison at nearby stores and even reviews of a product. I was at the store looking at Ethernet network switches. I didn't know which one to buy, so I scanned its UPC code. My phone showed reviews for the product, and I decided on another model!
What next? Newspapers and magazines could put mobile tags on articles. You could scan the tag to get expanded online content on your phone. There are all kinds of possibilities.
At the moment, the most popular type of mobile tag seems to be the QR code. From what I've read, it's the dominant type of mobile tag in Japan, the Netherlands, and South Korea. The same article tells me that there are several competing standards in the U.S., where I live—but, so far, the QR code is the only one I've seen in use.
A QR code barcode is not limited to a simple hyperlink. It can store as much as 4297 bytes of alphanumeric data. Mobile phone software reads the data from the barcode and looks for a hyperlink in the data. It displays the data to the user and lets the user open the hyperlink in a browser. The interface to do this is different depending on the application.
The Android operating system supports QR codes natively in its Google Goggles application, but there are other apps available. On the iPhone, you need to install a QR code reader, but there are more than 50 available, including many free ones in the App Store.
In searching for a free and simple way to generate QR codes, I stumbled upon Google Charts. Google offers many free web-based APIs, and Charts is one of them. It's designed for generating graphs and charts (e.g., pie charts, bar charts, and line charts). I was rather surprised to see that it also offers the ability to generate QR codes. For example, try opening the following link in your browser:
That link should show you a QR code mobile tag. Congratulations, you just generated your own QR code in your browser. Here are the parts of the URL:
- cht = chart type. cht=qr means that I want a QR code.
- chs = chart size. chs=200x200 means that the output should be a 200 pixel square image.
- chof = chart output format. PNG is Portable Network Graphics, an image format supported by all major browsers.
- chl = the data that should be encoded in the QR code. Any characters that have a special meaning must be escaped (URL encoded) so that you don't confuse the browser.
The preceding example shows how to use an HTTP GET request from your browser to create a QR code tag. The GET method of HTTP is the default HTTP method, but it suffers an annoying drawback; all the parameters to the API must be encoded into the URL, and the maximum length of a URL is limited. In some browsers, URLs may be forced to 1500 bytes or less! Even if your browser supports longer values, Google limits GET requests to 2000 bytes.
Fortunately, the Google Chart API also supports the HTTP POST method. POST lets you send an unlimited amount of data, but it's not quite as simple to use directly from your browser. If you'd like to try it, you could create an HTML document like this:
<form action="http://chart.apis.google.com/chart" method="post">
<input type="hidden" name="cht" value="qr" />
<input type="hidden" name="chs" value="200x200" />
<input type="hidden" name="chof" value="png" />
<input type="text" name="chl" maxlength="4296" size="100"
value="Type data to go in QR code here." />
<input type="submit" value=" Ok " />
Save this data (a simple text editor like Notepad will do) to a file named test.html on your desktop, and then open that with your browser. You get a form, and when you submit it, it provides a QR code tag. Notice that this form contains the same variables as the link I showed above. But the form uses the POST method, so it lets you use the full 4296 characters allowed in a QR code tag.
Calling the Google Chart API from RPG
Using the Open Source HTTPAPI tool makes it easy to do the same HTTP POST request from an RPG program. In my RPG code, I need to create an equivalent to the HTML form I showed above.
D VARPREF c 2
D form s like(WEBFORM)
D data s 4296a varying
data = 'Type data to go in QR code here.';
form = WEBFORM_open();
WEBFORM_setVar(form: 'chs' : '200x200');
WEBFORM_setVar(form: 'cht' : 'qr' );
WEBFORM_setVar(form: 'chof': 'png' );
WEBFORM_setPtr(form: 'chl' : %addr(data)+VARPREF: %len(data));
Hopefully, you can see how this correlates to the HTML form, above. But in this case, it's building the encoded form in an RPG program, using routines in the HTTPAPI service program. WEBFORM_open() reserves a spot in memory to store a new form. WEBFORM_setVar() sets one of the variables in the form.
Sadly WEBFORM_setVar() is limited to 256A of data. In 2001, when I created HTTPAPI, it seemed like a reasonable size. Now, I wish I had made it larger! Fortunately, I provided a workaround, WEBFORM_setPtr() sets the value of the form field using a pointer and can be millions of bytes long. I used WEBFORM_setPtr() for the chl field because it can be 4296 characters long.
You may be wondering why I added VARPREF (which has a constant value of 2) to the %addr() of the data variable. The reason is simple: The data variable is defined as varying. In RPG, a varying variable stores its length in the first 2 bytes (or 4 bytes if the variable is longer than 65535). By adding 2 to the address, I skip those length bytes and get only the data. If you're compiling to the IBM i 6.1 target release or higher, you can use %addr(data: *DATA) instead of adding 2.
The result of this is that HTTPAPI creates a web form, compatible with the one created by the browser by using HTML tags. This is done in dynamic memory inside the HTTPAPI service program, but I can call the WEBFORM_postData() routine to retrieve the memory location and length of the encoded data.
D enc_data_len s 10i 0
WEBFORM_postData(form: enc_data: enc_data_len );
rc = http_url_post( 'http://chart.apis.google.com/chart'
: '/tmp/result.png' );
The preceding code retrieves the encoded form data and sends it (using the POST method) to the Google Charts URL. The resulting PNG image file is written to the IFS in the /tmp/result.png directory.
Now that I've generated the QR code mobile tag and downloaded it to my IFS, I can include it in an HTML page (perhaps generated by CGIDEV2?) that my user will print out. Or, I can copy/paste it into a Word document.
The great thing about doing this in RPG is that I easily feed data from my existing business logic. Perhaps I'm printing flyers for my business, and they will have QR code in them that varies, depending on the current promotion. If all that promotion data is stored in a database, I can read it in RPG and generate the QR code.
exec SQL declare C1 cursor for
select promo_id from PROMOS;
exec SQL open C1;
exec SQL fetch next from C1 into :PromoCode;
data = 'http://example.com?promo=' + PromoCode;
<i><b>... insert form & http_url_post logic here ...</b></i>
exec SQL fetch next from C1 into :PromoCode;
exec SQL close C1;
At the moment, this type of coding is really still in its infancy. It's hard to imagine all the wonderful uses this might eventually have if the concept catches on. For now, I'm having fun experimenting!
The code in this article requires the HTTPAPI Open Source Toolkit so your program can use HTTP to connect to Google.