gnokii-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: thread safe usage of multiple phones


From: Peter Koch
Subject: Re: thread safe usage of multiple phones
Date: Sun, 14 May 2017 09:31:55 +0200

Dear Pawel

we are using multiple nokia phones now with our multi-threaded
sms-daemon. Works well so far

I had to fix one problem and I did it the quick+dirty way.

Have a look at routine verify_max_message_len() in
common/links/fbus-phonet.c, starting at line 64

static int verify_max_message_len(int len, char **message_buffer)
{
        static int max_message_len = 0;

        if (len > max_message_len) {
                dprintf("overrun: %d %d\n", len, max_message_len);
                *message_buffer = realloc(*message_buffer, len + 1);
                max_message_len = len + 1;
        }
        if (*message_buffer)
                return max_message_len;
        else
                return 0;
}

The static declaration of max_message_len causes problems if
multiple thread are calling this routine. Even worse. When opening
a phone max_message_len must be 0. Otherwise gn_lib_phone_open()
will fail.

This makes the following code fail on the second invocation of
gn_lib_phone_open(). max_message_len stays non-zero after
the first call of verify_max_message_len() and therefor no memory
will be allocated in the second call. *message_buffer will be NULL
and gn_lib_phone_open() fails.

Of course this only happens when the phonet-driver is used, so my
serial nokia 6310 works fine.

main(){
  struct gn_statemachine *state;
  gn_error err;

  err=gn_lib_phoneprofile_load_from_file(GNOKIIRC, NULL, &state);
  printf("load=%d, %s\n", err, gn_error_print(err));
  err=gn_lib_phone_open(state);
  printf("open=%d, %s\n", err, gn_error_print(err));
  err=gn_lib_phone_close(state);
  printf("close=%d, %s\n", err, gn_error_print(err));
  err=gn_lib_phone_open(state); // err will be 9 with nokia 6230i and dku2libusb
  printf("open=%d, %s\n", err, gn_error_print(err));
}

Here's my dirty fix for routine verify_max_message_len()

static int verify_max_message_len(int len, char **message_buffer)
{
        static int max_message_len = 0;

        if(len<PHONET_FRAME_MAX_LENGTH) len=PHONET_FRAME_MAX_LENGTH;
        if(len>PHONET_FRAME_MAX_LENGTH || !*message_buffer){
                dprintf("reallocating message_buffer to %d bytes\n", len+1);
                *message_buffer = realloc(*message_buffer, len+1);
        }
        return *message_buffer ? len+1 : 0;

        if (len > max_message_len) {
                dprintf("overrun: %d %d\n", len, max_message_len);
                *message_buffer = realloc(*message_buffer, len + 1);
                max_message_len = len + 1;
        }
        if (*message_buffer)
                return max_message_len;
        else
                return 0;
}

Peter

reply via email to

[Prev in Thread] Current Thread [Next in Thread]