示例#1
1
int main(int argc, char **argv)
{
    const char * rilLibPath = NULL;
    char **rilArgv;
    void *dlHandle;
    const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **);
    const RIL_RadioFunctions *(*rilInitSocket)(const struct RIL_EnvSocket *, int, char **);
    const RIL_RadioFunctions *funcs;
    const RIL_RadioFunctionsSocket *funcsSocket;
    char libPath[PROPERTY_VALUE_MAX];
    char socPath[PROPERTY_VALUE_MAX];
    unsigned char hasLibArgs = 0;

    int i;
    const char *clientId = NULL;
    RLOGD("**RIL Daemon Started**");
    RLOGD("**RILd param count=%d**", argc);

#ifdef MTK_RIL_MD2
    RLOGD("RILD started (MD2)");
#else
    RLOGD("RILD started");
#endif

    if (mtkInit() == -1) goto done;

    umask(S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH);
    for (i = 1; i < argc ;) {
        if (0 == strcmp(argv[i], "-l") && (argc - i > 1)) {
            rilLibPath = argv[i + 1];
            i += 2;
        } else if (0 == strcmp(argv[i], "--")) {
            i++;
            hasLibArgs = 1;
            break;
        } else if (0 == strcmp(argv[i], "-c") &&  (argc - i > 1)) {
            clientId = argv[i+1];
            i += 2;
        } else {
            usage(argv[0]);
        }
    }

    if (clientId == NULL) {
        clientId = "0";
    } else if (atoi(clientId) >= MAX_RILDS) {
        RLOGE("Max Number of rild's supported is: %d", MAX_RILDS);
        exit(0);
    }
    if (strncmp(clientId, "0", MAX_CLIENT_ID_LENGTH)) {
        RIL_setRilSocketName(strncat(rild, clientId, MAX_SOCKET_NAME_LENGTH));
    }

    if (rilLibPath == NULL) {
#ifdef MTK_RIL_MD2
        if ( 0 == property_get(LIB_PATH_PROPERTY, libPath, "/system/lib/mtk-rilmd2.so")) {
#else
        if ( 0 == property_get(LIB_PATH_PROPERTY, libPath, "/system/lib/mtk-ril.so")) {
#endif
            // No lib sepcified on the command line, and nothing set in props.
            // Assume "no-ril" case.
            goto done;
        } else {
            rilLibPath = libPath;
        }
    }

    /* special override when in the emulator */
#if 1
    {
        static char*  arg_overrides[5];
        static char   arg_device[32];
        int           done = 0;

#ifdef MTK_RIL_MD2
#define  REFERENCE_RIL_PATH  "/system/lib/mtk-rilmd2.so"
#else
#define  REFERENCE_RIL_PATH  "/system/lib/mtk-ril.so"
#endif
        /* first, read /proc/cmdline into memory */
        char          buffer[1024], *p, *q;
        int           len;
        int           fd = open("/proc/cmdline",O_RDONLY);

        if (fd < 0) {
            RLOGD("could not open /proc/cmdline:%s", strerror(errno));
            goto OpenLib;
        }

        do {
            len = read(fd,buffer,sizeof(buffer));
        }
        while (len == -1 && errno == EINTR);

        if (len < 0) {
            RLOGD("could not read /proc/cmdline:%s", strerror(errno));
            close(fd);
            goto OpenLib;
        }
        close(fd);

        if (strstr(buffer, "android.qemud=") != NULL)
        {
            /* the qemud daemon is launched after rild, so
            * give it some time to create its GSM socket
            */
            int  tries = 5;
#define  QEMUD_SOCKET_NAME    "qemud"

            while (1) {
                int  fd;

                sleep(1);

                fd = qemu_pipe_open("qemud:gsm");
                if (fd < 0) {
                    fd = socket_local_client(
                             QEMUD_SOCKET_NAME,
                             ANDROID_SOCKET_NAMESPACE_RESERVED,
                             SOCK_STREAM );
                }
                if (fd >= 0) {
                    close(fd);
                    snprintf( arg_device, sizeof(arg_device), "%s/%s",
                              ANDROID_SOCKET_DIR, QEMUD_SOCKET_NAME );

                    arg_overrides[1] = "-s";
                    arg_overrides[2] = arg_device;
                    done = 1;
                    break;
                }
                RLOGD("could not connect to %s socket: %s",
                      QEMUD_SOCKET_NAME, strerror(errno));
                if (--tries == 0)
                    break;
            }
            if (!done) {
                RLOGE("could not connect to %s socket (giving up): %s",
                      QEMUD_SOCKET_NAME, strerror(errno));
                while(1)
                    sleep(0x00ffffff);
            }
        }

        /* otherwise, try to see if we passed a device name from the kernel */
        if (!done) do {
#define  KERNEL_OPTION  "android.ril="
#define  DEV_PREFIX     "/dev/"

                p = strstr( buffer, KERNEL_OPTION );
                if (p == NULL)
                    break;

                p += sizeof(KERNEL_OPTION)-1;
                q  = strpbrk( p, " \t\n\r" );
                if (q != NULL)
                    *q = 0;

                snprintf( arg_device, sizeof(arg_device), DEV_PREFIX "%s", p );
                arg_device[sizeof(arg_device)-1] = 0;
                arg_overrides[1] = "-d";
                arg_overrides[2] = arg_device;
                done = 1;

            } while (0);

        if (done) {
            argv = arg_overrides;
            argc = 3;
            i    = 1;
            hasLibArgs = 1;
            rilLibPath = REFERENCE_RIL_PATH;

            RLOGD("overriding with %s %s", arg_overrides[1], arg_overrides[2]);
        }
    }
OpenLib:
#endif
    switchUser();

#ifdef MTK_RIL_MD2
    rilLibPath = "/system/lib/mtk-rilmd2.so";
#endif
    RLOGD("Open ril lib path: %s", rilLibPath);

    dlHandle = dlopen(rilLibPath, RTLD_NOW);

    if (dlHandle == NULL) {
        RLOGE("dlopen failed: %s", dlerror());
        exit(EXIT_FAILURE);
    }

    RIL_startEventLoop();

    rilInitSocket = (const int(*)(void))dlsym(dlHandle, "RIL_InitSocket");

    if (rilInitSocket == NULL) {
        RLOGD("Vendor RIL do not need socket id!");
        rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))dlsym(dlHandle, "RIL_Init");

        if (rilInit == NULL) {
            RLOGE("RIL_Init not defined or exported in %s\n", rilLibPath);
            exit(EXIT_FAILURE);
        }
    } else {
        RLOGD("vendor RIL need socket id");
    }

    if (hasLibArgs) {
        rilArgv = argv + i - 1;
        argc = argc -i + 1;
    } else {
        static char * newArgv[MAX_LIB_ARGS];
        static char args[PROPERTY_VALUE_MAX];
        rilArgv = newArgv;
#ifdef MTK_RIL_MD2
        property_get(LIB_ARGS_PROPERTY, args, "-d /dev/ccci2_tty0");
#else
        property_get(LIB_ARGS_PROPERTY, args, "-d /dev/ttyC0");
#endif
        argc = make_argv(args, rilArgv);
    }

    rilArgv[argc++] = "-c";
    rilArgv[argc++] = clientId;
    RLOGD("RIL_Init argc = %d clientId = %s", argc, rilArgv[argc-1]);

    // Make sure there's a reasonable argv[0]
    rilArgv[0] = argv[0];

    if (rilInitSocket == NULL) {
        RLOGD("Old vendor ril! so RIL_register is called");
        funcs = rilInit(&s_rilEnv, argc, rilArgv);
        RIL_register(funcs);
    } else {
        RLOGD("New vendor ril! so RIL_registerSocket is called");
        funcsSocket = rilInitSocket(&s_rilEnvSocket, argc, rilArgv);
        RIL_registerSocket(funcsSocket);
    }

done:

    RLOGD("RIL_Init starting sleep loop");
    while (true) {
        sleep(UINT32_MAX);
    }
}
void asyncOperation(void* ptr,
					asyncHandler handler,
					asyncDestructor dtor,
					const char* operationID) //operationID for debug
{
	//Run it right away to see if it finished instantly.
	auto res = handler(ptr);
	switch(res)
	{
		case ASYNC_OPERATION_COMPLETE:
			RLOGI("Async operation %s completed", operationID);
			break;
		case ASYNC_OPERATION_RUNNING:
			while(length == BUFFER_SIZE)
			{
				RLOGW("To many async operations in flight! %d", length);
				asyncOperationsProcess();
			}

			asyncBuffer[length++] = (AsyncItem){ptr, handler, dtor, operationID};
			break;
		case ASYNC_OPERATION_FAILURE:
			RLOGE("Async operation %s failed", operationID);
			break;
		default:
			RLOGE("Async operation %s returned invalid result %d", operationID, res);
			break;
	}
}
void asyncOperationsProcess()
{
	for(int i = 0; i < length; i++)
	{
		auto item = asyncBuffer[i];
		auto res  = item.handler(item.payload);
		switch(res)
		{
			case ASYNC_OPERATION_COMPLETE:
				asyncBuffer[i--] = asyncBuffer[--length];
				item.dtor(item.payload);

				RLOGI("Async operation %s completed", item.operationID);
				break;
			case ASYNC_OPERATION_RUNNING:
				//Do nothing
				break;
			case ASYNC_OPERATION_FAILURE:
				RLOGE("Async operation %s failed", item.operationID);
				asyncBuffer[i--] = asyncBuffer[--length];
				item.dtor(item.payload);
				break;
			default:
				RLOGE("Async operation %s returned invalid result %d", item.operationID, res);
				asyncBuffer[i--] = asyncBuffer[--length];
				item.dtor(item.payload);
				break;
		}
	}
}
示例#4
0
RILChannelCtx *openPPPDataChannel(int isBlocking)
{
    RLOGI("openDataChannel");
    RILChannelCtx* p_channel = &g_pppDataChannel;
    if (p_channel->fd > 0)
        closePPPDataChannel();

    memset(p_channel, 0, sizeof(RILChannelCtx));
    p_channel->fd = -1;    /* fd of the AT channel */

    int retryCounter = 0;
    int err = 0;
    while (p_channel->fd < 0 && retryCounter < 5) {
        do {
            RLOGI("set property for usb permission");
            /* set this property than the permission of /dev/ttyACM0 will be set to 777 */
            property_set("gsm.usb.ttyusb", "1");
            if (isBlocking)
                p_channel->fd = open("/dev/ttyUSB0", O_RDWR);
            else
                p_channel->fd = open("/dev/ttyUSB0", O_RDWR | O_NONBLOCK);
        } while (p_channel->fd < 0 && errno == EINTR);

        if (p_channel->fd < 0) {
            perror ("opening AT interface. retrying...");
            RLOGE("could not connect to %s: %s", "/dev/ttyUSB0", strerror(errno));
            /* reduce polling time for usb connected */
            sleep(1);
            /* never returns */
        } else {
            struct termios ios;
            tcgetattr(p_channel->fd, &ios );
            ios.c_lflag = 0;  /* disable ECHO, ICANON, etc... */
            ios.c_iflag = 0;
            tcsetattr(p_channel->fd, TCSANOW, &ios );
        }
        ++retryCounter;
    }

    if (p_channel->fd < 0) {
        RLOGE("/dev/ttyUSB0 open failed");
        return NULL;
    } else {
        RLOGI("/dev/ttyUSB0 open success");
        p_channel->ATBufferCur = p_channel->ATBuffer;
        p_channel->myName = "PPP_CHANNEL";
        p_channel->id = ++g_channelIndex;
        p_channel->unsolHandler = 0;
        p_channel->readerClosed = 0;
        p_channel->responsePrefix = NULL;
        p_channel->smsPDU = NULL;
        p_channel->p_response = NULL;
    }
    return &g_pppDataChannel;
}
示例#5
0
static void *readerLoop(void *arg)
{
	RILChannelCtx *p_channel = (RILChannelCtx *)arg;
	const char *readerName = p_channel->myName;

	RLOGI("%s is up", readerName);


	for (;; ) {
		const char *line;

		line = readline(p_channel);

		RLOGD("%s:%s", readerName, line);

		if (line == NULL)
			break;

		if (isSMSUnsolicited(line)) {
			char *line1;
			const char *line2;
			RLOGD("SMS Urc Received!");
			// The scope of string returned by 'readline()' is valid only
			// till next call to 'readline()' hence making a copy of line
			// before calling readline again.
			line1 = strdup(line);
			line2 = readline(p_channel);

			if (line2 == NULL) {
				RLOGE("NULL line found in %s", readerName);
				break;
			}

			if (p_channel->unsolHandler != NULL) {
				RLOGD("%s: line1:%s,line2:%s", readerName, line1, line2);
				p_channel->unsolHandler(line1, line2, p_channel);
			}
			free(line1);
		} else {
			pthread_mutex_lock(&p_channel->commandmutex);
			RLOGD("%s Enter processLine", readerName);
			processLine(line, p_channel);
			pthread_mutex_unlock(&p_channel->commandmutex);
		}
	}
	RLOGE("%s Closed", readerName);
	onReaderClosed(p_channel);

	return NULL;
}
示例#6
0
int openDataChannel(char* deviceNote, int isBlocking, RILChannelCtx* p_channel, int channelId)
{
    RLOGI("openDataChannel");
    if (p_channel->fd > 0)
        closeDataChannel(p_channel);

    memset(p_channel, 0, sizeof(RILChannelCtx));
    p_channel->fd = -1;    /* fd of the AT channel */

    int retryCounter = 0;
    int err = 0;
    while (p_channel->fd < 0 && retryCounter < 5) {
        do {
            RLOGI("set property for usb permission");
            p_channel->fd = open(deviceNote, isBlocking? O_RDWR : (O_RDWR | O_NONBLOCK));
        } while (p_channel->fd < 0 && errno == EINTR);

        if (p_channel->fd < 0) {
            perror ("opening AT interface. retrying...");
            RLOGE("could not connect to %s: %s", "/dev/ttyUSB0", strerror(errno));
            /* reduce polling time for usb connected */
            sleep(1);
            /* never returns */
        } else {
            struct termios ios;
            tcgetattr(p_channel->fd, &ios );
            ios.c_lflag = 0;  /* disable ECHO, ICANON, etc... */
            ios.c_iflag = 0;
            tcsetattr(p_channel->fd, TCSANOW, &ios );
        }
        ++retryCounter;
    }

    if (p_channel->fd < 0) {
        RLOGE("%s open failed", deviceNote);
        return -1;
    } else {
        RLOGI("%s open success", deviceNote);
        p_channel->ATBufferCur = p_channel->ATBuffer;
        p_channel->myName = deviceNote;
        p_channel->id = ++channelId;
        p_channel->unsolHandler = 0;
        p_channel->readerClosed = 0;
        p_channel->responsePrefix = NULL;
        p_channel->smsPDU = NULL;
        p_channel->p_response = NULL;
    }
    return 0;
}
示例#7
0
/*
 * switchUser - Switches UID to radio, preserving CAP_NET_ADMIN capabilities.
 * Our group, cache, was set by init.
 */
void switchUser() {
    char debuggable[PROP_VALUE_MAX];

    prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
    setuid(AID_RADIO);

    struct __user_cap_header_struct header;
    memset(&header, 0, sizeof(header));
    header.version = _LINUX_CAPABILITY_VERSION_3;
    header.pid = 0;

    struct __user_cap_data_struct data[2];
    memset(&data, 0, sizeof(data));

    data[CAP_TO_INDEX(CAP_NET_ADMIN)].effective |= CAP_TO_MASK(CAP_NET_ADMIN);
    data[CAP_TO_INDEX(CAP_NET_ADMIN)].permitted |= CAP_TO_MASK(CAP_NET_ADMIN);

    data[CAP_TO_INDEX(CAP_NET_RAW)].effective |= CAP_TO_MASK(CAP_NET_RAW);
    data[CAP_TO_INDEX(CAP_NET_RAW)].permitted |= CAP_TO_MASK(CAP_NET_RAW);

    if (capset(&header, &data[0]) == -1) {
        RLOGE("capset failed: %s", strerror(errno));
        exit(EXIT_FAILURE);
    }

    /*
     * Debuggable build only:
     * Set DUMPABLE that was cleared by setuid() to have tombstone on RIL crash
     */
    property_get("ro.debuggable", debuggable, "0");
    if (strcmp(debuggable, "1") == 0) {
        prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
    }
}
示例#8
0
static void processLine(const char *line)
{
    pthread_mutex_lock(&s_commandmutex);

    if (sp_response == NULL) {
        /* no command pending */
        handleUnsolicited(line);
    } else if (isFinalResponseSuccess(line)) {
        sp_response->success = 1;
        handleFinalResponse(line);
    } else if (isFinalResponseError(line)) {
        sp_response->success = 0;
        handleFinalResponse(line);
    } else if (s_smsPDU != NULL && 0 == strcmp(line, "> ")) {
        // See eg. TS 27.005 4.3
        // Commands like AT+CMGS have a "> " prompt
        writeCtrlZ(s_smsPDU);
        s_smsPDU = NULL;
    } else switch (s_type) {
        case NO_RESULT:
            handleUnsolicited(line);
            break;
        case NUMERIC:
            if (sp_response->p_intermediates == NULL
                && isdigit(line[0])
            ) {
                addIntermediate(line);
            } else {
                /* either we already have an intermediate response or
                   the line doesn't begin with a digit */
                handleUnsolicited(line);
            }
            break;
        case SINGLELINE:
            if (sp_response->p_intermediates == NULL
                && strStartsWith (line, s_responsePrefix)
            ) {
                addIntermediate(line);
            } else {
                /* we already have an intermediate response */
                handleUnsolicited(line);
            }
            break;
        case MULTILINE:
            if (strStartsWith (line, s_responsePrefix)) {
                addIntermediate(line);
            } else {
                handleUnsolicited(line);
            }
        break;

        default: /* this should never be reached */
            RLOGE("Unsupported AT command type %d\n", s_type);
            handleUnsolicited(line);
        break;
    }

    pthread_mutex_unlock(&s_commandmutex);
}
示例#9
0
static void checkGlError(const char* op) {
	for (GLint error = glGetError(); error; error = glGetError()) {
		switch (error)
		{
		case GL_INVALID_VALUE:
			RLOGE("after %s glError invalid value occured", op);
			break;
		case GL_INVALID_ENUM:
			RLOGE("after %s glError invalid enum occured", op);
			break;
		case GL_INVALID_OPERATION:
			RLOGE("after %s glError invalid operation occured", op);
			break;
		case GL_INVALID_FRAMEBUFFER_OPERATION:

			break;
		case EGL_CONTEXT_LOST:
			RLOGE("Context is lost!", "");
			break;
		}
	}
}
示例#10
0
void closeDataChannel(RILChannelCtx* p_channel)
{
    if (p_channel == NULL) {
        RLOGE("closeDataChannel invalid input argument");
        return;
    }

    RLOGI("closeDataChannel [%d, %d]", p_channel->id, p_channel->fd);
    if (p_channel->fd >= 0) {
        close(p_channel->fd);
    }
    p_channel->fd = -1;
}
示例#11
0
/*
 * switchUser - Switches UID to radio, preserving CAP_NET_ADMIN capabilities.
 * Our group, cache, was set by init.
 */
void switchUser() {
    prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
    setuid(AID_RADIO);

    struct __user_cap_header_struct header;
    memset(&header, 0, sizeof(header));
    header.version = _LINUX_CAPABILITY_VERSION_3;
    header.pid = 0;

    struct __user_cap_data_struct data[2];
    memset(&data, 0, sizeof(data));

    data[CAP_TO_INDEX(CAP_NET_ADMIN)].effective |= CAP_TO_MASK(CAP_NET_ADMIN);
    data[CAP_TO_INDEX(CAP_NET_ADMIN)].permitted |= CAP_TO_MASK(CAP_NET_ADMIN);

    data[CAP_TO_INDEX(CAP_NET_RAW)].effective |= CAP_TO_MASK(CAP_NET_RAW);
    data[CAP_TO_INDEX(CAP_NET_RAW)].permitted |= CAP_TO_MASK(CAP_NET_RAW);

    if (capset(&header, &data[0]) == -1) {
        RLOGE("capset failed: %s", strerror(errno));
        exit(EXIT_FAILURE);
    }
}
示例#12
0
/**
 * Called by atchannel when an unsolicited line appears
 * This is called on atchannel's reader thread. AT commands may
 * not be issued here
 */
static void onUnsolicited (const char *s, const char *sms_pdu, void * pChannel)
{
RLOGI("[Emu]get in onUnsolicited");
RLOGI("[Emu]command %s",s);
    char *line = NULL;
    int err;
    RIL_RadioState radioState = sState;
    RILChannelCtx * p_channel = (RILChannelCtx *) pChannel;

#ifdef MTK_GEMINI
    if (MTK_RIL_SOCKET_2 == getRILIdByChannelCtx(p_channel)) {
        radioState = sState2;
		RLOGI("[Emu]state2");
    }
#endif 

    /* Ignore unsolicited responses until we're initialized.
     * This is OK because the RIL library will poll for initial state
     */
    if (radioState == RADIO_STATE_UNAVAILABLE) {
        return;
    }

    if (!(rilNwUnsolicited(s,sms_pdu,p_channel) ||
          rilCcUnsolicited(s,sms_pdu, p_channel) ||
          rilSsUnsolicited(s,sms_pdu, p_channel) ||
          rilSmsUnsolicited(s,sms_pdu, p_channel) ||
          rilStkUnsolicited(s,sms_pdu, p_channel) ||
          rilOemUnsolicited(s,sms_pdu, p_channel) ||
          rilDataUnsolicited(s,sms_pdu, p_channel)||
          rilSimUnsolicited(s,sms_pdu, p_channel))
    ) {

        RLOGE("Unhandled unsolicited result code: %s\n", s);

    }
}
void RIL_startRILProxys(void)
{
    int ret;
    int i;
    int proxysNum = getRilProxysNum();
    
    for (i=0; i<proxysNum; i++)
    {
        pthread_attr_t attr;
        pthread_attr_init (&attr);
        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
        ret = pthread_create(&s_tid_proxy[i], &attr, proxyLoop,(void*) &s_Proxy[i]);


        if (ret < 0) {
            RLOGE("Failed to create proxy thread errno:%d", errno);
            assert(0);
            return;
        }

        LOGD("proxy %s is up, tid:%d",::proxyIdToString(i),(int) s_tid_proxy[i]);
    }

}
示例#14
0
int main(int argc, char **argv) {
    // vendor ril lib path either passed in as -l parameter, or read from rild.libpath property
    const char *rilLibPath = NULL;
    // ril arguments either passed in as -- parameter, or read from rild.libargs property
    char **rilArgv;
    // handle for vendor ril lib
    void *dlHandle;
    // Pointer to ril init function in vendor ril
    const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **);
    // Pointer to sap init function in vendor ril
    const RIL_RadioFunctions *(*rilUimInit)(const struct RIL_Env *, int, char **);
    const char *err_str = NULL;

    // functions returned by ril init function in vendor ril
    const RIL_RadioFunctions *funcs;
    // lib path from rild.libpath property (if it's read)
    char libPath[PROPERTY_VALUE_MAX];
    // flat to indicate if -- parameters are present
    unsigned char hasLibArgs = 0;

    int i;
    // ril/socket id received as -c parameter, otherwise set to 0
    const char *clientId = NULL;

    RLOGD("**RIL Daemon Started**");
    RLOGD("**RILd param count=%d**", argc);

    umask(S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH);
    for (i = 1; i < argc ;) {
        if (0 == strcmp(argv[i], "-l") && (argc - i > 1)) {
            rilLibPath = argv[i + 1];
            i += 2;
        } else if (0 == strcmp(argv[i], "--")) {
            i++;
            hasLibArgs = 1;
            break;
        } else if (0 == strcmp(argv[i], "-c") &&  (argc - i > 1)) {
            clientId = argv[i+1];
            i += 2;
        } else {
            usage(argv[0]);
        }
    }

    if (clientId == NULL) {
        clientId = "0";
    } else if (atoi(clientId) >= MAX_RILDS) {
        RLOGE("Max Number of rild's supported is: %d", MAX_RILDS);
        exit(0);
    }
    if (strncmp(clientId, "0", MAX_CLIENT_ID_LENGTH)) {
        snprintf(ril_service_name, sizeof(ril_service_name), "%s%s", ril_service_name_base,
                 clientId);
    }

    if (rilLibPath == NULL) {
        if ( 0 == property_get(LIB_PATH_PROPERTY, libPath, NULL)) {
            // No lib sepcified on the command line, and nothing set in props.
            // Assume "no-ril" case.
            goto done;
        } else {
            rilLibPath = libPath;
        }
    }

    dlHandle = dlopen(rilLibPath, RTLD_NOW);

    if (dlHandle == NULL) {
        RLOGE("dlopen failed: %s", dlerror());
        exit(EXIT_FAILURE);
    }

    RIL_startEventLoop();

    rilInit =
        (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))
        dlsym(dlHandle, "RIL_Init");

    if (rilInit == NULL) {
        RLOGE("RIL_Init not defined or exported in %s\n", rilLibPath);
        exit(EXIT_FAILURE);
    }

    dlerror(); // Clear any previous dlerror
    rilUimInit =
        (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))
        dlsym(dlHandle, "RIL_SAP_Init");
    err_str = dlerror();
    if (err_str) {
        RLOGW("RIL_SAP_Init not defined or exported in %s: %s\n", rilLibPath, err_str);
    } else if (!rilUimInit) {
        RLOGW("RIL_SAP_Init defined as null in %s. SAP Not usable\n", rilLibPath);
    }

    if (hasLibArgs) {
        rilArgv = argv + i - 1;
        argc = argc -i + 1;
    } else {
        static char * newArgv[MAX_LIB_ARGS];
        static char args[PROPERTY_VALUE_MAX];
        rilArgv = newArgv;
        property_get(LIB_ARGS_PROPERTY, args, "");
        argc = make_argv(args, rilArgv);
    }

    rilArgv[argc++] = "-c";
    rilArgv[argc++] = (char*)clientId;
    RLOGD("RIL_Init argc = %d clientId = %s", argc, rilArgv[argc-1]);

    // Make sure there's a reasonable argv[0]
    rilArgv[0] = argv[0];

    funcs = rilInit(&s_rilEnv, argc, rilArgv);
    RLOGD("RIL_Init rilInit completed");

    RIL_register(funcs);

    RLOGD("RIL_Init RIL_register completed");

    if (rilUimInit) {
        RLOGD("RIL_register_socket started");
        RIL_register_socket(rilUimInit, RIL_SAP_SOCKET, argc, rilArgv);
    }

    RLOGD("RIL_register_socket completed");

    rilc_thread_pool();

done:
    RLOGD("RIL_Init starting sleep loop");
    while (true) {
        sleep(UINT32_MAX);
    }
}
示例#15
0
static void initializeCallback(void *param)
{
	RLOGE ("[Emu]get in initializeCallback");
    ATResponse *p_response = NULL;
    int err;
    RILId rid = *((RILId *)param);

	char property_value[5] = { 0 };
    int current_share_modem = 0;

    current_share_modem = MTK_SHARE_MODEM_CURRENT;

    setRadioState (RADIO_STATE_OFF,rid);

    err = at_handshake(getDefaultChannelCtx(rid));

    RLOGI("AT handshake: %d",err);

    /* note: we don't check errors here. Everything important will
       be handled in onATTimeout and onATReaderClosed */

    /*  atchannel is tolerant of echo but it must */
    /*  have verbose result codes */
    at_send_command("ATE0Q0V1", NULL, getDefaultChannelCtx(rid));

    /*  No auto-answer */
    at_send_command("ATS0=0", NULL,getDefaultChannelCtx(rid));

    /*  Extended errors */
    at_send_command("AT+CMEE=1", NULL, getDefaultChannelCtx(rid));

    /*  Network registration events */
    err = at_send_command("AT+CREG=2", &p_response, getDefaultChannelCtx(rid));

    /* some handsets -- in tethered mode -- don't support CREG=2 */
    if (err < 0 || p_response->success == 0) {
        at_send_command("AT+CREG=1", NULL, getDefaultChannelCtx(rid));
    }

    at_response_free(p_response);

    /*  GPRS registration events */
    at_send_command("AT+CGREG=1", NULL, getDefaultChannelCtx(rid));

    /*  Call Waiting notifications */
    at_send_command("AT+CCWA=1", NULL, getDefaultChannelCtx(rid));
//[Emu]TODO diff
    /*  mtk00924: enable Call Progress notifications */
    at_send_command("AT+ECPI=4294967295", NULL, getDefaultChannelCtx(rid));

    /*  Alternating voice/data off */
    /*
    at_send_command("AT+CMOD=0", NULL, getDefaultChannelCtx(rid));
    */

    /*  Not muted */
    /*
    at_send_command("AT+CMUT=0", NULL, getDefaultChannelCtx(rid));
    */
    
//[Emu]TODO diff
    /*  +CSSU unsolicited supp service notifications */
    at_send_command("AT+CSSN=1,1", NULL, getDefaultChannelCtx(rid));
//[Emu]TODO diff
    /*  connected line identification on */
    at_send_command("AT+COLP=1", NULL, getDefaultChannelCtx(rid));
//[Emu]TODO diff
    /*  HEX character set */
    at_send_command("AT+CSCS=\"UCS2\"", NULL, getDefaultChannelCtx(rid));

    /*  USSD unsolicited */
    at_send_command("AT+CUSD=1", NULL, getDefaultChannelCtx(rid));

    /*  Enable +CGEV GPRS event notifications, but don't buffer */
    at_send_command("AT+CGEREP=1,0", NULL, getDefaultChannelCtx(rid));

    /*  SMS PDU mode */
    at_send_command("AT+CMGF=0", NULL, getDefaultChannelCtx(rid));

    /* Initial CID table */
    initialCidTable();

//[Emu]TODO diff
    /* Enable getting NITZ, include TZ and Operator Name*/
    /* To Receive +CIEV: 9 and +CIEV: 10*/
//[Emu]TODO_1_ changed
  //  at_send_command("AT+CTZR=1", NULL, getDefaultChannelCtx(rid));
//[Emu]TODO diff
    /*  Enable getting CFU info +ECFU and speech info +ESPEECH*/
//    at_send_command("AT+EINFO=114", NULL, getDefaultChannelCtx(rid));
//[Emu]TODO diff
    /*  Enable get ECSQ URC */
    //at_send_command("AT+ECSQ=2", NULL, getDefaultChannelCtx(rid));
//[Emu]TODO diff
    /*  Enable get +CIEV:7 URC to receive SMS SIM Storage Status*/
   // at_send_command("AT+CMER=1,0,0,2,0", NULL, getDefaultChannelCtx(rid));
//[Emu]TODO diff
#ifdef MTK_VT3G324M_SUPPORT
    at_send_command("AT+CRC=1", NULL, getDefaultChannelCtx(rid));
#endif
#ifdef MTK_GEMINI
    requestSimReset(rid);

	RLOGD("start rild bootup flow [%d, %d, %d, %d]", isDualTalkMode(), rid, RIL_is3GSwitched(), current_share_modem);
	if (isDualTalkMode()) {
		if (rid == MTK_RIL_SOCKET_1) {
			flightModeBoot();
			bootupGetIccid(rid); //query ICCID after AT+ESIMS
			bootupGetImei(rid);
			bootupGetImeisv(rid);
			bootupGetBasebandVersion(rid);
            bootupGetCalData(rid);			
			RLOGD("get SIM inserted status (DT) [%d]", sim_inserted_status);
			RIL_onUnsolicitedResponse(RIL_UNSOL_SIM_INSERTED_STATUS, &sim_inserted_status, sizeof(int), rid);
		}
	} else {
		if (current_share_modem == 1) {
			if (rid == MTK_RIL_SOCKET_1) {
				flightModeBoot();
				bootupGetIccid(rid); //query ICCID after AT+ESIMS
				bootupGetImei(rid);
				bootupGetImeisv(rid);
				bootupGetBasebandVersion(rid);
                bootupGetCalData(rid);											
				RLOGD("get SIM inserted status (Single) [%d]", sim_inserted_status);
				RIL_onUnsolicitedResponse(RIL_UNSOL_SIM_INSERTED_STATUS, &sim_inserted_status, sizeof(int), rid);
			}
		} else if (rid == MTK_RIL_SOCKET_2) {
			flightModeBoot();
			bootupGetIccid(MTK_RIL_SOCKET_1);
			bootupGetIccid(MTK_RIL_SOCKET_2);
			bootupGetImei(MTK_RIL_SOCKET_1);
			bootupGetImei(MTK_RIL_SOCKET_2);
			bootupGetImeisv(MTK_RIL_SOCKET_1);
			bootupGetImeisv(MTK_RIL_SOCKET_2);
			bootupGetBasebandVersion(MTK_RIL_SOCKET_1);
			bootupGetBasebandVersion(MTK_RIL_SOCKET_2);
            bootupGetCalData(MTK_RIL_SOCKET_1);						
			RLOGD("get SIM inserted status [%d]", sim_inserted_status);
			RIL_onUnsolicitedResponse(RIL_UNSOL_SIM_INSERTED_STATUS, &sim_inserted_status, sizeof(int), rid);
		}
	}
#else
	flightModeBoot();
	bootupGetIccid(rid);
	bootupGetImei(rid);
	bootupGetImeisv(rid);
	bootupGetBasebandVersion(rid);
        bootupGetCalData(rid);	
#endif  /* MTK_GEMINI */

//[Emu]TODO diff
    /* assume radio is off on error */
    if (isRadioOn(rid) > 0) {
        setRadioState (RADIO_STATE_SIM_NOT_READY,rid);
    }
}
示例#16
0
int main(int argc, char **argv)
{
    const char * rilLibPath = NULL;
    char **rilArgv;
    void *dlHandle;
    const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **);
    const RIL_RadioFunctions *funcs;
    char libPath[PROPERTY_VALUE_MAX];
    unsigned char hasLibArgs = 0;
    int modem_type = UNKNOWN_MODEM;
    int i;

    umask(S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH);
    for (i = 1; i < argc ;) {
        if (0 == strcmp(argv[i], "-l") && (argc - i > 1)) {
            rilLibPath = argv[i + 1];
            i += 2;
        } else if (0 == strcmp(argv[i], "--")) {
            i++;
            hasLibArgs = 1;
            break;
        } else {
            usage(argv[0]);
        }
    }

    //Wait for device ready.
    if (rilLibPath == NULL) {
		while(UNKNOWN_MODEM == modem_type){
		    modem_type = runtime_3g_port_type();
		    ALOGD("Couldn't find proper modem, retrying...");
		    s_poll_device_cnt++;
		    if (s_poll_device_cnt > MAX_POLL_DEVICE_CNT){
				/*
				*Maybe no device right now, start to monitor
				*hotplug event later.
				*/
				start_uevent_monitor();
				goto done;
		    }
		    sleep(5);
		}
    }

    start_uevent_monitor();

    switch (modem_type){
		case ZTE_MODEM:
		rilLibPath = REFERENCE_RIL_ZTE_PATH;
		break;

		case HUAWEI_MODEM:
		case AMAZON_MODEM:
		default:
			if (!rilLibPath)
				rilLibPath = REFERENCE_RIL_DEF_PATH;
		break;
    }
	RLOGE("ril lib path=%s\n", rilLibPath);
    if (rilLibPath == NULL) {
        if ( 0 == property_get(LIB_PATH_PROPERTY, libPath, NULL)) {
            // No lib sepcified on the command line, and nothing set in props.
            // Assume "no-ril" case.
            goto done;
        } else {
            rilLibPath = libPath;
        }
    }

    /* special override when in the emulator */
#if 1
    {
        static char*  arg_overrides[3];
        static char   arg_device[32];
        int           done = 0;

#define  REFERENCE_RIL_PATH  "/system/lib/libreference-ril.so"

        /* first, read /proc/cmdline into memory */
        char          buffer[1024], *p, *q;
        int           len;
        int           fd = open("/proc/cmdline",O_RDONLY);

        if (fd < 0) {
            RLOGD("could not open /proc/cmdline:%s", strerror(errno));
            goto OpenLib;
        }

        do {
            len = read(fd,buffer,sizeof(buffer)); }
        while (len == -1 && errno == EINTR);

        if (len < 0) {
            RLOGD("could not read /proc/cmdline:%s", strerror(errno));
            close(fd);
            goto OpenLib;
        }
        close(fd);

        if (strstr(buffer, "android.qemud=") != NULL)
        {
            /* the qemud daemon is launched after rild, so
            * give it some time to create its GSM socket
            */
            int  tries = 5;
#define  QEMUD_SOCKET_NAME    "qemud"

            while (1) {
                int  fd;

                sleep(1);

                fd = qemu_pipe_open("qemud:gsm");
                if (fd < 0) {
                    fd = socket_local_client(
                                QEMUD_SOCKET_NAME,
                                ANDROID_SOCKET_NAMESPACE_RESERVED,
                                SOCK_STREAM );
                }
                if (fd >= 0) {
                    close(fd);
                    snprintf( arg_device, sizeof(arg_device), "%s/%s",
                                ANDROID_SOCKET_DIR, QEMUD_SOCKET_NAME );

                    arg_overrides[1] = "-s";
                    arg_overrides[2] = arg_device;
                    done = 1;
                    break;
                }
                RLOGD("could not connect to %s socket: %s",
                    QEMUD_SOCKET_NAME, strerror(errno));
                if (--tries == 0)
                    break;
            }
            if (!done) {
                RLOGE("could not connect to %s socket (giving up): %s",
                    QEMUD_SOCKET_NAME, strerror(errno));
                while(1)
                    sleep(0x00ffffff);
            }
        }

        /* otherwise, try to see if we passed a device name from the kernel */
        if (!done) do {
#define  KERNEL_OPTION  "android.ril="
#define  DEV_PREFIX     "/dev/"

            p = strstr( buffer, KERNEL_OPTION );
            if (p == NULL)
                break;

            p += sizeof(KERNEL_OPTION)-1;
            q  = strpbrk( p, " \t\n\r" );
            if (q != NULL)
                *q = 0;

            snprintf( arg_device, sizeof(arg_device), DEV_PREFIX "%s", p );
            arg_device[sizeof(arg_device)-1] = 0;
            arg_overrides[1] = "-d";
            arg_overrides[2] = arg_device;
            done = 1;

        } while (0);

        if (done) {
            argv = arg_overrides;
            argc = 3;
            i    = 1;
            hasLibArgs = 1;
            rilLibPath = REFERENCE_RIL_PATH;

            RLOGD("overriding with %s %s", arg_overrides[1], arg_overrides[2]);
        }
    }
OpenLib:
#endif
    switchUser();

    dlHandle = dlopen(rilLibPath, RTLD_NOW);

    if (dlHandle == NULL) {
        RLOGE("dlopen failed: %s", dlerror());
        exit(-1);
    }

    RIL_startEventLoop();

    rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))dlsym(dlHandle, "RIL_Init");

    if (rilInit == NULL) {
        RLOGE("RIL_Init not defined or exported in %s\n", rilLibPath);
        exit(-1);
    }

    if (hasLibArgs) {
        rilArgv = argv + i - 1;
        argc = argc -i + 1;
    } else {
        static char * newArgv[MAX_LIB_ARGS];
        static char args[PROPERTY_VALUE_MAX];
        rilArgv = newArgv;
        property_get(LIB_ARGS_PROPERTY, args, "");
        argc = make_argv(args, rilArgv);
    }

    // Make sure there's a reasonable argv[0]
    rilArgv[0] = argv[0];
    funcs = rilInit(&s_rilEnv, argc, rilArgv);

    RIL_register(funcs);

done:

    while(1) {
        // sleep(UINT32_MAX) seems to return immediately on bionic
        sleep(0x00ffffff);
    }
}
示例#17
0
static const char *readline()
{
    ssize_t count;

    char *p_read = NULL;
    char *p_eol = NULL;
    char *ret;

    /* this is a little odd. I use *s_ATBufferCur == 0 to
     * mean "buffer consumed completely". If it points to a character, than
     * the buffer continues until a \0
     */
    if (*s_ATBufferCur == '\0') {
        /* empty buffer */
        s_ATBufferCur = s_ATBuffer;
        *s_ATBufferCur = '\0';
        p_read = s_ATBuffer;
    } else {   /* *s_ATBufferCur != '\0' */
        /* there's data in the buffer from the last read */

        // skip over leading newlines
        while (*s_ATBufferCur == '\r' || *s_ATBufferCur == '\n')
            s_ATBufferCur++;

        p_eol = findNextEOL(s_ATBufferCur);

        if (p_eol == NULL) {
            /* a partial line. move it up and prepare to read more */
            size_t len;

            len = strlen(s_ATBufferCur);

            memmove(s_ATBuffer, s_ATBufferCur, len + 1);
            p_read = s_ATBuffer + len;
            s_ATBufferCur = s_ATBuffer;
        }
        /* Otherwise, (p_eol !- NULL) there is a complete line  */
        /* that will be returned the while () loop below        */
    }

    while (p_eol == NULL) {
        if (0 == MAX_AT_RESPONSE - (p_read - s_ATBuffer)) {
            RLOGE("ERROR: Input line exceeded buffer\n");
            /* ditch buffer and start over again */
            s_ATBufferCur = s_ATBuffer;
            *s_ATBufferCur = '\0';
            p_read = s_ATBuffer;
        }

        do {
            count = read(s_fd, p_read,
                            MAX_AT_RESPONSE - (p_read - s_ATBuffer));
        } while (count < 0 && errno == EINTR);

        if (count > 0) {
            AT_DUMP( "<< ", p_read, count );

            p_read[count] = '\0';

            // skip over leading newlines
            while (*s_ATBufferCur == '\r' || *s_ATBufferCur == '\n')
                s_ATBufferCur++;

            p_eol = findNextEOL(s_ATBufferCur);
            p_read += count;
        } else if (count <= 0) {
            /* read error encountered or EOF reached */
            if(count == 0) {
                RLOGD("atchannel: EOF reached");
            } else {
                RLOGD("atchannel: read error %s", strerror(errno));
            }
            return NULL;
        }
    }

    /* a full line in the buffer. Place a \0 over the \r and return */

    ret = s_ATBufferCur;
    *p_eol = '\0';
    s_ATBufferCur = p_eol + 1; /* this will always be <= p_read,    */
                              /* and there will be a \0 at *p_read */

    RLOGD("AT< %s\n", ret);
    return ret;
}
示例#18
0
static void emulator_gemini_opensocket()
{
	int fd;
    		int ret;
		for (;;) {
       		 fd = -1;
			RLOGI("[Emu]emulator_gemini_opensocket_in\n");
			
			RLOGI("[Emu]s_device_socket %d\n",s_device_socket);
			RLOGI("[Emu]s_port %d\n",s_port);
			 while  (fd < 0) {
           			 if (s_port > 0) {
            			    fd = socket_loopback_client(s_port, SOCK_STREAM);
							RLOGI("[Emu]fd1 %d\n",fd);
          			  } else if (s_device_socket) {
            				    if (!strcmp(s_device_path, "/dev/socket/qemud")) {
	                			    /* Qemu-specific control socket */
	             			           fd = socket_local_client( "qemud",
	                                              ANDROID_SOCKET_NAMESPACE_RESERVED,
	                                              SOCK_STREAM );
								RLOGI("[Emu]fd2 %d\n",fd);	
	                 			   if (fd >= 0 ) {
	                 		         	   char  answer[2];

				                        if ( write(fd, "gsm", 3) != 3 ||
				                             read(fd, answer, 2) != 2 ||
				                             memcmp(answer, "OK", 2) != 0)
				                        {
				                            close(fd);
				                            fd = -1;
				                        }
                  		 	 	 }
		            	 	   }
		                	   else {
						  fd = socket_local_client( s_device_path,
                                            ANDROID_SOCKET_NAMESPACE_FILESYSTEM,
                                            SOCK_STREAM );
						}
							   RLOGI("[Emu]fd3 %d\n",fd);
                   			
            				} else if (s_device_path != NULL) {
                				fd = open (s_device_path, O_RDWR);
               				 if ( fd >= 0 && !memcmp( s_device_path, "/dev/ttyS", 9 ) ) {
				                 	/* disable echo on serial ports */
				                    struct termios  ios;
				                    tcgetattr( fd, &ios );
				                    ios.c_lflag = 0;  /* disable ECHO, ICANON, etc... */
							  ios.c_iflag = 0;		
				                    tcsetattr( fd, TCSANOW, &ios );
				                }
							 RLOGI("[Emu]fd4 %d\n",fd);
			            }

			            if (fd < 0) {
							 RLOGI("[Emu]fd<0");
			                perror ("opening AT interface. retrying...");
			                sleep(10);
			                /* never returns */
			            }
       		 }

		        s_closed = 0;
		        ret = at_open_emulator(fd, onUnsolicited,is_gemini_emulator);

		        if (ret < 0) {
		            RLOGE ("AT error %d on at_open\n", ret);
		            return 0;
		        }
			RLOGI("[Emu]RIL_requestTimedCallback");
			RIL_requestTimedCallback(initializeCallback, &s_pollSimId, &TIMEVAL_0);
#ifdef MTK_GEMINI
			RIL_requestTimedCallback(initializeCallback, &s_pollSimId2, &TIMEVAL_0);
#endif 
				RLOGI("[Emu]RIL_requestTimedCallback out");
			// Give initializeCallback a chance to dispatched, since
			// we don't presently have a cancellation mechanism
			sleep(1);
			
			waitForClose();
			RLOGI("Re-opening after close");

		}
}
示例#19
0
/**
 * Internal send_command implementation
 * Doesn't lock or call the timeout callback
 *
 * timeoutMsec == 0 means infinite timeout
 */
static int at_send_command_full_nolock(const char *command, ATCommandType type,
				       const char *responsePrefix, const char *smspdu,
				       long long timeoutMsec, ATResponse **pp_outResponse, RILChannelCtx *p_channel)
{
	int err = 0;

#ifndef USE_NP
	struct timespec ts;
#endif  /*USE_NP*/

	if (p_channel->p_response != NULL) {
		err = AT_ERROR_COMMAND_PENDING;
		RLOGE("AT_ERROR_COMMAND_PENDING: %s", command);
		goto error;
	}

	err = writeline(command, p_channel);

	if (err < 0)
		goto error;

	p_channel->type = type;
	p_channel->responsePrefix = responsePrefix;
	p_channel->smsPDU = smspdu;
	p_channel->p_response = at_response_new();

#ifndef USE_NP
	if (timeoutMsec != 0)
		setTimespecRelative(&ts, timeoutMsec);

#endif  /*USE_NP*/

	while (p_channel->p_response->finalResponse == NULL && p_channel->readerClosed == 0) {
		if (timeoutMsec != 0) {
#ifdef  USE_NP
			err = pthread_cond_timeout_np(&p_channel->commandcond, &p_channel->commandmutex, timeoutMsec);
#else
			err = pthread_cond_timedwait(&p_channel->commandcond, &p_channel->commandmutex, &ts);
#endif  /*USE_NP*/
		} else {
			err = pthread_cond_wait(&p_channel->commandcond, &p_channel->commandmutex);
		}

		if (err == ETIMEDOUT) {
			err = AT_ERROR_TIMEOUT;
			goto error;
		}
	}

	if (p_channel->readerClosed > 0) {
		err = AT_ERROR_CHANNEL_CLOSED;
		goto error;
	}

	if (pp_outResponse == NULL) {
		at_response_free(p_channel->p_response);
	} else {
		/* line reader stores intermediate responses in reverse order */
		reverseIntermediates(p_channel->p_response);
		*pp_outResponse = p_channel->p_response;
	}

	p_channel->p_response = NULL;

	err = 0;
    
error:
	clearPendingCommand(p_channel);

	return err;
}
示例#20
0
static void *
mainLoop(void *param)
{
    AT_DUMP("== ", "entering mainLoop()", -1 );
    at_set_on_reader_closed(onATReaderClosed);
    at_set_on_timeout(onATTimeout);
    initRILChannels();
	RLOGI("[Emu]mainloop_in");
	RLOGI("[Emu]mainloop_in %d\n",s_device_socket);
	if(s_device_socket)
		{
		emulator_gemini_opensocket();
		return NULL;
	}
	else
		{
		int ret;
	       int i;
	    	RILChannelCtx * p_channel;
	
	    	for (;;) {

		        for (i=0; i < RIL_SUPPORT_CHANNELS; i ++)
		        {
		            p_channel = getChannelCtxbyId(i);

		            while (p_channel->fd < 0)
		            {
		                do {
		                    p_channel->fd = open(s_mux_path[i], O_RDWR);
		                } while (p_channel->fd < 0 && errno == EINTR);
		                
		                if (p_channel->fd < 0) 
		                {
		                    perror ("opening AT interface. retrying...");
		                    RLOGE("could not connect to %s: %s",  s_mux_path[i], strerror(errno));
		                    sleep(10);
		                    /* never returns */
		                }
		                else
		                {
		                    struct termios  ios;
		                    tcgetattr(p_channel->fd, &ios );
		                    ios.c_lflag = 0;  /* disable ECHO, ICANON, etc... */
                  			  ios.c_iflag = 0;
		                    tcsetattr(p_channel->fd, TCSANOW, &ios );
		                }
		            }
		            
		            
		            s_closed = 0;
		            ret = at_open(p_channel->fd,onUnsolicited, p_channel);
		            
		            
		            if (ret < 0) {
		                RLOGE ("AT error %d on at_open\n", ret);
		                return 0;
		            }
	      		  }

		        RIL_requestTimedCallback(initializeCallback, &s_pollSimId, &TIMEVAL_0);
#ifdef MTK_GEMINI
		        RIL_requestTimedCallback(initializeCallback, &s_pollSimId2, &TIMEVAL_0);
#endif 

		        // Give initializeCallback a chance to dispatched, since
		        // we don't presently have a cancellation mechanism
		        sleep(1);

		        waitForClose();
		        RLOGI("Re-opening after close");
		}
   	 }
	
}
示例#21
0
static void processLine(const char *line, RILChannelCtx *p_channel)
{
	ATResponse *p_response = p_channel->p_response;
	const char *smsPDU = p_channel->smsPDU;
	//Move out to the function
	//pthread_mutex_lock(&p_channel->commandmutex);
	int isIntermediateResult = 0;

	if (p_response == NULL) {
		/* no command pending */
		handleUnsolicited(line, p_channel);
		return;
	} else {
		switch (p_channel->type) {
		case NO_RESULT:
			//handleUnsolicited(line,p_channel);
			break;
		case NUMERIC:
			if (p_response->p_intermediates == NULL
			    && isdigit(line[0])
			    ) {
				addIntermediate(line, p_channel);
				isIntermediateResult = 1;
			} else {
				/* either we already have an intermediate response or
				 *     the line doesn't begin with a digit */
				//handleUnsolicited(line,p_channel);
			}
			break;
		case SINGLELINE:
			if (p_response->p_intermediates == NULL
			    && strStartsWith(line, p_channel->responsePrefix)
			    ) {
				addIntermediate(line, p_channel);
				isIntermediateResult = 1;
			} else {
				/* we already have an intermediate response */
				//handleUnsolicited(line,p_channel);
			}
			break;
		case MULTILINE:
			if (strStartsWith(line, p_channel->responsePrefix)) {
				addIntermediate(line, p_channel);
				isIntermediateResult = 1;
			} else {
				//handleUnsolicited(line,p_channel);
			}
			break;
		/* atci start */
		case RAW:
			if (!isFinalResponseSuccess(line) && !isFinalResponseErrorEx(line, p_channel) && !isIntermediatePattern(line) ) {
				addIntermediate(line, p_channel);
				isIntermediateResult = 1;
			}
			break;
		/* atci end */
		default: /* this should never be reached */
			RLOGE("Unsupported AT command type %d\n", p_channel->type);
			//handleUnsolicited(line,p_channel);
			break;
		}
	}

	if (isIntermediateResult) {
		/* No need to run the following code*/
	} else if (isFinalResponseSuccess(line)) {
		p_response->success = 1;
		handleFinalResponse(line, p_channel);
	} else if (isFinalResponseErrorEx(line, p_channel)) {
		p_response->success = 0;
		handleFinalResponse(line, p_channel);
	} else if (smsPDU != NULL && 0 == strcmp(line, "> ")) {
		// See eg. TS 27.005 4.3
		// Commands like AT+CMGS have a "> " prompt
		writeCtrlZ(smsPDU, p_channel);
		smsPDU = NULL;
	} else if (isIntermediatePattern(line)) {
		p_response->success = 1;
		handleFinalResponse(line, p_channel);
	} else {
		handleUnsolicited(line, p_channel);
	}
	// Move out to the function
	//pthread_mutex_unlock(&p_channel->commandmutex);
}
示例#22
0
static void *
mainLoop(void *param)
{
    int fd;
    int ret;
    char path[50];
    int ttys_index;

    AT_DUMP("== ", "entering mainLoop()", -1 );
    at_set_on_reader_closed(onATReaderClosed);
    at_set_on_timeout(onATTimeout);

    for (;;) {
        fd = -1;
        while  (fd < 0) {
            if (s_port > 0) {
                fd = socket_loopback_client(s_port, SOCK_STREAM);
            } else if (s_device_socket) {
                if (!strcmp(s_device_path, "/dev/socket/qemud")) {
                    /* Qemu-specific control socket */
                    fd = socket_local_client( "qemud",
                                              ANDROID_SOCKET_NAMESPACE_RESERVED,
                                              SOCK_STREAM );
                    if (fd >= 0 ) {
                        char  answer[2];

                        if ( write(fd, "gsm", 3) != 3 ||
                             read(fd, answer, 2) != 2 ||
                             memcmp(answer, "OK", 2) != 0)
                        {
                            close(fd);
                            fd = -1;
                        }
                   }
                }
                else
                    fd = socket_local_client( s_device_path,
                                            ANDROID_SOCKET_NAMESPACE_FILESYSTEM,
                                            SOCK_STREAM );
            } else if (s_device_path != NULL) {
                fd = open (s_device_path, O_RDWR);
                if ( fd >= 0 && !memcmp( s_device_path, "/dev/ttyS", 9 ) ) {
                    /* disable echo on serial ports */
                    struct termios  ios;
                    tcgetattr( fd, &ios );
                    ios.c_lflag = 0;  /* disable ECHO, ICANON, etc... */
                    ios.c_iflag = 0;
                    tcsetattr( fd, TCSANOW, &ios );
                }
            }
   

            if (fd < 0) {
                perror ("opening AT interface. retrying...");
                sleep(10);
                /* never returns */
            }
        }

        RLOGD("FD: %d", fd);

        s_closed = 0;
        ret = at_open(fd, onUnsolicited);

        if (ret < 0) {
            RLOGE ("AT error %d on at_open\n", ret);
            return 0;
        }

        RIL_requestTimedCallback(initializeCallback, NULL, &TIMEVAL_0);

        // Give initializeCallback a chance to dispatched, since
        // we don't presently have a cancellation mechanism
        sleep(1);

        waitForClose();
        RLOGI("Re-opening after close");
    }
}
示例#23
0
const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv)
{
    int ret;
    int fd = -1;
    int opt;
    int index;
    char *tmp;
    pthread_attr_t attr;
    char path[50];
    int ttys_index, i;

    s_rilenv = env;

    while ( -1 != (opt = getopt(argc, argv, "p:d:s:m:"))) {
		
        switch (opt) {
            case 'p':
                s_port = atoi(optarg);
				RLOGI("s_port %s\n", s_port);
                if (s_port == 0) {
                    usage(argv[0]);
                    return NULL;
                }
                RLOGI("Opening loopback port %d\n", s_port);
            break;

            case 'd':
                s_device_path = optarg;
                RLOGI("Opening tty device1 %s\n", s_device_path);
				
            break;

            case 's':
                s_device_path   = optarg;
                s_device_socket = 1;
		 //[Emu]TODO create the middleLayer
		      is_gemini_emulator = 1;
                RLOGI("Opening socket1 %s\n", s_device_path);
		
            break;

            #ifdef MTK_RIL
            case 'm':
                RLOGD("Input range: %s %s %s",optarg, argv[1], argv[2]);
                tmp = strtok(optarg, " ");
                s_device_range_begin = atoi(tmp) ;
                tmp = strtok(NULL, " ");
                s_device_range_end = atoi(tmp);

                if(  (s_device_range_end - s_device_range_begin + 1) != RIL_SUPPORT_CHANNELS)
                {
                    RLOGE("We can't accept the input configuration for muliple channel since we need %d COM ports", RIL_SUPPORT_CHANNELS);
                    return NULL;
                }

                RLOGD("Open the ttyS%d to ttyS%d", s_device_range_begin, s_device_range_end);

                RLOGD("Link ttyS....");
                ttys_index = s_device_range_begin;
                i = 0;
                while(ttys_index <= s_device_range_end)
                {
                    sprintf(path, "/dev/ttyS%d", ttys_index);
                    RLOGD("Unlock %s on Link %s", path, s_mux_path[i]);
                    /*if(chmod(path, 0666) < 0 )
                    {
                        RLOGD("chomod: system-error: '%s' (code: %d)", strerror(errno), errno);
                        return NULL;
                    }*/
                    if(symlink(path, s_mux_path[i]) < 0)
                    {
                        RLOGD("symlink: system-error: '%s' (code: %d)", strerror(errno), errno);
                        return NULL;
                    }
                    ttys_index++;
                    i++;
                }
                break;
            #endif

            default:
                usage(argv[0]);
                return NULL;
        }
		
    }
	RLOGI("while out %s\n", s_device_path);
    if (s_port < 0 && s_device_path == NULL && 
        (s_device_range_begin < 0 || s_device_range_end < 0) ) {
        usage(argv[0]);
        return NULL;
    }

    pthread_attr_init (&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
//	if (is_gemini_emulator){
	//	  ret = pthread_create(&s_tid_mainloop, &attr, mainLoop_emulator, NULL);
		//}else{
 		ret = pthread_create(&s_tid_mainloop, &attr, mainLoop, NULL);
//	}
  

    return &s_callbacks;
}
示例#24
0
int main(int argc, char **argv)
{
    const char * rilLibPath = NULL;
    char **rilArgv;
    static char * s_argv[MAX_LIB_ARGS] = {NULL};
    void *dlHandle;
    const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **);
    const RIL_RadioFunctions *funcs;
    char libPath[PROPERTY_VALUE_MAX];
    unsigned char hasLibArgs = 0;
    int j = 0;
    int i;
    static char clientId[3] = {'0'};

    RLOGD("**RIL Daemon Started**");
    RLOGD("**RILd param count=%d**", argc);
    memset(s_argv, 0, sizeof(s_argv));

    s_argv[0] = argv[0];

    umask(S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH);
    for (i = 1, j = 1; i < argc ;) {
        if (0 == strcmp(argv[i], "-l") && (argc - i > 1)) {
            rilLibPath = argv[i + 1];
            i += 2;
        } else if (0 == strcmp(argv[i], "-c") && (argc - i > 1)) {
            strncpy(clientId, argv[i+1], strlen(clientId));
            i += 2;
        } else if (0 == strcmp(argv[i], "--")) {
            i++;
            hasLibArgs = 1;
            memcpy(&s_argv[j], &argv[i], argc-i);
            break;
        } else {
            usage(argv[0]);
        }
    }

#ifdef QCOM_HARDWARE
    if (atoi(clientId) >= MAX_RILDS) {
        RLOGE("Max Number of rild's supported is: %d", MAX_RILDS);
        exit(0);
    }
    RLOGD ("RIL Client Id:=%s", clientId);

    if (strncmp(clientId, "0", MAX_CLIENT_ID_LENGTH)) {
        if (RIL_setRilSocketName) {
            RIL_setRilSocketName(clientId);
        } else {
            RLOGE("Trying to instantiate multiple rild sockets without a compatible libril!");
        }
    }
#endif

    if (rilLibPath == NULL) {
        if ( 0 == property_get(LIB_PATH_PROPERTY, libPath, NULL)) {
            // No lib sepcified on the command line, and nothing set in props.
            // Assume "no-ril" case.
            goto done;
        } else {
            rilLibPath = libPath;
        }
    }

    /* special override when in the emulator */
#if 1
    {
        static char   arg_device[32];
        int           done = 0;

		//连接库地址:/system/lib/libreference-ril.so  
#define  REFERENCE_RIL_PATH  "/system/lib/libreference-ril.so"

        /* first, read /proc/cmdline into memory */
        char          buffer[1024], *p, *q;
        int           len;
        int           fd = open("/proc/cmdline",O_RDONLY);

        if (fd < 0) {
            RLOGD("could not open /proc/cmdline:%s", strerror(errno));
            goto OpenLib;
        }

        do {
            len = read(fd,buffer,sizeof(buffer)); }
        while (len == -1 && errno == EINTR);

        if (len < 0) {
            RLOGD("could not read /proc/cmdline:%s", strerror(errno));
            close(fd);
            goto OpenLib;
        }
        close(fd);

        if (strstr(buffer, "android.qemud=") != NULL)
        {
            /* the qemud daemon is launched after rild, so
            * give it some time to create its GSM socket
            */
            int  tries = 5;
#define  QEMUD_SOCKET_NAME    "qemud"

            while (1) {
                int  fd;

                sleep(1);

                fd = qemu_pipe_open("qemud:gsm");
                if (fd < 0) {
                    fd = socket_local_client(
                                QEMUD_SOCKET_NAME,
                                ANDROID_SOCKET_NAMESPACE_RESERVED,
                                SOCK_STREAM );
                }
                if (fd >= 0) {
                    close(fd);
                    snprintf( arg_device, sizeof(arg_device), "%s/%s",
                                ANDROID_SOCKET_DIR, QEMUD_SOCKET_NAME );

                    memset(s_argv, 0, sizeof(s_argv));
                    s_argv[1] = "-s";
                    s_argv[2] = arg_device;
                    done = 1;
                    break;
                }
                RLOGD("could not connect to %s socket: %s",
                    QEMUD_SOCKET_NAME, strerror(errno));
                if (--tries == 0)
                    break;
            }
            if (!done) {
                RLOGE("could not connect to %s socket (giving up): %s",
                    QEMUD_SOCKET_NAME, strerror(errno));
                while(1)
                    sleep(0x00ffffff);
            }
        }

        /* otherwise, try to see if we passed a device name from the kernel */
        if (!done) do {
#define  KERNEL_OPTION  "android.ril="
#define  DEV_PREFIX     "/dev/"

            p = strstr( buffer, KERNEL_OPTION );
            if (p == NULL)
                break;

            p += sizeof(KERNEL_OPTION)-1;
            q  = strpbrk( p, " \t\n\r" );
            if (q != NULL)
                *q = 0;

            snprintf( arg_device, sizeof(arg_device), DEV_PREFIX "%s", p );
            arg_device[sizeof(arg_device)-1] = 0;
            memset(s_argv, 0, sizeof(s_argv));
            s_argv[1] = "-d";
            s_argv[2] = arg_device;
            done = 1;

        } while (0);

        if (done) {
            argc = 3;
            i    = 1;
            hasLibArgs = 1;
            rilLibPath = REFERENCE_RIL_PATH;
            RLOGD("overriding with %s %s", s_argv[1], s_argv[2]);
        }
    }
OpenLib:
#endif
	//切换UID为AID_RADIO  
    switchUser();

	// 打开链接库
    dlHandle = dlopen(rilLibPath, RTLD_NOW);

    if (dlHandle == NULL) {
        RLOGE("dlopen failed: %s", dlerror());
        exit(-1);
    }

	// 开启EventLoop循环
    RIL_startEventLoop();

	// 从链接库中(也就是reference-ril.c)寻找RIL_Init函数地址  
    rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))dlsym(dlHandle, "RIL_Init");

    if (rilInit == NULL) {
        RLOGE("RIL_Init not defined or exported in %s\n", rilLibPath);
        exit(-1);
    }

    if (hasLibArgs) {
        argc = argc-i+1;
    } else {
        static char * newArgv[MAX_LIB_ARGS];
        static char args[PROPERTY_VALUE_MAX];
        property_get(LIB_ARGS_PROPERTY, args, "");
        argc = make_argv(args, s_argv);
    }

    // Make sure there's a reasonable argv[0]
    s_argv[0] = argv[0];

    if (argc >= MAX_LIB_ARGS - 2) {
        RLOGE("Max arguments are passed for rild, args count = %d", argc);
        exit(0);
    }
#ifdef QCOM_HARDWARE
    /* Client-id is a qualcomm thing */
    s_argv[argc++] = "-c";
    s_argv[argc++] = clientId;
#endif

    RLOGD("RIL_Init argc = %d clientId = %s", argc, s_argv[argc-1]);

	// 初始化过程将s_rilEnv全局变量传递给了reference,然后在reference-ril.c内部将这个值传给了s_rilenv
	// 而s_rilEnv的各个处理函数是在ril.cpp中实现的
	// 调用reference-ril.c中的RIL_Init函数进行初始化INIT,同时得到reference-ril的回调函数
    funcs = rilInit(&s_rilEnv, argc, s_argv);

#ifdef QCOM_HARDWARE
    if (funcs == NULL) {
        /* Pre-multi-client qualcomm vendor libraries won't support "-c" either, so
         * try again without it. This should only happen on ancient qcoms, so raise
         * a big fat warning
         */
        argc -= 2;
        RLOGE("============= Retrying RIL_Init without a client id. This is only required for very old versions,");
        RLOGE("============= and you're likely to have more radio breakage elsewhere!");
        funcs = rilInit(&s_rilEnv, argc, s_argv);
    }
#endif

	//注册得到的reference的回调函数
    RIL_register(funcs);

done:

    while(1) {
        // sleep(UINT32_MAX) seems to return immediately on bionic
        sleep(0x00ffffff);
    }
}