tdd.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
#include <time.h>
00018
#include <string.h>
00019
#include <stdio.h>
00020
#include <stdlib.h>
00021
#include <unistd.h>
00022
#include <math.h>
00023
#include <ctype.h>
00024
#include <asterisk/ulaw.h>
00025
#include <asterisk/tdd.h>
00026
#include <asterisk/logger.h>
00027
#include <asterisk/fskmodem.h>
00028
#include "ecdisa.h"
00029
00030
00031 struct tdd_state {
00032 fsk_data fskd;
00033 char rawdata[256];
00034 short oldstuff[4096];
00035 int oldlen;
00036 int pos;
00037 int modo;
00038 int mode;
00039 };
00040
00041
static float dr[4], di[4];
00042
static float tddsb = 176.0;
00043
00044 #define TDD_SPACE 1800.0
00045 #define TDD_MARK 1400.0
00046
00047
static int tdd_decode_baudot(
struct tdd_state *tdd,
unsigned char data)
00048 {
00049
static char ltrs[32]={
'<',
'E',
'\n',
'A',
' ',
'S',
'I',
'U',
00050
'\n',
'D',
'R',
'J',
'N',
'F',
'C',
'K',
00051
'T',
'Z',
'L',
'W',
'H',
'Y',
'P',
'Q',
00052
'O',
'B',
'G',
'^',
'M',
'X',
'V',
'^'};
00053
static char figs[32]={
'<',
'3',
'\n',
'-',
' ',
',',
'8',
'7',
00054
'\n',
'$',
'4',
'\'',
',',
'·',
':',
'(',
00055
'5',
'+',
')',
'2',
'·',
'6',
'0',
'1',
00056
'9',
'7',
'·',
'^',
'.',
'/',
'=',
'^'};
00057
int d;
00058 d=0;
00059
switch (data) {
00060
case 0x1f : tdd->
modo=0;
break;
00061
case 0x1b : tdd->
modo=1;
break;
00062
default:
if (tdd->
modo==0) d=ltrs[data];
else d=figs[data];
break;
00063 }
00064
return d;
00065 }
00066
00067 void tdd_init(
void)
00068 {
00069
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 }
00075
00076 struct tdd_state *
tdd_new(
void)
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;
00083 tdd->fskd.hdlc = 0;
00084 tdd->fskd.nbit = 5;
00085 tdd->fskd.nstop = 1.5;
00086 tdd->fskd.paridad = 0;
00087 tdd->fskd.bw=0;
00088 tdd->fskd.f_mark_idx = 0;
00089 tdd->fskd.f_space_idx = 1;
00090 tdd->fskd.pcola = 0;
00091 tdd->fskd.cont = 0;
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 }
00100
00101 int ast_tdd_gen_ecdisa(
unsigned char *outbuf,
int len)
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 }
00115
00116 int tdd_feed(
struct tdd_state *tdd,
unsigned char *ubuf,
int len)
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) {
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
00151
if (b > 0x7f)
00152
continue;
00153 c = tdd_decode_baudot(tdd,b);
00154
if ((c < 1) || (c > 126))
continue;
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;
00166
00167
return(c);
00168 }
00169
return 0;
00170 }
00171
00172 void tdd_free(
struct tdd_state *tdd)
00173 {
00174
free(tdd);
00175 }
00176
00177
static inline float tdd_getcarrier(
float *cr,
float *ci,
int bit)
00178 {
00179
00180
float t;
00181 t = *cr * dr[bit] - *ci * di[bit];
00182 *ci = *cr * di[bit] + *ci * dr[bit];
00183 *cr = t;
00184
00185 t = 2.0 - (*cr * *cr + *ci * *ci);
00186 *cr *= t;
00187 *ci *= t;
00188
return *cr;
00189 }
00190
00191 #define PUT_BYTE(a) do { \
00192
*(buf++) = (a); \
00193
bytes++; \
00194
} while(0)
00195
00196 #define PUT_AUDIO_SAMPLE(y) do { \
00197
int index = (short)(rint(8192.0 * (y))); \
00198
*(buf++) = AST_LIN2MU(index); \
00199
bytes++; \
00200
} while(0)
00201
00202 #define PUT_TDD_MARKMS do { \
00203
int x; \
00204
for (x=0;x<8;x++) \
00205
PUT_AUDIO_SAMPLE(tdd_getcarrier(&cr, &ci, 1)); \
00206
} while(0)
00207
00208 #define PUT_TDD_BAUD(bit) do { \
00209
while(scont < tddsb) { \
00210
PUT_AUDIO_SAMPLE(tdd_getcarrier(&cr, &ci, bit)); \
00211
scont += 1.0; \
00212
} \
00213
scont -= tddsb; \
00214
} while(0)
00215
00216 #define PUT_TDD_STOP do { \
00217
while(scont < (tddsb * 1.5)) { \
00218
PUT_AUDIO_SAMPLE(tdd_getcarrier(&cr, &ci, 1)); \
00219
scont += 1.0; \
00220
} \
00221
scont -= (tddsb * 1.5); \
00222
} while(0)
00223
00224
00225 #define PUT_TDD(byte) do { \
00226
int z; \
00227
unsigned char b = (byte); \
00228
PUT_TDD_BAUD(0); \
00229 for (z=0;z<5;z++) { \
00230 PUT_TDD_BAUD(b & 1); \
00231 b >>= 1; \
00232 } \
00233 PUT_TDD_STOP; \
00234 } while(0);
00235
00236 int tdd_generate(
struct tdd_state *tdd,
unsigned char *buf,
char *str)
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
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)
00254 {
00255
PUT_TDD(0);
00256
continue;
00257 }
00258
if (c ==
'\r')
00259 {
00260
PUT_TDD(8);
00261
continue;
00262 }
00263
if (c ==
'\n')
00264 {
00265
PUT_TDD(8);
00266
PUT_TDD(2);
00267
continue;
00268 }
00269
if (c ==
' ')
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)
00279 {
00280
if (tdd->
mode)
00281 {
00282
PUT_TDD(31);
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)
00293 {
00294
if (tdd->
mode != 1)
00295 {
00296
PUT_TDD(27);
00297 tdd->
mode = 1;
00298 }
00299
PUT_TDD(i);
00300
continue;
00301 }
00302 }
00303
return bytes;
00304 }
00305
00306
Generated on Sat Jun 12 16:40:59 2004 for Asterisk by
1.3.7