Migrate a large number of AMI events over to Stasis-Core
[asterisk/asterisk.git] / apps / app_minivm.c
index 3445b7e..ba6d6e5 100644 (file)
@@ -26,7 +26,6 @@
  * based on the Comedian Mail voicemail system (app_voicemail.c).
  * 
  * \par See also
- * \arg \ref Config_minivm
  * \arg \ref Config_minivm_examples
  * \arg \ref App_minivm
  *
@@ -167,14 +166,15 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/say.h"
 #include "asterisk/module.h"
 #include "asterisk/app.h"
-#include "asterisk/manager.h"
 #include "asterisk/dsp.h"
 #include "asterisk/localtime.h"
 #include "asterisk/cli.h"
 #include "asterisk/utils.h"
 #include "asterisk/linkedlists.h"
 #include "asterisk/callerid.h"
-#include "asterisk/event.h"
+#include "asterisk/stasis.h"
+#include "asterisk/stasis_channels.h"
+#include "asterisk/json.h"
 
 /*** DOCUMENTATION
 <application name="MinivmRecord" language="en_US">
@@ -496,7 +496,23 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
                <ref type="function">MINIVMCOUNTER</ref>
        </see-also>
 </function>
-
+       <managerEvent language="en_US" name="MiniVoiceMail">
+               <managerEventInstance class="EVENT_FLAG_CALL">
+                       <synopsis>Raised when a notification is sent out by a MiniVoiceMail application</synopsis>
+                       <syntax>
+                               <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
+                               <parameter name="Action">
+                                       <para>What action was taken. Currently, this will always be <literal>SentNotification</literal></para>
+                               </parameter>
+                               <parameter name="Mailbox">
+                                       <para>The mailbox that the notification was about, specified as <literal>mailbox</literal>@<literal>context</literal></para>
+                               </parameter>
+                               <parameter name="Counter">
+                                       <para>A message counter derived from the <literal>MVM_COUNTER</literal> channel variable.</para>
+                               </parameter>
+                       </syntax>
+               </managerEventInstance>
+       </managerEvent>
 ***/
 
 #ifndef TRUE
@@ -1159,7 +1175,6 @@ static const char *ast_str_encode_mime(struct ast_str **end, ssize_t maxlen, con
 {
        struct ast_str *tmp = ast_str_alloca(80);
        int first_section = 1;
-       *end = '\0';
 
        ast_str_reset(*end);
        ast_str_set(&tmp, -1, "=?%s?Q?", charset);
@@ -1229,6 +1244,7 @@ static int sendmail(struct minivm_template *template, struct minivm_account *vmu
        char dur[PATH_MAX];
        char tmp[80] = "/tmp/astmail-XXXXXX";
        char tmp2[PATH_MAX];
+       char newtmp[PATH_MAX]; /* Only used with volgain */
        struct timeval now;
        struct ast_tm tm;
        struct minivm_zone *the_zone = NULL;
@@ -1255,6 +1271,8 @@ static int sendmail(struct minivm_template *template, struct minivm_account *vmu
 
        if (ast_strlen_zero(email)) {
                ast_log(LOG_WARNING, "No address to send message to.\n");
+               ast_free(str1);
+               ast_free(str2);
                return -1;      
        }
 
@@ -1266,26 +1284,23 @@ static int sendmail(struct minivm_template *template, struct minivm_account *vmu
 
        /* If we have a gain option, process it now with sox */
        if (type == MVM_MESSAGE_EMAIL && (vmu->volgain < -.001 || vmu->volgain > .001) ) {
-               char newtmp[PATH_MAX];
                char tmpcmd[PATH_MAX];
                int tmpfd;
 
-               /**
-                * XXX
-                * /bug tmpfd is a leaked fd.  The file is also never unlinked.
-                *      See app_voicemail.c for how the code works there that
-                *      doesn't have this bug.
-                */
-
                ast_copy_string(newtmp, "/tmp/XXXXXX", sizeof(newtmp));
                ast_debug(3, "newtmp: %s\n", newtmp);
                tmpfd = mkstemp(newtmp);
-               if (tmpfd > -1) {
-                       snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, filename, format, newtmp, format);
-                       ast_safe_system(tmpcmd);
-                       finalfilename = newtmp;
-                       ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", filename, format, vmu->volgain, vmu->username);
+               if (tmpfd < 0) {
+                       ast_log(LOG_WARNING, "Failed to create temporary file for volgain: %d\n", errno);
+                       ast_free(str1);
+                       ast_free(str2);
+                       return -1;
                }
+               snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, filename, format, newtmp, format);
+               ast_safe_system(tmpcmd);
+               close(tmpfd);
+               finalfilename = newtmp;
+               ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", filename, format, vmu->volgain, vmu->username);
        } else {
                finalfilename = ast_strdupa(filename);
        }
@@ -1309,10 +1324,17 @@ static int sendmail(struct minivm_template *template, struct minivm_account *vmu
        }
        if (!p) {
                ast_log(LOG_WARNING, "Unable to open temporary file '%s'\n", tmp);
+               ast_free(str1);
+               ast_free(str2);
                return -1;
        }
        /* Allocate channel used for chanvar substitution */
        ast = ast_dummy_channel_alloc();
+       if (!ast) {
+               ast_free(str1);
+               ast_free(str2);
+               return -1;
+       }
 
        snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
 
@@ -1473,8 +1495,7 @@ static int sendmail(struct minivm_template *template, struct minivm_account *vmu
        ast_safe_system(tmp2);
        ast_debug(1, "Sent message to %s with command '%s' - %s\n", vmu->email, global_mailcmd, template->attachment ? "(media attachment)" : "");
        ast_debug(3, "Actual command used: %s\n", tmp2);
-       if (ast)
-               ast = ast_channel_release(ast);
+       ast = ast_channel_unref(ast);
        ast_free(str1);
        ast_free(str2);
        return 0;
@@ -1541,7 +1562,7 @@ static int invent_message(struct ast_channel *chan, char *domain, char *username
        snprintf(fn, sizeof(fn), "%s%s/%s/greet", MVM_SPOOL_DIR, domain, username);
 
        if (ast_fileexists(fn, NULL, NULL) > 0) {
-               res = ast_streamfile(chan, fn, chan->language);
+               res = ast_streamfile(chan, fn, ast_channel_language(chan));
                if (res) 
                        return -1;
                res = ast_waitstream(chan, ecodes);
@@ -1563,23 +1584,23 @@ static int invent_message(struct ast_channel *chan, char *domain, char *username
                }
 
                if (numericusername) {
-                       if (ast_streamfile(chan, "vm-theperson", chan->language))
+                       if (ast_streamfile(chan, "vm-theperson", ast_channel_language(chan)))
                                return -1;
                        if ((res = ast_waitstream(chan, ecodes)))
                                return res;
 
-                       res = ast_say_digit_str(chan, username, ecodes, chan->language);
+                       res = ast_say_digit_str(chan, username, ecodes, ast_channel_language(chan));
                        if (res)
                                return res;
                } else {
-                       if (ast_streamfile(chan, "vm-theextensionis", chan->language))
+                       if (ast_streamfile(chan, "vm-theextensionis", ast_channel_language(chan)))
                                return -1;
                        if ((res = ast_waitstream(chan, ecodes)))
                                return res;
                }
        }
 
-       res = ast_streamfile(chan, busy ? "vm-isonphone" : "vm-isunavail", chan->language);
+       res = ast_streamfile(chan, busy ? "vm-isonphone" : "vm-isunavail", ast_channel_language(chan));
        if (res)
                return -1;
        res = ast_waitstream(chan, ecodes);
@@ -1603,7 +1624,7 @@ static int vm_delete(char *file)
 /*!\internal
  * \brief Record voicemail message & let caller review or re-record it, or set options if applicable */
 static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt,
-                             int outsidecaller, struct minivm_account *vmu, int *duration, const char *unlockdir,
+                             int outsidecaller, struct minivm_account *vmu, int *duration, int *sound_duration, const char *unlockdir,
                              signed char record_gain)
 {
        int cmd = 0;
@@ -1635,7 +1656,7 @@ static int play_record_review(struct ast_channel *chan, char *playfile, char *re
                case '2':
                        /* Review */
                        ast_verb(3, "Reviewing the message\n");
-                       ast_streamfile(chan, recordfile, chan->language);
+                       ast_streamfile(chan, recordfile, ast_channel_language(chan));
                        cmd = ast_waitstream(chan, AST_DIGIT_ANY);
                        break;
                case '3':
@@ -1653,7 +1674,7 @@ static int play_record_review(struct ast_channel *chan, char *playfile, char *re
                                ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
                        if (ast_test_flag(vmu, MVM_OPERATOR))
                                canceldtmf = "0";
-                       cmd = ast_play_and_record_full(chan, playfile, recordfile, maxtime, fmt, duration, global_silencethreshold, global_maxsilence, unlockdir, acceptdtmf, canceldtmf);
+                       cmd = ast_play_and_record_full(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, global_silencethreshold, global_maxsilence, unlockdir, acceptdtmf, canceldtmf);
                        if (record_gain)
                                ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
                        if (cmd == -1) /* User has hung up, no options to give */
@@ -1744,10 +1765,10 @@ static void run_externnotify(struct ast_channel *chan, struct minivm_account *vm
        snprintf(arguments, sizeof(arguments), "%s %s@%s %s %s&", 
                ast_strlen_zero(vmu->externnotify) ? global_externnotify : vmu->externnotify, 
                vmu->username, vmu->domain,
-               (chan->caller.id.name.valid && chan->caller.id.name.str)
-                       ? chan->caller.id.name.str : "",
-               (chan->caller.id.number.valid && chan->caller.id.number.str)
-                       ? chan->caller.id.number.str : "");
+               (ast_channel_caller(chan)->id.name.valid && ast_channel_caller(chan)->id.name.str)
+                       ? ast_channel_caller(chan)->id.name.str : "",
+               (ast_channel_caller(chan)->id.number.valid && ast_channel_caller(chan)->id.number.str)
+                       ? ast_channel_caller(chan)->id.number.str : "");
 
        ast_debug(1, "Executing: %s\n", arguments);
        ast_safe_system(arguments);
@@ -1757,6 +1778,9 @@ static void run_externnotify(struct ast_channel *chan, struct minivm_account *vm
  * \brief Send message to voicemail account owner */
 static int notify_new_message(struct ast_channel *chan, const char *templatename, struct minivm_account *vmu, const char *filename, long duration, const char *format, char *cidnum, char *cidname)
 {
+       RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
+       RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
+       RAII_VAR(struct ast_mwi_state *, mwi_state, NULL, ao2_cleanup);
        char *stringp;
        struct minivm_template *etemplate;
        char *messageformat;
@@ -1822,8 +1846,26 @@ static int notify_new_message(struct ast_channel *chan, const char *templatename
                res = sendmail(etemplate, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_PAGE, counter);
        }
 
-       ast_manager_event(chan, EVENT_FLAG_CALL, "MiniVoiceMail", "Action: SentNotification\rn\nMailbox: %s@%s\r\nCounter: %s\r\n", vmu->username, vmu->domain, counter);
+       mwi_state = ast_mwi_create(vmu->username, vmu->domain);
+       if (!mwi_state) {
+               goto notify_cleanup;
+       }
+       mwi_state->snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(chan));
+
+       json_object = ast_json_pack("{s: s, s: s}",
+                       "Event", "MiniVoiceMail"
+                       "Action", "SentNotification",
+                       "Counter", counter);
+       if (!json_object) {
+               goto notify_cleanup;
+       }
+       message = ast_mwi_blob_create(mwi_state, ast_mwi_vm_app_type(), json_object);
+       if (!message) {
+               goto notify_cleanup;
+       }
+       stasis_publish(ast_mwi_topic(mwi_state->uniqueid), message);
 
+notify_cleanup:
        run_externnotify(chan, vmu);            /* Run external notification */
 
        if (etemplate->locale) {
@@ -1842,6 +1884,7 @@ static int leave_voicemail(struct ast_channel *chan, char *username, struct leav
        FILE *txt;
        int res = 0, txtdes;
        int duration = 0;
+       int sound_duration = 0;
        char date[256];
        char tmpdir[PATH_MAX];
        char ext_context[256] = "";
@@ -1899,7 +1942,7 @@ static int leave_voicemail(struct ast_channel *chan, char *username, struct leav
        txtdes = mkstemp(tmptxtfile);
        if (txtdes < 0) {
                ast_log(LOG_ERROR, "Unable to create message file %s: %s\n", tmptxtfile, strerror(errno));
-               res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
+               res = ast_streamfile(chan, "vm-mailboxfull", ast_channel_language(chan));
                if (!res)
                        res = ast_waitstream(chan, "");
                pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED");
@@ -1908,7 +1951,7 @@ static int leave_voicemail(struct ast_channel *chan, char *username, struct leav
 
        if (res >= 0) {
                /* Unless we're *really* silent, try to send the beep */
-               res = ast_streamfile(chan, "beep", chan->language);
+               res = ast_streamfile(chan, "beep", ast_channel_language(chan));
                if (!res)
                        res = ast_waitstream(chan, "");
        }
@@ -1917,7 +1960,7 @@ static int leave_voicemail(struct ast_channel *chan, char *username, struct leav
        /* Store information */
        ast_debug(2, "Open file for metadata: %s\n", tmptxtfile);
 
-       res = play_record_review(chan, NULL, tmptxtfile, global_vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain);
+       res = play_record_review(chan, NULL, tmptxtfile, global_vmmaxmessage, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain);
 
        txt = fdopen(txtdes, "w+");
        if (!txt) {
@@ -1932,18 +1975,18 @@ static int leave_voicemail(struct ast_channel *chan, char *username, struct leav
                ast_strftime(timebuf, sizeof(timebuf), "%H:%M:%S", &tm);
 
                ast_callerid_merge(callerid, sizeof(callerid),
-                       S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
-                       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
+                       S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, NULL),
+                       S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL),
                        "Unknown");
                snprintf(logbuf, sizeof(logbuf),
                        /* "Mailbox:domain:macrocontext:exten:priority:callerchan:callerid:origdate:origtime:duration:durationstatus:accountcode" */
                        "%s:%s:%s:%s:%d:%s:%s:%s:%s:%d:%s:%s\n",
                        username,
-                       chan->context,
-                       chan->macrocontext, 
-                       chan->exten,
-                       chan->priority,
-                       chan->name,
+                       ast_channel_context(chan),
+                       ast_channel_macrocontext(chan), 
+                       ast_channel_exten(chan),
+                       ast_channel_priority(chan),
+                       ast_channel_name(chan),
                        callerid,
                        date, 
                        timebuf,
@@ -1958,8 +2001,8 @@ static int leave_voicemail(struct ast_channel *chan, char *username, struct leav
                        ast_mutex_unlock(&minivmloglock);
                }
 
-               if (duration < global_vmminmessage) {
-                       ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, global_vmminmessage);
+               if (sound_duration < global_vmminmessage) {
+                       ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", sound_duration, global_vmminmessage);
                        fclose(txt);
                        ast_filedelete(tmptxtfile, NULL);
                        unlink(tmptxtfile);
@@ -2006,9 +2049,8 @@ static int leave_voicemail(struct ast_channel *chan, char *username, struct leav
 
 /*!\internal
  * \brief Queue a message waiting event */
-static void queue_mwi_event(const char *mbx, const char *ctx, int urgent, int new, int old)
+static void queue_mwi_event(const char *channel_id, const char *mbx, const char *ctx, int urgent, int new, int old)
 {
-       struct ast_event *event;
        char *mailbox, *context;
 
        mailbox = ast_strdupa(mbx);
@@ -2017,16 +2059,7 @@ static void queue_mwi_event(const char *mbx, const char *ctx, int urgent, int ne
                context = "default";
        }
 
-       if (!(event = ast_event_new(AST_EVENT_MWI,
-                       AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
-                       AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
-                       AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent),
-                       AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old,
-                       AST_EVENT_IE_END))) {
-               return;
-       }
-
-       ast_event_queue_and_cache(event);
+       ast_publish_mwi_state_channel(mailbox, context, new + urgent, old, channel_id);
 }
 
 /*!\internal
@@ -2045,10 +2078,6 @@ static int minivm_mwi_exec(struct ast_channel *chan, const char *data)
                return -1;
        }
        tmpptr = ast_strdupa((char *)data);
-       if (!tmpptr) {
-               ast_log(LOG_ERROR, "Out of memory\n");
-               return -1;
-       }
        argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv));
        if (argc < 4) {
                ast_log(LOG_ERROR, "%d arguments passed to MiniVM_MWI, need 4.\n", argc);
@@ -2065,7 +2094,7 @@ static int minivm_mwi_exec(struct ast_channel *chan, const char *data)
                ast_log(LOG_ERROR, "Need mailbox@context as argument. Sorry. Argument 0 %s\n", argv[0]);
                return -1;
        }
-       queue_mwi_event(mailbox, domain, atoi(argv[1]), atoi(argv[2]), atoi(argv[3]));
+       queue_mwi_event(ast_channel_uniqueid(chan), mailbox, domain, atoi(argv[1]), atoi(argv[2]), atoi(argv[3]));
 
        return res;
 }
@@ -2082,21 +2111,16 @@ static int minivm_notify_exec(struct ast_channel *chan, const char *data)
        char *domain;
        char *tmpptr;
        struct minivm_account *vmu;
-       char *username = argv[0];
+       char *username;
        const char *template = "";
        const char *filename;
        const char *format;
        const char *duration_string;
-
        if (ast_strlen_zero(data))  {
                ast_log(LOG_ERROR, "Minivm needs at least an account argument \n");
                return -1;
        }
        tmpptr = ast_strdupa((char *)data);
-       if (!tmpptr) {
-               ast_log(LOG_ERROR, "Out of memory\n");
-               return -1;
-       }
        argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv));
 
        if (argc == 2 && !ast_strlen_zero(argv[1]))
@@ -2138,8 +2162,8 @@ static int minivm_notify_exec(struct ast_channel *chan, const char *data)
                ast_channel_unlock(chan);
                res = notify_new_message(chan, template, vmu, filename, atoi(duration_string),
                        format,
-                       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
-                       S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL));
+                       S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL),
+                       S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, NULL));
        }
 
        pbx_builtin_setvar_helper(chan, "MVM_NOTIFY_STATUS", res == 0 ? "SUCCESS" : "FAILED");
@@ -2169,7 +2193,7 @@ static int minivm_record_exec(struct ast_channel *chan, const char *data)
        memset(&leave_options, 0, sizeof(leave_options));
 
        /* Answer channel if it's not already answered */
-       if (chan->_state != AST_STATE_UP)
+       if (ast_channel_state(chan) != AST_STATE_UP)
                ast_answer(chan);
 
        if (ast_strlen_zero(data))  {
@@ -2177,10 +2201,6 @@ static int minivm_record_exec(struct ast_channel *chan, const char *data)
                return -1;
        }
        tmp = ast_strdupa((char *)data);
-       if (!tmp) {
-               ast_log(LOG_ERROR, "Out of memory\n");
-               return -1;
-       }
        argc = ast_app_separate_args(tmp, ',', argv, ARRAY_LEN(argv));
        if (argc == 2) {
                if (ast_app_parse_options(minivm_app_options, &flags, opts, argv[1])) {
@@ -2240,10 +2260,6 @@ static int minivm_greet_exec(struct ast_channel *chan, const char *data)
                return -1;
        }
        tmpptr = ast_strdupa((char *)data);
-       if (!tmpptr) {
-               ast_log(LOG_ERROR, "Out of memory\n");
-               return -1;
-       }
        argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv));
 
        if (argc == 2) {
@@ -2271,7 +2287,7 @@ static int minivm_greet_exec(struct ast_channel *chan, const char *data)
        }
 
        /* Answer channel if it's not already answered */
-       if (chan->_state != AST_STATE_UP)
+       if (ast_channel_state(chan) != AST_STATE_UP)
                ast_answer(chan);
 
        /* Setup pre-file if appropriate */
@@ -2301,18 +2317,18 @@ static int minivm_greet_exec(struct ast_channel *chan, const char *data)
        if (ast_test_flag(vmu, MVM_OPERATOR)) {
                if (!ast_strlen_zero(vmu->exit)) {
                        if (ast_exists_extension(chan, vmu->exit, "o", 1,
-                               S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
+                               S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
                                strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
                                ouseexten = 1;
                        }
-               } else if (ast_exists_extension(chan, chan->context, "o", 1,
-                       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
+               } else if (ast_exists_extension(chan, ast_channel_context(chan), "o", 1,
+                       S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
                        strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
                        ouseexten = 1;
                }
-               else if (!ast_strlen_zero(chan->macrocontext)
-                       && ast_exists_extension(chan, chan->macrocontext, "o", 1,
-                               S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
+               else if (!ast_strlen_zero(ast_channel_macrocontext(chan))
+                       && ast_exists_extension(chan, ast_channel_macrocontext(chan), "o", 1,
+                               S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
                        strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
                        ousemacro = 1;
                }
@@ -2320,15 +2336,15 @@ static int minivm_greet_exec(struct ast_channel *chan, const char *data)
 
        if (!ast_strlen_zero(vmu->exit)) {
                if (ast_exists_extension(chan, vmu->exit, "a", 1,
-                       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
+                       S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
                        strncat(ecodes, "*", sizeof(ecodes) -  strlen(ecodes) - 1);
                }
-       } else if (ast_exists_extension(chan, chan->context, "a", 1,
-               S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
+       } else if (ast_exists_extension(chan, ast_channel_context(chan), "a", 1,
+               S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
                strncat(ecodes, "*", sizeof(ecodes) -  strlen(ecodes) - 1);
-       } else if (!ast_strlen_zero(chan->macrocontext)
-               && ast_exists_extension(chan, chan->macrocontext, "a", 1,
-                       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
+       } else if (!ast_strlen_zero(ast_channel_macrocontext(chan))
+               && ast_exists_extension(chan, ast_channel_macrocontext(chan), "a", 1,
+                       S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
                strncat(ecodes, "*", sizeof(ecodes) -  strlen(ecodes) - 1);
                ausemacro = 1;
        }
@@ -2336,7 +2352,7 @@ static int minivm_greet_exec(struct ast_channel *chan, const char *data)
        res = 0;        /* Reset */
        /* Play the beginning intro if desired */
        if (!ast_strlen_zero(prefile)) {
-               if (ast_streamfile(chan, prefile, chan->language) > -1) 
+               if (ast_streamfile(chan, prefile, ast_channel_language(chan)) > -1) 
                        res = ast_waitstream(chan, ecodes);
        } else {
                ast_debug(2, "%s doesn't exist, doing what we can\n", prefile);
@@ -2355,7 +2371,7 @@ static int minivm_greet_exec(struct ast_channel *chan, const char *data)
                res = 0;
        }
        if (!res && !ast_test_flag(&leave_options, OPT_SILENT)) {
-               res = ast_streamfile(chan, SOUND_INTRO, chan->language);
+               res = ast_streamfile(chan, SOUND_INTRO, ast_channel_language(chan));
                if (!res)
                        res = ast_waitstream(chan, ecodes);
                if (res == '#') {
@@ -2368,27 +2384,25 @@ static int minivm_greet_exec(struct ast_channel *chan, const char *data)
        /* Check for a '*' here in case the caller wants to escape from voicemail to something
           other than the operator -- an automated attendant or mailbox login for example */
        if (res == '*') {
-               chan->exten[0] = 'a';
-               chan->exten[1] = '\0';
+               ast_channel_exten_set(chan, "a");
                if (!ast_strlen_zero(vmu->exit)) {
-                       ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
-               } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) {
-                       ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
+                       ast_channel_context_set(chan, vmu->exit);
+               } else if (ausemacro && !ast_strlen_zero(ast_channel_macrocontext(chan))) {
+                       ast_channel_context_set(chan, ast_channel_macrocontext(chan));
                }
-               chan->priority = 0;
+               ast_channel_priority_set(chan, 0);
                pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "USEREXIT");
                res = 0;
        } else if (res == '0') { /* Check for a '0' here */
                if(ouseexten || ousemacro) {
-                       chan->exten[0] = 'o';
-                       chan->exten[1] = '\0';
+                       ast_channel_exten_set(chan, "o");
                        if (!ast_strlen_zero(vmu->exit)) {
-                               ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
-                       } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) {
-                               ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
+                               ast_channel_context_set(chan, vmu->exit);
+                       } else if (ousemacro && !ast_strlen_zero(ast_channel_macrocontext(chan))) {
+                               ast_channel_context_set(chan, ast_channel_macrocontext(chan));
                        }
                        ast_play_and_wait(chan, "transfer");
-                       chan->priority = 0;
+                       ast_channel_priority_set(chan, 0);
                        pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "USEREXIT");
                }
                res =  0;
@@ -2456,7 +2470,7 @@ static int minivm_accmess_exec(struct ast_channel *chan, const char *data)
        char *domain;
        char *tmpptr = NULL;
        struct minivm_account *vmu;
-       char *username = argv[0];
+       char *username;
        struct ast_flags flags = { 0 };
        char *opts[OPT_ARG_ARRAY_SIZE];
        int error = FALSE;
@@ -2467,14 +2481,9 @@ static int minivm_accmess_exec(struct ast_channel *chan, const char *data)
        if (ast_strlen_zero(data))  {
                ast_log(LOG_ERROR, "MinivmAccmess needs at least two arguments: account and option\n");
                error = TRUE;
-       } else 
+       } else {
                tmpptr = ast_strdupa((char *)data);
-       if (!error) {
-               if (!tmpptr) {
-                       ast_log(LOG_ERROR, "Out of memory\n");
-                       error = TRUE;
-               } else
-                       argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv));
+               argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv));
        }
 
        if (argc <=1) {
@@ -2517,7 +2526,7 @@ static int minivm_accmess_exec(struct ast_channel *chan, const char *data)
        }
 
        /* Answer channel if it's not already answered */
-       if (chan->_state != AST_STATE_UP)
+       if (ast_channel_state(chan) != AST_STATE_UP)
                ast_answer(chan);
        
        /* Here's where the action is */
@@ -2536,7 +2545,7 @@ static int minivm_accmess_exec(struct ast_channel *chan, const char *data)
        }
        snprintf(filename,sizeof(filename), "%s%s/%s/%s", MVM_SPOOL_DIR, vmu->domain, vmu->username, message);
        /* Maybe we should check the result of play_record_review ? */
-       play_record_review(chan, prompt, filename, global_maxgreet, default_vmformat, 0, vmu, &duration, NULL, FALSE);
+       play_record_review(chan, prompt, filename, global_maxgreet, default_vmformat, 0, vmu, &duration, NULL, NULL, FALSE);
 
        ast_debug(1, "Recorded new %s message in %s (duration %d)\n", message, filename, duration);
 
@@ -2614,7 +2623,7 @@ static int create_vmaccount(char *name, struct ast_variable *var, int realtime)
                        char *varname = ast_strdupa(var->value);
                        struct ast_variable *tmpvar;
 
-                       if (varname && (varval = strchr(varname, '='))) {
+                       if ((varval = strchr(varname, '='))) {
                                *varval = '\0';
                                varval++;
                                if ((tmpvar = ast_variable_new(varname, varval, ""))) {
@@ -2672,11 +2681,6 @@ static int timezone_add(const char *zonename, const char *config)
                return 0;
 
        msg_format = ast_strdupa(config);
-       if (msg_format == NULL) {
-               ast_log(LOG_WARNING, "Out of memory.\n");
-               ast_free(newzone);
-               return 0;
-       }
 
        timezone_str = strsep(&msg_format, "|");
        if (!msg_format) {
@@ -3192,10 +3196,7 @@ static int minivm_account_func_read(struct ast_channel *chan, const char *cmd, c
        struct minivm_account *vmu;
        char *username, *domain, *colname;
 
-       if (!(username = ast_strdupa(data))) {
-               ast_log(LOG_ERROR, "Memory Error!\n");
-               return -1;
-       }
+       username = ast_strdupa(data);
 
        if ((colname = strchr(username, ':'))) {
                *colname = '\0';
@@ -3340,16 +3341,13 @@ static int access_counter_file(char *directory, char *countername, int value, in
 static int minivm_counter_func_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 {
        char *username, *domain, *countername;
-       struct minivm_account *vmu = NULL;
        char userpath[BUFSIZ];
        int res;
 
        *buf = '\0';
 
-       if (!(username = ast_strdupa(data))) {  /* Copy indata to local buffer */
-               ast_log(LOG_WARNING, "Memory error!\n");
-               return -1;
-       }
+       username = ast_strdupa(data);
+
        if ((countername = strchr(username, ':'))) {
                *countername = '\0';
                countername++;
@@ -3378,7 +3376,7 @@ static int minivm_counter_func_read(struct ast_channel *chan, const char *cmd, c
        }
 
        /* If we can't find account or if the account is temporary, return. */
-       if (!ast_strlen_zero(username) && !(vmu = find_account(domain, username, FALSE))) {
+       if (!ast_strlen_zero(username) && !find_account(domain, username, FALSE)) {
                ast_log(LOG_ERROR, "Minivm account does not exist: %s@%s\n", username, domain);
                return 0;
        }
@@ -3397,7 +3395,6 @@ static int minivm_counter_func_write(struct ast_channel *chan, const char *cmd,
 {
        char *username, *domain, *countername, *operand;
        char userpath[BUFSIZ];
-       struct minivm_account *vmu;
        int change = 0;
        int operation = 0;
 
@@ -3405,10 +3402,7 @@ static int minivm_counter_func_write(struct ast_channel *chan, const char *cmd,
                return -1;
        change = atoi(value);
 
-       if (!(username = ast_strdupa(data))) {  /* Copy indata to local buffer */
-               ast_log(LOG_WARNING, "Memory error!\n");
-               return -1;
-       }
+       username = ast_strdupa(data);
 
        if ((countername = strchr(username, ':'))) {
                *countername = '\0';
@@ -3442,7 +3436,7 @@ static int minivm_counter_func_write(struct ast_channel *chan, const char *cmd,
        }
 
        /* If we can't find account or if the account is temporary, return. */
-       if (!ast_strlen_zero(username) && !(vmu = find_account(domain, username, FALSE))) {
+       if (!ast_strlen_zero(username) && !find_account(domain, username, FALSE)) {
                ast_log(LOG_ERROR, "Minivm account does not exist: %s@%s\n", username, domain);
                return 0;
        }