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
-~----------~----~----~----~------~----~------~--~---