How-to: Write an Asterisk Module, Part 2

In part 1, I explained the “Hello World” of Asterisk modules. It implemented just enough to properly compile, get loaded into Asterisk, and print something to the Asterisk log when the module was loaded and unloaded. Now, it’s time to start making modules that do something useful.

In res_helloworld.c, we implemented a load_module and unload_module function. In that module, they just printed to the log. They actually have a much more important purpose in life.

The job of load_module() is to say, “Hello Asterisk, I’m a module. I can provide some features to Asterisk and here is how you use them.”

Conversely, the job of unload module is to say, “Hello Asterisk, again. I’m about to disappear, so please don’t use any of these features that I was providing to you anymore. If you do, you’ll explode. kthx!”

So, it’s time to update this module to provide a feature to Asterisk. We’ll start with a CDR (Call Detail Record) handler. It is one of, if not the simplest interface to implement. To keep things simple, we’re going to implement an Asterisk CDR handler that once again, just uses the Asterisk logging interface.

The first thing to do is to add the appropriate header file so that module has the appropriate definitions for the CDR interface.


#include "asterisk/cdr.h"

Next, we’re going to add a new function. This function will get called every time that there is a new CDR to post. It takes a single argument, which is the CDR itself.

static int cdr_helloworld(struct ast_cdr *cdr)
{
    ast_log(LOG_NOTICE, "We got a CDR for channel '%s'.  "
        "Source: '%s', Dest: '%s', Duration: %ldn",
        cdr->channel, cdr->src, cdr->dst, cdr->duration);

    return 0;
}

Next, as I described before, we have to make the load_module() and unload_module() functions aware of this new feature that is implemented by the module.

In load_module(), we will add a function call to “register” the CDR handler with the Asterisk core. The arguments are the name of the handler, a short description, and the function that the Asterisk core needs to call when a CDR is ready for posting.


ast_cdr_register("HelloWorld", "Hello World CDR Handler", cdr_helloworld);

In unload_module(), we will add a function call to “unregister” the CDR handler form the Asterisk core.


ast_cdr_unregister("HelloWorld");

That’s it! See the finished code here, res_helloworld2.c.

Compile it and install it. When you start Asterisk, you should be able to verify that your new CDR handler has been registered with the Asterisk core.


*CLI> cdr show status
...
CDR registered backend: HelloWorld
...

When you hang up a call, you should see the result of your CDR handler being executed.


[Jun 20 18:08:29] NOTICE[4922]: res_helloworld.c:36 cdr_helloworld: We got a CDR for channel 'SIP/5001-007e9da8'. Source: '5001', Dest: '586', Duration: 1

And now, you have implemented an Asterisk module that adds custom handling of CDR records!

14 thoughts on “How-to: Write an Asterisk Module, Part 2

  1. Pingback: Programando módulos personalizados para Asterisk at Mi Brain-Training Personal

  2. Hi Russell,

    Thanx for nice explanation of module creation in Asterisk.

    I want to know that should i implement multithreading and socket programming concept using module in Asterisk ???

    Actually, i want to pop-up at Agent desk using socket programming in Queue Application. Currently i am using manager events for it. But i want to know that should it possible with Asterisk Module to handle multiple socket communication with Multithreading concept ???

    Thanxs in advance

  3. Allan, thank you very much for the kind words!

    Bharat, without knowing more, it sounds like writing an external application using the manager interface is the best way to achieve what you want to do. Another thing that you should look at is using Jabber for agent pop-ups. You can send jabber messages to your agents from the dialplan. Some people have done some very nice things for call centers just using that.

  4. Thanx Russell.

    I have three IVR server with 8 PRI (Zaptel) in each server for load sharing. One Agent server connected with all IVR server with SIP trunk ( To provide single ACD and common queue).

    Call transfer to Agent from Queue Application only. We integrate manager events of all 3 ivr server and Agent server. When ever i get event on manager for Agent Ringing, i send pop-up to Agent desk using external application.

    However, its working fine with Manager events intergration. I just want to know is it possible to include the same in Queue Application.

    I am studying Jabber also as per your suggession.

    Thanks again.

  5. is asterisk going to have sockets support for programming languages?

    i know there is cdr, but sockets would be great…

  6. Thanks. To find more in depth information, I will be posting more tutorials. Beyond that, the Asterisk source is your best friend, as there are hundreds of examples already there. You can also find API documentation in header files (include/asterisk/) and the doxygen generated documentation:

    http://www.asterisk.org/doxygen

  7. Pingback: How-to: Write an Asterisk Module, Part 3

  8. Pingback: Tutorials for writing Asterisk modules « Michigan Telephone, VoIP and Broadband blog

  9. Pingback: Asterisk Module Programming : alexanderjohansen[dot]com

  10. Hi Russel, thanks for res_ais module, but i have some troubles with it: while loading module, i get this error: ” Could not initialize cluster membership service: Does Not Exist”, can you give me a little advice ? 🙂 Thanks

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.