Saturday, December 27, 2014

Telegram (CLI) on Raspberry Pi

This post (in German) explains how to build Telegram Command Line Interface (CLI) client. I confirmed that those steps also works in my Raspberry Pi type B board, minus the Lua component. I had to disable Lua because I cannot get it to compile in my Raspberry Pi (running Raspbian). The compilation always failed because it doesn't have enough space in /tmp for the intermediate compilation result. Well, I don't have any need for Lua either.

Now, let's get down to the details. These are the steps (I'll repeat the steps in the linked article above for completeness sake):
  1. In order to make sure you have enough /tmp for the compilation, you can enlarge your /tmp as explained in this post (basically edit /etc/fstab and unmount, remount /tmp or reboot your Raspberry Pi to be sure).
  2. Install the needed libraries in your Raspbian:
    sudo apt-get install libreadline-dev libconfig-dev libssl-dev libevent-dev
    
    I leave all Lua-related stuff out because we don't need it.
  3. Next, let's clone Telegram CLI from github:
    [your_home_dir]: git clone --recursive https://github.com/vysheng/tg.git && cd tg
    
  4. Now, let's make a build directory in order not to clutter the source code with intermediate object files there.
    [your_home_dir]/tg: mkdir build && cd build
    
  5. Now carry out the compilation there. Remember to disable lua:
    [your_home_dir]/tg/build: ../configure --disable-liblua
    [your_home_dir]/tg/build: make
    
    Grab yourself some coffee to wait for the compilation to complete.
Once the compilation complete, you'll have Telegram CLI executable (named telegram-cli) in the tg/build/bin directory. Now, you can start using it. Just a hint: to end your telegram-cli session, type:
 /exit
In the current telegram-cli session. You can just type "/" then "TAB" to see the options available to you. It also confuse me how to quit when I first uses Telegram CLI ;-)

Thursday, May 29, 2014

Batch Encoding mp4 Videos to Wav (Audio CD format) in Windows

At times, you want to listen to your favorite tunes while driving in congested roads or for extended period of time between cities. The problem is, your car's audio only support Audio CD. This dictates you to convert your favorite tunes to Audio CD. Moreover, you don't have enough time to convert them one by one. Enter the "batch encoding" realm..
Simply put, batch encoding is the process of encoding multiple files in one go. To do that, we use shell script, or batch file in Windows. Because most of my favorite tunes are mp4 videos, my batch encoding script converts those mp4s into wav files. I used VLC to carry out the encoding and I'm using a powershell script to automate the encoding into batch encoding. This is the powershell script that I use:
$outputExtension = ".wav"
$bitrate = 128
$channels = 2

foreach($inputFile in get-childitem -Filter *.mp4)
{ 
  $outputFileName = [System.IO.Path]::GetFileNameWithoutExtension($inputFile.FullName) + $outputExtension;
  $outputFileName = [System.IO.Path]::Combine($inputFile.DirectoryName, $outputFileName);
  
  echo "Output filename: $outputFileName" 
    
  $programFiles = ${env:ProgramFiles(x86)};
  echo "Program Files: $programFiles"
  
  if($programFiles -eq $null) { $programFiles = $env:ProgramFiles; }
  
  $processName = $programFiles + "\VideoLAN\VLC\vlc.exe"
  echo "processName: $processName"
  
  $processArgs = "-I dummy -vvv `"$($inputFile.FullName)`" --sout=#transcode{acodec=`"s16l`",ab=`"$bitrate`",`"channels=$channels`"}:standard{access=`"file`",mux=`"wav`",dst=`"$outputFileName`"} vlc://quit"

  echo "processArgs: $processArgs"
  
  start-process $processName $processArgs -wait

  }
It's not that complicated. It's a slightly modified script from VLC wiki (https://wiki.videolan.org/How_to_Batch_Encode/). There was one hiccup though because by default poweshell doesn't permit script execution. Therefore, I have to run powershell as administrator and then modify the execution policy to unrestricted like so:
Windows PowerShell
Copyright (C) 2013 Microsoft Corporation. All rights reserved.

PS C:\Users\zzz> Set-ExecutionPolicy Unrestricted
Anyway, the powershell script above assumes that you placed all of the mp4 in the current directory (directory where the powershell script located). The batch encoding result will be located in the current directory as well.
Now, to create audio CD, you'll need the application to burn the wav files into audio CD. I'm using cdrecord in Linux to do this because for some reason, the only machine with CD/DVD writer that I have is running Linux. You can use your favorite CD authoring application to do this.

Happy Encoding!

Tuesday, May 20, 2014

AS400 Programming Tutorial

After searching the web for sometime on AS400 RPG-ILE tutorial, I found the most newbie friendly tutorial over at: http://www.letsas400.com/ile_rpg_iv/index.php. RPG-ILE is also known as RPG IV or RPG400. I'm not yet quite familiar with the AS400 hardware but it seems it's a Power machine. The OS400 on the other hand is a specific OS developed by IBM for the AS400 hardware.

IBM provides a more comprehensive tutorial in the ILE RPG Programmer's Guide. However, to save time, I prefer to read an overview on the language itself and the tutorial in the link above is just what I need to bootstrap learning the ILE RPG. I hope this post is of some use for those starting with ILE RPG on IBM Series i machines, like me. Happy coding :)

Monday, May 12, 2014

Preventing Pointer Aliasing in C (for Scientific Computing Optimization Purposes)

The issue of pointer aliasing in C for those working with Scientific Computing code is probably a familiar issue. Pointer aliasing happens when more than one pointer refers to the same or overlapping memory region. This hurts performance in Scientific Computing code written in C. Pointer aliasing is probably the biggest issue which hurts performance of Scientific Computing code written in C compared to those written in Fortran. However, as of C99 standard, pointer aliasing can be "disabled" via the __restrict__ keyword. Most mainline C/C++ compilers supports this keyword. These are the relevant links for various mainline compilers/toolchains:

Sunday, May 11, 2014

Raspberry Pi 3G-Ethernet Router

In this post, I'm going to explain a DIY 3G-ethernet router based on Raspberry Pi. The configuration of this DIY "router" is simple:

Internet <--> USB 3G modem <-->powered USB hub <--> Raspberry Pi <--> Ethernet <--> user machine (PC/Laptop)

The purpose of this kind of router varied, depending on your needs. However, I have a very specific need in one of my setup where providing Internet connection directly from the 3G modem is not possible and only Ethernet interface can be used by the user (physical/virtual) machine.

These are what you need:
  1. A Raspberry Pi (I'm using the B revision), with Raspbian distro.
  2. A powered USB hub. This is required because most USB 3G modems are power hungry and cannot be operated reliably only via the USB connector on the Pi.
  3. A USB 3G modem. Use whatever you have, hopefully Raspbian kernel already support it. I'm using Huawei E153 USB modem which is rather not so friendly in terms of operation in Raspbian, but it works reliably nonetheless, once you know how to "switch" it into modem "mode".
  4. Ethernet cable.
  5. A user machine to test the interconnection.
  6. Internet/data plan subscription to your mobile operator or whatever works for you.
Let's start with installing the software needed for the USB 3G modem to work on Raspbian. I'm basically using the steps mentioned at The Fan Club, but modify them a bit because I'm not using wvdial. These are my modified steps:
  1. Update your Raspbian with "sudo apt-get update"
  2. Install the needed packages with "sudo apt-get install ppp usb-modeswitch"
  3. Configure the pppd configuration file according to your needs.
Now, the software installation steps to setup the DHCP server and Network Address Translation (NAT) are mostly similar to the one at Adafruit: https://learn.adafruit.com/setting-up-a-raspberry-pi-as-a-wifi-access-point/install-software, except that you should remember that the "outgoing" interface in our case is eth0, instead of wlan0 and the "incoming" interface is ppp0 instead of eth0. Therefore, I believe you can adjust the steps accordingly. Also, I found that Adafruit step to make the NAT setting permanent is not working for me. I have to modify the configuration line in /etc/network/interfaces to:

pre-up iptables-restore < /etc/iptables.ipv4.nat

instead of the one explained by Adafruit to make the NAT work permanently across reboots and shutdowns.

The next step is to connect to the Internet. These are my steps:
  1. Power on the Raspberry Pi.
  2. Unplug the 3G USB modem from the USB hub, and then plug it back again if it's previously plugged in before Raspberry Pi finished booting. This is a compatibility hack because sometimes it is required, and sometimes not.
  3. Wait until the 3G USB modem is recognized (watch syslog, i.e. tail -f /var/log/messages)
  4. Run usb_modeswitch on the modem
  5. Run pppd
  6. Watch syslog to find out whether the data connection succeeded or not, i.e. tail -f /var/log/messages 
  7. Test the connection with your user machine connected through Raspberry Pi Ethernet.
Note that step 1 to 5 must be carried out exactly as mentioned above, otherwise pppd will always fail to initialize data connection with pppd. I'm not so sure what causes it, but it seems that the modem cannot respond to the AT command(s) sent by pppd correctly, at least the command to establish data connection. I saw that through syslog.

I also run a DHCP server in my Raspberry Pi, the isc-dhcp server. The configuration files for isc-dhcp are /etc/init.d/isc-dhcp-server, /etc/default/isc-dhcp-server and /etc/dhcp/dhcpd.conf. You only need to deal with the last two config files. /etc/default/isc-dhcp-server determines which network interface(s) used to listen for DHCP client requests. /etc/dhcp/dhcpd.conf determines the network configuration, such as the IP addresses to assign to the client, DNS servers, gateway, etc. Let's have a look at my configuration files.
This is how my /etc/default/isc-dhcp-server looks like.

# Defaults for isc-dhcp-server initscript
# sourced by /etc/init.d/isc-dhcp-server
# installed at /etc/default/isc-dhcp-server by the maintainer scripts

#
# This is a POSIX shell fragment
#

# Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf).
DHCPD_CONF=/etc/dhcp/dhcpd.conf

# Path to dhcpd's PID file (default: /var/run/dhcpd.pid).
#DHCPD_PID=/var/run/dhcpd.pid

# Additional options to start dhcpd with.
#       Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead
#OPTIONS=""

# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
#       Separate multiple interfaces with spaces, e.g. "eth0 eth1".
INTERFACES="eth0"
As you can see, isc-dhcp listens to client on the ethernet interface and the dhcpd configuration file to use is set to /etc/dhcp/dhcpd.conf. Now, let's have a look at /etc/dhcp/dhcpd.conf.
#
# Sample configuration file for ISC dhcpd for Debian
#
#

# The ddns-updates-style parameter controls whether or not the server will
# attempt to do a DNS update when a lease is confirmed. We default to the
# behavior of the version 2 packages ('none', since DHCP v2 didn't
# have support for DDNS.)
ddns-update-style none;

# option definitions common to all supported networks...
#option domain-name "example.org";
#option domain-name-servers ns1.example.org, ns2.example.org;

default-lease-time 7200;
max-lease-time 86400;

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
authoritative;

# Use this to send dhcp log messages to a different log file (you also
# have to hack syslog.conf to complete the redirection).
log-facility local7;

# .. irrelevant commented config omitted for brevity ..

# Raspberry Pi subnet - note: this is the subnet of M$ Internet Connection Sharing
# TODO: Make sure the router configuration is correct
subnet 192.168.137.0 netmask 255.255.255.0 {
  range 192.168.137.3 192.168.137.21;
  option broadcast-address 192.168.137.255;
  option routers 192.168.137.2;
  default-lease-time 7200;
  max-lease-time 86400;
  option domain-name "local";
  option domain-name-servers 8.8.8.8, 8.8.4.4;
}
As you can see, the lease time and maximum lease time configuration are consistent. I found that inconsistencies in these parameters sometimes causes isc-dhcp fails to provide valid IP addresses to the DHCP clients. So, watch-out to those parameters values.

Well, there are some more details regarding pppd, usb_modeswitch and iptables which are missing. This post is still considered beta and I'm going to update it in the not so distant future..

Saturday, March 29, 2014

OpenGL Texture is not (just) Picture

I'm a beginner in OpenGL for sure and one of the most confusing thing (read: naming convention) that has plagued me in these last two days is OpenGL texture. Contrary to the naming for functions, constants and objects used for OpenGL texture, everything related to texture on those "interfaces" don't really apply to image/picture only. It's much more general than that. OpenGL texture is basically a "lookup-table" (array) and it can store anything as long as the data type matches with the texture that you use in your code. The naming for OpenGL texture "interface" that usually implies the use of image/picture is a legacy of the past. It was used since the day of fixed-function video card and used until now to preserve API backward-compatibility--at least that's one of the reason that I'm aware of.

Anyway, these are some useful links regarding OpenGL texture:
http://www.mathematik.uni-dortmund.de/~goeddeke/gpgpu/tutorial.html#arrays1
http://www.arcsynthesis.org/gltut/Texturing/Tutorial%2014.html

Friday, March 21, 2014

Adding New Directory to CodeBlocks Code Completion

CodeBlocks (http://www.codeblocks.org) cannot enumerate all of the possible C/C++ include directories automatically in some cases. For example, when you are using 3rd party C/C++ libraries which are installed in non-standard path. At least that's the state of CodeBlocks v13.12.

Now, how do you go about adding new directories to be added to the codecompletion parser? The procedure is explained in CodeBlocks FAQ at http://wiki.codeblocks.org/index.php?title=FAQ-Settings. However, as I found out, only the second method works in CodeBlocks v13.12, i.e. only the per-project non-standard include directories (to be parsed) can be configured. These are the steps:

  1. Activate the project (either by double clicking on it in the Projects pane or right click on the project and then click "Activate")
  2. Click on the "Project | Properties" menu. 
  3. Click on the "C/C++ parser options" tab. 
  4. Add the additional include directory to be parsed by the Code Completion plugin.
  5. Click on OK.
Now, you should have code completion working in CodeBlocks editor. If it's not working yet, you might need to close the project and re-open the project again.

Wednesday, February 26, 2014

OpenGL Application Development in Windows 8.1 64-bit

I've been doing some OpenGL application development with Visual Studio 2012 for a week or so but I found it rather frustrating because M$ doesn't provide all headers required by C99 standards. Moreover, I have yet to configure GLSL syntax highlighting successfully in Visual Studio 2012. Well, it turned out it's much better to carryout OpenGL-related development with MinGW and using CodeBlocks as the IDE.

You can download CodeBlocks from www.codeblocks.org and use the 64-bit MinGW distribution from http://nuwen.net/mingw.html. The only missing library would be freeglut for MinGW which you can download from http://www.transmissionzero.co.uk/software/freeglut-devel/. The MinGW distribution from Stephan T. Lavavej (nuwen.net) already has GLEW in it, but it doesn't have glut or freeglut.

The way I setup my development environment as follows:
  1. Use CodeBlocks as the IDE, i.e. download and use CodeBlocks distribution that DOESN'T include MinGW because we are going to use the one from nuwen.net.
  2. Use nuwen.net MinGW as the source for base GCC, GLEW and GLM tools, libraries and includes.
  3. Use Freeglut for MinGW as the glut replacement.
Assuming you have setup all of the tools above correctly (consult their README files), it's time to create a sort of "Hello World" application in OpenGL. Head to http://en.wikibooks.org/wiki/OpenGL_Programming and try the first tutorial source code. This is how I create project in CodeBlocks for that tutorial:
  1. Create an empty project in CodeBlocks.
  2. Add all tutorial 01 source code from the basics arc (http://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Introduction) into the empty project.
  3. Fix all required settings before building the project, i.e. compiler include directory search paths and libraries search paths. The details are explained below.
The following screen captures show the settings that I changed to compile tutorial 01 successfully. The tabs, menus and entries highlighted (in red box) are those that you should change according to your MinGW installation details.





Once everything compiled and linked successfully, you can run the application. This is how the application should look like.


Well done. Now, you can proceed developing all other OpenGL application in Windows without thinking about C99 and GLSL syntax highlighting matters :-).

Anyway, you could actually setup the compiler and linker setting in per-project basis in CodeBlocks via the Project|Build Option menu. Clicking this menu will open a similar dialog box as shown in the screenshot above. However, it will only apply to currently active project.

UPDATE:
-----------
- The CodeBlocks steps I mentioned above are rather brute force approach. I'll update it with a better solution in the future.

Tuesday, February 18, 2014

Up-to-Date OpenGL Tutorial for Beginner

I found the Swiftless series article on OpenGL at: OpenGL 2 Tutorials and OpenGL 4 Tutorials
to be very compelling for newbie on the subject. They are particularly easy to follow for complete newbie.
One thing that sets them apart from other articles on the subject is they cover recent implementation of OpenGL. Therefore, it's easier to follow on present day OpenGL library available on recent systems and also features supported by present day GPUs.

Nice stuff Swiftless. Kudos to your work :-)

If you want a quite lengthy but deep introduction, head to Learning Modern 3D Graphics Programming. This is the most complete tutorial I found on the Net so far. Well, it's very well structured for my taste. I think, it's even better than http://en.wikibooks.org/wiki/OpenGL_Programming.

Tuesday, January 28, 2014

Running DHCP Server on Slackware 14

Running DHCP server on Slackware 14 is quite trivial. Just run pkgtool from the command line and enable the dnsmasq service. Dnsmasq is in the services to start on start-up category. What is not very clear is the configuration file for this service. You will find /etc/dhcpd.conf file in Slackware but this is not the configuration file used by dnsmasq. Dnsmasq uses /etc/dnsmasq.conf as configuration file. You only need to uncomment one line in this file to enable the DHCP server, i.e. the line that contains dhcp-range option, for example:

dhcp-range=192.168.137.2,192.168.137.10,48h 

The configuration above assumes the DHCP client are given address between the two IP addresses shown and a lease of 48 hours. If you have Windows computers running as client, you might want to uncomment this line too:
dhcp-option=vendor:MSFT,2,1i
This tells Windows to release the DHCP lease when it shuts down. Well, now you can restart dnsmasq and see the result.

Tuesday, January 7, 2014

Preventing Trivial Malicious Access to Your Linux Server

One of the problem haunting Linux server installation on the internet is malicious accesses, such as port scanning. One of the lightweight option to run in your Linux server to provide protection against "trivial" malicious activity from the internet is the psad (http://cipherdyne.org/psad/). This solution uses iptables as the source for analysis.