1

I have a c++ program that runs on the RPi 3 with a GPRS hat (SIM808) with is connected via UART. Currently I establish my connection with sudo pon <isp-name> and disconnect sudo poff <isp-name>. All of this works as expected.

Because the SIM808 have GPS as well which I use, I want to control the connect and disconnect from my application, which work as well by doing a fork(), but I found that in some instances the application falls over for no reason.

Is there a way for me to establish a pppd connection from code by including header files and calling a method instead of forking the process?

Update

This is my function that I use to do my forking

bool DoFork(const char *method, const char *param1, const char *param2 = NULL, const char *param3 = NULL, const char *SuccessMsg = "Success", const char *ErrorMsg = "Error")
{
pid_t forkid = fork();
int status;
SetLastUsedCommand("DoFork");

switch (forkid) {
case -1:
    LogEntry(LOG_CRIT, "Unable to make fork\n");
    break;
case 0:
{
    int res = execl(method, method, param1, param2, param3, NULL);
    LogEntry(LOG_NOTICE, ErrorMsg, res); //"GSM not started. %d\n"
    break;
}
default:
    fflush(NULL);
    if (waitpid(forkid, &status, 0) != -1)
    {
        if ((status & 0xff00) == 0)
        {
            sleep(2);
            return true;
        }
        else
            return false;
    }

    break;
}
return false;
}

I then call it like

res = DoFork("/usr/bin/sudo", "pon", "fona", NULL, "GSM Connection Made\n", "GSM not started. %d\n");

I think my problem is that I have threads that is running as well in my application, and the threads is what cause the segmentation problem

1
  • Use ioctl to directly configure the tunnel through the kernel /dev/ppp interface

OR

  • Use wait to suspend your application until the forked process has finished, preventing crashes due to concurrency issues.

Details

The utility pon and poff do not provide a system header, but inevitably they probably use standard linux ioctl calls through the /dev/ppp (or, possibly, /dev/net/tun) interface to configure the network interface but do not have their own API, possibly they interact through other kernel interfaces, its hard to tell from first look.

You have two options that I see

  1. Determine what it takes to configure the PPP through ioctl, I found one forum post that has examples.

    • This requires opening the device and issuing the correct IOCTL calls to configure the ppp driver.

    • The linux kernel documentation of this device is available here and is a good place to start. (

  2. Continue to use fork, but use a more robust mechanism to guarantee that the external process has concluded.

    • use the wait system call to block your application thread until the forked call to pon or poff is completed
    • For an example of how to wait for a forked process, take a look at this so question

Multiple Threads Edit

If you are using multiple threads, you must guarantee that all resources that are provided by the external process are protected. You have a few options (Not All Inclusive)

  1. fork and wait on External Process before threads are created
  2. Spawn a "forking thread" which does fork and wait, have all threads join (pthread_join) the 'forking thread'
  3. Use mutex, condition variable or other form of locking to restrict any resource handles provided by external ppp interface.
    • Sub threads acquire lock to access resource
    • If ppp is disabled, main thread holds lock on resource indefinitely
    • When main thread releases lock, signals other threads to wake
  4. Make your threads capable of detecting a disabled ppp and proceed accordingly
  • I've added some more information. I will look at the ioctl – Jaques Oct 26 '17 at 18:40
  • @Jaques I have updated with additional info. – crasic Oct 27 '17 at 5:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.