Thursday, September 25, 2008

Customizing BCM96338 (2)

Its after a long time I got time to re-visit this topic. First let me give you the iptables rules to forward the connection.

Step 1: Find your external interface
Do a "ifconfig". You will see an array of devices. One of this will have your global ip.
(Check the index page of your device if you are doubtful about which one is the global ip. You can find your global ip there)

Step 2: iptables rules
iptables -t nat -I PREROUTING -p tcp --dport 22 -i ppp_0_35_2 -j DNAT --to 192.168.1.100
iptables -t filter -I FORWARD -p tcp --dport 22 -d 192.168.1.100 -j ACCEPT

ppp_0_35_2 -> Replace this with the name of your external interface
192.168.1.100 -> Replace this with the ip of your local ssh server

Step 3: How to forward for other connections?
Say you want to have external access to a web server running inside your local network. All that you have to do is issue the above to commands with following differences.

1) --dport 22 will change to --dport 80
2) 192.168.1.100 will be replaced with the ip of your local web server.

If you have any other service running inside, use the portocol (tcp/udp), port and ip of that service.

Tuesday, September 9, 2008

Shady Asterisk

Hmm... you must be wondering why I call him so. Because he is of dubious character. He appears nice outside and what does he do within?

I got a feel of it when I was writing the channel. I wrote the skeleton channel and made an entry for that in extensions.conf.

exten => 200,1,Dial(Sarin/200)
exten => 200,n,Hangup()

From the console do "console dial 200". Then I got a message that "Couldn't call 200". I checked again and again to find what has gone wrong. Nothing as far as I could see.

Then I enabled debug mode. To enable the debug mode in asterisk, I had to do two things.

1.1 Edit the /etc/asterisk/logger.conf.
1.2 Look for a line that looks like "console => notice,warning,error"
1.3 Add debug to that list. "console => notice,warning,error,debug"
2. Now start asterisk with debug option. "asterisk -vvvdc"

(This for enabling debug prints on console)

Then, when I tried to call that number, I found that response from "ast_call" indicates a failure. And, what was causing it?

ast_call checks ast_check_hangup. Inside that function, there is this block of code:

if (!chan->tech_pvt) /* yes if no technology private data */
return 1;
Shame on you asterisk. You were checking the private elements of a channel!. You had no business poking around that pointer. It is private to the channel and it is upto the channel to decide to have it or not to have it (have it as NULL). If you wanted to do anything with it, you should not have called it pvt!

Anyway, I assigned a int pointer to it and then things went fine.

Monday, September 1, 2008

The channel woes

Today I was trying to register an asterisk channel. However my module registration failed with the error that module does not provide any description. I had half a mind to edit the line from Loader.c and load my module. However, I also noticed that I was compiling the module for one version (SVN trunk) and using it on some other version (1.4.15).

Then I downloaded asterisk from svn and compiled and installed it on some other machine. Then I just put in my simple module code, compiled, copied to /usr/lib/asterisk/modules/ and on the command line told "module load chan_thin" The stuff that was not happening for last two days just happened!

The sad part of my story is this. Till now the asterisk was giving me this message: "Module 'chan_thin.so' does not provide a description". I had tried various things including injecting the code of AST_MODULE_INFO macro into my module and adding checks on the functions used by that macro. I kept getting that vague error only because of some version change. (OK, it is still my mistake. Lot of things could have happened in a version change)

Anyway, now I have a module that goes in and does nothing. I have also checked oss channel driver in asterisk. I feel that is the most simple channel driver which I can use as a datum. More on it later. Before I end, let me put down a partial function call tree.

1. AST_MODULE_INFO -> Defines the module info and the register function. This registers ast_module_info
2. load_module -> This is made available to asterisk using ast_module_info structure. It is called when we load the module. For channel registration, ast_channel_register is called during load module. It passes a structure ast_channel_tech
3. ast_channel_tech -> This has all the callback functions. For OSS channel, the structure is as follows.

static struct ast_channel_tech oss_tech = {
.type = "Console",
.description = tdesc,
.capabilities = AST_FORMAT_SLINEAR, /* overwritten later */
.requester = oss_request,
.send_digit_begin = oss_digit_begin,
.send_digit_end = oss_digit_end,
.send_text = oss_text,
.hangup = oss_hangup,
.answer = oss_answer,
.read = oss_read,
.call = oss_call,
.write = oss_write,
.write_video = console_write_video,
.indicate = oss_indicate,
.fixup = oss_fixup,
};

4. oss_request -> This is the function that is called by asterisk when a call comes to your channel. The number is passed to you as a parameter to the function.

Got to do few more things. Rest later.