A Small Good Habit of Equality Test

Many programmers make mistakes at times by writing “=” instead of “==” in equality test. A good habit of programming is to write the constant first. For example, if we want to test if the length of a string is equal to 0. Instead of writing

strlen(x) == 0

We can

write 0 == strlen(x)

In case we write “=” by mistake,

0 = strlen(x)

The compiler will complain about it.

In this way, we will easily find the bug at the compilation instead of squeezing head.

Selective Decoding–My Master Thesis Project

Finally, it’s done!

Work full-time and study part-time can be touch sometimes. But after 2 years of hard working, I’ve made it through. Smile

My thesis is about selective decoding. As the name suggests, decoding video selectively. Zoom interface has been available for photos, web pages and maps, but few players support zoomable video. When a video is zoomed in, only part of the scene is displayed but the entire frame is decoded. It’s a waste.

The idea of selective decoding is to decode what you can see. However, simply decode those parts won’t work because video codec introduces dependencies among macroblocks. So we need to analyze the dependencies among macroblocks and try to decode the minimum.

The benefits of selective decoding comes from two aspects, higher playback frame rate and lower energy consumption.

One can find the entire thesis here.

Linux Environment Variables in Bash Scripting

0. A Stupid Mistake

I wrote shell script from time to time, but never learned it seriously. So I wrote a script contains lines as below,

#!/bin/bash
PATH=”/”
ls -l $PATH

And then I got this error,

./test.sh: line 3: ls: command not found

I struggled a little bit and suddenly realized long time ago I made the same mistake. PATH is an environment variable and it’s overwritten by my script. In the bash script, the shell looks at the directories defined in PATH for the command. In the script above, the PATH variable has been overwritten, and therefore the shell cannot find the command.

Once I changed the code to below, it works.

#!/bin/bash
FPATH=”/”
ls -l $FPATH

The mistake is stupid, and we all make mistakes like this. But I did it twice. 🙁

1. Linux Environment Variables

Environment variable contains information shared by one or more applications. It helps one to change the settings for one or more applications easily.

One can list all environment variables by the command,

env

If you simply want to check a value of a specific environment variable, use the command echo followed by the variable name (say HOME) preceded by “$” sign,

echo $HOME

We can create shell variables with environment variables. For example,

MY_DIR=$HOME/roman10/code/

2. Set Linux Environment Variables

Define Environment Variables Globally

To define a environment variable for all users, one can use /etc/bash.bashrc or /etc/profile

For example, add a line below

PATH=”/usr/bin”

Define Environment Variables for a Particular User

To define a environment variables for a particular user, one can use ~/.bashrc or ~/.profile.

For example, add a line below,

PATH=”/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:”

Define Environment Variables for a Particular Session

To define a environment variable for a particular session, we can use the export command.

For example, enter the command below,

export TEST=”test”

We can check by the command,

echo $TEST

3. Different Between X=”1” and export X=”1”

If you simply type X=”1” in the shell, the variable will be visible in the shell. It won’t be shown in “env” output. And if you launch another program in the same shell, that program won’t be able to see it as well.

On the contrast, if you use export, the variable will be visible in “env” output and the other program launched in the shell.

For example, we type the following in the shell,

X=”1”
export X1=”2”

Now we enter the command below,

echo $X
echo $X1

It will give output “1” and “2”

But if we start another program, say, sh by entering the command,

sh

We enter the commands in sh terminal,

echo $X
echo $X1

It will give empty and “2”. Here X1 is visible to sh, but not X.

A Simple Trick for Grep

grep is a great tool to search strings. I often use grep to check if a specific process is running or not. For example, we want to check if sshd is running, the command would be,

ps -ax |  grep sshd

In my computer, this gives the following output,

755 ?        Ss     0:00 /usr/sbin/sshd -D
6175 pts/1    S+     0:00 grep –color=auto sshd

The first line of output is what we want, but the second line is pesky. It is shown because of we’re using grep to search for sshd.

A simple trick is to use the invert command of grep. This is shown as below,

ps ax | grep -v grep | grep sshd

Now the output is,

755 ?        Ss     0:00 /usr/sbin/sshd -D

How to Set Up SSH Tunnel

I was setting up a distributed monitoring system recently. At local machine, I has a program named “proga”, trying to access a remote server named “remote” at port 5667. However, the port is blocked by the enterprise firewall.

This is easy to solve by SSH tunneling.

ssh -f roman10@remote -L 5668:remote:5667 –N

This command sets up the SSH tunnel for accessing port 5667 of remote server from my localhost.

-f: ssh goes to background before it executes the command.

roman10: my user name at remote server

-L 5668:remote:5667: forward the traffic received at localhost 5668 to remote server at 5667. More generally, -L [bind_address:]port:host:hostport: Specifies that the given port on the local (client) host is to be forwarded to the given host and port on the remote side.

-N: do not execute a remote command.

After authentication, the tunnel will be set up. After that, I can simply access the remote port by sending traffic to 5668 at localhost.

One can make sure the remote 5667 port is open by the command at remote host,

netstat -nan | grep 5667

After that, use telnet to test the tunnel at localhost,

telnet localhost 5668

If it connects, we have set up the SSH tunnel successfully.

Enable Caching on Mobile Devices

I’ve been working on a project that enables caching on mobile devices. Two different approaches are studied, explored and implemented.

The first approach is to implement a transparent caching system. The caching system will behave like a transparent proxy, and the traffic for user specified apps will be intercepted and examined. If the content is cachable, the system will cache it for later usage.

The second approach is a caching library. It targets at apps with list view structure using JSON to communicate with server. The libarary contains a client side to be integrated with client mobile app and a server component needed at backend server side.

Near the end of this project, I did poster presentation at NUS SoC mingling session. Below is the poster. You can also view and download the PDF version here.

caching

At the time of my presentation, the project is not finished yet. The evaluation is in progress. Later on, the evaluation proves that both request-response caching and object-level caching can help save energy, improve response time and reduce bandwidth consumption.

The project is completed and the research paper for this project is in editing mode.

Turn the Selfishness of Individuals into Good of Public

This was a ancient Chinese story regarding Zeng guofan (曾国藩). Zeng is a military general and Confucian scholar in Qing Dynasty. He has a large group of counselors working for him. But one thing bothers him is that a lot of people leaves after working for a short period. One day, he asked one of his trusted counselors why. The person answered, “It is hard to get promoted working for you because you think people should be selfless, and you only promote people with great contributions. There are other generals promotes people more quickly.”  Zeng then asked “How can we solve it”? The counselor said, “You’ll need to be selfishlessness and turn the Selfishness of Individuals into Good of Public  (合众人之私,成一人之公)”. Zeng took the advice and his counselors team became the best thereafter.

Think about it. Few people are selfless. Ordinary people like us are all working for our self interest. In all the companies I worked, people comes and leaves frequently. For the people who stays, quite a few of them do not have a better option. Few people really enjoys working.

Every company needs to take care of the selfness of the individuals, not just the management team, but everyone. Everyone should be given the opportunity to realize his/her full potential. Otherwise, the guy is going to leave sooner or later. And the company may ends of keeping someone, the ones that don’t have a better choice and don’t enjoy working.

How to Deploy Android NDK Library in Separate APK

There’re times developers want to deploy a NDK library in a separate APK. A typical use case is your library is big and it has different versions for different CPUs/phones. A naive strategy is to put all those libraries in a single huge apk and get lots of user complains. A better approach is to separate NDK library from the main application. This has been done by many video player apps.

Recently I also adopted this approach for my Video Converter Android app. This post gives a simple example of using separate APK for native library.

0. Create the NDK Library

The first step is to create the NDK library. We used the hello-jni code in the NDK sample. Note that when creating this project, uncheck the “Create Activity” box, since we’re going to create a apk contains NDK library only. This is shown in figure below,

Figure 1. Creating a Native Library

You can download the code at the end of this post.

Note that the package name for the library project is roman10.tutorial.nativelib. Once you export the apk and installed it on your device, the ndk library “libhello-jni.so” will be put at /data/data/roman10.tutorial.nativelib/lib/.

Note that the NDK library function’s signature needs to follow the JNI standard in order for the project code described below to call it.

1. Create a Project that Use the NDK Library

Now we create a project that uses the NDK library. To load the library, instead of loadLibrary function, we use load().

private static final String libPath = "/data/data/roman10.tutorial.nativelib/lib/libhello-jni.so";

System.load(libPath);

To call the NDK function, we need to declare the function.

public native String  stringFromJNI();

We can then call the NDK method.

displayText = (TextView) findViewById(R.id.display);        

displayText.setText( stringFromJNI() );

With APKs from both projects installed on my phone, I got the following results.

Figure 2. Execution Results

2. Downloads

You can download the code for the two projects here, from get them from my github here.