Blocked revisions 36725 via svnmerge
[asterisk/asterisk.git] / channels / chan_vpb.c
index f735e3d..d615e60 100644 (file)
  * \ingroup channel_drivers
  */
 
+/*** MODULEINFO
+       <depend>vpbapi</depend>
+ ***/
 
 extern "C" {
 
-#include <stdio.h>
-#include <string.h>
-
 #include "asterisk.h"
 
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
+#include <stdio.h>
+#include <string.h>
+
 #include "asterisk/lock.h"
 #include "asterisk/utils.h"
 #include "asterisk/channel.h"
@@ -93,7 +96,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 /**/
 
 static const char desc[] = "VoiceTronix V6PCI/V12PCI/V4PCI  API Support";
-static const char type[] = "vpb";
 static const char tdesc[] = "Standard VoiceTronix API Driver";
 static const char config[] = "vpb.conf";
 
@@ -150,7 +152,9 @@ static VPB_TONE Ringbacktone = {440, 480,   0, -20,   -20, -100,  2000, 4000};
 #endif
 
 /* grunt tone defn's */
+#if 0
 static VPB_DETECT toned_grunt = { 3, VPB_GRUNT, 1, 2000, 3000, 0, 0, -40, 0, 0, 0, 40, { { VPB_DELAY, 1000, 0, 0 }, { VPB_RISING, 0, 40, 0 }, { 0, 100, 0, 0 } } };
+#endif
 static VPB_DETECT toned_ungrunt = { 2, VPB_GRUNT, 1, 2000, 1, 0, 0, -40, 0, 0, 30, 40, { { 0, 0, 0, 0 } } };
 
 /* Use loop polarity detection for CID */
@@ -344,18 +348,20 @@ static int vpb_hangup(struct ast_channel *ast);
 static int vpb_answer(struct ast_channel *ast);
 static struct ast_frame *vpb_read(struct ast_channel *ast);
 static int vpb_write(struct ast_channel *ast, struct ast_frame *frame);
-static enum ast_bridge_result vpb_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
-static int vpb_indicate(struct ast_channel *ast, int condition);
+static enum ast_bridge_result ast_vpb_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
+static int vpb_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
 static int vpb_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
 
 static struct ast_channel_tech vpb_tech = {
-       type: type,
+       type: "vpb",
        description: tdesc,
        capabilities: AST_FORMAT_SLINEAR,
-       properties: NULL,
+       properties: 0,
        requester: vpb_request,
        devicestate: NULL,
        send_digit: vpb_digit,
+       send_digit_begin: NULL,
+       send_digit_end: NULL,
        call: vpb_call,
        hangup: vpb_hangup,
        answer: vpb_answer,
@@ -365,7 +371,7 @@ static struct ast_channel_tech vpb_tech = {
        send_image: NULL,
        send_html: NULL,
        exception: NULL,
-       bridge: vpb_bridge,
+       bridge: ast_vpb_bridge,
        indicate: vpb_indicate,
        fixup: vpb_fixup,
        setoption: NULL,
@@ -376,13 +382,15 @@ static struct ast_channel_tech vpb_tech = {
 };
 
 static struct ast_channel_tech vpb_tech_indicate = {
-       type: type,
+       type: "vpb",
        description: tdesc,
        capabilities: AST_FORMAT_SLINEAR,
-       properties: NULL,
+       properties: 0,
        requester: vpb_request,
        devicestate: NULL,
        send_digit: vpb_digit,
+       send_digit_begin: NULL,
+       send_digit_end: NULL,
        call: vpb_call,
        hangup: vpb_hangup,
        answer: vpb_answer,
@@ -392,7 +400,7 @@ static struct ast_channel_tech vpb_tech_indicate = {
        send_image: NULL,
        send_html: NULL,
        exception: NULL,
-       bridge: vpb_bridge,
+       bridge: ast_vpb_bridge,
        indicate: NULL,
        fixup: vpb_fixup,
        setoption: NULL,
@@ -402,7 +410,7 @@ static struct ast_channel_tech vpb_tech_indicate = {
        bridged_channel: NULL
 };
 
-/* Can't get vpb_bridge() working on v4pci without either a horrible 
+/* Can't get ast_vpb_bridge() working on v4pci without either a horrible 
 *  high pitched feedback noise or bad hiss noise depending on gain settings
 *  Get asterisk to do the bridging
 */
@@ -414,7 +422,7 @@ static struct ast_channel_tech vpb_tech_indicate = {
 /* #define HALF_DUPLEX_BRIDGE */
 
 /* This is the Native bridge code, which Asterisk will try before using its own bridging code */
-static enum ast_bridge_result vpb_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
+static enum ast_bridge_result ast_vpb_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
 {
        struct vpb_pvt *p0 = (struct vpb_pvt *)c0->tech_pvt;
        struct vpb_pvt *p1 = (struct vpb_pvt *)c1->tech_pvt;
@@ -476,6 +484,9 @@ static enum ast_bridge_result vpb_bridge(struct ast_channel *c0, struct ast_chan
                        ast_verbose(VERBOSE_PREFIX_2 "%s: vpb_bridge: Bridging call entered with [%s, %s]\n",p0->dev, c0->name, c1->name);
        }
 
+       if (option_verbose > 2) 
+               ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name);
+
        #ifdef HALF_DUPLEX_BRIDGE
 
        if (option_verbose>1) 
@@ -640,7 +651,7 @@ static void get_callerid(struct vpb_pvt *p)
                }
 
                if (option_verbose>3) 
-                       ast_verbose(VERBOSE_PREFIX_4 "CID record - skipped %ldms trailing ring\n",
+                       ast_verbose(VERBOSE_PREFIX_4 "CID record - skipped %dms trailing ring\n",
                                 ast_tvdiff_ms(ast_tvnow(), cid_record_time));
                cid_record_time = ast_tvnow();
 
@@ -655,7 +666,7 @@ static void get_callerid(struct vpb_pvt *p)
 #endif
 
                if (option_verbose>3) 
-                       ast_verbose(VERBOSE_PREFIX_4 "CID record - recorded %ldms between rings\n", 
+                       ast_verbose(VERBOSE_PREFIX_4 "CID record - recorded %dms between rings\n", 
                                 ast_tvdiff_ms(ast_tvnow(), cid_record_time));
 
                ast_mutex_unlock(&p->record_lock);
@@ -793,18 +804,14 @@ static void get_callerid_ast(struct vpb_pvt *p)
        }
        if (number)
                ast_shrink_phone_number(number);
-       if (!ast_strlen_zero(number)) {
-               owner->cid.cid_num = strdup(number);
-               owner->cid.cid_ani = strdup(number);
-               if (!ast_strlen_zero(name)){
-                       owner->cid.cid_name = strdup(name);
-                       snprintf(p->callerid,(sizeof(p->callerid)-1),"%s %s",number,name);
-               }
-               else {
-                       snprintf(p->callerid,(sizeof(p->callerid)-1),"%s",number);
-               }
+       ast_set_callerid(owner,
+               number, name,
+               owner->cid.cid_ani ? NULL : number);
+       if (!ast_strlen_zero(name)){
+               snprintf(p->callerid,(sizeof(p->callerid)-1),"%s %s",number,name);
+       } else {
+               snprintf(p->callerid,(sizeof(p->callerid)-1),"%s",number);
        }
-                                                                                                                    
        if (cs)
                callerid_free(cs);
 }
@@ -847,7 +854,7 @@ static inline int monitor_handle_owned(struct vpb_pvt *p, VPB_EVENT *e)
        if (option_verbose > 3) 
                ast_verbose(VERBOSE_PREFIX_4 "%s: handle_owned: got event: [%d=>%d]\n", p->dev, e->type, e->data);
 
-       f.src = (char *)type;
+       f.src = "vpb";
        switch (e->type) {
                case VPB_RING:
                        if (p->mode == MODE_FXO) {
@@ -915,7 +922,7 @@ static inline int monitor_handle_owned(struct vpb_pvt *p, VPB_EVENT *e)
                        else if (e->data == VPB_FAX){
                                if (!p->faxhandled){
                                        if (strcmp(p->owner->exten, "fax")) {
-                                               const char *target_context = ast_strlen_zero(p->owner->macrocontext) ? p->owner->context : p->owner->macrocontext;
+                                               const char *target_context = S_OR(p->owner->macrocontext, p->owner->context);
                                                
                                                if (ast_exists_extension(p->owner, target_context, "fax", 1, p->owner->cid.cid_num)) {
                                                        if (option_verbose > 2)
@@ -1128,7 +1135,7 @@ static inline int monitor_handle_notowned(struct vpb_pvt *p, VPB_EVENT *e)
                                                ast_verbose(VERBOSE_PREFIX_4 "Using VPB Caller ID\n");
                                        get_callerid(p);        /* UK CID before 1st ring*/
                                }
-/*                             get_callerid_ast(p);    /* Caller ID using the ast functions */
+/*                             get_callerid_ast(p); */   /* Caller ID using the ast functions */
                        }
                        break;
                case VPB_RING:
@@ -1709,7 +1716,7 @@ static struct vpb_pvt *mkif(int board, int channel, int mode, int gains, float t
        return tmp;
 }
 
-static int vpb_indicate(struct ast_channel *ast, int condition)
+static int vpb_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
 {
        struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt;
        int res = 0;
@@ -1807,7 +1814,7 @@ static int vpb_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
                else {
                        if (option_verbose > 3)
                                ast_verbose(VERBOSE_PREFIX_4 "%s: vpb_fixup Calling vpb_indicate\n", p->dev);
-                       vpb_indicate(newchan, AST_CONTROL_RINGING);
+                       vpb_indicate(newchan, AST_CONTROL_RINGING, NULL, 0);
                }
        }
 
@@ -2178,7 +2185,7 @@ static struct ast_frame  *vpb_read(struct ast_channel *ast)
        struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt; 
        static struct ast_frame f = {AST_FRAME_NULL}; 
 
-       f.src = (char *)type;
+       f.src = "vpb";
        ast_log(LOG_NOTICE, "%s: vpb_read: should never be called!\n", p->dev);
        ast_verbose("%s: vpb_read: should never be called!\n", p->dev);
 
@@ -2253,7 +2260,6 @@ static int vpb_write(struct ast_channel *ast, struct ast_frame *frame)
        struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt; 
        int res = 0, fmt = 0;
        struct timeval play_buf_time_start;
-       struct ast_frame *nextf;
        int tdiff;
 
 /*     ast_mutex_lock(&p->lock); */
@@ -2358,10 +2364,10 @@ static void *do_chanreads(void *pvt)
        int bridgerec = 0;
        int afmt, readlen, res, fmt, trycnt=0;
        int ignore_dtmf;
-       char * getdtmf_var = NULL;
+       const char * getdtmf_var = NULL;
 
        fr->frametype = AST_FRAME_VOICE;
-       fr->src = (char *)type;
+       fr->src = "vpb";
        fr->mallocd = 0;
        fr->delivery.tv_sec = 0;
        fr->delivery.tv_usec = 0;
@@ -2628,8 +2634,7 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, int state, char *context)
                        tmp->tech = &vpb_tech;
                }
 
-               strncpy(tmp->name, me->dev, sizeof(tmp->name) - 1);
-               tmp->type = type;
+               ast_string_field_set(tmp, name, me->dev);
                
                tmp->callgroup = me->callgroup;
                tmp->pickupgroup = me->pickupgroup;
@@ -2657,7 +2662,7 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, int state, char *context)
                else
                        strncpy(tmp->exten, "s",  sizeof(tmp->exten) - 1);
                if (strlen(me->language))
-                       strncpy(tmp->language, me->language, sizeof(tmp->language)-1);
+                       ast_string_field_set(tmp, language, me->language);
 
                me->owner = tmp;
      
@@ -2767,6 +2772,72 @@ static float parse_gain_value(char *gain_type, char *value)
        return gain;
 }
 
+
+int unload_module()
+{
+       struct vpb_pvt *p;
+       /* First, take us out of the channel loop */
+       if (use_ast_ind == 1){
+               ast_channel_unregister(&vpb_tech_indicate);
+       }
+       else {
+               ast_channel_unregister(&vpb_tech);
+       }
+
+       ast_mutex_lock(&iflock); {
+               /* Hangup all interfaces if they have an owner */
+               p = iflist;
+               while(p) {
+                       if (p->owner)
+                               ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
+                       p = p->next;
+               }
+               iflist = NULL;
+       } ast_mutex_unlock(&iflock);
+
+       ast_mutex_lock(&monlock); {
+               if (mthreadactive > -1) {
+                       pthread_cancel(monitor_thread);
+                       pthread_join(monitor_thread, NULL);
+               }
+               mthreadactive = -2;
+       } ast_mutex_unlock(&monlock);
+
+       ast_mutex_lock(&iflock); {
+               /* Destroy all the interfaces and free their memory */
+
+               while(iflist) {
+                       p = iflist;                 
+                       ast_mutex_destroy(&p->lock);
+                       pthread_cancel(p->readthread);
+                       ast_mutex_destroy(&p->owner_lock);
+                       ast_mutex_destroy(&p->record_lock);
+                       ast_mutex_destroy(&p->play_lock);
+                       ast_mutex_destroy(&p->play_dtmf_lock);
+                       p->readthread = 0;
+
+                       vpb_close(p->handle);
+
+                       iflist = iflist->next;
+
+                       free(p);
+               }
+               iflist = NULL;
+       } ast_mutex_unlock(&iflock);
+
+       ast_mutex_lock(&bridge_lock); {
+               memset(bridges, 0, sizeof bridges);          
+       } ast_mutex_unlock(&bridge_lock);
+       ast_mutex_destroy(&bridge_lock);
+       for(int i = 0; i < max_bridges; i++ ) {
+               ast_mutex_destroy(&bridges[i].lock);
+               ast_cond_destroy(&bridges[i].cond);
+       }
+       free(bridges);
+
+       return 0;
+}
+
 int load_module()
 {
        struct ast_config *cfg;
@@ -2937,7 +3008,7 @@ int load_module()
 
        if (use_ast_ind == 1){
                if (!error && ast_channel_register(&vpb_tech_indicate) != 0) {
-                       ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
+                       ast_log(LOG_ERROR, "Unable to register channel class 'vpb'\n");
                        error = -1;
                }
                else {
@@ -2946,7 +3017,7 @@ int load_module()
        }
        else {
                if (!error && ast_channel_register(&vpb_tech) != 0) {
-                       ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
+                       ast_log(LOG_ERROR, "Unable to register channel class 'vpb'\n");
                        error = -1;
                }
                else {
@@ -2963,83 +3034,17 @@ int load_module()
        return error;
 }
 
-
-int unload_module()
-{
-       struct vpb_pvt *p;
-       /* First, take us out of the channel loop */
-       if (use_ast_ind == 1){
-               ast_channel_unregister(&vpb_tech_indicate);
-       }
-       else {
-               ast_channel_unregister(&vpb_tech);
-       }
-
-       ast_mutex_lock(&iflock); {
-               /* Hangup all interfaces if they have an owner */
-               p = iflist;
-               while(p) {
-                       if (p->owner)
-                               ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
-                       p = p->next;
-               }
-               iflist = NULL;
-       } ast_mutex_unlock(&iflock);
-
-       ast_mutex_lock(&monlock); {
-               if (mthreadactive > -1) {
-                       pthread_cancel(monitor_thread);
-                       pthread_join(monitor_thread, NULL);
-               }
-               mthreadactive = -2;
-       } ast_mutex_unlock(&monlock);
-
-       ast_mutex_lock(&iflock); {
-               /* Destroy all the interfaces and free their memory */
-
-               while(iflist) {
-                       p = iflist;                 
-                       ast_mutex_destroy(&p->lock);
-                       pthread_cancel(p->readthread);
-                       ast_mutex_destroy(&p->owner_lock);
-                       ast_mutex_destroy(&p->record_lock);
-                       ast_mutex_destroy(&p->play_lock);
-                       ast_mutex_destroy(&p->play_dtmf_lock);
-                       p->readthread = 0;
-
-                       vpb_close(p->handle);
-
-                       iflist = iflist->next;
-
-                       free(p);
-               }
-               iflist = NULL;
-       } ast_mutex_unlock(&iflock);
-
-       ast_mutex_lock(&bridge_lock); {
-               memset(bridges, 0, sizeof bridges);          
-       } ast_mutex_unlock(&bridge_lock);
-       ast_mutex_destroy(&bridge_lock);
-       for(int i = 0; i < max_bridges; i++ ) {
-               ast_mutex_destroy(&bridges[i].lock);
-               ast_cond_destroy(&bridges[i].cond);
-       }
-       free(bridges);
-
-       return 0;
-}
-
 int usecount()
 {
        return usecnt;
 }
 
-char *description()
+const char *description()
 {
        return (char *) desc;
 }
 
-char *key()
+const char *key()
 {
        return ASTERISK_GPL_KEY;
 }
@@ -3049,3 +3054,5 @@ char *key()
  }
 #endif
 /**/
+
+