00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <unistd.h>
00031 #include <netinet/in.h>
00032 #include <arpa/inet.h>
00033 #include <stdlib.h>
00034 #include <sys/time.h>
00035 #include <stdio.h>
00036 #include <errno.h>
00037 #include <string.h>
00038
00039 #include "asterisk.h"
00040
00041 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 7221 $")
00042
00043 #include "asterisk/lock.h"
00044 #include "asterisk/channel.h"
00045 #include "asterisk/file.h"
00046 #include "asterisk/logger.h"
00047 #include "asterisk/sched.h"
00048 #include "asterisk/module.h"
00049 #include "asterisk/endian.h"
00050
00051 #include "msgsm.h"
00052
00053
00054
00055
00056
00057
00058 char msgsm_silence[] =
00059 {0x48,0x17,0xD6,0x84,0x02,0x80,0x24,0x49,0x92,0x24,0x89,0x02,0x80,0x24,0x49
00060 ,0x92,0x24,0x89,0x02,0x80,0x24,0x49,0x92,0x24,0x89,0x02,0x80,0x24,0x49,0x92
00061 ,0x24,0x09,0x82,0x74,0x61,0x4D,0x28,0x00,0x48,0x92,0x24,0x49,0x92,0x28,0x00
00062 ,0x48,0x92,0x24,0x49,0x92,0x28,0x00,0x48,0x92,0x24,0x49,0x92,0x28,0x00,0x48
00063 ,0x92,0x24,0x49,0x92,0x00};
00064
00065
00066 struct ast_filestream {
00067 void *reserved[AST_RESERVED_POINTERS];
00068
00069
00070
00071 FILE *f;
00072 struct ast_frame fr;
00073 char waste[AST_FRIENDLY_OFFSET];
00074 char empty;
00075 unsigned char gsm[66];
00076 int foffset;
00077 int secondhalf;
00078 struct timeval last;
00079 };
00080
00081
00082 AST_MUTEX_DEFINE_STATIC(wav_lock);
00083 static int glistcnt = 0;
00084
00085 static char *name = "wav49";
00086 static char *desc = "Microsoft WAV format (Proprietary GSM)";
00087 static char *exts = "WAV|wav49";
00088
00089 #if __BYTE_ORDER == __LITTLE_ENDIAN
00090 #define htoll(b) (b)
00091 #define htols(b) (b)
00092 #define ltohl(b) (b)
00093 #define ltohs(b) (b)
00094 #else
00095 #if __BYTE_ORDER == __BIG_ENDIAN
00096 #define htoll(b) \
00097 (((((b) ) & 0xFF) << 24) | \
00098 ((((b) >> 8) & 0xFF) << 16) | \
00099 ((((b) >> 16) & 0xFF) << 8) | \
00100 ((((b) >> 24) & 0xFF) ))
00101 #define htols(b) \
00102 (((((b) ) & 0xFF) << 8) | \
00103 ((((b) >> 8) & 0xFF) ))
00104 #define ltohl(b) htoll(b)
00105 #define ltohs(b) htols(b)
00106 #else
00107 #error "Endianess not defined"
00108 #endif
00109 #endif
00110
00111
00112 static int check_header(FILE *f)
00113 {
00114 int type, size, formtype;
00115 int fmt, hsize, fact;
00116 short format, chans;
00117 int freq;
00118 int data;
00119 if (fread(&type, 1, 4, f) != 4) {
00120 ast_log(LOG_WARNING, "Read failed (type)\n");
00121 return -1;
00122 }
00123 if (fread(&size, 1, 4, f) != 4) {
00124 ast_log(LOG_WARNING, "Read failed (size)\n");
00125 return -1;
00126 }
00127 size = ltohl(size);
00128 if (fread(&formtype, 1, 4, f) != 4) {
00129 ast_log(LOG_WARNING, "Read failed (formtype)\n");
00130 return -1;
00131 }
00132 if (memcmp(&type, "RIFF", 4)) {
00133 ast_log(LOG_WARNING, "Does not begin with RIFF\n");
00134 return -1;
00135 }
00136 if (memcmp(&formtype, "WAVE", 4)) {
00137 ast_log(LOG_WARNING, "Does not contain WAVE\n");
00138 return -1;
00139 }
00140 if (fread(&fmt, 1, 4, f) != 4) {
00141 ast_log(LOG_WARNING, "Read failed (fmt)\n");
00142 return -1;
00143 }
00144 if (memcmp(&fmt, "fmt ", 4)) {
00145 ast_log(LOG_WARNING, "Does not say fmt\n");
00146 return -1;
00147 }
00148 if (fread(&hsize, 1, 4, f) != 4) {
00149 ast_log(LOG_WARNING, "Read failed (formtype)\n");
00150 return -1;
00151 }
00152 if (ltohl(hsize) != 20) {
00153 ast_log(LOG_WARNING, "Unexpected header size %d\n", ltohl(hsize));
00154 return -1;
00155 }
00156 if (fread(&format, 1, 2, f) != 2) {
00157 ast_log(LOG_WARNING, "Read failed (format)\n");
00158 return -1;
00159 }
00160 if (ltohs(format) != 49) {
00161 ast_log(LOG_WARNING, "Not a GSM file %d\n", ltohs(format));
00162 return -1;
00163 }
00164 if (fread(&chans, 1, 2, f) != 2) {
00165 ast_log(LOG_WARNING, "Read failed (format)\n");
00166 return -1;
00167 }
00168 if (ltohs(chans) != 1) {
00169 ast_log(LOG_WARNING, "Not in mono %d\n", ltohs(chans));
00170 return -1;
00171 }
00172 if (fread(&freq, 1, 4, f) != 4) {
00173 ast_log(LOG_WARNING, "Read failed (freq)\n");
00174 return -1;
00175 }
00176 if (ltohl(freq) != 8000) {
00177 ast_log(LOG_WARNING, "Unexpected freqency %d\n", ltohl(freq));
00178 return -1;
00179 }
00180
00181 if (fread(&freq, 1, 4, f) != 4) {
00182 ast_log(LOG_WARNING, "Read failed (X_1)\n");
00183 return -1;
00184 }
00185
00186 if (fread(&freq, 1, 4, f) != 4) {
00187 ast_log(LOG_WARNING, "Read failed (X_2/X_3)\n");
00188 return -1;
00189 }
00190
00191 if (fread(&freq, 1, 4, f) != 4) {
00192 ast_log(LOG_WARNING, "Read failed (Y_1)\n");
00193 return -1;
00194 }
00195
00196 if (fread(&fact, 1, 4, f) != 4) {
00197 ast_log(LOG_WARNING, "Read failed (fact)\n");
00198 return -1;
00199 }
00200 if (memcmp(&fact, "fact", 4)) {
00201 ast_log(LOG_WARNING, "Does not say fact\n");
00202 return -1;
00203 }
00204
00205 if (fread(&fact, 1, 4, f) != 4) {
00206 ast_log(LOG_WARNING, "Read failed (fact header)\n");
00207 return -1;
00208 }
00209 if (fread(&fact, 1, 4, f) != 4) {
00210 ast_log(LOG_WARNING, "Read failed (fact value)\n");
00211 return -1;
00212 }
00213
00214 if (fread(&data, 1, 4, f) != 4) {
00215 ast_log(LOG_WARNING, "Read failed (data)\n");
00216 return -1;
00217 }
00218 if (memcmp(&data, "data", 4)) {
00219 ast_log(LOG_WARNING, "Does not say data\n");
00220 return -1;
00221 }
00222
00223 if (fread(&data, 1, 4, f) != 4) {
00224 ast_log(LOG_WARNING, "Read failed (data)\n");
00225 return -1;
00226 }
00227 return 0;
00228 }
00229
00230 static int update_header(FILE *f)
00231 {
00232 off_t cur,end,bytes;
00233 int datalen,filelen;
00234
00235 cur = ftell(f);
00236 fseek(f, 0, SEEK_END);
00237 end = ftell(f);
00238
00239 bytes = end - 60;
00240 datalen = htoll((bytes + 1) & ~0x1);
00241 filelen = htoll(52 + ((bytes + 1) & ~0x1));
00242 if (cur < 0) {
00243 ast_log(LOG_WARNING, "Unable to find our position\n");
00244 return -1;
00245 }
00246 if (fseek(f, 4, SEEK_SET)) {
00247 ast_log(LOG_WARNING, "Unable to set our position\n");
00248 return -1;
00249 }
00250 if (fwrite(&filelen, 1, 4, f) != 4) {
00251 ast_log(LOG_WARNING, "Unable to set write file size\n");
00252 return -1;
00253 }
00254 if (fseek(f, 56, SEEK_SET)) {
00255 ast_log(LOG_WARNING, "Unable to set our position\n");
00256 return -1;
00257 }
00258 if (fwrite(&datalen, 1, 4, f) != 4) {
00259 ast_log(LOG_WARNING, "Unable to set write datalen\n");
00260 return -1;
00261 }
00262 if (fseek(f, cur, SEEK_SET)) {
00263 ast_log(LOG_WARNING, "Unable to return to position\n");
00264 return -1;
00265 }
00266 return 0;
00267 }
00268
00269 static int write_header(FILE *f)
00270 {
00271 unsigned int hz=htoll(8000);
00272 unsigned int bhz = htoll(1625);
00273 unsigned int hs = htoll(20);
00274 unsigned short fmt = htols(49);
00275 unsigned short chans = htols(1);
00276 unsigned int fhs = htoll(4);
00277 unsigned int x_1 = htoll(65);
00278 unsigned short x_2 = htols(2);
00279 unsigned short x_3 = htols(320);
00280 unsigned int y_1 = htoll(20160);
00281 unsigned int size = htoll(0);
00282
00283 if (fwrite("RIFF", 1, 4, f) != 4) {
00284 ast_log(LOG_WARNING, "Unable to write header\n");
00285 return -1;
00286 }
00287 if (fwrite(&size, 1, 4, f) != 4) {
00288 ast_log(LOG_WARNING, "Unable to write header\n");
00289 return -1;
00290 }
00291 if (fwrite("WAVEfmt ", 1, 8, f) != 8) {
00292 ast_log(LOG_WARNING, "Unable to write header\n");
00293 return -1;
00294 }
00295 if (fwrite(&hs, 1, 4, f) != 4) {
00296 ast_log(LOG_WARNING, "Unable to write header\n");
00297 return -1;
00298 }
00299 if (fwrite(&fmt, 1, 2, f) != 2) {
00300 ast_log(LOG_WARNING, "Unable to write header\n");
00301 return -1;
00302 }
00303 if (fwrite(&chans, 1, 2, f) != 2) {
00304 ast_log(LOG_WARNING, "Unable to write header\n");
00305 return -1;
00306 }
00307 if (fwrite(&hz, 1, 4, f) != 4) {
00308 ast_log(LOG_WARNING, "Unable to write header\n");
00309 return -1;
00310 }
00311 if (fwrite(&bhz, 1, 4, f) != 4) {
00312 ast_log(LOG_WARNING, "Unable to write header\n");
00313 return -1;
00314 }
00315 if (fwrite(&x_1, 1, 4, f) != 4) {
00316 ast_log(LOG_WARNING, "Unable to write header\n");
00317 return -1;
00318 }
00319 if (fwrite(&x_2, 1, 2, f) != 2) {
00320 ast_log(LOG_WARNING, "Unable to write header\n");
00321 return -1;
00322 }
00323 if (fwrite(&x_3, 1, 2, f) != 2) {
00324 ast_log(LOG_WARNING, "Unable to write header\n");
00325 return -1;
00326 }
00327 if (fwrite("fact", 1, 4, f) != 4) {
00328 ast_log(LOG_WARNING, "Unable to write header\n");
00329 return -1;
00330 }
00331 if (fwrite(&fhs, 1, 4, f) != 4) {
00332 ast_log(LOG_WARNING, "Unable to write header\n");
00333 return -1;
00334 }
00335 if (fwrite(&y_1, 1, 4, f) != 4) {
00336 ast_log(LOG_WARNING, "Unable to write header\n");
00337 return -1;
00338 }
00339 if (fwrite("data", 1, 4, f) != 4) {
00340 ast_log(LOG_WARNING, "Unable to write header\n");
00341 return -1;
00342 }
00343 if (fwrite(&size, 1, 4, f) != 4) {
00344 ast_log(LOG_WARNING, "Unable to write header\n");
00345 return -1;
00346 }
00347 return 0;
00348 }
00349
00350 static struct ast_filestream *wav_open(FILE *f)
00351 {
00352
00353
00354
00355 struct ast_filestream *tmp;
00356 if ((tmp = malloc(sizeof(struct ast_filestream)))) {
00357 memset(tmp, 0, sizeof(struct ast_filestream));
00358 if (check_header(f)) {
00359 free(tmp);
00360 return NULL;
00361 }
00362 if (ast_mutex_lock(&wav_lock)) {
00363 ast_log(LOG_WARNING, "Unable to lock wav list\n");
00364 free(tmp);
00365 return NULL;
00366 }
00367 tmp->f = f;
00368 tmp->fr.data = tmp->gsm;
00369 tmp->fr.frametype = AST_FRAME_VOICE;
00370 tmp->fr.subclass = AST_FORMAT_GSM;
00371
00372 tmp->fr.src = name;
00373 tmp->fr.mallocd = 0;
00374 tmp->secondhalf = 0;
00375 glistcnt++;
00376 ast_mutex_unlock(&wav_lock);
00377 ast_update_use_count();
00378 }
00379 return tmp;
00380 }
00381
00382 static struct ast_filestream *wav_rewrite(FILE *f, const char *comment)
00383 {
00384
00385
00386
00387 struct ast_filestream *tmp;
00388 if ((tmp = malloc(sizeof(struct ast_filestream)))) {
00389 memset(tmp, 0, sizeof(struct ast_filestream));
00390 if (write_header(f)) {
00391 free(tmp);
00392 return NULL;
00393 }
00394 if (ast_mutex_lock(&wav_lock)) {
00395 ast_log(LOG_WARNING, "Unable to lock wav list\n");
00396 free(tmp);
00397 return NULL;
00398 }
00399 tmp->f = f;
00400 glistcnt++;
00401 ast_mutex_unlock(&wav_lock);
00402 ast_update_use_count();
00403 } else
00404 ast_log(LOG_WARNING, "Out of memory\n");
00405 return tmp;
00406 }
00407
00408 static void wav_close(struct ast_filestream *s)
00409 {
00410 char zero = 0;
00411 if (ast_mutex_lock(&wav_lock)) {
00412 ast_log(LOG_WARNING, "Unable to lock wav list\n");
00413 return;
00414 }
00415 glistcnt--;
00416 ast_mutex_unlock(&wav_lock);
00417 ast_update_use_count();
00418
00419 fseek(s->f, 0, SEEK_END);
00420 if (ftell(s->f) & 0x1)
00421 fwrite(&zero, 1, 1, s->f);
00422 fclose(s->f);
00423 free(s);
00424 s = NULL;
00425 }
00426
00427 static struct ast_frame *wav_read(struct ast_filestream *s, int *whennext)
00428 {
00429 int res;
00430 char msdata[66];
00431
00432
00433 s->fr.frametype = AST_FRAME_VOICE;
00434 s->fr.subclass = AST_FORMAT_GSM;
00435 s->fr.offset = AST_FRIENDLY_OFFSET;
00436 s->fr.samples = 160;
00437 s->fr.datalen = 33;
00438 s->fr.mallocd = 0;
00439 if (s->secondhalf) {
00440
00441 s->fr.data = s->gsm + 33;
00442 } else {
00443 if ((res = fread(msdata, 1, 65, s->f)) != 65) {
00444 if (res && (res != 1))
00445 ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
00446 return NULL;
00447 }
00448
00449 conv65(msdata, s->gsm);
00450 s->fr.data = s->gsm;
00451 }
00452 s->secondhalf = !s->secondhalf;
00453 *whennext = 160;
00454 return &s->fr;
00455 }
00456
00457 static int wav_write(struct ast_filestream *fs, struct ast_frame *f)
00458 {
00459 int res;
00460 char msdata[66];
00461 int len =0;
00462 int alreadyms=0;
00463 if (f->frametype != AST_FRAME_VOICE) {
00464 ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
00465 return -1;
00466 }
00467 if (f->subclass != AST_FORMAT_GSM) {
00468 ast_log(LOG_WARNING, "Asked to write non-GSM frame (%d)!\n", f->subclass);
00469 return -1;
00470 }
00471 if (!(f->datalen % 65))
00472 alreadyms = 1;
00473 while(len < f->datalen) {
00474 if (alreadyms) {
00475 fs->secondhalf = 0;
00476 if ((res = fwrite(f->data + len, 1, 65, fs->f)) != 65) {
00477 ast_log(LOG_WARNING, "Bad write (%d/65): %s\n", res, strerror(errno));
00478 return -1;
00479 }
00480 update_header(fs->f);
00481 len += 65;
00482 } else {
00483 if (fs->secondhalf) {
00484 memcpy(fs->gsm + 33, f->data + len, 33);
00485 conv66(fs->gsm, msdata);
00486 if ((res = fwrite(msdata, 1, 65, fs->f)) != 65) {
00487 ast_log(LOG_WARNING, "Bad write (%d/65): %s\n", res, strerror(errno));
00488 return -1;
00489 }
00490 update_header(fs->f);
00491 } else {
00492
00493 memcpy(fs->gsm, f->data + len, 33);
00494 }
00495 fs->secondhalf = !fs->secondhalf;
00496 len += 33;
00497 }
00498 }
00499 return 0;
00500 }
00501
00502 static int wav_seek(struct ast_filestream *fs, long sample_offset, int whence)
00503 {
00504 off_t offset=0,distance,cur,min,max;
00505 min = 60;
00506 cur = ftell(fs->f);
00507 fseek(fs->f, 0, SEEK_END);
00508 max = ftell(fs->f);
00509
00510
00511 distance = (sample_offset/320) * 65;
00512 if(whence == SEEK_SET)
00513 offset = distance + min;
00514 else if(whence == SEEK_CUR || whence == SEEK_FORCECUR)
00515 offset = distance + cur;
00516 else if(whence == SEEK_END)
00517 offset = max - distance;
00518
00519 offset = (offset < min)?min:offset;
00520 if (whence != SEEK_FORCECUR) {
00521 offset = (offset > max)?max:offset;
00522 } else if (offset > max) {
00523 int i;
00524 fseek(fs->f, 0, SEEK_END);
00525 for (i=0; i< (offset - max) / 65; i++) {
00526 fwrite(msgsm_silence, 1, 65, fs->f);
00527 }
00528 }
00529 fs->secondhalf = 0;
00530 return fseek(fs->f, offset, SEEK_SET);
00531 }
00532
00533 static int wav_trunc(struct ast_filestream *fs)
00534 {
00535 if (ftruncate(fileno(fs->f), ftell(fs->f)))
00536 return -1;
00537 return update_header(fs->f);
00538 }
00539
00540 static long wav_tell(struct ast_filestream *fs)
00541 {
00542 off_t offset;
00543 offset = ftell(fs->f);
00544
00545
00546 return (offset - 52)/65*320;
00547 }
00548
00549 static char *wav_getcomment(struct ast_filestream *s)
00550 {
00551 return NULL;
00552 }
00553
00554 int load_module()
00555 {
00556 return ast_format_register(name, exts, AST_FORMAT_GSM,
00557 wav_open,
00558 wav_rewrite,
00559 wav_write,
00560 wav_seek,
00561 wav_trunc,
00562 wav_tell,
00563 wav_read,
00564 wav_close,
00565 wav_getcomment);
00566
00567
00568 }
00569
00570 int unload_module()
00571 {
00572 return ast_format_unregister(name);
00573 }
00574
00575 int usecount()
00576 {
00577 return glistcnt;
00578 }
00579
00580 char *description()
00581 {
00582 return desc;
00583 }
00584
00585
00586 char *key()
00587 {
00588 return ASTERISK_GPL_KEY;
00589 }