Version 0.2.0 from FTP
[asterisk/asterisk.git] / channels / chan_modem_i4l.c
index f1e521a..553f144 100755 (executable)
@@ -17,7 +17,7 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <unistd.h>
-#include <pthread.h>
+#include <asterisk/lock.h>
 #include <asterisk/vmodem.h>
 #include <asterisk/module.h>
 #include <asterisk/frame.h>
@@ -33,7 +33,7 @@ static char *breakcmd = "\0x10\0x14\0x10\0x3";
 static char *desc = "ISDN4Linux Emulated Modem Driver";
 
 int usecnt;
-pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
 
 static char *i4l_idents[] = {
        /* Identify ISDN4Linux Driver */
@@ -58,7 +58,7 @@ static int i4l_setdev(struct ast_modem_pvt *p, int dev)
                return -1;
        }
        ast_modem_trim(p->response);
-       strncpy(cmd, p->response, sizeof(cmd));
+       strncpy(cmd, p->response, sizeof(cmd)-1);
        if (ast_modem_expect(p, "OK", 5)) {
                ast_log(LOG_WARNING, "Modem did not respond properly\n");
                return -1;
@@ -161,9 +161,9 @@ static int i4l_init(struct ast_modem_pvt *p)
                ast_log(LOG_WARNING, "Unable to set to transparent mode\n");
                return -1;
        }
-       if (ast_modem_send(p, "ATS23=1", 0) ||
+       if (ast_modem_send(p, "ATS23=9", 0) ||
             ast_modem_expect(p, "OK", 5)) {
-               ast_log(LOG_WARNING, "Unable to set to transparent mode\n");
+               ast_log(LOG_WARNING, "Unable to set to transparent/ringing mode\n");
                return -1;
        }
 
@@ -200,11 +200,15 @@ static struct ast_frame *i4l_handle_escape(struct ast_modem_pvt *p, char esc)
                p->fr.frametype = AST_FRAME_CONTROL;
                p->fr.subclass = AST_CONTROL_RING;
                return &p->fr;
+       case 'I': /* Pseudo ringing */
+               p->fr.frametype = AST_FRAME_CONTROL;
+               p->fr.subclass =  AST_CONTROL_RINGING;
+               return &p->fr;
        case 'X': /* Pseudo connect */
                p->fr.frametype = AST_FRAME_CONTROL;
                p->fr.subclass = AST_CONTROL_ANSWER;
                if (p->owner)
-                       p->owner->state = AST_STATE_UP;
+                       ast_setstate(p->owner, AST_STATE_UP);
                if (i4l_startrec(p))
                        return  NULL;
                return &p->fr;
@@ -287,12 +291,17 @@ static struct ast_frame *i4l_read(struct ast_modem_pvt *p)
                                return i4l_handle_escape(p, 'b');
                        } else
                        if (!strncasecmp(result, "CALLER NUMBER: ", 15 )) {
-                               strncpy(p->cid, result + 15, sizeof(p->cid));
+                               strncpy(p->cid, result + 15, sizeof(p->cid)-1);
                                return i4l_handle_escape(p, 'R');
                        } else
+                       if (!strcasecmp(result, "RINGING")) {
+                               if (option_verbose > 2)
+                                       ast_verbose(VERBOSE_PREFIX_3 "%s is ringing...\n", p->dev);
+                               return i4l_handle_escape(p, 'I');
+                       } else
                        if (!strncasecmp(result, "RING", 4)) {
                                if (result[4]=='/') 
-                                       strncpy(p->dnid, result + 4, sizeof(p->dnid));
+                                       strncpy(p->dnid, result + 4, sizeof(p->dnid)-1);
                                return i4l_handle_escape(p, 'R');
                        } else
                        if (!strcasecmp(result, "NO CARRIER")) {
@@ -377,7 +386,7 @@ static struct ast_frame *i4l_read(struct ast_modem_pvt *p)
 
 static int i4l_write(struct ast_modem_pvt *p, struct ast_frame *f)
 {
-#define MAX_WRITE_SIZE 512
+#define MAX_WRITE_SIZE 1024
        unsigned char result[MAX_WRITE_SIZE << 1];
        unsigned char b;
        int bpos=0, x;
@@ -407,8 +416,10 @@ static int i4l_write(struct ast_modem_pvt *p, struct ast_frame *f)
        res = write(p->fd, result, bpos);
 #endif
        if (res < 1) {
-               ast_log(LOG_WARNING, "Failed to write buffer\n");
-               return -1;
+               if (errno != EAGAIN) {
+                       ast_log(LOG_WARNING, "Failed to write buffer\n");
+                       return -1;
+               }
        }
 #if 0
        printf("Result of write is %d\n", res);
@@ -423,23 +434,23 @@ static char *i4l_identify(struct ast_modem_pvt *p)
 
 static void i4l_incusecnt()
 {
-       pthread_mutex_lock(&usecnt_lock);
+       ast_pthread_mutex_lock(&usecnt_lock);
        usecnt++;
-       pthread_mutex_unlock(&usecnt_lock);
+       ast_pthread_mutex_unlock(&usecnt_lock);
        ast_update_use_count();
 }
 
 static void i4l_decusecnt()
 {
-       pthread_mutex_lock(&usecnt_lock);
+       ast_pthread_mutex_lock(&usecnt_lock);
        usecnt++;
-       pthread_mutex_unlock(&usecnt_lock);
+       ast_pthread_mutex_unlock(&usecnt_lock);
        ast_update_use_count();
 }
 
 static int i4l_answer(struct ast_modem_pvt *p)
 {
-       if (ast_modem_send(p, "ATA", 0) ||
+       if (ast_modem_send(p, "ATA\r", 4) ||
             ast_modem_expect(p, "VCON", 10)) {
                ast_log(LOG_WARNING, "Unable to answer: %s", p->response);
                return -1;
@@ -475,8 +486,8 @@ static int i4l_dialdigit(struct ast_modem_pvt *p, char digit)
 static int i4l_dial(struct ast_modem_pvt *p, char *stuff)
 {
        char cmd[80];
-       snprintf(cmd, sizeof(cmd), "ATD%c %s", p->dialtype,stuff);
-       if (ast_modem_send(p, cmd, 0)) {
+       snprintf(cmd, sizeof(cmd), "ATD%c %s\n", p->dialtype,stuff);
+       if (ast_modem_send(p, cmd, strlen(cmd))) {
                ast_log(LOG_WARNING, "Unable to dial\n");
                return -1;
        }
@@ -551,9 +562,9 @@ static struct ast_modem_driver i4l_driver =
 int usecount(void)
 {
        int res;
-       pthread_mutex_lock(&usecnt_lock);
+       ast_pthread_mutex_lock(&usecnt_lock);
        res = usecnt;
-       pthread_mutex_unlock(&usecnt_lock);
+       ast_pthread_mutex_unlock(&usecnt_lock);
        return res;
 }