54 #ifdef INTEGRATE_HBBTV 72 extern void LogDateTime();
81 #define FUNCTION_START(X) STB_SPDebugWrite(">> %s\n", #X) 83 #ifdef FUNCTION_FINISH 84 #undef FUNCTION_FINISH 86 #define FUNCTION_FINISH(X) STB_SPDebugWrite("<< %s\n", #X) 91 #define TMR_DBG(x) STB_SPDebugWrite x 98 #define TMR_PVR_DBG(x) STB_SPDebugWrite x 100 #define TMR_PVR_DBG(x) 105 #define EVENT_DURATION_OVERRUN (2 * 60 * 60) 106 #define NORDIG_EVENT_DURATION_OVERRUN (4 * 60 * 60) 121 BOOLEAN is_recommendation;
122 BOOLEAN do_not_delete;
123 U8BIT prog_crid[TMR_PVR_CRID_LEN_MAX];
124 U8BIT other_crid[TMR_PVR_CRID_LEN_MAX];
130 static void *alt_event_queue;
134 static BOOLEAN DeleteTimer(U32BIT handle);
138 static void AlternateEventTask(
void *param);
140 static void TimerTask(
void *param);
141 static BOOLEAN StartRecordTimer(
ADB_TIMER_REC *timer, BOOLEAN recordings_can_start, BOOLEAN *start_record);
142 static BOOLEAN HasTimerExpired(U32BIT handle);
149 static void GetActualStartEndTime(U32DHMS timer_start, U32DHMS timer_duration, S32BIT start_padding, S32BIT end_padding,
150 U32DHMS *start_time, U32DHMS *end_time);
152 static U8BIT GetNumSimultaneousRecordings(U32BIT handle, U16BIT onet_id, U16BIT trans_id,
153 U16BIT serv_id, U8BIT max_recordings, U32DHMS start_date_time,
154 U32DHMS end_date_time, BOOLEAN include_start_padding, BOOLEAN include_end_padding,
155 U32BIT **conflicting_timers);
156 static BOOLEAN SetStartPadding(
ADB_TIMER_REC *timer, S32BIT padding);
158 static BOOLEAN SetEndPadding(
ADB_TIMER_REC *timer, S32BIT padding);
172 TMR_DBG((
"ATMR_Initialise"));
197 handle = INVALID_TIMER_HANDLE;
199 if ((info != NULL) && ((info->type == TIMER_TYPE_ALARM) || (info->type == TIMER_TYPE_SLEEP) ||
200 (info->type == TIMER_TYPE_PVR_RECORD) || (info->type == TIMER_TYPE_PRIVATE)))
207 SetTimerFields(timer, info);
209 if (timer->type == TIMER_TYPE_PVR_RECORD)
211 #ifdef INTEGRATE_HBBTV 214 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_APPLICATION, EV_PVR_BOOKING_CREATED,
215 (
void *)&timer->handle,
sizeof(timer->handle));
220 timer->u.record.service_id);
224 if (timer->dba_rec != NULL)
229 handle = timer->handle;
263 handle = INVALID_TIMER_HANDLE;
265 if ((event_ptr != NULL) && (serv_ptr != NULL))
267 memset(&info, 0,
sizeof(info));
269 info.frequency = TIMER_FREQ_ONCE;
276 memcpy(info.name,
string, str_len);
281 memcpy(info.name,
string, TMR_MAX_NAME_LENGTH);
282 info.name[TMR_MAX_NAME_LENGTH - 1] =
'\0';
292 info.type = TIMER_TYPE_PVR_RECORD;
294 info.u.record.service_id = serv_id;
295 info.u.record.transport_id = trans_id;
296 info.u.record.orig_net_id = onet_id;
298 info.u.record.start_padding = 0;
299 info.u.record.end_padding = 0;
301 info.u.record.event_triggered = event_triggered;
312 info.type = TIMER_TYPE_ALARM;
313 info.u.alarm.service_id = serv_id;
314 info.u.alarm.transport_id = trans_id;
315 info.u.alarm.orig_net_id = onet_id;
336 U32DHMS old_duration;
345 if (((timer =
DBDEF_FindTimerRec(handle)) != NULL) && (timer->type == TIMER_TYPE_PVR_RECORD))
347 if (timer->dba_rec != NULL)
357 old_duration = timer->u.record.duration;
360 if (old_duration < duration)
364 timer->u.record.duration =
STB_GCCalculateDHMS(timer->u.record.duration, time_diff, CALC_ADD);
370 timer->u.record.duration =
STB_GCCalculateDHMS(timer->u.record.duration, time_diff, CALC_SUB);
373 if (timer->dba_rec != NULL)
405 if ((info != NULL) && ((info->type == TIMER_TYPE_ALARM) || (info->type == TIMER_TYPE_SLEEP) ||
406 (info->type == TIMER_TYPE_PVR_RECORD) || (info->type == TIMER_TYPE_PRIVATE)))
413 SetTimerFields(timer, info);
415 if (timer->dba_rec != NULL)
438 BOOLEAN timer_deleted;
447 timer_deleted = DeleteTimer(handle);
451 timer_deleted = FALSE;
458 return(timer_deleted);
471 BOOLEAN date_time_order)
474 U16BIT list_size, index;
490 if ((list_type == TIMER_TYPE_ALL) || (timer->type == list_type))
499 if (*timer_list == NULL)
506 *list_size_ptr = list_size;
511 if ((list_type == TIMER_TYPE_ALL) || (timer->type == list_type))
513 (*timer_list)[index] = timer->handle;
542 USE_UNWANTED_PARAM(list_size);
544 if (timer_list != NULL)
561 U32BIT recording_handle;
562 U32DHMS stop_date_time;
564 BOOLEAN recording_started;
568 TMR_PVR_DBG((
"ATMR_StartRecord(%d)", path));
573 recording_started = FALSE;
579 if ((timer->type == TIMER_TYPE_PVR_RECORD) && timer->starting && (timer->u.record.path == path))
585 stop_date_time =
STB_GCCalculateDHMS(timer->start_time, timer->u.record.duration, CALC_ADD);
589 DHMS_MINS(stop_date_time), DHMS_SECS(stop_date_time)))
591 TMR_PVR_DBG((
"ATMR_StartRecord: stop timer in future - start new recording"));
595 #ifdef INTEGRATE_HBBTV 601 timer->u.record.event_id, timer->u.record.prog_crid, timer->u.record.other_crid,
604 TMR_PVR_DBG((
"ATMR_StartRecord(%u): Started recording \"%s\"", path, timer->name));
607 timer->u.record.recording_handle = recording_handle;
608 timer->u.record.programme_started = TRUE;
609 timer->u.record.programme_finished = FALSE;
611 timer->starting = FALSE;
612 timer->started = TRUE;
613 recording_started = TRUE;
620 #ifdef INTEGRATE_HBBTV 627 TMR_PVR_DBG((
"ATMR_StartRecord(%u): Failed to start recording \"%s\"", path, timer->name));
630 timer->missed = TRUE;
631 timer->started = FALSE;
632 timer->starting = FALSE;
634 #ifdef INTEGRATE_HBBTV 642 TMR_PVR_DBG((
"ATMR_StartRecord(%u): Timer is marked as starting but the stop time is in the past", path));
643 timer->u.record.recording_handle = STB_PVR_INVALID_HANDLE;
646 timer->missed = TRUE;
647 timer->starting = FALSE;
648 timer->started = FALSE;
657 return(recording_started);
677 if ((timer->type == TIMER_TYPE_PVR_RECORD) && timer->starting && (timer->u.record.path == path))
681 if ((timer->frequency == TIMER_FREQ_ONCE) &&
685 TMR_PVR_DBG((
"ATMR_RecordingFailed(%u): Destroy timer 0x%08lx", path, timer->handle));
687 DeleteTimer(timer->handle);
694 timer->missed = TRUE;
695 timer->starting = FALSE;
696 timer->started = FALSE;
738 if (timer_info != NULL)
740 memset(timer_info, 0,
sizeof(*timer_info));
743 timer_info->type = timer_type;
744 timer_info->frequency = TIMER_FREQ_ONCE;
748 switch (timer_info->type)
750 case TIMER_TYPE_SLEEP:
757 case TIMER_TYPE_ALARM:
759 timer_info->u.alarm.ramp_volume = FALSE;
761 if (serv_ptr != NULL)
763 timer_info->u.alarm.change_service = TRUE;
765 &timer_info->u.alarm.transport_id, &timer_info->u.alarm.service_id);
769 timer_info->u.alarm.change_service = FALSE;
772 if (event_ptr != NULL)
779 if (name_len > TMR_MAX_NAME_LENGTH)
781 memcpy(timer_info->name, name, TMR_MAX_NAME_LENGTH);
782 timer_info->name[TMR_MAX_NAME_LENGTH - 1] =
'\0';
786 memcpy(timer_info->name, name, name_len);
798 case TIMER_TYPE_PVR_RECORD:
802 if (serv_ptr != NULL)
805 &timer_info->u.record.transport_id, &timer_info->u.record.service_id);
808 if (event_ptr != NULL)
813 if (name_len > TMR_MAX_NAME_LENGTH)
815 memcpy(timer_info->name, name, TMR_MAX_NAME_LENGTH);
816 timer_info->name[TMR_MAX_NAME_LENGTH - 1] =
'\0';
820 memcpy(timer_info->name, name, name_len);
825 timer_info->u.record.event_triggered = TRUE;
828 timer_info->u.record.start_padding = 0;
829 timer_info->u.record.end_padding = 0;
832 DHMS_HOUR(timer_info->start_time), DHMS_MINS(timer_info->start_time),
833 DHMS_SECS(timer_info->start_time)))
838 timer_info->start_time = now;
840 time_diff, CALC_SUB);
846 strncpy((
char *)timer_info->u.record.prog_crid, (
char *)crid, TMR_PVR_CRID_LEN_MAX);
852 timer_info->u.record.event_triggered = FALSE;
856 timer_info->u.record.duration = DHMS_CREATE(0, 2, 0, 0);
861 case TIMER_TYPE_PRIVATE:
900 if (timer->dba_rec == NULL)
902 timer_info->ram_only = TRUE;
906 timer_info->ram_only = FALSE;
909 timer_info->type = timer->type;
910 timer_info->frequency = timer->frequency;
911 timer_info->start_time = timer->start_time;
912 memcpy(&timer_info->name[0], &timer->name[0], TMR_MAX_NAME_LENGTH);
916 case TIMER_TYPE_SLEEP:
920 case TIMER_TYPE_ALARM:
922 timer_info->u.alarm.change_service = timer->u.alarm.change_service;
923 timer_info->u.alarm.orig_net_id = timer->u.alarm.orig_net_id;
924 timer_info->u.alarm.transport_id = timer->u.alarm.transport_id;
925 timer_info->u.alarm.service_id = timer->u.alarm.service_id;
926 timer_info->u.alarm.ramp_volume = timer->u.alarm.ramp_volume;
930 case TIMER_TYPE_PVR_RECORD:
932 timer_info->u.record.duration = timer->u.record.duration;
933 timer_info->u.record.event_triggered = timer->u.record.event_triggered;
934 timer_info->u.record.event_id = timer->u.record.event_id;
935 timer_info->u.record.orig_net_id = timer->u.record.orig_net_id;
936 timer_info->u.record.transport_id = timer->u.record.transport_id;
937 timer_info->u.record.service_id = timer->u.record.service_id;
938 timer_info->u.record.disk_id = timer->u.record.disk_id;
939 timer_info->u.record.recommendation = timer->u.record.recommendation;
940 timer_info->u.record.start_padding = GetStartPadding(timer);
941 timer_info->u.record.end_padding = GetEndPadding(timer);
942 timer_info->u.record.notify_time = timer->u.record.notify_time;
943 timer_info->u.record.do_not_delete = timer->u.record.do_not_delete;
945 memcpy(&timer_info->u.record.prog_crid[0], &timer->u.record.prog_crid[0],
946 TMR_PVR_CRID_LEN_MAX);
947 memcpy(&timer_info->u.record.other_crid[0], &timer->u.record.other_crid[0],
948 TMR_PVR_CRID_LEN_MAX);
979 TMR_PVR_DBG((
"ATMR_GetRecordService(%u)", path));
989 if ((timer->type == TIMER_TYPE_PVR_RECORD) && (timer->u.record.path == path))
993 timer->u.record.service_id);
1022 retval = timer->name;
1047 size = strlen((
char *)name) + 1;
1048 if (size >= TMR_MAX_NAME_LENGTH)
1050 size = TMR_MAX_NAME_LENGTH - 1;
1052 memcpy(timer->name, name, size);
1053 timer->name[size] = 0;
1055 if (timer->dba_rec != NULL)
1085 retval = timer->start_time;
1111 if (((timer =
DBDEF_FindTimerRec(handle)) != NULL) && (timer->type == TIMER_TYPE_PVR_RECORD))
1113 retval = timer->u.record.duration;
1142 if (timer->type == TIMER_TYPE_PVR_RECORD)
1148 retval = timer->start_time;
1167 E_TIMER_TYPE timer_type;
1175 timer_type = timer->type;
1179 timer_type = TIMER_TYPE_NONE;
1197 E_TIMER_FREQ timer_freq;
1205 timer_freq = timer->frequency;
1209 timer_freq = TIMER_FREQ_ONCE;
1227 BOOLEAN change_service;
1233 if (((timer =
DBDEF_FindTimerRec(handle)) != NULL) && (timer->type == TIMER_TYPE_ALARM))
1235 change_service = timer->u.alarm.change_service;
1239 change_service = FALSE;
1246 return(change_service);
1257 BOOLEAN ramp_volume;
1263 if (((timer =
DBDEF_FindTimerRec(handle)) != NULL) && (timer->type == TIMER_TYPE_ALARM))
1265 ramp_volume = timer->u.alarm.ramp_volume;
1269 ramp_volume = FALSE;
1276 return(ramp_volume);
1293 if (((timer =
DBDEF_FindTimerRec(handle)) != NULL) && (timer->type == TIMER_TYPE_PVR_RECORD))
1295 event_id = timer->u.record.event_id;
1322 service_id = ADB_INVALID_DVB_ID;
1328 if (timer->type == TIMER_TYPE_ALARM)
1330 service_id = timer->u.alarm.service_id;
1332 else if (timer->type == TIMER_TYPE_PVR_RECORD)
1334 service_id = timer->u.record.service_id;
1358 trans_id = ADB_INVALID_DVB_ID;
1364 if (timer->type == TIMER_TYPE_ALARM)
1366 trans_id = timer->u.alarm.transport_id;
1368 else if (timer->type == TIMER_TYPE_PVR_RECORD)
1370 trans_id = timer->u.record.transport_id;
1394 onet_id = ADB_INVALID_DVB_ID;
1400 if (timer->type == TIMER_TYPE_ALARM)
1402 onet_id = timer->u.alarm.orig_net_id;
1404 else if (timer->type == TIMER_TYPE_PVR_RECORD)
1406 onet_id = timer->u.record.orig_net_id;
1433 missed = timer->missed;
1464 if (((timer =
DBDEF_FindTimerRec(handle)) != NULL) && (timer->type == TIMER_TYPE_PVR_RECORD))
1466 if (strlen((
char *)timer->u.record.prog_crid) > 0)
1468 prog_crid = timer->u.record.prog_crid;
1496 if (((timer =
DBDEF_FindTimerRec(handle)) != NULL) && (timer->type == TIMER_TYPE_PVR_RECORD))
1498 if (!timer->u.record.recommendation &&
1499 (strlen((
char *)timer->u.record.other_crid) > 0))
1529 if (((timer =
DBDEF_FindTimerRec(handle)) != NULL) && (timer->type == TIMER_TYPE_PVR_RECORD))
1531 if (timer->u.record.recommendation &&
1532 (strlen((
char *)timer->u.record.other_crid) > 0))
1564 if (((timer =
DBDEF_FindTimerRec(handle)) != NULL) && (timer->type == TIMER_TYPE_PVR_RECORD))
1566 if (strlen((
char *)timer->u.record.other_crid) > 0)
1568 crid = timer->u.record.other_crid;
1593 if (((timer =
DBDEF_FindTimerRec(handle)) != NULL) && (timer->type == TIMER_TYPE_PVR_RECORD))
1595 disk_id = timer->u.record.disk_id;
1599 disk_id = INVALID_DISK_ID;
1622 if (((timer =
DBDEF_FindTimerRec(handle)) != NULL) && (timer->type == TIMER_TYPE_PVR_RECORD))
1624 timer->u.record.disk_id = disk_id;
1626 if (timer->dba_rec != NULL)
1646 U32BIT recording_handle;
1650 recording_handle = STB_PVR_INVALID_HANDLE;
1654 if (((timer =
DBDEF_FindTimerRec(handle)) != NULL) && (timer->type == TIMER_TYPE_PVR_RECORD))
1656 recording_handle = timer->u.record.recording_handle;
1663 return(recording_handle);
1678 BOOLEAN delete_timer;
1679 BOOLEAN timers_updated;
1680 BOOLEAN stop_recording;
1681 U32BIT overrun_duration;
1682 U32DHMS start_date_time, end_date_time;
1683 U32BIT recording_handle;
1692 delete_timer = FALSE;
1693 timers_updated = FALSE;
1701 TMR_DBG((
"ATMR_HandleTimerEvent: Timer 0x%08lx has expired", timer->handle));
1703 memset(&info, 0,
sizeof(info));
1705 switch (timer->type)
1707 case TIMER_TYPE_SLEEP:
1710 timer->starting = FALSE;
1712 if (timer->frequency == TIMER_FREQ_ONCE)
1715 delete_timer = TRUE;
1719 info.type = TIMER_TYPE_SLEEP;
1720 info.start_time = timer->start_time;
1721 info.frequency = timer->frequency;
1723 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_APPLICATION, EV_TIMER_TRIGGERED,
1724 (
void *)&info,
sizeof(info));
1728 case TIMER_TYPE_ALARM:
1731 timer->starting = FALSE;
1733 if (timer->frequency == TIMER_FREQ_ONCE)
1736 delete_timer = TRUE;
1740 info.type = TIMER_TYPE_ALARM;
1741 info.start_time = timer->start_time;
1742 info.frequency = timer->frequency;
1743 memcpy(&info.name[0], &timer->name[0],
sizeof(timer->name));
1744 info.u.alarm.change_service = timer->u.alarm.change_service;
1745 info.u.alarm.orig_net_id = timer->u.alarm.orig_net_id;
1746 info.u.alarm.transport_id = timer->u.alarm.transport_id;
1747 info.u.alarm.service_id = timer->u.alarm.service_id;
1748 info.u.alarm.ramp_volume = timer->u.alarm.ramp_volume;
1750 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_APPLICATION, EV_TIMER_TRIGGERED,
1751 (
void *)&info,
sizeof(info));
1755 case TIMER_TYPE_PVR_RECORD:
1757 if (timer->u.record.event_triggered)
1759 stop_recording = FALSE;
1761 if (timer->u.record.programme_finished)
1765 stop_recording = TRUE;
1766 TMR_PVR_DBG((
"Programme has finished and timer 0x%x has expired, stopping recording",
1776 overrun_duration = NORDIG_EVENT_DURATION_OVERRUN;
1780 overrun_duration = EVENT_DURATION_OVERRUN;
1784 overrun_duration = 0;
1787 GetActualStartEndTime(timer->start_time, timer->u.record.duration, 0,
1788 overrun_duration, &start_date_time, &end_date_time);
1791 DHMS_MINS(end_date_time), DHMS_SECS(end_date_time)))
1794 stop_recording = TRUE;
1795 TMR_PVR_DBG((
"Timer 0x%x has overrun, stopping recording", timer->handle));
1802 stop_recording = TRUE;
1803 TMR_PVR_DBG((
"Timer 0x%x has expired, stopping recording", timer->handle));
1808 if (timer->u.record.recording_handle != STB_PVR_INVALID_HANDLE)
1810 #ifdef INTEGRATE_HBBTV 1814 recording_handle = timer->u.record.recording_handle;
1823 timers_updated = TRUE;
1839 timer->u.record.path = INVALID_RES_ID;
1844 if (timer->u.record.path != INVALID_RES_ID)
1856 timer->u.record.path = INVALID_RES_ID;
1858 else if (timer->frequency == TIMER_FREQ_ONCE)
1861 delete_timer = TRUE;
1871 case TIMER_TYPE_PRIVATE:
1876 TMR_DBG((
"ATMR_HandleTimerEvent: Unrecognised expired timer 0x%08lx, type=0x%02x",
1877 timer->handle, timer->type));
1882 if ((timer != NULL) && delete_timer)
1884 TMR_DBG((
"ATMR_HandleTimerEvent: deleting expired timer 0x%08lx", timer->handle));
1885 DeleteTimer(timer->handle);
1888 timers_updated = TRUE;
1893 if (timer->starting)
1895 switch (timer->type)
1897 case TIMER_TYPE_PVR_RECORD:
1899 TMR_PVR_DBG((
"ATMR_HandleTimerEvent: 0x%x, start recording", timer->handle));
1900 if (ActionTimerRecStart(timer))
1908 timers_updated = TRUE;
1913 TMR_DBG((
"ATMR_HandleTimerEvent: Timer type %d (0x%08lx) is set to start but hasn't been handled",
1914 timer->type, timer->handle));
1946 BOOLEAN timers_updated;
1947 BOOLEAN record_started;
1951 timers_updated = FALSE;
1952 record_started = FALSE;
1965 timer->selected = FALSE;
1968 if (timer->started && (timer->type == TIMER_TYPE_PVR_RECORD) &&
1969 timer->u.record.event_triggered && (timer->u.record.event_id != 0))
1972 timer->u.record.transport_id, timer->u.record.service_id);
1973 if (((service == NULL) && (s_ptr != NULL)) || (s_ptr == service))
1978 if (now_event != NULL)
1981 timer->u.record.programme_started)
1983 if (!timer->u.record.programme_finished)
1985 TMR_PVR_DBG((
"%s: Programme for timer 0x%x has finished", __FUNCTION__, timer->handle));
1986 timer->u.record.programme_finished = TRUE;
1989 timers_updated |= HasTimerExpired(timer->handle);
2003 if (timer->selected)
2006 TMR_PVR_DBG((
"%s: deleting expired timer 0x%08x", __FUNCTION__, timer->handle));
2007 DeleteTimer(timer->handle);
2008 timers_updated = TRUE;
2016 if ((timer->type == TIMER_TYPE_PVR_RECORD) && !timer->missed && !timer->expired &&
2017 timer->u.record.event_triggered && !timer->u.record.programme_started)
2020 timer->u.record.transport_id, timer->u.record.service_id);
2025 if (now_event != NULL)
2028 if (timer->u.record.event_id == event_id)
2030 TMR_PVR_DBG((
"%s: Programme for timer 0x%x has started", __FUNCTION__, timer->handle));
2031 timer->u.record.programme_started = TRUE;
2040 if ((timer->type == TIMER_TYPE_PVR_RECORD) && !timer->started && !timer->missed &&
2041 (!timer->starting || (timer->u.record.path == INVALID_RES_ID)))
2044 timer->u.record.transport_id, timer->u.record.service_id);
2047 if (!timer->u.record.event_triggered)
2049 timers_updated |= StartRecordTimer(timer, recordings_can_start, &record_started);
2055 if (now_event != NULL)
2060 if (recordings_can_start)
2062 TMR_PVR_DBG((
"%s: Timer 0x%x, start recording for event %lu @ %02u:%02u:%02u",
2063 __FUNCTION__, timer->handle, timer->u.record.event_id,
2064 DHMS_HOUR(timer->start_time), DHMS_MINS(timer->start_time),
2065 DHMS_SECS(timer->start_time)));
2068 timers_updated |= StartRecordTimer(timer, recordings_can_start, &record_started);
2078 TMR_PVR_DBG((
"ATMR_CheckRecordStatus: Can't find service 0x%04x/0x%04x/0x%04x",
2079 timer->u.record.orig_net_id, timer->u.record.transport_id, timer->u.record.service_id));
2094 return(record_started);
2108 U32DHMS event_start;
2109 U32DHMS event_duration;
2111 U32DHMS rec_end_time;
2113 BOOLEAN event_missed;
2126 if (timer->type == TIMER_TYPE_PVR_RECORD)
2129 if (!timer->expired)
2131 if ((timer->u.record.service_id != 0) && (timer->u.record.event_id != 0))
2134 timer->u.record.orig_net_id, timer->u.record.transport_id,
2135 timer->u.record.service_id);
2136 if (serv_ptr != NULL)
2141 event_missed = TRUE;
2145 event_missed = FALSE;
2148 event_ptr =
ADB_GetEvent(serv_ptr, timer->u.record.event_id);
2149 if (event_ptr == NULL)
2152 TMR_PVR_DBG((
"ATMR_EitUpdated: Event %lu on %lu @ %02lu:%02lu not found in schedule",
2153 timer->u.record.event_id, DHMS_DATE(timer->start_time),
2154 DHMS_HOUR(timer->start_time), DHMS_MINS(timer->start_time)));
2156 event_missed = TRUE;
2166 if (!timer->started &&
2168 DHMS_MINS(end_time), DHMS_SECS(end_time)))
2171 event_missed = TRUE;
2172 TMR_PVR_DBG((
"ATMR_EitUpdated: Event %d ending on %d @ %02d:%02d has been missed",
2173 timer->u.record.event_id, DHMS_DATE(end_time), DHMS_HOUR(end_time),
2174 DHMS_MINS(end_time)));
2182 if ((timer->start_time != event_start) &&
2183 (timer->u.record.event_triggered && !timer->u.record.programme_started))
2185 if ((timer->u.record.recording_handle != STB_PVR_INVALID_HANDLE) &&
2186 (event_start > timer->start_time))
2203 timer->u.record.path = INVALID_RES_ID;
2206 EV_PVR_RECORDING_STOPPED, &timer->u.record.recording_handle,
2207 sizeof(timer->u.record.recording_handle));
2210 timer->u.record.recording_handle = STB_PVR_INVALID_HANDLE;
2212 timer->starting = FALSE;
2213 timer->started = FALSE;
2214 timer->u.record.notified = FALSE;
2217 timer->start_time = event_start;
2218 if (timer->dba_rec != NULL)
2225 if (timer->u.record.duration != event_duration)
2230 rec_end_time =
STB_GCCalculateDHMS(timer->start_time, timer->u.record.duration, CALC_ADD);
2232 if (end_time != rec_end_time)
2234 timer->u.record.duration = event_duration;
2235 if (timer->dba_rec != NULL)
2243 #ifdef INTEGRATE_HBBTV 2261 DHMS_MINS(end_time), 0))
2274 TMR_PVR_DBG((
"Missed event on %u @ %02u:%02u and ends on %d @ %02d:%02d (today=%d)\n",
2275 DHMS_DATE(timer->start_time), DHMS_HOUR(timer->start_time),
2276 DHMS_MINS(timer->start_time), DHMS_DATE(end_time), DHMS_HOUR(end_time),
2280 timer->missed = TRUE;
2281 if (timer->dba_rec != NULL)
2287 #ifdef INTEGRATE_HBBTV 2293 alt_event_data.timer_handle = timer->handle;
2294 alt_event_data.is_recommendation = timer->u.record.recommendation;
2295 alt_event_data.do_not_delete = timer->u.record.do_not_delete;
2296 strncpy((
char *)alt_event_data.prog_crid, (
char *)timer->u.record.prog_crid, TMR_PVR_CRID_LEN_MAX);
2297 strncpy((
char *)alt_event_data.other_crid, (
char *)timer->u.record.other_crid, TMR_PVR_CRID_LEN_MAX);
2300 sizeof(alt_event_data), TIMEOUT_NOW);
2307 TMR_PVR_DBG((
"Missed event on %u @ %02u:%02u and ends on %d @ %02d:%02d (today=%d)\n",
2308 DHMS_DATE(timer->start_time), DHMS_HOUR(timer->start_time),
2309 DHMS_MINS(timer->start_time), DHMS_DATE(end_time), DHMS_HOUR(end_time),
2314 DeleteTimer(timer->handle);
2323 TMR_PVR_DBG((
"ATMR_EitUpdated: Service not found, timer deleted!!"));
2324 DeleteTimer(timer->handle);
2353 handle = INVALID_TIMER_HANDLE;
2359 while (timer != NULL)
2361 if ((timer->type == TIMER_TYPE_PVR_RECORD) &&
2362 (timer->u.record.recording_handle == recording_handle))
2364 handle = timer->handle;
2396 if (timer->u.record.recording_handle == recording_handle)
2398 if (timer->frequency == TIMER_FREQ_ONCE)
2401 TMR_PVR_DBG((
"ATMR_DeleteRecordingTimer: Destroy timer 0x%08lx", timer->handle));
2402 DeleteTimer(timer->handle);
2410 timer->u.record.recording_handle = STB_PVR_INVALID_HANDLE;
2411 TMR_PVR_DBG((
"ATMR_DeleteRecordingTimer: timer periodic, do not destroy, clear recording handle"));
2433 U32DHMS end_date_time, U32BIT **conflicting_timers)
2435 U8BIT num_recordings;
2441 num_recordings = GetNumSimultaneousRecordings(INVALID_TIMER_HANDLE, ADB_INVALID_DVB_ID,
2442 ADB_INVALID_DVB_ID, ADB_INVALID_DVB_ID, max_recordings, start_date_time, end_date_time, FALSE, FALSE,
2443 conflicting_timers);
2449 return(num_recordings);
2467 BOOLEAN is_recommendation, BOOLEAN check_alternatives, BOOLEAN do_not_delete)
2472 U8BIT num_recordings;
2473 void *result_event_ptr = event_ptr;
2474 #ifdef TMR_PVR_DEBUG 2475 U8BIT *event_prog_crid;
2486 end_time, &conflicts);
2491 if ((prog_crid != NULL) && check_alternatives)
2500 result_event_ptr = NULL;
2504 if (result_event_ptr == NULL)
2506 U16BIT serv_id, trans_id, onet_id;
2508 void *s_ptr, *event;
2509 U8BIT *p_crid, *o_crid;
2511 for (t = 0; t < num_recordings; t++)
2527 if ((p_crid != NULL) && check_alternatives)
2540 #ifdef TMR_PVR_DEBUG 2543 TMR_PVR_DBG((
" Moving programmed event to \"%s\", start: %d:%d.%d, len: %d.%d, event=%d",
2548 if (event_prog_crid != NULL)
2550 TMR_PVR_DBG((
" prog CRID=\"%s\"", event_prog_crid));
2560 strncpy((
char *)timer_info.u.record.other_crid, (
char *)o_crid, TMR_PVR_CRID_LEN_MAX);
2566 timer_info.u.record.event_triggered = TRUE;
2567 timer_info.u.record.do_not_delete = do_not_delete;
2568 timer_info.u.record.start_padding = 0;
2569 timer_info.u.record.end_padding = 0;
2577 result_event_ptr = event_ptr;
2589 if (result_event_ptr != NULL)
2596 if (result_event_ptr != NULL)
2600 if (other_crid != NULL)
2602 strncpy((
char *)timer_info.u.record.other_crid, (
char *)other_crid, TMR_PVR_CRID_LEN_MAX);
2605 timer_info.u.record.recommendation = is_recommendation;
2607 timer_info.u.record.event_triggered = TRUE;
2608 timer_info.u.record.do_not_delete = do_not_delete;
2610 #ifdef TMR_PVR_DEBUG 2611 TMR_PVR_DBG((
" Recording event \"%s\", start: %d:%d.%d, len: %d.%d, event=%d",
2613 DHMS_HOUR(timer_info.start_time), DHMS_MINS(timer_info.start_time),
2614 DHMS_HOUR(timer_info.u.record.duration), DHMS_MINS(timer_info.u.record.duration),
2615 timer_info.u.record.event_id));
2618 if (event_prog_crid != NULL)
2620 TMR_PVR_DBG((
" prog CRID=\"%s\"", event_prog_crid));
2629 if (conflicts != NULL)
2638 return(result_event_ptr);
2654 BOOLEAN do_not_delete, BOOLEAN search_forward)
2657 void *alt_event_ptr;
2658 U32DHMS limit_date_time;
2659 U32DHMS end_date_time;
2660 U32DHMS next_date_time;
2661 U32DHMS event_start_time;
2664 BOOLEAN continue_search;
2665 BOOLEAN event_recorded;
2669 event_recorded = FALSE;
2676 limit_date_time =
STB_GCCalculateDHMS(start_date_time, DHMS_CREATE(0, 3, 0, 0), CALC_ADD);
2678 next_date_time = start_date_time;
2679 continue_search = TRUE;
2681 while (continue_search)
2683 TMR_PVR_DBG((
"--- Searching for event after %d:%02d.%02d", DHMS_DATE(next_date_time),
2684 DHMS_HOUR(next_date_time), DHMS_MINS(next_date_time)));
2687 DHMS_HOUR(next_date_time), DHMS_MINS(next_date_time));
2689 if (event_ptr != NULL)
2694 if (limit_date_time >= event_start_time)
2697 #ifdef TMR_PVR_DEBUG 2698 if (event_crid != NULL)
2700 TMR_PVR_DBG((
" Found event in time limit, crid=\"%s\"", event_crid));
2704 TMR_PVR_DBG((
" Found event in time limit"));
2715 TMR_PVR_DBG((
" Recording event @ %d:%02d.%02d, crid=\"%s\"",
2718 TMR_PVR_DBG((
" Search forward: Recording event @ %d:%02d.%02d, crid=\"%s\", event_id=%u\n",
2724 FALSE, FALSE, do_not_delete);
2725 if (alt_event_ptr != NULL)
2727 event_recorded = TRUE;
2729 if (alt_event_ptr != event_ptr)
2733 event_ptr = alt_event_ptr;
2754 if (event_crid != NULL)
2762 continue_search = FALSE;
2763 TMR_PVR_DBG((
" No more events within 3 hours"));
2772 continue_search = FALSE;
2773 TMR_PVR_DBG((
" No more events"));
2780 limit_date_time =
STB_GCCalculateDHMS(start_date_time, DHMS_CREATE(0, 3, 0, 0), CALC_SUB);
2782 next_date_time = start_date_time;
2783 continue_search = TRUE;
2785 while (continue_search)
2787 TMR_PVR_DBG((
"--- Searching for event before %d:%02d.%02d", DHMS_DATE(next_date_time),
2788 DHMS_HOUR(next_date_time), DHMS_MINS(next_date_time)));
2791 DHMS_HOUR(next_date_time), DHMS_MINS(next_date_time));
2793 if (event_ptr != NULL)
2799 if (limit_date_time <= end_date_time)
2802 #ifdef TMR_PVR_DEBUG 2803 if (event_crid != NULL)
2805 TMR_PVR_DBG((
" Found event in time limit, crid=\"%s\"", event_crid));
2809 TMR_PVR_DBG((
" Found event in time limit"));
2820 TMR_PVR_DBG((
" Recording event @ %d:%02d.%02d, crid=\"%s\"",
2823 TMR_PVR_DBG((
" Search backward: Recording event @ %d:%02d.%02d, crid=\"%s\", event_id=%u\n",
2829 do_not_delete, FALSE, FALSE);
2830 if (alt_event_ptr != NULL)
2832 event_recorded = TRUE;
2833 if (alt_event_ptr != event_ptr)
2837 event_ptr = alt_event_ptr;
2857 if (event_crid != NULL)
2865 continue_search = FALSE;
2866 TMR_PVR_DBG((
" No events within 3 hours"));
2875 continue_search = FALSE;
2876 TMR_PVR_DBG((
" No more events"));
2883 return(event_recorded);
2900 U32DHMS end_date_time;
2902 FUNCTION_START(AMTR_GetFirstWakeupTime);
2906 handle = INVALID_TIMER_HANDLE;
2915 if (timer->type == TIMER_TYPE_ALARM)
2918 DHMS_HOUR(timer->start_time), DHMS_MINS(timer->start_time), DHMS_SECS(timer->start_time)))
2920 *date_time = timer->start_time;
2921 *onet_id = timer->u.alarm.orig_net_id;
2922 *trans_id = timer->u.alarm.transport_id;
2923 *service_id = timer->u.alarm.service_id;
2924 handle = timer->handle;
2927 else if (timer->type == TIMER_TYPE_PVR_RECORD)
2930 end_date_time =
STB_GCCalculateDHMS(timer->start_time, timer->u.record.duration, CALC_ADD);
2932 TMR_PVR_DBG((
"%s: handle=0x%08x, start=%u@%02u:%02u, end=%u@%02u:%02u, missed=%u",
2933 __FUNCTION__, timer->handle, DHMS_DATE(timer->start_time), DHMS_HOUR(timer->start_time),
2934 DHMS_MINS(timer->start_time), DHMS_DATE(end_date_time), DHMS_HOUR(end_date_time),
2935 DHMS_MINS(end_date_time), timer->missed));
2938 DHMS_HOUR(end_date_time), DHMS_MINS(end_date_time), DHMS_SECS(end_date_time)))
2940 *date_time = timer->start_time;
2941 *onet_id = timer->u.record.orig_net_id;
2942 *trans_id = timer->u.record.transport_id;
2943 *service_id = timer->u.record.service_id;
2944 handle = timer->handle;
2951 FUNCTION_FINISH(AMTR_GetFirstWakeupTime);
2967 U32BIT timer_handle;
2973 timer_handle = INVALID_TIMER_HANDLE;
2975 for (timer =
DBDEF_GetNextTimerRec(NULL); (timer_handle == INVALID_TIMER_HANDLE) && (timer != NULL);
2978 if (timer->type == TIMER_TYPE_PVR_RECORD)
2980 if ((timer->u.record.orig_net_id == onet_id) && (timer->u.record.transport_id == trans_id) &&
2981 (timer->u.record.service_id == serv_id) && (timer->u.record.event_id == event_id))
2983 timer_handle = timer->handle;
2992 return(timer_handle);
3003 U32BIT timer_handle;
3009 timer_handle = INVALID_TIMER_HANDLE;
3011 for (timer =
DBDEF_GetNextTimerRec(NULL); (timer_handle == INVALID_TIMER_HANDLE) && (timer != NULL);
3014 if (timer->type == TIMER_TYPE_PVR_RECORD)
3018 timer_handle = timer->handle;
3027 return(timer_handle);
3041 U32BIT timer_handle;
3047 timer_handle = INVALID_TIMER_HANDLE;
3049 for (timer =
DBDEF_GetNextTimerRec(NULL); (timer_handle == INVALID_TIMER_HANDLE) && (timer != NULL);
3052 if (timer->type == TIMER_TYPE_PVR_RECORD)
3054 if (timer->u.record.service_id == service_id)
3058 if (timer->u.record.event_id == event_id)
3060 timer_handle = timer->handle;
3071 return(timer_handle);
3083 BOOLEAN timer_deleted;
3089 TMR_PVR_DBG((
"ATMR_DeleteTimersForSeriesRecommendations(\"%s\")", crid));
3094 timer_deleted = FALSE;
3096 if (is_recommendation)
3102 TMR_PVR_DBG((
"ATMR_DeleteTimersForSeriesRecommendations: Deleting timer 0x%08lx", timer->handle));
3103 DeleteTimer(timer->handle);
3104 timer_deleted = TRUE;
3108 if (!timer_deleted &&
3111 TMR_PVR_DBG((
"ATMR_DeleteTimersForSeriesRecommendations: Deleting timer 0x%08lx", timer->handle));
3112 DeleteTimer(timer->handle);
3136 if (((timer =
DBDEF_FindTimerRec(handle)) != NULL) && (timer->type == TIMER_TYPE_PVR_RECORD))
3138 if (size >= TMR_PVR_ADDINFO_LEN_MAX)
3140 size = TMR_PVR_ADDINFO_LEN_MAX - 1;
3143 memcpy(timer->u.record.additional_info, info, size);
3144 timer->u.record.additional_info[size] = 0;
3146 if (timer->dba_rec != NULL)
3149 timer->u.record.additional_info, size);
3173 U8BIT *additional_info = NULL;
3179 if (((timer =
DBDEF_FindTimerRec(handle)) != NULL) && (timer->type == TIMER_TYPE_PVR_RECORD))
3181 *size = strlen((
char *)timer->u.record.additional_info) + 1;
3183 strncpy((
char *)additional_info, (
char *)timer->u.record.additional_info, *size);
3190 return additional_info;
3211 retval = GetStartPadding(timer);
3244 retval = SetStartPadding(timer, start_padding);
3246 if (retval && (timer->dba_rec != NULL))
3249 timer->u.record.start_padding);
3282 retval = GetEndPadding(timer);
3315 retval = SetEndPadding(timer, end_padding);
3347 if (((timer =
DBDEF_FindTimerRec(handle)) != NULL) && (timer->type == TIMER_TYPE_PVR_RECORD))
3349 timer->u.record.do_not_delete = do_not_delete;
3373 if (((timer =
DBDEF_FindTimerRec(handle)) != NULL) && (timer->type == TIMER_TYPE_PVR_RECORD))
3375 retval = timer->u.record.do_not_delete;
3419 static BOOLEAN DeleteTimer(U32BIT handle)
3422 BOOLEAN timer_deleted;
3424 FUNCTION_START(DeleteTimer);
3426 timer_deleted = FALSE;
3431 if (timer->type == TIMER_TYPE_PVR_RECORD)
3435 if ((timer->u.record.recording_handle == STB_PVR_INVALID_HANDLE) ||
3440 #ifdef INTEGRATE_HBBTV 3443 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_APPLICATION, EV_PVR_BOOKING_DELETED,
3444 (
void *)&handle,
sizeof(handle));
3452 timer_deleted = TRUE;
3455 FUNCTION_FINISH(DeleteTimer);
3457 return(timer_deleted);
3476 BOOLEAN new_tuned_service;
3477 U32BIT recording_handle;
3479 FUNCTION_START(ActionTimerRecStart);
3483 TMR_PVR_DBG((
"ActionTimerRecStart()"));
3489 if (stop_time > gmt)
3491 TMR_PVR_DBG((
"ActionTimerRecStart: stop timer in future - start new recording"));
3493 #ifdef INTEGRATE_HBBTV 3499 timer->u.record.transport_id, timer->u.record.service_id, &new_tuned_service);
3501 if (timer->u.record.path != INVALID_RES_ID)
3506 TMR_PVR_DBG((
"ActionTimerRecStart: APVR_PrepareNewRecording, path=%u", timer->u.record.path));
3513 if (!new_tuned_service)
3515 TMR_PVR_DBG((
"ActionTimerRecStart: Starting recording \"%s\" with path %d",
3516 timer->name, timer->u.record.path));
3521 timer->name, timer->u.record.event_id, timer->u.record.prog_crid,
3522 timer->u.record.other_crid, &recording_handle);
3527 timer->u.record.recording_handle = recording_handle;
3528 timer->u.record.programme_finished = FALSE;
3530 TMR_PVR_DBG((
"ActionTimerRecStart: Recording started"));
3537 #ifdef INTEGRATE_HBBTV 3544 TMR_PVR_DBG((
"ActionTimerRecStart: Failed to start recording"));
3548 timer->u.record.path = INVALID_RES_ID;
3551 timer->missed = TRUE;
3553 if (timer->dba_rec != NULL)
3559 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_APPLICATION, EV_PVR_RECORDING_FAILED, NULL, 0);
3561 #ifdef INTEGRATE_HBBTV 3568 timer->starting = FALSE;
3573 TMR_PVR_DBG((
"ActionTimerRecStart: Failed to get a tuner to record"));
3576 timer->starting = FALSE;
3577 timer->missed = TRUE;
3579 if (timer->dba_rec != NULL)
3585 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_APPLICATION, EV_PVR_RECORDING_FAILED, NULL, 0);
3587 #ifdef INTEGRATE_HBBTV 3594 TMR_PVR_DBG((
"ActionTimerRecStart: Stop time in the past, so recording has been missed"));
3597 timer->u.record.recording_handle = STB_PVR_INVALID_HANDLE;
3598 timer->missed = TRUE;
3599 timer->starting = FALSE;
3601 if (timer->dba_rec != NULL)
3606 #ifdef INTEGRATE_HBBTV 3611 FUNCTION_FINISH(ActionTimerRecStart);
3621 static void TimerTask(
void *param)
3625 U32DHMS start_date_time, end_date_time;
3626 BOOLEAN timer_updated;
3627 BOOLEAN start_record;
3629 FUNCTION_START(TimerTask);
3631 USE_UNWANTED_PARAM(param);
3641 timer_updated = FALSE;
3645 while (timer != NULL)
3652 if (timer->type == TIMER_TYPE_PVR_RECORD)
3654 GetActualStartEndTime(timer->start_time, timer->u.record.duration,
3655 GetStartPadding(timer), GetEndPadding(timer), &start_date_time,
3660 start_date_time = timer->start_time;
3661 end_date_time = timer->start_time;
3665 DHMS_MINS(start_date_time), DHMS_SECS(start_date_time)))
3669 DHMS_MINS(end_date_time), DHMS_SECS(end_date_time)))
3672 timer->starting = TRUE;
3674 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_TIMER, EV_TYPE_SUCCESS, (
void *)&timer->handle,
3675 sizeof(timer->handle));
3680 timer_updated = TRUE;
3682 if (!RescheduleTimer(timer))
3685 if ((timer->type != TIMER_TYPE_PVR_RECORD) ||
3690 DeleteTimer(timer->handle);
3695 timer->expired = TRUE;
3696 timer_updated |= FALSE;
3721 timer_updated = FALSE;
3727 while (timer != NULL)
3730 if (timer->started || timer->starting)
3733 timer_updated |= HasTimerExpired(timer->handle);
3735 else if (timer->expired)
3738 TMR_DBG((
"[%s:%d]: Timer 0x%x still expired", __FUNCTION__, __LINE__, timer->handle));
3740 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_TIMER, EV_TYPE_SUCCESS, (
void *)&timer->handle,
3741 sizeof(timer->handle));
3749 while (timer != NULL)
3752 if (!timer->started && !timer->expired && !timer->missed)
3754 if (timer->type == TIMER_TYPE_PVR_RECORD)
3756 timer_updated |= StartRecordTimer(timer, TRUE, &start_record);
3761 if (!timer->starting && !timer->missed &&
3763 DHMS_MINS(timer->start_time), DHMS_SECS(timer->start_time)))
3766 TMR_DBG((
"[%s:%d]: Timer 0x%x starting", __FUNCTION__, __LINE__, timer->handle));
3768 timer->starting = TRUE;
3771 (
void *)&timer->handle,
sizeof(timer->handle));
3791 FUNCTION_FINISH(TimerTask);
3794 static BOOLEAN StartRecordTimer(
ADB_TIMER_REC *timer, BOOLEAN recordings_can_start, BOOLEAN *start_record)
3796 BOOLEAN timer_updated;
3797 U32DHMS start_date_time, end_date_time;
3799 U32DHMS padding_start, padding_end;
3800 U8BIT max_recordings;
3801 U8BIT num_recordings;
3802 BOOLEAN start_timer;
3803 BOOLEAN conflict_resolved;
3806 S32BIT start_padding;
3810 S32BIT padding_time;
3812 FUNCTION_START(StartRecordTimer);
3814 timer_updated = FALSE;
3815 *start_record = FALSE;
3817 start_padding = GetStartPadding(timer);
3818 end_padding = GetEndPadding(timer);
3820 GetActualStartEndTime(timer->start_time, timer->u.record.duration, start_padding, end_padding,
3821 &start_date_time, &end_date_time);
3824 if (!timer->u.record.notified)
3826 notify_time = timer->u.record.notify_time;
3827 if (notify_time == 0)
3832 if (notify_time != 0)
3838 DHMS_MINS(notify_time), DHMS_SECS(notify_time)))
3840 TMR_PVR_DBG((
"%s: Timer 0x%x being notified", __FUNCTION__, timer->handle));
3844 (
void *)&timer->handle,
sizeof(timer->handle));
3846 timer->u.record.notified = TRUE;
3852 if (!timer->starting && !timer->missed &&
3854 DHMS_MINS(start_date_time), DHMS_SECS(start_date_time)) ||
3855 (timer->u.record.event_triggered && timer->u.record.programme_started)))
3857 if (timer->type == TIMER_TYPE_PVR_RECORD)
3859 start_timer = FALSE;
3863 if (start_padding != 0)
3866 GetActualStartEndTime(timer->start_time, 0, start_padding, 0, &padding_start,
3868 padding_end = timer->start_time;
3870 num_recordings = GetNumSimultaneousRecordings(timer->handle, timer->u.record.orig_net_id,
3871 timer->u.record.transport_id, timer->u.record.service_id, max_recordings,
3872 padding_start, padding_end, TRUE, TRUE, &conflicts);
3874 if (num_recordings < max_recordings)
3881 TMR_PVR_DBG((
"[%s:%d]: Resolving conflict for timer 0x%x, @ %02u:%02u:%02u (padding %d/%d)",
3882 __FUNCTION__, __LINE__, timer->handle, DHMS_HOUR(start_date_time),
3883 DHMS_MINS(start_date_time), DHMS_SECS(start_date_time), start_padding, end_padding));
3887 for (i = 0, conflict_resolved = FALSE; !conflict_resolved && (i < max_recordings) &&
3888 (conflicts[i] != INVALID_TIMER_HANDLE); i++)
3898 padding_time = DHMS_MINS(time_diff) * 60 + DHMS_SECS(time_diff);
3902 if (padding_time != 0)
3910 TMR_PVR_DBG((
"[%s:%d]: Changing start padding of timer 0x%x from %d to %d",
3911 __FUNCTION__, __LINE__, timer->handle, start_padding, padding_time));
3913 SetStartPadding(timer, padding_time);
3915 else if (start_padding < (padding_time / 2))
3919 padding_time -= start_padding;
3921 TMR_PVR_DBG((
"[%s:%d]: Changing end padding of timer 0x%x from %d to %d",
3930 TMR_PVR_DBG((
"[%s:%d]: Splitting padding:", __FUNCTION__, __LINE__));
3931 TMR_PVR_DBG((
" timer 0x%x start padding %d to %d",
3932 timer->handle, start_padding, padding_time / 2));
3934 SetStartPadding(timer, padding_time / 2);
3936 TMR_PVR_DBG((
" timer 0x%x end padding %d to %d", conflicts[i],
3938 padding_time - GetStartPadding(timer)));
3943 conflict_resolved = TRUE;
3947 HasTimerExpired(conflicts[i]);
3954 for (i = 0; !conflict_resolved && (i < max_recordings) &&
3955 (conflicts[i] != INVALID_TIMER_HANDLE); i++)
3961 TMR_PVR_DBG((
"[%s:%d]: Found back-to-back recording with timer 0x%x, setting padding to 0",
3962 __FUNCTION__, __LINE__, conflicts[i]));
3964 SetStartPadding(timer, 0);
3966 conflict_resolved = TRUE;
3970 HasTimerExpired(conflicts[i]);
3974 if (conflict_resolved)
3976 TMR_PVR_DBG((
"[%s:%d]: Timer 0x%x padding now %d/%d", __FUNCTION__, __LINE__,
3977 timer->handle, GetStartPadding(timer), GetEndPadding(timer)));
3979 for (i = 0; (i < max_recordings) && (conflicts[i] != INVALID_TIMER_HANDLE); i++)
3981 TMR_PVR_DBG((
"[%s:%d]: Timer 0x%x padding now %d/%d", __FUNCTION__, __LINE__,
3990 start_padding = GetStartPadding(timer);
3991 end_padding = GetEndPadding(timer);
3993 GetActualStartEndTime(timer->start_time, 0, start_padding, 0,
3994 &padding_start, &padding_end);
3995 padding_end = timer->start_time;
3997 num_recordings = GetNumSimultaneousRecordings(timer->handle,
3998 timer->u.record.orig_net_id, timer->u.record.transport_id,
3999 timer->u.record.service_id, max_recordings,
4000 padding_start, padding_end, TRUE, TRUE, &conflicts);
4002 if (num_recordings < max_recordings)
4006 GetActualStartEndTime(timer->start_time, timer->u.record.duration,
4007 start_padding, end_padding, &start_date_time, &end_date_time);
4010 DHMS_MINS(start_date_time), DHMS_SECS(start_date_time)))
4019 if (conflicts != NULL)
4027 num_recordings = GetNumSimultaneousRecordings(timer->handle, timer->u.record.orig_net_id,
4028 timer->u.record.transport_id, timer->u.record.service_id, max_recordings,
4031 if (num_recordings < max_recordings)
4033 if (!timer->u.record.event_triggered || timer->u.record.programme_started)
4041 TMR_PVR_DBG((
"[%s:%d]: Resolving conflict for timer 0x%x, @ %02u:%02u:%02u (padding %d/%d)",
4042 __FUNCTION__, __LINE__, timer->handle, DHMS_HOUR(start_date_time),
4043 DHMS_MINS(start_date_time), DHMS_SECS(start_date_time), start_padding, end_padding));
4047 for (i = 0, conflict_resolved = FALSE; !conflict_resolved && (i < max_recordings) &&
4048 (conflicts[i] != INVALID_TIMER_HANDLE); i++)
4055 padding_time = DHMS_MINS(time_diff) * 60 + DHMS_SECS(time_diff);
4057 TMR_PVR_DBG((
"[%s:%d]: Changing end padding for timer 0x%x from %d to %d",
4062 conflict_resolved = TRUE;
4066 HasTimerExpired(conflicts[i]);
4070 if (conflict_resolved)
4072 TMR_PVR_DBG((
"[%s:%d]: Timer 0x%x padding now %d/%d", __FUNCTION__, __LINE__,
4073 timer->handle, start_padding, end_padding));
4075 for (i = 0; (i < max_recordings) && (conflicts[i] != INVALID_TIMER_HANDLE); i++)
4077 TMR_PVR_DBG((
"[%s:%d]:: Timer 0x%x padding now %d/%d", __FUNCTION__, __LINE__,
4086 num_recordings = GetNumSimultaneousRecordings(timer->handle,
4087 timer->u.record.orig_net_id, timer->u.record.transport_id,
4088 timer->u.record.service_id, max_recordings, timer->start_time,
4091 if (num_recordings < max_recordings)
4093 if (!timer->u.record.event_triggered || timer->u.record.programme_started)
4102 if (conflicts != NULL)
4115 *start_record = TRUE;
4117 if (recordings_can_start)
4120 TMR_PVR_DBG((
"[%s:%d]: Timer 0x%x starting", __FUNCTION__, __LINE__, timer->handle));
4122 timer->starting = TRUE;
4124 if (timer->u.record.duration == 0)
4127 TMR_PVR_DBG((
"[%s:%d]: Timer 0x%x has expired due to 0 duration!", __FUNCTION__,
4128 __LINE__, timer->handle));
4130 timer->expired = TRUE;
4131 timer_updated |= RescheduleTimer(timer);
4135 (
void *)&timer->handle,
sizeof(timer->handle));
4139 else if (recordings_can_start && timer->starting && !timer->missed &&
4140 (timer->u.record.path != INVALID_RES_ID))
4149 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_APPLICATION, EV_PVR_RECORDING_FAILED, NULL, 0);
4153 FUNCTION_FINISH(StartRecordTimer);
4155 return(timer_updated);
4158 static BOOLEAN HasTimerExpired(U32BIT handle)
4162 U32DHMS start_date_time, end_date_time;
4164 U8BIT start_day, wday, start_month;
4166 U8BIT end_day, end_month;
4170 FUNCTION_START(HasTimerExpired);
4175 if ((timer != NULL) && (timer->type == TIMER_TYPE_PVR_RECORD))
4177 if (timer->type == TIMER_TYPE_PVR_RECORD)
4179 GetActualStartEndTime(timer->start_time, timer->u.record.duration,
4180 GetStartPadding(timer), GetEndPadding(timer), &start_date_time, &end_date_time);
4184 start_date_time = timer->start_time;
4185 end_date_time = timer->start_time;
4189 STB_GCGetMJDDateInfo(DHMS_DATE(start_date_time), &start_day, &wday, &start_month, &start_year);
4191 TMR_DBG((
"Timer 0x%x, start:%d/%d/%d %02d:%02d, end %d/%d/%d %02d:%02d; started:%s starting:%s", timer->handle,
4192 start_day, start_month, start_year, DHMS_HOUR(start_date_time), DHMS_MINS(start_date_time),
4193 end_day, end_month, end_year, DHMS_HOUR(end_date_time), DHMS_MINS(end_date_time),
4194 timer->started ?
"TRUE" :
"FALSE", timer->starting ?
"TRUE" :
"FALSE"));
4197 if (timer->type == TIMER_TYPE_PVR_RECORD)
4199 if (!timer->u.record.event_triggered &&
4201 DHMS_MINS(end_date_time), DHMS_SECS(end_date_time)))
4203 TMR_PVR_DBG((
"[%s:%d]: Timer 0x%x expired", __FUNCTION__, __LINE__, timer->handle));
4206 else if (timer->u.record.event_triggered)
4208 if (timer->u.record.programme_finished &&
4210 DHMS_HOUR(end_date_time), DHMS_MINS(end_date_time), DHMS_SECS(end_date_time))))
4214 TMR_PVR_DBG((
"[%s:%d]: Timer 0x%x expired", __FUNCTION__, __LINE__, timer->handle));
4218 DHMS_HOUR(end_date_time), DHMS_MINS(end_date_time), DHMS_SECS(end_date_time)))
4222 TMR_PVR_DBG((
"[%s:%d]: Event missed, timer 0x%x expired", __FUNCTION__, __LINE__, timer->handle));
4228 DHMS_MINS(end_date_time), DHMS_SECS(end_date_time)))
4230 TMR_DBG((
"%s: Timer 0x%x expired", __FUNCTION__, timer->handle));
4237 timer->starting = FALSE;
4238 timer->expired = TRUE;
4240 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_TIMER, EV_TYPE_SUCCESS, (
void *)&timer->handle,
4241 sizeof(timer->handle));
4243 if (RescheduleTimer(timer))
4245 if (timer->type == TIMER_TYPE_PVR_RECORD)
4247 #ifdef INTEGRATE_HBBTV 4250 STB_ERSendEvent(FALSE, FALSE, EV_CLASS_APPLICATION, EV_PVR_BOOKING_CREATED,
4251 (
void *)&timer->handle,
sizeof(timer->handle));
4257 FUNCTION_FINISH(HasTimerExpired);
4264 BOOLEAN rescheduled;
4266 U8BIT hour, mins, secs;
4267 E_STB_GC_WEEKDAY wday;
4268 U8BIT oohour, oomin, nohour, nomin;
4269 BOOLEAN ooneg, noneg;
4270 BOOLEAN check_offset = FALSE;
4272 FUNCTION_START(RescheduleTimer);
4274 rescheduled = FALSE;
4277 timer->started = FALSE;
4279 code = DHMS_DATE(timer->start_time);
4280 hour = DHMS_HOUR(timer->start_time);
4281 mins = DHMS_MINS(timer->start_time);
4282 secs = DHMS_SECS(timer->start_time);
4288 switch (timer->frequency)
4290 case TIMER_FREQ_ONCE:
4294 case TIMER_FREQ_WEEKLY:
4297 check_offset = TRUE;
4301 case TIMER_FREQ_WEEKENDDAYS:
4304 if (wday == WEEKDAY_MONDAY)
4306 if (wday == WEEKDAY_TUESDAY)
4308 if (wday == WEEKDAY_WEDNESDAY)
4310 if (wday == WEEKDAY_THURSDAY)
4312 if (wday == WEEKDAY_FRIDAY)
4314 if (wday == WEEKDAY_SATURDAY)
4316 if (wday == WEEKDAY_SUNDAY)
4318 check_offset = TRUE;
4322 case TIMER_FREQ_WEEKDAYS:
4325 if (wday == WEEKDAY_MONDAY)
4327 if (wday == WEEKDAY_TUESDAY)
4329 if (wday == WEEKDAY_WEDNESDAY)
4331 if (wday == WEEKDAY_THURSDAY)
4333 if (wday == WEEKDAY_FRIDAY)
4335 if (wday == WEEKDAY_SATURDAY)
4337 if (wday == WEEKDAY_SUNDAY)
4339 check_offset = TRUE;
4343 case TIMER_FREQ_DAILY:
4346 check_offset = TRUE;
4350 case TIMER_FREQ_HOURLY:
4352 hour = DHMS_HOUR(timer->start_time) + 1;
4367 if (check_offset == TRUE)
4370 if ((oohour != nohour) || (oomin != nomin) || (ooneg != noneg))
4375 &code, &hour, &mins, &secs, CALC_SUB);
4380 &code, &hour, &mins, &secs, CALC_ADD);
4386 &code, &hour, &mins, &secs, CALC_ADD);
4391 &code, &hour, &mins, &secs, CALC_SUB);
4397 timer->start_time = DHMS_CREATE(code, hour, mins, secs);
4399 if (timer->dba_rec != NULL)
4401 DBA_SetFieldValue(timer->dba_rec, DBA_FIELD_TIMER_STARTTIME, timer->start_time);
4404 if (rescheduled && (timer->type == TIMER_TYPE_PVR_RECORD))
4407 timer->u.record.notified = FALSE;
4410 FUNCTION_FINISH(RescheduleTimer);
4412 return(rescheduled);
4421 static void AlternateEventTask(
void *param)
4426 void *alt_event_ptr;
4427 #ifdef TMR_PVR_DEBUG 4430 U8BIT *new_prog_crid;
4432 USE_UNWANTED_PARAM(param);
4436 if (
STB_OSReadQueue(alt_event_queue, &alt_event_data,
sizeof(alt_event_data), TIMEOUT_NEVER))
4441 if (event_ptr != NULL)
4443 #ifdef TMR_PVR_DEBUG 4449 DeleteTimer(alt_event_data.timer_handle);
4452 TMR_PVR_DBG((
"Alternative event found for \"%s\" on %lu @ %02lu:%02lu on LCN %d\n",
4459 alt_event_data.other_crid, alt_event_data.is_recommendation, TRUE,
4460 alt_event_data.do_not_delete);
4462 if ((alt_event_ptr != NULL) && (alt_event_ptr != event_ptr))
4487 static void GetActualStartEndTime(U32DHMS timer_start, U32DHMS timer_duration, S32BIT start_padding, S32BIT end_padding,
4488 U32DHMS *start_time, U32DHMS *end_time)
4490 U32BIT pad_hours, pad_mins, pad_secs;
4492 if (start_padding == 0)
4494 *start_time = timer_start;
4500 pad_secs = (start_padding < 0) ? (-1 * start_padding) : start_padding;
4502 while (pad_secs > 59)
4507 while (pad_mins > 59)
4513 if (start_padding > 0)
4527 if (end_padding != 0)
4531 pad_secs = (end_padding < 0) ? (-1 * end_padding) : end_padding;
4533 while (pad_secs > 59)
4538 while (pad_mins > 59)
4544 if (end_padding > 0)
4569 timer->type = info->type;
4571 if ((info->frequency != TIMER_FREQ_ONCE) &&
4572 (info->frequency != TIMER_FREQ_WEEKLY) &&
4573 (info->frequency != TIMER_FREQ_WEEKENDDAYS) &&
4574 (info->frequency != TIMER_FREQ_WEEKDAYS) &&
4575 (info->frequency != TIMER_FREQ_DAILY))
4577 timer->frequency = TIMER_FREQ_ONCE;
4581 timer->frequency = info->frequency;
4584 timer->start_time = info->start_time;
4588 memcpy(timer->name, info->name, name_len);
4595 if (timer->dba_rec != NULL)
4599 DBA_SetFieldValue(timer->dba_rec, DBA_FIELD_TIMER_STARTTIME, timer->start_time);
4603 switch (timer->type)
4605 case TIMER_TYPE_ALARM:
4607 timer->u.alarm.change_service = info->u.alarm.change_service;
4609 timer->u.alarm.orig_net_id = info->u.alarm.orig_net_id;
4610 timer->u.alarm.transport_id = info->u.alarm.transport_id;
4611 timer->u.alarm.service_id = info->u.alarm.service_id;
4613 timer->u.alarm.ramp_volume = info->u.alarm.ramp_volume;
4615 if (timer->dba_rec != NULL)
4617 DBA_SetFieldValue(timer->dba_rec, DBA_FIELD_ORIG_NET_ID, timer->u.alarm.orig_net_id);
4618 DBA_SetFieldValue(timer->dba_rec, DBA_FIELD_TRANSPORT_ID, timer->u.alarm.transport_id);
4619 DBA_SetFieldValue(timer->dba_rec, DBA_FIELD_SERVICE_ID, timer->u.alarm.service_id);
4620 DBA_SetFieldValue(timer->dba_rec, DBA_FIELD_TIMER_RAMPVOLUME, timer->u.alarm.ramp_volume);
4625 case TIMER_TYPE_PVR_RECORD:
4627 timer->u.record.duration = info->u.record.duration;
4629 timer->u.record.event_triggered = info->u.record.event_triggered;
4630 timer->u.record.event_id = info->u.record.event_id;
4632 timer->u.record.orig_net_id = info->u.record.orig_net_id;
4633 timer->u.record.transport_id = info->u.record.transport_id;
4634 timer->u.record.service_id = info->u.record.service_id;
4636 timer->u.record.disk_id = info->u.record.disk_id;
4638 timer->u.record.recommendation = info->u.record.recommendation;
4640 if (info->u.record.start_padding != timer->u.record.start_padding)
4642 timer->u.record.has_start_padding = TRUE;
4643 timer->u.record.start_padding = info->u.record.start_padding;
4646 if (info->u.record.end_padding != timer->u.record.end_padding)
4648 timer->u.record.has_end_padding = TRUE;
4649 timer->u.record.end_padding = info->u.record.end_padding;
4652 timer->u.record.notify_time = info->u.record.notify_time;
4653 timer->u.record.do_not_delete = info->u.record.do_not_delete;
4657 memcpy(timer->u.record.prog_crid, info->u.record.prog_crid, name_len);
4658 if (timer->dba_rec != NULL)
4660 DBA_SetFieldString(timer->dba_rec, DBA_FIELD_TIMER_CRID, timer->u.record.prog_crid, name_len);
4665 timer->u.record.prog_crid[0] =
'\0';
4670 memcpy(timer->u.record.other_crid, info->u.record.other_crid, name_len);
4671 if (timer->dba_rec != NULL)
4673 DBA_SetFieldString(timer->dba_rec, DBA_FIELD_TIMER_OTHERCRID, timer->u.record.other_crid, name_len);
4678 timer->u.record.other_crid[0] =
'\0';
4681 if (timer->dba_rec != NULL)
4683 DBA_SetFieldValue(timer->dba_rec, DBA_FIELD_TIMER_DURATION, timer->u.record.duration);
4685 timer->u.record.event_triggered);
4686 DBA_SetFieldValue(timer->dba_rec, DBA_FIELD_TIMER_EVENTID, timer->u.record.event_id);
4687 DBA_SetFieldValue(timer->dba_rec, DBA_FIELD_ORIG_NET_ID, timer->u.record.orig_net_id);
4688 DBA_SetFieldValue(timer->dba_rec, DBA_FIELD_TRANSPORT_ID, timer->u.record.transport_id);
4689 DBA_SetFieldValue(timer->dba_rec, DBA_FIELD_SERVICE_ID, timer->u.record.service_id);
4690 DBA_SetFieldValue(timer->dba_rec, DBA_FIELD_TIMER_DISKID, timer->u.record.disk_id);
4691 DBA_SetFieldValue(timer->dba_rec, DBA_FIELD_CRID_RECOMMENDED, timer->u.record.recommendation);
4692 DBA_SetFieldValue(timer->dba_rec, DBA_FIELD_TIMER_NOTIFY_TIME, timer->u.record.notify_time);
4693 DBA_SetFieldValue(timer->dba_rec, DBA_FIELD_TIMER_DO_NOT_DELETE, timer->u.record.do_not_delete);
4694 DBA_SetFieldValue(timer->dba_rec, DBA_FIELD_TIMER_START_PADDING, timer->u.record.start_padding);
4695 DBA_SetFieldValue(timer->dba_rec, DBA_FIELD_TIMER_END_PADDING, timer->u.record.end_padding);
4698 timer->u.record.path = INVALID_RES_ID;
4723 static U8BIT GetNumSimultaneousRecordings(U32BIT handle, U16BIT onet_id, U16BIT trans_id,
4724 U16BIT serv_id, U8BIT max_recordings, U32DHMS start_date_time,
4725 U32DHMS end_date_time, BOOLEAN include_start_padding, BOOLEAN include_end_padding,
4726 U32BIT **conflicting_timers)
4729 U32DHMS timer_duration;
4730 U32DHMS timer_end, timer_start;
4732 U8BIT slot, max_slot;
4749 TMR_PVR_DBG((
"GetNumSimultaneousRecordings(0x%x): between %02d.%02d -> %02d.%02d, max_recordings=%d",
4750 handle, DHMS_HOUR(start_date_time), DHMS_MINS(start_date_time), DHMS_HOUR(end_date_time),
4751 DHMS_MINS(end_date_time), max_recordings));
4755 if (conflicting_timers != NULL)
4757 *conflicting_timers = (U32BIT *)
STB_AppGetMemory(max_recordings *
sizeof(U32BIT));
4758 if (*conflicting_timers != NULL)
4760 for (slot = 0; slot < max_recordings; slot++)
4762 (*conflicting_timers)[slot] = INVALID_TIMER_HANDLE;
4771 if ((timer->type == TIMER_TYPE_PVR_RECORD) &&
4772 ((handle == INVALID_TIMER_HANDLE) || (timer->handle != handle)) &&
4773 !timer->expired && !timer->missed)
4777 if (timer->dba_rec != NULL)
4783 timer_duration = timer->u.record.duration;
4786 GetActualStartEndTime(timer->start_time, timer_duration,
4787 (include_start_padding ? GetStartPadding(timer) : 0),
4788 (include_end_padding ? GetEndPadding(timer) : 0),
4789 &timer_start, &timer_end);
4791 TMR_PVR_DBG((
"GetNumSimultaneousRecordings: Timer 0x%08lx: %u @ %02d.%02d -> %02d.%02d",
4792 timer->handle, DHMS_DATE(timer_start), DHMS_HOUR(timer_start), DHMS_MINS(timer_start),
4793 DHMS_HOUR(timer_end), DHMS_MINS(timer_end)));
4798 if ((timer_end > start_date_time) && (timer_start < end_date_time) &&
4799 ((onet_id != timer->u.record.orig_net_id) ||
4800 (trans_id != timer->u.record.transport_id) ||
4801 (serv_id != timer->u.record.service_id)))
4806 for (slot = 0; !slot_found && (slot < max_slot) && (slot < max_recordings); )
4808 if (timer_start >= timer_slot[slot].end_time)
4810 TMR_PVR_DBG((
"GetNumSimultaneousRecordings: Using slot %d", slot));
4813 timer_slot[slot].start_time = timer_start;
4814 timer_slot[slot].end_time = timer_end;
4816 if ((conflicting_timers != NULL) && (*conflicting_timers != NULL))
4818 TMR_PVR_DBG((
"[%s:%d] Saving timer 0x%x\n", __FUNCTION__, __LINE__, timer->handle));
4819 (*conflicting_timers)[slot] = timer->handle;
4830 if (!slot_found && (max_slot < max_recordings))
4832 TMR_PVR_DBG((
"GetNumSimultaneousRecordings: New slot %d", max_slot));
4834 timer_slot[max_slot].start_time = timer_start;
4835 timer_slot[max_slot].end_time = timer_end;
4837 if ((conflicting_timers != NULL) && (*conflicting_timers != NULL))
4839 (*conflicting_timers)[max_slot] = timer->handle;
4855 static BOOLEAN SetStartPadding(
ADB_TIMER_REC *timer, S32BIT padding)
4859 if ((timer != NULL) && (timer->type == TIMER_TYPE_PVR_RECORD))
4861 timer->u.record.has_start_padding = TRUE;
4862 timer->u.record.start_padding = padding;
4880 if ((timer != NULL) && (timer->type == TIMER_TYPE_PVR_RECORD))
4882 if (timer->u.record.has_start_padding)
4884 padding = timer->u.record.start_padding;
4895 static BOOLEAN SetEndPadding(
ADB_TIMER_REC *timer, S32BIT padding)
4899 if ((timer != NULL) && (timer->type == TIMER_TYPE_PVR_RECORD))
4901 timer->u.record.has_end_padding = TRUE;
4902 timer->u.record.end_padding = padding;
4904 if (timer->dba_rec != NULL)
4907 timer->u.record.end_padding);
4931 if ((timer != NULL) && (timer->type == TIMER_TYPE_PVR_RECORD))
4933 if (timer->u.record.has_end_padding)
4935 padding = timer->u.record.end_padding;
4953 FUNCTION_START(DumpTimer);
4955 TMR_DBG((
"Timer 0x%08lx: ", timer->handle));
4956 TMR_DBG((
" name=\"%s\"", timer->name));
4957 TMR_DBG((
" freq=%u", timer->frequency));
4958 TMR_DBG((
" starts on=%u %02u:%02u:%02u",
4959 DHMS_DATE(timer->start_time), DHMS_HOUR(timer->start_time), DHMS_MINS(timer->start_time),
4960 DHMS_SECS(timer->start_time)));
4962 switch (timer->type)
4964 case TIMER_TYPE_SLEEP:
4965 TMR_DBG((
" type=SLEEP"));
4968 case TIMER_TYPE_ALARM:
4969 TMR_DBG((
" type=ALARM"));
4970 TMR_DBG((
" ramp volume=%u", timer->u.alarm.ramp_volume));
4971 TMR_DBG((
" change service=%u", timer->u.alarm.change_service));
4972 TMR_DBG((
" service=0x%04x/0x%04x/0x%04x", timer->u.alarm.orig_net_id,
4973 timer->u.alarm.transport_id, timer->u.alarm.service_id));
4976 case TIMER_TYPE_PVR_RECORD:
4977 TMR_DBG((
" type=PVR RECORD"));
4978 TMR_DBG((
" duration=%02u:%02u", DHMS_HOUR(timer->u.record.duration),
4979 DHMS_MINS(timer->u.record.duration)));
4980 TMR_DBG((
" event triggered=%u", timer->u.record.event_triggered));
4981 if (timer->u.record.event_triggered)
4983 TMR_DBG((
" event id=%u", timer->u.record.event_id));
4985 TMR_DBG((
" service=0x%04x/0x%04x/0x%04x", timer->u.record.orig_net_id,
4986 timer->u.record.transport_id, timer->u.record.service_id));
4987 TMR_DBG((
" disk id=0x%04x", timer->u.record.disk_id));
4988 if (strlen((
char *)timer->u.record.prog_crid) != 0)
4990 TMR_DBG((
" prog crid=\"%s\"", timer->u.record.prog_crid));
4992 if (strlen((
char *)timer->u.record.other_crid) != 0)
4994 TMR_DBG((
" other crid=\"%s\"", timer->u.record.other_crid));
4995 TMR_DBG((
" recommendation=%u", timer->u.record.recommendation));
4997 TMR_DBG((
" start padding=%u", timer->u.record.start_padding));
4998 TMR_DBG((
" end padding=%u", timer->u.record.end_padding));
4999 TMR_DBG((
" notify time=%u", timer->u.record.notify_time));
5000 TMR_DBG((
" do_not_delete=%u", timer->u.record.do_not_delete));
5001 TMR_DBG((
" recording handle=%08x", timer->u.record.recording_handle));
5002 TMR_DBG((
" path=%u", timer->u.record.path));
5006 TMR_DBG((
" type=OTHER(0x%02x)", timer->type));
5010 TMR_DBG((
" starting=%u", timer->starting));
5011 TMR_DBG((
" started=%u", timer->started));
5012 TMR_DBG((
" expired=%u", timer->expired));
5013 TMR_DBG((
" missed=%u", timer->missed));
5014 TMR_DBG((
" selected=%u", timer->selected));
5016 FUNCTION_FINISH(DumpTimer);
U32BIT ATMR_FindTimerFromEvent(U16BIT onet_id, U16BIT trans_id, U16BIT serv_id, U16BIT event_id)
Searches the timers for a recording timer with the given event and service IDs.
U32BIT ATMR_FindTimerFromCridAndEvent(U8BIT *prog_crid, U16BIT service_id, U16BIT event_id)
Searches the timers for a recording timer with the given programme CRID and event ID...
U32DHMS ADB_GetEventDuration(void *event_ptr)
Returns a value representing the duration of the given event.
U32DHMS STB_GCCalculateDHMS(U32DHMS dhms, U32DHMS period, E_STB_GC_CALCTYPE calc)
Calculates the date/time when the period is added/subtracted to/from dhms.
U8BIT STB_GCGetGMTDay(void)
Reads the current GMT day number.
U8BIT * ADB_GetEventSeriesCrid(U8BIT index, void *serv_ptr, void *event_ptr)
Returns the full series CRID of the given event The returned string should be freed using STB_AppFree...
U32DHMS STB_GCCreateDHMSFromSeconds(U32BIT num_seconds)
Creates a DHMS value consisting of hours, minutes and seconds from a number of seconds.
BOOLEAN ATMR_HasRecommendationCrid(U32BIT handle)
Does the timer have a recommendation crid?
E_TIMER_FREQ ATMR_GetFrequency(U32BIT handle)
Returns the frequency setting for the given timer.
void ADB_SaveDatabase(void)
Saves the database to non-volatile memory.
macros and function prototypes for public use
BOOLEAN ATMR_HasSeriesCrid(U32BIT handle)
Does the timer have a series crid?
U16BIT ATMR_GetEventId(U32BIT handle)
Returns the event ID for a PVR recording timer.
U8BIT * ADB_GetEventFullProgrammeCrid(void *serv_ptr, void *event_ptr)
Returns the full programme CRID of the given event (including IMI). The returned string should be fre...
Function prototypes for HW control.
U8BIT STB_GCGetGMTMin(void)
Reads the current GMT minute.
void ATMR_DeleteTimersForSeriesRecommendations(U8BIT *crid, BOOLEAN is_recommendation)
Deletes any PVR record timers with the given series CRID.
void STB_PVRRecordingSetEndPadding(U32BIT handle, S32BIT end_padding)
Sets the end padding value for the specified recording.
void * ADB_GetEvent(void *serv_ptr, U16BIT event_id)
Returns a copy of the event with the given event ID on the given service.
U16BIT ATMR_GetOriginalNetworkId(U32BIT handle)
Returns the original network ID for an alarm or PVR recording timer.
BOOLEAN STB_DPIsLivePath(U8BIT path)
Is the given decode path being used for live viewing.
Application configuration.
void ATMR_Initialise(void)
Performs initialisation of the timers, reading existing entries from the database, rescheduling or deleting any timers that have been missed and starting background tasks.
Application database control.
U32DHMS STB_GCNowDHMSGmt(void)
Reads the current GMT date code and time.
void ATMR_RecordingFailed(U8BIT path)
Handles the timer when a recording fails to start for some reason. This may result in the timer being...
U32BIT ATMR_AddTimer(S_TIMER_INFO *info)
Creates a new timer based on the information supplied.
Header file - macros and function prototypes for public use.
void STB_GCGetLocalTimeChange(U16BIT code, U8BIT hour, U8BIT min, U8BIT secs, U8BIT *ohour, U8BIT *omin, BOOLEAN *neg)
Reads local time offset from GMT.
void ACTL_TuneOff(U8BIT path)
Stops tuning on the given path.
BOOLEAN ATMR_UpdateTimerDuration(U32BIT handle, U32DHMS duration)
Updates the duration for an existing PVR recording timer.
void STB_PVRRecordingSetAdditionalInfo(U32BIT handle, U8BIT *additional_info)
Sets the additional info string for a recording.
S32BIT ATMR_GetStartPadding(U32BIT handle)
Returns the value of start padding associated with the specified timer The start padding is the numbe...
U32DHMS ADB_GetEventStartDateTime(void *event_ptr)
Returns a value representing the date and time of the start of the given event.
void * STB_AppGetMemory(U32BIT bytes)
Attempts to allocate memory from the application heap.
BOOLEAN ATMR_SetDoNotDelete(U32BIT handle, BOOLEAN do_not_delete)
Sets the do_not_delete flag in a recording timer, which if set to TRUE, will lock any recordings that...
ADB_SERVICE_REC * DBDEF_FindServiceRecByIds(ADB_SERVICE_REC *servp, U32BIT net_id, U32BIT onet_id, U32BIT tran_id, U32BIT serv_id)
Search for a service with the given IDs.
U8BIT * ADB_GetEventProgrammeCrid(void *serv_ptr, void *event_ptr)
Returns the programme CRID of the given event (excluding IMI) The returned string should be freed usi...
U16BIT ATMR_GetServiceId(U32BIT handle)
Returns the service ID for an alarm or PVR recording timer.
U16BIT ADB_GetEventStartDate(void *event_ptr)
Returns the MJD date code for the start of the given event.
void DBA_SaveRecord(void *record)
Forces a record to be saved to non-volatile storage. Depending on the implementation, this function may not do anything if the data is updated to non-volatile storage as any records and/or fields are created or updated.
void DBDEF_DeleteTimerRec(ADB_TIMER_REC *timer)
Deletes the given timer from the database.
void STB_DPStopRecording(U8BIT path)
Requests stop of recording on specified path.
void STB_GCCalculateDateTime(U16BIT code, U8BIT hour, U8BIT min, U8BIT secs, U8BIT ohour, U8BIT omin, U8BIT osecs, U16BIT *rcode, U8BIT *rhour, U8BIT *rmin, U8BIT *rsecs, E_STB_GC_CALCTYPE calc)
Adds or subtracts offset from a date/time.
BOOLEAN ATMR_GetTimerInfo(U32BIT handle, S_TIMER_INFO *timer_info)
Copies timer data for the given timer info the info structure provided.
BOOLEAN ATMR_CheckRecordStatus(BOOLEAN recordings_can_start, void *service)
Checks all timers to see whether any recordings should be started or stopped as a result of the now e...
PVR messages database access functions header file.
BOOLEAN APVR_StartNewRecording(U16BIT disk_id, U8BIT path, U8BIT *recording_name, U16BIT event_id, U8BIT *prog_crid, U8BIT *other_crid, U32BIT *rec_handle)
Starts a recording after any tuning has completed and sets the info to be stored with it...
U8BIT ATMR_GetNumSimultaneousRecordings(U8BIT max_recordings, U32DHMS start_date_time, U32DHMS end_date_time, U32BIT **conflicting_timers)
Counts the number of simultaneous recordings (EXT and PVR) between the given start and end dates/time...
void STB_PVRRecordingSetStartPadding(U32BIT handle, S32BIT start_padding)
Sets the start padding value for the specified recording.
BOOLEAN ATMR_GetTimerList(U32BIT **timer_list, U16BIT *list_size_ptr, E_TIMER_TYPE list_type, BOOLEAN date_time_order)
Returns a list of all the timer handles and the number of items in the list.
U32BIT ATMR_AddTimerForEvent(void *event_ptr, void *serv_ptr, BOOLEAN record, BOOLEAN event_triggered)
Creates a timer based on the given event. If a recording timer is created, it will be set to record o...
U32DHMS STB_GCCreateDHMS(U16BIT date, U8BIT hour, U8BIT mins, U8BIT secs)
Makes U32DHMS formated date/time from date code, hour, minutes, seconds.
void * ADB_FindServiceByIds(U16BIT onet_id, U16BIT tid, U16BIT sid)
Returns a pointer to the service matching the given IDs.
void ASTE_StartRecording(void)
Application timer functions and defines.
void ADB_GetNowNextEvents(void *serv_ptr, void **now_event, void **next_event)
Makes copies of the now and/or next events (EITp/f) for the given service. The returned events should...
BOOLEAN ATMR_InitialiseTimer(S_TIMER_INFO *timer_info, E_TIMER_TYPE timer_type, void *serv_ptr, void *event_ptr)
Sets up the given timer info structure with default values for the given timer type using the service...
BOOLEAN STB_DPReleasePath(U8BIT path, E_STB_DP_RES_OWNER owner)
Releases the decode path and all resources no longer needed. The path won't be released if the path i...
Header file - macros and function prototypes for public use.
S32BIT ATMR_GetEndPadding(U32BIT handle)
Returns the value of end padding associated with the specified timer The end padding is the number of...
U8BIT ADB_GetEventStartMin(void *event_ptr)
Returns the minute (0-59) value for the start of the given event.
void STB_ERSendEvent(BOOLEAN latched, BOOLEAN repeat, U16BIT path_class, U16BIT type, void *data, U32BIT data_size)
Sends an event to event reporting control module.
BOOLEAN ATMR_SetStartPadding(U32BIT handle, S32BIT start_padding)
Sets the value of start padding associated with the specified timer The start padding is the number o...
U32BIT ATMR_GetFirstWakeupTime(U32DHMS *date_time, U16BIT *onet_id, U16BIT *trans_id, U16BIT *service_id)
Searches the timers for the first timer that will cause the DVB to wakeup that hasn't been missed...
U16BIT ATMR_GetDiskId(U32BIT handle)
Returns the disk id for the given timer if the timer is a PVR recording timer.
U8BIT * ATMR_GetName(U32BIT handle)
Get the name of the timer with the given handle.
U8BIT STB_GCGetGMTMonth(void)
Reads the current GMT month number.
U8BIT APVR_PrepareNewRecording(U16BIT onet_id, U16BIT trans_id, U16BIT service_id, BOOLEAN *new_tuned_service)
Acquires a decode path for recording the given service and tunes to it.
U16BIT ATMR_GetTransportId(U32BIT handle)
Returns the transport ID for an alarm or PVR recording timer.
void STB_PVRStartRecordRunning(U8BIT path)
Set to start recording in running mode.
U8BIT ADB_GetEventDurationMin(void *event_ptr)
Returns the minute value (0-59) for the duration of the given event.
void STB_ReleaseUnicodeString(U8BIT *string)
Releases the specified unicode string, freeing associated heap resources.
BOOLEAN ATMR_GetMissed(U32BIT handle)
Gets the timer's missed flag.
U16BIT STB_GCGetGMTYear(void)
Reads the current GMT year number.
void DBDEF_ReleaseAccess(void)
Releases access to the app's database.
void ATMR_DumpAllTimers(void)
Prints details of all existing timers.
U16BIT ADB_GetServiceLcn(void *s_ptr)
Returns the logical channel number assigned to the given service.
BOOLEAN ACFG_IsNordigCountry(void)
Returns whether the current country requires Nordig compliance for SI.
BOOLEAN DBA_SetFieldString(void *record, U32BIT field_id, U8BIT *string, U16BIT num_bytes)
Set the string value of a record's field. The function will fail if the record doesn't exist...
void ATMR_ReleaseTimerList(U32BIT *timer_list, U16BIT list_size)
Release the given array of timer handles.
U32DHMS ATMR_GetStartDateTime(U32BIT handle)
Get the start date & time of the timer with the given handle. The date/time returned will be in UTC...
Debug functions header file.
Header file - Function prototypes for linked lists.
Header file - macros and function prototypes for public use.
U8BIT * ATMR_GetOtherCrid(U32BIT handle)
Returns a pointer to the other CRID string from a recording timer. This will either be a series or re...
Header file - macros and function prototypes for public use.
Database access defines, structures and public functions.
U8BIT ADB_GetEventDurationHour(void *event_ptr)
Returns the hour value for the duration of the given event.
void * ADB_GetLaterEvent(void *serv_ptr, U16BIT date, U8BIT hour, U8BIT min)
Returns a copy of the event following the given date/time on the given service.
void * ATMR_RecordEvent(void *serv_ptr, void *event_ptr, U8BIT *prog_crid, U8BIT *other_crid, BOOLEAN is_recommendation, BOOLEAN check_alternatives, BOOLEAN do_not_delete)
Adds a timer to perform a recording based on the given event and service. Conflicts are checked and a...
Header file - Function prototypes for Event Reporting.
BOOLEAN ATMR_DeleteTimer(U32BIT handle)
Delete the timer with the given handle.
Header for STB unicode string handling routines.
void * ATMR_GetRecordService(U8BIT path)
Returns the service for the recording timer on the given path.
void ATMR_SetName(U32BIT handle, U8BIT *name)
Sets the name of the timer with the given handle.
void * ADB_FindEventFromCrid(U8BIT *prog_crid, void *original_event_ptr, void **serv_ptr)
Finds an alternative event for the given programme CRID and returns a pointer to a copy of the event ...
void * ADB_GetEarlierEvent(void *serv_ptr, U16BIT date, U8BIT hour, U8BIT min)
Returns a copy of the event preceeding the given date/time on the given service.
void DBDEF_RequestAccess(void)
Requests access to the app's database.
U8BIT ACTL_TuneToService(U8BIT path, S_ACTL_OWNER_INFO *owner_info, void *s_ptr, BOOLEAN override_lock, BOOLEAN for_live)
Starts the process of tuning to the specified service. If the service is to be tuned on the live path...
BOOLEAN ATMR_StartRecord(U8BIT path)
Finds the timer using the given decode path and if it's a recording timer the recording will be start...
U32BIT ATMR_GetRecordingHandle(U32BIT handle)
Returns the recording handle associated with a PVR recording timer.
void ATMR_DeleteRecordingTimer(U32BIT recording_handle)
Delete the PVR record timer with the given recording handle.
BOOLEAN STB_GCIsFutureDateTime(U16BIT code, U8BIT hour, U8BIT min, U8BIT secs)
Tests given date and time against current GMT date and time.
U16BIT ADB_GetServiceId(void *s_ptr)
Returns the signalled service id of the given service.
U32BIT ACFG_GetCountry(void)
Returns the country code the DVB is configured for.
U32BIT STB_GetNumBytesInString(U8BIT *string_ptr)
Determines the no of bytes of the given string.
Application stb layer control.
BOOLEAN STB_OSWriteQueue(void *queue, void *msg, U16BIT msg_size, U16BIT timeout)
Write a message to the queue.
Header file - Function prototypes for operating system.
System Wide Global Technical Data Type Definitions.
void STB_DPStopSI(U8BIT path)
Requests stop of SI engine.
BOOLEAN DBA_SetFieldValue(void *record, U32BIT field_id, U32BIT value)
Set the value of a record's field. The function will fail if the record doesn't exist, the record doesn't include the given field, or the field is a string value.
BOOLEAN APVR_StopRecording(U32BIT recording_handle)
Stops the given recording.
void STB_AppFreeMemory(void *addr)
Releases previously allocated application heap memory.
Application level HBBTV callback functions.
U8BIT STB_GCGetGMTHour(void)
Reads the current GMT hour.
BOOLEAN STB_PVRRecordingSetLocked(U32BIT handle, BOOLEAN state)
Sets the locked state of a recording.
U8BIT ADB_GetEventStartHour(void *event_ptr)
Returns the hour (0-23) value for the start of the given event.
BOOLEAN ATMR_GetRampVolume(U32BIT handle)
Returns the ramp volume setting for an alarm timer.
void * STB_OSCreateTask(void(*function)(void *), void *param, U32BIT stack, U8BIT priority, U8BIT *name)
Create a New Task to the calling process. Upon success, the created task runs on its own stack...
void * STB_OSCreateQueue(U16BIT msg_size, U16BIT msg_max)
Create Queue of given number of messages and size of message.
S8BIT STB_CompareStringsIgnoreCase(U8BIT *string1_ptr, U8BIT *string2_ptr)
Compares the contents of the two given ASCII strings and returns the status (as per strcmp) but ignor...
S32BIT APVR_GetStartPadding(void)
Returns the current setting for the start padding time added to all recording timers.
void STB_GCGetMJDDateInfo(U16BIT code, U8BIT *day, U8BIT *wday, U8BIT *month, U16BIT *year)
Returns the date info from the given MJD date code.
U32BIT ATMR_FindRecordingTimer(U32BIT recording_handle)
Finds the timer for the given recording handle.
Header file - Function prototypes for heap memory.
void ADB_GetServiceIds(void *s_ptr, U16BIT *onet_id, U16BIT *trans_id, U16BIT *serv_id)
Returns the original network id, transport id and service id for the given service.
U8BIT * ATMR_GetProgrammeCrid(U32BIT handle)
Returns a pointer to the programme CRID string from a recording timer. The returned value shouldn't b...
void ATMR_SetAdditionalInfo(U32BIT handle, U8BIT *info, U32BIT size)
Sets the additioinal information string for the specified timer and commits the change to the databas...
U8BIT * ATMR_GetAdditionalInfo(U32BIT handle, U32BIT *size)
Gets the additional information string associated with a timer. The name is allocated in UI temp memo...
void DBDEF_SortTimers(BOOLEAN date_time_order)
Sorts timer list into date/time or alphabetical order.
BOOLEAN STB_OSReadQueue(void *queue, void *msg, U16BIT msg_size, U16BIT timeout)
Read a message from a queue.
U32DHMS ADB_GetEventEndDateTime(void *event_ptr)
Returns a value representing the date and time of the end of the given event.
U8BIT STB_HWGetNumRecorders(void)
Returns the number of recordings that can take place at the same time.
Function prototypes for disk functions.
void HBBTV_NotifyRecordingEvent(U32BIT id, E_HBBTV_RECORDING_EVENT event)
Notifies the HbbTV engine of a recording event.
BOOLEAN ATMR_GetChangeService(U32BIT handle)
Returns the change service setting for an alarm timer.
void STB_OSTaskDelay(U16BIT timeout)
Delay Task for Specifed Time Period.
U16BIT STB_GCGetGMTDate(void)
Reads the current GMT date code.
BOOLEAN ATMR_SetEndPadding(U32BIT handle, S32BIT end_padding)
Sets the value of end padding associated with the specified timer The end padding is the number of se...
U16BIT ADB_GetEventId(void *event_ptr)
Returns the event id for the given event.
BOOLEAN ATMR_RecordSplitEvent(void *serv_ptr, U8BIT *prog_crid, U32DHMS start_date_time, BOOLEAN do_not_delete, BOOLEAN search_forward)
Searches for events within 3 hours of the given start date/time for an event with the given programme...
S32BIT APVR_GetEndPadding(void)
Returns the current setting for the end padding time added to all recording timers.
ADB_TIMER_REC * DBDEF_GetNextTimerRec(ADB_TIMER_REC *timer_ptr)
Returns the next timer record after the one given. If the argument is NULL then the first record is r...
BOOLEAN DBA_GetFieldValue(void *record, U32BIT field_id, U32BIT *value)
Gets the value of a record's field. The function will fail if the record doesn't exist, the record doesn't include the given field, or the field is a string value.
E_TIMER_TYPE ATMR_GetType(U32BIT handle)
Returns the type of the given timer.
BOOLEAN APVR_DeleteRecording(U32BIT handle)
Delete the given recording, including all files associated with it and remove it from the database of...
BOOLEAN ATMR_UpdateTimer(U32BIT handle, S_TIMER_INFO *info)
Updates all the timer fields.
ADB_TIMER_REC * DBDEF_AddTimerRec(BOOLEAN store_in_nvm)
Creates a new timer record in the database, assigning it a unique handle.
U16BIT APVR_GetNotifyTime(void)
Returns the current recording notification time in seconds.
U8BIT * ADB_GetEventName(void *event_ptr)
Returns the name of the event as a UTF-8 string. The returned string should be freed using STB_Releas...
U32DHMS ATMR_GetEndDateTime(U32BIT handle)
Get the end date & time of the timer with the given handle. The date/time returned will be in UTC...
U32BIT ATMR_FindTimerFromCrid(U8BIT *prog_crid)
Searches the timers for a recording timer with the given programme CRID.
U16BIT STB_PVRGetDefaultDisk(void)
Returns the set default disk, or finds the first mounted (usable) disk if a default hasn't been set...
U32DHMS ATMR_GetDuration(U32BIT handle)
Returns the duration of the PVR record timer with the given handle.
void ATMR_HandleTimerEvent(U32BIT handle)
Used by the DVB stack to handle an event for the given timer. If the timer requires the app to deal w...
Application database access functions.
BOOLEAN ATMR_GetDoNotDelete(U32BIT handle)
Returns the setting of the do not delete flag for the given timer.
ADB_TIMER_REC * DBDEF_FindTimerRec(U32BIT handle)
Returns the timer record with the given timer handle.
Header file - macros and function prototypes for public use.
void ATMR_EitUpdated(void)
Checks each recording timer that's linked to an event to see whether the event is still in the schedu...
E_STB_GC_WEEKDAY STB_GCGetDateWeekDay(U16BIT code)
Returns the weekday number of the specified date code.
void ATMR_SetDiskId(U32BIT handle, U16BIT disk_id)
Set the disk for the given timer if the timer is a recording timer.
void ADB_ReleaseEventData(void *event_ptr)
Frees any memory allocated for the given event and the event itself.