· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
Asterisk Inst/Voice Mail

AsteriskInst/VoiceMail

  • http://www.asterisk.org/doxygen/1.2/main.html
  • http://bugs.digium.com/view.php?id=1429
  • app_voicemail.c
  • int load_module(void)
    • res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm);
    • res |= ast_register_application(app2, vm_execmain, synopsis_vmain, descrip_vmain);
    • res |= ast_register_application(app3, vm_box_exists, synopsis_vm_box_exists, descrip_vm_box_exists);
    • res |= ast_register_application(app4, vmauthenticate, synopsis_vmauthenticate, descrip_vmauthenticate);
      • static char *app = "VoiceMail";
      • static char *app2 = "VoiceMailMain";
      • static char *app3 = "MailboxExists";
      • static char *app4 = "VMAuthenticate";
    • res=load_config()
    • ast_cli_register(&show_voicemail_users_cli);
    • ast_cli_register(&show_voicemail_zones_cli);
    • ast_install_vm_functions(has_voicemail, messagecount);
  • int ast_register_application(const char *app, int (*execute)(struct ast_channel *, void *), const char *synopsis, const char *description)
    • pbx.c
  • static int load_config(void)
    • cfg = ast_config_load(VOICEMAIL_CONFIG);
      • #define VOICEMAIL_CONFIG "voicemail.conf"
  • static int vm_exec(struct ast_channel *chan, void *data)
  • static int vm_execmain(struct ast_channel *chan, void *data)
  • static int vm_box_exists(struct ast_channel *chan, void *data)
  • static int vmauthenticate(struct ast_channel *chan, void *data)
  • static int has_voicemail(const char *mailbox, const char *folder)
  • static int messagecount(const char *mailbox, int *newmsgs, int *oldmsgs)

vm_execmain

  • static int vm_execmain(struct ast_channel *chan, void *data)
  • if (chan->_state != AST_STATE_UP)
    • ast_answer(chan);
  • if (!ast_strlen_zero(data))
  • if (!valid)
    • res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0);
  • adsi_begin(chan, &useadsi);
  • res = open_mailbox(&vms, vmu, 1);
  • res = open_mailbox(&vms, vmu, 0);
  • if (!vms.newmessages && vms.oldmessages)
  • if (!strcasecmp(vmu->mailbox, vmu->password) && (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET)))
  • cmd = vm_intro(chan, &vms);
  • while ((cmd > -1) && (cmd != 't') && (cmd != '#'))
    • switch(cmd)
    • case '1': Read voicemail message
      • vms.curmsg = 0;
      • Fall through
    • case '5': Repeat current message
      • cmd = vm_browse_messages(chan, &vms, vmu);
    • case '2': Change folders
      • adsi_folders(chan, 0, "Change to folder...");
      • cmd = get_folder2(chan, "vm-changeto", 0);
      • res = open_mailbox(&vms, vmu, cmd);
      • adsi_status2(chan, &vms);
      • cmd = vm_play_folder_name(chan, vms.vmbox);
    • case '3': Advanced options
    • case '4': Play previous message
    • case '6': Play next message
    • case '7': Delete current message
    • case '8': Forward message to another mailbox
    • case '9': Save message in a folder
    • case '*': Help
      • cmd = ast_play_and_wait(chan, "vm-onefor");
      • cmd = vm_play_folder_name(chan, vms.vmbox);
      • cmd = ast_play_and_wait(chan, "vm-opts");
  •  vm-opts	 
     Press 2 to change folders. Press 3 for advanced options. Press zero for mailbox options.
     
    • cmd = vm_instructions(chan, &vms, 1);
    • case '0': Mailbox options
      • cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain);
      • adsi_status(chan, &vms);
    • default:
      • cmd = vm_instructions(chan, &vms, 0);
  • if ((cmd == 't') || (cmd == '#'))
    • res = 0; Timeout
  • else
    • res = -1; Hangup
  • out:
  • if (res > -1)
    • ast_stopstream(chan);
    • adsi_goodbye(chan);
    • res = ast_play_and_wait(chan, "vm-dialout");
    • vm-dialout : Please wait while I connect your call.
    • res = ast_play_and_wait(chan, "vm-goodbye");
    • vm-goodbye : goodbye
    • adsi_unload_session(chan);
  • if (vmu)
    • close_mailbox(&vms, vmu);
  • if (valid)
    • manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL));
    • run_externnotify(vmu->context, vmu->mailbox);

vm_box_exists

  • MailboxExists(mailbox@contextoptions)
    • If no voicemail context is specified, the 'default' context will be used.
    • Options:
      • j - Jump to priority n+101 if the mailbox is found.
  • static int vm_box_exists(struct ast_channel *chan, void *data)
             AST_DECLARE_APP_ARGS(args,
                     AST_APP_ARG(mbox);
                     AST_APP_ARG(options);
             );
     
    • LOCAL_USER_ADD(u);
    • box = ast_strdupa(data);
    • AST_STANDARD_APP_ARGS(args, box);
    • j option 이 주어졌으면, priority_jump = 1;
    • @ 가 있으면, context 에 @ 다음 string 을 assign
      • 없으면, NULL assign
    • if (find_user(&svm, context, args.mbox))
      • pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS");
        • channel variable 인 VMBOXEXISTSSTATUS 에 SUCCESS assign
      • if (priority_jump || option_priority_jumping)
        • ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)
    • LOCAL_USER_REMOVE(u);
    • return 0;
  • static struct ast_vm_user *find_user(struct ast_vm_user *ivm, const char *context, const char *mailbox)
    • context 가 null 이고,
    • voicemail.conf 의 general section 의 searchcontexts=no 면
      • context = "default";
    • while (cur)
      • searchcontexts=yes 고 cur->mailbox 가 mailbox 와 같으면, break
      • context 가 null 이 아니고, cur->context 가 context 와 같고, cur->mailbox 가 mailbox 와 같으면 break
      • cur=cur->next;
    • vmu struct(ast_vm_user) 에 cur struct 복사
    • return vmu;
  • void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
    • called by
      • pbx_builtin_setvar
      • pbx_builtin_importvar
      • pbx_builtin_setglobalvar
      • pbx_extension_helper
      • __ast_pbx_run
    • name 에 value assign
    • 좀 더 들여다 볼 것
  • int ast_goto_if_exists(struct ast_channel *chan, char* context, char *exten, int priority)
    • return __ast_goto_if_exists(chan, context, exten, priority, 0);
  • static int __ast_goto_if_exists(struct ast_channel *chan, char *context, char *exten, int priority, int async)
    • 열심히 들여다 보면?
  • include/asterisk/app.h
    • #define AST_APP_ARG(name) char *name
      • Define an application argument
      • name The name of the argument
  •  #define AST_DECLARE_APP_ARGS(name, arglist) \
             struct { \
                     unsigned int argc; \
                     char *argv[0]; \
                     arglist \
             } name
     
      • Declare a structure to hold the application's arguments.
      • name The name of the structure
      • arglist The list of arguments, defined using AST_APP_ARG
     #define AST_STANDARD_APP_ARGS(args, parse) \
             args.argc = ast_app_separate_args(parse, '|', args.argv, (sizeof(args) - sizeof(args.argc)) / sizeof(args.argv[0]))
     
      • Performs the 'standard' argument separation process for an application.
      • args An argument structure defined using AST_DECLARE_APP_ARGS
      • parse A modifiable buffer containing the input to be parsed
  • include/asterisk/module.h
     Local user routines keep track of which channels are using a given module resource.  They can help make removing modules safer, particularly if they're in use at the time they have been requested to be removed
     
    • LOCAL_USER_ADD(u)
      • Add a localuser.
      • u a pointer to a localuser struct
  •  This macro adds a localuser to the list of users and increments the usecount.  It expects a variable named chan of type ast_channel in the current scope.
     
     This function dynamically allocates memory.  If this operation fails, it will cause your function to return -1 to the caller.
     
    • LOCAL_USER_REMOVE(u)
      • Remove a localuser.
      • u the user to add, should be of type struct localuser
     This macro removes a localuser from the list of users and decrements the usecount.
     

vmauthenticate

  • VMAuthenticate(mailbox@contextoptions):
     Behaves identically to the Authenticate application, with the exception that the passwords are taken from voicemail.conf. If the mailbox is specified, only that mailbox's password will be considered valid. If the mailbox is not specified, the channel variable AUTH_MAILBOX will be set with the authenticated mailbox. If the options contain 's' then no initial prompts will be played. 
     
  • static int vmauthenticate(struct ast_channel *chan, void *data)
    • char *s = data(mailbox@context|options)
    • if (s)
      • user = strsep(&s, "|");
      • options = strsep(&s, "|");
        • s = user;
        • user = strsep(&s, "@");
        • context = strsep(&s, "");
        • ast_copy_string(mailbox, user, sizeof(mailbox));
    • if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent))
      • mailbox is not specified
      • pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox);
        • channel variable
      • pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context);
      • ast_play_and_wait(chan, "auth-thankyou");
      • auth-thankyou: Thank you.
      • res = 0;
    • return res;
  • static int vm_authenticate(struct ast_channel *chan, char *mailbox, int mailbox_size, struct ast_vm_user *res_vmu, const char *context, const char *prefix, int skipuser, int maxlogins, int silent)
    • adsi_begin(chan, &useadsi);

diff

  • data area
     411c411
     < static char charset[32] = "ISO-8859-1";
     ---
     > static char charset[32] = "EUC-KR";
     

  • static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail)
     1706,1710c1705,1710
     <               } else if (ast_test_flag((&globalflags), VM_PBXSKIP))
     <                       fprintf(p, "Subject: New message %d in mailbox %s\n", msgnum + 1, mailbox);
     <               else
     <                       fprintf(p, "Subject: [PBX]: New message %d in mailbox %s\n", msgnum + 1, mailbox);
     <               fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>\n", msgnum, (unsigned int)rand(), mailbox, getpid(), host);
     ---
     >               } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) {
     >                       fprintf(p, "Subject: 내선번호 %s, 새로운 메시지 %d가 도>착하였습니다\n", mailbox, msgnum + 1);//@2006-10-28
     >               } else
     >                       fprintf(p, "Subject: [PBX]: 내선번호 %s, 새로운 메시지가
      도착하였습니다\n", mailbox);
     >               fprintf(p, "X-Accept-Language: kr\n");
     >               fprintf(p, "X-Country: Korea\n");
     

  • static int get_folder(struct ast_channel *chan, int start)
     3201,3204c3201
     <       d = ast_play_and_wait(chan, "vm-press");        /* "Press" */
     <       if (d)
     <               return d;
     <       for (x = start; x< 5; x++) {    /* For all folders */
     ---
     >       for (x = start; x< 3; x++) {    //0,1,2만 동작
     

  • static int get_folder2(struct ast_channel *chan, char *fn, int start)
     3229c3226
     <       while (((res < '0') || (res > '9')) &&
     ---
     >       while (((res < '0') || (res > '2')) &&
     

  • static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname)
     3306d3302
     <                       sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, fn, fmt, duration, attach_user_voicemail);
     

  • static int forward_message(struct ast_channel *chan, char *context, char *dir, int curmsg, struct ast_vm_user *sender, char *fmt, int flag, signed char record_gain)
     3425c3421
     <                       res = ast_streamfile(chan, "vm-extension", chan->language);     /* "extension" */
     ---
     >                       res = ast_streamfile(chan, "3203", chan->language);//메>시지를 전달할 내선번호를 입력하십시오
     
     3561c3557
     <                               res = ast_play_and_wait(chan, "vm-msgsaved");
     ---
     >                               res = ast_play_and_wait(chan, "3204");//메시지가
      전달되었습니다
     

  • static int vm_intro_en(struct ast_channel *chan,struct vm_state *vms)
     4013,4015c4009
     <       int res;
     <       res = ast_play_and_wait(chan, "vm-youhave");
     <       if (!res) {
     ---
     >       int res = 0;
     
     4018c4012,4013
     <                       if (!res)
     ---
     >                       if (!res){
     >                               res = ast_play_and_wait(chan, "3201");//개의
     
     4020,4022c4015,4016
     <                       if (vms->oldmessages && !res)
     <                               res = ast_play_and_wait(chan, "vm-and");
     <                       else if (!res) {
     ---
     >                       }
     >                       if (!res) {//메시지
     
     4028c4022,4023
     <
     ---
     >                       if (vms->oldmessages && !res)
     >                               res = ast_play_and_wait(chan, "vm-and");
     
     4032c4027,4028
     <                       if (!res)
     ---
     >                       if (!res) {
     >                               res = ast_play_and_wait(chan, "3201");//개의
     
     4033a4030,4031
     >                       }
     >
     
     4044c4042
     <                               if (!res)
     ---
     >                               res = ast_play_and_wait(chan, "3201");//개의
     
     4048c4046,4049
     <       }
     ---
     >
     >               if (!res) {
     >                       res = ast_play_and_wait(chan, "vm-youhave");//가 있습니다
     >               }
     

    • 읽어 볼 것
    • vm_intro_ko 를 만드는 것이 맞지 않을까?
  • static int vm_instructions(struct ast_channel *chan, struct vm_state *vms, int skipadvanced)
     4530,4531d4530
     <                               res = ast_play_and_wait(chan, "vm-onefor");
     <                               if (!res)
     
     4532a4532,4541
     >                                       if (!res) {
     >                                               res = ast_play_and_wait(chan, "3202");//을 들으려면
     >                                               res = ast_play_and_wait(chan, "vm-onefor");//1번을 눌러주십시오(hanul71)
     >                                       }
     >
     >                       }
     >                       if (!res) {
     >                               if (vms->lastmsg == -1) {//2006-12-01hanulb71
     >                                       res = ast_play_and_wait(chan, "vm-nomore");//더이상 메지지가 없습니다
     >                               }
     
     4535c4544,4547
     <                               res = ast_play_and_wait(chan, "vm-opts");
     ---
     >                         res = ast_play_and_wait(chan, "vm-opts");
     >                       if (!res)
     >                         res = ast_play_and_wait(chan, "vm-helpexit");//종료를 원하시면 우물정자를 눌러주십시오
     >
     
     4539,4540d4550
     <                       if (!res && !skipadvanced)
     <                               res = ast_play_and_wait(chan, "vm-advopts");
     
     4553a4564,4567
     >                               if (!res)//hanul71
     >                                       res = ast_play_and_wait(chan, "vm-advopts");
     >                               if (!res)
     >                                       res = ast_play_and_wait(chan, "vm-helpexit");//종료를 원하시면 우물정자를 눌러주십시오
     
     4557,4558d4570
     <                       res = ast_play_and_wait(chan, "vm-helpexit");
     <               if (!res)
     

    • 읽어 볼 것
  • static int vm_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
     4673,4674c4685
     <                       snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
     <                       cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
     ---
     >                       cmd = ast_play_and_wait(chan, "vm-sorry");
     
     4677,4678c4688
     <                       snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
     <                       cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
     ---
     >                       cmd = ast_play_and_wait(chan, "vm-sorry");
     
     4681,4682c4691
     <                       snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
     <                       cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
     ---
     >                       cmd = ast_play_and_wait(chan, "vm-sorry");
     
     4688,4725c4697
     <                       if (vmu->password[0] == '-') {
     <                               cmd = ast_play_and_wait(chan, "vm-no");
     <                               break;
     <                       }
     <                       newpassword[1] = '\0';
     <                       newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
     <                       if (cmd == '#')
     <                               newpassword[0] = '\0';
     <                       else {
     <                               if (cmd < 0)
     <                                       break;
     <                               if ((cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#")) < 0) {
     <                                       break;
     <                               }
     <                       }
     <                       newpassword2[1] = '\0';
     <                       newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
     <                       if (cmd == '#')
     <                               newpassword2[0] = '\0';
     <                       else {
     <                               if (cmd < 0)
     <                                       break;
     <
     <                               if ((cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#"))) {
     <                                       break;
     <                               }
     <                       }
     <                       if (strcmp(newpassword, newpassword2)) {
     <                               ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
     <                               cmd = ast_play_and_wait(chan, "vm-mismatch");
     <                               break;
     <                       }
     <                       if (ast_strlen_zero(ext_pass_cmd))
     <                               vm_change_password(vmu,newpassword);
     <                       else
     <                               vm_change_password_shell(vmu,newpassword);
     <                       ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
     <                       cmd = ast_play_and_wait(chan,"vm-passchanged");
     ---
     >                       cmd = ast_play_and_wait(chan, "vm-sorry");
     

    • 읽어 볼 것
  • static int vm_authenticate(struct ast_channel *chan, char *mailbox, int mailbox_size, struct ast_vm_user *res_vmu, const char *context, const char *prefix, int skipuser, int maxlogins, int silent)
     4939c4911
     <       if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) {
     ---
     >               if (!silent && !skipuser && ast_streamfile(chan, "3103", chan->language)) {
     
     4957c4929
     <                                       ast_verbose(VERBOSE_PREFIX_3 "Username not entered\n");
     ---
     >                                       ast_verbose(VERBOSE_PREFIX_3 "Username not entered\n");
     
     4976c4948
     <                       if (ast_streamfile(chan, "vm-password", chan->language)) {
     ---
     >                       if (ast_streamfile(chan, "enter-password", chan->language)) {
     
     5008c4980
     <                               if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) {
     ---
     >                               if (ast_streamfile(chan, "vm-mismatch", chan->language)) {
     
     5019c4991
     <               ast_play_and_wait(chan, "vm-goodbye");
     ---
     >               ast_play_and_wait(chan, "terminating");
     

    • 읽어 볼 것
  • static int vm_execmain(struct ast_channel *chan, void *data)
     5034a5007
     >       int tmpcmd=0;//hanul71(2006-04-19)추가
     
     5201a5175
     >                               tmpcmd = cmd;//hanul71
     
     5213,5214c5187,5202
     <                       if (!cmd)
     <                               cmd = vm_play_folder_name(chan, vms.vmbox);
     ---
     >                       if (!cmd){
     >                               ast_log(LOG_WARNING, "mail cmdB = %d \n", cmd);
     >                               ast_log(LOG_WARNING, "mail cmdC = %s \n", vms.vmbox);
     >                               ast_log(LOG_WARNING, "mail cmdD = %d \n", tmpcmd);
     >                               switch(tmpcmd) {
     >                                       case 0:
     >                                       case 1:
     >                                       case 2:
     >                                                       cmd = tmpcmd;//@2006-10-15//@2006-10-31//@2006-11-15
     >                                                       break;
     >                                       default :
     >                                                       cmd = ast_play_and_wait(chan, "vm-sorry");
     >                                                       break;
     >                               }
     >                               //***********************************************************@
     >                       }
     
     5250,5260d5237
     <                               case '3': /* Envelope */
     <                                       if (vms.lastmsg > -1) {
     <                                               cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain);
     <                                               if (cmd == ERROR_LOCK_PATH) {
     <                                                       res = cmd;
     <                                                       goto out;
     <                                               }
     <                                       } else
     <                                               cmd = ast_play_and_wait(chan, "vm-sorry");
     <                                       cmd = 't';
     <                                       break;
     
     5298,5300d5274
     <                                       if (!cmd && !vms.starting) {
     <                                               cmd = ast_play_and_wait(chan, "vm-tohearenv");
     <                                       }
     
     5368c5342
     <                       cmd = get_folder2(chan, "vm-savefolder", 1);
     ---
     >                       cmd = '2';//2006-10-02
     
     5375,5383c5349,5369
     <                               cmd = save_to_folder(vmu, vms.curdir, vms.curmsg, vmu->context, vms.username, cmd);
     <                               if (cmd == ERROR_LOCK_PATH) {
     <                                       res = cmd;
     <                                       goto out;
     <                               } else if (!cmd) {
     <                                       vms.deleted[vms.curmsg] = 1;
     <                               } else {
     <                                       vms.deleted[vms.curmsg] = 0;
     <                                       vms.heard[vms.curmsg] = 0;
     ---
     >                               ast_log(LOG_WARNING, "mail cmd = %d \n", cmd);
     >                               ast_log(LOG_WARNING, "mail box = %d \n", box);
     >                               switch(box) {
     >                                       case 0:
     >                                       case 1:
     >                                       case 2:
     >                                                       cmd = save_to_folder(vmu, vms.curdir, vms.curmsg, vmu->context, vms.username, cmd);
     >                                                       if (cmd == ERROR_LOCK_PATH) {
     >                                                               res = cmd;
     >                                                               goto out;
     >                                                       } else if (!cmd) {
     >                                                               vms.deleted[vms.curmsg] = 1;
     >                                                       } else {
     >                                                               vms.deleted[vms.curmsg] = 0;
     >                                                               vms.heard[vms.curmsg] = 0;
     >                                                       }
     >                                                       break;
     >                                       case 3:
     >                                       case 4:
     >                                                       //cmd = ast_play_and_wait(chan, "vm-sorry");
     >                                                       break;
     
     5384a5371
     >                               //***********************************************************@
     
     5391d5377
     <                               cmd = ast_play_and_wait(chan, "vm-message");
     
     5393c5379
     <                                       cmd = say_and_wait(chan, vms.curmsg + 1, chan->language);
     ---
     >                                       cmd = vm_play_folder_name(chan, vms.fn);
     
     5396,5397d5381
     <                               if (!cmd)
     <                                       cmd = vm_play_folder_name(chan, vms.fn);
     
     5399c5383
     <                               cmd = ast_play_and_wait(chan, "vm-mailboxfull");
     ---
     >                               cmd = ast_play_and_wait(chan, "vm-sorry");
     
     5400a5385
     >
     
     5412,5414c5397
     <                               cmd = ast_play_and_wait(chan, "vm-onefor");
     <                               if (!cmd)
     <                                       cmd = vm_play_folder_name(chan, vms.vmbox);
     ---
     >                               cmd = 0;
     
    • 읽어 볼 것
  • static int load_config(void)
     6146c6129
     <               strcpy(charset, "ISO-8859-1");
     ---
     >               strcpy(charset, "EUC-KR");
     
    • 바꿀 필요 없음.
    • voicemail.conf 에 general 의 charset 을 설정하면 됨.
  • static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, const char *unlockdir, signed char record_gain)
     6679,6684c6661
     <
     <                       if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) {
     <                               cmd = ast_play_and_wait(chan, "vm-reachoper");
     <                               if (!cmd)
     <                                       cmd = ast_waitfordigit(chan, 600);
     <                       }
     ---
     >
     
    • Record message & let caller review or re-record it, or set options if applicable
    • outsidecaller: leave_voicemail 에서 call 할 때만 1 로 설정, 나머자 모든 경우에 0
    • vm-reachoper: Press zero to reach an operator.

ast_play_and_wait

  • int ast_play_and_wait(struct ast_channel *chan, const char *fn)
    • app.c
    • Play a stream and wait for a digit, returning the digit that was pressed
    • d = ast_streamfile(chan, fn, chan->language);
    • if (d)
      • return d; 오류인 경우
    • d = ast_waitstream(chan, AST_DIGIT_ANY);
      • include/asterisk/file.h
      • #define AST_DIGIT_ANY "0123456789#*ABCD"
    • ast_stopstream(chan);
    • return d; AST_DIGIT_ANY 거나 -1 또는 0
  • int ast_streamfile(struct ast_channel *chan, const char *filename, const char *preflang)
    • file.c
    • fs = ast_openstream(chan, filename, preflang);
    • ast_applystream(chan, fs)
    • ast_playstream(fs)
  • int ast_waitstream(struct ast_channel *c, const char *breakon)
    • file.c
    • Wait for a stream to stop or for any one of a given digit to arrive
    • streams a file until a dtmf tone that matches a character in char* parameter breakon is received.
    • while(c->stream)
      • res = ast_sched_wait(c->sched);
      • res = ast_waitfor(c, res);
      • fr = ast_read(c);
      • switch(fr->frametype)
      • case AST_FRAME_DTMF:
        • res = fr->subclass;
        • if (strchr(breakon, res))
          • ast_frfree(fr);
          • return res;
      • ast_sched_runq(c->sched);
    • return (c->_softhangup ? -1 : 0);
  • int ast_stopstream(struct ast_channel *tmp)
    • file.c
    • Stop a running stream if there is one
    • ast_closestream(tmp->stream);
    • tmp->oldwriteformat 이 설정되어 있으면
      • ast_set_write_format(tmp, tmp->oldwriteformat)

ast_waitfordigit

  • int ast_waitfordigit(struct ast_channel *c, int ms)
    • channel.c
    • Wait for a digit. Returns <0 on error, 0 on no entry, and the digit on success.
    • ms how many milliseconds to wait

misc

  • sendmail
    • notify_new_message
    • forward_message
  • notify_new_message
    • copy_message
    • leave_voicemail
  • forward_message
    • vm_execmain
  • copy_message
    • leave_voicemail
  • leave_voicemail
    • forward_message
    • vm_exec
    • advanced_options
  • advanced_options
    • vm_execmain

get_folder

  • get_folder2
    • res = get_folder(chan, 0);
  • vm_execmain
    • cmd = get_folder2(chan, "vm-changeto", 0);
    • vm-changeto: Change to which folder?
    • cmd = get_folder2(chan, "vm-savefolder", 1);
    • vm-savefolder: Which folder should I save the message to?
  • static int get_folder(struct ast_channel *chan, int start)
    • d = ast_play_and_wait(chan, "vm-press");
    • vm-press: press
    • if (d)
      • return d;
    • for (x = start; x< 5; x++)
      • d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, (char *) NULL)
      • d = ast_play_and_wait(chan, "vm-for");
      • snprintf(fn, sizeof(fn), "vm-%s", mbox(x));
        • mbox(0): INBOX new
        • mbox(1): Old old
        • mbox(2): Work work
        • mbox(3): Family family
        • mbox(4): Friends friends
      • d = vm_play_folder_name(chan, fn);
      • d = ast_waitfordigit(chan, 500);
    • d = ast_play_and_wait(chan, "vm-tocancel");
    • vm-tocancel: or hash to cancel.
    • if (d)
      • return d;
    • d = ast_waitfordigit(chan, 4000);
    • return d;
  • static int get_folder2(struct ast_channel *chan, char *fn, int start)
    • res = ast_play_and_wait(chan, fn);
    • res = get_folder(chan, 0);

notify_new_message

  • int vm_execmain
    • cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain);
    • cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain);
    • cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain);
    • cmd = forward_message(chan, context, vms.curdir, vms.curmsg, vmu, vmfmts, 1, record_gain);
    • cmd = forward_message(chan, context, vms.curdir, vms.curmsg, vmu, vmfmts, 0, record_gain);
  • advanced_options
    • res = leave_voicemail(chan, num, &leave_options);
  • forward_message
    • cmd = leave_voicemail(chan, username, &leave_options);
  • vm_exec
    • res = leave_voicemail(chan, argv0, &leave_options);
  • leave_voicemail
    • copy_message(chan, vmu, 0, msgnum, duration, recip, fmt);
    • notify_new_message(chan, vmu, msgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name);
  • copy_message
    • notify_new_message(chan, recip, recipmsgnum, duration, fmt, chan->cid.cid_num, chan->cid.cid_name);
  • static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname)
    • make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX");
    • make_file(fn, sizeof(fn), todir, msgnum);
  •  static int make_dir(char *dest, int len, char *context, char *ext, char *mailbox)
     {
             return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, mailbox);
     }
     
     static int make_file(char *dest, int len, char *dir, int num)
     {
             return snprintf(dest, len, "%s/msg%04d", dir, num);
     }
     
    • snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
    • fmt = ast_strdupa(fmt);
     When making applications, always ast_strdupa(data) to a local pointer if you intend to parse the incoming data string.
     
    • if (fmt)
      • sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, fn, fmt, duration, attach_user_voicemail);
      • sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, duration, vmu);
    • if (ast_test_flag(vmu, VM_DELETE))
      • DELETE(todir, msgnum, fn);
    • if (ast_app_has_voicemail(ext_context, NULL))
      • ast_app_messagecount(ext_context, &newmsgs, &oldmsgs);
    • manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s@%s\r\nWaiting: %d\r\nNew: %d\r\nOld: %d\r\n", vmu->mailbox, vmu->context, ast_app_has_voicemail(ext_context, NULL), newmsgs, oldmsgs);
    • run_externnotify(vmu->context, vmu->mailbox);
    • return 0;

vm_instructions

  • vm_execmain
    • cmd = vm_instructions(chan, &vms, 1);
    • cmd = vm_instructions(chan, &vms, 0);
  • static int vm_instructions(struct ast_channel *chan, struct vm_state *vms, int skipadvanced)
    • while (!res)
      • if (vms->starting)
        • res = ast_play_and_wait(chan, "vm-onefor");
        • vm-onefor: Press 1 for
        • res = vm_play_folder_name(chan, vms->vmbox);
        • res = ast_play_and_wait(chan, "vm-opts");
  •  vm-opts	 
     Press 2 to change folders. Press 3 for advanced options. Press zero for mailbox options.
     
      • else
        • res = ast_play_and_wait(chan, "vm-prev");
        • vm-prev: Press 4 for the previous message.
        • res = ast_play_and_wait(chan, "vm-advopts");
        • vm-advopts: Press 3 for advanced options.
        • res = ast_play_and_wait(chan, "vm-repeat");
        • vm-repeat: Press 5 to repeat the current message.
        • res = ast_play_and_wait(chan, "vm-next");
        • vm-next: Press 6 to play the next message.
        • res = ast_play_and_wait(chan, "vm-delete");
        • vm-delete: Press 7 to delete this message.
        • res = ast_play_and_wait(chan, "vm-undelete");
        • vm-undelete: Press 7 to undelete this message.
        • res = ast_play_and_wait(chan, "vm-toforward");
        • vm-toforward: Press 8 to forward the message to another user.
        • res = ast_play_and_wait(chan, "vm-savemessage");
        • vm-savemessage: or 9 to save this message.
      • res = ast_play_and_wait(chan, "vm-helpexit");
      • vm-helpexit: Press star for help or hash to exit.
      • res = ast_waitfordigit(chan, 6000);
    • return res;

vm_options

  • vm_execmain
    • cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain);
  • static int vm_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
    • if (adsi_available(chan))
      • make bytes
      • adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
    • while ((cmd >= 0) && (cmd != 't'))
      • switch (cmd)
      • case '1':
        • cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
      • case '2':
        • cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
      • case '3':
        • cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
      • case '4':
        • cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain);
      • case '5':
        • cmd = ast_play_and_wait(chan, "vm-no");
        • newpassword0 = cmd = ast_play_and_wait(chan,"vm-newpassword");
        • vm-newpassword: Please enter your new password followed by the hash key.
        • newpassword20 = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
        • vm-reenterpassword: Please reenter your password followed by the hash key.
        • cmd = ast_play_and_wait(chan, "vm-mismatch");
        • vm-mismatch: The passwords you entered and re-entered did not match. Please try again.
        • vm_change_password(vmu,newpassword);
        • vm_change_password_shell(vmu,newpassword);
        • cmd = ast_play_and_wait(chan,"vm-passchanged");
        • vm-passchanged: Your passwords have been changed.
      • case '*':
        • cmd = 't';
      • default:
        • cmd = ast_play_and_wait(chan,"vm-options");
  •  vm-options	 
     Press 1 to record your unavailable message. Press 2 to record your busy message. Press 3 to record your name. Press 4 to record your temporary greeting. Press 5 to change your password. Press star to return to the main menu.
     
        • cmd = ast_waitfordigit(chan,6000);
    • return cmd;

vm_intro_en

  • vm_intro
    • chan->language
    • return vm_intro_en(chan, vms);
  • vm_execmain
    • cmd = vm_intro(chan, &vms);
  • static int vm_intro_en(struct ast_channel *chan,struct vm_state *vms)
    • res = ast_play_and_wait(chan, "vm-youhave");
    • vm-youhave : You have
    • if (!res)
      • if (vms->newmessages)
        • res = say_and_wait(chan, vms->newmessages, chan->language);
        • if (!res)
          • res = ast_play_and_wait(chan, "vm-INBOX");
          • vm-INBOX: new
        • if (vms->oldmessages && !res)
          • res = ast_play_and_wait(chan, "vm-and");
          • vm-and: and
        • else if (!res)
          • res = ast_play_and_wait(chan, "vm-message(s)");
          • vm-message(s): message(s)
      • if (!res && vms->oldmessages)
        • res = say_and_wait(chan, vms->oldmessages, chan->language);
        • if (!res)
          • res = ast_play_and_wait(chan, "vm-Old");
          • vm-Old: old
        • if (!res)
          • res = ast_play_and_wait(chan, "vm-message(s)");
      • if (!res)
        • if (!vms->oldmessages && !vms->newmessages)
          • res = ast_play_and_wait(chan, "vm-no");
          • vm-no: no
          • if (!res)
            • res = ast_play_and_wait(chan, "vm-messages");

play_record_review

  • leave_voicemail
    • res = play_record_review(chan, NULL, fn, vmmaxmessage, fmt, 1, vmu, &duration, dir, options->record_gain);
  • vm_newuser
    • cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
      • vm-rec-name: After the tone say your name and then press the hash key.
    • cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
      • vm-rec-unv: After the tone say your unavailable message and then press the hash key.
    • cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
      • vm-rec-busy: After the tone say your busy message and then press the hash key.
  • vm_options
    • cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
    • cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
    • cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
  • vm_tempgreeting
    • cmd = play_record_review(chan,"vm-rec-temp",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
      • vm-rec-temp: After the tone, say your temporary message, then press the hash key.
    • play_record_review(chan,"vm-rec-temp",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain);
  • static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, const char *unlockdir, signed char record_gain)
    • Record message & let caller review or re-record it, or set options if applicable
    • cmd = '3';
    • case '3':
    • recorded = 1;
    • cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir);
    • message_exists = 1;
    • cmd = 0;
    • if (outsidecaller)
      • ast_play_and_wait(chan, "vm-goodbye");
      • vm-goodbye: goodbye
    • case '0':
    • if (message_exists || recorded)
      • cmd = ast_play_and_wait(chan, "vm-saveoper");
      • vm-saveoper: Press 1 to accept this recording, otherwise please hold.
      • if (cmd == '1')
        • ast_play_and_wait(chan, "vm-msgsaved");
        • vm-msgsaved: Your message has been saved.
        • cmd = '0';
    • return cmd;



sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2008-09-09 22:13:01
Processing time 0.0687 sec