Add a massive set of changes for converting to use the ast_debug() macro.
[asterisk/asterisk.git] / channels / chan_phone.c
index a165cf2..e33d1a1 100644 (file)
@@ -48,9 +48,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #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/lock.h"
@@ -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);
@@ -162,7 +156,7 @@ 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_begin(struct ast_channel *ast, char digit);
-static int phone_digit_end(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);
@@ -176,7 +170,7 @@ static int phone_indicate(struct ast_channel *chan, int condition, const void *d
 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_begin = phone_digit_begin,
        .send_digit_end = phone_digit_end,
@@ -214,8 +208,7 @@ static int phone_indicate(struct ast_channel *chan, int condition, const void *d
 {
        struct phone_pvt *p = chan->tech_pvt;
        int res=-1;
-       if (option_debug)
-               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);
@@ -250,12 +243,12 @@ static int phone_digit_begin(struct ast_channel *chan, char digit)
        return 0;
 }
 
-static int phone_digit_end(struct ast_channel *ast, char digit)
+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':
@@ -286,7 +279,7 @@ static int phone_digit_end(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;
@@ -326,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)
@@ -339,7 +331,7 @@ static int phone_call(struct ast_channel *ast, char *dest, int timeout)
                {
                  digit++;
                  while (*digit)
-                   phone_digit_end(ast, *digit++);
+                   phone_digit_end(ast, *digit++, 0);
                }
        }
  
@@ -352,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;
@@ -371,16 +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)) { 
-                       if (option_debug)
-                               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;
        }
@@ -391,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;
@@ -411,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;
@@ -469,18 +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)) {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n", ast->name, strerror(errno));
-               }
-               else {
-                       if (option_debug)
-                               ast_log(LOG_DEBUG, "Took linejack off hook\n");
-               }
+               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_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;
@@ -518,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);
@@ -528,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 {
@@ -679,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;
@@ -696,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);
@@ -844,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 &&
@@ -869,7 +875,7 @@ 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;
@@ -888,10 +894,7 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *conte
                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);
@@ -926,8 +929,7 @@ static void phone_check_exception(struct phone_pvt *i)
        union telephony_exception phonee;
        /* XXX Do something XXX */
 #if 0
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Exception!\n");
+       ast_debug(1, "Exception!\n");
 #endif
        phonee.bytes = ioctl(i->fd, PHONE_EXCEPTION);
        if (phonee.bits.dtmf_ready)  {
@@ -955,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;
                                }
@@ -972,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 */
@@ -985,10 +983,7 @@ static void phone_check_exception(struct phone_pvt *i)
                                ioctl(i->fd, PHONE_PLAY_START);
                                i->lastformat = -1;
                        } else if (i->mode == MODE_SIGMA) {
-                               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 */
@@ -996,12 +991,8 @@ static void phone_check_exception(struct phone_pvt *i)
                                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)
                        {
@@ -1093,8 +1084,7 @@ static void *do_monitor(void *data)
                }
                /* Okay, select has finished.  Let's see what happened.  */
                if (res < 0) {
-                       if (option_debug)
-                               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
@@ -1172,32 +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)) {
-                               if (option_debug)
-                                       ast_log(LOG_DEBUG, "Unable to set port to PSTN\n");
+                               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)) {
-                       if (option_debug)
-                               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) 
@@ -1245,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])) {
@@ -1262,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;
@@ -1337,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);
@@ -1413,7 +1400,9 @@ static int load_module(void)
                } else if (!strcasecmp(v->name, "context")) {
                        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)