Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:33 2009

## Asterisk developer's documentation

# chan_modem_bestdata.c File Reference

`#include <stdio.h>`
`#include <string.h>`
`#include <stdlib.h>`
`#include <errno.h>`
`#include <unistd.h>`
`#include "asterisk.h"`
`#include "asterisk/lock.h"`
`#include "asterisk/vmodem.h"`
`#include "asterisk/module.h"`
`#include "asterisk/frame.h"`
`#include "asterisk/logger.h"`
`#include "asterisk/options.h"`

Include dependency graph for chan_modem_bestdata.c:

Go to the source code of this file.

## Defines

#define | DLE 16
#define | RINGT 7000
#define | STATE_COMMAND 0
#define | STATE_VOICE 1
#define | STATE_VOICEPLAY 2
#define | VRA "40"
#define | VRN "25"

## Functions

| AST_MUTEX_DEFINE_STATIC (usecnt_lock)
static int | bestdata_answer (struct ast_modem_pvt *p)
static int | bestdata_break (struct ast_modem_pvt *p)
static void | bestdata_decusecnt (void)
static int | bestdata_dial (struct ast_modem_pvt *p, char *stuff)
static int | bestdata_dialdigit (struct ast_modem_pvt *p, char digit)
static struct ast_frame * | bestdata_handle_escape (struct ast_modem_pvt *p, char esc)
static int | bestdata_hangup (struct ast_modem_pvt *p)
static char * | bestdata_identify (struct ast_modem_pvt *p)
static void | bestdata_incusecnt (void)
static int | bestdata_init (struct ast_modem_pvt *p)
static struct ast_frame * | bestdata_read (struct ast_modem_pvt *p)
static int | bestdata_startplay (struct ast_modem_pvt *p)
static int | bestdata_startrec (struct ast_modem_pvt *p)
static int | bestdata_write (struct ast_modem_pvt *p, struct ast_frame *f)
char * | description ()
| Provides a description of the module.
char * | key ()
| Returns the ASTERISK_GPL_KEY.
int | load_module (void)
| Initialize the module.
int | unload_module (void)
| Cleanup all module structures, sockets, etc.
int | usecount (void)
| Provides a usecount.

## Variables

static struct ast_modem_driver | bestdata_driver
static char * | bestdata_idents []
static char * | breakcmd = "\020!"
static char * | desc = "BestData (Conexant V.90 Chipset) VoiceModem Driver"
static int | usecnt

## Define Documentation

#define DLE 16

Referenced by bestdata_write().

#define RINGT 7000

Definition at line 52 of file chan_modem_bestdata.c.

Referenced by bestdata_handle_escape().

#define STATE_COMMAND 0

Definition at line 45 of file chan_modem_bestdata.c.

#define STATE_VOICE 1

Definition at line 46 of file chan_modem_bestdata.c.

#define STATE_VOICEPLAY 2

Definition at line 47 of file chan_modem_bestdata.c.

Referenced by bestdata_read(), bestdata_startplay(), and bestdata_write().

#define VRA "40"

Definition at line 49 of file chan_modem_bestdata.c.

#define VRN "25"

Definition at line 50 of file chan_modem_bestdata.c.

## Function Documentation

AST_MUTEX_DEFINE_STATIC | ( | usecnt_lock |  | ) |

static int bestdata_answer | ( | struct ast_modem_pvt * | p | ) | `[static]`

Definition at line 476 of file chan_modem_bestdata.c.

References ast_log(), ast_modem_expect(), ast_modem_send(), ast_modem_pvt::lastring, LOG_WARNING, ast_modem_pvt::response, and ast_modem_pvt::ringt.

    00477 {
    00478    p->ringt = 0;
    00479    p->lastring = 0;
    00480    if (ast_modem_send(p, "AT+VLS=1", 0) ||
    00481         ast_modem_expect(p, "OK", 10)) {
    00482       ast_log(LOG_WARNING, "Unable to answer: %s", p->response);
    00483       return -1;
    00484    }
    00485    return 0;
    00486 }

static int bestdata_break | ( | struct ast_modem_pvt * | p | ) | `[static]`

Definition at line 93 of file chan_modem_bestdata.c.

References ast_log(), ast_modem_expect(), ast_modem_read_response(), ast_modem_send(), LOG_WARNING, ast_modem_pvt::ministate, and STATE_COMMAND.

Referenced by bestdata_dial(), bestdata_dialdigit(), bestdata_hangup(), bestdata_init(), bestdata_startplay(), and bestdata_startrec().

    00094 {
    00095    if (ast_modem_send(p, breakcmd, 2)) {
    00096       ast_log(LOG_WARNING, "Failed to break\n");
    00097       return -1;
    00098    }
    00099    p->ministate = STATE_COMMAND;
    00100    usleep(10000);
    00101    /* Read any outstanding junk */
    00102    while(!ast_modem_read_response(p, 1));
    00103    if (ast_modem_send(p, "AT", 0)) {
    00104       /* Modem might be stuck in some weird mode, try to get it out */
    00105       ast_modem_send(p, "+++", 3);
    00106       if (ast_modem_expect(p, "OK", 10)) {
    00107          ast_log(LOG_WARNING, "Modem is not responding\n");
    00108          return -1;
    00109       }
    00110       if (ast_modem_send(p, "AT", 0)) {
    00111          ast_log(LOG_WARNING, "Modem is not responding\n");
    00112          return -1;
    00113       }
    00114    }
    00115    if (ast_modem_expect(p, "OK", 5)) {
    00116       ast_log(LOG_WARNING, "Modem did not respond properly\n");
    00117       return -1;
    00118    }
    00119    return 0;
    00120 }

static void bestdata_decusecnt | ( | void |  | ) | `[static]`

Definition at line 468 of file chan_modem_bestdata.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_update_use_count(), and usecnt_lock.

    00469 {
    00470    ast_mutex_lock(&usecnt_lock);
    00471    usecnt++;
    00472    ast_mutex_unlock(&usecnt_lock);
    00473    ast_update_use_count();
    00474 }

static int bestdata_dial | ( | struct ast_modem_pvt * | p,
|  | char * | stuff |
| ) |  |  | `[static]`

Definition at line 502 of file chan_modem_bestdata.c.

References ast_log(), ast_modem_send(), bestdata_break(), ast_modem_pvt::dialtype, LOG_WARNING, ast_modem_pvt::ministate, and STATE_COMMAND.

    00503 {
    00504    char cmd[800] = "",a[20]="";
    00505    int i,j;
    00506
    00507    if (p->ministate != STATE_COMMAND)
    00508       {
    00509       bestdata_break(p);
    00510       strncpy(cmd, "AT+VTS=", sizeof(cmd) - 1);
    00511       j = strlen(cmd);
    00512       for(i = 0; stuff[i]; i++)
    00513          {
    00514          switch(stuff[i])
    00515             {
    00516              case '!' :
    00517             a[0] = stuff[i];
    00518             a[1] = 0;
    00519             break;
    00520              case ',':
    00521             strncpy(a, "[,,100]", sizeof(a) - 1);
    00522             break;
    00523              default:
    00524             snprintf(a, sizeof(a), "{%c,7}", stuff[i]);
    00525             }
    00526          if (stuff[i + 1]) strncat(a, ",", sizeof(a) - strlen(a) - 1);
    00527          strncpy(cmd + j, a, sizeof(cmd) - j - 1);
    00528          j += strlen(a);
    00529          }
    00530       }
    00531    else
    00532       {
    00533       snprintf(cmd, sizeof(cmd), "ATD%c %s", p->dialtype,stuff);
    00534       }
    00535    if (ast_modem_send(p, cmd, 0)) {
    00536       ast_log(LOG_WARNING, "Unable to dial\n");
    00537       return -1;
    00538    }
    00539    return 0;
    00540 }

static int bestdata_dialdigit | ( | struct ast_modem_pvt * | p,
|  | char | digit |
| ) |  |  | `[static]`

Definition at line 488 of file chan_modem_bestdata.c.

References ast_log(), ast_modem_expect(), ast_modem_send(), bestdata_break(), LOG_WARNING, ast_modem_pvt::ministate, ast_modem_pvt::response, and STATE_COMMAND.

    00489 {
    00490    char cmd[80];
    00491
    00492    if (p->ministate != STATE_COMMAND) bestdata_break(p);
    00493    snprintf(cmd, sizeof(cmd), "AT+VTS=%c", digit);
    00494    if (ast_modem_send(p, cmd, 0) ||
    00495         ast_modem_expect(p, "OK", 10)) {
    00496       ast_log(LOG_WARNING, "Unable to answer: %s", p->response);
    00497       return -1;
    00498    }
    00499    return 0;
    00500 }

static struct ast_frame* bestdata_handle_escape | ( | struct ast_modem_pvt * | p,
|  | char | esc |
| ) |  |  | `[static, read]`

Definition at line 168 of file chan_modem_bestdata.c.

References AST_CONTROL_BUSY, AST_CONTROL_RING, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_NULL, ast_log(), ast_modem_read_response(), ast_modem_send(), ast_modem_trim(), ast_setstate(), AST_STATE_UP, bestdata_startrec(), CHAR_ETX, ast_channel::cid, ast_callerid::cid_name, ast_modem_pvt::cid_name, ast_callerid::cid_num, ast_modem_pvt::cid_num, ast_frame::data, ast_frame::datalen, ast_frame::delivery, ast_modem_pvt::dtmfrx, ast_modem_pvt::fr, ast_frame::frametype, ast_modem_pvt::gotclid, ast_modem_pvt::lastring, LOG_DEBUG, LOG_WARNING, ast_frame::mallocd, name, ast_frame::offset, ast_modem_pvt::owner, ast_modem_pvt::response, ast_modem_pvt::ringt, RINGT, ast_frame::samples, strdup, and ast_frame::subclass.

Referenced by bestdata_read().

    00169 {
    00170    char name[30]="",nmbr[30]="";
    00171    time_t   now;
    00172
    00173    /* Handle escaped characters -- but sometimes we call it directly as
    00174       a quick way to cause known responses */
    00175    p->fr.frametype = AST_FRAME_NULL;
    00176    p->fr.subclass = 0;
    00177    p->fr.data = NULL;
    00178    p->fr.datalen = 0;
    00179    p->fr.samples = 0;
    00180    p->fr.offset = 0;
    00181    p->fr.mallocd = 0;
    00182    p->fr.delivery.tv_sec = 0;
    00183    p->fr.delivery.tv_usec = 0;
    00184    if (esc)
    00185       ast_log(LOG_DEBUG, "Escaped character '%c'\n", esc);
    00186
    00187    switch(esc) {
    00188    case 'R': /* Pseudo ring */
    00189       time(&now);
    00190       if (now > (p->lastring + (RINGT / 1000)))
    00191          { /* if stale, treat as new */
    00192          p->gotclid = 0;
    00193          }
    00194       if (p->gotclid)
    00195          {
    00196          p->fr.frametype = AST_FRAME_CONTROL;
    00197          p->fr.subclass = AST_CONTROL_RING;
    00198          }
    00199       p->ringt = RINGT;
    00200       time(&p->lastring);
    00201       return &p->fr;
    00202    case 'X': /* Caller-ID Spill */
    00203       if (p->gotclid) return &p->fr;
    00204       name[0] = nmbr[0] = 0;
    00205       for(;;)
    00206          {
    00207          char res[1000]="";
    00208
    00209          if (ast_modem_read_response(p, 5)) break;
    00210          strncpy(res, p->response, sizeof(res)-1);
    00211          ast_modem_trim(res);
    00212          if (!strncmp(res,"\020.",2)) break;
    00213          if (!strncmp(res,"NAME",4)) strncpy(name,res + 7, sizeof(name) - 1);
    00214          if (!strncmp(res,"NMBR",4)) strncpy(nmbr,res + 7, sizeof(nmbr) - 1);
    00215          }
    00216       p->gotclid = 1;
    00217       if ((!strcmp(name,"O")) || (!strcmp(name,"P"))) name[0] = 0;
    00218       if ((!strcmp(nmbr,"O")) || (!strcmp(nmbr,"P"))) nmbr[0] = 0;
    00219       if (name[0])
    00220          strncpy(p->cid_name, name, sizeof(p->cid_name) - 1);
    00221       if (nmbr[0])
    00222          strncpy(p->cid_num, nmbr, sizeof(p->cid_num) - 1);
    00223       if (p->owner) {
    00224          p->owner->cid.cid_num = strdup(p->cid_num);
    00225          p->owner->cid.cid_name = strdup(p->cid_name);
    00226       }
    00227       return &p->fr;
    00228    case '@': /* response from "OK" in command mode */
    00229       if (p->owner)
    00230          ast_setstate(p->owner, AST_STATE_UP);
    00231       if (bestdata_startrec(p)) return NULL;
    00232       p->fr.frametype = AST_FRAME_CONTROL;
    00233       p->fr.subclass = AST_CONTROL_RING;
    00234       return &p->fr;
    00235    case 'b': /* Busy signal */
    00236       p->fr.frametype = AST_FRAME_CONTROL;
    00237       p->fr.subclass = AST_CONTROL_BUSY;
    00238       return &p->fr;
    00239    case 'o': /* Overrun */
    00240       ast_log(LOG_WARNING, "Overflow on modem, flushing buffers\n");
    00241       if (ast_modem_send(p, "\0x10E", 2))
    00242          ast_log(LOG_WARNING, "Unable to flush buffers\n");
    00243       return &p->fr;
    00244    case '0':  /* All the DTMF characters */
    00245    case '1':
    00246    case '2':
    00247    case '3':
    00248    case '4':
    00249    case '5':
    00250    case '6':
    00251    case '7':
    00252    case '8':
    00253    case '9':
    00254    case '*':
    00255    case '#':
    00256    case 'A':
    00257    case 'B':
    00258    case 'C':
    00259    case 'D':
    00260       p->dtmfrx = esc;  /* save this for when its done */
    00261       return &p->fr;
    00262    case '/': /* Start of DTMF tone shielding */
    00263       p->dtmfrx = ' ';
    00264       return &p->fr;
    00265    case '~': /* DTMF transition to off */
    00266       if (p->dtmfrx > ' ')
    00267          {
    00268          p->fr.frametype = AST_FRAME_DTMF;
    00269          p->fr.subclass = p->dtmfrx;
    00270          }
    00271       p->dtmfrx = 0;
    00272       return &p->fr;
    00273    case 'u': /* Underrun */
    00274       ast_log(LOG_WARNING, "Data underrun\n");
    00275       /* Fall Through */
    00276    case CHAR_ETX: /* End Transmission */
    00277    case 'd': /* Dialtone */
    00278    case 'c': /* Calling Tone */
    00279    case 'e': /* European version */
    00280    case 'a': /* Answer Tone */
    00281    case 'f': /* Bell Answer Tone */
    00282    case 'T': /* Timing mark */
    00283    case 't': /* Handset off hook */
    00284    case 'h': /* Handset hungup */
    00285    case 0: /* Pseudo signal */
    00286       /* Ignore */
    00287       return &p->fr;
    00288    default:
    00289       ast_log(LOG_DEBUG, "Unknown Escaped character '%c' (%d)\n", esc, esc);
    00290    }
    00291    return &p->fr;
    00292 }

static int bestdata_hangup | ( | struct ast_modem_pvt * | p | ) | `[static]`

Definition at line 542 of file chan_modem_bestdata.c.

References ast_log(), ast_modem_expect(), ast_modem_send(), bestdata_break(), ast_modem_pvt::dtmfrx, ast_modem_pvt::gotclid, ast_modem_pvt::lastring, LOG_WARNING, and ast_modem_pvt::ringt.

    00543 {
    00544    if (bestdata_break(p))
    00545       return -1;
    00546    /* Hangup by switching to data, then back to voice */
    00547    if (ast_modem_send(p, "ATH", 0) ||
    00548         ast_modem_expect(p, "OK", 8)) {
    00549       ast_log(LOG_WARNING, "Unable to set to data mode\n");
    00550       return -1;
    00551    }
    00552    if (ast_modem_send(p, "AT+FCLASS=8", 0) ||
    00553         ast_modem_expect(p, "OK", 5)) {
    00554       ast_log(LOG_WARNING, "Unable to set to voice mode\n");
    00555       return -1;
    00556    }
    00557    p->gotclid = 0;
    00558    p->ringt = 0;
    00559    p->lastring = 0;
    00560    p->dtmfrx = 0;
    00561    return 0;
    00562 }

static char* bestdata_identify | ( | struct ast_modem_pvt * | p | ) | `[static]`

Definition at line 435 of file chan_modem_bestdata.c.

References ast_modem_expect(), ast_modem_read_response(), ast_modem_send(), ast_modem_trim(), ast_modem_pvt::response, and strdup.

    00436 {
    00437    char identity[256];
    00438    char mfr[80];
    00439    char mdl[80];
    00440    char rev[80];
    00441    ast_modem_send(p, "AT+FMM", 0);
    00442    ast_modem_read_response(p, 5);
    00443    strncpy(mdl, p->response, sizeof(mdl)-1);
    00444    ast_modem_trim(mdl);
    00445    ast_modem_expect(p, "OK", 5);
    00446    ast_modem_send(p, "AT+FMI", 0);
    00447    ast_modem_read_response(p, 5);
    00448    strncpy(mfr, p->response, sizeof(mfr)-1);
    00449    ast_modem_trim(mfr);
    00450    ast_modem_expect(p, "OK", 5);
    00451    ast_modem_send(p, "AT+FMR", 0);
    00452    ast_modem_read_response(p, 5);
    00453    strncpy(rev, p->response, sizeof(rev)-1);
    00454    ast_modem_trim(rev);
    00455    ast_modem_expect(p, "OK", 5);
    00456    snprintf(identity, sizeof(identity), "%s Model %s Revision %s", mfr, mdl, rev);
    00457    return strdup(identity);
    00458 }

static void bestdata_incusecnt | ( | void |  | ) | `[static]`

Definition at line 460 of file chan_modem_bestdata.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_update_use_count(), and usecnt_lock.

    00461 {
    00462    ast_mutex_lock(&usecnt_lock);
    00463    usecnt++;
    00464    ast_mutex_unlock(&usecnt_lock);
    00465    ast_update_use_count();
    00466 }

static int bestdata_init | ( | struct ast_modem_pvt * | p | ) | `[static]`

Definition at line 122 of file chan_modem_bestdata.c.

References ast_log(), ast_modem_expect(), ast_modem_send(), bestdata_break(), LOG_DEBUG, LOG_WARNING, ast_modem_pvt::ministate, option_debug, STATE_COMMAND, VRA, and VRN.

    00123 {
    00124    if (option_debug)
    00125       ast_log(LOG_DEBUG, "bestdata_init()\n");
    00126    if (bestdata_break(p))
    00127       return -1;
    00128    /* Force into command mode */
    00129    p->ministate = STATE_COMMAND;
    00130    if (ast_modem_send(p, "AT+FCLASS=8", 0) ||
    00131         ast_modem_expect(p, "OK", 5)) {
    00132       ast_log(LOG_WARNING, "Unable to set to voice mode\n");
    00133       return -1;
    00134    }
    00135    if (ast_modem_send(p, "AT+VSM=1,8000,0,0", 0) ||
    00136         ast_modem_expect(p, "OK", 5)) {
    00137       ast_log(LOG_WARNING, "Unable to set to 8000 Hz sampling\n");
    00138       return -1;
    00139    }
    00140    if (ast_modem_send(p, "AT+VLS=0", 0) ||
    00141         ast_modem_expect(p, "OK", 5)) {
    00142       ast_log(LOG_WARNING, "Unable to set to telco interface\n");
    00143       return -1;
    00144    }
    00145    if (ast_modem_send(p, "AT+VRA=" VRA, 0) ||
    00146         ast_modem_expect(p, "OK", 5)) {
    00147       ast_log(LOG_WARNING, "Unable to set to 'ringback goes away' timer\n");
    00148       return -1;
    00149    }
    00150    if (ast_modem_send(p, "AT+VRN=" VRN, 0) ||
    00151         ast_modem_expect(p, "OK", 5)) {
    00152       ast_log(LOG_WARNING, "Unable to set to 'ringback never came timer'\n");
    00153       return -1;
    00154    }
    00155    if (ast_modem_send(p, "AT+VTD=63", 0) ||
    00156         ast_modem_expect(p, "OK", 5)) {
    00157       ast_log(LOG_WARNING, "Unable to set to tone detection\n");
    00158       return -1;
    00159    }
    00160    if (ast_modem_send(p, "AT+VCID=1", 0) ||
    00161         ast_modem_expect(p, "OK", 5)) {
    00162       ast_log(LOG_WARNING, "Unable to enable Caller*ID\n");
    00163       return -1;
    00164    }
    00165    return 0;
    00166 }

static struct ast_frame* bestdata_read | ( | struct ast_modem_pvt * | p | ) | `[static, read]`

Definition at line 294 of file chan_modem_bestdata.c.

References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_modem_trim(), ast_waitfor_n_fd(), bestdata_handle_escape(), bestdata_startrec(), CHAR_DLE, ast_frame::data, ast_frame::datalen, ast_frame::delivery, ast_modem_pvt::dev, ast_modem_pvt::dtmfrx, ast_modem_pvt::f, ast_modem_pvt::fr, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_frame::mallocd, ast_modem_pvt::ministate, ast_modem_pvt::mode, MODEM_MODE_IMMEDIATE, ast_modem_pvt::obuf, ast_modem_pvt::obuflen, ast_frame::offset, option_debug, result, ast_modem_pvt::ringt, ast_frame::samples, ast_frame::src, STATE_COMMAND, STATE_VOICEPLAY, and ast_frame::subclass.

    00295 {
    00296    char result[256];
    00297    short *b;
    00298    struct ast_frame *f=NULL;
    00299    int res;
    00300    int x;
    00301
    00302    if (p->ministate == STATE_COMMAND) {
    00303       /* Read the first two bytes, first, in case it's a control message */
    00304       fread(result, 1, 2, p->f);
    00305       if (result[0] == CHAR_DLE) {
    00306          return bestdata_handle_escape(p, result[1]);
    00307       } else {
    00308          if (p->ringt) /* if ring timeout specified */
    00309             {
    00310             x = fileno(p->f);
    00311             res = ast_waitfor_n_fd(&x, 1, &p->ringt, NULL);
    00312             if (res < 0) {
    00313                return NULL;
    00314             }
    00315             }
    00316          if ((result[0] == '\n') || (result[0] == '\r'))
    00317             return bestdata_handle_escape(p, 0);
    00318          /* Read the rest of the line */
    00319          fgets(result + 2, sizeof(result) - 2, p->f);
    00320          ast_modem_trim(result);
    00321          if (!strcasecmp(result, "OK")) {
    00322             /* If we're in immediate mode, reply now */
    00323             if (p->mode == MODEM_MODE_IMMEDIATE)
    00324                return bestdata_handle_escape(p, '@');
    00325          } else
    00326          if (!strcasecmp(result, "BUSY")) {
    00327             /* Same as a busy signal */
    00328             return bestdata_handle_escape(p, 'b');
    00329          } else
    00330          if (!strcasecmp(result, "RING")) {
    00331             return bestdata_handle_escape(p, 'R');
    00332          } else
    00333          if (!strcasecmp(result, "NO DIALTONE")) {
    00334             /* There's no dialtone, so the line isn't working */
    00335             ast_log(LOG_WARNING, "Device '%s' lacking dialtone\n", p->dev);
    00336             return NULL;
    00337          }
    00338          ast_log(LOG_DEBUG, "Modem said '%s'\n", result);
    00339          return bestdata_handle_escape(p, 0);
    00340       }
    00341    } else {
    00342         /* if playing, start recording instead */
    00343       if (p->ministate == STATE_VOICEPLAY)
    00344          {
    00345          if (bestdata_startrec(p)) return NULL;
    00346          }
    00347       /* We have to be more efficient in voice mode */
    00348       b = (short *)(p->obuf + p->obuflen);
    00349       while (p->obuflen/2 < 240) {
    00350          /* Read ahead the full amount */
    00351          res = fread(result, 1, 240 - p->obuflen/2, p->f);
    00352          if (res < 1) {
    00353             /* If there's nothing there, just continue on */
    00354             if (errno == EAGAIN)
    00355                return bestdata_handle_escape(p, 0);
    00356             ast_log(LOG_WARNING, "Read failed: %s\n", strerror(errno));
    00357          }
    00358          for (x=0;x<res;x++) {
    00359             /* Process all the bytes that we've read */
    00360             if (result[x] == CHAR_DLE) {
    00361                /* We assume there is no more than one signal frame among our
    00362                   data.  */
    00363                if (f) ast_log(LOG_WARNING, "Warning: Dropped a signal frame\n");
    00364                  /* if not a DLE in the data */
    00365                if (result[++x] != CHAR_DLE)
    00366                   {
    00367                   /* If bestdata_handle_escape says NULL, say it now, doesn't matter
    00368                      what else is there, the connection is dead. */
    00369                   f = bestdata_handle_escape(p, result[x]);
    00370                   if (p->dtmfrx) continue;
    00371                   return(f);
    00372                   }
    00373             }
    00374             /* Generate a 16-bit signed linear value from our
    00375                unsigned 8-bit value */
    00376             *(b++) = (((short)result[x]) - 127) * 0xff;
    00377             p->obuflen += 2;
    00378          }
    00379          if (f) break;
    00380       }
    00381       /* If we have a control frame, return it now */
    00382       if (f) return f;
    00383       /* If we get here, we have a complete voice frame */
    00384       p->fr.frametype = AST_FRAME_VOICE;
    00385       p->fr.subclass = AST_FORMAT_SLINEAR;
    00386       p->fr.samples = 240;
    00387       p->fr.data = p->obuf;
    00388       p->fr.datalen = p->obuflen;
    00389       p->fr.mallocd = 0;
    00390       p->fr.delivery.tv_sec = 0;
    00391       p->fr.delivery.tv_usec = 0;
    00392       p->fr.offset = AST_FRIENDLY_OFFSET;
    00393       p->fr.src = __FUNCTION__;
    00394       if (option_debug)
    00395          ast_log(LOG_DEBUG, "bestdata_read(voice frame)\n");
    00396       p->obuflen = 0;
    00397       return &p->fr;
    00398    }
    00399    return NULL;
    00400 }

static int bestdata_startplay | ( | struct ast_modem_pvt * | p | ) | `[static]`

Definition at line 81 of file chan_modem_bestdata.c.

References ast_log(), ast_modem_expect(), ast_modem_send(), bestdata_break(), LOG_WARNING, ast_modem_pvt::ministate, STATE_COMMAND, and STATE_VOICEPLAY.

Referenced by bestdata_write().

    00082 {
    00083    if (p->ministate != STATE_COMMAND) bestdata_break(p);
    00084    if (ast_modem_send(p, "AT+VTX", 0) ||
    00085         ast_modem_expect(p, "CONNECT", 5)) {
    00086       ast_log(LOG_WARNING, "Unable to start recording\n");
    00087       return -1;
    00088    }
    00089    p->ministate = STATE_VOICEPLAY;
    00090    return 0;
    00091 }

static int bestdata_startrec | ( | struct ast_modem_pvt * | p | ) | `[static]`

Definition at line 69 of file chan_modem_bestdata.c.

References ast_log(), ast_modem_expect(), ast_modem_send(), bestdata_break(), LOG_WARNING, ast_modem_pvt::ministate, STATE_COMMAND, and STATE_VOICE.

Referenced by bestdata_handle_escape(), and bestdata_read().

    00070 {
    00071    if (p->ministate != STATE_COMMAND) bestdata_break(p);
    00072    if (ast_modem_send(p, "AT+VRX", 0) ||
    00073         ast_modem_expect(p, "CONNECT", 5)) {
    00074       ast_log(LOG_WARNING, "Unable to start recording\n");
    00075       return -1;
    00076    }
    00077    p->ministate = STATE_VOICE;
    00078    return 0;
    00079 }

static int bestdata_write | ( | struct ast_modem_pvt * | p,
|  | struct ast_frame * | f |
| ) |  |  | `[static]`

Definition at line 402 of file chan_modem_bestdata.c.

References ast_channel::_state, ast_log(), AST_STATE_UP, bestdata_startplay(), ast_frame::data, ast_frame::datalen, DLE, ast_modem_pvt::f, LOG_DEBUG, LOG_WARNING, ast_modem_pvt::ministate, option_debug, ast_modem_pvt::owner, and STATE_VOICEPLAY.

    00403 {
    00404 unsigned char  c,buf[32768]; /* I hope we dont have frames larger then 16K */
    00405 int   i,j;
    00406 short *sp;
    00407 unsigned long u;
    00408 #define  DLE   16
    00409
    00410    if (p->owner && (p->owner->_state == AST_STATE_UP) &&
    00411       (p->ministate != STATE_VOICEPLAY) && bestdata_startplay(p)) return -1;
    00412    sp = (short *) f->data;
    00413      /* stick DLE's in ahead of anything else */
    00414    for(i = 0,j = 0; i < f->datalen / 2; i++)
    00415       {
    00416       *sp *= 3;
    00417       u = *sp++ + 32768;
    00418       c = u >> 8;
    00419       if (c == DLE) buf[j++] = DLE;
    00420       buf[j++] = c;
    00421       }
    00422    do i = fwrite(buf,1,j,p->f);
    00423    while ((i == -1) && (errno == EWOULDBLOCK));
    00424    if (i != j)
    00425       {
    00426       ast_log(LOG_WARNING,"modem short write!!\n");
    00427       return -1;
    00428       }
    00429    fflush(p->f);
    00430    if (option_debug)
    00431       ast_log(LOG_DEBUG, "bestdata_write()\n");
    00432    return 0;
    00433 }

char* description | ( | void |  | ) |

Provides a description of the module.

Returns:
  a short description of your module

Definition at line 605 of file chan_modem_bestdata.c.

    00606 {
    00607    return desc;
    00608 }

char* key | ( | void |  | ) |

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

     char *key(void) {
             return ASTERISK_GPL_KEY;
     }

Returns:
  ASTERISK_GPL_KEY

Definition at line 610 of file chan_modem_bestdata.c.

References ASTERISK_GPL_KEY.

    00611 {
    00612    return ASTERISK_GPL_KEY;
    00613 }

int load_module | ( | void |  | ) |

Initialize the module.

This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.

Returns:
  This function should return 0 on success and non-zero on failure. If the module is not loaded successfully, Asterisk will call its unload_module() function.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
  int Always 0.

TE STUFF END

Definition at line 595 of file chan_modem_bestdata.c.

References ast_register_modem_driver().

    00596 {
    00597    return ast_register_modem_driver(&bestdata_driver);
    00598 }

int unload_module | ( | void |  | ) |

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
  Zero on success, or non-zero on error.

Definition at line 600 of file chan_modem_bestdata.c.

References ast_unregister_modem_driver().

    00601 {
    00602    return ast_unregister_modem_driver(&bestdata_driver);
    00603 }

int usecount | ( | void |  | ) |

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
  The module's usecount.

Definition at line 590 of file chan_modem_bestdata.c.

    00591 {
    00592    return usecnt;
    00593 }

## Variable Documentation

struct ast_modem_driver bestdata_driver`[static]`

Definition at line 564 of file chan_modem_bestdata.c.

char* bestdata_idents[]`[static]`

Initial value:

     {

       "ACF3_V1.010-V90_P21_FSH",
       NULL
    }

Definition at line 61 of file chan_modem_bestdata.c.

char* breakcmd = "\020!"`[static]`

Definition at line 54 of file chan_modem_bestdata.c.

char* desc = "BestData (Conexant V.90 Chipset) VoiceModem Driver"`[static]`

Definition at line 56 of file chan_modem_bestdata.c.

int usecnt`[static]`

Definition at line 58 of file chan_modem_bestdata.c.