Some code snippets,
Seem to have trouble getting a valid fd the second time around.

I suspect I am doing something wrong with dupping the fd or not using
select properly in the data__poll function.

Code:

static int
control__open_data_source(struct sensors_control_device_t *dev)
{
    if (control_fd[CONTROL_READ] == -1 || control_fd[CONTROL_WRITE] ==
-1)
    {
        // create socket pair for inter-process communication
        if ( socketpair( AF_LOCAL, SOCK_STREAM, 0, control_fd) < 0 )
        {
            E("Could not create thread control socket pair: %s",
                 strerror(errno));
            return -1;
        }
    }

    SensorControl*  ctl = (void*)dev;
    if (ctl->fd < 0)
    {
        ctl->fd = open_sensors_phy();
    }

    D("%s: fd=%d", __FUNCTION__, ctl->fd);

    return ctl->fd;
}

static int
data__sensors_open(struct sensors_data_device_t *dev, int fd)
{
    SensorData*  data = (void*)dev;
    int i;
    D("%s: dev=%p fd=%d", __FUNCTION__, dev, fd);
    memset(&data->sensors, 0, sizeof(data->sensors));

    for (i=0 ; i<MAX_NUM_SENSORS ; i++) {
        data->sensors[i].vector.status = SENSOR_STATUS_ACCURACY_HIGH;
    }
    data->pendingSensors = 0;
    data->timeStart      = 0;
    data->timeOffset     = 0;
    data->events_fd      = 0;

    int newfd = dup(fd);
    if (newfd < 0)
    {
        D("%s: Error dupping fd: \n errorno = %d \n errormsg =  %s",
            __FUNCTION__, errno, strerror(errno));
    }
    else
    {
        data->events_fd = newfd;
    }

    D("New dupped fd: %d", data->events_fd);

    return 0;
}

static int
data__poll(struct sensors_data_device_t *dev, sensors_data_t* values)
{
    SensorData*  data = (void*)dev;
    int result = 0;

    D("%s: data=%p", __FUNCTION__, dev);

    // there are pending sensors, returns them now...
    if (data->pendingSensors) {
        return pick_sensor(data, values);
    }

    //set up socket multiplexing
    fd_set rfds;
    int nfds;
    int available_fds;

    //initialize the read file descriptors
    FD_ZERO(&rfds);
    FD_SET(data->events_fd, &rfds);
    FD_SET(control_fd[CONTROL_READ], &rfds);

    //nfds - The highest file descriptor in all given sets plus one
    if (data->events_fd > control_fd[CONTROL_READ])
        nfds = data->events_fd + 1;
    else
        nfds = control_fd[CONTROL_READ] + 1;

    //initialize buffers
    char buf[512];
    memset(buf, 0, sizeof(buf));
    unsigned int bufPos = 0;

    D("%s: Beginning loop to read a sentence.", __FUNCTION__);
    while (1)
    {
        //wait file descriptors to become avail for read operation,
        //return immediately, we want this behavior since we are
polling
        available_fds = select(nfds, &rfds, NULL, NULL, 0);

        if (available_fds < 0)
        {
            D("%s: Error occurred with select(): \n errorno = %d \n
errormsg =  %s",
                __FUNCTION__, errno, strerror(errno));
            break; //error occurred
        }

        //lets read control messages first from control fd
        if (FD_ISSET(control_fd[CONTROL_READ], &rfds))
        {
            D("%s: Checking for Control Message", __FUNCTION__);
            char buff;
            read(control_fd[CONTROL_READ], &buff, sizeof(buff));
            D("%s: Control Char: 0x%02X", __FUNCTION__, buff);

            if (buff == WAKE_SOURCE)
            {
                FD_ZERO(&rfds);
                D("%s: WAKE Called", __FUNCTION__);
                return -EWOULDBLOCK;
            }
        }

        if (FD_ISSET(data->events_fd, &rfds))
        {
            /* Example output line = 73 chars (72 + \n)
            /
$C34.2P-3.8R-39.3T22.6Mx-158.67My219.46Mz31.85Ax-0.069Ay-0.650Az0.792*0F
            */

            D("%s: Reading from serial fd: %d", __FUNCTION__, data-
>events_fd);
            int nchars;
            do {
                //-1 to make room for '\0'
                nchars = read( data->events_fd, buf + bufPos, sizeof
(buf)-bufPos-1 );
            } while (nchars < 0 && errno == EINTR);

            if (nchars < 0)
            {
                D("%s: Error reading from serial: \n errorno = %d \n
errormsg =  %s",
                __FUNCTION__, errno, strerror(errno));
            }
            else
            {
                D("%s: Num of chars read: %d", __FUNCTION__, nchars);
            }

            if (nchars > 0)
            {
                bufPos = bufPos + nchars;
            }

            //do we need to need to reset buffer?
            if (bufPos >= (sizeof(buf)-1))
            {
                //null terminate
                buf[sizeof(buf)-1] = '\0';

                D("%s: Buffer Reset, bad sentence data: %s",
__FUNCTION__, buf);
                //should never happen...
                //need to reset, we are out of buffer
                memset(buf, 0, sizeof(buf));
                bufPos = 0;
            }

            //do we have a full data sentence?
            if (contains_full_sentence(buf))
            {
                //...process sentence
                //break out of while to return if necessary
            }
        } //end FD_ISSET

        usleep(100000);

    } //end while(1)

    return result;
}

On Aug 18, 6:33 pm, Ke <[email protected]> wrote:
> I am in the process of writing the sensor glue for the os4000-t
> digital compass/accel device. This reports nmea style string via TTL.
>
> I have modeled my file after sensors_qemu.c example.
>
> I have it working partially. The first process which tries to use
> SensorManager is able to receive orientation updates. Any processes
> launched afterward are not.
>
> I believe I have traced it to the "open_data_source" and "data_open"
> functions.
>
> It seems that the "data_open" function is not receiving the FD that
> "open_data_source" retrieves. From my logs, it seems that
> "open_data_source" is actually called from the first process (system
> screen orientation) when the second process (android app) tries to
> open sensor up for polling. data_open is invoked under the pid of the
> second process but it does not receive the right FD.
>
> I assumed that:
> int (*data_open)(struct sensors_data_device_t *dev, int fd);
>
> the fd there would be from:
> int (*open_data_source)(struct sensors_control_device_t *dev);
>
> but it is not happening.
>
> As I mentioned, the first app, whether it be the system screen
> orientation manager (when enabled) or a standalone app which utilizies
> SensorManager, everything works great. If I try to relaunch the app
> (since it would be under different PID) it isn't able to obtain valid
> FD to talk to the device.
>
> If you have any experience with writing the sensors.c glue for any
> devices, would greatly appreciate any hints or tips.
--~--~---------~--~----~------------~-------~--~----~
unsubscribe: [email protected]
website: http://groups.google.com/group/android-porting
-~----------~----~----~----~------~----~------~--~---

Reply via email to