102102 <para>Name of modem protocol to use. Default is Bell 103.</para>
103103 <enumlist>
104104 <enum name="103">
105- <para>Bell 103 modem (300 baud), terminating </para>
105+ <para>Bell 103 modem (300 baud), originating </para>
106106 </enum>
107107 <enum name="202">
108108 <para>Bell 202 modem (1200 baud)</para>
@@ -144,6 +144,7 @@ struct receive_buffer {
144144 int ptr ;
145145 unsigned int quitoncarrierlost :1 ;
146146 unsigned int fsk_eof :1 ;
147+ unsigned int got_data :1 ;
147148 char * buffer ;
148149};
149150
@@ -168,26 +169,29 @@ static void rx_status(void *user_data, int status)
168169
169170static void get_bit (void * user_data , int bit )
170171{
172+ char c ;
171173 struct receive_buffer * data = user_data ;
172174 if (bit < 0 ) {
173175 rx_status (user_data , bit );
174176 return ;
175177 }
176- ast_debug (2 , "Got '%c' on the stream\n" , (char ) bit & 0xff );
177- * (data -> buffer + data -> ptr ++ ) = (char ) bit & 0xff ;
178+ c = (char ) bit & 0xff ;
179+ data -> got_data = 1 ;
180+ ast_debug (2 , "Got %d '%c' on the stream\n" , c , isprint (c ) ? c : ' ' );
181+ * (data -> buffer + data -> ptr ++ ) = c ;
178182}
179183
180184static int put_bit (struct transmit_buffer * user_data )
181185{
182186 int8_t data ;
183187
184188 if (user_data -> ptr <= user_data -> bytes2send ) {
185- if (( user_data -> current_bit_no != 0 ) && ( user_data -> current_bit_no != 9 ) ) {
186- data = * (( int8_t * ) user_data -> buffer + user_data -> ptr ) & ( 1 << ( user_data -> current_bit_no - 1 ));
187- } else if (user_data -> current_bit_no != 9 ) {
188- data = 0 ;
189+ if (user_data -> current_bit_no == 0 ) {
190+ data = 0 ; /* start bit */
191+ } else if (user_data -> current_bit_no <= 8 ) {
192+ data = * (( int8_t * ) user_data -> buffer + user_data -> ptr ) & ( 1 << ( user_data -> current_bit_no - 1 )) ;
189193 } else {
190- data = 1 ;
194+ data = 1 ; /* stop bit */
191195 }
192196 ++ user_data -> current_bit_no ;
193197 if (user_data -> current_bit_no == 10 ) {
@@ -214,9 +218,6 @@ static int fsk_tx_exec(struct ast_channel *chan, const char *data)
214218 .samples = BLOCK_LEN ,
215219 .data .ptr = & caller_amp ,
216220 };
217- struct ast_format * native_format ;
218- unsigned int sampling_rate ;
219- struct ast_format * write_format ;
220221 int samples ;
221222 int modem ;
222223 int res = 0 ;
@@ -226,10 +227,7 @@ static int fsk_tx_exec(struct ast_channel *chan, const char *data)
226227 AST_APP_ARG (data );
227228 );
228229
229- native_format = ast_format_cap_get_format (ast_channel_nativeformats (chan ), 0 );
230- sampling_rate = ast_format_get_sample_rate (native_format );
231- write_format = ast_format_cache_get_slin_by_rate (sampling_rate );
232- f .subclass .format = write_format ;
230+ f .subclass .format = ast_format_slin ;
233231
234232 if (ast_strlen_zero (data )) {
235233 ast_log (LOG_WARNING , "SendFSK requires an argument\n" );
@@ -257,25 +255,49 @@ static int fsk_tx_exec(struct ast_channel *chan, const char *data)
257255
258256 ast_debug (1 , "Modem channel is '%s'\n" , preset_fsk_specs [modem ].name );
259257
260- out = ast_malloc (sizeof (* out ));
258+ if ((res = ast_set_write_format (chan , ast_format_slin )) < 0 ) {
259+ ast_log (LOG_ERROR , "Unable to set channel to linear mode\n" );
260+ return -1 ;
261+ }
262+
263+ out = ast_calloc (1 , sizeof (* out ));
261264 if (!out ) {
262265 return -1 ;
263266 }
264267 out -> buffer = arglist .data ;
265268 out -> bytes2send = strlen (arglist .data );
266- out -> current_bit_no = 0 ;
267- out -> ptr = 0 ;
268269
269270 memset (caller_amp , 0 , sizeof (* caller_amp ));
270271
271272 caller_tx = fsk_tx_init (NULL , & preset_fsk_specs [modem ], (get_bit_func_t ) & put_bit , out );
273+ if (!caller_tx ) {
274+ ast_free (out );
275+ return -1 ;
276+ }
277+
278+ /* Send a few frames of mark tone first, to allow receiver to synchronize */
279+ for (samples = 0 ; samples < 7 ; samples ++ ) {
280+ res = ast_waitfor (chan , -1 );
281+ fr = ast_read (chan );
282+ if (!fr ) {
283+ ast_debug (2 , "User hung up\n" );
284+ goto abort ;
285+ }
286+ ast_frfree (fr );
287+ fsk_tx (caller_tx , caller_amp , BLOCK_LEN );
288+ if (ast_write (chan , & f ) < 0 ) {
289+ ast_debug (1 , "Failed to write mark tone\n" );
290+ goto abort ;
291+ }
292+ }
293+
294+ /* Send the payload */
272295 while (out -> ptr < out -> bytes2send ) {
273296 res = ast_waitfor (chan , 1000 );
274297 fr = ast_read (chan );
275298 if (!fr ) {
276299 ast_debug (2 , "User hung up\n" );
277- res = -1 ;
278- break ;
300+ goto abort ;
279301 }
280302 if (fr -> frametype == AST_FRAME_DTMF ) {
281303 ast_debug (1 , "User pressed a key\n" );
@@ -284,23 +306,35 @@ static int fsk_tx_exec(struct ast_channel *chan, const char *data)
284306 samples = fsk_tx (caller_tx , caller_amp , BLOCK_LEN );
285307 if ((res = ast_write (chan , & f )) < 0 ) {
286308 ast_debug (1 , "Failed to write %d samples\n" , samples );
287- res = -1 ;
288- break ;
309+ goto abort ;
289310 }
290311 }
291- memset (caller_amp , 0 , sizeof (caller_amp ));
292- res = ast_waitfor (chan , -1 );
293- fr = ast_read (chan );
294- if (!fr ) {
295- ast_debug (2 , "User hung up\n" );
296- return -1 ;
297- }
298- ast_frfree (fr );
299- if (ast_write (chan , & f ) < 0 ) {
300- res = -1 ;
312+
313+ /* Send a few extra frames of mark tone to allow receiver to reliably receive last bit of data */
314+ for (samples = 0 ; samples < 4 ; samples ++ ) {
315+ res = ast_waitfor (chan , -1 );
316+ fr = ast_read (chan );
317+ if (!fr ) {
318+ ast_debug (2 , "User hung up\n" );
319+ goto abort ;
320+ }
321+ ast_frfree (fr );
322+ fsk_tx (caller_tx , caller_amp , BLOCK_LEN );
323+ if (ast_write (chan , & f ) < 0 ) {
324+ ast_debug (1 , "Failed to write mark tone\n" );
325+ goto abort ;
326+ }
301327 }
328+
302329 ast_debug (1 , "SendFSK Completed.\n" );
330+ ast_free (out );
331+ fsk_tx_free (caller_tx );
303332 return 0 ;
333+
334+ abort :
335+ ast_free (out );
336+ fsk_tx_free (caller_tx );
337+ return -1 ;
304338}
305339
306340static int fsk_rx_exec (struct ast_channel * chan , const char * data )
@@ -315,6 +349,8 @@ static int fsk_rx_exec(struct ast_channel *chan, const char *data)
315349 int modem ;
316350 int silence_flag = 0 ;
317351 int res = 0 ;
352+ int retries = 0 ;
353+ int eof_count = 0 ;
318354
319355 AST_DECLARE_APP_ARGS (arglist ,
320356 AST_APP_ARG (variable );
@@ -340,10 +376,10 @@ static int fsk_rx_exec(struct ast_channel *chan, const char *data)
340376 }
341377 }
342378
343- modem = FSK_BELL103CH2 ;
379+ modem = FSK_BELL103CH1 ;
344380 if (!ast_strlen_zero (arglist .modem )) {
345381 if (!strcmp (arglist .modem , "103" )) {
346- modem = FSK_BELL103CH2 ;
382+ modem = FSK_BELL103CH1 ;
347383 } else if (!strcmp (arglist .modem , "202" )) {
348384 modem = FSK_BELL202 ;
349385 } else {
@@ -360,11 +396,13 @@ static int fsk_rx_exec(struct ast_channel *chan, const char *data)
360396 }
361397
362398 memset (output_frame , 0 , sizeof (output_frame ));
363- in = ast_malloc ( sizeof (* in ));
399+ in = ast_calloc ( 1 , sizeof (* in ));
364400 if (!in ) {
365401 return -1 ;
366402 }
367403
404+ in -> quitoncarrierlost = 1 ;
405+
368406 if (!ast_strlen_zero (arglist .options )) {
369407 ast_app_parse_options (read_app_options , & flags , NULL , arglist .options );
370408 if (ast_test_flag (& flags , OPT_HANGOUT )) {
@@ -375,34 +413,59 @@ static int fsk_rx_exec(struct ast_channel *chan, const char *data)
375413 }
376414 }
377415
378- in -> fsk_eof = 0 ;
379- in -> quitoncarrierlost = 1 ;
380-
381416 in -> buffer = ast_calloc (1 , 65536 ); /* Reserve 64KB space for receive buffer. */
382417 if (!in -> buffer ) {
383418 ast_free (in );
384419 return -1 ;
385420 }
386-
387- in -> ptr = 0 ;
388-
389421 if (silence_flag ) {
390422 silgen = ast_channel_start_silence_generator (chan );
391423 }
392424 caller_rx = fsk_rx_init (NULL , & preset_fsk_specs [modem ], FSK_FRAME_MODE_8N1_FRAMES , get_bit , in );
425+ if (!caller_rx ) {
426+ ast_free (in -> buffer );
427+ ast_free (in );
428+ return -1 ;
429+ }
393430 fsk_rx_set_modem_status_handler (caller_rx , rx_status , (void * ) in );
394431 while (ast_waitfor (chan , -1 ) > -1 ) {
395432 f = ast_read (chan );
396433 if (!f ) {
397- res = -1 ;
398- break ;
434+ ast_debug ( 1 , "No more frames to read\n" ) ;
435+ goto done ; /* Caller hung up immediately, but there might be data to read */
399436 }
400- if (f -> frametype == AST_FRAME_VOICE ){
437+ if (f -> frametype == AST_FRAME_VOICE ) {
401438 fsk_rx (caller_rx , f -> data .ptr , f -> samples );
402439 }
403- if (in -> fsk_eof != 0 ) {
404- ast_debug (1 , "fsk_eof\n" );
405- break ;
440+ if (in -> fsk_eof ) {
441+ if (!in -> got_data ) {
442+ /* Don't abort immediately if there's no carrier present yet,
443+ * the sender may not have started sending yet...
444+ * to a point, if we never get anything after a while (5 seconds), abort anyways. */
445+ if (++ retries > 250 ) {
446+ ast_log (LOG_WARNING , "No FSK data received\n" );
447+ ast_frfree (f );
448+ goto done ; /* This is normal success */
449+ }
450+ ast_debug (4 , "fsk_eof, but no data received yet, waiting...\n" );
451+ eof_count = in -> fsk_eof = 0 ; /* Reset */
452+ } else {
453+ eof_count ++ ;
454+ ast_debug (3 , "FSK eof count %d\n" , eof_count );
455+ /* Require 2 carrier downs in a row to signify EOF
456+ * Note that rx_status only fires when receiving FSK audio,
457+ * but even if we really only get one carrier down,
458+ * this still works because the next loop iteration here,
459+ * fsk_eof will still be set true and we'll break,
460+ * i.e. SpanDSP telling us carrier down + next frame is not FSK. */
461+ if (eof_count > 1 ) {
462+ ast_debug (1 , "FSK carrier seems to have dropped\n" );
463+ ast_frfree (f );
464+ goto done ; /* This is typically normal success */
465+ }
466+ }
467+ } else {
468+ eof_count = 0 ;
406469 }
407470 f -> subclass .format = ast_format_slin ;
408471 f -> datalen = BLOCK_LEN ;
@@ -411,24 +474,32 @@ static int fsk_rx_exec(struct ast_channel *chan, const char *data)
411474 f -> src = __PRETTY_FUNCTION__ ;
412475 f -> data .ptr = & output_frame ;
413476 if (ast_write (chan , f ) < 0 ) {
414- res = -1 ;
477+ ast_debug ( 1 , "No more frames to read\n" ) ;
415478 ast_frfree (f );
416- break ;
479+ goto abort ;
417480 }
418- ast_frfree (f );
419481 }
420482 if (!f ) {
421483 ast_debug (1 , "Got hangup\n" );
422- res = -1 ;
484+ goto abort ;
423485 }
486+
487+ done :
424488 ast_debug (1 , "received buffer is: %s\n" , in -> buffer );
425489 pbx_builtin_setvar_helper (chan , arglist .variable , in -> buffer );
426- ast_free (in -> buffer );
427490 if (silgen ) {
428491 ast_channel_stop_silence_generator (chan , silgen );
429492 }
493+ ast_free (in -> buffer );
430494 ast_free (in );
495+ fsk_rx_free (caller_rx );
431496 return 0 ;
497+
498+ abort :
499+ ast_free (in -> buffer );
500+ ast_free (in );
501+ fsk_rx_free (caller_rx );
502+ return -1 ;
432503}
433504
434505static int unload_module (void )
0 commit comments