+void eDVBCAService::registerChannelCallback(eDVBResourceManager *res_mgr)
+{
+ res_mgr->connectChannelAdded(slot(&DVBChannelAdded), m_chanAddedConn);
+}
+
+void eDVBCAService::DVBChannelAdded(eDVBChannel *chan)
+{
+ if ( chan )
+ {
+ eDebug("[eDVBCAService] new channel %p!", chan);
+ channel_data *data = new channel_data();
+ data->m_channel = chan;
+ data->m_prevChannelState = -1;
+ data->m_dataDemux = -1;
+ exist_channels[chan] = data;
+ chan->connectStateChange(slot(&DVBChannelStateChanged), data->m_stateChangedConn);
+ }
+}
+
+void eDVBCAService::DVBChannelStateChanged(iDVBChannel *chan)
+{
+ ChannelMap::iterator it =
+ exist_channels.find(chan);
+ if ( it != exist_channels.end() )
+ {
+ int state=0;
+ chan->getState(state);
+ if ( it->second->m_prevChannelState != state )
+ {
+ switch (state)
+ {
+ case iDVBChannel::state_ok:
+ {
+ eDebug("[eDVBCAService] channel %p running", chan);
+ break;
+ }
+ case iDVBChannel::state_release:
+ {
+ eDebug("[eDVBCAService] remove channel %p", chan);
+ unsigned char msg[8] = { 0x9f,0x80,0x3f,0x04,0x83,0x02,0x00,0x00 };
+ msg[7] = it->second->m_dataDemux & 0xFF;
+ int sock, clilen;
+ struct sockaddr_un servaddr;
+ memset(&servaddr, 0, sizeof(struct sockaddr_un));
+ servaddr.sun_family = AF_UNIX;
+ strcpy(servaddr.sun_path, "/tmp/camd.socket");
+ clilen = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path);
+ sock = socket(PF_UNIX, SOCK_STREAM, 0);
+ if (sock > -1)
+ {
+ connect(sock, (struct sockaddr *) &servaddr, clilen);
+ fcntl(sock, F_SETFL, O_NONBLOCK);
+ int val=1;
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, 4);
+ if (write(sock, msg, 8) != 8)
+ eDebug("[eDVBCAService] write leave transponder failed!!");
+ close(sock);
+ }
+ exist_channels.erase(it);
+ delete it->second;
+ it->second=0;
+ break;
+ }
+ default: // ignore all other events
+ return;
+ }
+ if (it->second)
+ it->second->m_prevChannelState = state;
+ }
+ }
+}
+
+channel_data *eDVBCAService::getChannelData(eDVBChannelID &chid)
+{
+ for (ChannelMap::iterator it(exist_channels.begin()); it != exist_channels.end(); ++it)
+ {
+ if (chid == it->second->m_channel->getChannelID())
+ return it->second;
+ }
+ return 0;
+}
+// end static methods
+
+void eDVBCAService::socketCB(int what)
+{
+ if (what & eSocketNotifier::Read)
+ /*eDebug("[eDVBCAService] data to read\n")*/;
+ if (what & eSocketNotifier::Priority)
+ /*eDebug("[eDVBCAService] priority data to read\n")*/;
+ if (what & eSocketNotifier::Hungup) {
+ /*eDebug("[eDVBCAService] connection closed\n")*/;
+ m_sendstate=1;
+ sendCAPMT();
+ }
+ if (what & eSocketNotifier::Error)
+ /*eDebug("[eDVBCAService] connection error\n")*/;
+}
+