Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

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:

Include dependency graph

Go to the source code of this file.

Data Structures

struct  tdd_state

Defines

#define TDD_SPACE   1800.0 /* 1800 hz for "0" */
#define TDD_MARK   1400.0 /* 1400 hz for "1" */
#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.

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.

Referenced by callerid_generate(), and vmwi_generate().

#define PUT_TDD byte   ) 
 

Definition at line 225 of file tdd.c.

Referenced by tdd_generate().

#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 /* 1400 hz for "1" */
 

Definition at line 45 of file tdd.c.

Referenced by tdd_init().

#define TDD_SPACE   1800.0 /* 1800 hz for "0" */
 

Definition at line 44 of file tdd.c.

Referenced by tdd_init().


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.

References ast_log(), AST_MULAW, free, fsk_serie(), tdd_state::fskd, LOG_ERROR, LOG_NOTICE, LOG_WARNING, malloc, tdd_state::mode, tdd_state::oldlen, and tdd_state::oldstuff.

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.

References free.

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.

References tdd_state::mode, and PUT_TDD.

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.

References TDD_MARK, and TDD_SPACE.

Referenced by main().

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   ) 
 

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.

References ast_log(), LOG_WARNING, and malloc.

00077 { 00078 struct tdd_state *tdd; 00079 tdd = malloc(sizeof(struct tdd_state)); 00080 memset(tdd, 0, sizeof(struct tdd_state)); 00081 if (tdd) { 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 Sat Jun 12 16:41:48 2004 for Asterisk by doxygen 1.3.7