RDK Documentation (Open Sourced RDK Components)
Device_InterfaceStack.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 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  * @file Device_InterfaceStack.cpp
22  * @brief This source file contains the APIs of device interface stack.
23  */
24 
25 /*****************************************************************************
26  * STANDARD INCLUDE FILES
27  *****************************************************************************/
28 #include <string>
29 #include <sstream>
30 #include <map>
31 #include <utility> // for std::pair
32 #include <typeinfo>
33 #include <list>
34 
35 #include <string.h>
36 #include "Device_InterfaceStack.h"
37 #include "Device_IP.h"
38 #include "Device_IP_Interface.h"
40 #include "hostIf_utils.h"
41 
42 #ifdef USE_MoCA_PROFILE
43 #include "Device_MoCA_Interface.h"
44 #endif
45 
46 #ifdef YOCTO_BUILD
47 #include "secure_wrapper.h"
48 #endif
49 
50 #define MAX_BUF_LEN 128
51 #define MAX_CMD_LEN 256
52 #define MAX_IFNAME_LEN 64
53 #define SYS_CLASS_NET_PATH "/sys/class/net/"
54 
55 #define IN
56 #define OUT
57 #define INOUT
58 #define DEVICE_ETHERNET_INTERFACE(PORT_NUM) std::string("Device.Ethernet.Interface.") + int_to_string(PORT_NUM)
59 #ifdef USE_MoCA_PROFILE
60 #define DEVICE_MOCA_INTERFACE(PORT_NUM) std::string("Device.MoCA.Interface.") + int_to_string(PORT_NUM)
61 #endif
62 #define DEVICE_IP_INTERFACE(PORT_NUM) std::string("Device.IP.Interface.") + int_to_string(PORT_NUM)
63 #define DEVICE_BRIDGING_BRIDGE(BRIDGE_NUM, PORT_NUM) (std::string("Device.Bridging.Bridge.") + \
64  int_to_string(BRIDGE_NUM) + \
65  ".PORT." + \
66  int_to_string(PORT_NUM))
67 
68 /*****************************************************************************
69  * Initialize all the static variables of the class
70  *****************************************************************************/
71 GHashTable* hostif_InterfaceStack::stIshash = NULL;
72 GHashTable* hostif_InterfaceStack::stBridgeTableHash = NULL;
73 GMutex* hostif_InterfaceStack::stMutex = NULL;
74 GHashTable* hostif_InterfaceStack::m_notifyHash = NULL;
75 
76 /*
77  * hostif_InterfaceStack Constructor
78  */
79 
80 /**
81  * @brief Class Constructor of the class hostif_InterfaceStack.
82  *
83  * It will initialize the device id.
84  *
85  * @param[in] dev_id Identification number of the device.
86  * @param[in] _higherLayer String of the higher layer i.e "Device.Bridging.Bridge.1.port.2".
87  * @param[in] _lowerLayer String of the lower layer i.e "Device.Ethernet.Interface.1".
88  */
89 hostif_InterfaceStack::hostif_InterfaceStack(int dev_id, char *_higherLayer, char *_lowerLayer):dev_id(dev_id)
90 {
91  RDK_LOG(RDK_LOG_DEBUG,LOG_TR69HOSTIF,"Inside constructor for dev_id:%d\n", dev_id);
92 
93  bCalledHigherLayer = 0;
94  bCalledLowerLayer = 0;
95 
96  memset(backupHigherLayer, '\0', sizeof(backupHigherLayer));
97  memset(backupLowerLayer, '\0', sizeof(backupLowerLayer));
98  if(_higherLayer)
99  {
100  strncpy(higherLayer, _higherLayer, sizeof(higherLayer));
101  }
102  else
103  {
104  memset(higherLayer, '\0', sizeof(higherLayer));
105  }
106 
107  if(_lowerLayer)
108  {
109  strncpy(lowerLayer, _lowerLayer, sizeof(lowerLayer) -1); //CID:136379 - Buffer size warning
110  lowerLayer[sizeof(lowerLayer) -1] = '\0';
111  }
112  else
113  {
114  memset(lowerLayer, '\0', sizeof(lowerLayer));
115  }
116 }
117 
118 /*
119  * It populates an interface stack table hash and returns the number of entries in the table by
120  * following below steps.
121  * - Deletes existing interface stack table and bridge table
122  * - Populated bridge table with the list of bridges and bridge interfaces
123  *
124  * - Build lower layer entries for
125  * - All available ethernet interfaces
126  * - All available Moca Interfaces (If MoCA is enabled)
127  * - Build higher layer and lower layer entries for all bridges and underlying interfaces that are part of the bridge.
128  * - Note: bridges are filled up only with lower layer entries
129  * underlying interfaces are filled up with higher layer entries
130  * lower layer entries for underlying bridge interfaces have been built in previous step.
131  * - Fill up the remaining higher layer entries with the IP interfaces.
132  * - 'remaining higher layer entries' is meant that the unfilled higher layer entries in previous steps.
133  *
134  * - Create interface stack instances by parsing the 'layer info' map that was filled up in previous steps.
135  *
136  * Consider the following example:
137  * Given the 'Lower level Interfaces' and 'Bridge Table', the program should build the Interface Stack as below.
138 
139  * Lower level Interfaces
140  * ----------------------
141  * InterfaceName TypeOfInterface LowerLevelDM
142  * bcm0 Ethernet Device.Ethernet.Interface.1
143  * eth2 Ethernet Device.Ethernet.Interface.2
144  * eth1 MoCA Device.MoCA.Interface.1
145  * Bridge Table
146  * ------------
147  * BridgeName ParentInterface ChildInterface
148  * hnbr0 hnbr0 -
149  * hnbr0 - bcm0
150  * hnbr0 - MoCA
151  * Interface Stack to be built
152  * ---------------------------
153  * Row HigherLayer LowerLayer
154  * 1 Device.Bridging.Bridge.1.port.2 Device.Ethernet.Interface.1
155  * 3 Device.Bridging.Bridge.1.port.3 Device.MoCA.Interface.1
156  * 4 Device.IP.Interface.8 Device.Ethernet.Interface.2
157  * 5 Device.IP.Interface.9 Device.Bridging.Bridge.1.port.1
158  * 6 Device.Bridging.Bridge.1.port.1 Device.Bridging.Bridge.1.port.2
159  * 7 Device.Bridging.Bridge.1.port.1 Device.Bridging.Bridge.1.port.3
160  *
161  */
162 int hostif_InterfaceStack:: get_Device_InterfaceStackNumberOfEntries(HOSTIF_MsgData_t *stMsgData)
163 {
164  int ret = NOK;
165  int interfaceStackNumOfEntries = 0;
166  char lowerLayerPath[MAX_HIGHERLAYER_LEN] = {'\0'};
167  char higherLayerPath[MAX_HIGHERLAYER_LEN] = {'\0'};
168 
169  InterfaceStackMap_t layerInfo;
170  InterfaceStackMap_t::iterator layerIterator;
171  IPInterfacesMap_t ipInterfaceMap;
172 
173  // Close all instances of the interface stack table
174  hostif_InterfaceStack::closeAllInstances();
175 
176  // Delete existing Bridge table
177  hostif_InterfaceStack::deleteBridgeTable();
178 
179  // Populate bridge table
180  hostif_InterfaceStack::populateBridgeTable();
181 
182  do
183  {
184  if( OK != getIPInterfaces(ipInterfaceMap))
185  {
186  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"%s:%d get_Device_IP_InterfaceNumberOfEntries failed\n", __FILE__, __LINE__);
187  break;
188  }
189 
190  if( OK != buildLowerLayerInfo<hostIf_EthernetInterface>(layerInfo))
191  {
192  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"%s:%d Failed while building layer info for Ethernet interfaces\n", __FILE__, __LINE__);
193  break;
194  }
195 
196 #ifdef USE_MoCA_PROFILE
197  if( OK != buildLowerLayerInfo<MoCAInterface>(layerInfo))
198  {
199  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"%s:%d Failed while building layer info for MoCA interfaces\n", __FILE__, __LINE__);
200  break;
201  }
202 #endif
203 
204  if( OK != buildBridgeTableLayerInfo(layerInfo))
205  {
206  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"%s:%d Failed while building layer info for bridges\n", __FILE__, __LINE__);
207  break;
208  }
209 
210  fillHigherLayersWithIP(layerInfo, ipInterfaceMap);
211 
212  for(layerIterator = layerInfo.begin(); layerIterator != layerInfo.end(); layerIterator++)
213  {
214  interfaceStackNumOfEntries++;
215 
216  memset(lowerLayerPath, '\0', sizeof(lowerLayerPath));
217  memset(higherLayerPath, '\0', sizeof(higherLayerPath));
218 
219  snprintf(higherLayerPath, sizeof(higherLayerPath), layerIterator->second.higherLayer.c_str());
220  snprintf(lowerLayerPath, sizeof(lowerLayerPath), layerIterator->second.lowerLayer.c_str());
221 
222  if(OK == hostif_InterfaceStack::createInstance(interfaceStackNumOfEntries, higherLayerPath, lowerLayerPath ))
223  {
224  RDK_LOG(RDK_LOG_DEBUG,LOG_TR69HOSTIF,"%s:%d successfully created instance [%d] with higher layer [%s] lower layer [%s]\n",
225  __FUNCTION__, __LINE__, interfaceStackNumOfEntries, higherLayerPath, lowerLayerPath);
226  }
227  }
228  } while(0);
229 
230  if(interfaceStackNumOfEntries > 0)
231  {
232  ret = OK;
233  stMsgData->paramtype=hostIf_IntegerType;
234  stMsgData->paramLen = sizeof(int);
235  put_int(stMsgData->paramValue, interfaceStackNumOfEntries);
236  }
237 
238  return ret;
239 }
240 
241 void hostif_InterfaceStack::getLock()
242 {
243  if(!stMutex)
244  {
245  stMutex = g_mutex_new();
246  }
247  g_mutex_lock(stMutex);
248 }
249 
250 void hostif_InterfaceStack::releaseLock()
251 {
252  g_mutex_unlock(stMutex);
253 }
254 
255 GHashTable* hostif_InterfaceStack::getNotifyHash()
256 {
257  if(m_notifyHash)
258  {
259  return m_notifyHash;
260  }
261  else
262  {
263  return m_notifyHash = g_hash_table_new(g_str_hash, g_str_equal);
264  }
265 }
266 
267 hostif_InterfaceStack::~hostif_InterfaceStack()
268 {
269  if(m_notifyHash)
270  {
271  g_hash_table_destroy(m_notifyHash);
272  }
273 }
274 
275 hostif_InterfaceStack* hostif_InterfaceStack::getInstance(int dev_id)
276 {
277  RDK_LOG(RDK_LOG_DEBUG,LOG_TR69HOSTIF,"Entering [%s]\n", __FUNCTION__);
278  hostif_InterfaceStack* pRet = NULL;
279 
280  if(stIshash)
281  {
282  pRet = (hostif_InterfaceStack *)g_hash_table_lookup(stIshash, (gpointer) dev_id);
283  }
284 
285  if(!pRet)
286  {
287  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"No instance is found with dev_id %d\n", dev_id);
288  }
289 
290  return pRet;
291 }
292 
293 int hostif_InterfaceStack::createInstance(int dev_id, char *higherLayer, char *lowerLayer)
294 {
295  int ret = NOK;
296  hostif_InterfaceStack *instance = NULL;
297 
298  if(higherLayer && lowerLayer)
299  {
300  if(!stIshash)
301  {
302  stIshash = g_hash_table_new(NULL, NULL);
303  }
304 
305  instance = new hostif_InterfaceStack(dev_id, higherLayer, lowerLayer );
306 
307  if(instance)
308  {
309  g_hash_table_insert(stIshash, (gpointer)dev_id, instance);
310  ret = OK;
311  }
312  else
313  {
314  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"Unable to create InterfaceStack instance\n");
315  }
316  }
317  else
318  {
319  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"%s:%d NULL parameters passed\n", __FUNCTION__, __LINE__);
320  }
321 
322  return ret;
323 }
324 
325 
326 GList* hostif_InterfaceStack::getAllInstances()
327 {
328  if(stIshash)
329  return g_hash_table_get_keys(stIshash);
330  return NULL;
331 }
332 
333 
334 void hostif_InterfaceStack::closeInstance(hostif_InterfaceStack *pDev)
335 {
336  if(pDev)
337  {
338  g_hash_table_remove(stIshash, (gconstpointer)pDev->dev_id);
339  delete pDev;
340  }
341 }
342 
343 
344 void hostif_InterfaceStack::closeAllInstances()
345 {
346  if(stIshash)
347  {
348  GList* tmp_list = g_hash_table_get_values (stIshash);
349 
350  while(tmp_list)
351  {
352  hostif_InterfaceStack* pDev = (hostif_InterfaceStack *)tmp_list->data;
353  tmp_list = tmp_list->next;
354  closeInstance(pDev);
355  }
356  }
357 }
358 
359 /*
360  * hostif_InterfaceStack::populateBridgeTable()
361  *
362  * It identifies the list of bridges and its interfaces by following steps
363  * - Iterate through the sub-directories of /sys/class/net and check if bridge directory exists
364  * - If bridge directory exists, it checks if the sub-directories of /sys/class/net has brif directory
365  * - If brif directory exists, it gets the the list of interfaces present in brif directory in comma separated format
366  * - And then it inserts a new row in stBridgeTableHash with key as bridge name and value as comma separated interfaces *
367  */
368 int hostif_InterfaceStack::populateBridgeTable()
369 {
370  int ret = NOK;
371  struct dirent **nameList;
372  int noOfDirEntries = -1;
373  char cmd[MAX_CMD_LEN] = {'\0'};
374  char result_buff[MAX_BUF_LEN] = {'\0'};
375  FILE *fp = NULL;
376 
377  if(0 > (noOfDirEntries = scandir(SYS_CLASS_NET_PATH, &nameList, NULL, alphasort)))
378  {
379  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"%s:%s:%d error opening %s\n", __FILE__, __FUNCTION__, __LINE__, SYS_CLASS_NET_PATH);
380  return NOK;
381  }
382 
383  // Account for extra 2 '/..' and '/.' directives
384  for(int i = 2; i < noOfDirEntries; i++)
385  {
386  // Check if bride directory exists in sys/class/net/d_name
387  snprintf(cmd, sizeof(cmd), "%s%s/bridge", SYS_CLASS_NET_PATH, nameList[i]->d_name);
388  if(-1 != access(cmd, F_OK))
389  {
390  // Check if brif directory exists in sys/class/net/d_name
391  snprintf(cmd, sizeof(cmd), "%s%s/brif", SYS_CLASS_NET_PATH, nameList[i]->d_name);
392  if(-1 != access(cmd, F_OK))
393  {
394  // Get the list of interfaces present inside brif director in comma separated format
395  snprintf(cmd, sizeof(cmd), "ls %s%s/brif|awk 'BEGIN{ORS=\",\";}{print $1}'", SYS_CLASS_NET_PATH, nameList[i]->d_name);
396 #ifdef YOCTO_BUILD
397  fp = v_secure_popen("r", "ls %s%s/brif|awk 'BEGIN{ORS=\",\";}{print $1}'", SYS_CLASS_NET_PATH, nameList[i]->d_name);
398 #else
399  fp = popen(cmd, "r");
400 #endif
401  if(fp)
402  {
403  memset(result_buff, '\0', sizeof(result_buff));
404  fgets(result_buff, sizeof(result_buff), fp);
405  // Insert a row in bridge table with bridge as key and comma separated interface as value
406  ret = insertRowIntoBridgeTable(nameList[i]->d_name, result_buff);
407 #ifdef YOCTO_BUILD
408  v_secure_pclose(fp);
409 #else
410  pclose(fp);
411 #endif
412  fp = NULL;
413  }
414  }
415  }
416 
417  }
418 
419  while(noOfDirEntries--)
420  {
421  free (nameList[noOfDirEntries]);
422  }
423  free (nameList);
424 
425  return ret;
426 }
427 
428 /*
429  * Destructor to free key data in stBridgeTableHash when a row is removed from the hash
430  */
431 void hostif_InterfaceStack::bridgeInteface_key_data_free(gpointer key)
432 {
433  char *myKey = (char*)key;
434 
435  if(myKey)
436  {
437  g_free(myKey);
438  }
439 }
440 
441 /*
442  * Destructor to free value date in stBridgeTableHash when a row is removed from the hash
443  */
444 void hostif_InterfaceStack::bridgeInteface_value_data_free(gpointer value)
445 {
446  char *val = (char*)value;
447 
448  if(val)
449  {
450  g_free(val);
451  }
452 }
453 
454 /*
455  * Deletes the bridge table hash (stBridgeTableHash)
456  */
457 void hostif_InterfaceStack::deleteBridgeTable()
458 {
459  GList *keyList = NULL;
460  GList *elem = NULL;
461 
462  if(stBridgeTableHash)
463  {
464  keyList = g_hash_table_get_keys(stBridgeTableHash);
465  for(elem = keyList; elem; elem = elem->next)
466  {
467  g_hash_table_remove(stBridgeTableHash, elem->data);
468  }
469  g_hash_table_destroy(stBridgeTableHash);
470  stBridgeTableHash = NULL;
471  }
472  if(keyList)
473  g_list_free(keyList);
474 }
475 
476 /*
477  * Inserts a new into stBridgeTableHash with bridge name as key and bridge interfaces as value
478  */
479 int hostif_InterfaceStack::insertRowIntoBridgeTable(IN char *bridge, IN char *bridgeInterfaces)
480 {
481  int ret = NOK;
482 
483  if(!stBridgeTableHash)
484  {
485  stBridgeTableHash = g_hash_table_new_full(NULL, NULL, (GDestroyNotify)bridgeInteface_key_data_free,
486  (GDestroyNotify)bridgeInteface_value_data_free);
487  }
488 
489  if(bridge && bridgeInterfaces)
490  {
491  RDK_LOG(RDK_LOG_DEBUG,LOG_TR69HOSTIF,"%s:%d Adding bridge %s bridgeInterfaces %s to hash table\n", __FUNCTION__, __LINE__, bridge, bridgeInterfaces);
492  g_hash_table_insert(stBridgeTableHash, g_strdup(bridge), g_strdup(bridgeInterfaces));
493  ret = OK;
494  }
495 
496  return ret;
497 }
498 
499 /*
500  * This function returns the number of lower level interfaces available.
501  *
502  */
503 template<typename T>
504 int hostif_InterfaceStack::getLowerInterfaceNumberOfEntries()
505 {
506  int numEntries = 0;
507  HOSTIF_MsgData_t msgData;
508  memset(&msgData, 0, sizeof(msgData));
509 
510 
511  if(0 == strcmp(typeid(T).name(), typeid(hostIf_EthernetInterface).name()))
512  {
514  {
515  numEntries = get_int(msgData.paramValue);
516  }
517  else
518  {
519  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"%s:%d get_Device_Ethernet_InterfaceNumberOfEntries failed\n", __FILE__, __LINE__);
520  }
521  }
522 #ifdef USE_MoCA_PROFILE
523  else if(0 == strcmp(typeid(T).name(), typeid(MoCAInterface).name()))
524  {
526  {
527  numEntries = get_int(msgData.paramValue);
528  }
529  else
530  {
531  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"%s:%d get_Device_MoCA_InterfaceNumberOfEntries failed\n", __FILE__, __LINE__);
532  }
533  }
534 #endif
535 
536  return(numEntries);
537 }
538 
539 /*
540  * This function returns the interface name (such as 'eth0', 'bcm0') for lower level interfaces.
541  */
542 template<typename T>
543 std::string hostif_InterfaceStack::getInterfaceName(T* pIface)
544 {
545  std::string ifname;
546  HOSTIF_MsgData_t msgData;
547  memset(&msgData, 0, sizeof(msgData));
548 
549  if(0 == strcmp(typeid(T).name(), typeid(hostIf_EthernetInterface).name()))
550  {
551  if(OK == ((hostIf_EthernetInterface*)pIface)->get_Device_Ethernet_Interface_Name(&msgData))
552  {
553  ifname.append(msgData.paramValue);
554  }
555  else
556  {
557  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"%s:%d get_Device_Ethernet_Interface_Name failed\n", __FILE__, __LINE__);
558  }
559  }
560 #ifdef USE_MoCA_PROFILE
561  else if(0 == strcmp(typeid(T).name(), typeid(MoCAInterface).name()))
562  {
563  if(OK == ((MoCAInterface*)pIface)->get_Name(&msgData))
564  {
565  ifname.append(msgData.paramValue);
566  }
567  else
568  {
569  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"%s:%d get_Device_MoCA_Interface_Name failed\n", __FILE__, __LINE__);
570  }
571  }
572 #endif
573 
574  return(ifname);
575 }
576 
577 /*
578  * get Data Model path for the lower level interfaces.
579  */
580 template<typename T>
581 std::string hostif_InterfaceStack::getLowerLayerName(int index)
582 {
583  std::string baseName;
584  if(0 == strcmp(typeid(T).name(), typeid(hostIf_EthernetInterface).name()))
585  {
586  baseName.append(DEVICE_ETHERNET_INTERFACE(index));
587  }
588 #ifdef USE_MoCA_PROFILE
589  else if(0 == strcmp(typeid(T).name(), typeid(MoCAInterface).name()))
590  {
591  baseName.append(DEVICE_MOCA_INTERFACE(index));
592  }
593 #endif
594 
595  return(baseName);
596 }
597 
598 /*
599  * This function builds the lower layer entries in the supplied 'layerInfo' map for the lower level physical interfaces
600  *
601  * In the example given, the buildLowerLayerInfo function builds the Interface stack table as below:
602  * Note that the higherlayers have not been filled up yet.
603  * InterfaceStackMap
604  * ---------------
605  * InterfaceName HigherLayer LowerLayer
606  * bcm0 Device.Ethernet.Interface.1
607  * eth1 Device.MoCA.Interface.1
608  * eth2 Device.Ethernet.Interface.2
609  *
610  */
611 template<typename T>
612 int hostif_InterfaceStack::buildLowerLayerInfo (InterfaceStackMap_t &layerInfo)
613 {
614  int numOfEntries = getLowerInterfaceNumberOfEntries<T> ();
615  for (int index = 1; index <= numOfEntries; index++)
616  {
617  T *pIface = T::getInstance (index);
618  if (pIface == NULL)
619  {
620  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "%s:%d getInstance failed\n", __FILE__, __LINE__);
621  return NOK;
622  }
623 
624  std::string ifname = getInterfaceName<T> (pIface);
625  if (!ifname.empty ())
626  {
627  std::pair<std::string, LayerInfo_t> map_element;
628  map_element.first = ifname;
629  map_element.second.higherLayer = std::string ("");
630  map_element.second.lowerLayer = getLowerLayerName<T> (index);
631 
632  layerInfo.insert (map_element);
633  }
634  }
635 
636  return OK;
637 }
638 
639 /*
640  * This function get the list of bridge elements from the
641  * CSV format for bridge elements.
642  */
643 std::list<std::string> hostif_InterfaceStack::getBridgeElements(char* elementsCSV)
644 {
645  char *token = NULL;
646  char *savePtr = NULL;
647  std::list<std::string> bridgeElements;
648 
649  if(elementsCSV)
650  {
651  token = strtok_r(elementsCSV, ",", &savePtr);
652  while(token != NULL)
653  {
654  bridgeElements.push_back(std::string(token));
655  token = strtok_r(NULL, ",", &savePtr);
656  }
657  }
658 
659  return bridgeElements;
660 }
661 
662 /*
663  * This function adds the lower layer info for bridges.
664  * Lower layer info contains the higher layer of unmanaged interface of the link
665  *
666  * In the example given, the buildLowerLayerInfo function builds the Interface stack table as below:
667  * Note that the higherlayers have not been filled up yet.
668  * InterfaceStackMap
669  * ---------------
670  * InterfaceName HigherLayer LowerLayer
671  * bcm0 Device.Ethernet.Interface.1
672  * eth1 Device.MoCA.Interface.1
673  * eth2 Device.Ethernet.Interface.2
674  * hnbr0 Device.Bridging.Bridge.1.Port.1
675  *
676  */
677 void hostif_InterfaceStack::addBridgeNameLayerInfo(InterfaceStackMap_t &layerInfo, std::string ifname, std::string bridgeLowerLayer)
678 {
679  InterfaceStackMap_t::iterator it = layerInfo.find(ifname);
680 
681  if(it != layerInfo.end())
682  {
683  it->second.lowerLayer = bridgeLowerLayer;
684  }
685  else
686  {
687  LayerInfo_t tempLayerInfo;
688  std::pair<std::string, LayerInfo_t> map_element;
689 
690  tempLayerInfo.higherLayer = std::string("");
691  tempLayerInfo.lowerLayer = bridgeLowerLayer;
692 
693  map_element.first = ifname;
694  map_element.second = tempLayerInfo;
695 
696  layerInfo.insert(map_element);
697  }
698 }
699 
700 /*
701  * This function adds the higher layer info for bridge interfaces.
702  * Higher layer info contains the lower layer of unmanaged interface of the link
703  *
704  *
705  * In the example given, the buildLowerLayerInfo function builds the Interface stack table as below:
706  * The example illustrates for the one child entry only. Remaining child entries will be filled up same.
707  *
708  * InterfaceStackMap
709  * ---------------
710  * InterfaceName HigherLayer LowerLayer
711  * bcm0 Device.Bridging.Bridge.1.Port.1 Device.Ethernet.Interface.1
712  * eth1 Device.MoCA.Interface.1
713  * eth2 Device.Ethernet.Interface.2
714  * hnbr0 Device.Bridging.Bridge.1.Port.1
715  * hnbr0-chld Device.Bridging.Bridge.1.Port.1 Device.Bridging.Bridge.1.Port.2
716  *
717  */
718 int hostif_InterfaceStack::addBridgeChildLayerInfo(InterfaceStackMap_t &layerInfo, std::string ifname, std::string bridgeHigherLayer)
719 {
720  int rc = OK;
721  InterfaceStackMap_t::iterator it = layerInfo.find(ifname);
722 
723  if(it != layerInfo.end())
724  {
725  it->second.higherLayer = bridgeHigherLayer;
726  }
727  else
728  {
729  gpointer origKey;
730  gpointer value;
731 
732  if( TRUE == g_hash_table_lookup_extended (stBridgeTableHash, ifname.c_str(), &origKey, &value) )
733  {
734  LayerInfo_t tempLayerInfo;
735 
736  tempLayerInfo.higherLayer = bridgeHigherLayer;
737  tempLayerInfo.lowerLayer = std::string("");
738 
739  layerInfo.insert( std::pair<std::string, LayerInfo_t>(ifname, tempLayerInfo));
740  }
741  else
742  {
743  rc = NOK;
744  }
745  }
746  return(rc);
747 }
748 
749 /*
750  * This function creates unmanaged layer info for the links between bridge and underlying bridge interfaces.
751  *
752  *
753  * In the example given, the buildLowerLayerInfo function builds the Interface stack table as below:
754  * The example illustrates for the one child entry only. Remaining child entries will be filled up same.
755  *
756  * InterfaceStackMap
757  * ---------------
758  * InterfaceName HigherLayer LowerLayer
759  * bcm0 Device.Ethernet.Interface.1
760  * eth1 Device.MoCA.Interface.1
761  * eth2 Device.Ethernet.Interface.2
762  * hnbr0 Device.Bridging.Bridge.1.Port.1
763  * hnbr0-chld Device.Bridging.Bridge.1.Port.1 Device.Bridging.Bridge.1.Port.2
764  *
765  */
766 void hostif_InterfaceStack::addBridgeUnmanagedLayerInfo(InterfaceStackMap_t &layerInfo, std::string ifname, std::string bridgeHigherLayer, std::string bridgeLowerLayer)
767 {
768  LayerInfo_t tempLayerInfo;
769  std::pair<std::string, LayerInfo_t> map_element;
770 
771  tempLayerInfo.higherLayer = bridgeHigherLayer;
772  tempLayerInfo.lowerLayer = bridgeLowerLayer;
773 
774  map_element.first = ifname;
775  map_element.second = tempLayerInfo;
776 
777  layerInfo.insert(map_element);
778 }
779 
780 /*
781  * This function parses all the bridge list and underlying bridge interfaces
782  * creates all the needed layer info (higher layer and lower layer) in layerInfo map.
783 */
784 int hostif_InterfaceStack::buildBridgeTableLayerInfo(InterfaceStackMap_t &layerInfo)
785 {
786  int rc = OK;
787  GList *bridgeList = NULL;
788  GList *elem = NULL;
789  int bridgeNum = 1;
790 
791  if(stBridgeTableHash)
792  {
793  GHashTableIter iter;
794  gpointer key, value;
795 
796  g_hash_table_iter_init(&iter, stBridgeTableHash);
797  while (g_hash_table_iter_next (&iter, &key, &value))
798  {
799  /*
800  * The Bridges and underlying interfaces have the ports.
801  * The port number '1' is dedicated to the port number of the bridge.
802  * The port numbers for the underlying bridges start from '2'.
803  *
804  */
805  int portNum = 1;
806  std::string bridgeName;
807  std::list<std::string> bridgeElements;
808  std::string bridgeNameLayer; // LowerLayer string to be inserted in InterfaceStackMap
809  std::list<std::string>::iterator it;
810 
811  if(key == NULL)
812  continue;
813 
814  bridgeName.append((const char*)key);
815  bridgeNameLayer.append( DEVICE_BRIDGING_BRIDGE(bridgeNum, portNum) );
816  addBridgeNameLayerInfo(layerInfo, bridgeName, bridgeNameLayer);
817 
818  if(value == NULL)
819  continue;
820 
821  bridgeElements = getBridgeElements( (char*) value);
822  portNum++;
823  for(it = bridgeElements.begin(); it != bridgeElements.end(); ++it, portNum++)
824  {
825  std::string unmanagedBridgeName;
826  std::string ifname = *it;
827 
828  // HigherLayer String to be inserted in InterfaceStackMap
829  std::string bridgeElementLayer = DEVICE_BRIDGING_BRIDGE(bridgeNum, portNum);
830 
831  if(OK == addBridgeChildLayerInfo(layerInfo, ifname, bridgeElementLayer))
832  {
833  //If Child Entry is added successfully, then create unmanaged bridges.
834  unmanagedBridgeName.append(bridgeName+"-child");
835  addBridgeUnmanagedLayerInfo(layerInfo, unmanagedBridgeName, bridgeNameLayer, bridgeElementLayer);
836  }
837  }
838  }
839  }
840 
841  if(bridgeList)
842  g_list_free(bridgeList);
843 
844  return(rc);
845 }
846 
847 /* getIPInterfaces
848 * This function builds up a map for all the available IP interfaces.
849 */
850 int hostif_InterfaceStack::getIPInterfaces(IPInterfacesMap_t& interfaceList)
851 {
852  int rc = OK;
853  int ipNumOfEntries = 0;
854  int ipIndex = 1;
855  HOSTIF_MsgData_t msgData;
856 
858  {
859  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"%s:%d get_Device_IP_InterfaceNumberOfEntries failed\n", __FILE__, __LINE__);
860  rc = NOK;
861  }
862  else
863  {
864  ipNumOfEntries=get_int(msgData.paramValue);
865  RDK_LOG(RDK_LOG_DEBUG,LOG_TR69HOSTIF,"%s:%d ipNumOfEntries = %d\n", __FUNCTION__, __LINE__, ipNumOfEntries);
866 
867  for(ipIndex=1; ipIndex <= ipNumOfEntries; ipIndex++)
868  {
869  std::string ipIfName;
870  hostIf_IPInterface *pIface = hostIf_IPInterface::getInstance(ipIndex);
871 
872  if(!pIface)
873  {
874  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"%s:%d hostIf_IPInterface::getInstance failed\n", __FILE__, __LINE__);
875  rc=NOK;
876  break;
877  }
878 
879  memset(&msgData, '\0', sizeof(msgData));
880 
881  if (OK == pIface->get_Interface_Name(&msgData))
882  {
883  ipIfName.append(msgData.paramValue);
884  interfaceList.insert( std::pair<std::string, int>(ipIfName, ipIndex));
885  }
886  }
887  }
888  return(rc);
889 }
890 
891 /*
892  * fillHigherLayersWithIP
893  * This function fills up the empty 'higherLayer' entries in 'layerInfo' map
894  * interface names are the key to get the 'Device.IP.Interface.<interface number>'
895  */
896 
897 void hostif_InterfaceStack::fillHigherLayersWithIP(InterfaceStackMap_t &layerInfo, IPInterfacesMap_t& ipInterfaceMap)
898 {
899  InterfaceStackMap_t::iterator layerIterator;
900 
901  for(layerIterator = layerInfo.begin(); layerIterator != layerInfo.end(); layerIterator++)
902  {
903  if(layerIterator->second.higherLayer.empty())
904  {
905  IPInterfacesMap_t::iterator interfaceIterator;
906  std::string ifname = layerIterator->first;
907  interfaceIterator = ipInterfaceMap.find(ifname);
908 
909  if(interfaceIterator != ipInterfaceMap.end())
910  {
911  int portNum = interfaceIterator->second;
912  std::string higherLayer = DEVICE_IP_INTERFACE(portNum);
913  layerIterator->second.higherLayer = higherLayer;
914  }
915  }
916  }
917 }
918 
919 void hostif_InterfaceStack::print_map(InterfaceStackMap_t &layerInfo)
920 {
921  InterfaceStackMap_t::iterator layerIterator;
922 
923  for(layerIterator = layerInfo.begin(); layerIterator != layerInfo.end(); layerIterator++)
924  {
925  RDK_LOG(RDK_LOG_INFO,LOG_TR69HOSTIF,"%s - %s --- %s\n", layerIterator->first.c_str(), layerIterator->second.higherLayer.c_str(), layerIterator->second.lowerLayer.c_str());
926  }
927 }
928 
929 /*
930  * Gets the HigherLayer of Interface Stack table for a given instance
931  */
932 
933 /**
934  * @brief This function gets the higher layer of the device interface stack.
935  *
936  * @param[out] stMsgData TR-069 Host interface message request.
937  * @param[in] pChanged Status of the operation.
938  *
939  * @returns Returns '0' if the method successfully get the higher layer of interface stack
940  * else returns '-1'.
941  * @ingroup TR69_HOSTIF_INTERFACESTACK_INTERFACE_API
942  */
943 int hostif_InterfaceStack::get_Device_InterfaceStack_HigherLayer(HOSTIF_MsgData_t *stMsgData, bool *pChanged)
944 {
945  int ret = OK;
946 
947  if(bCalledHigherLayer && pChanged && strncmp(backupHigherLayer, higherLayer, sizeof(backupHigherLayer)))
948  {
949  *pChanged = true;
950  }
951  bCalledHigherLayer = true;
952  strncpy(backupHigherLayer, higherLayer, sizeof(backupHigherLayer) -1); //CID:136448 - Buffer size warnin
953  backupHigherLayer[sizeof(backupHigherLayer) -1] = '\0';
954  strncpy(stMsgData->paramValue, higherLayer, TR69HOSTIFMGR_MAX_PARAM_LEN );
955  stMsgData->paramtype = hostIf_StringType;
956  stMsgData->paramLen = strlen(stMsgData->paramValue);
957 
958  return ret;
959 }
960 
961 /*
962  * Gets the LowerLayer of Interface Stack table for a given instance
963  */
964 /**
965  * @brief This function gets the lower layer of the device interface stack.
966  *
967  * @param[out] stMsgData TR-069 Host interface message request.
968  * @param[in] pChanged Status of the operation.
969  *
970  * @returns Returns '0' if the method successfully get the lower layer of interface stack else returns '-1'.
971  * @ingroup TR69_HOSTIF_INTERFACESTACK_INTERFACE_API
972  */
973 int hostif_InterfaceStack::get_Device_InterfaceStack_LowerLayer(HOSTIF_MsgData_t *stMsgData, bool *pChanged)
974 {
975  int ret = OK;
976 
977  if(bCalledLowerLayer && pChanged && strncmp(backupLowerLayer, lowerLayer, sizeof(backupLowerLayer)))
978  {
979  *pChanged = true;
980  }
981  bCalledLowerLayer = true;
982  strncpy(backupLowerLayer, lowerLayer, sizeof(backupLowerLayer) -1); //CID:136386 - Buffer size warning
983  backupLowerLayer[sizeof(backupLowerLayer) -1] = '\0';
984  strncpy(stMsgData->paramValue, lowerLayer, TR69HOSTIFMGR_MAX_PARAM_LEN );
985  stMsgData->paramtype = hostIf_StringType;
986  stMsgData->paramLen = strlen(stMsgData->paramValue);
987 
988  return ret;
989 }
990 
991 /* End of doxygen group */
992 /**
993  * @}
994  */
MoCAInterface
Definition: Device_MoCA_Interface.h:114
Device_InterfaceStack.h
The header file provides TR069 device interface stack information APIs.
hostIf_EthernetInterface::get_Device_Ethernet_InterfaceNumberOfEntries
static int get_Device_Ethernet_InterfaceNumberOfEntries(HOSTIF_MsgData_t *, bool *pChanged=NULL)
Get the number of entries in the Interface table.
Definition: Device_Ethernet_Interface.cpp:486
hostIf_IPInterface::get_Interface_Name
int get_Interface_Name(HOSTIF_MsgData_t *stMsgData, bool *pChanged=NULL)
This function gets the IP Interface Name.It provides the textual name of the interface as assigned by...
Definition: Device_IP_Interface.cpp:638
_HostIf_MsgData_t
Definition: hostIf_tr69ReqHandler.h:170
Device_IP_Interface.h
The header file provides TR069 device IP interface information APIs.
MoCAInterface::get_InterfaceNumberOfEntries
static int get_InterfaceNumberOfEntries(HOSTIF_MsgData_t *, bool *pChanged=NULL)
Get the number of entries in the MoCA Interface table.
Definition: Device_MoCA_Interface.cpp:278
hostIf_IP::get_Device_IP_InterfaceNumberOfEntries
static int get_Device_IP_InterfaceNumberOfEntries(HOSTIF_MsgData_t *)
Get the number of entries in the Interface table.
Definition: Device_IP.cpp:641
_HostIf_MsgData_t::paramtype
HostIf_ParamType_t paramtype
Definition: hostIf_tr69ReqHandler.h:177
RDK_LOG
#define RDK_LOG
Definition: rdk_debug.h:258
hostIf_EthernetInterface
This class provides the interface for getting Device ethernet interface information.
Definition: Device_Ethernet_Interface.h:195
Device_MoCA_Interface.h
_HostIf_MsgData_t::paramValue
char paramValue[(4 *1024)]
Definition: hostIf_tr69ReqHandler.h:172
Device_IP.h
The header file provides TR069 device IP information APIs.
hostIf_IPInterface
This class provides the hostIf IP interface for getting IP interface information.
Definition: Device_IP_Interface.h:224
put_int
void put_int(char *ptr, int val)
This function converts the input data to integer type.
Definition: hostIf_utils.cpp:152
Device_Ethernet_Interface.h
The header file provides TR069 device ethernet interface information APIs.
TRUE
#define TRUE
Defines for TRUE/FALSE/ENABLE flags.
Definition: wifi_common_hal.h:199
_HostIf_MsgData_t::paramLen
short paramLen
Definition: hostIf_tr69ReqHandler.h:175