RDK Documentation (Open Sourced RDK Components)
Executors.cpp
1 /*
2  * If not stated otherwise in this file or this component's Licenses.txt file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2016 RDK Management
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18 */
19 
20 
21 /**
22 * @defgroup trm
23 * @{
24 * @defgroup qtapp
25 * @{
26 **/
27 
28 
29 #include <limits>
30 #include <map>
31 
32 #include "trm/TRM.h"
33 #include "trm/Enum.h"
34 #include "trm/TunerState.h"
35 #include "trm/Messages.h"
36 #include "trm/JsonEncoder.h"
37 
38 #include "Server.h"
39 #include "Manager.h"
40 #include "Filter.h"
41 #include "Util.h"
42 #include "Executors.h"
43 
44 TRM_BEGIN_NAMESPACE
45 std::string GetDeviceId();
46 TRM_END_NAMESPACE
47 
48 LOCAL_BEGIN_NAMESPACE
49 
50 using namespace TRM;
51 
52 
53 
54 class Policy {
55 public:
56  /*
57  * If a device already owns a valid token for certain activity, the
58  * device must include the token in the new request for the same
59  * activity.
60  */
61  static bool RequireTokenInRequest(void) {
62  return false;
63  }
64 
65  static bool allowLinearRecordSharing(void) {
66  return true;
67  }
68 
69  static bool enableConflictsForHotRecording(void) {
70  return true;
71  }
72 
73  /*
74  * policy.allowOverlapRecordings() - true, means that
75  * there can be two active recodings of same sourceid
76  *
77  * This can happen if User explicitly request recordings of
78  * same source Id with overlapping time window, by exetending
79  * the stop time of current recoridng in back-to-back recording
80  * scenarios.
81  */
82  static bool allowOverlapRecordings(void) {
83  return true;
84  }
85 };
86 
87 void FindConflictsForRequestedLive(const ReserveTuner &request, ReserveTunerResponse::ConflictCT &conflicts)
88 {
89  /*
90  * Populate with conflicts for the LIVE request.
91  * Only the following reservations can be returned as conflicts:
92  * 1) R (Active or Pending) reservations on R tuners without Pending L.
93  * 2) R (Pending) reservations on F tuner without Pending L.
94  * 3) L reservation on the owning tuner (could be L or H).
95  * 4) R reservation on the owning tuner (could be L or H)
96  *
97  */
98 
99  TunerReservation::TokenList R_tokens_on_R_tuners; //Active or Pending
100  TunerReservation::TokenList R_tokens_on_F_tuners; //Pending
101  TunerReservation::TokenList L_tokens_on_Self_tuner;//Active, self tuner could be in H or L
102  TunerReservation::TokenList R_tokens_on_Self_tuner;//Active, self tuner could be in H or L
103 
104  Tuner::IdList tunerIds;
105 
106  tunerIds.clear();
107  Filter<ByActivity>(Activity::kRecord,
108  Manager::getInstance().
109  getReservationTokens(R_tokens_on_R_tuners,
110  Filter<ByTunerState>(TunerState::kRecord, Manager::getInstance().getTunerIds(tunerIds))));
111  tunerIds.clear();
112  Filter<ByActivity>(Activity::kRecord,
113  Manager::getInstance().
114  getReservationTokens(R_tokens_on_F_tuners,
115  Filter<ByTunerState>(TunerState::kFree, Manager::getInstance().getTunerIds(tunerIds))));
116 
117 
118  if (1 || (!request.getTunerReservation().getReservationToken().empty())) {
119  /* Get the L reservation on same parent tuner */
120  tunerIds.clear();
121  Filter<ByDevice>(request.getDevice(),
122  Filter<ByActivity>(Activity::kLive,
123  Manager::getInstance().getReservationTokens(L_tokens_on_Self_tuner, Manager::getInstance().getTunerIds(tunerIds))));
124 
125  Assert(L_tokens_on_Self_tuner.size() <= 1);
126 
127  if (L_tokens_on_Self_tuner.size() == 1) {
128  tunerIds.clear();
129  Filter<ByActivity>(Activity::kRecord,
130  Manager::getInstance().getReservationTokens(R_tokens_on_Self_tuner,
131  Manager::getInstance().getParent(*L_tokens_on_Self_tuner.begin())));
132  }
133  }
134 
135  {
136  const int kStateActive = TunerReservation::ACTIVE;
137  Filter<ByReservationState> (kStateActive, R_tokens_on_R_tuners);
138  Filter<ByReservationState> (kStateActive, R_tokens_on_F_tuners);
139  Filter<ByReservationState> (kStateActive, R_tokens_on_Self_tuner);
140  }
141 
142  TunerReservation::TokenList::const_iterator it;
143 
144  for (it = R_tokens_on_R_tuners.begin(); it != R_tokens_on_R_tuners.end(); it++) {
145  conflicts.push_back(Manager::getInstance().getReservation(*it));
146  }
147 
148  for (it = R_tokens_on_F_tuners.begin(); it != R_tokens_on_F_tuners.end(); it++) {
149  conflicts.push_back(Manager::getInstance().getReservation(*it));
150  }
151 
152  for (it = R_tokens_on_Self_tuner.begin(); it != R_tokens_on_Self_tuner.end(); it++) {
153  conflicts.push_back(Manager::getInstance().getReservation(*it));
154  }
155 }
156 
157 void FindConflictsForRequestedRecord(const ReserveTuner &request, ReserveTunerResponse::ConflictCT &conflicts)
158 {
159  /*
160  * Populate with conflicts for the LIVE request.
161  * Only the following reservations can be returned as conflicts with Recording:
162  * 1) L reservations on L tuners.
163  */
164 
165  TunerReservation::TokenList L_tokens_on_L_tuners;
166  Tuner::IdList tunerIds;
167 
168  if (!request.getTunerReservation().getDevice().empty()) {
169  Log() << "Look for L tuners owned by " << request.getTunerReservation().getDevice() << std::endl;
170  Filter<ByDevice>(request.getTunerReservation().getDevice(),
171  Filter<ByInConflict>(false,
172  Filter<ByActivity>(Activity::kLive,
173  Manager::getInstance().
174  getReservationTokens(L_tokens_on_L_tuners,
175  Filter<ByTunerState>(TunerState::kLive, Manager::getInstance().getTunerIds(tunerIds))))));
176  if (L_tokens_on_L_tuners.size() != 0) {
177  Log() << "Found L tuner owned by " << request.getTunerReservation().getDevice() << std::endl;
178 
179  /* Skip (the only 1) L tuners that already have a pending R */
180  {
181 
182  TunerReservation::TokenList::iterator it = L_tokens_on_L_tuners.begin();
183  while (it != L_tokens_on_L_tuners.end()) {
184  TunerReservation::TokenList R_tokens_on_L_tuner;
185  R_tokens_on_L_tuner.clear();
186  Filter<ByActivity>(Activity::kRecord,
187  Manager::getInstance().
188  getReservationTokens(R_tokens_on_L_tuner,
189  Manager::getInstance().getParent(*it)));
190  if (R_tokens_on_L_tuner.size() != 0) {
191  /* Skip */
192  it = L_tokens_on_L_tuners.erase(it);
193  Log() << "Skip L tuner owned by " << request.getTunerReservation().getDevice() << " Because it has R pending " << std::endl;
194 
195  }
196  else {
197  it++;
198  }
199 
200  }
201  }
202  }
203  }
204 
205  if (request.getTunerReservation().getDevice().empty() || L_tokens_on_L_tuners.size() == 0) {
206  Filter<ByInConflict>(false,
207  Filter<ByActivity>(Activity::kLive,
208  Manager::getInstance().
209  getReservationTokens(L_tokens_on_L_tuners,
210  Filter<ByTunerState>(TunerState::kLive, Manager::getInstance().getTunerIds(tunerIds)))));
211 
212  /* Skip L tuners that already have a pending R */
213  {
214  TunerReservation::TokenList::iterator it = L_tokens_on_L_tuners.begin();
215  while (it != L_tokens_on_L_tuners.end()) {
216  TunerReservation::TokenList R_tokens_on_L_tuner;
217  R_tokens_on_L_tuner.clear();
218  Filter<ByActivity>(Activity::kRecord,
219  Manager::getInstance().
220  getReservationTokens(R_tokens_on_L_tuner,
221  Manager::getInstance().getParent(*it)));
222  if (R_tokens_on_L_tuner.size() != 0) {
223  /* Skip */
224  it = L_tokens_on_L_tuners.erase(it);
225  Log() << "Skip L tuner owned by " << request.getTunerReservation().getDevice() << " Because it has R pending " << std::endl;
226 
227  }
228  else {
229  it++;
230  }
231 
232  }
233  }
234 
235  }
236 
237  TunerReservation::TokenList::const_iterator it;
238  //Only return 1 L for 1 R conflict.
239  //@TODO: Better selection than simply returning the first L?
240  it = L_tokens_on_L_tuners.begin();
241  if (it != L_tokens_on_L_tuners.end()) {
242  conflicts.push_back(Manager::getInstance().getReservation(*it));
243  }
244 
245  if (conflicts.size() == 0) {
246  /* No L conflicts available from L tuners. Now look for H tuners
247  * For H tuner, the L is a conflict if the R on the H will terminate before the new start time
248  */
249  TunerReservation::TokenList R_tokens_on_H_tuners_That_Ends_Before_New_StartTime;
250 
251  Filter<ByReservationEndBefore>(request.getTunerReservation().getStartTime(),
252  Filter<ByActivity>(Activity::kRecord,
253  Manager::getInstance().
254  getReservationTokens(R_tokens_on_H_tuners_That_Ends_Before_New_StartTime,
255  Filter<ByTunerState>(TunerState::kHybrid, Manager::getInstance().getTunerIds(tunerIds)))));
256 
257  //@TODO: Better selection than simply returning the first L?
258  /* Return the peer L reservation as conflict */
259  it = R_tokens_on_H_tuners_That_Ends_Before_New_StartTime.begin();
260 
261  Log() << "Found A future conflict to return \r\n" << std::endl;
262  TunerReservation::TokenList L_tokens_on_H_tuners;
263 
264  tunerIds.clear();
265  L_tokens_on_H_tuners.clear();
266 
267  if (it != R_tokens_on_H_tuners_That_Ends_Before_New_StartTime.end()) {
268  Filter<ByActivity>(Activity::kLive,
269  Manager::getInstance().getReservationTokens(L_tokens_on_H_tuners,
270  Filter<ByTunerId>(Manager::getInstance().getParent(*it), Manager::getInstance().getTunerIds(tunerIds))));
271  }
272  Assert(tunerIds.size() == 1);
273 
274  Assert(L_tokens_on_H_tuners.size() == 1);
275  conflicts.push_back(Manager::getInstance().getReservation(*L_tokens_on_H_tuners.begin()));
276  }
277 }
278 /*
279  * Reserve Tuner For Live:
280  *
281  * When asking for a NEW reservation:
282  * The new tuner is either taken from a Free tuner
283  * or share with a R tuner with matching locator.
284  *
285  * H,R,L-Tuners may have PENDING R tokens.
286  *
287  *
288  * IF this is RENEW (the requester already owns a L)
289  * --
290  * -- IF exiting L is on L-Tuner,
291  * -- -- IF has pending R, check if source locator match new locator.
292  * -- -- -- IF locator match, grant token, T state stays at L
293  * -- -- -- ELSE must move to F-Tuner or R-Tuner.
294  * -- -- ELSE, grant L on same tuner (a.k.a renew current L with same or different locator)
295  * -- ELSE exiting L is on H-Tuner
296  * -- -- must move to F-Tuner or R-Tuner.
297  *
298  * CONTINUE. Need to look for F-Tuner or R-Tuner with matching Locator.
299  * IF there is a R tuner with ALL and ONLY (ACTIVE|PENDING) tokens matching locator, move to this R-TUNER
300  * ELSE there is a F tuner with ALL and ONLY PENDING R tokens matching locator, move to this F-tuner.
301  *
302  * CONTINUE. Now prepare conflicts.
303  * L conflicts to all ACTIVE & PENDING R tokens on (F,R) tuners.
304  *
305  */
306 //TODOTODO:
307 //Now we have F with pending R, L with Pending R and R with pending R.
308 void reserveLive(const ReserveTuner &request, ReserveTunerResponse &response, int32_t clientId)
309 {
310  response.getStatus() += "Start reservation process for <Live> \r\n";
311 
312  {
313  const int alwaysAllowFuture = 1;
314  const int firstThreshold = (60 * 1000); // 60 second
315  const int secondThreshold = (300 * 1000); // 5 minute
316 
317  int64_t diff = ((int64_t)request.getTunerReservation().getStartTime()) - ((int64_t)GetCurrentEpoch());
318  if (diff <= 0) {
319  /* Request startTime is in the past. OK */
320  }
321  else {
322  if (alwaysAllowFuture || diff <= firstThreshold) {
323  if (!alwaysAllowFuture) {
324  Log() << "Requesting <Live> reservation is less than 60 seoncds in the future...this is now allowed\r\n";
325  response.getStatus() += "Requesting <Live> reservation is less than 60 seconds in the future...this is now allowed \r\n";
326  }
327  else {
328  Log() << "Requesting <Live> reservation starts from 'NOW'\r\n";
329  response.getStatus() += "Requesting <Live> reservation starts from 'NOW'\r\n";
330  }
331  TunerReservation & reservation = const_cast<TunerReservation &>(request.getTunerReservation());
332  reservation.setStartTime(GetCurrentEpoch() - 1);
333  }
334  else {
335  Log() << "Requesting <Live> reservation is more than 60 seoncds in the future...this is not allowed\r\n";
336  response.getStatus() += "Requesting <Live> reservation is more than 60 seconds in the future...this is not allowed \r\n";
337  response.getStatus() = ResponseStatus::kMalFormedRequest;
338  throw IllegalArgumentException();
339  }
340  }
341  }
342 
343  /*
344  * Basically the resolution is to find the existing token, if any, to release,
345  * and to find the new destination to host the token.
346  */
347  std::string tokenToAddTo = "";
348  std::string tokenToRelease = "";
349  std::string tunerToAddTo = "";
350  std::string tokenToResurrect = "";
351 
352  tokenToAddTo = request.getTunerReservation().getReservationToken();
353  int isResurrect = (request.getResurrect().compare("true") == 0);
354 
355  {
356  Tuner::IdList tunerIds;
357  TunerReservation::TokenList tokens;
358 
359  tunerIds.clear();
360  tokens.clear();
361  Filter<ByDevice>(request.getDevice(),
362  Filter<ByActivity>(Activity::kLive,
363  Manager::getInstance().getReservationTokens(tokens, Manager::getInstance().getTunerIds(tunerIds))));
364 
365  if (tokens.size() != 0) {
366  Log() << "Found Existing <Live> reservation owned by requesting device\r\n";
367  response.getStatus() += "Found Existing <Live> reservation owned by requesting device \r\n";
368  /* A device can only have 1 L token, either active or pending */
369  Assert(tokens.size() == 1);
370  tokenToRelease = (*tokens.begin());
371  }
372  else
373  {
374  if((isResurrect) && (!tokenToAddTo.empty()))
375  {
376  tokenToResurrect = tokenToAddTo;
377  tokenToAddTo = "";
378  Log() << "Existing <Live> reservation does not exist\r\n";
379  Log() << "Use Resurrect Token = " << tokenToResurrect << std::endl;
380  }
381  }
382  }
383 
384  if ((!tokenToRelease.empty()) && (Manager::getInstance().getReservation(tokenToRelease).state == TunerReservation::IDLE)) {
385  Log() << "Existing <Live> reservation is not yet started\r\n";
386  response.getStatus() += "Existing <Live> reservation is not yet started \r\n";
387  response.getStatus() = ResponseStatus::kInvalidState;
388  throw InvalidStateException();
389  }
390 
391  if ( ((tokenToRelease.empty()) && (!tokenToAddTo.empty())) ||
392  ((!tokenToRelease.empty()) && (Manager::getInstance().getReservation(tokenToRelease).state == TunerReservation::IDLE)) ||
393  ((!tokenToRelease.empty()) && (!tokenToAddTo.empty()) && (tokenToRelease.compare(tokenToAddTo) != 0)))
394  {
395  Log() << "Existing <Live> reservation does not exist\r\n";
396  response.getStatus() += "Existing <Live> reservation does not match that in request \r\n";
397  response.getStatus() = ResponseStatus::kInvalidToken;
398  throw ItemNotFoundException();
399  }
400 
401  tokenToAddTo = tokenToRelease;
402 
403  Log() << "tokenToRelease = " << tokenToRelease << std::endl;
404  Log() << "tokenToAddTo = " << tokenToAddTo << std::endl;
405 
406  if (!tokenToRelease.empty()) {
407  /* Requesting device has an existing token */
408  if (request.getTunerReservation().
409  getServiceLocator().
410  compare(Manager::getInstance().getReservation(tokenToRelease).getServiceLocator()) == 0) {
411  Log() << "Existing <Live> reservation has same locator, reuse it \r\n";
412  response.getStatus() += "Existing <Live> reservation has same locator, reuse it \r\n";
413  tunerToAddTo = Manager::getInstance().getTuner(Manager::getInstance().getParent(tokenToRelease)).getId();
414  }
415  }
416 
417  /* Need a tuner for LIVE token. Check for sharing R tuner*/
418 
419  if (tunerToAddTo.empty()) {
420  Tuner::IdList tunerIds;
421  TunerReservation::TokenList tokens;
422  tunerIds.clear();
423  tokens.clear();
424 
425  Log() << "look for R tuner that has tokens of same locator \r\n";
426  response.getStatus() += "look for R tuner that has tokens of same locator \r\n";
427 
428  Filter<ByTunerState>(TunerState::kRecord, Manager::getInstance().getTunerIds(tunerIds));
429 
430  if (tunerIds.size() != 0) {
431  Tuner::IdList::const_iterator tidIT = tunerIds.begin();
432  while (tidIT != tunerIds.end()) {
433  /* A security check: R tuner should not have active L reservation*/
434  try {
435  Manager::getInstance().getTuner(*tidIT).getReservation(Activity::kLive, TunerReservation::ACTIVE);
436  Assert(0);
437  }
438  catch(ItemNotFoundException &e) {
439  }
440 
441  /* R tuner should always have active R reservation*/
442  if (Manager::getInstance().
443  getTuner(*tidIT).
444  getReservation(Activity::kRecord, TunerReservation::ACTIVE).
445  getServiceLocator().
446  compare(request.getTunerReservation().getServiceLocator()) == 0) {
447  Log() << "found R tuner that has tokens of same locator \r\n";
448  response.getStatus() += "found R tuner that has tokens of same locator \r\n";
449  tunerToAddTo = *tidIT;
450  break;
451  }
452 
453  tidIT++;
454  }
455  }
456  }
457 
458  /* There is no existing R tuner to share, check for currently owned tuner with future R of same locator */
459 
460  std::string fallbackTuner = "";
461 
462  if (tunerToAddTo.empty()) {
463  if (((!tokenToRelease.empty())) &&
464  Manager::getInstance().
465  getTuner(Manager::getInstance().getParent(tokenToRelease)).
466  getState() == TunerState::kLive) {
467  /* Check existing L tuner to see if we can reuse. This is a L tuner so its R token, if any, has to be IDLE */
468  try {
469  //SM-N4
470  if (Manager::getInstance().
471  getTuner(Manager::getInstance().getParent(tokenToRelease)).
472  getReservation(Activity::kRecord, TunerReservation::IDLE).
473  getServiceLocator().
474  compare(request.getTunerReservation().getServiceLocator()) == 0) {
475  Log() << "Current L tuner that has Future R token of same locator \r\n";
476  response.getStatus() += "Current L tuner that has Future R token of same locator \r\n";
477  tunerToAddTo = Manager::getInstance().getTuner(Manager::getInstance().getParent(tokenToRelease)).getId();
478  }
479  else {
480  Log() << "Current L tuner that has Future R token of different locator \r\n";
481  response.getStatus() += "Current L tuner that has Future R token of different locator \r\n";
482  fallbackTuner = Manager::getInstance().getTuner(Manager::getInstance().getParent(tokenToRelease)).getId();
483  }
484 
485  }
486  catch(ItemNotFoundException &e) {
487  //There is no IDLE Record Token.
488  Log() << "Current L tuner that no Future R tokens\r\n";
489  response.getStatus() += "Current L tuner that no Future R tokens \r\n";
490  fallbackTuner = Manager::getInstance().getTuner(Manager::getInstance().getParent(tokenToRelease)).getId();
491  }
492  }
493  }
494 
495  /* There is no currently owned tuner. or the current tuner does not have future R of same locator,
496  * check for F tuner with future R of same locator.
497  */
498  if (tunerToAddTo.empty()) {
499  //SM-N6
500  Tuner::IdList tunerIds;
501  TunerReservation::TokenList tokens;
502  tunerIds.clear();
503  tokens.clear();
504 
505  Log() << "look for F tuner that has future tokens of same locator \r\n";
506  response.getStatus() += "look for F tuner that has future tokens of same locator \r\n";
507 
508  Filter<ByTunerState>(TunerState::kFree, Manager::getInstance().getTunerIds(tunerIds));
509 
510  if (tunerIds.size() != 0) {
511  Tuner::IdList::const_iterator tidIT = tunerIds.begin();
512  while (tidIT != tunerIds.end()) {
513  /* A security check: F tuner should not have active L or R reservation*/
514  try {
515  Manager::getInstance().getTuner(*tidIT).getReservation(Activity::kLive, TunerReservation::ACTIVE);
516  Assert(0);
517  }
518  catch(ItemNotFoundException &e) {
519  }
520 
521  try {
522  Manager::getInstance().getTuner(*tidIT).getReservation(Activity::kRecord, TunerReservation::ACTIVE);
523  Assert(0);
524  }
525  catch(ItemNotFoundException &e) {
526  }
527 
528  /* F tuner may have future R reservation*/
529  try {
530  if (Manager::getInstance().
531  getTuner(*tidIT).
532  getReservation(Activity::kRecord, TunerReservation::IDLE).
533  getServiceLocator().
534  compare(request.getTunerReservation().getServiceLocator()) == 0) {
535  Log() << "found F tuner that has future R tokens of same locator \r\n";
536  response.getStatus() += "found F tuner that has future R tokens of same locator \r\n";
537  tunerToAddTo = *tidIT;
538  break;
539  }
540  }
541  catch(ItemNotFoundException &e) {
542  }
543 
544  tidIT++;
545  }
546  }
547  }
548 
549  //SM-N7
550  /* There is no F tuner with future R of same locator,
551  * check a F without future R.
552  */
553  if (tunerToAddTo.empty()) {
554  Tuner::IdList tunerIds;
555  tunerIds.clear();
556 
557  Log() << "look for F tuner that has no future tokens \r\n";
558  response.getStatus() += "look for F tuner that has no future tokens \r\n";
559 
560  Filter<ByTunerState>(TunerState::kFree, Manager::getInstance().getTunerIds(tunerIds));
561 
562  if (tunerIds.size() != 0) {
563  Tuner::IdList::const_iterator tidIT = tunerIds.begin();
564  while (tidIT != tunerIds.end()) {
565  /* A security check: F tuner should not have active L or R reservation*/
566  try {
567  Manager::getInstance().getTuner(*tidIT).getReservation(Activity::kLive, TunerReservation::ACTIVE);
568  Assert(0);
569  }
570  catch(ItemNotFoundException &e) {
571  }
572 
573  try {
574  Manager::getInstance().getTuner(*tidIT).getReservation(Activity::kRecord, TunerReservation::ACTIVE);
575  Assert(0);
576  }
577  catch(ItemNotFoundException &e) {
578  }
579 
580  TunerReservation::TokenList tokens;
581  tokens.clear();
582  Manager::getInstance().getTuner(*tidIT).getReservationTokens(tokens);
583  if (tokens.size() == 0) {
584  tunerToAddTo = *tidIT;
585  break;
586  }
587 
588  tidIT++;
589  }
590  }
591  }
592 
593  if (!tunerToAddTo.empty()) {
594  /*If requester is remote, and tunerToAddTo is the last Free tuner, and this Free tuner is reserved local tuner
595  * we cannot use it unless the requester has no tuner and we can relocate the reserved local tuner
596  */
597  if (request.getDevice().compare(GetDeviceId()) != 0) {
598  Tuner::IdList tunerIds;
599  tunerIds.clear();
600 
601  Filter<ByTunerState>(TunerState::kFree, Manager::getInstance().getTunerIds(tunerIds));
602  if ((tunerIds.size() == 1) && (tunerToAddTo.compare(Manager::getInstance().getLocalTuner()) == 0)) {
603  Log() << "There are (" << tunerIds.size() << " - 1) F tuners (" << tunerToAddTo << ") to move reservedDeviceId to for remote device" << std::endl;
604  if (fallbackTuner.empty()) {
605  /* check if we can relocate the reserved local tuner to a R tuner */
606  tunerIds.clear();
607  Filter<ByTunerState>(TunerState::kRecord, Manager::getInstance().getTunerIds(tunerIds));
608  Log() << "There are (" << tunerIds.size() << " R tuners to move reservedDeviceId to for remote device" << std::endl;
609  if (tunerIds.size() >= 1) {
610  /* set the first one to be reserved */
611  Log() << "set reservedDeviceId to R tuner" << std::endl;
612  Manager::getInstance().setLocalTuner(*(tunerIds.begin()));
613  }
614  else {
615  tunerToAddTo ="";
616  }
617  }
618  else {
619  tunerToAddTo ="";
620  }
621  }
622  }
623  }
624 
625  if (tunerToAddTo.empty()) {
626  tunerToAddTo = fallbackTuner;
627  }
628 
629  if (tunerToAddTo.empty()) {
630 
631  Tuner::IdList tunerIds;
632  tunerIds.clear();
633 
634  Log() << "look for F tuner that has ANY future tokens (of diff serviceLocator) \r\n";
635  response.getStatus() += "look for F tuner that has ANY future tokens (of diff serviceLocator) \r\n";
636 
637  Filter<ByTunerState>(TunerState::kFree, Manager::getInstance().getTunerIds(tunerIds));
638 
639  if (tunerIds.size() != 0) {
640  Tuner::IdList::const_iterator tidIT = tunerIds.begin();
641  while (tidIT != tunerIds.end()) {
642  try {
643  Manager::getInstance().getTuner(*tidIT).getReservation(Activity::kRecord, TunerReservation::IDLE);
644  Log() << "found F tuner that has future R tokens of diff locator \r\n";
645  response.getStatus() += "found F tuner that has future R tokens of diff locator \r\n";
646  tunerToAddTo = *tidIT;
647  break;
648  }
649  catch(ItemNotFoundException &e) {
650  }
651 
652  tidIT++;
653  }
654  }
655 
656  }
657 
658  if (!tunerToAddTo.empty()) {
659  /*
660  * Check tuner allocation and make sure that the host device has a dedicated tuner for Live:
661  * The granted tuner is either in one of the following states
662  * Free state: The requester does not yet have a L token.
663  * Record state:The requester does not yet have a L token.
664  * Live state: The requester already has a L token and is reusing it.
665  */
666  if (tunerToAddTo.compare(fallbackTuner) == 0) {
667  /* Reusing current tuner. No changes */
668  Log() << "[reserveLocal] Reusing current tuner. No changes" << std::endl;
669  if ((request.getDevice().compare(GetDeviceId()) == 0) && Manager::getInstance().getLocalTuner().empty()) {
670  Log() << "[reserveLocal] set reservedDeviceId for local tuner" << std::endl;
671  Manager::getInstance().setLocalTuner(tunerToAddTo);
672  }
673  }
674  else if (!GetDeviceId().empty()) {
675  /* switching to new tuner for Live. The new tuner is either Free or Record */
676  Log() << "[reserveLocal] switching to new tuner for Live. The new tuner (Free or Record) is curently in state "
677  << (const char *)(Manager::getInstance().getTuner(tunerToAddTo).getState().getState())
678  << std::endl;
679 
680  if (request.getDevice().compare(GetDeviceId()) == 0) {
681  Log() << "[reserveLocal] requester is local host, moving reservedDeviceId "
682  << GetDeviceId() << " from "
683  << Manager::getInstance().getLocalTuner()
684  << " to " << tunerToAddTo << std::endl;
685 
686  Manager::getInstance().setLocalTuner(tunerToAddTo);
687  }
688  else {
689  Log() << "[reserveLocal] requester is remote host" << std::endl;
690 
691  /* If remote host is taking the reservedDeviceId tuner, move the reserveDeviceId to a new one */
692  /* The remove host is taking either a F or a R tuner for requested Live*/
693 
694  /* If granted tuner is last tuner that can take LIVE (i.e. a F or R),
695  * we have to make sure there is already one reserved for local host */
696  if (tunerToAddTo.compare(Manager::getInstance().getLocalTuner()) == 0) {
697  /* If tunerToAddTo is a F or R, we have to find another F or R */
698  bool foundReserved = false;
699  if (!foundReserved) {
700  Tuner::IdList tunerIds;
701  tunerIds.clear();
702 
703  Filter<ByTunerState>(TunerState::kFree, Manager::getInstance().getTunerIds(tunerIds));
704  if (tunerIds.size() != 0) {
705  Log() << "There are (" << tunerIds.size() << " - 1) F tuners to move reservedDeviceId to " << std::endl;
706  tunerIds.remove(tunerToAddTo);
707  if (tunerIds.size() != 0) {
708  Manager::getInstance().setLocalTuner(*tunerIds.begin());
709  foundReserved = true;
710  }
711  else {
712  /* no more Free, look for R */
713  }
714  }
715  }
716 
717 
718  if (!foundReserved) {
719  Log() << "There is no more F tuner to move reservedDeviceId to " << std::endl;
720  Tuner::IdList tunerIds;
721  tunerIds.clear();
722  /* Move reservedTuner to one of the other R's */
723  Filter<ByTunerState>(TunerState::kRecord, Manager::getInstance().getTunerIds(tunerIds));
724  if (tunerIds.size() != 0) {
725  Log() << "There are (" << tunerIds.size() << " - 1) R tuners to move reservedDeviceId to " << std::endl;
726  tunerIds.remove(tunerToAddTo);
727  if (tunerIds.size() != 0) {
728  Manager::getInstance().setLocalTuner(*tunerIds.begin());
729  foundReserved = true;
730  }
731  else {
732  /* no more R */
733  }
734  }
735  }
736 
737  if (!foundReserved) {
738  Log() << "cannot find a new home for reserved tuner, reject current request " << std::endl;
739  tunerToAddTo = "";
740  }
741  }
742  }
743  }
744  else {
745  Log() << "Warning: DeviceId Not available, ignore reserveDeviceId assignment " << std::endl;
746  Manager::getInstance().setLocalTuner(std::string(""));
747  }
748  }
749 
750  if (!tunerToAddTo.empty()) {
751  Log() << "Granting New Reservation to Live on tuner " << tunerToAddTo << std::endl;
752 
753  TunerReservation newReservation = request.getTunerReservation();
754  if (!tokenToRelease.empty()) {
755  newReservation.setReservationToken(tokenToRelease);
756  Manager::getInstance().releaseReservation(tokenToRelease, false/*transition release do not notify client*/);
757  }
758  else if((isResurrect) && (!tokenToResurrect.empty())) {
759  newReservation.setReservationToken(tokenToResurrect);
760  Log() << "Granting Reservation on Live with Resurrect Token = " << tokenToResurrect << std::endl;
761  }
762  else {
763  newReservation.setReservationToken(GenerateUUID());
764  }
765 
766  const bool considerFutureToken = false;
767  if(!Manager::getInstance().getTuner(tunerToAddTo).getServiceLocator(considerFutureToken).empty()) {
768  if (newReservation.getServiceLocator().
769  compare(Manager::getInstance().getTuner(tunerToAddTo).getServiceLocator(considerFutureToken)) != 0) {
770  Log() << "Modify response locator from " << newReservation.getServiceLocator() << " to " << Manager::getInstance().getTuner(tunerToAddTo).getServiceLocator(considerFutureToken) << "\r\n";
771  response.getStatus() += "Modify response locator\r\n";
772  newReservation.setServiceLocator(Manager::getInstance().getTuner(tunerToAddTo).getServiceLocator(considerFutureToken));
773  }
774  }
775 
776  Manager::getInstance().addReservation(newReservation, tunerToAddTo);
777  printf("===============+Reservation %s from Connection %x ADDED\r\n", newReservation.getReservationToken().c_str(), clientId);
778  Manager::getInstance().setReservationAttributes(newReservation.getReservationToken(), ReservationAttributes(clientId));
779 
780  response.setTunerReservation(newReservation);
781  response.getStatus() = ResponseStatus::kOk;
782  }
783  else {
784  response.getStatus() += "Error: Reservation Failed with conflicts\r\n";
785  response.getStatus() = ResponseStatus::kGeneralError;
786  FindConflictsForRequestedLive(request, response.getConflicts());
787 
788  /* Send Response as Insufficient resource during no conflicts */
789  if (response.getConflicts().size() == 0){
790  response.getStatus() = ResponseStatus::kInsufficientResource;
791  }
792  else {
793  response.getStatus() = ResponseStatus::kOk;
794  }
795 
796 
797  /* For each conflicts, change the state from ACTIVE to IN_CONFLICT */
798  }
799 }
800 
801 void renewRecord(const ReserveTuner &request, ReserveTunerResponse &response, int32_t clientId)
802 {
803 
804  Tuner::IdList tunerIds;
805  TunerReservation::TokenList tokens;
806  std::string tokenToRenew = "";
807 
808  /* RENEW */
809  Log() << "Look for Existing <Record> reservation for the same locator\r\n";
810  response.getStatus() += "Look for Existing <Record> reservation for the same locator\r\n";
811 
812  tunerIds.clear();
813  tokens.clear();
814  Filter<ByActivity>(Activity::kRecord,
815  Filter<ByReservationLocator>(request.getTunerReservation().getServiceLocator(),
816  Filter<ByDevice>(request.getTunerReservation().getDevice(),
817  Manager::getInstance().getReservationTokens(tokens, Manager::getInstance().getTunerIds(tunerIds)))));
818 
819  if (tokens.size() != 0) {
820  Log() << "Found Existing <Record> reservation for SrcID "
822  << " owned by requesting device " << request.getTunerReservation().getDevice() << "\r\n";
823 
824  SafeAssert(tokens.size() == 1);
825 
826  response.getStatus() += "Found Existing <Record> reservation : ";
827  response.getStatus() += (*tokens.begin()).c_str();
828  response.getStatus() += " owned by requesting device \r\n";
829 
830  Log() << "Found Existing <Record> reservation : " << (*tokens.begin()) << " owned by requesting device \r\n";
831 
832  if (!request.getTunerReservation().getReservationToken().empty()) {
833  tokenToRenew = (*tokens.begin());
834  Assert(tokenToRenew.compare(request.getTunerReservation().getReservationToken()) == 0);
835  }
836  else {
837  /* Recorder is not trying to renew, even though the source locator is same */
838  tokenToRenew = "";
839  }
840 
841  Log() << "Token to renew is " << tokenToRenew << std::endl;
842  /* Update the token */
843  tunerIds.clear();
844  tunerIds.insert(tunerIds.begin(), Manager::getInstance().getParent(tokenToRenew));
845  //Exception will be thrown if release fails.
846  if (!tokenToRenew.empty()) {
847  Manager::getInstance().releaseReservation(tokenToRenew, false/*transition release do not notify client*/);
848  Manager::getInstance().addReservation(request.getTunerReservation(), (*(tunerIds.begin())));
849  Manager::getInstance().setReservationAttributes(request.getTunerReservation().getReservationToken(), ReservationAttributes(clientId));
850  response.setTunerReservation(request.getTunerReservation());
851  }
852  else {
853  //Simply add a 2nd reservation to the tuner.
854  }
855  }
856  else {
857  Log() << "No Existing <Record> reservation owned by requesting device\r\n";
858  response.getStatus() += "No Existing <Record> reservation owned by requesting device \r\n";
859  tokenToRenew = "";
860  response.getStatus() = ResponseStatus::kInvalidToken;
861  }
862 
863 }
864 
865 void reserveRecord(const ReserveTuner &request, ReserveTunerResponse &response, int32_t clientId)
866 {
867  response.getStatus() += "Start reservation process for <Recording> \r\n";
868 
869  std::string tunerToAddTo = "";
870  const uint64_t endTime = request.getTunerReservation().getStartTime();
871  bool hasStarted = (request.getTunerReservation().getStartTime() < GetCurrentEpoch());
872 
873  /*
874  * Check R Token can be granted without triggering conflicts. Searched in the following order
875  *
876  * A tuner without future tokens is considered to have a future token whose end time is NOW().
877  *
878  * If there is a H tuner whose R end time is before the new start time and whose srcId is same.
879  * If there is a L tuner with no <future> R who has the longest active time and whose srcId is same.
880  * If there is a R tuner whose end time is before the new start time.
881  * If there is a F tuner.
882  *
883  */
884 
885  if(!request.getTunerReservation().getReservationToken().empty()) {
886  Log() << "Renew existing token \r\n";
887  response.getStatus() += "Renew existing token \r\n";
888  renewRecord(request, response, clientId);
889  return;
890  }
891 
892  /* At any given time, there can only be upto N active recording and 2 future recording per source Id, per Tuner */
893  {
894  Tuner::IdList tunerIds;
895  tunerIds.clear();
896  int count = 0;
897  Manager::getInstance().getTunerIds(tunerIds);
898  Tuner::IdList::const_iterator tidIT = tunerIds.begin();
899  while (tidIT != tunerIds.end()) {
900  try {
901  Manager::getInstance().getTuner(*tidIT).getReservation(
902  Activity::kRecord,
903  TunerReservation::ACTIVE,
905  count++;
906  }
907  catch(ItemNotFoundException &e) {
908  }
909 
910  tidIT++;
911  }
912 
913  if(!Policy::allowOverlapRecordings()) {
914  if (hasStarted) {
915  Assert(count ==0);
916  }
917  else {
918  Assert(count <=1);
919  }
920  }
921  else {
922  if (count != 0) {
923  Log() << "Recoridng " << request.getTunerReservation().getServiceLocator() << "already has " << count << " in progress" << std::endl;
924  }
925  }
926  }
927 
928  {
929  Tuner::IdList tunerIds;
930  tunerIds.clear();
931  int count = 0;
932  Manager::getInstance().getTunerIds(tunerIds);
933  Tuner::IdList::const_iterator tidIT = tunerIds.begin();
934  while (tidIT != tunerIds.end()) {
935  try {
936  Manager::getInstance().getTuner(*tidIT).getReservation(
937  Activity::kRecord,
938  TunerReservation::IDLE,
940  Log() << "There is already an pending recording on locator "
941  << request.getTunerReservation().getServiceLocator()
942  << " on tuner " << tunerToAddTo
943  << std::endl;
944  /*
945  * use this tuner if the new recording is back-2-back with the
946  * pending recording, and if the time does not overlap
947  */
948  if (Manager::getInstance().getTuner(*tidIT).getEndTime(Activity::kRecord) <= request.getTunerReservation().getStartTime()) {
949  tunerToAddTo = *tidIT;
950  }
951  count++;
952  }
953  catch(ItemNotFoundException &e) {
954  }
955 
956  tidIT++;
957  }
958 
959  if (!Policy::allowOverlapRecordings()) Assert(count <= 1);
960  }
961 
962  if (tunerToAddTo.empty())
963  {
964  Tuner::IdList tunerIds;
965  TunerReservation::TokenList tokens;
966 
967  Log() << "First look for H tuner whose R end time is before the new start time and whose srcId is same \r\n";
968  response.getStatus() += "First look for H tuner whose R end time is before the new start time and whose srcId is same \r\n";
969 
970  Filter<ByTunerLocator>(request.getTunerReservation().getServiceLocator(),
971  Filter<ByTunerEndBefore>(endTime,
972  Filter<ByTunerState>(TunerState::kHybrid, Manager::getInstance().getTunerIds(tunerIds))));
973 
974  if (tunerIds.size() != 0) {
975  Log() << "Found <Hybrid> tuner of same locator for the recording \r\n";
976  response.getStatus() += "Found <Hybrid> tuner of same locator for the recording\r\n";
977  Assert(tunerIds.size() == 1);
978  tunerToAddTo = (*tunerIds.begin());
979  }
980  }
981 
982  if (tunerToAddTo.empty())
983  {
984  Tuner::IdList tunerIds;
985  tunerIds.clear();
986 
987  Log() << "Then look for L tuner with no <future> R who has the longest active time and whose srcId is same \r\n";
988  response.getStatus() += "Then look for L tuner with no <future> R who has the longest active time and whose srcId is same \r\n";
989 
990  Filter<ByTunerLocator>(request.getTunerReservation().getServiceLocator(),
991  Filter<ByTunerState>(TunerState::kLive, Manager::getInstance().getTunerIds(tunerIds)));
992 
993  Tuner::IdList::const_iterator tidIT = tunerIds.begin();
994  while (tidIT != tunerIds.end()) {
995  /* There can be multiple LIVE tuners streaming the recording channel. Pick the oldest */
996  TunerReservation::TokenList tokens;
997  tokens.clear();
998 
999  Manager::getInstance().getTuner(*tidIT).getReservationTokens(tokens);
1000  if (tokens.size() == 1) {
1001  if (Manager::getInstance().
1002  getTuner(*tidIT).
1003  getServiceLocator(false).
1004  compare(request.getTunerReservation().getServiceLocator()) == 0) {
1005  Log() << "found L tuner with no <future> R who has the longest active time and whose srcId is same \r\n";
1006  response.getStatus() += "found L tuner with no <future> R who has the longest active time and whose srcId is same \r\n";
1007  tunerToAddTo = (*tidIT);
1008  break;
1009  }
1010  }
1011  tidIT++;
1012  }
1013  }
1014 
1015  if (tunerToAddTo.empty())
1016  {
1017  Tuner::IdList tunerIds;
1018  tunerIds.clear();
1019 
1020  Log() << "Then look for R tuner of same sourceId whose end time is before the new start time \r\n";
1021  response.getStatus() += "Then look for R tuner of same sourceId whose end time is before the new start time \r\n";
1022 
1023  /* This R tuner must not already have a future R token */
1024  Filter<ByTunerLocator>(request.getTunerReservation().getServiceLocator(),
1025  Filter<ByTunerEndBefore>(endTime,
1026  Filter<ByTunerState>(TunerState::kRecord, Manager::getInstance().getTunerIds(tunerIds))));
1027 
1028  /* There can only be at most 1 tuner actively recording a given sourceId */
1029  if (!Policy::allowOverlapRecordings()) Assert(((int)tunerIds.size()) <= 1);
1030  if (tunerIds.size() != 0) {
1031  tunerToAddTo = (*tunerIds.begin());
1032  }
1033  }
1034 
1035  if (tunerToAddTo.empty())
1036  {
1037  Tuner::IdList tunerIds;
1038  tunerIds.clear();
1039 
1040  Log() << "Then look for R tuner of different sourceId whose end time is before the new start time \r\n";
1041  response.getStatus() += "Then look for R tuner of different sourceId whose end time is before the new start time \r\n";
1042 
1043  /* This R tuner must not already have a future R token */
1044  Filter<ByTunerEndBefore>(endTime,
1045  Filter<ByTunerState>(TunerState::kRecord, Manager::getInstance().getTunerIds(tunerIds)));
1046 
1047  if (tunerIds.size() != 0) {
1048  tunerToAddTo = (*tunerIds.begin());
1049  }
1050  }
1051 
1052  if (tunerToAddTo.empty())
1053  {
1054  Log() << "Then look for F tuner with no future R \r\n";
1055  response.getStatus() += "Then look for F tuner with no future R \r\n";
1056 
1057  Tuner::IdList tunerIds;
1058  tunerIds.clear();
1059 
1060  Filter<ByTunerState>(TunerState::kFree, Manager::getInstance().getTunerIds(tunerIds));
1061 
1062  if (tunerIds.size() != 0) {
1063  Tuner::IdList::const_iterator tidIT = tunerIds.begin();
1064  while (tidIT != tunerIds.end()) {
1065  /* A security check: F tuner should not have active L or R reservation*/
1066  try {
1067  Manager::getInstance().getTuner(*tidIT).getReservation(Activity::kLive, TunerReservation::ACTIVE);
1068  Assert(0);
1069  }
1070  catch(ItemNotFoundException &e) {
1071  }
1072 
1073  try {
1074  Manager::getInstance().getTuner(*tidIT).getReservation(Activity::kRecord, TunerReservation::ACTIVE);
1075  Assert(0);
1076  }
1077  catch(ItemNotFoundException &e) {
1078  }
1079 
1080  /* A security check: F tuner can have an IDLE token whose expiration time is in the past*/
1081  try {
1082  Manager::getInstance().getTuner(*tidIT).getReservation(Activity::kLive, TunerReservation::IDLE);
1083  Log() << "Tuner " << *tidIT << " has IDLE tokens " << std::endl;
1084  }
1085  catch(ItemNotFoundException &e) {
1086  }
1087 
1088 
1089  TunerReservation::TokenList tokens;
1090  tokens.clear();
1091  Manager::getInstance().getTuner(*tidIT).getReservationTokens(tokens);
1092  if (tokens.size() == 0) {
1093  tunerToAddTo = *tidIT;
1094  break;
1095  }
1096  else if (tokens.size() == 1) {
1097  /* First filter out the tuner if the only token is for futhre R */
1098  if (Manager::getInstance().getReservation(*tokens.begin()).getActivity() == Activity::kLive) {
1099  /* Accept if the token is IDLE and statTime has passed */
1100  TunerReservation reservation = Manager::getInstance().getTuner(*tidIT).getReservation(Activity::kLive, TunerReservation::IDLE);
1101  if (reservation.getServiceLocator().compare(request.getTunerReservation().getServiceLocator()) == 0) {
1102  if (reservation.getStartTime() <= GetCurrentEpoch()) {
1103  Log() << "Tuner " << *tidIT << " is accepted " << std::endl;
1104  tunerToAddTo = *tidIT;
1105  break;
1106  }
1107  }
1108  }
1109  else {
1110  }
1111  }
1112 
1113  tidIT++;
1114  }
1115  }
1116  }
1117 
1118  /*
1119  * Check tuner allocation and make sure that the host device has a dedicated tuner for Live:
1120  * The granted tuner is either in one of the following states
1121  * Live state: The R will make it into H state.
1122  * Free state: The R will make it into R state. If the F tuner originally belong to local device, find a replacement.
1123  */
1124  if (!tunerToAddTo.empty()) {
1125  if ((Manager::getInstance().getTuner(tunerToAddTo).getState().getState() == TunerState::kFree) &&
1126  (tunerToAddTo.compare(Manager::getInstance().getLocalTuner()) == 0)) {
1127  /* Look for another free tuner and to give it to local device */
1128  Tuner::IdList tunerIds;
1129  tunerIds.clear();
1130  Filter<ByTunerState>(TunerState::kFree, Manager::getInstance().getTunerIds(tunerIds));
1131  if (tunerIds.size() != 0) {
1132  tunerIds.remove(tunerToAddTo);
1133  /* Pick the one that is no the granted tuner */
1134  if (tunerIds.size() != 0) {
1135  Log() << "[reserveLocal] requester is recorder, moving reservedDeviceId "
1136  << GetDeviceId() << " from "
1137  << Manager::getInstance().getLocalTuner()
1138  << " to " << *tunerIds.begin() << std::endl;
1139  Manager::getInstance().setLocalTuner(*tunerIds.begin());
1140  }
1141  else {
1142  /* no more F tuner, reservedDeviceId stays with current R tuner */
1143  }
1144  }
1145  }
1146  }
1147 
1148  if (!tunerToAddTo.empty())
1149  {
1150  Log() << "Granting New Reservation to Record on tuner " << tunerToAddTo << std::endl;
1151  //@TODO: Validate the requested reservation. For now we simply make a copy and use it.
1152  TunerReservation recordReservation(request.getTunerReservation());
1153  recordReservation.setReservationToken(GenerateUUID());
1154  /* Use the tuner whose last endtime is closet to the new startTime */
1155  Manager::getInstance().addReservation(recordReservation, ((tunerToAddTo)));
1156  Manager::getInstance().setReservationAttributes(recordReservation.getReservationToken(), ReservationAttributes(clientId));
1157  response.setTunerReservation(recordReservation);
1158  }
1159  else {
1160  /* Looking for a conflict */
1161  //@TODO How to handle over booking?
1162  response.getStatus() += "Error: Reservation Failed with conflicts\r\n";
1163  response.getStatus() = ResponseStatus::kInsufficientResource;
1164 
1165  /* Only look for conflict resolution when recording is not hot */
1166  if (Policy::enableConflictsForHotRecording() || request.getTunerReservation().getActivity().getDetail("hot").compare("true") != 0) {
1167  response.getStatus() += "Error: This is a recording, see if we can find resolution\r\n";
1168  FindConflictsForRequestedRecord(request, response.getConflicts());
1169  }
1170  else {
1171  response.getStatus() += "Error: This is a hot recording, let request fail\r\n";
1172  }
1173 
1174  ReserveTunerResponse::ConflictCT & conflicts = response.getConflicts();
1175  if (conflicts.size() == 0 ) {
1176  /* Over booked */
1177  response.getStatus() += "Error: All tuners are recording\r\n";
1178  }
1179  else if (conflicts.size() == 1) {
1180  Log() << "Found one L tuner to start Conflict-resolution process\r\n";
1181  response.getStatus() += "Found one L tuner to start Conflict-resolution process\r\n";
1182  }
1183  else if (conflicts.size() > 1) {
1184  Assert(0);
1185  }
1186  }
1187 }
1188 
1189 
1190 LOCAL_END_NAMESPACE
1191 
1192 extern Server *serverInstance;
1193 
1194 TRM_BEGIN_NAMESPACE
1195 
1196 
1197 void Execute(Executor<ReserveTuner> &exec)
1198 {
1199  const ReserveTuner &request = exec.messageIn;
1200  ReserveTunerResponse response(request.getUUID());
1201 
1202  Log() << "[EXEC]Reserving"
1203  << " For Activity " << (const char *)request.getTunerReservation().getActivity().getActivity()
1204  << " From Device " << request.getDevice() << std::endl;
1205 
1206 
1207  try {
1208  if (request.getTunerReservation().getActivity() == Activity::kLive) {
1209 
1210  try
1211  {
1212  reserveLive(request, response, exec.getClientId());
1213  exec.messageOut = response;
1214  }
1215  catch(InvalidStateException &e) {
1216  exec.messageOut.getStatus() += (response.getStatus().getDetails() + " -->Error: Token Is In a bad state").c_str();
1217  exec.messageOut.getStatus() = ResponseStatus::kInvalidState;
1218  }
1219  catch(ItemNotFoundException &e) {
1220  exec.messageOut.getStatus() += (response.getStatus().getDetails() + " -->Error: Token Is Not Found").c_str();
1221  exec.messageOut.getStatus() = ResponseStatus::kInvalidToken;
1222  }
1223  catch(IllegalArgumentException &e) {
1224  exec.messageOut.getStatus() += (response.getStatus().getDetails() + " -->Error: Request Is malformed").c_str();
1225  exec.messageOut.getStatus() = ResponseStatus::kMalFormedRequest;
1226  }
1227 
1228  {
1229  Log() << "Sending the message:RL: " << std::endl;
1230  std::vector<uint8_t> out;
1231  SerializeMessage(exec.messageOut, exec.getClientId(), out);
1232  ::serverInstance->getConnection(exec.getClientId()).sendAsync(out);
1233  }
1234  }
1235  else if(request.getTunerReservation().getActivity() == Activity::kRecord) {
1236  try {
1237  reserveRecord(request, response, exec.getClientId());
1238  exec.messageOut = response;
1239 
1240  if (exec.messageOut.getConflicts().size() == 1) {
1241 
1242  /* Send Conflicts to L's Connection */
1243  std::string temporaryToken = GenerateUUID();
1244  const int CONFLICT_RESOLUTION_TIMEOUT_MS = (53500);
1245 
1246  //PendingRequest(exec.getClientId(), temporaryToken, request, exec.messageOut.getConflicts())
1247  TunerReservation & conflict = *(exec.messageOut.getConflicts().begin());
1248  /* conflict to R is L token,therefore, the conflict's clientId is L token's requester, i.e. XRE */
1249  ReservationAttributes &attrs = Manager::getInstance().getReservationAttributes(conflict.getReservationToken());
1250  /* If the connection is still alive, send connection to it */
1251  #if 0
1252  /* Send conflict content in this order (R, L) */
1253  NotifyTunerReservationConflicts notification(GenerateUUID(), request.getTunerReservation(), exec.messageOut.getConflicts());
1254  #else
1255  /* Send conflict content in this order (L, R) */
1256  NotifyTunerReservationConflicts notification(GenerateUUID(), conflict, request.getTunerReservation());
1257  #endif
1258  notification.getConflicts().begin()->setReservationToken(temporaryToken);
1259  std::string parentId = Manager::getInstance().getParent(notification.getTunerReservation().getReservationToken());
1260  Manager::getInstance().addPendingRequest(new PendingReserveTunerConflictProcessor(temporaryToken, exec.getClientId(), notification, request, parentId), CONFLICT_RESOLUTION_TIMEOUT_MS);
1261 
1262  {
1263  std::vector<uint8_t> out;
1264  SerializeMessage(notification, attrs.clientId, out);
1265  ::serverInstance->getConnection(attrs.clientId).sendAsync(out);
1266  }
1267  }
1268  else {
1269  Log() << "to Send Record Response, with no conflict resolution\r\n";
1270  std::vector<uint8_t> out;
1271  SerializeMessage(exec.messageOut, exec.getClientId(), out);
1272  ::serverInstance->getConnection(exec.getClientId()).sendAsync(out);
1273  }
1274  }
1275  catch(AssertionFailureException &e) {
1276  /* Respond with general error */
1277  Log() << "to Send failed Record Response, with no conflict resolution included\r\n";
1278  exec.messageOut.getStatus() = ResponseStatus::kGeneralError;
1279  std::vector<uint8_t> out;
1280  SerializeMessage(exec.messageOut, exec.getClientId(), out);
1281  ::serverInstance->getConnection(exec.getClientId()).sendAsync(out);
1282  }
1283 
1284  }
1285  }
1286  catch(ConnectionNotFoundException &e) {
1287  Log() << "Connection for message has reset/lost, discarding message\r\n";
1288  }
1289  catch(...) {
1290  Assert(0);
1291  }
1292 
1293 }
1294 
1295 void Execute(Executor<ReleaseTunerReservation> &exec)
1296 {
1297  const ReleaseTunerReservation &request = exec.messageIn;
1298  ReleaseTunerReservationResponse response(request.getUUID(), request.getReservationToken());;
1299 
1300  Log() << "[EXEC]Releasing"
1301  << " Token " << request.getReservationToken()
1302  << " From device" << request.getDevice() << std::endl;
1303 
1304  try {
1305  Manager::getInstance().releaseReservation(request.getReservationToken());
1306  response.setReleased(true);
1307  response.getStatus() = ResponseStatus::kOk;
1308  exec.messageOut = response;
1309 
1310  }
1311  catch(ItemNotFoundException &e) {
1312  exec.messageOut.setReleased(false);
1313  exec.messageOut.getStatus() += "Error: Token Is Not Found";
1314  exec.messageOut.getStatus() = ResponseStatus::kInvalidToken;
1315  }
1316 
1317  std::vector<uint8_t> out;
1318  SerializeMessage(exec.messageOut, exec.getClientId(), out);
1319  ::serverInstance->getConnection(exec.getClientId()).sendAsync(out);
1320 }
1321 
1322 void Execute(Executor<ValidateTunerReservation> &exec)
1323 {
1324  const ValidateTunerReservation &request = exec.messageIn;
1325  ValidateTunerReservationResponse response(request.getUUID(), request.getReservationToken());;
1326 
1327  Log() << "[EXEC]Validating"
1328  << " Token " << request.getReservationToken()
1329  << " From device" << request.getDevice() << std::endl;
1330  try {
1331  TunerReservation &reservation = Manager::getInstance().getReservation(request.getReservationToken());
1332  ReservationAttributes & attr = Manager::getInstance().getReservationAttributes(reservation.getReservationToken());
1333 
1334  if (attr.clientId == exec.getClientId()) {
1335  exec.messageOut.setValid(true);
1336  response.getStatus() = ResponseStatus::kOk;
1337  exec.messageOut = response;
1338  }
1339  else {
1340  Log() << "Throw ItemNotFoundException from Execute()" << std::endl;
1341  throw ItemNotFoundException();
1342  }
1343  }
1344  catch(...) {
1345  exec.messageOut.setValid(false);
1346  exec.messageOut.getStatus() += "Error: Token Is Not Found";
1347  exec.messageOut.getStatus() = ResponseStatus::kOk;
1348  }
1349 
1350  std::vector<uint8_t> out;
1351  SerializeMessage(exec.messageOut, exec.getClientId(), out);
1352  ::serverInstance->getConnection(exec.getClientId()).sendAsync(out);
1353 }
1354 
1355 void Execute(Executor<CancelRecording> &exec)
1356 {
1357  /* Forward Request to Recorder */
1358  const CancelRecording &request = exec.messageIn;
1359  CancelRecordingResponse response(request.getUUID(), request.getReservationToken());;
1360 
1361  try {
1362  /*
1363  * Check if the recording being cancelled has any pending reserveTuner() requests.
1364  */
1365  if (Manager::getInstance().isPendingConflict(request.getReservationToken())) {
1366  /* The recording has not yet started. Reject Recorder's reservation request */
1367  PendingReserveTunerConflictProcessor &pendingRequest = *static_cast<PendingReserveTunerConflictProcessor *>(&Manager::getInstance().getPendingRequest(request.getReservationToken()));
1368 
1369  Assert(pendingRequest.getUUID() == request.getReservationToken());
1370  Log() << "[EXEC]CancelRecording "
1371  << "Temporary Recording Token " << pendingRequest.getUUID()
1372  << " clientId " << exec.getClientId()
1373  << " clientId2 " << pendingRequest.clientId
1374  << std::endl;
1375 
1376  /* Respond to cancel Temporary as "User Cancel */
1377  {
1378  ReserveTunerResponse response(pendingRequest.request.getUUID());
1379  response.getStatus() += "User canceled recording as Conflict Resolution";
1380  response.getStatus() = ResponseStatus::kUserCancellation;
1381 
1382  SafeAssert(pendingRequest.clientId != exec.getClientId());
1383 
1384  std::vector<uint8_t> out;
1385  /* First notify requester of cancel success */
1386  SerializeMessage(response, pendingRequest.clientId, out);
1387  ::serverInstance->getConnection(pendingRequest.clientId).sendAsync(out);
1388  }
1389 
1390  Manager::getInstance().removePendingRequest(pendingRequest.getUUID());
1391  delete &pendingRequest;
1392  /*Then notify xre of cancellation */
1393  {
1394  CancelRecordingResponse response(request.getUUID(), request.getReservationToken());;
1395  response.getStatus() += "Cancellation Success \r\n";
1396  response.getStatus() = ResponseStatus::kOk;
1397  response.setCanceled(true);
1398 
1399  exec.messageOut = response;
1400  std::vector<uint8_t> out;
1401  SerializeMessage(exec.messageOut, exec.getClientId(), out);
1402  ::serverInstance->getConnection(exec.getClientId()).sendAsync(out);
1403  }
1404  }
1405  else {
1406  /* The recording being cancelled does not have any pending requests. Forward to Recorder*/
1407  if (!(Manager::getInstance().getReservation(request.getReservationToken()).getActivity() == Activity::kRecord)) {
1408  throw IllegalArgumentException();
1409  }
1410 
1411  Log() << "[EXEC]CancelRecording "
1412  << "From client " << exec.getClientId() << " "
1413  << "Actual Recording Token " << Manager::getInstance().getReservation(request.getReservationToken()).getReservationToken()
1414  << std::endl;
1415 
1416  const int CANCEL_RECORDING_TIMEOUT_MS = (15000);
1417 
1418  /* Forward to cancel Actual to Recorder */
1419  Manager::getInstance().addPendingRequest(new PendingCancelRecordingProcessor(exec.getClientId(), request), CANCEL_RECORDING_TIMEOUT_MS);
1420 
1421  std::vector<uint8_t> out;
1422  SerializeMessage(exec.messageIn, exec.getClientId(), out);
1423  ::serverInstance->getConnection(Connection::kRecorderClientId).sendAsync(out);
1424  }
1425 
1426  }
1427  catch(ConnectionNotFoundException &e) {
1428  /* There is no recorder. Send Response Error. */
1429  exec.messageOut.getStatus() += "Recorder is not connected \r\n";
1430  exec.messageOut.getStatus() = ResponseStatus::kGeneralError;
1431  exec.messageOut.setCanceled(false);
1432 
1433  std::vector<uint8_t> out;
1434  SerializeMessage(exec.messageOut, exec.getClientId(), out);
1435  ::serverInstance->getConnection(exec.getClientId()).sendAsync(out);
1436  }
1437  catch(IllegalArgumentException &e) {
1438  exec.messageOut.getStatus() += "Reservation Token is not valid \r\n";
1439  exec.messageOut.getStatus() = ResponseStatus::kGeneralError;
1440  exec.messageOut.setCanceled(false);
1441 
1442  std::vector<uint8_t> out;
1443  SerializeMessage(exec.messageOut, exec.getClientId(), out);
1444  ::serverInstance->getConnection(exec.getClientId()).sendAsync(out);
1445 
1446  }
1447 
1448  catch(ItemNotFoundException &e) {
1449  /* Received Invalid or NULL Token, Send Response Error. */
1450  exec.messageOut.getStatus() += "Error: Token Is Not Found";
1451  exec.messageOut.getStatus() = ResponseStatus::kInvalidToken;
1452  exec.messageOut.setCanceled(false);
1453 
1454  std::vector<uint8_t> out;
1455  SerializeMessage(exec.messageOut, exec.getClientId(), out);
1456  ::serverInstance->getConnection(exec.getClientId()).sendAsync(out);
1457  }
1458 
1459 }
1460 
1461 void Execute(Executor<CancelRecordingResponse> &exec)
1462 {
1463  /* Forward Request to Recorder */
1464  const CancelRecordingResponse &response = exec.messageIn;
1465 
1466  Log() << "[EXEC]CancelRecordingResponse"
1467  << " Token " << response.getReservationToken()
1468  << " For Client " << exec.getClientId()
1469  << std::endl;
1470  try {
1471  if (!(Manager::getInstance().getReservation(response.getReservationToken()).getActivity() == Activity::kRecord)) {
1472  throw IllegalArgumentException();
1473  }
1474 
1475  if (exec.getClientId() == Connection::kTrmClientId) {
1476  /* The CancelRecording was sent by TRM. Consume it */
1477  /* Assert(0) as now TRM doesn't initiate CancelRecording */
1478  Assert(0);
1479  }
1480  else {
1481  const PendingCancelRecordingProcessor &pendingRequest = *static_cast<PendingCancelRecordingProcessor *>(&Manager::getInstance().getPendingRequest(response.getUUID()));
1482 
1483 
1484  Log() << "[EXEC]CancelRecordingResponse "
1485  << "Recording Token " << pendingRequest.request.getReservationToken()
1486  << "for client " << pendingRequest.clientId
1487  << std::endl;
1488 
1489  Assert(pendingRequest.request.getReservationToken() == response.getReservationToken());
1490 
1491  /* Release the reservation and forward the response to the orginator */
1492  Log() << "Release the reservation and Send the response to the orginator" << std::endl;
1493  Manager::getInstance().removePendingRequest(response.getUUID());
1494  Assert(!Manager::getInstance().isPendingRequest(response.getUUID()));
1495 
1496  std::vector<uint8_t> out;
1497  SerializeMessage(exec.messageIn, pendingRequest.clientId, out);
1498  ::serverInstance->getConnection(pendingRequest.clientId).sendAsync(out);
1499 
1500  delete &pendingRequest;
1501 
1502  }
1503 
1504  /* Either way, release the token. */
1505  Manager::getInstance().releaseReservation(response.getReservationToken());
1506 
1507  }
1508  catch(IllegalArgumentException &) {
1509  Log() << "[EXEC]CancelRecordingResponse contains invalid arguments..discarding " << std::endl;
1510  }
1511  catch(AssertionFailureException &) {
1512  /* Do nothing */
1513  Log() << "[EXEC]Assert Error caught " << std::endl;
1514  }
1515  catch (ItemNotFoundException &) {
1516  Log() << "[EXEC]Matching CancelRecording Request is not found" << std::endl;
1517  }
1518  catch(...) {
1519  /* Do nothing */
1520  Log() << "[EXEC]Unknonw Exception caught " << std::endl;
1521  }
1522 }
1523 
1524 void Execute(Executor<GetAllTunerIds> &exec)
1525 {
1526  const GetAllTunerIds &request = exec.messageIn;
1527  GetAllTunerIdsResponse response(request.getUUID());;
1528 
1529  try {
1530  Tuner::IdList tunerIds;
1531  response.addTunerId(Manager::getInstance().getTunerIds(tunerIds));
1532  response.getStatus() = ResponseStatus::kOk;
1533  response.getStatus() += "GetAllTunerIds ok";
1534  exec.messageOut = response;
1535  }
1536  catch(...) {
1537  exec.messageOut.getStatus() += "Error: Cannot get IDs";
1538  exec.messageOut.getStatus() = ResponseStatus::kGeneralError;
1539  }
1540 
1541  std::vector<uint8_t> out;
1542  SerializeMessage(exec.messageOut, exec.getClientId(), out);
1543  ::serverInstance->getConnection(exec.getClientId()).sendAsync(out);
1544 }
1545 
1546 void Execute(Executor<GetAllTunerStates> &exec)
1547 {
1548  const GetAllTunerStates &request = exec.messageIn;
1549  GetAllTunerStatesResponse response(request.getUUID());;
1550  try {
1551  Tuner::IdList tunerIds;
1552  Manager::getInstance().getTunerIds(tunerIds);
1553  Tuner::IdList::const_iterator it;
1554  for (it=tunerIds.begin(); it != tunerIds.end(); it++) {
1555  response.addTunerState(*it, (const char *)(Manager::getInstance().getTuner(*it).getState().getState()));
1556  }
1557 
1558  /* 2.0 or above only */
1559  for (it=tunerIds.begin(); it != tunerIds.end(); it++) {
1560  Log() << "Adding Detailed Tuner State "
1561  << (const char *)(Manager::getInstance().getTuner(*it).getState().getState())
1562  << " with locator " << (Manager::getInstance().getTuner(*it).getServiceLocator())
1563  << " for Tuner " << *it
1564  << std::endl;
1565 
1566  std::string reservedDeviceId = "";
1567  if (Manager::getInstance().getLocalTuner().compare(*it) == 0) {
1568  reservedDeviceId = GetDeviceId();
1569  }
1570  response.addTunerState(*it,
1571  (const char *)(Manager::getInstance().getTuner(*it).getState().getState()),
1572  (Manager::getInstance().getTuner(*it).getServiceLocator()), reservedDeviceId);
1573 
1574  TunerReservation::TokenList tokens;
1575  TunerReservation::TokenList::const_iterator itt;
1576  Manager::getInstance().getReservationTokens(tokens, *it);
1577  for (itt=tokens.begin(); itt != tokens.end(); itt++) {
1578  /* Get the activity and device of the token*/
1579  if (Manager::getInstance().getReservation(*itt).state == TunerReservation::ACTIVE) {
1580  Log() << "Adding Detailed Tuner Activity "
1581  << (const char *)Manager::getInstance().getReservation(*itt).getActivity().getActivity()
1582  << " with Owner " << Manager::getInstance().getReservation(*itt).getDevice()
1583  << std::endl;
1584  response.addTunerOwner(*it,
1585  (const char *)Manager::getInstance().getReservation(*itt).getActivity().getActivity(),
1586  Manager::getInstance().getReservation(*itt).getDevice());
1587  }
1588  else {
1589  Log() << "Ignoring Inactive token " << *itt << std::endl;
1590  }
1591  }
1592  }
1593 
1594  response.getStatus() = ResponseStatus::kOk;
1595  exec.messageOut = response;
1596  }
1597  catch(...) {
1598  exec.messageOut.getStatus() += "Error: Cannot get States";
1599  exec.messageOut.getStatus() = ResponseStatus::kGeneralError;
1600  }
1601 
1602  std::vector<uint8_t> out;
1603  SerializeMessage(exec.messageOut, exec.getClientId(), out);
1604  ::serverInstance->getConnection(exec.getClientId()).sendAsync(out);
1605 }
1606 
1607 void Execute(Executor<GetAllReservations> &exec)
1608 {
1609  const GetAllReservations &request = exec.messageIn;
1610  GetAllReservationsResponse response(request.getUUID());;
1611 
1612  try {
1613  Tuner::IdList tunerIds;
1614  Manager::getInstance().getTunerIds(tunerIds);
1615  Tuner::IdList::const_iterator it;
1616  for (it=tunerIds.begin(); it != tunerIds.end(); it++) {
1617  TunerReservation::TokenList tokens;
1618  Manager::getInstance().getReservationTokens(tokens, *it);
1619  //Apply Filter:
1620  if (!request.getFilter("device").empty()) {
1621  Filter<ByDevice>(request.getFilter("device"), tokens);
1622  }
1623 
1624  if (!request.getFilter("activity").empty()) {
1625  Filter<ByActivity>(Activity(request.getFilter("activity").c_str()).getActivity(), tokens);
1626  }
1627 
1628  if (!request.getFilter("state").empty()) {
1629  Filter<ByTunerState>(TunerState(request.getFilter("state").c_str()).getState(), tokens);
1630  }
1631 
1632  TunerReservation::TokenList::const_iterator itt;
1633  for (itt = tokens.begin(); itt != tokens.end(); itt++) {
1634  response.addTunerReservation(*it, Manager::getInstance().getReservation(*itt));
1635  }
1636  }
1637  response.getStatus() = ResponseStatus::kOk;
1638  exec.messageOut = response;
1639  }
1640  catch(...) {
1641  exec.messageOut.getStatus() += "Error: Cannot get Reservations";
1642  exec.messageOut.getStatus() = ResponseStatus::kGeneralError;
1643  }
1644 
1645  std::vector<uint8_t> out;
1646  SerializeMessage(exec.messageOut, exec.getClientId(), out);
1647  ::serverInstance->getConnection(exec.getClientId()).sendAsync(out);
1648 }
1649 
1650 void Execute(Executor<ReserveTuner> &exec, const std::string &parentTunerId)
1651 {
1652  const ReserveTuner &request = exec.messageIn;
1653  ReserveTunerResponse response(request.getUUID());
1654 
1655  Log() << "[EXEC]Reserving and Always Granting"
1656  << " For Activity " << (const char *)request.getTunerReservation().getActivity().getActivity()
1657  << " From Device " << request.getDevice() << std::endl;
1658 
1659  try {
1660  if (request.getTunerReservation().getActivity() == Activity::kLive) {
1661  /* Not supported */
1662  Assert(0);
1663  }
1664  else if(request.getTunerReservation().getActivity() == Activity::kRecord) {
1665  /* Grant token unconditionally. Caller is responsible to make sure there will not be conflicts */
1666  TunerReservation recordReservation(request.getTunerReservation());
1667  if (request.getTunerReservation().getReservationToken().empty()) {
1668  recordReservation.setReservationToken(GenerateUUID());
1669  }
1670  else {
1671  recordReservation.setReservationToken(request.getTunerReservation().getReservationToken());
1672  }
1673 
1674  response.getStatus() += "Granting token unconditionally\r\n";
1675  response.getStatus() = ResponseStatus::kOk;
1676 
1677  /* Grant reservation to Record, and put the tuner that owsn the conflicting LIVE to HYBRID */
1678  response.setTunerReservation(recordReservation);
1679 
1680  uint64_t origStartTime = recordReservation.getStartTime();
1681  uint64_t origDuration = recordReservation.getDuration();
1682 
1683  /* only adjust startTime to 'now' when this is the first recording on the tuner.
1684  * (i.e. when tuner is in F or H state).
1685  */
1686  {
1687  const TunerState &tunerState = Manager::getInstance().getTuner(parentTunerId).getState();
1688  if (tunerState.getState() == TunerState::kFree || tunerState.getState() == TunerState::kLive) {
1689  recordReservation.setStartTime(GetCurrentEpoch()-1); /* start the timer now so we can force synchybrid */
1690  }
1691  }
1692 
1693  if (origStartTime < GetCurrentEpoch()) {
1694  /* Recording already started */
1695  recordReservation.setStartTime(GetCurrentEpoch()); /* start the timer now so we can force synchybrid */
1696  }
1697 
1698  if (recordReservation.getStartTime() > origStartTime) {
1699  /* Start time is move slightly ahead */
1700  if (recordReservation.getStartTime() > (origStartTime + origDuration)) {
1701  recordReservation.setDuration(0);
1702  }
1703  else {
1704  recordReservation.setDuration(origStartTime + origDuration - recordReservation.getStartTime());
1705  }
1706  }
1707  else {
1708  /* Start time is move slightly behind */
1709  recordReservation.setDuration(origDuration + origStartTime - recordReservation.getStartTime());
1710  }
1711 
1712  SafeAssert((origStartTime + origDuration) == (recordReservation.getStartTime() + recordReservation.getDuration()));
1713 
1714  Log() << "Orig Record (start,dur) vs Adjusted : ("
1715  << origStartTime << ", " << origDuration << "), ("
1716  << recordReservation.getStartTime() << ", " << recordReservation.getDuration() << ")"
1717  << std::endl;
1718 
1719  Manager::getInstance().addReservation(recordReservation, parentTunerId);
1720  Manager::getInstance().setReservationAttributes(recordReservation.getReservationToken(), ReservationAttributes(exec.getClientId()));
1721  exec.messageOut = response;
1722  try {
1723  Log() << "Sending the message:RL: " << std::endl;
1724  std::vector<uint8_t> out;
1725  SerializeMessage(exec.messageOut, exec.getClientId(), out);
1726  ::serverInstance->getConnection(exec.getClientId()).sendAsync(out);
1727  }
1728  catch (...) {
1729  Log() << "Sending the mssage failed" << std::endl;
1730  }
1731  }
1732  }
1733  catch(...) {
1734  Assert(0);
1735  }
1736 
1737 }
1738 
1739 void Execute(Executor<GetVersion> &exec)
1740 {
1741  const GetVersion &request = exec.messageIn;
1742  GetVersionResponse response(request.getUUID());;
1743 
1744  try {
1745  response.setVersion(GetSpecVersion().toString().c_str());
1746  response.getStatus() = ResponseStatus::kOk;
1747  response.getStatus() += "GetVersion ok";
1748  exec.messageOut = response;
1749  }
1750  catch(...) {
1751  exec.messageOut.getStatus() += "Error: Cannot get version";
1752  exec.messageOut.getStatus() = ResponseStatus::kGeneralError;
1753  }
1754 
1755  std::vector<uint8_t> out;
1756  SerializeMessage(exec.messageOut, exec.getClientId(), out);
1757  ::serverInstance->getConnection(exec.getClientId()).sendAsync(out);
1758 }
1759 
1760 void Execute(Executor<UpdateTunerActivityStatus> &exec)
1761 {
1762  const UpdateTunerActivityStatus &request = exec.messageIn;
1763  UpdateTunerActivityStatusResponse response(request.getUUID());
1764  try {
1765  std::vector<uint8_t> out;
1766  SerializeMessage(request, Connection::kTunerAgentId, out);
1767  ::serverInstance->getConnection(Connection::kTunerAgentId).sendAsync(out);
1768  //Send UpdateTunerActivityStatusResponse response
1769  exec.messageOut = response;
1770  {
1771  Log() << "Sending UpdateTunerActivityStatusResponse: " << std::endl;
1772  std::vector<uint8_t> out;
1773  SerializeMessage(exec.messageOut, exec.getClientId(), out);
1774  ::serverInstance->getConnection(exec.getClientId()).sendAsync(out);
1775  }
1776 
1777  }
1778  catch(...) {
1779  }
1780 
1781 }
1782 
1783 #if 1
1784 void Execute(Executor<CancelLive> &exec)
1785 {
1786  const CancelLive &request = exec.messageIn;
1787  CancelLiveResponse response(request.getUUID());;
1788  Log() << "Executing CancelLive from " << std::hex << exec.getClientId() << std::endl;
1789  try {
1790  //forward this to TuneAgent/Recorder
1791  std::vector<uint8_t> out;
1792  SerializeMessage(exec.messageIn, exec.getClientId(), out);
1793  ::serverInstance->getConnection(Connection::kRecorderClientId).sendAsync(out);
1794  }
1795  catch(...) {
1796  }
1797 #if 0
1798  exec.messageOut.getStatus() += "Test: Fake Cancel";
1799  exec.messageOut.getStatus() = ResponseStatus::kOk;
1800  exec.messageOut.setCanceled(true);
1801 
1802  std::vector<uint8_t> out;
1803  SerializeMessage(exec.messageOut, exec.getClientId(), out);
1804  ::serverInstance->getConnection(exec.getClientId()).sendAsync(out);
1805 #endif
1806 }
1807 
1808 void Execute(Executor<CancelLiveResponse> &exec)
1809 {
1810  /* Check if the request to this response message is still pending. */
1811  const CancelLiveResponse &response = exec.messageIn;
1812 
1813  if(Manager::getInstance().isPendingRequest(response.getUUID())) {
1814  Log() << "emit CancelLiveResponse from " << std::hex << exec.getClientId() << std::endl;
1815  PendingCancelLiveProcessor &pendingRequest = *static_cast<PendingCancelLiveProcessor *>(&Manager::getInstance().getPendingRequest(response.getUUID()));
1816  emit Manager::getInstance().cancelLiveResponse(response, pendingRequest.reserveRequest, pendingRequest.parentId);
1817  Manager::getInstance().removePendingRequest(response.getUUID());
1818  delete &pendingRequest;
1819  }
1820 }
1821 
1822 #endif
1823 TRM_END_NAMESPACE
1824 
1825 
1826 /** @} */
1827 /** @} */
TRM::ValidateTunerReservation
Implements the message format for client to validate an existing tuner reservation.
Definition: Messages.h:1168
TRM::TunerReservationBase::setServiceLocator
void setServiceLocator(const std::string &_serviceLocator)
This function is used to set the locator of the service that the tuner will tune to....
Definition: TunerReservation.cpp:155
TRM::TunerReservationBase::getStartTime
uint64_t getStartTime(void) const
This function is used to get the start time of the reservation in milliseconds from the epoch.
Definition: TunerReservation.cpp:105
TRM::ValidateTunerReservationResponse
Implements the response message payload for Tuner reservation validation requests.
Definition: Messages.h:1118
TRM::AssertionFailureException
Definition: TRM.h:66
TRM::CancelRecording
Implements a message to cancel the recording.
Definition: Messages.h:1241
TRM::ConnectionNotFoundException
Definition: TRM.h:62
TRM::ReserveTuner::getTunerReservation
TunerReservation & getTunerReservation(void)
This function is used to return the unique token generated when a reservation is created....
Definition: Messages.h:1006
TRM::Activity
The Activity class represents the request or granted usage of a tuner. The activity field in the clas...
Definition: Activity.h:92
TRM::ReleaseTunerReservation
Implements the message payload for releasing tuner reservation.
Definition: Messages.h:1094
TRM::ReserveTuner
Class implementing a Tuner reservation request, the client uses this message to request,...
Definition: Messages.h:972
TRM::TunerReservationBase::setStartTime
void setStartTime(const uint64_t &_startTime)
This function is used to set the start time of the reservation in milliseconds from the epoch....
Definition: TunerReservation.cpp:169
TRM::Activity::getDetail
const std::string & getDetail(const std::string &key) const
This function will get the details of the recording. Each activity may be associated with a set of de...
Definition: Activity.cpp:114
TRM::TunerReservationBase::setReservationToken
void setReservationToken(const std::string &token)
This function is used to set a unique token generated when a reservation is created....
Definition: TunerReservation.cpp:71
TRM::TunerReservationBase::getDevice
const std::string & getDevice(void) const
This function is used to get the remote device id requesting for tuner reservation.
Definition: TunerReservation.cpp:127
TRM::UpdateTunerActivityStatus
Definition: Messages.h:2246
TRM::CancelRecordingResponse
Implements payload for a response message against cancel recording request.
Definition: Messages.h:1194
TRM::TunerState
The TunerState class represents state of the tuner. The state field in the class indicates the activi...
Definition: TunerState.h:147
TRM::UpdateTunerActivityStatusResponse
Definition: Messages.h:2234
TRM::ReleaseTunerReservationResponse
Class implementing the response message payload for releasing Tuner reservation.
Definition: Messages.h:1046
TRM::GetAllTunerStates
Implements a request message for getting the state of all tuners in the system.
Definition: Messages.h:1668
TRM::CancelLive
Implements a message to cancel the live streaming.
Definition: Messages.h:1334
TRM::NotifyTunerReservationConflicts
Class for implementing asynchronous notification from TRM to the owner of a token that a tuner reserv...
Definition: Messages.h:1945
TRM::ReserveTunerResponse
Class implementing the response message to a ReserveTuner request.
Definition: Messages.h:858
Policy
Definition: Executors.cpp:54
TRM::TunerReservationBase::getActivity
const Activity & getActivity(void) const
This function is used to return the granted activity. Granted activity may or may not be the same as ...
Definition: TunerReservation.cpp:142
Messages.h
TRM::TunerReservationBase::getServiceLocator
const std::string & getServiceLocator(void) const
This function is used to return the locator of the service that the tuner is tuned to.
Definition: TunerReservation.cpp:94
TRM::GetAllTunerIdsResponse
Implements the response message payload against a Tuner Id request.
Definition: Messages.h:1378
TRM::GetAllTunerStatesResponse
Implements the response payload against a Get tuner state request.
Definition: Messages.h:1563
Executor
Definition: Executors.h:44
TRM::GetAllReservationsResponse
Implements the response message for the request to get All tuner reservation details.
Definition: Messages.h:1692
TRM::GetAllTunerIds
Implements the message payload format for requesting the system allocated Unique Id of tuner....
Definition: Messages.h:1439
TRM::ItemNotFoundException
Definition: TRM.h:58
TRM::GetAllReservations
Implements a request message to get reservation detail of all the tuners that are valid at that time.
Definition: Messages.h:1727
TRM::CancelLiveResponse
Implements payload for a response message against cancel live streaming request.
Definition: Messages.h:1265
TRM::InvalidStateException
Definition: TRM.h:70
TRM::TunerReservationBase
The TunerReservation class is used to set the requested or granted tuner reservation from client....
Definition: TunerReservation.h:139
TRM::TunerReservationBase::getReservationToken
const std::string & getReservationToken(void) const
This function is used to return the unique token generated when a reservation is created.
Definition: TunerReservation.cpp:83
TRM::Server
Definition: Server.h:42
TRM::Activity::getActivity
const Enum< Activity > & getActivity(void) const
This function is used to return the request or granted usage of tuner. The Activity field represents ...
Definition: Activity.cpp:89
TRM::ReserveTuner::getResurrect
const std::string & getResurrect(void) const
This function is used to return the list of resurrect (dead) reservation tokens.
Definition: Messages.h:1032
TRM::GetVersion
Implements a message to request for getting TRM server version.
Definition: Messages.h:1820
TRM::GetVersionResponse
Implements the response message for the queries that request TRM server version.
Definition: Messages.h:1783
TRM::IllegalArgumentException
Definition: TRM.h:50