Monday, March 29, 2010

Total Commander, what a weapon!

I've used freecommander for years. It greatly improves my efficiency. Unfortunately, for some unkonwn reasons, my freecommander configuration file get corrupted after my machine power down unexpectedly several days before. Rather than making these configurations from scrarch again, I decided to give Total Commander a shot.

After I tried TC, I found it's far more powerful. TC is fully customizable, I can define any shortcut key combinations for TC internal commands or external commands defined by me. In FC, only Ctrl+[Number] is allowed to be set as shortcut key for external commands.
The most promising feature for TC is its plugin system. There are so many wonderful plugins that make TC so powerful. With packer plugin, I don't need a stand alone zip/tar/bzip2 applicaitons. With some creative filesystem plugins, task manager, regedit, dependency walker are not necessary any more. By using plugins, I can perform a lot of totally different tasks in a consistent manner, just manipulate some (fake) files in TC. This is very similar to abstraction in linux, where everything can be examined and manipulated like normal files. Abstract thinking should always be a popular idea among programmers, so I'm totally fascinated by TC.

Suggestions for Total Commander

1. Add global shortcut key. It's more convient to active total commander application with global shortcut key than pressing ctrl+tab sereval times. Though this can be achieved with tools like autohotkey, it's better if TC natively support global shortcut.

2. Improvement on command line. In windows console and linux shell, we can use tab key to complete file/command name. It's fabulous if TC also support this feature.

Wednesday, March 24, 2010

change command prompt font

Having used consolas font for a period, I felt very comfortable with it. I've used it in putty, vim, visual studio. And I tried to use it in windows console (cmd.exe) by following scott's post, Using Consolas as the Windows Console Font. But consolas font didn't show in console's available font list. It seemed to have to do with my console code page setting, which is 936 chinese gbk. Consolas was shown after I changed the console's code page to 850 with chcp command. Thing was not perfect, I could not use chinese input method under this code page in console, and chinese characters are not displayed correctly.
As a matter of fact, there is another way to set consolas font for console through registry, which doesn't require us to change code page. Our preferences for default console are saved in HKCU\Console, including console's width, height and font. Subitems of this key save preperences for console with specified title. So we can modify the FaceName item to force a font get applied. As shown below.

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Console]
"FaceName"="Consolas"

[HKEY_CURRENT_USER\Console\%SystemRoot%_system32_cmd.exe]
"FaceName"="Consolas"


Here is a snapshot of the font comparison:

BTW, consolas font is designed specifically for ClearType. It looks extremely poor if ClearType is not enabled. We can use ClearType Tuner PowerToy to fine tune ClearType under windows xp.

References:
Necessary criteria for fonts to be available in a command window
Give Your Eyes a Treat

Monday, March 22, 2010

getting start with osip

As described in rfc3261, sip is a layered protocol. Its layers are shown in the image below.

Unlike other sophisicated sip libiraies, exosip, pjsip, mjsip, which implement all layers of sip protocol, oSip library doesn't implement transport layer. oSip claims it doesn't provide high level api for controlling SIP session, it only provides api for sip message parsing, sdp message parsing and transaction handling. The api contains implementation for syntax, transaction and transaction unit layer.
So, in order to use oSip in our own application, we need to implement transport layer, and hook the transport layer with the oSip library.

Core structures of oSip
oSip library has four core structures, osip_t, osip_transaction_t, osip_event_t, osip_message_t. osip_t is the context of the sip library runs in. osip_transaction_t defines transaction which composes of a request message and all subsequent response messages related to the request. osip_event_t defines event inside transaction pending on handling. osip_message_t is the mapping from sip message syntax to c structure.

osip_t has four lists of transactions, each corresponds to a kind of transaction. For instance, if our sip application makes a call to another sip application, our application runs as uac (User Agent Client). A transaction is created and added to the osip_ict_transactions ( ict is short for invite client transaction) list. In the application being called, a transaction is also created and added to the osip_ist_transactions (ist is short for invite server transaction).
There are three members, msg_callbacks, kill_callbacks and cb_send_message in osip_t. They store callbacks to be called while handling events of transaction. They are designed as internal members. The proper way to add callbacks is using following apis: osip_set_cb_send_message, osip_set_message_callback and osip_set_kill_transaction_callback.

osip_transaction_t contains many members. Among them, the most important ones are:
  • transactionid, which uniquely identifis a transaction
  • state, which shows current state of the transaction
  • transactionff, a fifo containing all events belonging to this transaction
osip_event_t is used to represent an event pending on processing. It doesn't contain much information. It only has the transactionid of the owning transaction, the type of the event and a pointer to the sip_message_t correlate with the event. An event is usually constructed accompany with a sip_message_t instance. For example, upon receiving a incoming request, we can use osip_parse function to parse the received string to a osip_message_t instance, meanwhile, a osip_event_t instance will be created and returned. osip_event_t instance is only useful after it has been added to a transaction's event fifo. This can be done with osip_transaction_add_event or osip_find_transaction_and_add_event functions.

After events have been added to fifo, we need to call osip_xxx_execute functions to actually handle them. There are four osip_xxx_execute functions, each will handle all events belong to a transaction category. For example, osip_ist_execute function will iterate through all IST transactions in osip_ist_transactions list, loop through all events in each transaction's transactionff, call corresponding callback functions depending on the type of the event.

How to use oSip
To use oSip library, we usually follow below steps:
  1. Initialize oSip and setup callback functions
  2. Implement transport layer. In most cases, we create a socket based transport layer.
  3. Create/add events by parsing incoming messages
  4. Call osip_xxx_execute function to process all events
Here is a basic sample:
http://code.google.com/p/rxwen-blog-stuff/source/browse/trunk/protocol/basic_osip_sample/basic_osip_sample.cpp
This sample is a UAS(callee) for windows, and just show the basic steps of using oSip without error handling.

Something useful
  • It's strongly recommended not to run time consuming or indefinite ending tasks inside callback functions, otherwise, the osip main procedure will be blocked until the callback finishes.
  • oSip has provided a wrapper layer above native system apis to make it portable. In order to use its multi-thread feature (which is almost always necessary), we need to define OSIP_MT macro in our application.
  • In most cases, we don't need to concern about freeing of transaction & message instances. Their life time are managed by the osip runtime, through state machine.