Ejemplo n.º 1
0
static int writeCtrlZ(const char *s, RILChannelCtx *p_channel)
{
	size_t cur = 0;
	size_t len = strlen(s);
	ssize_t written;

	if (p_channel->fd < 0 || p_channel->readerClosed > 0)
		return AT_ERROR_CHANNEL_CLOSED;

	RLOGD("AT> %s^Z\n", s);

	AT_DUMP(">* ", s, strlen(s));

	/* the main string */
	while (cur < len) {
		do
			written = write(p_channel->fd, s + cur, len - cur);
		while (written < 0 && errno == EINTR);

		if (written < 0)
			return AT_ERROR_GENERIC;

		cur += written;
	}

	/* the ^Z  */
	do {
		written = write(p_channel->fd, "\032", 1);
	} while ((written < 0 && errno == EINTR) || (written == 0));

	if (written < 0)
		return AT_ERROR_GENERIC;

	return 0;
}
Ejemplo n.º 2
0
static int writeTransparentMode (const char *s)
{
    size_t cur = 0;
    size_t len;
    ssize_t written;
    size_t write_len = 0;

    struct atcontext *context = get_at_context();

    ENTER;

    len = context->pdu_length;

    if (context->fd < 0 || context->readerClosed > 0) {
        EXIT;
        return AT_ERROR_CHANNEL_CLOSED;
    }

    MBMLOGD("AT> %s^Z\n", s);

    AT_DUMP( ">* ", s, strlen(s) );

    /* The main string. */
    while (cur < len) {
        do {
            usleep(AT_WRITE_DELAY);
            if ((len - cur) >= 256)
                write_len = 256;
            else
                write_len = len - cur;
            written = write (context->fd, s + cur, write_len);
        } while (written < 0 && errno == EINTR);

        if (written < 0) {
            MBMLOGE("%s, AT_ERROR_GENERIC, written=%d", __FUNCTION__, (int)written);
            EXIT;
            return AT_ERROR_GENERIC;
        }

        cur += written;
    }

    EXIT;
    return 0;
}
Ejemplo n.º 3
0
/**
 * Sends string s to the radio with a \r appended.
 * Returns AT_ERROR_* on error, 0 on success.
 *
 * This function exists because as of writing, android libc does not
 * have buffered stdio.
 */
static int writeline (const char *s)
{
    size_t cur = 0;
    size_t len;
    ssize_t written;
    char *cmd = NULL;

    struct atcontext *context = get_at_context();

    ENTER;

    if (context->fd < 0 || context->readerClosed > 0) {
        EXIT;
        return AT_ERROR_CHANNEL_CLOSED;
    }

    MBMLOGD("AT(%d)> %s\n", context->fd, s);

    AT_DUMP( ">> ", s, strlen(s) );

    len = asprintf(&cmd, "%s\r\n", s);

    /* The main string. */
    while (cur < len) {
        do {
            usleep(AT_WRITE_DELAY);
            written = write (context->fd, cmd + cur, len - cur);
        } while (written < 0 && (errno == EINTR || errno == EAGAIN));

        if (written < 0) {
            free(cmd);
            EXIT;
            return AT_ERROR_GENERIC;
        }

        cur += written;
    }

    free(cmd);

    EXIT;
    return 0;
}
Ejemplo n.º 4
0
/**
 * Sends string s to the radio with a \r appended.
 * Returns AT_ERROR_* on error, 0 on success.
 *
 * This function exists because as of writing, android libc does not
 * have buffered stdio.
 */
static int writeline (const char *s)
{
    size_t cur = 0;
    size_t len = strlen(s);
    char *cmd;
    ssize_t written;

    struct atcontext *ac = getAtContext();

    if (ac->fd < 0 || ac->readerClosed > 0) {
        return AT_ERROR_CHANNEL_CLOSED;
    }

    ALOGD("AT(%d)> %s", ac->fd, s);

    AT_DUMP( ">> ", s, strlen(s) );

    if (!(asprintf(&cmd, "%s\r", s))) {
        ALOGE("%s() Failed to allocate string", __func__);
        return AT_ERROR_GENERIC;
    }

    len++;

    /* The whole string. */
    while (cur < len) {
        do {
            written = write (ac->fd, cmd + cur, len - cur);
        } while (written < 0 && errno == EINTR);

        if (written < 0) {
            free(cmd);
            return AT_ERROR_GENERIC;
        }

        cur += written;
    }

    free(cmd);

    return 0;
}
Ejemplo n.º 5
0
static int writeCtrlZ (const char *s)
{
    size_t cur = 0;
    size_t len = strlen(s);
    ssize_t written;
    char *w;
    int ret = 0;

    if (s_fd < 0 || s_readerClosed > 0) {
        return AT_ERROR_CHANNEL_CLOSED;
    }

    LOGD("AT> %s^Z\n", s);

    AT_DUMP( ">* ", s, len );

    w = malloc(len+1);
    if (!w)
        return AT_ERROR_GENERIC;
    strcpy(w, s);
    w[len] = '\032';
    len++;

    /* the main string */
    while (cur < len) {
        do {
            written = write (s_fd, w + cur, len - cur);
        } while (written < 0 && errno == EINTR);

        if (written < 0) {
            ret = AT_ERROR_GENERIC;
            break;
        }

        cur += written;
    }
    free(w);

    return ret;
}
Ejemplo n.º 6
0
static int writeline (const char *s)
{
    size_t cur = 0;
    size_t len = strlen(s);
    ssize_t written;

    if (s_fd < 0 || s_readerClosed > 0) {
        return AT_ERROR_CHANNEL_CLOSED;
    }

    if (!is_hide)
        LOGD("AT> %s\n", s);

    AT_DUMP( ">> ", s, strlen(s) );

    /* the main string */
    while (cur < len) {
        do {
            written = write (s_fd, s + cur, len - cur);
        } while (written < 0 && errno == EINTR);

        if (written < 0) {
            return AT_ERROR_GENERIC;
        }

        cur += written;
    }

    /* the \r  */

    do {
        written = write (s_fd, "\r" , 1);
    } while ((written < 0 && errno == EINTR) || (written == 0));

    if (written < 0) {
        return AT_ERROR_GENERIC;
    }

    return 0;
}
Ejemplo n.º 7
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)) {
            LOGE("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 );
            s_readCount += 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) {
                LOGD("atchannel: EOF reached");
            } else {
                LOGD("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 */

    LOGD("AT< %s\n", ret);
    return ret;
}
Ejemplo n.º 8
0
static const char *readline(void)
{
    ssize_t count;

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

    struct atcontext *ac = getAtContext();
    read(ac->fd,NULL,0);

    /* This is a little odd. I use *s_ATBufferCur == 0 to mean
     * "buffer consumed completely". If it points to a character,
     * then the buffer continues until a \0.
     */
    if (*ac->ATBufferCur == '\0') {
        /* Empty buffer. */
        ac->ATBufferCur = ac->ATBuffer;
        *ac->ATBufferCur = '\0';
        p_read = ac->ATBuffer;
    } else {   /* *s_ATBufferCur != '\0' */
        /* There's data in the buffer from the last read. */

        /* skip over leading newlines */
        while (*ac->ATBufferCur == '\r' || *ac->ATBufferCur == '\n')
            ac->ATBufferCur++;

        p_eol = findNextEOL(ac->ATBufferCur);

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

            len = strlen(ac->ATBufferCur);

            memmove(ac->ATBuffer, ac->ATBufferCur, len + 1);
            p_read = ac->ATBuffer + len;
            ac->ATBufferCur = ac->ATBuffer;
        }
        /* Otherwise, (p_eol !- NULL) there is a complete line 
           that will be returned from the while () loop below. */
    }

    while (p_eol == NULL) {
        int err;
        struct pollfd pfds[2];

        /* This condition should be synchronized with the read function call
         * size argument below.
         */
        if (0 >= MAX_AT_RESPONSE - (p_read - ac->ATBuffer) - 2) {
            ALOGE("%s() ERROR: Input line exceeded buffer", __func__);
            /* Ditch buffer and start over again. */
            ac->ATBufferCur = ac->ATBuffer;
            *ac->ATBufferCur = '\0';
            p_read = ac->ATBuffer;
        }

        /* If our fd is invalid, we are probably closed. Return. */
        if (ac->fd < 0)
            return NULL;

        pfds[0].fd = ac->fd;
        pfds[0].events = POLLIN | POLLERR;

        pfds[1].fd = ac->readerCmdFds[0];
        pfds[1].events = POLLIN;

        err = poll(pfds, 2, -1);

        if (err < 0) {
            ALOGE("%s() poll: error: %s", __func__, strerror(errno));
            return NULL;
        }

        if (pfds[1].revents & POLLIN) {
            char buf[10];

            /* Just drain it. We don't care, this is just for waking up. */
            read(pfds[1].fd, &buf, 1);
            continue;
        }

        if (pfds[0].revents & POLLERR) {
            ALOGE("%s() POLLERR event! Returning...", __func__);
            return NULL;
        }

        if (!(pfds[0].revents & POLLIN))
            continue;

        do
            /* The size argument should be synchronized to the ditch buffer
             * condition above.
             */
            count = read(ac->fd, p_read,
                         MAX_AT_RESPONSE - (p_read - ac->ATBuffer) - 2);

        while (count < 0 && errno == EINTR);

        if (count > 0) {
            AT_DUMP( "<< ", p_read, count );
            ac->readCount += count;

            /* Implementation requires extra EOS or EOL to get it right if
             * there are no trailing newlines in the read buffer. Adding extra
             * EOS does not harm even if there actually were trailing EOLs.
             */
            p_read[count] = '\0';
            p_read[count+1] = '\0';

            /* Skip over leading newlines. */
            while (*ac->ATBufferCur == '\r' || *ac->ATBufferCur == '\n')
                ac->ATBufferCur++;

            p_eol = findNextEOL(ac->ATBufferCur);
            p_read += count;
        } else if (count <= 0) {
            /* Read error encountered or EOF reached. */
            if (count == 0)
                ALOGD("%s() atchannel: EOF reached.", __func__);
            else
                ALOGD("%s() atchannel: read error %s", __func__, strerror(errno));

            return NULL;
        }
    }

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

    ret = ac->ATBufferCur;
    *p_eol = '\0';

    /* The extra EOS added after read takes care of the case when there is no
     * valid data after p_eol.
     */
    ac->ATBufferCur = p_eol + 1;     /* This will always be <= p_read,    
                                        and there will be a \0 at *p_read. */

    ALOGI("AT(%d)< %s", ac->fd, ret);
    return ret;
}
Ejemplo n.º 9
0
static const char *readline(void)
{
    ssize_t count;

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

    struct atcontext *context = get_at_context();

    ENTER;

    read(context->fd,NULL,0);

    /* This is a little odd. I use *s_ATBufferCur == 0 to mean
     * "buffer consumed completely". If it points to a character,
     * then the buffer continues until a \0.
     */
    if (*context->ATBufferCur == '\0') {
        /* Empty buffer. */
        context->ATBufferCur = context->ATBuffer;
        *context->ATBufferCur = '\0';
        p_read = context->ATBuffer;
    } else {   /* *s_ATBufferCur != '\0' */
        /* There's data in the buffer from the last read. */

        /* skip over leading newlines */
        while (*context->ATBufferCur == '\r' || *context->ATBufferCur == '\n')
            context->ATBufferCur++;

        p_eol = findNextEOL(context->ATBufferCur);

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

            len = strlen(context->ATBufferCur);

            memmove(context->ATBuffer, context->ATBufferCur, len + 1);
            p_read = context->ATBuffer + len;
            context->ATBufferCur = context->ATBuffer;
        }
        /* Otherwise, (p_eol !- NULL) there is a complete line 
           that will be returned from the while () loop below. */
    }

    while (p_eol == NULL) {
        int err;
        struct pollfd pfds[2];

        if (0 >= MAX_AT_RESPONSE - (p_read - context->ATBuffer)) {
            MBMLOGE("%s() ERROR: Input line exceeded buffer", __FUNCTION__);
            /* Ditch buffer and start over again. */
            context->ATBufferCur = context->ATBuffer;
            *context->ATBufferCur = '\0';
            p_read = context->ATBuffer;
        }

        /* If our fd is invalid, we are probably closed. Return. */
        if (context->fd < 0) {
            EXIT;
            return NULL;
        }

        pfds[0].fd = context->fd;
        pfds[0].events = POLLIN | POLLERR;

        pfds[1].fd = context->readerCmdFds[0];
        pfds[1].events = POLLIN;

        err = poll(pfds, 2, -1);

        if (err < 0) {
            MBMLOGE("%s() poll: error: %s", __FUNCTION__, strerror(errno));
            EXIT;
            return NULL;
        }

        if (pfds[1].revents & POLLIN) {
            char buf[10];

            /* Just drain it. We don't care, this is just for waking up. */
            read(pfds[1].fd, &buf, 1);
            continue;
        }

        if (pfds[0].revents & POLLERR) {
            MBMLOGE("POLLERR! Returning..");
            EXIT;
            return NULL;
        }

        if (!(pfds[0].revents & POLLIN)) {
            continue;
        }

        do {
            count = read(context->fd, p_read,
                            MAX_AT_RESPONSE - (p_read - context->ATBuffer));
        } while (count < 0 && ((errno == EINTR) || (errno == EAGAIN)));

        if (count > 0) {
            AT_DUMP( "<< ", p_read, count );
            context->readCount += count;

            p_read[count] = '\0';

            /* Skip over leading newlines. */
            while (*context->ATBufferCur == '\r' || *context->ATBufferCur == '\n')
                context->ATBufferCur++;

            p_eol = findNextEOL(context->ATBufferCur);
            p_read += count;
        } else if (count <= 0) {
            /* Read error encountered or EOF reached. */
            if (count == 0) {
                MBMLOGE("%s() atchannel: EOF reached.", __FUNCTION__);
            } else {
                MBMLOGE("%s() atchannel: read error %s", __FUNCTION__, strerror(errno));
            }
            EXIT;
            return NULL;
        }
    }

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

    ret = context->ATBufferCur;
    *p_eol = '\0';
    context->ATBufferCur = p_eol + 1;     /* This will always be <= p_read,    
                                        and there will be a \0 at *p_read. */

    MBMLOGD("AT(%d)< %s", context->fd, ret);

    EXIT;
    return ret;
}
Ejemplo n.º 10
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");
    }
}
Ejemplo n.º 11
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");
		}
   	 }
	
}