RDK Documentation (Open Sourced RDK Components)
snmpAdapter.cpp
Go to the documentation of this file.
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  * @file snmpAdapter.cpp
22  * @brief This source file contains the APIs for getting device information.
23  */
24 
25 /**
26  * @file snmpAdapter.cpp
27  *
28  * @brief SNMP RDKCENTRAL API Implementation.
29  *
30  * This is the implementation of the DeviceInfo API.
31  *
32  * @par Document
33  * TBD Relevant design or API documentation.
34  *
35  */
36 
37 
38 /*****************************************************************************
39  * STANDARD INCLUDE FILES
40  *****************************************************************************/
41 
42 
43 /**
44 * @defgroup tr69hostif
45 * @{
46 * @defgroup hostif
47 * @{
48 **/
49 
50 #include "snmpAdapter.h"
51 #include <fstream>
52 #include "safec_lib.h"
53 #include <vector>
54 #include <cstring>
55 
56 #ifdef YOCTO_BUILD
57 #include "secure_wrapper.h"
58 #endif
59 
60 #define TR181_SNMPOID_FILE "/etc/tr181_snmpOID.conf"
61 #define interface_STB "STB"
62 #define interface_CM "CM"
63 #define SNMP_AGENT_CM_IP_ADDRESS "192.168.100.1"
64 #define SNMP_AGENT_STB_IP_ADDRESS "127.0.0.1"
65 #define SNMP_COMMUNITY "hDaFHJG7"
66 
67 GHashTable* hostIf_snmpAdapter::ifHash = NULL;
68 GHashTable* hostIf_snmpAdapter::m_notifyHash = NULL;
69 GMutex* hostIf_snmpAdapter::m_mutex = NULL;
70 map<string, vector<pair <string, string>>> hostIf_snmpAdapter::tr181Map;
71 /****************************************************************************************************************************************************/
72 // Device.X_RDKCENTRAL Profile. Getters:
73 /****************************************************************************************************************************************************/
74 
75 /**
76  * @brief Class Constructor of the class hostIf_snmpAdapter.
77  *
78  */
80  dev_id(dev_id)
81 {
82 
83 }
84 
85 /**
86  * @brief Class Destructor of the class hostIf_snmpAdapter.
87  *
88  */
90 {
91  if(m_notifyHash)
92  {
93  g_hash_table_destroy(m_notifyHash);
94  }
95 }
96 
97 /**
98  * @brief This function opens the RF_DocsIf_tr181_snmp map file,
99  * parse the TR181 parameter and its correspoinding OID, fill it in map container.
100  *
101  */
103 {
104  string line;
105  ifstream fileStream (TR181_SNMPOID_FILE);
106  char delimeter[] = " \t\n\r\f\v";
107 
108  tr181Map.clear();
109  if (fileStream.is_open())
110  {
111  while(getline(fileStream, line))
112  {
113  int pos = line.find('=');
114  if(pos != string::npos)
115  {
116  string OID_value,interface_value;
117  string key = line.substr(0, pos);
118  int result = line.find(interface_STB);
119  if(result>0)
120  {
121  interface_value = interface_STB;
122  line.erase(line.find(interface_value));
123  OID_value = line.substr(pos+1);
124  }
125  else
126  {
127  interface_value = interface_CM;
128  line.erase(line.find(interface_value));
129  OID_value = line.substr(pos+1);
130  }
131  key.erase(0, key.find_first_not_of(delimeter));
132  key.erase(key.find_last_not_of(delimeter) + 1);
133 
134  OID_value.erase(0, OID_value.find_first_not_of(delimeter));
135  OID_value.erase(OID_value.find_last_not_of(delimeter) + 1);
136 
137  tr181Map.insert( { key, {{ OID_value, interface_value }} } );
138  }
139 
140  }
141  }
142  else
143  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"[%s:%d] Error opening %s fileStream.", __FUNCTION__, __LINE__, TR181_SNMPOID_FILE );
144 }
145 
146 /**
147  * @brief This function clear the TR181 OID map container.
148  *
149  */
151 {
152  tr181Map.clear();
153 }
154 
155 hostIf_snmpAdapter* hostIf_snmpAdapter::getInstance(int dev_id)
156 {
157  hostIf_snmpAdapter* pRet = NULL;
158 
159  if(ifHash)
160  pRet = (hostIf_snmpAdapter *)g_hash_table_lookup(ifHash,(gpointer) dev_id);
161  else
162  ifHash = g_hash_table_new(NULL,NULL);
163 
164  if(!pRet)
165  {
166  try {
167  pRet = new hostIf_snmpAdapter(dev_id);
168  } catch(int e)
169  {
170  RDK_LOG(RDK_LOG_WARN,LOG_TR69HOSTIF,"Caught exception, not able create SNMP Device RDK Central instance..\n");
171  }
172  g_hash_table_insert(ifHash, (gpointer)dev_id, pRet);
173  }
174  return pRet;
175 }
176 
177 GList* hostIf_snmpAdapter::getAllInstances()
178 {
179  if(ifHash)
180  return g_hash_table_get_keys(ifHash);
181  return NULL;
182 }
183 
184 void hostIf_snmpAdapter::closeInstance(hostIf_snmpAdapter *pDev)
185 {
186  if(pDev)
187  {
188  g_hash_table_remove(ifHash, (gconstpointer)pDev->dev_id);
189  delete pDev;
190  }
191 }
192 
193 void hostIf_snmpAdapter::closeAllInstances()
194 {
195  if(ifHash)
196  {
197  GList* tmp_list = g_hash_table_get_values (ifHash);
198 
199  while(tmp_list)
200  {
201  hostIf_snmpAdapter* pDev = (hostIf_snmpAdapter *)tmp_list->data;
202  tmp_list = tmp_list->next;
203  closeInstance(pDev);
204  }
205  }
206 }
207 
208 void hostIf_snmpAdapter::getLock()
209 {
210  if(!m_mutex)
211  {
212  m_mutex = g_mutex_new();
213  }
214  g_mutex_lock(m_mutex);
215 }
216 
217 void hostIf_snmpAdapter::releaseLock()
218 {
219  g_mutex_unlock(m_mutex);
220 }
221 
222 GHashTable* hostIf_snmpAdapter::getNotifyHash()
223 {
224  if(m_notifyHash)
225  return m_notifyHash;
226  else
227  return m_notifyHash = g_hash_table_new(g_str_hash, g_str_equal);
228 }
229 
230 /**
231  * @brief This function fetch the SNMP OID for the corresponding TR181 param,
232  * and run the snmpget command with the OID. The result will be return back as string.
233  *
234  */
236 {
237  int ret = NOT_HANDLED;
238  char cmd[BUFF_LENGTH_256] = { 0 };
239  char resultBuff[BUFF_LENGTH_256] = { 0 };
240  char delimeter[] = " \t\n\r\f\v";
241  map<string, vector<pair <string, string>>>::iterator it;
242  string consoleString("");
243  errno_t rc = -1;
244 
245  if(stMsgData)
246  {
247  it = tr181Map.find(stMsgData->paramName);
248  if (it != tr181Map.end())
249  {
250  string value = it->second[0].second;
251  if (value.compare(interface_STB) == 0)
252  {
253  snprintf (cmd, BUFF_LENGTH_256, "snmpget -OQ -Ir -v 2c -c %s %s %s",
254  SNMP_COMMUNITY,
255  SNMP_AGENT_STB_IP_ADDRESS,
256  it->second[0].first.c_str());
257  }
258  else
259  {
260  snprintf (cmd, BUFF_LENGTH_256, "snmpget -OQ -Ir -v 2c -c %s %s %s",
261  SNMP_COMMUNITY,
262  SNMP_AGENT_CM_IP_ADDRESS,
263  it->second[0].first.c_str());
264  }
265 
266  RDK_LOG(RDK_LOG_TRACE1,LOG_TR69HOSTIF,"[%s] %s\n", __FUNCTION__, cmd);
267  ret = GetStdoutFromCommand( cmd, consoleString);
268  if (ret == OK)
269  {
270  int pos = consoleString.find('=');
271  if(pos != string::npos)
272  {
273  string subStr = consoleString.substr(pos + 1);
274  subStr.erase(0, subStr.find_first_not_of(delimeter));
275  subStr.erase(subStr.find_last_not_of(delimeter) + 1);
276  rc=strcpy_s(stMsgData->paramValue,sizeof(stMsgData->paramValue), subStr.c_str());
277  if(rc!=EOK)
278  {
279  ERR_CHK(rc);
280  }
281  }
282  else
283  {
284  rc=strcpy_s(stMsgData->paramValue,sizeof(stMsgData->paramValue), resultBuff);
285  if(rc!=EOK)
286  {
287  ERR_CHK(rc);
288  }
289  }
290  stMsgData->paramtype = hostIf_StringType;
291  RDK_LOG(RDK_LOG_TRACE1,LOG_TR69HOSTIF,"[%s] %s %s\n", __FUNCTION__, stMsgData->paramName, stMsgData->paramValue);
292  ret = OK;
293  }
294  }
295  else
296  {
297  ret = NOK;
298  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"[%s:%d] %s NOT found in the map.\n", __FUNCTION__, __LINE__, stMsgData->paramName );
299  }
300  }
301  return ret;
302 }
303 
304 /**
305  * @brief This function fetch the SNMP OID for the corresponding TR181 param,
306  * and run the snmpset command with the OID.
307  *
308  */
310 {
311  int ret = NOT_HANDLED;
312  char cmd[BUFF_LENGTH_256] = { 0 };
313  char resultBuff[BUFF_LENGTH_256] = { 0 };
314  map<string, vector<pair <string, string>>>::iterator it;
315 
316 #ifdef YOCTO_BUILD
317  FILE *fp;
318 #define CMD(cmd, length, args...) ({ snprintf(cmd, length, args); fp = (v_secure_popen("r", args); )})
319 #else
320 #define CMD(cmd, length, args...) ({ snprintf(cmd, length, args); })
321 #endif
322 
323  if(stMsgData)
324  {
325  it = tr181Map.find(stMsgData->paramName);
326  if (it != tr181Map.end())
327  {
328  string value = it->second[0].second;
329  switch(stMsgData->paramtype)
330  {
331  case hostIf_StringType:
332  if (value.compare(interface_STB) == 0){
333  CMD(cmd, BUFF_LENGTH_256, "snmpset -v 2c -c %s %s %s s %s",
334  SNMP_COMMUNITY, SNMP_AGENT_STB_IP_ADDRESS,
335  it->second[0].first.c_str(),
336  stMsgData->paramValue);
337  }
338  else{
339  CMD(cmd, BUFF_LENGTH_256, "snmpset -v 2c -c %s %s %s s %s",
340  SNMP_COMMUNITY, SNMP_AGENT_CM_IP_ADDRESS,
341  it->second[0].first.c_str(),
342  stMsgData->paramValue);
343  }
344  break;
345 
346  case hostIf_IntegerType:
347  if (value.compare(interface_STB) == 0)
348  {
349  CMD(cmd, BUFF_LENGTH_256, "snmpset -v 2c -c %s %s %s i %d",
350  SNMP_COMMUNITY, SNMP_AGENT_STB_IP_ADDRESS,
351  it->second[0].first.c_str(),
352  stMsgData->paramValue);
353  }
354  else{
355  CMD(cmd, BUFF_LENGTH_256, "snmpset -v 2c -c %s %s %s i %d",
356  SNMP_COMMUNITY, SNMP_AGENT_CM_IP_ADDRESS,
357  it->second[0].first.c_str(),
358  stMsgData->paramValue);
359  }
360  break;
361 
362  case hostIf_UnsignedIntType:
363  if (value.compare(interface_STB) == 0)
364  {
365  CMD(cmd, BUFF_LENGTH_256, "snmpset -v 2c -c %s %s %s u %d",
366  SNMP_COMMUNITY,
367  SNMP_AGENT_STB_IP_ADDRESS,
368  it->second[0].first.c_str(),
369  stMsgData->paramValue);
370  }
371  else{
372  CMD(cmd, BUFF_LENGTH_256, "snmpset -v 2c -c %s %s %s u %d",
373  SNMP_COMMUNITY,
374  SNMP_AGENT_CM_IP_ADDRESS,
375  it->second[0].first.c_str(),
376  stMsgData->paramValue);
377  }
378  break;
379 
380  case hostIf_BooleanType:
381  case hostIf_DateTimeType:
382  case hostIf_UnsignedLongType:
383  default:
384  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"[%s:%d] %s not supported type %d\n", __FUNCTION__, __LINE__, stMsgData->paramName, stMsgData->paramtype);
385  return NOK;
386  }
387 
388  RDK_LOG(RDK_LOG_TRACE1,LOG_TR69HOSTIF,"[%s] %s\n", __FUNCTION__, cmd);
389 #ifdef YOCTO_BUILD
390  if (fp == NULL) {
391  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s]: cannot run command [%s]\n", __FUNCTION__, cmd);
392  ret = NOK;
393  } else if (fgets (resultBuff, BUFF_LENGTH_256, fp) == NULL) {
394  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s]: cannot read output from command [%s]\n", __FUNCTION__, cmd);
395  v_secure_pclose (fp);
396  ret = NOK;
397  } else {
398  ret = v_secure_pclose(fp);
399  }
400 
401  RDK_LOG (RDK_LOG_DEBUG, LOG_TR69HOSTIF, "[%s]: command [%s] returned [%s]\n", __FUNCTION__, cmd, resultBuff);
402 #else
403  ret = read_command_output (cmd, resultBuff, BUFF_LENGTH_256);
404 #endif
405  stMsgData->faultCode = (OK == ret)?fcNoFault:fcRequestDenied;
406  }
407  else
408  {
409  ret = NOK;
410  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"[%s:%d] %s NOT found in the map.\n", __FUNCTION__,__LINE__, stMsgData->paramName );
411  }
412  }
413 #undef CMD
414  return ret;
415 }
416 
417 /* End of doxygen group */
418 /**
419  * @}
420  */
421 
422 /* End of file xxx_api.c. */
423 
424 
425 /** @} */
426 /** @} */
hostIf_snmpAdapter
This class provides the interface for getting device information.
Definition: snmpAdapter.h:94
_HostIf_MsgData_t
Definition: hostIf_tr69ReqHandler.h:170
hostIf_snmpAdapter::get_ValueFromSNMPAdapter
int get_ValueFromSNMPAdapter(HOSTIF_MsgData_t *)
This function fetch the SNMP OID for the corresponding TR181 param, and run the snmpget command with ...
Definition: snmpAdapter.cpp:235
hostIf_snmpAdapter::init
static void init(void)
This function opens the RF_DocsIf_tr181_snmp map file, parse the TR181 parameter and its correspoindi...
Definition: snmpAdapter.cpp:102
hostIf_snmpAdapter::set_ValueToSNMPAdapter
int set_ValueToSNMPAdapter(HOSTIF_MsgData_t *)
This function fetch the SNMP OID for the corresponding TR181 param, and run the snmpset command with ...
Definition: snmpAdapter.cpp:309
hostIf_snmpAdapter::hostIf_snmpAdapter
hostIf_snmpAdapter(int dev_id)
Class Constructor of the class hostIf_snmpAdapter.
Definition: snmpAdapter.cpp:79
snmpAdapter.h
The header file provides TR181 SNMP device RDK Central APIs.
_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
GetStdoutFromCommand
int GetStdoutFromCommand(char *cmd, string &consoleString)
This function reads the complete output(upto 1k bytes) as string and return to caller....
Definition: hostIf_utils.cpp:435
_HostIf_MsgData_t::paramValue
char paramValue[(4 *1024)]
Definition: hostIf_tr69ReqHandler.h:172
hostIf_snmpAdapter::unInit
static void unInit(void)
This function clear the TR181 OID map container.
Definition: snmpAdapter.cpp:150
hostIf_snmpAdapter::~hostIf_snmpAdapter
~hostIf_snmpAdapter()
Class Destructor of the class hostIf_snmpAdapter.
Definition: snmpAdapter.cpp:89