100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/* //device/system/rild/rild.c
200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project**
300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** Copyright 2006, The Android Open Source Project
400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project**
500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** you may not use this file except in compliance with the License.
700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** You may obtain a copy of the License at
800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project**
900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
1000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project**
1100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
1200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
1300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** See the License for the specific language governing permissions and
1500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** limitations under the License.
1600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project*/
1700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <stdio.h>
1900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <stdlib.h>
2000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <dlfcn.h>
2100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <string.h>
2200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <stdint.h>
2300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <unistd.h>
2400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <fcntl.h>
2500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <errno.h>
2600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
2700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <telephony/ril.h>
2800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define LOG_TAG "RILD"
2900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <utils/Log.h>
3000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <cutils/properties.h>
3100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <cutils/sockets.h>
32fe4e1ec0233967f537e21d1b2ae30e7d33a97051Nick Kralevich#include <sys/capability.h>
3300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <linux/prctl.h>
3400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
3500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <private/android_filesystem_config.h>
36385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine#include "hardware/qemu_pipe.h"
3700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
3800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define LIB_PATH_PROPERTY   "rild.libpath"
3900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define LIB_ARGS_PROPERTY   "rild.libargs"
4000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define MAX_LIB_ARGS        16
4100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
4200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void usage(const char *argv0)
4300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
4400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    fprintf(stderr, "Usage: %s -l <ril impl library> [-- <args for impl library>]\n", argv0);
4500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    exit(-1);
4600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
4700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
4800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectextern void RIL_register (const RIL_RadioFunctions *callbacks);
4900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
5000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectextern void RIL_onRequestComplete(RIL_Token t, RIL_Errno e,
5100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                           void *response, size_t responselen);
5200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
5300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectextern void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
5400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                                size_t datalen);
5500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
562932f31296822b86ed945e09cadaabf2a453843cWink Savilleextern void RIL_requestTimedCallback (RIL_TimedCallback callback,
5700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                               void *param, const struct timeval *relativeTime);
5800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
5900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
6000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic struct RIL_Env s_rilEnv = {
6100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete,
6200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onUnsolicitedResponse,
632932f31296822b86ed945e09cadaabf2a453843cWink Saville    RIL_requestTimedCallback
6400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project};
6500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
6600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectextern void RIL_startEventLoop();
6700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
6800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int make_argv(char * args, char ** argv)
6900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
7000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // Note: reserve argv[0]
7100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int count = 1;
7200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char * tok;
7300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char * s = args;
7400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
7500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    while ((tok = strtok(s, " \0"))) {
7600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        argv[count] = tok;
7700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        s = NULL;
7800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        count++;
7900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
8000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return count;
8100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
8200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
8300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/*
8400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * switchUser - Switches UID to radio, preserving CAP_NET_ADMIN capabilities.
8500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * Our group, cache, was set by init.
8600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project */
8700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectvoid switchUser() {
8800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
8900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    setuid(AID_RADIO);
9000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
9100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    struct __user_cap_header_struct header;
9200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    struct __user_cap_data_struct cap;
9300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    header.version = _LINUX_CAPABILITY_VERSION;
9400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    header.pid = 0;
95c45f4678481f1f38c969989cebbd4c3bd25d6667Pal Szasz    cap.effective = cap.permitted = (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW);
9600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    cap.inheritable = 0;
9700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    capset(&header, &cap);
9800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
9900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
10000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectint main(int argc, char **argv)
10100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
10200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    const char * rilLibPath = NULL;
10300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char **rilArgv;
10400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    void *dlHandle;
10500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **);
10600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    const RIL_RadioFunctions *funcs;
10700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char libPath[PROPERTY_VALUE_MAX];
10800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    unsigned char hasLibArgs = 0;
10900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
11000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int i;
11100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
112aea7d5beb2d2cc4d49954f9d5158b8a53c3d7d31Nick Kralevich    umask(S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH);
11300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for (i = 1; i < argc ;) {
11400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (0 == strcmp(argv[i], "-l") && (argc - i > 1)) {
11500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            rilLibPath = argv[i + 1];
11600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            i += 2;
11700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        } else if (0 == strcmp(argv[i], "--")) {
11800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            i++;
11900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            hasLibArgs = 1;
12000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
12100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        } else {
12200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            usage(argv[0]);
12300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
12400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
12500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
12600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (rilLibPath == NULL) {
12700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if ( 0 == property_get(LIB_PATH_PROPERTY, libPath, NULL)) {
12800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // No lib sepcified on the command line, and nothing set in props.
12900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // Assume "no-ril" case.
13000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto done;
13100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        } else {
13200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            rilLibPath = libPath;
13300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
13400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
13500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
13600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* special override when in the emulator */
13700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#if 1
13800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    {
13900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        static char*  arg_overrides[3];
14000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        static char   arg_device[32];
14100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        int           done = 0;
14200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
14300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define  REFERENCE_RIL_PATH  "/system/lib/libreference-ril.so"
14400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
14500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        /* first, read /proc/cmdline into memory */
14600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        char          buffer[1024], *p, *q;
14700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        int           len;
14800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        int           fd = open("/proc/cmdline",O_RDONLY);
14900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
15000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (fd < 0) {
1518eb2a12cb7b525e74736300962a5f3848427275aWink Saville            RLOGD("could not open /proc/cmdline:%s", strerror(errno));
15200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto OpenLib;
15300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
15400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
15500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        do {
15600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            len = read(fd,buffer,sizeof(buffer)); }
15700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        while (len == -1 && errno == EINTR);
15800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
15900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (len < 0) {
1608eb2a12cb7b525e74736300962a5f3848427275aWink Saville            RLOGD("could not read /proc/cmdline:%s", strerror(errno));
16100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            close(fd);
16200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto OpenLib;
16300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
16400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        close(fd);
16500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
16600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (strstr(buffer, "android.qemud=") != NULL)
16700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        {
16800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            /* the qemud daemon is launched after rild, so
16900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            * give it some time to create its GSM socket
17000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            */
17100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            int  tries = 5;
172e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project#define  QEMUD_SOCKET_NAME    "qemud"
17300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
17400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            while (1) {
17500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                int  fd;
17600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
17700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                sleep(1);
17800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
179385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                fd = qemu_pipe_open("qemud:gsm");
180385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                if (fd < 0) {
181385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                    fd = socket_local_client(
182385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                                QEMUD_SOCKET_NAME,
183385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                                ANDROID_SOCKET_NAMESPACE_RESERVED,
184385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                                SOCK_STREAM );
185385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                }
18600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                if (fd >= 0) {
18700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    close(fd);
18800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    snprintf( arg_device, sizeof(arg_device), "%s/%s",
18900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                                ANDROID_SOCKET_DIR, QEMUD_SOCKET_NAME );
19000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
19100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    arg_overrides[1] = "-s";
19200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    arg_overrides[2] = arg_device;
19300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    done = 1;
19400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    break;
19500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                }
1968eb2a12cb7b525e74736300962a5f3848427275aWink Saville                RLOGD("could not connect to %s socket: %s",
19700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    QEMUD_SOCKET_NAME, strerror(errno));
19800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                if (--tries == 0)
19900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    break;
20000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
20100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (!done) {
2028eb2a12cb7b525e74736300962a5f3848427275aWink Saville                RLOGE("could not connect to %s socket (giving up): %s",
20300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    QEMUD_SOCKET_NAME, strerror(errno));
20400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                while(1)
20500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    sleep(0x00ffffff);
20600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
20700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
20800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
20900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        /* otherwise, try to see if we passed a device name from the kernel */
21000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (!done) do {
21100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define  KERNEL_OPTION  "android.ril="
21200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define  DEV_PREFIX     "/dev/"
21300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
21400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            p = strstr( buffer, KERNEL_OPTION );
21500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (p == NULL)
21600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                break;
21700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
21800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            p += sizeof(KERNEL_OPTION)-1;
21900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            q  = strpbrk( p, " \t\n\r" );
22000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (q != NULL)
22100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                *q = 0;
22200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
22300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            snprintf( arg_device, sizeof(arg_device), DEV_PREFIX "%s", p );
22400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            arg_device[sizeof(arg_device)-1] = 0;
22500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            arg_overrides[1] = "-d";
22600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            arg_overrides[2] = arg_device;
22700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            done = 1;
22800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
22900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        } while (0);
23000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
23100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (done) {
23200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            argv = arg_overrides;
23300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            argc = 3;
23400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            i    = 1;
23500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            hasLibArgs = 1;
23600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            rilLibPath = REFERENCE_RIL_PATH;
23700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
2388eb2a12cb7b525e74736300962a5f3848427275aWink Saville            RLOGD("overriding with %s %s", arg_overrides[1], arg_overrides[2]);
23900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
24000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
24100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source ProjectOpenLib:
24200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif
24300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    switchUser();
24400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
24500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    dlHandle = dlopen(rilLibPath, RTLD_NOW);
24600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
24700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (dlHandle == NULL) {
2488eb2a12cb7b525e74736300962a5f3848427275aWink Saville        RLOGE("dlopen failed: %s", dlerror());
24900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        exit(-1);
25000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
25100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
25200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_startEventLoop();
25300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
25400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))dlsym(dlHandle, "RIL_Init");
25500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
25600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (rilInit == NULL) {
2578eb2a12cb7b525e74736300962a5f3848427275aWink Saville        RLOGE("RIL_Init not defined or exported in %s\n", rilLibPath);
25800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        exit(-1);
25900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
26000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
26100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (hasLibArgs) {
26200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        rilArgv = argv + i - 1;
26300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        argc = argc -i + 1;
26400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else {
26500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        static char * newArgv[MAX_LIB_ARGS];
26600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        static char args[PROPERTY_VALUE_MAX];
26700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        rilArgv = newArgv;
26800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        property_get(LIB_ARGS_PROPERTY, args, "");
26900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        argc = make_argv(args, rilArgv);
27000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
27100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
27200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // Make sure there's a reasonable argv[0]
27300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    rilArgv[0] = argv[0];
27400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
27500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    funcs = rilInit(&s_rilEnv, argc, rilArgv);
27600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
27700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_register(funcs);
27800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
27900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectdone:
28000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
28100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    while(1) {
28200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // sleep(UINT32_MAX) seems to return immediately on bionic
28300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        sleep(0x00ffffff);
28400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
28500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
28600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
287