tdd.c File Reference

#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <ctype.h>
#include <asterisk/ulaw.h>
#include <asterisk/tdd.h>
#include <asterisk/logger.h>
#include <asterisk/fskmodem.h>
#include "ecdisa.h"

Include dependency graph for tdd.c:

Go to the source code of this file.

Data Structures

struct  tdd_state

Defines

#define TDD_SPACE   1800.0
#define TDD_MARK   1400.0
#define PUT_BYTE(a)
#define PUT_AUDIO_SAMPLE(y)
#define PUT_TDD_MARKMS
#define PUT_TDD_BAUD(bit)
#define PUT_TDD_STOP
#define PUT_TDD(byte)

Functions

void tdd_init (void)
 CallerID Initialization.
struct tdd_statetdd_new (void)
 Create a TDD state machine.
int ast_tdd_gen_ecdisa (unsigned char *outbuf, int len)
 Generate Echo Canceller diable tone (2100HZ).
int tdd_feed (struct tdd_state *tdd, unsigned char *ubuf, int len)
 Read samples into the state machine, and return character (if any).
void tdd_free (struct tdd_state *tdd)
 Free a TDD state machine.
int tdd_generate (struct tdd_state *tdd, unsigned char *buf, char *str)
 Generates a CallerID FSK stream in ulaw format suitable for transmission.


Define Documentation

#define PUT_AUDIO_SAMPLE (  ) 

Value:

do { \
   int index = (short)(rint(8192.0 * (y))); \
   *(buf++) = AST_LIN2MU(index); \
   bytes++; \
} while(0)

Definition at line 196 of file tdd.c.

#define PUT_BYTE (  ) 

Value:

do { \
   *(buf++) = (a); \
   bytes++; \
} while(0)

Definition at line 191 of file tdd.c.

#define PUT_TDD ( byte   ) 

Definition at line 225 of file tdd.c.

#define PUT_TDD_BAUD ( bit   ) 

Definition at line 208 of file tdd.c.

#define PUT_TDD_MARKMS

Value:

do { \
   int x; \
   for (x=0;x<8;x++) \
      PUT_AUDIO_SAMPLE(tdd_getcarrier(&cr, &ci, 1)); \
} while(0)

Definition at line 202 of file tdd.c.

#define PUT_TDD_STOP

Definition at line 216 of file tdd.c.

#define TDD_MARK   1400.0

Definition at line 45 of file tdd.c.

#define TDD_SPACE   1800.0

Definition at line 44 of file tdd.c.


Function Documentation

int ast_tdd_gen_ecdisa ( unsigned char *  outbuf,
int  len 
)

Generate Echo Canceller diable tone (2100HZ).

Parameters:
outbuf This is the buffer to receive the tone data
len This is the length (in samples) of the tone data to generate Returns 0 if no error, and -1 if error.

Definition at line 101 of file tdd.c.

00102 {
00103    int pos = 0;
00104    int cnt;
00105    while(len) {
00106       cnt = len;
00107       if (cnt > sizeof(ecdisa))
00108          cnt = sizeof(ecdisa);
00109       memcpy(outbuf + pos, ecdisa, cnt);
00110       pos += cnt;
00111       len -= cnt;
00112    }
00113    return 0;
00114 }

int tdd_feed ( struct tdd_state tdd,
unsigned char *  ubuf,
int  samples 
)

Read samples into the state machine, and return character (if any).

Parameters:
tdd Which state machine to act upon
buffer containing your samples
samples number of samples contained within the buffer.
Send received audio to the TDD demodulator. Returns -1 on error, 0 for "needs more samples", and > 0 (the character) if reception of a character is complete.

Definition at line 116 of file tdd.c.

00117 {
00118    int mylen = len;
00119    int olen;
00120    int b = 'X';
00121    int res;
00122    int c,x;
00123    short *buf = malloc(2 * len + tdd->oldlen);
00124    short *obuf = buf;
00125    if (!buf) {
00126       ast_log(LOG_WARNING, "Out of memory\n");
00127       return -1;
00128    }
00129    memset(buf, 0, 2 * len + tdd->oldlen);
00130    memcpy(buf, tdd->oldstuff, tdd->oldlen);
00131    mylen += tdd->oldlen/2;
00132    for (x=0;x<len;x++) 
00133       buf[x+tdd->oldlen/2] = AST_MULAW(ubuf[x]);
00134    c = res = 0;
00135    while(mylen >= 1320) { /* has to have enough to work on */
00136       olen = mylen;
00137       res = fsk_serie(&tdd->fskd, buf, &mylen, &b);
00138       if (mylen < 0) {
00139          ast_log(LOG_ERROR, "fsk_serie made mylen < 0 (%d) (olen was %d)\n", mylen,olen);
00140          free(obuf);
00141          return -1;
00142       }
00143       buf += (olen - mylen);
00144       if (res < 0) {
00145          ast_log(LOG_NOTICE, "fsk_serie failed\n");
00146          free(obuf);
00147          return -1;
00148       }
00149       if (res == 1) {
00150          /* Ignore invalid bytes */
00151          if (b > 0x7f)
00152             continue;
00153          c = tdd_decode_baudot(tdd,b);
00154          if ((c < 1) || (c > 126)) continue; /* if not valid */
00155          break;
00156       }
00157    }
00158    if (mylen) {
00159       memcpy(tdd->oldstuff, buf, mylen * 2);
00160       tdd->oldlen = mylen * 2;
00161    } else
00162       tdd->oldlen = 0;
00163    free(obuf);
00164    if (res)  {
00165       tdd->mode = 2; /* put it in mode where it
00166          reliably puts teleprinter in correct shift mode */
00167       return(c);
00168    }
00169    return 0;
00170 }

void tdd_free ( struct tdd_state tdd  ) 

Free a TDD state machine.

Parameters:
tdd This is the tdd_state state machine to free This function frees tdd_state tdd.

Definition at line 172 of file tdd.c.

00173 {
00174    free(tdd);
00175 }

int tdd_generate ( struct tdd_state tdd,
unsigned char *  buf,
char *  string 
)

Generates a CallerID FSK stream in ulaw format suitable for transmission.

Parameters:
buf Buffer to use. This needs to be large enough to accomodate all the generated samples.
string This is the string to send. This function creates a stream of TDD data in ulaw format. It returns the size (in bytes) of the data (if it returns a size of 0, there is probably an error)

Definition at line 236 of file tdd.c.

00237 {
00238    int bytes=0;
00239    int i,x;
00240    char  c;
00241    static unsigned char lstr[31] = "\000E\nA SIU\rDRJNFCKTZLWHYPQOBG\000MXV";
00242    static unsigned char fstr[31] = "\0003\n- \00787\r$4',!:(5\")2\0006019?&\000./;";
00243    /* Initial carriers (real/imaginary) */
00244    float cr = 1.0;
00245    float ci = 0.0;
00246    float scont = 0.0;
00247 
00248    for(x = 0; str[x]; x++) {
00249       c = toupper(str[x]);
00250 #if   0
00251       printf("%c",c); fflush(stdout);
00252 #endif
00253       if (c == 0) /* send null */
00254          {
00255          PUT_TDD(0);
00256          continue;
00257          }
00258       if (c == '\r') /* send c/r */
00259          {
00260          PUT_TDD(8);
00261          continue;
00262          }
00263       if (c == '\n') /* send c/r and l/f */
00264          {
00265          PUT_TDD(8);
00266          PUT_TDD(2);
00267          continue;
00268          }
00269       if (c == ' ') /* send space */
00270          {
00271          PUT_TDD(4);
00272          continue;
00273          }
00274       for(i = 0; i < 31; i++)
00275          {
00276          if (lstr[i] == c) break;
00277          }
00278       if (i < 31) /* if we found it */
00279          {
00280          if (tdd->mode)  /* if in figs mode, change it */
00281             { 
00282             PUT_TDD(31); /* Send LTRS */
00283             tdd->mode = 0;
00284             }
00285          PUT_TDD(i);
00286          continue;
00287          }
00288       for(i = 0; i < 31; i++)
00289          {
00290          if (fstr[i] == c) break;
00291          }
00292       if (i < 31) /* if we found it */
00293          {
00294          if (tdd->mode != 1)  /* if in ltrs mode, change it */
00295             {
00296             PUT_TDD(27); /* send FIGS */
00297             tdd->mode = 1;
00298             }
00299          PUT_TDD(i);  /* send byte */
00300          continue;
00301          }
00302       }
00303    return bytes;
00304 }

void tdd_init ( void   ) 

CallerID Initialization.

Initializes the TDD system. Mostly stuff for inverse FFT

Definition at line 67 of file tdd.c.

00068 {
00069    /* Initialize stuff for inverse FFT */
00070    dr[0] = cos(TDD_SPACE * 2.0 * M_PI / 8000.0);
00071    di[0] = sin(TDD_SPACE * 2.0 * M_PI / 8000.0);
00072    dr[1] = cos(TDD_MARK * 2.0 * M_PI / 8000.0);
00073    di[1] = sin(TDD_MARK * 2.0 * M_PI / 8000.0);
00074 }

struct tdd_state* tdd_new ( void   )  [read]

Create a TDD state machine.

This function returns a malloc'd instance of the tdd_state data structure. Returns a pointer to a malloc'd tdd_state structure, or NULL on error.

Definition at line 76 of file tdd.c.

00077 {
00078    struct tdd_state *tdd;
00079    tdd = malloc(sizeof(struct tdd_state));
00080    if (tdd) {
00081       memset(tdd, 0, sizeof(struct tdd_state));
00082       tdd->fskd.spb = 176;    /* 45.5 baud */
00083       tdd->fskd.hdlc = 0;     /* Async */
00084       tdd->fskd.nbit = 5;     /* 5 bits */
00085       tdd->fskd.nstop = 1.5;  /* 1.5 stop bits */
00086       tdd->fskd.paridad = 0;  /* No parity */
00087       tdd->fskd.bw=0;         /* Filter 75 Hz */
00088       tdd->fskd.f_mark_idx =  0; /* 1400 Hz */
00089       tdd->fskd.f_space_idx = 1; /* 1800 Hz */
00090       tdd->fskd.pcola = 0;    /* No clue */
00091       tdd->fskd.cont = 0;        /* Digital PLL reset */
00092       tdd->fskd.x0 = 0.0;
00093       tdd->fskd.state = 0;
00094       tdd->pos = 0;
00095       tdd->mode = 2;
00096    } else
00097       ast_log(LOG_WARNING, "Out of memory\n");
00098    return tdd;
00099 }


Generated on Wed Oct 28 17:01:03 2009 for Asterisk by  doxygen 1.5.6