solved it.. apparently system_server was closing the master/original
fd every time there is a request for the fd from a process which
utilizes sensor manager.

if (ctl->fd < 0)
{
    ctl->fd = open_sensors_phy();
}

inside the

static int control__open_data_source(struct sensors_control_device_t
*dev)

function was causing it to not open the physical sensor again if it
the fd was set. When the system_server closes the master fd after the
first request, the ctl->fd value still stays the same. It should
probably to changed to check whether the fd is still open. What I did
was just remove the if conditional.

ctl->fd = open_sensors_phy();

just that works great.

On Aug 20, 8:50 am, Ke <keke...@gmail.com> wrote:
> 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 <keke...@gmail.com> 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: android-porting+unsubscr...@googlegroups.com
website: http://groups.google.com/group/android-porting
-~----------~----~----~----~------~----~------~--~---

Reply via email to