I am writing some code to multiplex a GSM Modem. It is all working fine apart from one vital part, when i poll the pseudo serial ports the poll never returns.
You will notice that when the reader starts (thread body below) poll is called with just the actual serial device file descriptor first; then, once the muxed communications have been established with the modem and the channels have been opened, we poll for events on the pseudo serial devices as well.
When calling poll with just the modems serial file descriptor, it works, even when the channels are open, i can see data passed from the modem to the pseudo serial ports, but when i poll for events coming back down the pseudo serial port (as well as the modem), poll never returns, for either the modem or the pseudo devices.
void* GsmMux::Body(void)
{
struct pollfd pfd[1];
struct pollfd pfd_channels[mDLC_Max+1];
int nfd = 1;
int nfd_channels = mDLC_Max+1; // Plus control channel
int timeout = -1;
// Initialise the pollfd array
pfd_channels[0].fd = pfd[0].fd = mSerial.fd;
pfd_channels[0].events = pfd[0].events = POLLIN;
pfd_channels[0].revents = pfd[0].revents = NULL;
bool openedChannels = false;
while(mMuxing)
{
// If the control channel is open, then the device channels
// are also open and we need to start listening for data on them.
if(!openedChannels && mChannelList[0].opened)
{
for(int i = 1; i <= mDLC_Max; i++)
{
if(mChannelList[i].fd != -1)
{
pfd_channels[i].fd = mChannelList[i].fd;
pfd_channels[i].events = POLLIN;
pfd_channels[i].revents = NULL;
nfd++;
}
}
openedChannels = true;
}
int events = 0;
if ((events = poll( openedChannels ? pfd_channels : pfd,
openedChannels ? nfd_channels : nfd,
timeout)) > 0)
{
// Make sure we cover all events
for(int i = 0; i < events; i++)
{ // Find the event fd
int b = 0; // channel
for(; b < mDLC_Max; b++)
{
if(pfd[b].revents != 0)
{
break;
}
}
// Read appropriate device. Channel 0 data, indicates
// that data is coming from the actual serial device.
// Other channels indicates data coming from the pseudo devices.
if((pfd[b].revents & POLLIN) && b == 0)
this->SerialDeviceRead();
elseif((pfd[b].revents & POLLIN) && b < mDLC_Max)
this->PseudoDeviceRead(b); // Shift the channel pointer as 0 is the control channel
// Handled event
pfd[b].revents = NULL;
}
}
}
return 0;
}
If anyone knows why this could be happening, please let me know.