// maybe we could get rid of the phase length
void
ProportionalFair::updatePastDataRates(std::map<UserID, float> bitsBeforeThisFrame,
                                      std::map<UserID, float> bitsAfterThisFrame,
                                      simTimeType phaseLength)
{
    UserID user;
    float bitsThisFrame = 0.0;
    float pastDataRate = 0.0;
    float currentRate = 0.0;

    for (std::map<UserID, float>::const_iterator iter = bitsBeforeThisFrame.begin();
         iter != bitsBeforeThisFrame.end(); ++iter)
    {
        user = iter->first;
        bitsThisFrame = bitsBeforeThisFrame[user] - bitsAfterThisFrame[user];
        currentRate = bitsThisFrame / phaseLength;
        pastDataRate = pastDataRates[user];

        if (pastDataRates.find(user) != pastDataRates.end()) {
            pastDataRates[user] = (1.0-historyWeight) * currentRate + historyWeight * pastDataRates[user];
        } else {
            // new user
            pastDataRates[user] = currentRate;
        }
        MESSAGE_SINGLE(NORMAL, logger, "updatePastDataRates("<<user.getName()<<","<<phaseLength<<"s): pastDataRate: new= "<< pastDataRates[user]<<" bit/s, old= "<<pastDataRate<<" bit/s, currentRate= "<<currentRate<<" bit/s");
    }
}
// preferences should be a member
wns::scheduler::ConnectionID
ProportionalFair::getNextConnection(SchedulerStatePtr schedulerState,
                                    std::priority_queue<UserPreference> preferences)
{
    wns::scheduler::ConnectionID next = -1;

    while (!preferences.empty())
    {
        int priority = schedulerState->currentState->getCurrentPriority();
        const float preference = preferences.top().first;
        const UserID user = preferences.top().second;
        MESSAGE_SINGLE(NORMAL, logger, "Selected user="******"Selected connection with CID="<<next);
            return next;
        }
        preferences.pop();
    }
    return next;
}
QString Formatting::validityShort( const UserID & uid ) {
    if ( uid.isRevoked() )
	return i18n("revoked");
    if ( uid.isInvalid() )
	return i18n("invalid");
    switch ( uid.validity() ) {
    case UserID::Unknown:   return i18nc("unknown trust level", "unknown");
    case UserID::Undefined: return i18nc("undefined trust", "undefined");
    case UserID::Never:     return i18n("untrusted");
    case UserID::Marginal:  return i18nc("marginal trust", "marginal");
    case UserID::Full:      return i18nc("full trust", "full");
    case UserID::Ultimate:  return i18nc("ultimate trust", "ultimate");
    }
    return QString();
}
QString Formatting::prettyUserID( const UserID & uid ) {
    if ( uid.parent().protocol() == OpenPGP )
        return prettyNameAndEMail( uid );
    const QByteArray id = QByteArray( uid.id() ).trimmed();
    if ( id.startsWith( '<' ) )
        return prettyEMail( uid.email(), uid.id() );
    if ( id.startsWith( '(' ) )
        // ### parse uri/dns:
        return QString::fromUtf8( uid.id() );
    else
        return DN( uid.id() ).prettyDN();
}
Example #5
0
void TalkManager::ProcessMessageData(XMLEntity *entity)
{
	ChatWindow::talk_type type;
	string                thread_id;
	string                sender;
	string				  receiver;

	string                group_room;
	string                group_server;
	string                group_identity;
	string                group_username;
	
	// must be sender to continue
	if (!entity->Attribute("from"))
	{
		fprintf(stderr, "From is unspecified. Return.\n");
		return;
	}

	// determine message type
	if (!entity->Attribute("type"))
	{
		if (entity->Child("x", "xmlns", "jabber:x:oob"))
			type = ChatWindow::GROUP;
		else
		{
			fprintf(stderr, "Type is unspecified. Return.\n");
			return;
		}
	}
	else if (!strcasecmp(entity->Attribute("type"), "normal"))
	{
		type = ChatWindow::CHAT;
	}
	else if (!strcasecmp(entity->Attribute("type"), "chat"))
	{
		type = ChatWindow::CHAT;
	}
	else if (!strcasecmp(entity->Attribute("type"), "groupchat"))
	{
		type = ChatWindow::GROUP;
	}
	else if (!strcasecmp(entity->Attribute("type"), "error"))
	{
		char buffer[2048];
		
		if (entity->Child("error")) {
			const char *text = entity->Child("error")->Child("text") ? entity->Child("error")->Child("text")->Data() : "Unknown";
			sprintf(buffer, "An error occurred when you tried sending a message to %s.  The reason is as follows:\n\n%s", entity->Attribute("from"), text);
			ModalAlertFactory::Alert(buffer, "Oh, well.", NULL, NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT);
		}
		
		//delete entity;
		
		return;
	}
	else if (!strcasecmp(entity->Attribute("type"), "headline"))
	{
		fprintf(stderr, "Tune message.\n");
		return;
	}
	else
	{
		type = ChatWindow::CHAT;
	}
	
	sender = string(entity->Attribute("from"));
	receiver = string(entity->Attribute("to"));
	group_username = UserID(sender).JabberResource();
	group_room = UserID(sender).JabberUsername();
	UserID sender_user(sender);

	ChatWindow *window = FindWindow(sender_user.JabberHandle());
		
	if (!window)
	{
		//JRoster::Instance()->Lock();
			
			  
		UserID *user = BlabberMainWindow::Instance()->fRosterView->
							fUsers[sender_user.JabberHandle()];
						//JRoster::Instance()->FindUser(&sender_user);
		
		if (!user)
		{
			user = new UserID(sender_user);
			
			fprintf(stderr, "Username: %s.\n", user->JabberUsername().c_str());
			fprintf(stderr, "Server: %s.\n", user->JabberServer().c_str());
			fprintf(stderr, "Resource: %s.\n", user->JabberResource().c_str());
			fprintf(stderr, "Valid?: %s.\n", user->WhyNotValidJabberHandle().c_str());
			if (user->JabberServer().empty())
			{
				user->SetFriendlyName(string("Server Chat"));
				user->SetJabberServer(sender);
				fprintf(stderr, "Username: %s.\n", user->JabberUsername().c_str());
				fprintf(stderr, "Server: %s.\n", user->JabberServer().c_str());
				fprintf(stderr, "Resource: %s.\n", user->JabberResource().c_str());
			}
			fprintf(stderr, "Not found incoming message user in roster.\n");
		}

		//JRoster::Instance()->Unlock();
			
		if (type==ChatWindow::CHAT /*|| type==ChatWindow::GROUP*/ )
		{
			window = CreateTalkSession(type, user);
			fprintf(stderr, "Create Window for incoming message.\n");
			window->jabber = jabber;
		} else {
			fprintf(stderr, "Unexisted Groupchat Window. No route\n");
			return;
		}
	}
	else
	{
		fprintf(stderr, "Redirected to Existed Window: %s.\n", sender_user.JabberHandle().c_str());
	}
				
	fprintf(stderr, "Lock. ");
	window->Lock();
	
	//fprintf(stderr, "Activate. ");
	//window->Activate();
			
	string body;
	string subject;
		
	if (entity->Child("body") && entity->Child("body")->Data())
		body = string(entity->Child("body")->Data());
		
	if (entity->Child("subject") && entity->Child("subject")->Data())
		subject = string(entity->Child("subject")->Data());
				
	if (type == ChatWindow::CHAT && !body.empty())
	{
		window->NewMessage(body);
	}
	else if (type == ChatWindow::GROUP && (!body.empty() || !subject.empty()))
	{
		//Accept exectly our JID in destinations 
		if (UserID(receiver).JabberHandle() != UserID(jabber->jid.String()).JabberHandle())
		{
			window->Unlock();
			fprintf(stderr, "Unlock.\n");
			delete entity;
			return;
		}
		
		if (group_username == "")
			window->AddToTalk(group_room, body, ChatWindow::MAIN_RECIPIENT); // channel messages
		else
		{
			if (!subject.empty())
			{
				window->AddToTalk(group_username, subject, ChatWindow::TOPIC); // topic messages
				fprintf(stderr, "Topic message.\n");
			}
			else			
				window->AddToTalk(group_username, body, ChatWindow::MAIN_RECIPIENT); // user messages
		}
	}
		
	window->Unlock();
	fprintf(stderr, "Unlock.\n");
	
}
wns::scheduler::PowerCapabilities
Strategy::getPowerCapabilities(const UserID user) const
{
    /* This method changes the state "schedulerState->powerCapabilities".
       This is good and ok if all users are the same (default of all systems),
       but if they are different (future), APC must call this function anytime.
    */
    switch (schedulerState->powerControlType)
    {
        case PowerControlDLMaster:
        {
            schedulerState->powerCapabilities = 
                colleagues.registry->getPowerCapabilities(); 
            break;
        }
        case PowerControlULMaster:
        {
            // peer unknown. Assume peer=UT.
            if (!user.isValid()) 
            { 
                MESSAGE_SINGLE(NORMAL, logger, "getPowerCapabilities(NULL): asking registry...");
                schedulerState->powerCapabilities = colleagues.registry->getPowerCapabilities(user); 

                MESSAGE_SINGLE(NORMAL, logger, "getPowerCapabilities(NULL): nominal="
                    << schedulerState->powerCapabilities.nominalPerSubband);

                return schedulerState->powerCapabilities;
            }
            schedulerState->powerCapabilities = colleagues.registry->getPowerCapabilities(user); 
            break;
        }
        case PowerControlULSlave:
        {
            if (schedulerState->defaultTxPower!=wns::Power()) 
            {
                // don't use powerCapabilities but masterBurst instead
                assure(schedulerState->defaultTxPower!=wns::Power(),"undefined defaultTxPower");
                schedulerState->powerCapabilities.nominalPerSubband = schedulerState->defaultTxPower;
                schedulerState->powerCapabilities.maxPerSubband = schedulerState->defaultTxPower;
                // limit not used for slave
                schedulerState->powerCapabilities.maxOverall = schedulerState->defaultTxPower * 1000.0; 
            } 
            // not given (by masterBurst) because there is an InputSchedulingMap (new method)
            else 
            { 
                assure(schedulerState->currentState->strategyInput->inputSchedulingMap != wns::scheduler::SchedulingMapPtr(), 
                    "need inputSchedulingMap with txPower information");

            // the power settings in inputSchedulingMap can be overwritten
            // if APC strategy is changed to use nominal power. Therefore we need these values:
            schedulerState->powerCapabilities = colleagues.registry->getPowerCapabilities(); 
            }
            break;
        }
        default:
        {
            throw wns::Exception("invalid powerControlType");
        }
    } // switch(powerControlType)
    if (user.isValid()) 
    {
        MESSAGE_SINGLE(NORMAL, logger, "getPowerCapabilities("
            << user.getName() << "): nominal="
            << schedulerState->powerCapabilities.nominalPerSubband);

    } 
    else 
    {
        MESSAGE_SINGLE(NORMAL, logger, "getPowerCapabilities(NULL): nominal="
            << schedulerState->powerCapabilities.nominalPerSubband);
    }
    assure(schedulerState->powerCapabilities.nominalPerSubband != wns::Power(),
        "undefined power nominalPerSubband="<<schedulerState->powerCapabilities.nominalPerSubband);

    return schedulerState->powerCapabilities;
}
Example #7
0
 size_t operator()(const UserID &u) const {
     return std::hash<std::string>()(u.name()) ^ std::hash<unsigned int>()(u.index());
 }
Example #8
0
 bool operator()(const UserID &u1, const UserID &u2) const {
     if(u1.name()==u2.name() && u1.index()==u2.index()) return true;
     return false;
 }
std::priority_queue<ProportionalFair::UserPreference>
ProportionalFair::calculateUserPreferences(UserSet activeUsers, bool txStrategy) const
{
    std::map<UserID, ChannelQualityOnOneSubChannel> sinrs;

    // preference for every user in a priority queue which automatically sorts
    std::priority_queue<UserPreference> preferences;
    assure(preferences.size()==0, "preferences.size() must be 0");

    for ( UserSet::const_iterator iter = activeUsers.begin();
          iter != activeUsers.end(); ++iter)
    {
        UserID user = *iter;
        assure(user.isValid(), "No valid user");

        //determines the users SINRs depending on the tx/Rx mode of the strategy
        if (txStrategy)
        {
            sinrs[user] = colleagues.registry->estimateTxSINRAt(user);
        }
        else
        {
            sinrs[user] = colleagues.registry->estimateRxSINROf(user);
        }

        // calculate PhyModeRate for available users
        wns::Ratio sinr(sinrs[user].carrier / sinrs[user].interference);
        wns::service::phy::phymode::PhyModeInterfacePtr phyMode = colleagues.registry->getPhyModeMapper()->getBestPhyMode(sinr);
        assure(phyMode->isValid(),"invalid PhyMode");

        // calculate userRate, which is the maximum possible data rate
        // for one subChannel for the best PhyMode available here
        float phyModeRate = phyMode->getDataRate(); // rate [b/s] of one subChannel
        float referenceRate;
        float pastDataRate = 1.0;

        // get the past data rate for this user:
        // iterate over the global past data rates map of all users and
        // find the past data rate for this user
        // there is exactly one pastDataRate value per userID
        int weight = colleagues.registry->getTotalNumberOfUsers(user);
        for (std::map<UserID, float>::const_iterator iter = pastDataRates.begin();
             iter != pastDataRates.end(); ++iter)
        {
            if (iter->first/*userID*/ == user)
            {
                float dataRate = iter->second;
                // a RN must get a better share of the bandwidth
                // here: proportional to its number of users:
                assure(weight>0, "numberOfUsers(" <<user.getName()<<")=" << weight);
                dataRate /= static_cast<float>(weight);
                // dataRate now has the meaning of a weight.
                pastDataRate = dataRate;
            }
        } // for all userIDs in pastDataRates

        if (pastDataRate < 0.01)
            pastDataRate = 0.01;

        // preference is achievable current user rate divided by a history
        // factor that takes the past throughput of this user into account

        assure(maxRateOfSubchannel>0.0, "unknown maxRateOfSubchannel");

        // goal is either rate (true) or resource (false) fairness
        if (rateFairness == true)
        {
            referenceRate = maxRateOfSubchannel;
        }
        else
        {
            referenceRate = phyModeRate;
        }

        // maxRateOfSubchannel is constant, with range [0..1][bit/s]
        float resultMaxThroughput = referenceRate / maxRateOfSubchannel;
        float resultPropFair      = referenceRate / pastDataRate; // can be any range
        if (scalingBetweenMaxTPandPFair <= 0.5) {
            // variate the preference for each user, so that they differ a little bit (1%)
            // and the automatic sorting does not always give the same order
            // (would be a problem for identical preference weights).
            resultMaxThroughput *=  (1 + 0.01*(*preferenceVariationDistribution)());
        }
        float UserPref =
            (1.0-scalingBetweenMaxTPandPFair) * resultMaxThroughput
            +scalingBetweenMaxTPandPFair  * resultPropFair;

        MESSAGE_SINGLE(NORMAL, logger, "getPreference("<<user.getName()<<"): weight=" << weight << ", pastDataRate= "<<pastDataRate<<" bit/s, UserPreference= "<<UserPref<<" (resultMaxThroughput="<<resultMaxThroughput<<",resultProportionalFair="<<resultPropFair<<")");

        // calculate preferences for users and order them
        preferences.push(UserPreference(UserPref, user));
    }
    return preferences;
}
Example #10
0
QString Formatting::prettyEMail( const UserID & uid ) {
    return prettyEMail( uid.email(), uid.id() );
}
Example #11
0
QString Formatting::prettyName( const UserID & uid ) {
    return prettyName( uid.parent().protocol(), uid.id(), uid.name(), uid.comment() );
}
Example #12
0
Key *
BaseG::parseKeyData(const QCString &output, int &offset, Key *key /* = 0 */)
// This function parses the data for a single key which is output by GnuPG
// with the following command line arguments:
//   --batch --list-public-keys --with-fingerprint --with-colons
//   --fixed-list-mode [--no-expensive-trust-checks]
// It expects the key data to start at offset and returns the start of
// the next key's data in offset.
// Subkeys are currently ignored.
{
    int index = offset;

    if((strncmp(output.data() + offset, "pub:", 4) != 0)
            && (strncmp(output.data() + offset, "sec:", 4) != 0))
    {
        return 0;
    }

    if(key == 0)
        key = new Key();
    else
        key->clear();

    QCString keyID;
    bool firstKey = true;

    while(true)
    {
        int eol;
        // search the end of the current line
        if((eol = output.find('\n', index)) == -1)
            break;

        bool bIsPublicKey = false;
        if((bIsPublicKey = !strncmp(output.data() + index, "pub:", 4))
                || !strncmp(output.data() + index, "sec:", 4))
        {
            // line contains primary key data
            // Example: pub:f:1024:17:63CB691DFAEBD5FC:860451781::379:-:::scESC:

            // abort parsing if we found the start of the next key
            if(!firstKey)
                break;
            firstKey = false;

            key->setSecret(!bIsPublicKey);

            Subkey *subkey = new Subkey(QCString(), !bIsPublicKey);

            int pos = index + 4; // begin of 2nd field
            int pos2 = output.find(':', pos);
            for(int field = 2; field <= 12; field++)
            {
                switch(field)
                {
                    case 2: // the calculated trust
                        if(pos2 > pos)
                        {
                            switch(output[pos])
                            {
                                case 'o': // unknown (this key is new to the system)
                                    break;
                                case 'i': // the key is invalid, e.g. missing self-signature
                                    subkey->setInvalid(true);
                                    key->setInvalid(true);
                                    break;
                                case 'd': // the key has been disabled
                                    subkey->setDisabled(true);
                                    key->setDisabled(true);
                                    break;
                                case 'r': // the key has been revoked
                                    subkey->setRevoked(true);
                                    key->setRevoked(true);
                                    break;
                                case 'e': // the key has expired
                                    subkey->setExpired(true);
                                    key->setExpired(true);
                                    break;
                                case '-': // undefined (no path leads to the key)
                                case 'q': // undefined (no trusted path leads to the key)
                                case 'n': // don't trust this key at all
                                case 'm': // the key is marginally trusted
                                case 'f': // the key is fully trusted
                                case 'u': // the key is ultimately trusted (secret key available)
                                    // These values are ignored since we determine the key trust
                                    // from the trust values of the user ids.
                                    break;
                                default:
                                    kdDebug(5100) << "Unknown trust value\n";
                            }
                        }
                        break;
                    case 3: // length of key in bits
                        if(pos2 > pos)
                            subkey->setKeyLength(output.mid(pos, pos2 - pos).toUInt());
                        break;
                    case 4: //  the key algorithm
                        if(pos2 > pos)
                            subkey->setKeyAlgorithm(output.mid(pos, pos2 - pos).toUInt());
                        break;
                    case 5: // the long key id
                        keyID = output.mid(pos, pos2 - pos);
                        subkey->setKeyID(keyID);
                        break;
                    case 6: // the creation date (in seconds since 1970-01-01 00:00:00)
                        if(pos2 > pos)
                            subkey->setCreationDate(output.mid(pos, pos2 - pos).toLong());
                        break;
                    case 7: // the expiration date (in seconds since 1970-01-01 00:00:00)
                        if(pos2 > pos)
                            subkey->setExpirationDate(output.mid(pos, pos2 - pos).toLong());
                        else
                            subkey->setExpirationDate(-1);   // key expires never
                        break;
                    case 8: // local ID (ignored)
                    case 9: // Ownertrust (ignored for now)
                    case 10: // User-ID (always empty in --fixed-list-mode)
                    case 11: // signature class (always empty except for key signatures)
                        break;
                    case 12: // key capabilities
                        for(int i = pos; i < pos2; i++)
                            switch(output[i])
                            {
                                case 'e':
                                    subkey->setCanEncrypt(true);
                                    break;
                                case 's':
                                    subkey->setCanSign(true);
                                    break;
                                case 'c':
                                    subkey->setCanCertify(true);
                                    break;
                                case 'E':
                                    key->setCanEncrypt(true);
                                    break;
                                case 'S':
                                    key->setCanSign(true);
                                    break;
                                case 'C':
                                    key->setCanCertify(true);
                                    break;
                                default:
                                    kdDebug(5100) << "Unknown key capability\n";
                            }
                        break;
                }
                pos = pos2 + 1;
                pos2 = output.find(':', pos);
            }
            key->addSubkey(subkey);
        }
        else if(!strncmp(output.data() + index, "uid:", 4))
        {
            // line contains a user id
            // Example: uid:f::::::::Philip R. Zimmermann <*****@*****.**>:

            UserID *userID = new UserID("");

            int pos = index + 4; // begin of 2nd field
            int pos2 = output.find(':', pos);
            for(int field = 2; field <= 10; field++)
            {
                switch(field)
                {
                    case 2: // the calculated trust
                        if(pos2 > pos)
                        {
                            switch(output[pos])
                            {
                                case 'i': // the user id is invalid, e.g. missing self-signature
                                    userID->setInvalid(true);
                                    break;
                                case 'r': // the user id has been revoked
                                    userID->setRevoked(true);
                                    break;
                                case '-': // undefined (no path leads to the key)
                                case 'q': // undefined (no trusted path leads to the key)
                                    userID->setValidity(KPGP_VALIDITY_UNDEFINED);
                                    break;
                                case 'n': // don't trust this key at all
                                    userID->setValidity(KPGP_VALIDITY_NEVER);
                                    break;
                                case 'm': // the key is marginally trusted
                                    userID->setValidity(KPGP_VALIDITY_MARGINAL);
                                    break;
                                case 'f': // the key is fully trusted
                                    userID->setValidity(KPGP_VALIDITY_FULL);
                                    break;
                                case 'u': // the key is ultimately trusted (secret key available)
                                    userID->setValidity(KPGP_VALIDITY_ULTIMATE);
                                    break;
                                default:
                                    kdDebug(5100) << "Unknown trust value\n";
                            }
                        }
                        break;
                    case 3: // these fields are empty
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                        break;
                    case 10: // User-ID
                        QCString uid = output.mid(pos, pos2 - pos);
                        // replace "\xXX" with the corresponding character;
                        // other escaped characters, i.e. \n, \r etc., are ignored
                        // because they shouldn't appear in user IDs
                        for(int idx = 0 ; (idx = uid.find("\\x", idx)) >= 0 ; ++idx)
                        {
                            char str[2] = "x";
                            str[0] = (char) QString(uid.mid(idx + 2, 2)).toShort(0, 16);
                            uid.replace(idx, 4, str);
                        }
                        QString uidString = QString::fromUtf8(uid.data());
                        // check whether uid was utf-8 encoded
                        bool isUtf8 = true;
                        for(unsigned int i = 0; i + 1 < uidString.length(); ++i)
                        {
                            if(uidString[i].unicode() == 0xdbff &&
                                    uidString[i + 1].row() == 0xde)
                            {
                                // we found a non-Unicode character (see QString::fromUtf8())
                                isUtf8 = false;
                                break;
                            }
                        }
                        if(!isUtf8)
                        {
                            // The user id isn't utf-8 encoded. It was most likely
                            // created with PGP which either used latin1 or koi8-r.
                            kdDebug(5100) << "User Id '" << uid
                                          << "' doesn't seem to be utf-8 encoded." << endl;

                            // We determine the ratio between non-ASCII and ASCII chars.
                            // A koi8-r user id should have lots of non-ASCII chars.
                            int nonAsciiCount = 0, asciiCount = 0;

                            // We only look at the first part of the user id (i. e. everything
                            // before the email address resp. before a comment)
                            for(signed char *ch = (signed char *)uid.data();
                                    *ch && (*ch != '(') && (*ch != '<');
                                    ++ch)
                            {
                                if(((*ch >= 'A') && (*ch <= 'Z'))
                                        || ((*ch >= 'a') && (*ch <= 'z')))
                                    ++asciiCount;
                                else if(*ch < 0)
                                    ++nonAsciiCount;
                            }
                            kdDebug(5100) << "ascii-nonAscii ratio : " << asciiCount
                                          << ":" << nonAsciiCount << endl;
                            if(nonAsciiCount > asciiCount)
                            {
                                // assume koi8-r encoding
                                kdDebug(5100) << "Assume koi8-r encoding." << endl;
                                QTextCodec *codec = QTextCodec::codecForName("KOI8-R");
                                uidString = codec->toUnicode(uid.data());
                                // check the case of the first two characters to find out
                                // whether the user id is probably CP1251 encoded (for some
                                // reason in CP1251 the lower case characters have smaller
                                // codes than the upper case characters, so if the first char
                                // of the koi8-r decoded user id is lower case and the second
                                // char is upper case then it's likely that the user id is
                                // CP1251 encoded)
                                if((uidString.length() >= 2)
                                        && (uidString[0].lower() == uidString[0])
                                        && (uidString[1].upper() == uidString[1]))
                                {
                                    // koi8-r decoded user id has inverted case, so assume
                                    // CP1251 encoding
                                    kdDebug(5100) << "No, it doesn't seem to be koi8-r. "
                                                  "Use CP 1251 instead." << endl;
                                    QTextCodec *codec = QTextCodec::codecForName("CP1251");
                                    uidString = codec->toUnicode(uid.data());
                                }
                            }
                            else
                            {
                                // assume latin1 encoding
                                kdDebug(5100) << "Assume latin1 encoding." << endl;
                                uidString = QString::fromLatin1(uid.data());
                            }
                        }
                        userID->setText(uidString);
                        break;
                }
                pos = pos2 + 1;
                pos2 = output.find(':', pos);
            }

            // user IDs are printed in UTF-8 by gpg (if one uses --with-colons)
            key->addUserID(userID);
        }
        else if(!strncmp(output.data() + index, "fpr:", 4))
        {
            // line contains a fingerprint
            // Example: fpr:::::::::17AFBAAF21064E513F037E6E63CB691DFAEBD5FC:

            if(key == 0)  // invalid key data
                break;

            // search the fingerprint (it's in the 10th field)
            int pos = index + 4;
            for(int i = 0; i < 8; i++)
                pos = output.find(':', pos) + 1;
            int pos2 = output.find(':', pos);

            key->setFingerprint(keyID, output.mid(pos, pos2 - pos));
        }
        index = eol + 1;
    }

    //kdDebug(5100) << "finished parsing key data\n";

    offset = index;

    return key;
}
void
JabberProtocol::ProcessPresence(XMLEntity *entity)
{
	

	int num_matches = 0;

	// verify we have a username
	if (entity->Attribute("from"))
	{
		// circumvent groupchat presences
		string room, server, user;
		
		if (entity->Child("x", "xmlns", "http://jabber.org/protocol/muc#user"))
		{
			UserID from = UserID(string(entity->Attribute("from")));
			room = from.JabberUsername();
			server = from.JabberServer();
			user = from.JabberResource();
			fprintf(stderr, "Group Presence in room %s from user %s.\n", 
				from.JabberHandle().c_str(), user.c_str());
						
			BMessage *msg = new BMessage(JAB_GROUP_CHATTER_ONLINE);
			msg->AddString("room", (room + '@' + server).c_str());
			msg->AddString("server", server.c_str());
			msg->AddString("username", user.c_str());
			
			if (!entity->Attribute("type") || !strcasecmp(entity->Attribute("type"), "available"))
			{
				if (entity->Child("show") && entity->Child("show")->Data())
				{
					msg->AddString("show", entity->Child("show")->Data());
				} else
					msg->AddString("show", "online");

				if (entity->Child("status") && entity->Child("status")->Data())
				{
					msg->AddString("status", entity->Child("status")->Data());
				} else
					msg->AddString("status", "");
				
				if (entity->Child("x")->Child("item") &&
					entity->Child("x")->Child("item")->Attribute("role"))
					msg->AddString("role", entity->Child("x")->Child("item")->Attribute("role"));
				else
					msg->AddString("role", "admin");
				
				if (entity->Child("x")->Child("item") &&
					entity->Child("x")->Child("item")->Attribute("affiliation"))
					msg->AddString("affiliation", entity->Child("x")->Child("item")->Attribute("affiliation"));
				else
					msg->AddString("affiliation", "none");
		
				msg->what = JAB_GROUP_CHATTER_ONLINE;
			}
			else if (!strcasecmp(entity->Attribute("type"), "unavailable"))
			{
				msg->what = JAB_GROUP_CHATTER_OFFLINE;
			}
			
			TalkManager::Instance()->Lock();
			
			ChatWindow *window = TalkManager::Instance()->FindWindow(from.JabberHandle());
			
			if (window != NULL)
			{
				fprintf(stderr, "Process group presence %s.\n", window->GetUserID()->JabberHandle().c_str());
				
				window->PostMessage(msg);
			}
			else
			{
				fprintf(stderr, "There is no window group presence route to.\n");
			}
			
			TalkManager::Instance()->Unlock();
			
			return;
		}		
		
		JRoster *roster = JRoster::Instance();
		
		roster->Lock();
		
		for (JRoster::ConstRosterIter i = roster->BeginIterator(); i != roster->EndIterator(); ++i)
		{
			UserID *user = NULL;

			if (!strcasecmp(UserID(entity->Attribute("from")).JabberHandle().c_str(),
					(*i)->JabberHandle().c_str()))
			{
				++num_matches;
				user = *i;
				ProcessUserPresence(user, entity);
				fprintf(stderr, "Process roster presence %s.\n", user->JabberHandle().c_str());
			}
		}
		
		if (num_matches == 0)
		{
			UserID user(string(entity->Attribute("from")));
			fprintf(stderr, "Process not in roster presence %s.\n", user.JabberHandle().c_str());
			ProcessUserPresence(&user, entity);
		}
			
		roster->Unlock();
		
		mainWindow->PostMessage(BLAB_UPDATE_ROSTER);			

	}
}
CertifyCertificateCommand::CertifyCertificateCommand( const UserID & uid )
    : Command( uid.parent(), new Private( this, 0 ) )
{
    std::vector<UserID>( 1, uid ).swap( d->uids );
    d->init();
}
DSAResult
BestCapacity::getSubChannelWithDSA(RequestForResource& request,
                                   SchedulerStatePtr schedulerState,
                                   SchedulingMapPtr schedulingMap)
{
    DSAResult dsaResult;
    UserID user = request.user;
    if (userInfoMap.find(user) == userInfoMap.end()) {
        userInfoMap.insert(UserInfoMap::value_type(user, UserInfo(schedulerState->currentState->strategyInput->fChannels)));
    }
    UserInfo& userInfo = userInfoMap.find(user)->second;

    int lastUsedSubChannel = userInfo.lastUsedSubChannel;
    int subChannel = lastUsedSubChannel;
    int maxSubChannel = schedulingMap->subChannels.size();
    int maxTimeSlots = schedulerState->currentState->strategyInput->getNumberOfTimeSlots();
    int lastUsedTimeSlot = userInfo.lastUsedTimeSlot;
    int timeSlot = lastUsedTimeSlot;

    assure(maxSubChannel==schedulerState->currentState->strategyInput->fChannels,"maxSubChannel="<<maxSubChannel<<"!=fChannels");
    ChannelQualitiesOnAllSubBandsPtr channelQualitiesOnAllSubBands = userInfo.channelQualitiesOnAllSubBands;
    if (channelQualitiesOnAllSubBands==ChannelQualitiesOnAllSubBandsPtr()) { // empty
        assure(channelQualitiesOfAllUsers->knowsUser(user),"channelQualitiesOfAllUsers["<<user.getName()<<"] invalid");
        // ^ or should we ask the registryProxy for CQI here?
        channelQualitiesOnAllSubBands = channelQualitiesOfAllUsers->find(user)->second;
        userInfo.channelQualitiesOnAllSubBands = channelQualitiesOnAllSubBands;
    }
    MESSAGE_SINGLE(NORMAL, logger, "getSubChannelWithDSA("<<request.toString()<<"): lastSC="<<lastUsedSubChannel);

    int spatialLayer=0;
    bool found  = false;
    bool giveUp = false;
    if (!schedulerState->isTx
        && adjacentSubchannelsOnUplink
        && (lastUsedSubChannel!=DSAsubChannelNotFound) // already used subChannel
        )
    { // UL SC-FDMA
        // adjacentSubchannelsOnUplink
        while(!found && !giveUp)
        {
            // try same old subChannel again:
            subChannel = lastUsedSubChannel;
            if (!userInfo.usedSubChannels[subChannel]
                && channelIsUsable(subChannel, timeSlot, request, schedulerState, schedulingMap))
            { // PDU fits in
                found=true; break;
            } else { // mark unusable
                userInfo.usedSubChannels[subChannel] = true;
            }
            // TODO: consider timeSlots !!!

            // try +/-1 +/-2 and so on
            for (int tryThisSubChannelOffset=0; tryThisSubChannelOffset<maxSubChannel/2; tryThisSubChannelOffset++)
            {
                subChannel = (lastUsedSubChannel + tryThisSubChannelOffset*userInfo.toggleOffset);
                if ((subChannel>=0) && !userInfo.usedSubChannels[subChannel]
                    && (subChannel<maxSubChannel)
                    && channelIsUsable(subChannel, timeSlot, request, schedulerState, schedulingMap))
                { // PDU fits in
                    found=true; break;
                } else { // mark unusable
                    userInfo.usedSubChannels[subChannel] = true;
                }
                subChannel = (lastUsedSubChannel - tryThisSubChannelOffset*userInfo.toggleOffset);
                if ((subChannel>=0) && !userInfo.usedSubChannels[subChannel]
                    && (subChannel<maxSubChannel)
                    && channelIsUsable(subChannel, timeSlot, request, schedulerState, schedulingMap))
                { // PDU fits in
                    found=true; break;
                } else { // mark unusable
                    userInfo.usedSubChannels[subChannel] = true;
                }
            } // for offset +/-
            // the resulting DSA may not be contiguous in the case of another small-band user nearby
        } // while
        userInfo.toggleOffset *= -1;
    } else { // free search
        BetterChannelCapacity comparator; // from SchedulerTypes.hpp
        wns::service::phy::phymode::PhyModeMapperInterface* phyModeMapper = colleagues.registry->getPhyModeMapper();
        double channelCapacity = 0.0;
        double remainingTimeOnthisChannel = 0.0;
        wns::Power nominalPower;
        // to get tx power, default or nominal
        // the same power will be used on all subchannels for comparing, so that
        // the best capacity depend only on the free time and datarate
        if (schedulerState->defaultTxPower!=wns::Power())
        { // predefined, e.g. in slave mode
            nominalPower = schedulerState->defaultTxPower;
        } else {
            wns::scheduler::PowerCapabilities powerCapabilities =
                schedulerState->strategy->getPowerCapabilities(request.user);
            nominalPower = powerCapabilities.nominalPerSubband;
        }

        // O(N^2) operations:
        while(!found && !giveUp)
        {
            subChannel = DSAsubChannelNotFound;
            double bestChannelCapacity = 0.0;
            // find channel with best capacity of the remaining subChannels:
            for (int tryThisSubChannel=0; tryThisSubChannel<maxSubChannel; tryThisSubChannel++)
            {
                for (int tryThisTimeSlot=0; tryThisTimeSlot<maxTimeSlots; tryThisTimeSlot++)
                {
                    // TODO: userInfo.usedSubChannels[tryThisSubChannel][tryThisTimeSlot]
                    if (!userInfo.usedSubChannels[tryThisSubChannel]) { // could be free (at least not checked before)
                        ChannelQualityOnOneSubChannel channelQuality
                            = (*channelQualitiesOnAllSubBands)[tryThisSubChannel];
                        if (channelIsUsable(tryThisSubChannel, tryThisTimeSlot, request, schedulerState, schedulingMap))
                        {
                            spatialLayer = getSpatialLayerForSubChannel(tryThisSubChannel, tryThisTimeSlot, request, schedulerState, schedulingMap);
                        }
                        else
                        {
                            continue;
                        }

                        remainingTimeOnthisChannel = schedulingMap->subChannels[tryThisSubChannel].temporalResources[tryThisTimeSlot]->physicalResources[spatialLayer].getFreeTime();
                        wns::Ratio sinr = nominalPower/(channelQuality.interference * channelQuality.pathloss.get_factor());
                        wns::SmartPtr<const wns::service::phy::phymode::PhyModeInterface> bestPhyMode = phyModeMapper->getBestPhyMode(sinr);
                        channelCapacity = bestPhyMode->getDataRate() * remainingTimeOnthisChannel;

                        if (comparator(channelCapacity, bestChannelCapacity)) {
                            bestChannelCapacity = channelCapacity;
                            subChannel = tryThisSubChannel;
                            timeSlot = tryThisTimeSlot;
                        }
                    } // if unused
                } // forall tryThisTimeSlot
            } // forall tryThisSubChannel

            if (subChannel==DSAsubChannelNotFound)
            { // one complete round already done
                giveUp=true; break;
            }
            // best subChannel and spatialLayer found; now check if usable:
            if (channelIsUsable(subChannel, timeSlot, spatialLayer, request, schedulerState, schedulingMap))
            { // PDU fits in
                found=true; break;
            } else { // mark unusable
                // TODO: userInfo.usedSubChannels[tryThisSubChannel][tryThisTimeSlot]
                userInfo.usedSubChannels[subChannel] = true;
            }
        } // while
    } // if free search or linear (SC-FDMA)

    if (giveUp) {
        MESSAGE_SINGLE(NORMAL, logger, "getSubChannelWithDSA(): no free subchannel");
        return dsaResult; // empty with subChannel=DSAsubChannelNotFound
    } else {
        MESSAGE_SINGLE(NORMAL, logger, "getSubChannelWithDSA(): subChannel="<<subChannel);
        userInfo.lastUsedSubChannel = subChannel;
        dsaResult.subChannel = subChannel;
        dsaResult.spatialLayer = spatialLayer;
        return dsaResult;
    }
    return dsaResult; // empty with subChannel=DSAsubChannelNotFound
}