· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
Asterisk Source/App Dial

AsteriskSource/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
Everybody ought to have a friend.


sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2009-08-09 14:52:34
Processing time 0.0124 sec