RDK Documentation (Open Sourced RDK Components)
Capabilities.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 2017 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 #include <string>
22 #include <list>
23 #include "rdk_debug.h"
24 #include "hostIf_main.h"
25 #include "Capabilities.h"
26 
27 #include "host.hpp"
28 #include "dsTypes.h"
29 #include "videoDevice.hpp"
30 
31 #define MAX_RESOLUTION_LENGTH 30
32 
33 hostIf_STBServiceCapabilities* hostIf_STBServiceCapabilities::getInstance()
34 {
35  hostIf_STBServiceCapabilities* pRet = NULL;
36 
37  if(!pRet)
38  {
39  try {
40  pRet = new hostIf_STBServiceCapabilities();
41  } catch(const std::exception& e)
42  {
43  RDK_LOG(RDK_LOG_WARN,LOG_TR69HOSTIF,"[%s] Caught exception \" %s\"\n", __FUNCTION__, e.what());
44  }
45  }
46  return pRet;
47 }
48 
49 
50 void hostIf_STBServiceCapabilities::closeInstance(hostIf_STBServiceCapabilities *pDev)
51 {
52  if(pDev)
53  {
54  delete pDev;
55  }
56 }
57 
58 hostIf_STBServiceCapabilities::hostIf_STBServiceCapabilities()
59 {
60 }
61 
62 int hostIf_STBServiceCapabilities::handleSetMsg(HOSTIF_MsgData_t *stMsgData)
63 {
64  int ret = NOT_HANDLED;
65  stMsgData->faultCode = fcAttemptToSetaNonWritableParameter;
66  return ret;
67 }
68 
69 int hostIf_STBServiceCapabilities::handleGetMsg(HOSTIF_MsgData_t *stMsgData)
70 {
71  int ret = NOT_HANDLED;
72  const char *path = NULL, *paramName = NULL, *attr = NULL;
73  int index = 0;
74  try {
75  int str_len = strlen(CAPABILITIES_OBJ);
76  path = stMsgData->paramName;
77 
78  RDK_LOG(RDK_LOG_TRACE1,LOG_TR69HOSTIF,"[%s:%s]Entering... \n", __FILE__, __FUNCTION__);
79 
80  if(NULL == path) {
81  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"[%s:%s:%d]Failed : Parameter is NULL, %s \n", __FILE__, __FUNCTION__, __LINE__, path);
82  stMsgData->faultCode = fcInvalidParameterName;
83  return ret;
84  }
85 
86  if((strncasecmp(path, CAPABILITIES_OBJ, str_len) != 0)) {
87  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"[%s:%s:%d]Failed : Mismatch parameter path : %s \n", __FILE__, __FUNCTION__, __LINE__, path);
88  stMsgData->faultCode = fcInvalidParameterName;
89  return ret;
90  }
91 
92  /* Parse video decoder object.*/
93  const char *tmp_ptr = strchr(path+str_len-1,'.');
94  if(tmp_ptr == NULL) {
95  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"[%s:%s] Parameter is NULL \n", __FILE__, __FUNCTION__);
96  stMsgData->faultCode = fcInvalidParameterName;
97  return ret;
98  }
99 
100  tmp_ptr++;
101  paramName = tmp_ptr; //Now points to STBService.1.Capabilities.*
102  if (strcasecmp(paramName, VIDEO_STANDARDS_STRING) == 0)
103  {
104  ret = getVideoStandards(stMsgData);
105  }
106  else if(strcasecmp(paramName, PROFILE_NUM_ENTRIES_STRING) == 0)
107  {
108  ret = getNumHEVCProfileEntries(stMsgData);
109  }
110  else if(matchComponent(stMsgData->paramName, HEVC_PROFILE_OBJ, &attr, index))
111  {
112  //Profile-specific details. One of many profiles.
113  ret = getHEVCProfileDetails(stMsgData, attr, index);
114  }
115  else if(strcasecmp(stMsgData->paramName, HDMI_RESOLUTIONS_STRING) == 0)
116  {
117  ret = getSupportedResolutions(stMsgData);
118  }
119  else
120  {
121  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"[%s:%s] Parameter \'%s\' is Not Supported \n", __FILE__, __FUNCTION__, paramName);
122  stMsgData->faultCode = fcInvalidParameterName;
123  ret = NOK;
124  }
125  }
126  catch (const std::exception& e )
127  {
128  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"[%s:%s] Exception caught %s \n", __FILE__, __FUNCTION__, e.what());
129  stMsgData->faultCode = fcInternalError;
130  return NOK;
131  }
132  RDK_LOG(RDK_LOG_TRACE1,LOG_TR69HOSTIF,"[%s:%s]Exiting... \n", __FILE__, __FUNCTION__);
133  return ret;
134 }
135 
136 int hostIf_STBServiceCapabilities::getVideoStandards(HOSTIF_MsgData_t *stMsgData)
137 {
138  int bytes_written = 0;
139  try {
141  unsigned int supported_standards = decoder.getSupportedVideoCodingFormats();
142  if(0 != (supported_standards & dsVIDEO_CODEC_MPEGHPART2))
143  {
144  bytes_written += snprintf(&(stMsgData->paramValue[bytes_written]), (TR69HOSTIFMGR_MAX_PARAM_LEN - bytes_written), "%s,", "MPEGH-Part2 ([ISO/IEC23008-1]])");
145  }
146  if(0 != (supported_standards & dsVIDEO_CODEC_MPEG2))
147  {
148  bytes_written += snprintf(&(stMsgData->paramValue[bytes_written]), (TR69HOSTIFMGR_MAX_PARAM_LEN - bytes_written), "%s,", "MPEG2-Part2 ([ISO/IEC13818-1])");
149  }
150  if(0 != (supported_standards & dsVIDEO_CODEC_MPEG4PART10))
151  {
152  bytes_written += snprintf(&(stMsgData->paramValue[bytes_written]), (TR69HOSTIFMGR_MAX_PARAM_LEN - bytes_written), "%s,", "MPEG4-Part10 ([ISO/IEC14496-10])");
153  }
154  stMsgData->paramValue[bytes_written -1] = '\0'; //substitue string terminator for the final comma.
155  RDK_LOG(RDK_LOG_DEBUG,LOG_TR69HOSTIF,"[%s] : Value: %s \n",__FUNCTION__, stMsgData->paramValue);
156  stMsgData->paramtype = hostIf_StringType;
157  stMsgData->paramLen = strlen(stMsgData->paramValue);
158  }
159  catch (const std::exception e) {
160  RDK_LOG(RDK_LOG_WARN,LOG_TR69HOSTIF,"[%s] Exception\n",__FUNCTION__);
161  stMsgData->faultCode = fcInternalError;
162  return NOK;
163  }
164 
165  return OK;
166 }
167 
168 int hostIf_STBServiceCapabilities::getNumHEVCProfileEntries(HOSTIF_MsgData_t *stMsgData)
169 {
170  try {
172  dsVideoCodecInfo_t info = decoder.getVideoCodecInfo(dsVIDEO_CODEC_MPEGHPART2);
173 
174  if(0 == info.num_entries)
175  {
176  RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Zero profile entries reported.\n",__FUNCTION__);
177  stMsgData->faultCode = fcInternalError;
178  return NOK;
179  }
180  put_int(stMsgData->paramValue, info.num_entries);
181  RDK_LOG(RDK_LOG_DEBUG,LOG_TR69HOSTIF,"[%s] : Value: %s \n",__FUNCTION__, stMsgData->paramValue);
182  stMsgData->paramtype = hostIf_UnsignedIntType;
183  stMsgData->paramLen = sizeof(unsigned int);
184  }
185  catch (const std::exception e) {
186  RDK_LOG(RDK_LOG_WARN,LOG_TR69HOSTIF,"[%s] Exception\n",__FUNCTION__);
187  stMsgData->faultCode = fcInternalError;
188  return NOK;
189  }
190 
191  return OK;
192 }
193 
194 static const char * convertHEVCProfileNameToString(dsVideoCodecHevcProfiles_t profile)
195 {
196  switch(profile)
197  {
198  case dsVIDEO_CODEC_HEVC_PROFILE_MAIN:
199  return "MAIN";
200  case dsVIDEO_CODEC_HEVC_PROFILE_MAIN10:
201  return "MAIN 10";
202  case dsVIDEO_CODEC_HEVC_PROFILE_MAINSTILLPICTURE:
203  return "MAIN STILL PICTURE";
204  default:
205  RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Unknown profile 0x%x!\n",__FUNCTION__, (unsigned int)profile);
206  return "";
207  }
208 }
209 
210 static unsigned int getMaxHEVCDecodeKBitRate(dsVideoCodecProfileSupport_t &entry)
211 {
212  unsigned int kbit_rate = 0;
213  if((dsVIDEO_CODEC_HEVC_PROFILE_MAIN10 == entry.profile) && (5.1f == entry.level))
214  {
215  kbit_rate = 40000;
216  }
217  else
218  {
219  RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Unknown profile (0x%x) and level (%g) combination!\n",__FUNCTION__, entry.profile, entry.level);
220  }
221  return kbit_rate;
222 }
223 
224 static const char* getTR181ResolutionString(std::string &resolution)
225 {
226  if("720p" == resolution)
227  return "1280x720p/59.94Hz";
228  else if("1080i" == resolution)
229  return "1920x1080i/59.94Hz";
230  else if(("1080p60" == resolution) || ("1080p" == resolution))
231  return "1920x1080p/59.94Hz";
232  else if("2160p30" == resolution)
233  return "3840x2160p/30Hz";
234  else if("2160p60" == resolution)
235  return "3840x2160p/59.94Hz";
236  else if("480i" == resolution)
237  return "720x480i/59.94Hz";
238  else if("480p" == resolution)
239  return "720x480p/59.94Hz";
240  else if(("576p50" == resolution) || ("576p" == resolution))
241  return "720x576p/50Hz";
242  else if("720p50" == resolution)
243  return "1280x720p/50Hz";
244  else if("1080p30" == resolution)
245  return "1920x1080p/30Hz";
246  else if(("1080i50" == resolution) || ("1080i25" == resolution))
247  return "1920x1080i/50Hz";
248  else if("1080p24" == resolution)
249  return "1920x1080p/24Hz";
250  else if("1080p50" == resolution)
251  return "1920x1080p/50Hz";
252  else if("2160p50" == resolution)
253  return "3840x2160p/50Hz";
254  else if ("1080p25" == resolution)
255  return "1920x1080p/25Hz";
256  else
257  {
258  RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s: Unhandled resolution: %s. Cannot translate!\n", __FUNCTION__, resolution.c_str());
259  return "";
260  }
261 }
262 
263 int hostIf_STBServiceCapabilities::getHEVCProfileDetails(HOSTIF_MsgData_t * stMsgData, const char* attr, unsigned int index)
264 {
265  int ret = OK;
266  int bytes_written = 0;
267  try {
269  dsVideoCodecInfo_t info = decoder.getVideoCodecInfo(dsVIDEO_CODEC_MPEGHPART2);
270 
271  if((0 == info.num_entries) || (index > info.num_entries))
272  {
273  RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Could not find profiles matching index %d.\n",__FUNCTION__, index);
274  stMsgData->faultCode = ((0 == info.num_entries) ? fcInternalError : fcInvalidParameterName );
275  return NOK;
276  }
277 
278  if(strcasecmp(attr, PROFILE_NAME_STRING) == 0)
279  {
280  bytes_written = snprintf(stMsgData->paramValue, TR69HOSTIFMGR_MAX_PARAM_LEN, "%s", convertHEVCProfileNameToString(info.entries[index - 1].profile));
281  stMsgData->paramValue[bytes_written] = '\0';
282  stMsgData->paramtype = hostIf_StringType;
283  stMsgData->paramLen = bytes_written;
284  }
285  else if(strcasecmp(attr, PROFILE_LEVEL_STRING) == 0)
286  {
287  bytes_written = snprintf(stMsgData->paramValue, TR69HOSTIFMGR_MAX_PARAM_LEN, "L%g", info.entries[index - 1].level);
288  stMsgData->paramValue[bytes_written] = '\0';
289  stMsgData->paramtype = hostIf_StringType;
290  stMsgData->paramLen = bytes_written;
291  }
292  else if(strcasecmp(attr, PROFILE_MAX_DECODE_CAPABILITY_STRING) == 0)
293  {
294  put_int(stMsgData->paramValue,getMaxHEVCDecodeKBitRate(info.entries[index -1]));
295  stMsgData->paramtype = hostIf_UnsignedIntType;
296  stMsgData->paramLen = sizeof(unsigned int);
297  }
298  else
299  {
300  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"[%s:%s] Parameter \'%s\' is Not Supported \n", __FILE__, __FUNCTION__, attr);
301  stMsgData->faultCode = fcInvalidParameterName;
302  ret = NOK;
303  }
304 
305  }
306  catch (...) {
307  RDK_LOG(RDK_LOG_WARN,LOG_TR69HOSTIF,"[%s] Exception\n",__FUNCTION__);
308  stMsgData->faultCode = fcInternalError;
309  return NOK;
310  }
311 
312  return OK;
313 
314 }
315 
316 int hostIf_STBServiceCapabilities::getSupportedResolutions(HOSTIF_MsgData_t *stMsgData)
317 {
318  size_t iElementInList = 0;
319  size_t iResolutionsListSize = 0;
320  char aiResolution[MAX_RESOLUTION_LENGTH] = {'\0'};
321  try
322  {
323  std::list <std::string> supported_resolutions;
325  decoder.getSettopSupportedResolutions(supported_resolutions);
326  iResolutionsListSize = supported_resolutions.size();
327 
328  RDK_LOG(RDK_LOG_DEBUG,LOG_TR69HOSTIF,"[%s] : List Size: %d \n",__FUNCTION__, iResolutionsListSize);
329  memset(stMsgData->paramValue, 0, TR69HOSTIFMGR_MAX_PARAM_LEN);
330 
331  std::list<std::string>::iterator entry;
332  for(entry = supported_resolutions.begin(); entry != supported_resolutions.end(); entry++)
333  {
334  iElementInList++;
335  snprintf(aiResolution, MAX_RESOLUTION_LENGTH, "%s", getTR181ResolutionString(*entry));
336  strncat(stMsgData->paramValue, aiResolution, TR69HOSTIFMGR_MAX_PARAM_LEN-strlen(stMsgData->paramValue)-1);
337  if(iElementInList < iResolutionsListSize)
338  strncat(stMsgData->paramValue,",", TR69HOSTIFMGR_MAX_PARAM_LEN-strlen(stMsgData->paramValue)-1);
339  RDK_LOG(RDK_LOG_DEBUG,LOG_TR69HOSTIF,"[%s] : resolution: %s\n",__FUNCTION__, (*entry).c_str());
340  }
341  stMsgData->paramtype = hostIf_StringType;
342  stMsgData->paramLen = strlen(stMsgData->paramValue);
343  RDK_LOG(RDK_LOG_DEBUG,LOG_TR69HOSTIF,"[%s] : Value: %s \n",__FUNCTION__, stMsgData->paramValue);
344  }
345  catch (...) {
346  RDK_LOG(RDK_LOG_WARN,LOG_TR69HOSTIF,"[%s] Exception\n",__FUNCTION__);
347  stMsgData->faultCode = fcInternalError;
348  return NOK;
349  }
350  return OK;
351 
352 }
dsTypes.h
Device Settings HAL types.
dsVideoCodecProfileSupport_t
Definition: dsTypes.h:1105
rdk_debug.h
_HostIf_MsgData_t
Definition: hostIf_tr69ReqHandler.h:170
hostIf_main.h
hostIf_main API.
_HostIf_MsgData_t::paramtype
HostIf_ParamType_t paramtype
Definition: hostIf_tr69ReqHandler.h:177
RDK_LOG
#define RDK_LOG
Definition: rdk_debug.h:258
_HostIf_MsgData_t::faultCode
faultCode_t faultCode
Definition: hostIf_tr69ReqHandler.h:179
_HostIf_MsgData_t::paramName
char paramName[(4 *1024)]
Definition: hostIf_tr69ReqHandler.h:171
device::Host::getVideoDevices
List< VideoDevice > getVideoDevices()
This API is used to get the list of the video devices (i.e. Decoders) supported on the device....
Definition: host.cpp:331
videoDevice.hpp
It contains class referenced by videoDevice.cpp file.
hostIf_STBServiceCapabilities
Definition: Capabilities.h:44
_HostIf_MsgData_t::paramValue
char paramValue[(4 *1024)]
Definition: hostIf_tr69ReqHandler.h:172
device::Host::getInstance
static Host & getInstance(void)
This API is used to get a reference to the single instance of the Host object.
Definition: host.cpp:88
device::VideoDevice
class extending DSConstant to implement the videoDevice interface.
Definition: videoDevice.hpp:53
dsVideoCodecInfo_t
Definition: dsTypes.h:1111
put_int
void put_int(char *ptr, int val)
This function converts the input data to integer type.
Definition: hostIf_utils.cpp:152
_HostIf_MsgData_t::paramLen
short paramLen
Definition: hostIf_tr69ReqHandler.h:175