int subCmd_top(int argc, char **argv, qi::ApplicationSession& app) { po::options_description desc("Usage: qicli top [-i interval] [<ServicePattern>..]"); std::vector<std::string> serviceList; desc.add_options() ("numeric,n", po::bool_switch(&numeric), "Do not resolve slot Ids to names") ("full,f", po::bool_switch(&full), "Do not abreviate anything") ("service-directory,s", po::value<std::string>(&sdUrl), "url to connect to") ("service,s", po::value<std::vector<std::string> >(&objectNames), "Object(s) to monitor, specify multiple times, comma-separate, use '*' for all, use '-globPattern' to remove from list") ("interval,i", po::value<float>(&interval)->default_value(1), "Poll interval in seconds"); po::positional_options_description positionalOptions; positionalOptions.add("service", -1); po::variables_map vm; if (!poDefault(po::command_line_parser(argc, argv).options(desc).positional(positionalOptions), vm, desc)) return 1; qiLogVerbose() << "Connecting to service directory"; app.startSession(); qi::SessionPtr s = app.session(); qiLogVerbose() << "Resolving services"; // resolve target service names std::vector<std::string> allServices; std::vector<qi::ServiceInfo> si = s->services(); for (unsigned i=0; i<si.size(); ++i) allServices.push_back(si[i].name()); std::vector<std::string> services = parseServiceList(objectNames, allServices); std::vector<std::string> servicesOk; qiLogVerbose() << "Fetching services: " << boost::join(services, ","); // access services for (unsigned i=0; i<services.size(); ++i) { qi::AnyObject o; try { o = s->service(services[i]); } catch (const std::exception& e) { qiLogError() << "Error fetching " << services[i] << " : " << e.what(); services[i] = ""; continue; } if (!o) { qiLogError() << "Error fetching " << services[i]; services[i] = ""; continue; } objectMap[services[i]] = o; servicesOk.push_back(services[i]); } if (objectMap.empty()) return 0; qiLogVerbose() << "Monitoring services: " << boost::join(servicesOk, ","); for(ObjectMap::value_type& ov: objectMap) { maxServiceLength = std::max(maxServiceLength, (unsigned int)ov.first.size()); ov.second.async<void>("enableStats", true); } boost::thread t(&main_loop); qi::Application::atStop(boost::bind(&boost::thread::interrupt, boost::ref(t))); qi::Application::run(); t.join(); qiLogInfo() << "Disabling statistics gathering..." << std::endl; std::vector<qi::Future<void> > futures; for(ObjectMap::value_type& ov: objectMap) { futures.push_back(ov.second.async<void>("enableStats", false)); } qi::waitForAll(futures); return 0; }
void SSDPParser::parse(const char * buffer, int size) { xmlDocPtr doc; xmlNodePtr root; xmlChar* xpathDevice = (xmlChar*) "//ns:device"; xmlChar* xpathUDN = (xmlChar*) "///ns:UDN"; xmlXPathObjectPtr deviceList; xmlXPathObjectPtr serviceList; xmlXPathObjectPtr udnNodeList; xmlChar* udn = 0; xmlBufferPtr configBuf = 0; const xmlChar* ns = 0; xmlKeepBlanksDefault(0); doc = xmlParseMemory(buffer, size); if (!doc) return; root = xmlDocGetRootElement(doc); if (root) ns = root->ns->href; deviceList = getNodeSet(doc, ns, xpathDevice); if (deviceList) { int i; xmlNodeSetPtr nodeSet = deviceList->nodesetval; udnNodeList = getNodeSet(doc, ns, xpathUDN); if (!udnNodeList) return; /* Loop on <device> contains in the <deviceList> element */ for (i = 0; i < nodeSet->nodeNr; i++) { char xpathService[32]; xmlNodePtr udnNode = udnNodeList->nodesetval->nodeTab[i]; xmlNodePtr deviceNode = xmlCopyNode(nodeSet->nodeTab[i], 1); udn = xmlNodeListGetString(doc, udnNode->xmlChildrenNode, 1); sprintf(xpathService, "//ns:device[%d]//ns:service", i+1); configBuf = xmlBufferCreate(); if (!configBuf) break; xmlNodeDump(configBuf, doc, deviceNode, 1, 1); serviceList = getNodeSet(doc, ns, (xmlChar*)xpathService); if (serviceList) { /* Loop on <service> contains in the <serviceList> element */ parseServiceList(doc, ns, udn, serviceList->nodesetval, configBuf); xmlXPathFreeObject(serviceList); } if (udn) xmlFree(udn); xmlBufferFree(configBuf); xmlFreeNode(deviceNode); } xmlXPathFreeObject(udnNodeList); xmlXPathFreeObject(deviceList); } xmlFreeDoc(doc); xmlCleanupParser(); }
int subCmd_trace(int argc, char **argv, qi::ApplicationSession& app) { po::options_description desc("Usage: qicli trace [<ServicePattern>..]"); std::vector<std::string> serviceList; desc.add_options() ("numeric,n", po::bool_switch(&numeric), "Do not resolve slot Ids to names") ("full,f", po::bool_switch(&full), "Do not abreviate anything") ("service,s", po::value<std::vector<std::string> >(&objectNames), "Object(s) to monitor, specify multiple times, comma-separate, use '*' for all, use '-globPattern' to remove from list") ("print,p", po::bool_switch(&printMo), "Print out the Metaobject and exit") ("disable,d", po::bool_switch(&disableTrace), "Disable trace on objects and exit") ("trace-status", po::bool_switch(&traceState), "Show trace status on objects and exit"); po::positional_options_description positionalOptions; positionalOptions.add("service", -1); po::variables_map vm; if (!poDefault(po::command_line_parser(argc, argv).options(desc).positional(positionalOptions), vm, desc)) return 1; qiLogVerbose() << "Connecting to service directory"; app.start(); qi::SessionPtr s = app.session(); qiLogVerbose() << "Resolving services"; std::vector<std::string> allServices; std::vector<qi::ServiceInfo> si = s->services(); for (unsigned i=0; i<si.size(); ++i) allServices.push_back(si[i].name()); std::vector<std::string> services = parseServiceList(objectNames, allServices); std::vector<std::string> servicesOk; qiLogVerbose() << "Fetching services: " << boost::join(services, ","); // access services for (unsigned i=0; i<services.size(); ++i) { qi::AnyObject o; try { o = s->service(services[i]); } catch (const std::exception& e) { qiLogError() << "Error fetching " << services[i] << " : " << e.what(); services[i] = ""; continue; } if (!o) { qiLogError() << "Error fetching " << services[i]; services[i] = ""; continue; } objectMap[services[i]] = o; servicesOk.push_back(services[i]); if (printMo) { std::cout << "\n\n" << services[i] << "\n"; qi::details::printMetaObject(std::cout, o.metaObject()); } if (disableTrace) { try { o.call<void>("enableTrace", false); } catch(...) {} } if (traceState) { try { bool s = o.call<bool>("isTraceEnabled"); std::cout << services[i] << ": " << s << std::endl; } catch(...) {} } } if (printMo || disableTrace || traceState || objectMap.empty()) return 0; qiLogVerbose() << "Monitoring services: " << boost::join(servicesOk, ","); foreach(ObjectMap::value_type& ov, objectMap) { maxServiceLength = std::max(maxServiceLength, (unsigned int)ov.first.size()); ov.second.connect("traceObject", (boost::function<void(qi::EventTrace)>) boost::bind(&onTrace, ov, _1)).async(); }