/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>

#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <dirent.h>

#include <netinet/in.h>
#include <arpa/inet.h>

#define LOG_TAG "PppController"
#include <cutils/log.h>

#include "PppController.h"

PppController::PppController() {
    mTtys = new TtyCollection();
    mPid = 0;
}

PppController::~PppController() {
    TtyCollection::iterator it;

    for (it = mTtys->begin(); it != mTtys->end(); ++it) {
        free(*it);
    }
    mTtys->clear();
}

int PppController::attachPppd(const char *tty, struct in_addr local,
                              struct in_addr remote, struct in_addr dns1,
                              struct in_addr dns2) {
    pid_t pid;

    if (mPid) {
        ALOGE("Multiple PPPD instances not currently supported");
        errno = EBUSY;
        return -1;
    }

    TtyCollection::iterator it;
    for (it = mTtys->begin(); it != mTtys->end(); ++it) {
        if (!strcmp(tty, *it)) {
            break;
        }
    }
    if (it == mTtys->end()) {
        ALOGE("Invalid tty '%s' specified", tty);
        errno = -EINVAL;
        return -1;
    }

    if ((pid = fork()) < 0) {
        ALOGE("fork failed (%s)", strerror(errno));
        return -1;
    }

    if (!pid) {
        char *l = strdup(inet_ntoa(local));
        char *r = strdup(inet_ntoa(remote));
        char *d1 = strdup(inet_ntoa(dns1));
        char *d2 = strdup(inet_ntoa(dns2));
        char dev[32];
        char *lr;

        asprintf(&lr, "%s:%s", l, r);
        free(l);
        free(r);

        snprintf(dev, sizeof(dev), "/dev/%s", tty);

        // TODO: Deal with pppd bailing out after 99999 seconds of being started
        // but not getting a connection
        if (execl("/system/bin/pppd", "/system/bin/pppd", "-detach", dev, "115200",
                  lr, "ms-dns", d1, "ms-dns", d2, "lcp-max-configure", "99999", (char *) NULL)) {
            ALOGE("execl failed (%s)", strerror(errno));
        }
        free(lr);
        free(d1);
        free(d2);
        ALOGE("Should never get here!");
        return 0;
    } else {
        mPid = pid;
    }
    return 0;
}

int PppController::detachPppd(const char *tty) {

    if (mPid == 0) {
        ALOGE("PPPD already stopped");
        return 0;
    }

    ALOGD("Stopping PPPD services on port %s", tty);
    kill(mPid, SIGTERM);
    waitpid(mPid, NULL, 0);
    mPid = 0;
    ALOGD("PPPD services on port %s stopped", tty);
    return 0;
}

TtyCollection *PppController::getTtyList() {
    updateTtyList();
    return mTtys;
}

int PppController::updateTtyList() {
    TtyCollection::iterator it;

    for (it = mTtys->begin(); it != mTtys->end(); ++it) {
        free(*it);
    }
    mTtys->clear();

    DIR *d = opendir("/sys/class/tty");
    if (!d) {
        ALOGE("Error opening /sys/class/tty (%s)", strerror(errno));
        return -1;
    }

    struct dirent *de;
    while ((de = readdir(d))) {
        if (de->d_name[0] == '.')
            continue;
        if ((!strncmp(de->d_name, "tty", 3)) && (strlen(de->d_name) > 3)) {
            mTtys->push_back(strdup(de->d_name));
        }
    }
    closedir(d);
    return 0;
}
