· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
Asterisk Ver0-1-0/App Dial

AsteriskVer0-1-0/AppDial


Attempts to "dial out" on all the specified channels (each specified by a type and identifier) simultaneously. The first channel that answers "wins", and all the other outgoing channels are hung up.

* int load_module(void)
  • return ast_register_application(app, dial_exec);

struct localuser {
        struct ast_channel *chan;
        int stillgoing;
        int allowredirect;
        struct localuser *next;
};

\ digit digit digit
    An octal character code. The numeric code is 3 octal digits. For compatibility with other Unix systems, 8 and 9 are accepted as digits: for example, \008 has the value 010, and \009 the value 011. 

* static int dial_exec(struct ast_channel *chan, void *data)
  • struct localuser *outgoing=NULL, *tmp;
  • peers = strtok(info, "|");
  • timeout = strtok(NULL, "|");
  • rest = peers;
    • technology1/number1&technology2/number2...
  • do {
    • cur = strtok(rest, "&");
    • rest = strtok(NULL, "\128");
      • ¾ÕºÎºÐÀÇ technology ¿Í number À» cur ¿¡ ³Ö°í, ³ª¸ÓÁö ºÎºÐÀ» rest ¿¡ º¸°üÇÏ°íÀÚ ÇÏ´Â ÇÁ·Î±×·¥À̳ª ¹®Á¦ ÀÖÀ½.
    • tech ¿Í number ¿¡ technology ¿Í number À» assign
    • tmp = malloc(sizeof(struct localuser));
    • tmp->allowredirect = 1;
    • number ÀÌ BYEXTENSION À̸é number = chan->exten; tmp->allowredirect = 0;
      • ¾ø¾îÁø option ÀεíÇÔ.
    • tmp->chan = ast_request(tech, chan->format, number);
      • channel À» »ý¼ºÇÏÁö ¸øÇϸé, free(tmp); continue;
    • res = ast_call(tmp->chan, number, 0);
      • call ÀÌ ¾ÈµÇ¸é, ast_hangup(tmp->chan); free(tmp); continue;
    • tmp->stillgoing = -1;
    • tmp->next = outgoing;
    • outgoing = tmp; request ¿Í call ÀÌ ¼º°øÇÑ localuser list ¸¦ ¸¸µë.
  • } while(rest);
  • if (timeout) to = atoi(timeout) * 1000;
  • else to = -1;
  • peer = wait_for_answer(chan, outgoing, &to, &allowredir);
    • outgoing ÀÌ null ÀÎ °æ¿ì ÀÌÀü¿¡ Á¶Ä¡¸¦ ÃëÇÏ´Â °ÍÀÌ ÁÁÀ» µíÇÔ.
  • if (peer) {
    • hanguptree(outgoing, peer); peer À» Àç¿ÜÇÑ ³ª¸ÓÁö channel À» hangup ½ÃÅ´.
    • outgoing = NULL;
    • res = bridge_call(chan, peer, allowredir);
    • ast_hangup(peer);
  • }
  • out:
  • hanguptree(outgoing, NULL);
  • return res;

struct chanlist {
        char type[80];
        char description[80];
        int capabilities;
        struct ast_channel * (*requester)(char *type, int format, void *data);
        struct chanlist *next;
} *backends = NULL;
* struct ast_channel *ast_request(char *type, int format, void *data)
  • chan = backends;
  • type ÀÇ channel À» ã¾Æ, chan->requester °¡ ÀÖÀ¸¸é À̸¦ ¼öÇà½ÃŲ´Ù.
    • c = chan->requester(type, format, data);
  • return c;

* int ast_call(struct ast_channel *chan, char *addr, int timeout)
  • chan->pvt_call ÀÌ ÀÖÀ¸¸é À̸¦ ¼öÇà½ÃŲ´Ù.
    • res = chan->pvt->call(chan, addr, timeout);
  • return res;

* int ast_hangup(struct ast_channel *chan)
  • if (chan->stream) ast_stopstream(chan);
  • if (chan->sched) sched_context_destroy(chan->sched);
  • if (chan->blocking) Hard hangup called, while fd is blocking
  • if (chan->pvt->hangup)
    • res = chan->pvt->hangup(chan);
  • if (chan->pvt->pvt) Channel '%s' may not have been hung up properly
  • if (chan->trans) Hard hangup called on '%s' while a translator is in place!
  • if (chan->pbx) PBX may not have been terminated properly
  • if (chan->dnid) free(chan->dnid);
  • if (chan->callerid) free(chan->callerid);
  • free(chan->pvt);
  • free(chan);
  • return res;

* static struct ast_channel *ixj_request(char *type, int format, void *data)

* static int ixj_call(struct ast_channel *ast, char *dest, int timeout)
  • p = ast->pvt->pvt;
  • channel state °¡ AST_STATE_DOWN µµ ¾Æ´Ï°í AST_STATE_RESERVED µµ ¾Æ´Ï¸é
    • return -1;
  • ioctl(p->fd, IXJCTL_RING_START);
  • ast->state = AST_STATE_RINGING;
  • return 0;

* static int ixj_hangup(struct ast_channel *ast)
  • p = ast->pvt->pvt;
  • ast->state = AST_STATE_DOWN;
  • ioctl(p->fd, IXJCTL_REC_STOP) stop recording
  • ioctl(p->fd, IXJCTL_PLAY_STOP) stop playing
  • ioctl(p->fd, IXJCTL_RING_STOP) stop ringing
  • ioctl(p->fd, IXJCTL_CPT_STOP) stop sounds
  • if (ioctl(p->fd, IXJCTL_HOOKSTATE))
    • ioctl(p->fd, IXJCTL_BUSY);
  • p->lastformat = -1; p->lastinput = -1; p->ministate = 0; p->obuflen = 0; p->dialtone = 0;
  • ast->pvt->pvt = NULL;
  • ast->state = AST_STATE_DOWN;
  • restart_monitor();
  • return 0;

* static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localuser *outgoing, int *to, int *allowredir)
  • to °¡ -1 ÀÎ °æ¿ì ¸Å²ô·´Áö ¸øÇÔ.
  • tv.tv_sec = *to / 1000; tv.tv_usec = (*to % 1000) * 1000;
  • while((tv.tv_sec || tv.tv_usec) && !peer) {
    • FD_SET(in->fd, &rfds); FD_SET(in->fd, &efds);
    • o = outgoing;
    • found = -1; numlines = 0;
    • while(o) {
      • if (o->stillgoing) {
        • CHECK_BLOCKING(o->chan);
        • FD_SET(o->chan->fd, &rfds); FD_SET(o->chan->fd, &efds);
        • if (o->chan->fd > found) found = o->chan->fd;
      • }
      • numlines++;
      • o = o->next;
    • }
      • input channel °ú request, call ÀÌ ¼º°øÀûÀÎ channel µéÀ» FD_SET ÇÔ.
    • if (found<0) {
    • }
    • if (in->fd > found) found = in->fd;
    • if (*to > -1)
      • found = select(found + 1, &rfds, NULL, &efds, &tv);
    • else
      • found = select(found + 1, &rfds, NULL, &efds, NULL);
    • if (found < 0) {
    • }
    • o = outgoing;
    • while(o) {
      • if (o->stillgoing) {
        • o->chan->blocking = 0;
        • if (FD_ISSET(o->chan->fd, &rfds) || FD_ISSET(o->chan->fd, &efds)) {
        • ÀÔ·ÂµÈ µ¥ÀÌŸ°¡ ÀÖÀ¸¸é
          • f = ast_read(o->chan); ixj_read
          • if (f) {
            • AST_CONTROL_ANSWER: ringing ÀÎ »óÅ¿¡¼­ offhook À̸é
              • peer = o->chan;
            • AST_CONTROL_BUSY
              • o->stillgoing = 0;
              • numbusies++;
            • AST_CONTROL_RINGING
            • AST_CONTROL_OFFHOOK
            • ast_frfree(f);
          • } else {
            • o->stillgoing = 0;
          • }
        • }
      • }
      • o = o->next;
    • }
    • if (FD_ISSET(in->fd, &rfds) || FD_ISSET(in->fd, &efds)) {
      • f = ast_read(in);
      • ÀÔ·ÂµÈ µ¥ÀÌŸ°¡ ¾ø°Å³ª, hangup À̸é
        • *to=-1; return NULL;
    • }
  • }
  • if (!(tv.tv_sec || tv.tv_usec) && (option_verbose > 2))
    • Nobody picked up in %d ms\n
  • *to = 0;
  • return peer;

FD_ZERO(fd_set *fdset) : *fdsetÀÇ ¸ðµç ºñÆ®¸¦ Áö¿î´Ù.
FD_SET(int fd, fd_set *fdset) : *fdset Áß ¼ÒÄÏ fd¿¡ ÇØ´çÇÏ´Â ºñÆ®¸¦ 1·Î ÇÑ´Ù.
FD_CLR(int fd, fd_set *fdset) : *fdset Áß ¼ÒÄÏ fd¿¡ ÇØ´çÇÏ´Â ºñÆ®¸¦ 0À¸·Î ÇÑ´Ù.
FD_ISSET(int fd, fd_set *fdset) : *fdset Áß ¼ÒÄÏ fd¿¡ ÇØ´çÇÏ´Â ºñÆ®°¡ ¼¼Æ®µÇ¾î ÀÖÀ¸¸é ¾ç¼ö°ªÀÎ fd¸¦ ¸®ÅÏÇÑ´Ù.

select() ´Â FD_SETÀ¸·Î ¼³Á¤µÈ fd¸¸À» È®ÀÎÇÕ´Ï´Ù. ±×¸®°í È®ÀÎ °á°ú read¶Ç´Â write Áغñ°¡ µÈ fd¸¦ fdset ³»¿¡¼­ '¼¼Æ®'½Ãŵ´Ï´Ù. µû¶ó¼­ select() ÇÔ¼ö Á÷ÈÄ¿¡ FD_ISSETÀ¸·Î ƯÁ¤ fd°¡ 'SET'µÇ¾ú´ÂÁö È®ÀÎÇÒ ¼ö ÀÖ½À´Ï´Ù. 

* static int bridge_call(struct ast_channel *chan, struct ast_channel *peer, int allowredirect)
  • struct ast_channel *cs3;
  • if (chan->state != AST_STATE_UP)
    • if (ast_answer(chan))
      • return -1;
  • cs0 = chan;
  • cs1 = peer;
  • for (/* ever */;;) {
    • who = ast_waitfor_n(cs, 2, &to);
    • f = ast_read(who);
    • if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)))
      • return -1;
    • if ((f->frametype == AST_FRAME_VOICE) ||
      (f->frametype == AST_FRAME_DTMF)) {
      • if ((f->frametype == AST_FRAME_DTMF) && (who == peer) && allowredirect) {
      • } else {
        • if (who == chan)
          • ast_write(peer, f);
        • else
          • ast_write(chan, f);
      • }
      • ast_frfree(f);
    • } else
      • ast_frfree(f);
    • cs2 = cs0; cs0 = cs1; cs1 = cs2;
  • }
  • return res;

* static int ixj_answer(struct ast_channel *ast)
  • ixj_setup(ast);
  • ast->rings = 0;
  • ast->state = AST_STATE_UP;
  • return 0;

* static int ixj_setup(struct ast_channel *ast)
  • p = ast->pvt->pvt;
  • ioctl(p->fd, IXJCTL_CPT_STOP);
  • if (ast->format & AST_FORMAT_G723_1) {
    • ioctl(p->fd, IXJCTL_REC_STOP);
    • if (p->lastinput != AST_FORMAT_G723_1) {
      • p->lastinput = AST_FORMAT_G723_1;
      • if (ioctl(p->fd, IXJCTL_REC_CODEC, G723_63)) {
        • Failed to set codec to g723.1
        • return -1;
      • }
    • }
  • } else if (ast->format & AST_FORMAT_SLINEAR) {
    • ioctl(p->fd, IXJCTL_REC_STOP);
    • if (p->lastinput != AST_FORMAT_SLINEAR) {
      • p->lastinput = AST_FORMAT_SLINEAR;
      • if (ioctl(p->fd, IXJCTL_REC_CODEC, LINEAR16)) {
        • Failed to set codec to signed linear 16
        • return -1;
      • }
    • }
  • } else {
    • Can't do format
    • return -1;
  • }
  • if (ioctl(p->fd, IXJCTL_REC_START)) {
    • Failed to start recording
    • return -1;
  • }
  • return 0;

ID
Password
Join
You will hear good news from one you thought unfriendly to you.


sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2009-07-14 08:59:36
Processing time 0.0117 sec