void LLFloaterMessageLog::refreshNetInfo(BOOL force)
{
	if(mInfoPaneMode != IPANE_NET) return;
	LLScrollListCtrl* scrollp = getChild<LLScrollListCtrl>("net_list");
	LLScrollListItem* selected_itemp = scrollp->getFirstSelected();
	if(selected_itemp)
	{
		LLTextEditor* net_info = getChild<LLTextEditor>("net_info");
		if(!force && (net_info->hasSelection() || net_info->hasFocus())) return;
		LLNetListItem* itemp = findNetListItem(selected_itemp->getUUID());
		if(itemp)
		{
			std::string info(llformat("%s, %d\n--------------------------------\n\n", itemp->mName.c_str(), itemp->mHandle));
			if(itemp->mCircuitData)
			{
				LLCircuitData* cdp = itemp->mCircuitData;
				info.append("Circuit\n--------------------------------\n");
				info.append(llformat(" * Host: %s\n", cdp->getHost().getString().c_str()));
				S32 seconds = (S32)cdp->getAgeInSeconds();
				S32 minutes = seconds / 60;
				seconds = seconds % 60;
				S32 hours = minutes / 60;
				minutes = minutes % 60;
				info.append(llformat(" * Age: %dh %dm %ds\n", hours, minutes, seconds));
				info.append(llformat(" * Alive: %s\n", cdp->isAlive() ? "yes" : "no"));
				info.append(llformat(" * Blocked: %s\n", cdp->isBlocked() ? "yes" : "no"));
				info.append(llformat(" * Allow timeout: %s\n", cdp->getAllowTimeout() ? "yes" : "no"));
				info.append(llformat(" * Trusted: %s\n", cdp->getTrusted() ? "yes" : "no"));
				info.append(llformat(" * Ping delay: %d\n", cdp->getPingDelay()));
				info.append(llformat(" * Packets out: %d\n", cdp->getPacketsOut()));
				info.append(llformat(" * Bytes out: %d\n", cdp->getBytesOut()));
				info.append(llformat(" * Packets in: %d\n", cdp->getPacketsIn()));
				info.append(llformat(" * Bytes in: %d\n", cdp->getBytesIn()));
				info.append(llformat(" * Endpoint ID: %s\n", cdp->getLocalEndPointID().asString().c_str()));
				info.append(llformat(" * Remote ID: %s\n", cdp->getRemoteID().asString().c_str()));
				info.append(llformat(" * Remote session ID: %s\n", cdp->getRemoteSessionID().asString().c_str()));
				info.append("\n");
			}

			childSetText("net_info", info);
		}
		else childSetText("net_info", std::string(""));
	}
	else childSetText("net_info", std::string(""));
}
예제 #2
0
void LLTransferSourceChannel::updateTransfers()
{
	// Actually, this should do the following:
	// Decide if we can actually send data.
	// If so, update priorities so we know who gets to send it.
	// Send data from the sources, while updating until we've sent our throttle allocation.

	LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(getHost());
	if (!cdp)
	{
		return;
	}

	if (cdp->isBlocked())
	{
		// *NOTE: We need to make sure that the throttle bits
		// available gets reset.

		// We DON'T want to send any packets if they're blocked, they'll just end up
		// piling up on the other end.
		//llwarns << "Blocking transfers due to blocked circuit for " << getHost() << llendl;
		return;
	}

	const S32 throttle_id = mThrottleID;

	LLThrottleGroup &tg = cdp->getThrottleGroup();

	if (tg.checkOverflow(throttle_id, 0.f))
	{
		return;
	}

	LLPriQueueMap<LLTransferSource *>::pqm_iter iter, next;

	BOOL done = FALSE;
	for (iter = mTransferSources.mMap.begin(); (iter != mTransferSources.mMap.end()) && !done;)
	{
		//llinfos << "LLTransferSourceChannel::updateTransfers()" << llendl;
		// Do stuff. 
		next = iter;
		next++;

		LLTransferSource *tsp = iter->second;
		U8 *datap = NULL;
		S32 data_size = 0;
		BOOL delete_data = FALSE;
		S32 packet_id = 0;
		S32 sent_bytes = 0;
		LLTSCode status = LLTS_OK;

		// Get the packetID for the next packet that we're transferring.
		packet_id = tsp->getNextPacketID();
		status = tsp->dataCallback(packet_id, DEFAULT_PACKET_SIZE, &datap, data_size, delete_data);

		if (status == LLTS_SKIP)
		{
			// We don't have any data, but we're not done, just go on.
			// This will presumably be used for streaming or async transfers that
			// are stalled waiting for data from another source.
			iter=next;
			continue;
		}

		LLUUID *cb_uuid = new LLUUID(tsp->getID());
		LLUUID transaction_id = tsp->getID();

		// Send the data now, even if it's an error.
		// The status code will tell the other end what to do.
		gMessageSystem->newMessage("TransferPacket");
		gMessageSystem->nextBlock("TransferData");
		gMessageSystem->addUUID("TransferID", tsp->getID());
		gMessageSystem->addS32("ChannelType", getChannelType());
		gMessageSystem->addS32("Packet", packet_id);	// HACK!  Need to put in a REAL packet id
		gMessageSystem->addS32("Status", status);
		gMessageSystem->addBinaryData("Data", datap, data_size);
		sent_bytes = gMessageSystem->getCurrentSendTotal();
		gMessageSystem->sendReliable(getHost(), LL_DEFAULT_RELIABLE_RETRIES, TRUE, 0.f,
									 LLTransferManager::reliablePacketCallback, (void**)cb_uuid);

		// Do bookkeeping for the throttle
		done = tg.throttleOverflow(throttle_id, sent_bytes*8.f);
		gTransferManager.addTransferBitsOut(mChannelType, sent_bytes*8);

		// Clean up our temporary data.
		if (delete_data)
		{
			delete[] datap;
			datap = NULL;
		}

		if (findTransferSource(transaction_id) == NULL)
		{
			//Warning!  In the case of an aborted transfer, the sendReliable call above calls 
			//AbortTransfer which in turn calls deleteTransfer which means that somewhere way 
			//down the chain our current iter can get invalidated resulting in an infrequent
			//sim crash.  This check gets us to a valid transfer source in this event.
			iter=next;
			continue;
		}

		// Update the packet counter
		tsp->setLastPacketID(packet_id);

		switch (status)
		{
		case LLTS_OK:
			// We're OK, don't need to do anything.  Keep sending data.
			break;
		case LLTS_ERROR:
			llwarns << "Error in transfer dataCallback!" << llendl;
			// fall through
		case LLTS_DONE:
			// We need to clean up this transfer source.
			//llinfos << "LLTransferSourceChannel::updateTransfers() " << tsp->getID() << " done" << llendl;
			tsp->completionCallback(status);
			delete tsp;
			
			mTransferSources.mMap.erase(iter);
			iter = next;
			break;
		default:
			llerrs << "Unknown transfer error code!" << llendl;
		}

		// At this point, we should do priority adjustment (since some transfers like
		// streaming transfers will adjust priority based on how much they've sent and time,
		// but I'm not going to bother yet. - djs.
	}
}