Exemplo n.º 1
0
    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");
    }
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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
}
Exemplo n.º 7
0
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;
}