mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-neutrino.git
synced 2025-08-26 23:13:00 +02:00
Origin commit data
------------------
Commit: af3abc9b8e
Author: Markus Volk <f_l_k@t-online.de>
Date: 2020-01-30 (Thu, 30 Jan 2020)
550 lines
16 KiB
C++
550 lines
16 KiB
C++
/*
|
||
Timer Daemon - DBoxII-Project
|
||
|
||
Copyright (C) 2002 Dirk Szymanski 'Dirch'
|
||
|
||
$Id: timerdclient.cpp,v 1.55 2007/10/09 20:46:05 guenther Exp $
|
||
|
||
License: GPL
|
||
|
||
This program is free software; you can redistribute it and/or modify
|
||
it under the terms of the GNU General Public License as published by
|
||
the Free Software Foundation; either version 2 of the License, or
|
||
(at your option) any later version.
|
||
|
||
This program is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU General Public License for more details.
|
||
|
||
You should have received a copy of the GNU General Public License
|
||
along with this program; if not, write to the Free Software
|
||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||
*/
|
||
|
||
#include <string.h>
|
||
|
||
#include <eventserver.h>
|
||
#include <timerdclient/timerdmsg.h>
|
||
#include <timerdclient/timerdclient.h>
|
||
|
||
#ifdef PEDANTIC_VALGRIND_SETUP
|
||
#define VALGRIND_PARANOIA(x) memset(&x, 0, sizeof(x))
|
||
#else
|
||
#define VALGRIND_PARANOIA(x) {}
|
||
#endif
|
||
|
||
//int CTimerdClient::adzap_eventID = 0;
|
||
|
||
unsigned char CTimerdClient::getVersion () const
|
||
{
|
||
return CTimerdMsg::ACTVERSION;
|
||
}
|
||
|
||
const char * CTimerdClient::getSocketName() const
|
||
{
|
||
return TIMERD_UDS_NAME;
|
||
}
|
||
|
||
//-------------------------------------------------------------------------
|
||
|
||
void CTimerdClient::registerEvent(unsigned int eventID, unsigned int clientID, const char * const udsName)
|
||
{
|
||
CEventServer::commandRegisterEvent msg2;
|
||
VALGRIND_PARANOIA(msg2);
|
||
|
||
msg2.eventID = eventID;
|
||
msg2.clientID = clientID;
|
||
|
||
strcpy(msg2.udsName, udsName);
|
||
|
||
send(CTimerdMsg::CMD_REGISTEREVENT, (char*)&msg2, sizeof(msg2));
|
||
|
||
close_connection();
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
|
||
void CTimerdClient::unRegisterEvent(unsigned int eventID, unsigned int clientID)
|
||
{
|
||
CEventServer::commandUnRegisterEvent msg2;
|
||
VALGRIND_PARANOIA(msg2);
|
||
|
||
msg2.eventID = eventID;
|
||
msg2.clientID = clientID;
|
||
|
||
send(CTimerdMsg::CMD_UNREGISTEREVENT, (char*)&msg2, sizeof(msg2));
|
||
|
||
close_connection();
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
|
||
int CTimerdClient::setSleeptimer(time_t announcetime, time_t alarmtime, int timerid)
|
||
{
|
||
int timerID;
|
||
|
||
if(timerid == 0)
|
||
timerID = getSleeptimerID();
|
||
else
|
||
timerID = timerid;
|
||
|
||
if(timerID != 0)
|
||
{
|
||
modifyTimerEvent(timerID, announcetime, alarmtime, 0);
|
||
}
|
||
else
|
||
{
|
||
timerID = addTimerEvent(CTimerd::TIMER_SLEEPTIMER,NULL,announcetime,alarmtime,0);
|
||
}
|
||
|
||
return timerID;
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
|
||
int CTimerdClient::getSleeptimerID()
|
||
{
|
||
send(CTimerdMsg::CMD_GETSLEEPTIMER);
|
||
CTimerdMsg::responseGetSleeptimer response;
|
||
if(!receive_data((char*)&response, sizeof(CTimerdMsg::responseGetSleeptimer)))
|
||
response.eventID =0;
|
||
close_connection();
|
||
return response.eventID;
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
|
||
int CTimerdClient::getSleepTimerRemaining()
|
||
{
|
||
int timerID;
|
||
if((timerID = getSleeptimerID()) != 0)
|
||
{
|
||
CTimerd::responseGetTimer timer;
|
||
getTimer( timer, timerID);
|
||
int min=(((timer.alarmTime + 1 - time(NULL)) / 60)+1); //aufrunden auf n<>chst gr<67><72>erere Min.
|
||
if(min <1)
|
||
min=1;
|
||
return min;
|
||
}
|
||
else
|
||
return 0;
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
|
||
void CTimerdClient::getTimerList(CTimerd::TimerList &timerlist)
|
||
{
|
||
CTimerdMsg::generalInteger responseInteger;
|
||
CTimerd::responseGetTimer response;
|
||
|
||
send(CTimerdMsg::CMD_GETTIMERLIST);
|
||
|
||
timerlist.clear();
|
||
|
||
if (CBasicClient::receive_data((char* )&responseInteger, sizeof(responseInteger)))
|
||
{
|
||
while (responseInteger.number-- > 0)
|
||
{
|
||
if (CBasicClient::receive_data((char*)&response, sizeof(response)))
|
||
if (response.eventState != CTimerd::TIMERSTATE_TERMINATED)
|
||
timerlist.push_back(response);
|
||
};
|
||
}
|
||
|
||
close_connection();
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
|
||
void CTimerdClient::getTimer( CTimerd::responseGetTimer &timer, unsigned timerID)
|
||
{
|
||
send(CTimerdMsg::CMD_GETTIMER, (char*)&timerID, sizeof(timerID));
|
||
|
||
CTimerd::responseGetTimer response;
|
||
receive_data((char*)&response, sizeof(CTimerd::responseGetTimer));
|
||
timer = response;
|
||
close_connection();
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
|
||
|
||
bool CTimerdClient::modifyTimerEvent(int eventid, time_t announcetime, time_t alarmtime, time_t stoptime, CTimerd::CTimerEventRepeat evrepeat, uint32_t repeatcount)
|
||
{
|
||
return modifyTimerEvent(eventid,announcetime,alarmtime,stoptime,evrepeat,repeatcount,NULL);
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
|
||
bool CTimerdClient::modifyTimerEvent(int eventid, time_t announcetime, time_t alarmtime, time_t stoptime, CTimerd::CTimerEventRepeat evrepeat, uint32_t repeatcount, void *data,
|
||
int datalen)
|
||
{
|
||
// set new time values for event eventid
|
||
|
||
CTimerdMsg::commandModifyTimer msgModifyTimer;
|
||
VALGRIND_PARANOIA(msgModifyTimer);
|
||
msgModifyTimer.eventID = eventid;
|
||
msgModifyTimer.announceTime = announcetime;
|
||
msgModifyTimer.alarmTime = alarmtime;
|
||
msgModifyTimer.stopTime = stoptime;
|
||
msgModifyTimer.eventRepeat = evrepeat;
|
||
msgModifyTimer.repeatCount = repeatcount;
|
||
send(CTimerdMsg::CMD_MODIFYTIMER, (char*) &msgModifyTimer, sizeof(msgModifyTimer));
|
||
|
||
if (data && datalen)
|
||
send_data((char*)data,datalen);
|
||
|
||
CTimerdMsg::responseStatus response;
|
||
receive_data((char*)&response, sizeof(response));
|
||
|
||
close_connection();
|
||
return true;
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
|
||
bool CTimerdClient::modifyRecordTimerEvent(int eventid, time_t announcetime, time_t alarmtime, time_t stoptime, CTimerd::CTimerEventRepeat evrepeat, uint32_t repeatcount,
|
||
const char * const recordingdir)
|
||
{
|
||
CTimerdMsg::commandRecordDir rdir;
|
||
strncpy(rdir.recDir,recordingdir,RECORD_DIR_MAXLEN-1);
|
||
return modifyTimerEvent(eventid,announcetime,alarmtime,stoptime,evrepeat,repeatcount,&rdir,sizeof(rdir));
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
|
||
bool CTimerdClient::rescheduleTimerEvent(int eventid, time_t diff)
|
||
{
|
||
rescheduleTimerEvent(eventid,diff,diff,diff);
|
||
return true;
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
|
||
bool CTimerdClient::rescheduleTimerEvent(int eventid, time_t announcediff, time_t alarmdiff, time_t stopdiff)
|
||
{
|
||
CTimerdMsg::commandModifyTimer msgModifyTimer;
|
||
VALGRIND_PARANOIA(msgModifyTimer);
|
||
msgModifyTimer.eventID = eventid;
|
||
msgModifyTimer.announceTime = announcediff;
|
||
msgModifyTimer.alarmTime = alarmdiff;
|
||
msgModifyTimer.stopTime = stopdiff;
|
||
|
||
send(CTimerdMsg::CMD_RESCHEDULETIMER, (char*) &msgModifyTimer, sizeof(msgModifyTimer));
|
||
|
||
CTimerdMsg::responseStatus response;
|
||
receive_data((char*)&response, sizeof(response));
|
||
|
||
close_connection();
|
||
return response.status;
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
|
||
/*
|
||
int CTimerdClient::addTimerEvent( CTimerEventTypes evType, void* data , int min, int hour, int day, int month, CTimerd::CTimerEventRepeat evrepeat)
|
||
{
|
||
time_t actTime_t;
|
||
time(&actTime_t);
|
||
struct tm* actTime = localtime(&actTime_t);
|
||
|
||
actTime->tm_min = min;
|
||
actTime->tm_hour = hour;
|
||
|
||
if (day > 0)
|
||
actTime->tm_mday = day;
|
||
if (month > 0)
|
||
actTime->tm_mon = month -1;
|
||
|
||
addTimerEvent(evType,true,data,0,mktime(actTime),0);
|
||
}
|
||
*/
|
||
bool CTimerdClient::checkDouble(CTimerd::CTimerEventTypes evType, void* data, time_t announcetime, time_t alarmtime,time_t stoptime,
|
||
CTimerd::CTimerEventRepeat evrepeat, uint32_t repeatcount)
|
||
{
|
||
if (evType != CTimerd::TIMER_RECORD && evType != CTimerd::TIMER_ZAPTO)
|
||
return false;//skip check not zap and record timer
|
||
|
||
CTimerd::TimerList timerlist;
|
||
getTimerList(timerlist);
|
||
for (CTimerd::TimerList::iterator it = timerlist.begin(); it != timerlist.end();++it)
|
||
{
|
||
if ( (it->eventType == CTimerd::TIMER_RECORD || it->eventType == CTimerd::TIMER_ZAPTO ) &&
|
||
(it->alarmTime == alarmtime && it->announceTime == announcetime && it->stopTime == stoptime && it->eventRepeat == evrepeat && it->repeatCount == repeatcount ) )
|
||
{
|
||
if( it->eventType == CTimerd::TIMER_ZAPTO )
|
||
{
|
||
CTimerd::EventInfo *ei=static_cast<CTimerd::EventInfo*>(data);
|
||
if( ei->channel_id == it->channel_id )
|
||
{
|
||
if(( ei->epg_id != 0 && ei->epg_id != it->epg_id ) || ( ei->epg_starttime != 0 && it->epg_starttime != ei->epg_starttime) )
|
||
{
|
||
return false;//not double
|
||
}
|
||
return true;
|
||
}
|
||
}
|
||
else if(it->eventType == CTimerd::TIMER_RECORD)
|
||
{
|
||
CTimerd::RecordingInfo *ri=static_cast<CTimerd::RecordingInfo*>(data);
|
||
if(ri->channel_id == it->channel_id && ri->apids == it->apids && !strncmp(ri->recordingDir, it->recordingDir, RECORD_DIR_MAXLEN-1) )
|
||
{
|
||
if( ( ri->epg_id != 0 && ri->epg_id != it->epg_id ) || ( ri->epg_starttime != 0 && it->epg_starttime != ri->epg_starttime) )
|
||
{
|
||
return false;//not double
|
||
}
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return false;//not double
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
int CTimerdClient::addTimerEvent( CTimerd::CTimerEventTypes evType, void* data, time_t announcetime, time_t alarmtime,time_t stoptime,
|
||
CTimerd::CTimerEventRepeat evrepeat, uint32_t repeatcount,bool forceadd)
|
||
{
|
||
if(checkDouble(evType, data, announcetime, alarmtime, stoptime, evrepeat, repeatcount))//check if timer is add double
|
||
return -1;
|
||
|
||
if (!forceadd)
|
||
{
|
||
//printf("[CTimerdClient] checking for overlapping timers\n");
|
||
CTimerd::TimerList overlappingTimer;
|
||
overlappingTimer = getOverlappingTimers(alarmtime, stoptime);
|
||
if (!overlappingTimer.empty())
|
||
{
|
||
// timerd starts eventID at 0 so we can return -1
|
||
return -1;
|
||
}
|
||
}
|
||
CTimerd::TransferEventInfo tei;
|
||
CTimerd::TransferRecordingInfo tri;
|
||
CTimerdMsg::commandAddTimer msgAddTimer;
|
||
VALGRIND_PARANOIA(tei);
|
||
VALGRIND_PARANOIA(tri);
|
||
VALGRIND_PARANOIA(msgAddTimer);
|
||
msgAddTimer.alarmTime = alarmtime;
|
||
msgAddTimer.announceTime = announcetime;
|
||
msgAddTimer.stopTime = stoptime;
|
||
msgAddTimer.eventType = evType;
|
||
msgAddTimer.eventRepeat = evrepeat;
|
||
msgAddTimer.repeatCount = repeatcount;
|
||
int length;
|
||
if( evType == CTimerd::TIMER_SHUTDOWN || evType == CTimerd::TIMER_SLEEPTIMER )
|
||
{
|
||
length = 0;
|
||
}
|
||
/* else if(evType == CTimerd::TIMER_NEXTPROGRAM || evType == CTimerd::TIMER_ZAPTO || */
|
||
else if (evType == CTimerd::TIMER_ZAPTO ||
|
||
evType == CTimerd::TIMER_IMMEDIATE_RECORD)
|
||
{
|
||
CTimerd::EventInfo *ei=static_cast<CTimerd::EventInfo*>(data);
|
||
tei.apids = ei->apids;
|
||
tei.channel_id = ei->channel_id;
|
||
tei.epg_starttime = ei->epg_starttime;
|
||
tei.epg_id = ei->epg_id;
|
||
tei.recordingSafety = ei->recordingSafety;
|
||
length = sizeof( CTimerd::TransferEventInfo);
|
||
data = &tei;
|
||
}
|
||
else if(evType == CTimerd::TIMER_RECORD)
|
||
{
|
||
CTimerd::RecordingInfo *ri=static_cast<CTimerd::RecordingInfo*>(data);
|
||
tri.apids = ri->apids;
|
||
tri.channel_id = ri->channel_id;
|
||
tri.epg_starttime = ri->epg_starttime;
|
||
tri.epg_id = ri->epg_id;
|
||
tri.recordingSafety = ri->recordingSafety;
|
||
tri.autoAdjustToEPG = ri->autoAdjustToEPG;
|
||
tri.channel_ci = ri->channel_ci; //NI
|
||
strncpy(tri.recordingDir, ri->recordingDir, RECORD_DIR_MAXLEN);
|
||
length = sizeof( CTimerd::TransferRecordingInfo);
|
||
data = &tri;
|
||
}
|
||
else if(evType == CTimerd::TIMER_STANDBY)
|
||
{
|
||
length = sizeof(CTimerdMsg::commandSetStandby);
|
||
}
|
||
else if(evType == CTimerd::TIMER_REMIND)
|
||
{
|
||
length = sizeof(CTimerdMsg::commandRemind);
|
||
}
|
||
else if(evType == CTimerd::TIMER_EXEC_PLUGIN)
|
||
{
|
||
length = sizeof(CTimerdMsg::commandExecPlugin);
|
||
}
|
||
else
|
||
{
|
||
length = 0;
|
||
}
|
||
|
||
send(CTimerdMsg::CMD_ADDTIMER, (char*)&msgAddTimer, sizeof(msgAddTimer));
|
||
|
||
if((data != NULL) && (length > 0))
|
||
send_data((char*)data, length);
|
||
|
||
CTimerdMsg::responseAddTimer response;
|
||
receive_data((char*)&response, sizeof(response));
|
||
close_connection();
|
||
|
||
return( response.eventID);
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
|
||
void CTimerdClient::removeTimerEvent( int evId)
|
||
{
|
||
CTimerdMsg::commandRemoveTimer msgRemoveTimer;
|
||
VALGRIND_PARANOIA(msgRemoveTimer);
|
||
|
||
msgRemoveTimer.eventID = evId;
|
||
|
||
send(CTimerdMsg::CMD_REMOVETIMER, (char*) &msgRemoveTimer, sizeof(msgRemoveTimer));
|
||
|
||
close_connection();
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
|
||
bool CTimerdClient::isTimerdAvailable()
|
||
{
|
||
if(!send(CTimerdMsg::CMD_TIMERDAVAILABLE))
|
||
return false;
|
||
|
||
CTimerdMsg::responseAvailable response;
|
||
bool ret=receive_data((char*)&response, sizeof(response));
|
||
close_connection();
|
||
return ret;
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
|
||
CTimerd::TimerList CTimerdClient::getOverlappingTimers(time_t& startTime, time_t& stopTime)
|
||
{
|
||
CTimerd::TimerList timerlist;
|
||
CTimerd::TimerList overlapping;
|
||
int timerPre;
|
||
int timerPost;
|
||
|
||
getTimerList(timerlist);
|
||
getRecordingSafety(timerPre,timerPost);
|
||
|
||
for (CTimerd::TimerList::iterator it = timerlist.begin();
|
||
it != timerlist.end();++it)
|
||
{
|
||
if(it->stopTime != 0 && stopTime != 0)
|
||
{
|
||
// Check if both timers have start and end. In this case do not show conflict, if endtime is the same than the starttime of the following timer
|
||
if ((stopTime+timerPost > it->alarmTime) && (startTime-timerPre < it->stopTime))
|
||
{
|
||
overlapping.push_back(*it);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (!((stopTime < it->announceTime) || (startTime > it->stopTime)))
|
||
{
|
||
overlapping.push_back(*it);
|
||
}
|
||
}
|
||
}
|
||
return overlapping;
|
||
}
|
||
|
||
//-------------------------------------------------------------------------
|
||
|
||
bool CTimerdClient::shutdown()
|
||
{
|
||
send(CTimerdMsg::CMD_SHUTDOWN);
|
||
|
||
CTimerdMsg::responseStatus response;
|
||
receive_data((char*)&response, sizeof(response));
|
||
|
||
close_connection();
|
||
return response.status;
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
void CTimerdClient::modifyTimerAPid(int eventid, unsigned char apids)
|
||
{
|
||
CTimerdMsg::commandSetAPid data;
|
||
VALGRIND_PARANOIA(data);
|
||
data.eventID=eventid;
|
||
data.apids = apids;
|
||
send(CTimerdMsg::CMD_SETAPID, (char*) &data, sizeof(data));
|
||
close_connection();
|
||
}
|
||
|
||
//-------------------------------------------------------------------------
|
||
void CTimerdClient::setRecordingSafety(int pre, int post)
|
||
{
|
||
CTimerdMsg::commandRecordingSafety data;
|
||
VALGRIND_PARANOIA(data);
|
||
data.pre = pre;
|
||
data.post = post;
|
||
send(CTimerdMsg::CMD_SETRECSAFETY, (char*) &data, sizeof(data));
|
||
close_connection();
|
||
}
|
||
|
||
//-------------------------------------------------------------------------
|
||
void CTimerdClient::getRecordingSafety(int &pre, int &post)
|
||
{
|
||
send(CTimerdMsg::CMD_GETRECSAFETY);
|
||
CTimerdMsg::commandRecordingSafety data;
|
||
|
||
bool success = receive_data((char*)&data, sizeof(data));
|
||
close_connection();
|
||
if (success)
|
||
{
|
||
pre = data.pre;
|
||
post = data.post;
|
||
}
|
||
else
|
||
{
|
||
/* fill with default values (cf. timermanager.cpp) */
|
||
pre = 0;
|
||
post = 0;
|
||
}
|
||
}
|
||
|
||
//-------------------------------------------------------------------------
|
||
//void CTimerdClient::getWeekdaysFromStr(int *rep, const char* str)
|
||
void CTimerdClient::getWeekdaysFromStr(CTimerd::CTimerEventRepeat *eventRepeat, std::string &str)
|
||
{
|
||
if (str.length() < 7)
|
||
str.append(7 - str.length(), '-');
|
||
int rep = (int) *eventRepeat;
|
||
if(rep >= (int)CTimerd::TIMERREPEAT_WEEKDAYS)
|
||
{
|
||
for(int n=0;n<7;n++)
|
||
{
|
||
if(str[n]=='X' || str[n]=='x')
|
||
{
|
||
rep |= (1 << (n+9));
|
||
}
|
||
else
|
||
{
|
||
rep &= (~(1 << (n+9)));
|
||
}
|
||
}
|
||
}
|
||
*eventRepeat = (CTimerd::CTimerEventRepeat) rep;
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
void CTimerdClient::setWeekdaysToStr(CTimerd::CTimerEventRepeat rep, std::string &str)
|
||
{
|
||
if (str.length() < 7)
|
||
str.append(7 - str.length(), '-');
|
||
if(rep >= CTimerd::TIMERREPEAT_WEEKDAYS)
|
||
{
|
||
for(int n=0;n<7;n++)
|
||
{
|
||
if(rep & (1 << (n+9)))
|
||
str.at(n)='X';
|
||
else
|
||
str.at(n)='-';
|
||
}
|
||
}
|
||
else
|
||
str = "-------";
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
void CTimerdClient::stopTimerEvent( int evId)
|
||
{
|
||
CTimerdMsg::commandRemoveTimer msgRemoveTimer;
|
||
VALGRIND_PARANOIA(msgRemoveTimer);
|
||
|
||
msgRemoveTimer.eventID = evId;
|
||
|
||
send(CTimerdMsg::CMD_STOPTIMER, (char*) &msgRemoveTimer, sizeof(msgRemoveTimer));
|
||
|
||
close_connection();
|
||
}
|
||
|