Version 0.1.12 from FTP
[asterisk/asterisk.git] / channels / chan_phone.c
index 6b59574..b7f82ea 100755 (executable)
@@ -126,6 +126,7 @@ static int phone_digit(struct ast_channel *ast, char digit)
                return -1;
        }
        ioctl(p->fd, PHONE_PLAY_TONE, digit);
+       p->lastformat = -1;
        return 0;
 }
 
@@ -206,7 +207,7 @@ static int phone_setup(struct ast_channel *ast)
        p = ast->pvt->pvt;
        ioctl(p->fd, PHONE_CPT_STOP);
        /* Nothing to answering really, just start recording */
-       if (ast->format & AST_FORMAT_G723_1) {
+       if (ast->pvt->rawreadformat == AST_FORMAT_G723_1) {
                /* Prefer g723 */
                ioctl(p->fd, PHONE_REC_STOP);
                if (p->lastinput != AST_FORMAT_G723_1) {
@@ -216,7 +217,7 @@ static int phone_setup(struct ast_channel *ast)
                                return -1;
                        }
                }
-       } else if (ast->format & AST_FORMAT_SLINEAR) {
+       } else if (ast->pvt->rawreadformat == AST_FORMAT_SLINEAR) {
                ioctl(p->fd, PHONE_REC_STOP);
                if (p->lastinput != AST_FORMAT_SLINEAR) {
                        p->lastinput = AST_FORMAT_SLINEAR;
@@ -226,7 +227,7 @@ static int phone_setup(struct ast_channel *ast)
                        }
                }
        } else {
-               ast_log(LOG_WARNING, "Can't do format %d\n", ast->format);
+               ast_log(LOG_WARNING, "Can't do format %d\n", ast->pvt->rawreadformat);
                return -1;
        }
        if (ioctl(p->fd, PHONE_REC_START)) {
@@ -267,7 +268,7 @@ static char phone_2digit(char c)
                return '?';
 }
 
-static struct ast_frame  *phone_read(struct ast_channel *ast)
+static struct ast_frame  *phone_exception(struct ast_channel *ast)
 {
        int res;
        union telephony_exception phonee;
@@ -284,7 +285,8 @@ static struct ast_frame  *phone_read(struct ast_channel *ast)
 
        phonee.bytes = ioctl(p->fd, PHONE_EXCEPTION);
        if (phonee.bits.dtmf_ready)  {
-               ast_log(LOG_DEBUG, "phone_read(): DTMF\n");
+               if (option_debug)
+                       ast_log(LOG_DEBUG, "phone_exception(): DTMF\n");
        
                /* We've got a digit -- Just handle this nicely and easily */
                digit =  ioctl(p->fd, PHONE_GET_DTMF_ASCII);
@@ -293,10 +295,12 @@ static struct ast_frame  *phone_read(struct ast_channel *ast)
                return &p->fr;
        }
        if (phonee.bits.hookstate) {
-               ast_log(LOG_DEBUG, "Hookstate changed\n");
+               if (option_debug)
+                       ast_log(LOG_DEBUG, "Hookstate changed\n");
                res = ioctl(p->fd, PHONE_HOOKSTATE);
                /* See if we've gone on hook, if so, notify by returning NULL */
-               ast_log(LOG_DEBUG, "New hookstate: %d\n", res);
+               if (option_debug)
+                       ast_log(LOG_DEBUG, "New hookstate: %d\n", res);
                if (!res && (p->mode != MODE_FXO))
                        return NULL;
                else {
@@ -320,6 +324,25 @@ static struct ast_frame  *phone_read(struct ast_channel *ast)
        if (phonee.bits.pstn_wink)
                ast_verbose("Detected Wink\n");
 #endif
+       /* Strange -- nothing there.. */
+       p->fr.frametype = AST_FRAME_NULL;
+       p->fr.subclass = 0;
+       return &p->fr;
+}
+
+static struct ast_frame  *phone_read(struct ast_channel *ast)
+{
+       int res;
+       struct phone_pvt *p = ast->pvt->pvt;
+
+       /* Some nice norms */
+       p->fr.datalen = 0;
+       p->fr.timelen = 0;
+       p->fr.data =  NULL;
+       p->fr.src = type;
+       p->fr.offset = 0;
+       p->fr.mallocd=0;
+
        /* Try to read some data... */
        CHECK_BLOCKING(ast);
        res = read(p->fd, p->buf, PHONE_MAX_BUF);
@@ -396,6 +419,7 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
        char *pos;
        int sofar;
        int expected;
+       int codecset = 0;
        char tmpbuf[4];
        /* Write a frame of (presumably voice) data */
        if (frame->frametype != AST_FRAME_VOICE) {
@@ -429,6 +453,7 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
                        p->lastinput = AST_FORMAT_G723_1;
                        /* Reset output buffer */
                        p->obuflen = 0;
+                       codecset = 1;
                }
                if (frame->datalen > 24) {
                        ast_log(LOG_WARNING, "Frame size too large for G.723.1 (%d bytes)\n", frame->datalen);
@@ -449,20 +474,23 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
                        }
                        p->lastformat = AST_FORMAT_SLINEAR;
                        p->lastinput = AST_FORMAT_SLINEAR;
+                       codecset = 1;
                        /* Reset output buffer */
                        p->obuflen = 0;
                }
                maxfr = 480;
        }
-       ioctl(p->fd, PHONE_REC_DEPTH, 3);
-       ioctl(p->fd, PHONE_PLAY_DEPTH, 3);
-       if (ioctl(p->fd, PHONE_PLAY_START)) {
-               ast_log(LOG_WARNING, "Failed to start playback\n");
-               return -1;
-       }
-       if (ioctl(p->fd, PHONE_REC_START)) {
-               ast_log(LOG_WARNING, "Failed to start recording\n");
-               return -1;
+       if (codecset) {
+               ioctl(p->fd, PHONE_REC_DEPTH, 3);
+               ioctl(p->fd, PHONE_PLAY_DEPTH, 3);
+               if (ioctl(p->fd, PHONE_PLAY_START)) {
+                       ast_log(LOG_WARNING, "Failed to start playback\n");
+                       return -1;
+               }
+               if (ioctl(p->fd, PHONE_REC_START)) {
+                       ast_log(LOG_WARNING, "Failed to start recording\n");
+                       return -1;
+               }
        }
        /* If we get here, we have a voice frame of Appropriate data */
        sofar = 0;
@@ -508,7 +536,7 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *conte
                tmp->type = type;
                tmp->fd = i->fd;
                /* XXX Switching formats silently causes kernel panics XXX */
-               tmp->format = prefformat;
+               tmp->nativeformats = prefformat;
                tmp->state = state;
                if (state == AST_STATE_RING)
                        tmp->rings = 1;
@@ -519,6 +547,7 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *conte
                tmp->pvt->answer = phone_answer;
                tmp->pvt->read = phone_read;
                tmp->pvt->write = phone_write;
+               tmp->pvt->exception = phone_exception;
                strncpy(tmp->context, context, sizeof(tmp->context));
                if (strlen(i->ext))
                        strncpy(tmp->exten, i->ext, sizeof(tmp->exten));
@@ -626,6 +655,7 @@ static void phone_check_exception(struct phone_pvt *i)
                                ioctl(i->fd, PHONE_PLAY_STOP);
                                ioctl(i->fd, PHONE_PLAY_CODEC, ULAW);
                                ioctl(i->fd, PHONE_PLAY_START);
+                               i->lastformat = -1;
                        }
                } else {
                        if (i->dialtone) {
@@ -639,6 +669,7 @@ static void phone_check_exception(struct phone_pvt *i)
                        ioctl(i->fd, PHONE_PLAY_STOP);
                        ioctl(i->fd, PHONE_REC_STOP);
                        i->dialtone = 0;
+                       i->lastformat = -1;
                }
        }
        if (phonee.bits.pstn_ring) {
@@ -1041,3 +1072,7 @@ char *description()
        return desc;
 }
 
+char *key()
+{
+       return ASTERISK_GPL_KEY;
+}