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
00031
00032
00033 #include "asterisk.h"
00034
00035 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 267539 $")
00036
00037 #include <fcntl.h>
00038 #include <stdlib.h>
00039 #include <unistd.h>
00040 #include <netinet/in.h>
00041 #include <string.h>
00042 #include <stdio.h>
00043
00044 #include "asterisk/lock.h"
00045 #include "asterisk/translate.h"
00046 #include "asterisk/config.h"
00047 #include "asterisk/options.h"
00048 #include "asterisk/module.h"
00049 #include "asterisk/logger.h"
00050 #include "asterisk/channel.h"
00051 #include "asterisk/utils.h"
00052
00053 #ifdef HAVE_GSM_HEADER
00054 #include "gsm.h"
00055 #elif defined(HAVE_GSM_GSM_HEADER)
00056 #include <gsm/gsm.h>
00057 #endif
00058
00059 #include "../formats/msgsm.h"
00060
00061
00062 #include "slin_gsm_ex.h"
00063 #include "gsm_slin_ex.h"
00064
00065 #define BUFFER_SAMPLES 8000
00066 #define GSM_SAMPLES 160
00067 #define GSM_FRAME_LEN 33
00068 #define MSGSM_FRAME_LEN 65
00069
00070 struct gsm_translator_pvt {
00071 gsm gsm;
00072 int16_t buf[BUFFER_SAMPLES];
00073 };
00074
00075 static int gsm_new(struct ast_trans_pvt *pvt)
00076 {
00077 struct gsm_translator_pvt *tmp = pvt->pvt;
00078
00079 return (tmp->gsm = gsm_create()) ? 0 : -1;
00080 }
00081
00082 static struct ast_frame *lintogsm_sample(void)
00083 {
00084 static struct ast_frame f;
00085 f.frametype = AST_FRAME_VOICE;
00086 f.subclass = AST_FORMAT_SLINEAR;
00087 f.datalen = sizeof(slin_gsm_ex);
00088
00089 f.samples = sizeof(slin_gsm_ex)/2;
00090 f.mallocd = 0;
00091 f.offset = 0;
00092 f.src = __PRETTY_FUNCTION__;
00093 f.data = slin_gsm_ex;
00094 return &f;
00095 }
00096
00097 static struct ast_frame *gsmtolin_sample(void)
00098 {
00099 static struct ast_frame f;
00100 f.frametype = AST_FRAME_VOICE;
00101 f.subclass = AST_FORMAT_GSM;
00102 f.datalen = sizeof(gsm_slin_ex);
00103
00104 f.samples = GSM_SAMPLES;
00105 f.mallocd = 0;
00106 f.offset = 0;
00107 f.src = __PRETTY_FUNCTION__;
00108 f.data = gsm_slin_ex;
00109 return &f;
00110 }
00111
00112
00113 static int gsmtolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00114 {
00115 struct gsm_translator_pvt *tmp = pvt->pvt;
00116 int x;
00117 int16_t *dst = (int16_t *)pvt->outbuf;
00118
00119 int flen = (f->datalen % MSGSM_FRAME_LEN == 0) ?
00120 MSGSM_FRAME_LEN : GSM_FRAME_LEN;
00121
00122 for (x=0; x < f->datalen; x += flen) {
00123 unsigned char data[2 * GSM_FRAME_LEN];
00124 unsigned char *src;
00125 int len;
00126 if (flen == MSGSM_FRAME_LEN) {
00127 len = 2*GSM_SAMPLES;
00128 src = data;
00129
00130
00131
00132
00133 conv65(f->data + x, data);
00134 } else {
00135 len = GSM_SAMPLES;
00136 src = f->data + x;
00137 }
00138
00139 if (pvt->samples + len > BUFFER_SAMPLES) {
00140 ast_log(LOG_WARNING, "Out of buffer space\n");
00141 return -1;
00142 }
00143 if (gsm_decode(tmp->gsm, src, dst + pvt->samples)) {
00144 ast_log(LOG_WARNING, "Invalid GSM data (1)\n");
00145 return -1;
00146 }
00147 pvt->samples += GSM_SAMPLES;
00148 pvt->datalen += 2 * GSM_SAMPLES;
00149 if (flen == MSGSM_FRAME_LEN) {
00150 if (gsm_decode(tmp->gsm, data + GSM_FRAME_LEN, dst + pvt->samples)) {
00151 ast_log(LOG_WARNING, "Invalid GSM data (2)\n");
00152 return -1;
00153 }
00154 pvt->samples += GSM_SAMPLES;
00155 pvt->datalen += 2 * GSM_SAMPLES;
00156 }
00157 }
00158 return 0;
00159 }
00160
00161
00162 static int lintogsm_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00163 {
00164 struct gsm_translator_pvt *tmp = pvt->pvt;
00165
00166
00167
00168
00169 if (pvt->samples + f->samples > BUFFER_SAMPLES) {
00170 ast_log(LOG_WARNING, "Out of buffer space\n");
00171 return -1;
00172 }
00173 memcpy(tmp->buf + pvt->samples, f->data, f->datalen);
00174 pvt->samples += f->samples;
00175 return 0;
00176 }
00177
00178
00179 static struct ast_frame *lintogsm_frameout(struct ast_trans_pvt *pvt)
00180 {
00181 struct gsm_translator_pvt *tmp = pvt->pvt;
00182 int datalen = 0;
00183 int samples = 0;
00184
00185
00186 if (pvt->samples < GSM_SAMPLES)
00187 return NULL;
00188 while (pvt->samples >= GSM_SAMPLES) {
00189
00190 gsm_encode(tmp->gsm, tmp->buf + samples, (gsm_byte *) pvt->outbuf + datalen);
00191 datalen += GSM_FRAME_LEN;
00192 samples += GSM_SAMPLES;
00193 pvt->samples -= GSM_SAMPLES;
00194 }
00195
00196
00197 if (pvt->samples)
00198 memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
00199
00200 return ast_trans_frameout(pvt, datalen, samples);
00201 }
00202
00203 static void gsm_destroy_stuff(struct ast_trans_pvt *pvt)
00204 {
00205 struct gsm_translator_pvt *tmp = pvt->pvt;
00206 if (tmp->gsm)
00207 gsm_destroy(tmp->gsm);
00208 }
00209
00210 static struct ast_translator gsmtolin = {
00211 .name = "gsmtolin",
00212 .srcfmt = AST_FORMAT_GSM,
00213 .dstfmt = AST_FORMAT_SLINEAR,
00214 .newpvt = gsm_new,
00215 .framein = gsmtolin_framein,
00216 .destroy = gsm_destroy_stuff,
00217 .sample = gsmtolin_sample,
00218 .buffer_samples = BUFFER_SAMPLES,
00219 .buf_size = BUFFER_SAMPLES * 2,
00220 .desc_size = sizeof (struct gsm_translator_pvt ),
00221 };
00222
00223 static struct ast_translator lintogsm = {
00224 .name = "lintogsm",
00225 .srcfmt = AST_FORMAT_SLINEAR,
00226 .dstfmt = AST_FORMAT_GSM,
00227 .newpvt = gsm_new,
00228 .framein = lintogsm_framein,
00229 .frameout = lintogsm_frameout,
00230 .destroy = gsm_destroy_stuff,
00231 .sample = lintogsm_sample,
00232 .desc_size = sizeof (struct gsm_translator_pvt ),
00233 .buf_size = (BUFFER_SAMPLES * GSM_FRAME_LEN + GSM_SAMPLES - 1)/GSM_SAMPLES,
00234 };
00235
00236
00237 static int reload(void)
00238 {
00239 return 0;
00240 }
00241
00242 static int unload_module(void)
00243 {
00244 int res;
00245
00246 res = ast_unregister_translator(&lintogsm);
00247 if (!res)
00248 res = ast_unregister_translator(&gsmtolin);
00249
00250 return res;
00251 }
00252
00253 static int load_module(void)
00254 {
00255 int res;
00256
00257 res = ast_register_translator(&gsmtolin);
00258 if (!res)
00259 res=ast_register_translator(&lintogsm);
00260 else
00261 ast_unregister_translator(&gsmtolin);
00262
00263 return res;
00264 }
00265
00266 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "GSM Coder/Decoder",
00267 .load = load_module,
00268 .unload = unload_module,
00269 .reload = reload,
00270 );