Avoid large buffer on stack, to prevent stack overflows

This affectes:
 * demodulation in libfsk
 * audio processing in libmobile
This commit is contained in:
Andreas Eversberg 2024-02-18 16:14:06 +01:00
parent 91443acdc0
commit be650bf549
4 changed files with 30 additions and 13 deletions

View File

@ -361,6 +361,8 @@ void fsk_demod_cleanup(fsk_demod_t *fsk)
//#define DEBUG_MODULATOR
//#define DEBUG_FILTER
#define CHUNK 1024
/* Demodulates bits
*
* If bit is received, callback function send_bit() is called.
@ -375,15 +377,21 @@ void fsk_demod_cleanup(fsk_demod_t *fsk)
*/
void fsk_demod_receive(fsk_demod_t *fsk, sample_t *sample, int length)
{
sample_t I[length], Q[length], frequency[length], f;
sample_t I[CHUNK], Q[CHUNK], frequency[CHUNK], f;
int i;
int bit;
double level, quality;
/* demod samples to offset around center frequency */
fm_demodulate_real(&fsk->demod, frequency, length, sample, I, Q);
for (i = 0; i < length; i++) {
/* this is called on first sample and subsequently every sample defined by CHUNK */
if (i % CHUNK == 0) {
length -= i;
i = 0;
/* demod CHUNK samples to offset around center frequency */
fm_demodulate_real(&fsk->demod, frequency, (length > CHUNK) ? CHUNK : length, sample, I, Q);
sample += CHUNK;
}
f = frequency[i];
if (f < 0)
bit = fsk->low_bit;

View File

@ -617,6 +617,7 @@ void main_mobile_loop(const char *name, int *quit, void (*myhandler)(void), cons
sender_t *sender;
double last_time_call = 0, begin_time, now, sleep;
struct termios term, term_orig;
int num_chan, i;
int c;
int rc;
@ -693,6 +694,15 @@ void main_mobile_loop(const char *name, int *quit, void (*myhandler)(void), cons
if (console_open_audio(buffer_size, dsp_interval))
return;
/* alloc memory for audio processing */
for (num_chan = 0, sender = sender_head; sender; num_chan++, sender = sender->next);
sample_t *samples[num_chan];
uint8_t *powers[num_chan];
for (i = 0; i < num_chan; i++) {
samples[i] = calloc(buffer_size, sizeof(**samples));
powers[i] = calloc(buffer_size, sizeof(**powers));
}
/* real time priority */
if (rt_prio > 0) {
struct sched_param schedp;
@ -739,7 +749,7 @@ void main_mobile_loop(const char *name, int *quit, void (*myhandler)(void), cons
/* do not process audio for an audio slave, since it is done by audio master */
if (sender->master) /* if master is set, we are an audio slave */
continue;
process_sender_audio(sender, quit, buffer_size);
process_sender_audio(sender, quit, samples, powers, buffer_size);
}
/* process audio for call instances */
@ -855,6 +865,11 @@ next_char:
signal(SIGTERM, SIG_DFL);
signal(SIGPIPE, SIG_DFL);
for (i = 0; i < num_chan; i++) {
free(samples[i]);
free(powers[i]);
}
/* reset terminal */
tcsetattr(0, TCSANOW, &term_orig);

View File

@ -331,7 +331,7 @@ static void gain_samples(sample_t *samples, int length, double gain)
}
/* Handle audio streaming of one transceiver. */
void process_sender_audio(sender_t *sender, int *quit, int buffer_size)
void process_sender_audio(sender_t *sender, int *quit, sample_t **samples, uint8_t **power, int buffer_size)
{
sender_t *inst;
int rc, count;
@ -342,15 +342,9 @@ void process_sender_audio(sender_t *sender, int *quit, int buffer_size)
/* count instances for audio channel */
for (num_chan = 0, inst = sender; inst; num_chan++, inst = inst->slave);
sample_t buff[num_chan][buffer_size], *samples[num_chan];
uint8_t pbuff[num_chan][buffer_size], *power[num_chan];
enum paging_signal paging_signal[num_chan];
int on[num_chan];
double rf_level_db[num_chan];
for (i = 0; i < num_chan; i++) {
samples[i] = buff[i];
power[i] = pbuff[i];
}
#ifdef DEBUG_TIME_CONSUMPTION
t1 = get_time();

View File

@ -100,7 +100,7 @@ void sender_set_fm(sender_t *sender, double max_deviation, double max_modulation
void sender_set_am(sender_t *sender, double max_modulation, double speech_deviation, double max_display, double modulation_index);
int sender_open_audio(int buffer_size, double interval);
int sender_start_audio(void);
void process_sender_audio(sender_t *sender, int *quit, int buffer_size);
void process_sender_audio(sender_t *sender, int *quit, sample_t **samples, uint8_t **power, int buffer_size);
void sender_send(sender_t *sender, sample_t *samples, uint8_t *power, int count);
void sender_receive(sender_t *sender, sample_t *samples, int count, double rf_level_db);
void sender_paging(sender_t *sender, int on);