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 <[email protected]> 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 <[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
-~----------~----~----~----~------~----~------~--~---