void testStartStop() { report(0,"checking start/stop works..."); Contact address("/port", "tcp", "127.0.0.1", safePort()); PortCore core; core.listen(address); core.start(); report(0,"there will be a small delay, stress-testing port..."); int tct = 10; int ct = 0; for (int i=0; i<tct; i++) { Time::delay(0.01*(i%4)); OutputProtocol *op = Carriers::connect(address); if (op!=nullptr) { op->getOutputStream().write('h'); op->close(); delete op; ct++; // connect is an event } else { report(1,"a connection failed"); } } while (core.getOutputCount()>0 || core.getEventCount()<ct) { // close could abort connections Time::delay(0.2); } core.close(); ct++; // close is an event report(0,"finished stress-testing port..."); core.join(); checkEqual(core.getEventCount(),ct,"Got all events"); }
bool NameSpace::checkNetwork() { Contact c = queryName(getNameServerName()); if (!c.isValid()) return false; OutputProtocol *out = Carriers::connect(Address::fromContact(c)); if (out==NULL) { return false; } out->close(); delete out; out = NULL; return true; }
bool NameSpace::checkNetwork(double timeout) { Contact c = queryName(getNameServerName()); if (!c.isValid()) return false; c.setTimeout((float)timeout); OutputProtocol *out = Carriers::connect(c); if (out==NULL) { return false; } out->close(); delete out; out = NULL; return true; }
bool NameSpace::checkNetwork() { if (localOnly()) return true; Contact c = queryName(getNameServerName()); if (!c.isValid()) return false; OutputProtocol *out = Carriers::connect(c); if (out==YARP_NULLPTR) { return false; } out->close(); delete out; out = YARP_NULLPTR; return true; }
bool NetworkBase::write(const Contact& contact, PortWriter& cmd, PortReader& reply, const ContactStyle& style) { if (!getNameSpace().serverAllocatesPortNumbers()) { // switch to more up-to-date method Port port; port.setAdminMode(style.admin); port.openFake("network_write"); Contact ec = contact; if (style.carrier!="") { ec.setCarrier(style.carrier); } if (!port.addOutput(ec)) { if (!style.quiet) { ACE_OS::fprintf(stderr, "Cannot make connection to '%s'\n", ec.toString().c_str()); } return false; } bool ok = port.write(cmd,reply); return ok; } const char *connectionName = "admin"; ConstString name = contact.getName(); const char *targetName = name.c_str(); // use carefully! Contact address = contact; if (!address.isValid()) { address = getNameSpace().queryName(targetName); } if (!address.isValid()) { if (!style.quiet) { YARP_SPRINTF1(Logger::get(),error, "cannot find port %s", targetName); } return false; } if (style.timeout>0) { address.setTimeout((float)style.timeout); } OutputProtocol *out = Carriers::connect(address); if (out==YARP_NULLPTR) { if (!style.quiet) { YARP_SPRINTF1(Logger::get(),error, "Cannot connect to port %s", targetName); } return false; } if (style.timeout>0) { out->setTimeout(style.timeout); } Route r(connectionName,targetName, (style.carrier!="")?style.carrier.c_str():"text_ack"); out->open(r); PortCommand pc(0,style.admin?"a":"d"); BufferedConnectionWriter bw(out->getConnection().isTextMode(), out->getConnection().isBareMode()); bool ok = true; if (out->getConnection().canEscape()) { ok = pc.write(bw); } if (!ok) { if (!style.quiet) { YARP_ERROR(Logger::get(),"could not write to connection"); } if (out!=YARP_NULLPTR) delete out; return false; } ok = cmd.write(bw); if (!ok) { if (!style.quiet) { YARP_ERROR(Logger::get(),"could not write to connection"); } if (out!=YARP_NULLPTR) delete out; return false; } if (style.expectReply) { bw.setReplyHandler(reply); } out->write(bw); if (out!=YARP_NULLPTR) { delete out; out = YARP_NULLPTR; } return true; }
void PortCoreInputUnit::run() { running = true; phase.post(); Route route; bool wasNoticed = false; bool posted = false; bool done = false; YARP_ASSERT(ip!=NULL); PortCommand cmd; if (autoHandshake) { bool ok = true; if (!reversed) { ip->open(getName().c_str()); } if (!ok) { YARP_DEBUG(Logger::get(),String("new input connection to ")+ getOwner().getName()+ " is broken"); done = true; } else { route = ip->getRoute(); // just before going official, tag any lurking inputs from // the same source as undesired if (Name(route.getFromName()).isRooted()) { YARP_SPRINTF3(Logger::get(), debug, "Port %s starting up, flushing routes %s->*->%s", getOwner().getName().c_str(), route.getFromName().c_str(), route.getToName().c_str()); getOwner().removeIO(Route(route.getFromName(), route.getToName(),"*"),true); } officialRoute = route; setMode(); getOwner().reportUnit(this,true); String msg = String("Receiving input from ") + route.getFromName() + " to " + route.getToName() + " using " + route.getCarrierName(); if (Name(route.getFromName()).isRooted()) { if (reversed||ip->getConnection().isPush()) { YARP_INFO(Logger::get(),msg); posted = true; } else { YARP_DEBUG(Logger::get(),msg); } } else { YARP_DEBUG(Logger::get(),msg); } // Report the new connection PortInfo info; info.message = msg.c_str(); info.tag = yarp::os::PortInfo::PORTINFO_CONNECTION; info.incoming = true; info.created = true; info.sourceName = route.getFromName().c_str(); info.targetName = route.getToName().c_str(); info.portName = info.targetName; info.carrierName = route.getCarrierName().c_str(); if (info.sourceName!="admin"&&info.sourceName!="null") { getOwner().report(info); wasNoticed = true; } } } else { bool ok = ip->open(""); // anonymous connection route = ip->getRoute(); if (!ok) { done = true; } } if (!reversed) { if (!ip->getConnection().isPush()) { /* IP=OP */ OutputProtocol *op = &(ip->getOutput()); Route r = op->getRoute(); // reverse route op->rename(Route().addFromName(r.getToName()).addToName(r.getFromName()).addCarrierName(r.getCarrierName())); getOwner().addOutput(op); ip = NULL; done = true; } } if (closing) { done = true; } void *id = (void *)this; while (!done) { ConnectionReader& br = ip->beginRead(); if (br.getReference()!=NULL) { //printf("HAVE A REFERENCE\n"); if (localReader!=NULL) { bool ok = localReader->read(br); if (!br.isActive()) { done = true; break; } if (!ok) continue; } else { PortManager& man = getOwner(); bool ok = man.readBlock(br,id,NULL); if (!br.isActive()) { done = true; break; } if (!ok) continue; } //printf("DONE WITH A REFERENCE\n"); if (ip!=NULL) { ip->endRead(); } continue; } if (autoHandshake&&(ip->getConnection().canEscape())) { bool ok = cmd.read(br); if (!br.isActive()) { done = true; break; } if (!ok) continue; } else { cmd = PortCommand('d',""); if (!ip->checkStreams()) { done = true; break; } } if (closing||isDoomed()) { done = true; break; } char key = cmd.getKey(); //ACE_OS::printf("Port command is [%c:%d/%s]\n", // (key>=32)?key:'?', key, cmd.getText().c_str()); PortManager& man = getOwner(); OutputStream *os = NULL; if (br.isTextMode()) { os = &(ip->getOutputStream()); } switch (key) { case '/': YARP_SPRINTF3(Logger::get(), debug, "Port command (%s): %s should add connection: %s", route.toString().c_str(), getOwner().getName().c_str(), cmd.getText().c_str()); man.addOutput(cmd.getText(),id,os); break; case '!': YARP_SPRINTF3(Logger::get(), debug, "Port command (%s): %s should remove output: %s", route.toString().c_str(), getOwner().getName().c_str(), cmd.getText().c_str()); man.removeOutput(cmd.getText().substr(1,String::npos),id,os); break; case '~': YARP_SPRINTF3(Logger::get(), debug, "Port command (%s): %s should remove input: %s", route.toString().c_str(), getOwner().getName().c_str(), cmd.getText().c_str()); man.removeInput(cmd.getText().substr(1,String::npos),id,os); break; case '*': man.describe(id,os); break; case 'D': case 'd': { bool suppressed = false; // this will be the new way to signal that // replies are not expected. if (key=='D') { ip->suppressReply(); } String env = cmd.getText(); if (env.length()>1) { if (!suppressed) { // This is the backwards-compatible // method for signalling replies are // not expected. To be used until // YARP 2.1.2 is a "long time ago". if (env[1]=='o') { ip->suppressReply(); } } if (env.length()>2) { //YARP_ERROR(Logger::get(), //"***** received an envelope! [%s]", env.c_str()); String env2 = env.substr(2,env.length()); man.setEnvelope(env2); ip->setEnvelope(env2); } } if (localReader) { localReader->read(br); if (!br.isActive()) { done = true; break; } } else { if (ip->getReceiver().acceptIncomingData(br)) { man.readBlock(ip->getReceiver().modifyIncomingData(br),id,os); } else { skipIncomingData(br); } if (!br.isActive()) { done = true; break; } } } break; case 'a': { man.adminBlock(br,id,os); } break; case 'r': /* In YARP implementation, OP=IP. (This information is used rarely, and when used is tagged with OP=IP keyword) If it were not true, memory alloc would need to reorganized here */ { OutputProtocol *op = &(ip->getOutput()); ip->endRead(); Route r = op->getRoute(); // reverse route op->rename(Route().addFromName(r.getToName()).addToName(r.getFromName()).addCarrierName(r.getCarrierName())); getOwner().addOutput(op); ip = NULL; done = true; } break; case 'q': done = true; break; case 'i': printf("Interrupt requested\n"); //ACE_OS::kill(0,2); // SIGINT //ACE_OS::kill(Logger::get().getPid(),2); // SIGINT ACE_OS::kill(Logger::get().getPid(),15); // SIGTERM break; case '?': case 'h': if (os!=NULL) { BufferedConnectionWriter bw(true); bw.appendLine("This is a YARP port. Here are the commands it responds to:"); bw.appendLine("* Gives a description of this port"); bw.appendLine("d Signals the beginning of input for the port's owner"); bw.appendLine("do The same as \"d\" except replies should be suppressed (\"data-only\")"); bw.appendLine("q Disconnects"); bw.appendLine("i Interrupt parent process (unix only)"); bw.appendLine("r Reverse connection type to be a reader"); bw.appendLine("/port Requests to send output to /port"); bw.appendLine("!/port Requests to stop sending output to /port"); bw.appendLine("~/port Requests to stop receiving input from /port"); bw.appendLine("a Signals the beginning of an administrative message"); bw.appendLine("? Gives this help"); bw.write(*os); } break; default: if (os!=NULL) { BufferedConnectionWriter bw(true); bw.appendLine("Port command not understood."); bw.appendLine("Type d to send data to the port's owner."); bw.appendLine("Type ? for help."); bw.write(*os); } break; } if (ip!=NULL) { ip->endRead(); } if (ip==NULL) { done = true; break; } if (closing||isDoomed()||(!ip->checkStreams())) { done = true; break; } } setDoomed(true); YARP_DEBUG(Logger::get(),"PortCoreInputUnit closing ip"); access.wait(); if (ip!=NULL) { ip->close(); } access.post(); YARP_DEBUG(Logger::get(),"PortCoreInputUnit closed ip"); if (autoHandshake) { String msg = String("Removing input from ") + route.getFromName() + " to " + route.getToName(); if (Name(route.getFromName()).isRooted()) { if (posted) { YARP_INFO(Logger::get(),msg); } } else { YARP_DEBUG(Logger::get(),"PortCoreInputUnit (unrooted) shutting down"); } getOwner().reportUnit(this,false); if (wasNoticed) { // Report the disappearing connection PortInfo info; info.message = msg.c_str(); info.tag = yarp::os::PortInfo::PORTINFO_CONNECTION; info.incoming = true; info.created = false; info.sourceName = route.getFromName().c_str(); info.targetName = route.getToName().c_str(); info.portName = info.targetName; info.carrierName = route.getCarrierName().c_str(); if (info.sourceName!="admin") { getOwner().report(info); } } } else { YARP_DEBUG(Logger::get(),"PortCoreInputUnit shutting down"); } if (localReader!=NULL) { delete localReader; localReader = NULL; } running = false; finished = true; // it would be nice to get my entry removed from the port immediately, // but it would be a bit dodgy to delete this object and join this // thread within and from themselves }
String NameClient::send(const String& cmd, bool multi) { //printf("*** OLD YARP command %s\n", cmd.c_str()); setup(); if (NetworkBase::getQueryBypass()) { ContactStyle style; Bottle bcmd(cmd.c_str()), reply; NetworkBase::writeToNameServer(bcmd,reply,style); ConstString si = reply.toString(), so; for (int i=0; i<(int)si.length(); i++) { if (si[i]!='\"') { so += si[i]; } } return so.c_str(); } bool retried = false; bool retry = false; String result; Contact server = getAddress(); float timeout = 10; server.setTimeout(timeout); do { YARP_DEBUG(Logger::get(),String("sending to nameserver: ") + cmd); if (isFakeMode()) { //YARP_DEBUG(Logger::get(),"fake mode nameserver"); return getServer().apply(cmd,Contact::bySocket("tcp","127.0.0.1",NetworkBase::getDefaultPortRange())) + "\n"; } TcpFace face; YARP_DEBUG(Logger::get(),String("connecting to ") + getAddress().toURI()); OutputProtocol *ip = NULL; if (!retry) { ip = face.write(server); } else { retried = true; } if (ip==NULL) { YARP_INFO(Logger::get(),"No connection to nameserver"); if (!allowScan) { YARP_INFO(Logger::get(),"*** try running: yarp detect ***"); } Contact alt; if (!isFakeMode()) { if (allowScan) { YARP_INFO(Logger::get(),"no connection to nameserver, scanning mcast"); reportScan = true; #ifdef YARP_HAS_ACE alt = FallbackNameClient::seek(); #else return ""; // nothing to do, nowhere to turn #endif } } if (alt.isValid()) { address = alt; if (allowSaveScan) { reportSaveScan = true; NameConfig nc; nc.setAddress(alt); nc.toFile(); } server = getAddress(); server.setTimeout(timeout); ip = face.write(server); if (ip==NULL) { YARP_ERROR(Logger::get(), "no connection to nameserver, scanning mcast"); return ""; } } else { return ""; } } String cmdn = cmd + "\n"; Bytes b((char*)cmdn.c_str(),cmdn.length()); ip->getOutputStream().write(b); bool more = multi; while (more) { String line = ""; line = ip->getInputStream().readLine(); if (!(ip->isOk())) { more = false; //YARP_DEBUG(Logger::get(), e.toString() + " <<< exception from name server"); retry = true; break; } if (line.length()>1) { if (line[0] == '*'||line[0] == '[') { more = false; } } result += line + "\n"; } ip->close(); delete ip; YARP_SPRINTF1(Logger::get(), debug, "<<< received from nameserver: %s",result.c_str()); } while (retry&&!retried); return result; }