Add a massive set of changes for converting to use the ast_debug() macro.
[asterisk/asterisk.git] / channels / chan_phone.c
index 1c6fff4..e33d1a1 100644 (file)
        <depend>ixjuser</depend>
  ***/
 
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
 #include <linux/telephony.h>
 /* Still use some IXJ specific stuff */
 #include <linux/version.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-# include <linux/compiler.h>
-#endif
 #include <linux/ixjuser.h>
 
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
 #include "asterisk/lock.h"
 #include "asterisk/channel.h"
 #include "asterisk/config.h"
@@ -64,6 +61,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/callerid.h"
 #include "asterisk/causes.h"
 #include "asterisk/stringfields.h"
+#include "asterisk/musiconhold.h"
 
 #include "DialTone.h"
 
@@ -87,7 +85,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #define PHONE_MAX_BUF 480
 #define DEFAULT_GAIN 0x100
 
-static const char desc[] = "Linux Telephony API Support";
 static const char tdesc[] = "Standard Linux Telephony API Driver";
 static const char config[] = "phone.conf";
 
@@ -96,15 +93,12 @@ static char context[AST_MAX_EXTENSION] = "default";
 
 /* Default language */
 static char language[MAX_LANGUAGE] = "";
-static int usecnt =0;
 
 static int echocancel = AEC_OFF;
 
 static int silencesupression = 0;
 
-static int prefformat = AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW;
-
-AST_MUTEX_DEFINE_STATIC(usecnt_lock);
+static int prefformat = AST_FORMAT_G729A | AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW;
 
 /* Protect the interface list (of phone_pvt's) */
 AST_MUTEX_DEFINE_STATIC(iflock);
@@ -127,8 +121,9 @@ static int restart_monitor(void);
    
 #define MODE_DIALTONE  1
 #define MODE_IMMEDIATE 2
-#define MODE_FXO               3
+#define MODE_FXO       3
 #define MODE_FXS        4
+#define MODE_SIGMA      5
 
 static struct phone_pvt {
        int fd;                                                 /* Raw file descriptor for this device */
@@ -160,7 +155,8 @@ static char cid_num[AST_MAX_EXTENSION];
 static char cid_name[AST_MAX_EXTENSION];
 
 static struct ast_channel *phone_request(const char *type, int format, void *data, int *cause);
-static int phone_digit(struct ast_channel *ast, char digit);
+static int phone_digit_begin(struct ast_channel *ast, char digit);
+static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
 static int phone_call(struct ast_channel *ast, char *dest, int timeout);
 static int phone_hangup(struct ast_channel *ast);
 static int phone_answer(struct ast_channel *ast);
@@ -169,14 +165,15 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame);
 static struct ast_frame *phone_exception(struct ast_channel *ast);
 static int phone_send_text(struct ast_channel *ast, const char *text);
 static int phone_fixup(struct ast_channel *old, struct ast_channel *new);
-static int phone_indicate(struct ast_channel *chan, int condition);
+static int phone_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
 
 static const struct ast_channel_tech phone_tech = {
        .type = "Phone",
        .description = tdesc,
-       .capabilities = AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW,
+       .capabilities = AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_G729A,
        .requester = phone_request,
-       .send_digit = phone_digit,
+       .send_digit_begin = phone_digit_begin,
+       .send_digit_end = phone_digit_end,
        .call = phone_call,
        .hangup = phone_hangup,
        .answer = phone_answer,
@@ -191,7 +188,8 @@ static struct ast_channel_tech phone_tech_fxs = {
        .type = "Phone",
        .description = tdesc,
        .requester = phone_request,
-       .send_digit = phone_digit,
+       .send_digit_begin = phone_digit_begin,
+       .send_digit_end = phone_digit_end,
        .call = phone_call,
        .hangup = phone_hangup,
        .answer = phone_answer,
@@ -206,11 +204,11 @@ static struct ast_channel_tech phone_tech_fxs = {
 
 static struct ast_channel_tech *cur_tech;
 
-static int phone_indicate(struct ast_channel *chan, int condition)
+static int phone_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
 {
        struct phone_pvt *p = chan->tech_pvt;
        int res=-1;
-       ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name);
+       ast_debug(1, "Requested indication %d on channel %s\n", condition, chan->name);
        switch(condition) {
                case AST_CONTROL_FLASH:
                        ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_ON_HOOK);
@@ -219,6 +217,12 @@ static int phone_indicate(struct ast_channel *chan, int condition)
                        p->lastformat = -1;
                        res = 0;
                        break;
+               case AST_CONTROL_HOLD:
+                       ast_moh_start(chan, data, NULL);
+                       break;
+               case AST_CONTROL_UNHOLD:
+                       ast_moh_stop(chan);
+                       break;
                default:
                        ast_log(LOG_WARNING, "Condition %d is not supported on channel %s\n", condition, chan->name);
        }
@@ -233,12 +237,18 @@ static int phone_fixup(struct ast_channel *old, struct ast_channel *new)
        return 0;
 }
 
-static int phone_digit(struct ast_channel *ast, char digit)
+static int phone_digit_begin(struct ast_channel *chan, char digit)
+{
+       /* XXX Modify this callback to let Asterisk support controlling the length of DTMF */
+       return 0;
+}
+
+static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
 {
        struct phone_pvt *p;
        int outdigit;
        p = ast->tech_pvt;
-       ast_log(LOG_NOTICE, "Dialed %c\n", digit);
+       ast_debug(1, "Dialed %c\n", digit);
        switch(digit) {
        case '0':
        case '1':
@@ -269,7 +279,7 @@ static int phone_digit(struct ast_channel *ast, char digit)
                ast_log(LOG_WARNING, "Unknown digit '%c'\n", digit);
                return -1;
        }
-       ast_log(LOG_NOTICE, "Dialed %d\n", outdigit);
+       ast_debug(1, "Dialed %d\n", outdigit);
        ioctl(p->fd, PHONE_PLAY_TONE, outdigit);
        p->lastformat = -1;
        return 0;
@@ -296,12 +306,12 @@ static int phone_call(struct ast_channel *ast, char *dest, int timeout)
        }
        /* the standard format of ast->callerid is:  "name" <number>, but not always complete */
        if (ast_strlen_zero(ast->cid.cid_name))
-               strncpy(cid.name, DEFAULT_CALLER_ID, sizeof(cid.name) - 1);
+               strcpy(cid.name, DEFAULT_CALLER_ID);
        else
-               strncpy(cid.name, ast->cid.cid_name, sizeof(cid.name) - 1);
+               ast_copy_string(cid.name, ast->cid.cid_name, sizeof(cid.name));
 
        if (ast->cid.cid_num) 
-               strncpy(cid.number, ast->cid.cid_num, sizeof(cid.number) - 1);
+               ast_copy_string(cid.number, ast->cid.cid_num, sizeof(cid.number));
 
        p = ast->tech_pvt;
 
@@ -309,8 +319,7 @@ static int phone_call(struct ast_channel *ast, char *dest, int timeout)
                ast_log(LOG_WARNING, "phone_call called on %s, neither down nor reserved\n", ast->name);
                return -1;
        }
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Ringing %s on %s (%d)\n", dest, ast->name, ast->fds[0]);
+       ast_debug(1, "Ringing %s on %s (%d)\n", dest, ast->name, ast->fds[0]);
 
        start = IXJ_PHONE_RING_START(cid);
        if (start == -1)
@@ -322,7 +331,7 @@ static int phone_call(struct ast_channel *ast, char *dest, int timeout)
                {
                  digit++;
                  while (*digit)
-                   phone_digit(ast, *digit++);
+                   phone_digit_end(ast, *digit++, 0);
                }
        }
  
@@ -335,8 +344,7 @@ static int phone_hangup(struct ast_channel *ast)
 {
        struct phone_pvt *p;
        p = ast->tech_pvt;
-       if (option_debug)
-               ast_log(LOG_DEBUG, "phone_hangup(%s)\n", ast->name);
+       ast_debug(1, "phone_hangup(%s)\n", ast->name);
        if (!ast->tech_pvt) {
                ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
                return 0;
@@ -354,14 +362,13 @@ static int phone_hangup(struct ast_channel *ast)
 
        /* If it's an FXO, hang them up */
        if (p->mode == MODE_FXO) {
-               if (ioctl(p->fd, PHONE_PSTN_SET_STATE, PSTN_ON_HOOK)) 
-                       ast_log(LOG_DEBUG, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n",ast->name, strerror(errno));
+               if (ioctl(p->fd, PHONE_PSTN_SET_STATE, PSTN_ON_HOOK))
+                       ast_debug(1, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n",ast->name, strerror(errno));
        }
 
        /* If they're off hook, give a busy signal */
        if (ioctl(p->fd, PHONE_HOOKSTATE)) {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Got hunghup, giving busy signal\n");
+               ast_debug(1, "Got hunghup, giving busy signal\n");
                ioctl(p->fd, PHONE_BUSY);
                p->cpt = 1;
        }
@@ -372,12 +379,7 @@ static int phone_hangup(struct ast_channel *ast)
        p->dialtone = 0;
        memset(p->ext, 0, sizeof(p->ext));
        ((struct phone_pvt *)(ast->tech_pvt))->owner = NULL;
-       ast_mutex_lock(&usecnt_lock);
-       usecnt--;
-       if (usecnt < 0) 
-               ast_log(LOG_WARNING, "Usecnt < 0???\n");
-       ast_mutex_unlock(&usecnt_lock);
-       ast_update_use_count();
+       ast_module_unref(ast_module_info->self);
        if (option_verbose > 2) 
                ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
        ast->tech_pvt = NULL;
@@ -392,8 +394,17 @@ static int phone_setup(struct ast_channel *ast)
        p = ast->tech_pvt;
        ioctl(p->fd, PHONE_CPT_STOP);
        /* Nothing to answering really, just start recording */
-       if (ast->rawreadformat == AST_FORMAT_G723_1) {
-               /* Prefer g723 */
+       if (ast->rawreadformat == AST_FORMAT_G729A) {
+               /* Prefer g729 */
+               ioctl(p->fd, PHONE_REC_STOP);
+               if (p->lastinput != AST_FORMAT_G729A) {
+                       p->lastinput = AST_FORMAT_G729A;
+                       if (ioctl(p->fd, PHONE_REC_CODEC, G729)) {
+                               ast_log(LOG_WARNING, "Failed to set codec to g729\n");
+                               return -1;
+                       }
+               }
+        } else if (ast->rawreadformat == AST_FORMAT_G723_1) {
                ioctl(p->fd, PHONE_REC_STOP);
                if (p->lastinput != AST_FORMAT_G723_1) {
                        p->lastinput = AST_FORMAT_G723_1;
@@ -450,14 +461,13 @@ static int phone_answer(struct ast_channel *ast)
        p = ast->tech_pvt;
        /* In case it's a LineJack, take it off hook */
        if (p->mode == MODE_FXO) {
-               if (ioctl(p->fd, PHONE_PSTN_SET_STATE, PSTN_OFF_HOOK)) 
-                       ast_log(LOG_DEBUG, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n", ast->name, strerror(errno));
+               if (ioctl(p->fd, PHONE_PSTN_SET_STATE, PSTN_OFF_HOOK))
+                       ast_debug(1, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n", ast->name, strerror(errno));
                else
-                       ast_log(LOG_DEBUG, "Took linejack off hook\n");
+                       ast_debug(1, "Took linejack off hook\n");
        }
        phone_setup(ast);
-       if (option_debug)
-               ast_log(LOG_DEBUG, "phone_answer(%s)\n", ast->name);
+       ast_debug(1, "phone_answer(%s)\n", ast->name);
        ast->rings = 0;
        ast_setstate(ast, AST_STATE_UP);
        return 0;
@@ -495,8 +505,7 @@ static struct ast_frame  *phone_exception(struct ast_channel *ast)
        
        phonee.bytes = ioctl(p->fd, PHONE_EXCEPTION);
        if (phonee.bits.dtmf_ready)  {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "phone_exception(): DTMF\n");
+               ast_debug(1, "phone_exception(): DTMF\n");
        
                /* We've got a digit -- Just handle this nicely and easily */
                digit =  ioctl(p->fd, PHONE_GET_DTMF_ASCII);
@@ -505,12 +514,10 @@ static struct ast_frame  *phone_exception(struct ast_channel *ast)
                return &p->fr;
        }
        if (phonee.bits.hookstate) {
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "Hookstate changed\n");
+               ast_debug(1, "Hookstate changed\n");
                res = ioctl(p->fd, PHONE_HOOKSTATE);
                /* See if we've gone on hook, if so, notify by returning NULL */
-               if (option_debug)
-                       ast_log(LOG_DEBUG, "New hookstate: %d\n", res);
+               ast_debug(1, "New hookstate: %d\n", res);
                if (!res && (p->mode != MODE_FXO))
                        return NULL;
                else {
@@ -656,7 +663,7 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
                return 0;
        }
        if (!(frame->subclass &
-               (AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW)) && 
+               (AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_G729A)) && 
            p->mode != MODE_FXS) {
                ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
                return -1;
@@ -673,7 +680,30 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
                return 0;
        }
 #endif 
-       if (frame->subclass == AST_FORMAT_G723_1) {
+       if (frame->subclass == AST_FORMAT_G729A) {
+               if (p->lastformat != AST_FORMAT_G729A) {
+                       ioctl(p->fd, PHONE_PLAY_STOP);
+                       ioctl(p->fd, PHONE_REC_STOP);
+                       if (ioctl(p->fd, PHONE_PLAY_CODEC, G729)) {
+                               ast_log(LOG_WARNING, "Unable to set G729 mode\n");
+                               return -1;
+                       }
+                       if (ioctl(p->fd, PHONE_REC_CODEC, G729)) {
+                               ast_log(LOG_WARNING, "Unable to set G729 mode\n");
+                               return -1;
+                       }
+                       p->lastformat = AST_FORMAT_G729A;
+                       p->lastinput = AST_FORMAT_G729A;
+                       /* Reset output buffer */
+                       p->obuflen = 0;
+                       codecset = 1;
+               }
+               if (frame->datalen > 80) {
+                       ast_log(LOG_WARNING, "Frame size too large for G.729 (%d bytes)\n", frame->datalen);
+                       return -1;
+               }
+               maxfr = 80;
+        } else if (frame->subclass == AST_FORMAT_G723_1) {
                if (p->lastformat != AST_FORMAT_G723_1) {
                        ioctl(p->fd, PHONE_PLAY_STOP);
                        ioctl(p->fd, PHONE_REC_STOP);
@@ -821,10 +851,9 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *conte
 {
        struct ast_channel *tmp;
        struct phone_codec_data codec;
-       tmp = ast_channel_alloc(1);
+       tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", i->ext, i->context, 0, "Phone/%s", i->dev + 5);
        if (tmp) {
                tmp->tech = cur_tech;
-               ast_string_field_build(tmp, name, "Phone/%s", i->dev + 5);
                tmp->fds[0] = i->fd;
                /* XXX Switching formats silently causes kernel panics XXX */
                if (i->mode == MODE_FXS &&
@@ -846,26 +875,26 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *conte
                        tmp->rawreadformat = prefformat;
                        tmp->rawwriteformat = prefformat;
                }
-               ast_setstate(tmp, state);
+               /* no need to call ast_setstate: the channel_alloc already did its job */
                if (state == AST_STATE_RING)
                        tmp->rings = 1;
                tmp->tech_pvt = i;
-               strncpy(tmp->context, context, sizeof(tmp->context)-1);
+               ast_copy_string(tmp->context, context, sizeof(tmp->context));
                if (!ast_strlen_zero(i->ext))
-                       strncpy(tmp->exten, i->ext, sizeof(tmp->exten)-1);
+                       ast_copy_string(tmp->exten, i->ext, sizeof(tmp->exten));
                else
-                       strncpy(tmp->exten, "s",  sizeof(tmp->exten) - 1);
+                       strcpy(tmp->exten, "s");
                if (!ast_strlen_zero(i->language))
                        ast_string_field_set(tmp, language, i->language);
-               if (!ast_strlen_zero(i->cid_num))
-                       tmp->cid.cid_num = strdup(i->cid_num);
-               if (!ast_strlen_zero(i->cid_name))
-                       tmp->cid.cid_name = strdup(i->cid_name);
+
+               /* Don't use ast_set_callerid() here because it will
+                * generate a NewCallerID event before the NewChannel event */
+               tmp->cid.cid_num = ast_strdup(i->cid_num);
+               tmp->cid.cid_ani = ast_strdup(i->cid_num);
+               tmp->cid.cid_name = ast_strdup(i->cid_name);
+
                i->owner = tmp;
-               ast_mutex_lock(&usecnt_lock);
-               usecnt++;
-               ast_mutex_unlock(&usecnt_lock);
-               ast_update_use_count();
+               ast_module_ref(ast_module_info->self);
                if (state != AST_STATE_DOWN) {
                        if (state == AST_STATE_RING) {
                                ioctl(tmp->fds[0], PHONE_RINGBACK);
@@ -900,12 +929,12 @@ static void phone_check_exception(struct phone_pvt *i)
        union telephony_exception phonee;
        /* XXX Do something XXX */
 #if 0
-       ast_log(LOG_DEBUG, "Exception!\n");
+       ast_debug(1, "Exception!\n");
 #endif
        phonee.bytes = ioctl(i->fd, PHONE_EXCEPTION);
        if (phonee.bits.dtmf_ready)  {
                digit[0] = ioctl(i->fd, PHONE_GET_DTMF_ASCII);
-               if (i->mode == MODE_DIALTONE || i->mode == MODE_FXS) {
+               if (i->mode == MODE_DIALTONE || i->mode == MODE_FXS || i->mode == MODE_SIGMA) {
                        ioctl(i->fd, PHONE_PLAY_STOP);
                        ioctl(i->fd, PHONE_REC_STOP);
                        ioctl(i->fd, PHONE_CPT_STOP);
@@ -928,8 +957,7 @@ static void phone_check_exception(struct phone_pvt *i)
                                        /* XXX This should probably be justified better XXX */
                                }  else if (!ast_canmatch_extension(NULL, "default", i->ext, 1, i->cid_num)) {
                                        /* It's not a valid extension, give a busy signal */
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "%s can't match anything in %s or default\n", i->ext, i->context);
+                                       ast_debug(1, "%s can't match anything in %s or default\n", i->ext, i->context);
                                        ioctl(i->fd, PHONE_BUSY);
                                        i->cpt = 1;
                                }
@@ -945,10 +973,7 @@ static void phone_check_exception(struct phone_pvt *i)
                        if (i->mode == MODE_IMMEDIATE) {
                                phone_new(i, AST_STATE_RING, i->context);
                        } else if (i->mode == MODE_DIALTONE) {
-                               ast_mutex_lock(&usecnt_lock);
-                               usecnt++;
-                               ast_mutex_unlock(&usecnt_lock);
-                               ast_update_use_count();
+                               ast_module_ref(ast_module_info->self);
                                /* Reset the extension */
                                i->ext[0] = '\0';
                                /* Play the dialtone */
@@ -957,14 +982,17 @@ static void phone_check_exception(struct phone_pvt *i)
                                ioctl(i->fd, PHONE_PLAY_CODEC, ULAW);
                                ioctl(i->fd, PHONE_PLAY_START);
                                i->lastformat = -1;
+                       } else if (i->mode == MODE_SIGMA) {
+                               ast_module_ref(ast_module_info->self);
+                               /* Reset the extension */
+                               i->ext[0] = '\0';
+                               /* Play the dialtone */
+                               i->dialtone++;
+                               ioctl(i->fd, PHONE_DIALTONE);
                        }
                } else {
-                       if (i->dialtone) {
-                               ast_mutex_lock(&usecnt_lock);
-                               usecnt--;
-                               ast_mutex_unlock(&usecnt_lock);
-                               ast_update_use_count();
-                       }
+                       if (i->dialtone)
+                               ast_module_unref(ast_module_info->self);
                        memset(i->ext, 0, sizeof(i->ext));
                        if (i->cpt)
                        {
@@ -1022,7 +1050,7 @@ static void *do_monitor(void *data)
                                FD_SET(i->fd, &efds);
                                if (i->fd > n)
                                        n = i->fd;
-                               if (i->dialtone) {
+                               if (i->dialtone && i->mode != MODE_SIGMA) {
                                        /* Remember we're going to have to come back and play
                                           more dialtones */
                                        if (ast_tvzero(tv)) {
@@ -1040,7 +1068,7 @@ static void *do_monitor(void *data)
                ast_mutex_unlock(&iflock);
 
                /* Wait indefinitely for something to happen */
-               if (dotone) {
+               if (dotone && i->mode != MODE_SIGMA) {
                        /* If we're ready to recycle the time, set it to 30 ms */
                        tonepos += 240;
                        if (tonepos >= sizeof(DialTone))
@@ -1056,7 +1084,7 @@ static void *do_monitor(void *data)
                }
                /* Okay, select has finished.  Let's see what happened.  */
                if (res < 0) {
-                       ast_log(LOG_DEBUG, "select return %d: %s\n", res, strerror(errno));
+                       ast_debug(1, "select return %d: %s\n", res, strerror(errno));
                        continue;
                }
                /* If there are no fd's changed, just continue, it's probably time
@@ -1119,7 +1147,7 @@ static int restart_monitor()
        }
        monitor = 1;
        /* Start a new monitor */
-       if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) {
+       if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
                ast_mutex_unlock(&monlock);
                ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
                return -1;
@@ -1134,28 +1162,29 @@ static struct phone_pvt *mkif(char *iface, int mode, int txgain, int rxgain)
        struct phone_pvt *tmp;
        int flags;      
        
-       tmp = malloc(sizeof(struct phone_pvt));
+       tmp = ast_calloc(1, sizeof(*tmp));
        if (tmp) {
                tmp->fd = open(iface, O_RDWR);
                if (tmp->fd < 0) {
                        ast_log(LOG_WARNING, "Unable to open '%s'\n", iface);
-                       free(tmp);
+                       ast_free(tmp);
                        return NULL;
                }
                if (mode == MODE_FXO) {
-                       if (ioctl(tmp->fd, IXJCTL_PORT, PORT_PSTN)) 
-                               ast_log(LOG_DEBUG, "Unable to set port to PSTN\n");
+                       if (ioctl(tmp->fd, IXJCTL_PORT, PORT_PSTN)) {
+                               ast_debug(1, "Unable to set port to PSTN\n");
+                       }
                } else {
                        if (ioctl(tmp->fd, IXJCTL_PORT, PORT_POTS)) 
                                 if (mode != MODE_FXS)
-                                     ast_log(LOG_DEBUG, "Unable to set port to POTS\n");
+                                     ast_debug(1, "Unable to set port to POTS\n");
                }
                ioctl(tmp->fd, PHONE_PLAY_STOP);
                ioctl(tmp->fd, PHONE_REC_STOP);
                ioctl(tmp->fd, PHONE_RING_STOP);
                ioctl(tmp->fd, PHONE_CPT_STOP);
-               if (ioctl(tmp->fd, PHONE_PSTN_SET_STATE, PSTN_ON_HOOK)) 
-                       ast_log(LOG_DEBUG, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n",iface, strerror(errno));
+               if (ioctl(tmp->fd, PHONE_PSTN_SET_STATE, PSTN_ON_HOOK))
+                       ast_debug(1, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n",iface, strerror(errno));
                if (echocancel != AEC_OFF)
                        ioctl(tmp->fd, IXJCTL_AEC_START, echocancel);
                if (silencesupression) 
@@ -1171,15 +1200,15 @@ static struct phone_pvt *mkif(char *iface, int mode, int txgain, int rxgain)
                tmp->lastinput = -1;
                tmp->ministate = 0;
                memset(tmp->ext, 0, sizeof(tmp->ext));
-               strncpy(tmp->language, language, sizeof(tmp->language)-1);
-               strncpy(tmp->dev, iface, sizeof(tmp->dev)-1);
-               strncpy(tmp->context, context, sizeof(tmp->context)-1);
+               ast_copy_string(tmp->language, language, sizeof(tmp->language));
+               ast_copy_string(tmp->dev, iface, sizeof(tmp->dev));
+               ast_copy_string(tmp->context, context, sizeof(tmp->context));
                tmp->next = NULL;
                tmp->obuflen = 0;
                tmp->dialtone = 0;
                tmp->cpt = 0;
-               strncpy(tmp->cid_num, cid_num, sizeof(tmp->cid_num)-1);
-               strncpy(tmp->cid_name, cid_name, sizeof(tmp->cid_name)-1);
+               ast_copy_string(tmp->cid_num, cid_num, sizeof(tmp->cid_num));
+               ast_copy_string(tmp->cid_name, cid_name, sizeof(tmp->cid_name));
                tmp->txgain = txgain;
                ioctl(tmp->fd, PHONE_PLAY_VOLUME, tmp->txgain);
                tmp->rxgain = rxgain;
@@ -1203,7 +1232,7 @@ static struct ast_channel *phone_request(const char *type, int format, void *dat
        p = iflist;
        while(p) {
                if (p->mode == MODE_FXS ||
-                   format & (AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW)) {
+                   format & (AST_FORMAT_G729A | AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW)) {
                    size_t length = strlen(p->dev + 5);
                if (strncmp(name, p->dev + 5, length) == 0 &&
                    !isalnum(name[length])) {
@@ -1220,7 +1249,7 @@ static struct ast_channel *phone_request(const char *type, int format, void *dat
        restart_monitor();
        if (tmp == NULL) {
                oldformat = format;
-               format &= (AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW);
+               format &= (AST_FORMAT_G729A | AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW);
                if (!format) {
                        ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat);
                        return NULL;
@@ -1295,7 +1324,7 @@ static int __unload_module(void)
                        pl = p;
                        p = p->next;
                        /* Free associated memory */
-                       free(pl);
+                       ast_free(pl);
                }
                iflist = NULL;
                ast_mutex_unlock(&iflock);
@@ -1307,12 +1336,12 @@ static int __unload_module(void)
        return 0;
 }
 
-static int unload_module(void *mod)
+static int unload_module(void)
 {
        return __unload_module();
 }
 
-static int load_module(void *mod)
+static int load_module(void)
 {
        struct ast_config *cfg;
        struct ast_variable *v;
@@ -1324,7 +1353,7 @@ static int load_module(void *mod)
        /* We *must* have a config file otherwise stop immediately */
        if (!cfg) {
                ast_log(LOG_ERROR, "Unable to load config %s\n", config);
-               return -1;
+               return AST_MODULE_LOAD_DECLINE;
        }
        if (ast_mutex_lock(&iflock)) {
                /* It's a little silly to lock it, but we mind as well just to be sure */
@@ -1350,12 +1379,14 @@ static int load_module(void *mod)
                } else if (!strcasecmp(v->name, "silencesupression")) {
                        silencesupression = ast_true(v->value);
                } else if (!strcasecmp(v->name, "language")) {
-                       strncpy(language, v->value, sizeof(language)-1);
+                       ast_copy_string(language, v->value, sizeof(language));
                } else if (!strcasecmp(v->name, "callerid")) {
                        ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
                } else if (!strcasecmp(v->name, "mode")) {
                        if (!strncasecmp(v->value, "di", 2)) 
                                mode = MODE_DIALTONE;
+                       else if (!strncasecmp(v->value, "sig", 3))
+                               mode = MODE_SIGMA;
                        else if (!strncasecmp(v->value, "im", 2))
                                mode = MODE_IMMEDIATE;
                        else if (!strncasecmp(v->value, "fxs", 3)) {
@@ -1367,9 +1398,11 @@ static int load_module(void *mod)
                        else
                                ast_log(LOG_WARNING, "Unknown mode: %s\n", v->value);
                } else if (!strcasecmp(v->name, "context")) {
-                       strncpy(context, v->value, sizeof(context)-1);
+                       ast_copy_string(context, v->value, sizeof(context));
                } else if (!strcasecmp(v->name, "format")) {
-                       if (!strcasecmp(v->value, "g723.1")) {
+                       if (!strcasecmp(v->value, "g729")) {
+                               prefformat = AST_FORMAT_G729A;
+                        } else if (!strcasecmp(v->value, "g723.1")) {
                                prefformat = AST_FORMAT_G723_1;
                        } else if (!strcasecmp(v->value, "slinear")) {
                                if (mode == MODE_FXS)
@@ -1419,16 +1452,4 @@ static int load_module(void *mod)
        return 0;
 }
 
-static const char *description(void)
-{
-       return (char *) desc;
-}
-
-static const char *key(void)
-{
-       return ASTERISK_GPL_KEY;
-}
-
-STD_MOD1;
-
-
+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Linux Telephony API Support");