// 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(); }
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; }
size_t operator()(const UserID &u) const { return std::hash<std::string>()(u.name()) ^ std::hash<unsigned int>()(u.index()); }
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; }
QString Formatting::prettyEMail( const UserID & uid ) { return prettyEMail( uid.email(), uid.id() ); }
QString Formatting::prettyName( const UserID & uid ) { return prettyName( uid.parent().protocol(), uid.id(), uid.name(), uid.comment() ); }
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 }