示例#1
0
void Network::Spin()
{
	if (active)
	{
//		++inLwip;
		ethernet_task();			// keep the Ethernet running
//		--inLwip;

		// See if we can send anything
		RequestState* r = writingTransactions;
		if (r != NULL)
		{
			bool finished = r->Send();

			// Disable interrupts while we mess around with the lists in case we get a callback from a network ISR
			irqflags_t flags = cpu_irq_save();
			writingTransactions = r->next;

			if (finished)
			{
				RequestState *rn = r->nextWrite;
				r->nextWrite = NULL;
				HttpState *hs = r->hs;
				AppendTransaction(&freeTransactions, r);
				if (rn != NULL)
				{
					if (hs != NULL)
					{
						hs->sendingRs = (rn->hs == hs) ? rn : NULL;
					}
					AppendTransaction(&writingTransactions, rn);
				}
				else if (hs != NULL)
				{
					hs->sendingRs = NULL;
				}
			}
			else
			{
				AppendTransaction(&writingTransactions, r);
			}
			cpu_irq_restore(flags);
		}
	}
	else if (establish_ethernet_link())
	{
		start_ethernet(reprap.GetPlatform()->IPAddress(), reprap.GetPlatform()->NetMask(), reprap.GetPlatform()->GateWay());
		httpd_init();
		active = true;
	}
}
示例#2
0
// We have no data to write and we want to keep the current connection alive if possible.
// That way we can speed up freeing the current NetworkTransaction.
void Network::CloseTransaction()
{
	// Free the current NetworkTransaction's data (if any)
	NetworkTransaction *r = readyTransactions;
	if (r == NULL)
	{
		return;
	}
	r->FreePbuf();

	// Terminate this connection if this NetworkTransaction indicates a graceful disconnect
	TransactionStatus status = r->status;
	if (!r->LostConnection() && status == disconnected)
	{
//		debugPrintf("Network: CloseRequest is closing connection cs=%08x\n", (unsigned int)locCs);
		ConnectionClosed(r->cs, true);
	}

	// Remove the current item from readyTransactions
	readyTransactions = r->next;

	// Append it to freeTransactions again unless it's already on another list
	if (status != dataSending)
	{
		AppendTransaction(&freeTransactions, r);
	}
}
示例#3
0
// This is called when a connection is being established and returns an initialised ConnectionState instance.
ConnectionState *Network::ConnectionAccepted(tcp_pcb *pcb)
{
	ConnectionState *cs = freeConnections;
	if (cs == NULL)
	{
		platform->Message(HOST_MESSAGE, "Network::ConnectionAccepted() - no free ConnectionStates!\n");
		return NULL;
	}

	NetworkTransaction* r = freeTransactions;
	if (r == NULL)
	{
		platform->Message(HOST_MESSAGE, "Network::ConnectionAccepted() - no free transactions!\n");
		return NULL;
	}

	freeConnections = cs->next;
	cs->Init(pcb);

	r->Set(NULL, cs, connected);
	freeTransactions = r->next;
	AppendTransaction(&readyTransactions, r);

	return cs;
}
示例#4
0
// Send the output data we already have, optionally with a file appended, then close the connection unless keepConnectionOpen is true.
// The file may be too large for our buffer, so we may have to send it in multiple transactions.
void Network::SendAndClose(FileStore *f, bool keepConnectionOpen)
{
	irqflags_t flags = cpu_irq_save();
	RequestState *r = readyTransactions;
	if (r == NULL)
	{
		cpu_irq_restore(flags);
	}
	else
	{
		readyTransactions = r->next;
		cpu_irq_restore(flags);
		r->FreePbuf();
		if (r->LostConnection())
		{
			if (f != NULL)
			{
				f->Close();
			}
			AppendTransaction(&freeTransactions, r);
//			debugPrintf("Conn lost before send\n");
		}
		else
		{
			r->nextWrite = NULL;
			r->fileBeingSent = f;
			r->persistConnection = keepConnectionOpen;
			RequestState *sendingRs = r->hs->sendingRs;
			if (sendingRs == NULL)
			{
				r->hs->sendingRs = r;
				AppendTransaction(&writingTransactions, r);
//debug
// r->outputBuffer[r->outputPointer] = 0;
// debugPrintf("Transaction queued for writing to network, file=%c, data=%s\n", (f ? 'Y' : 'N'), r->outputBuffer);
			}
			else
			{
				while (sendingRs->nextWrite != NULL)
				{
					sendingRs = sendingRs->nextWrite;
				}
				sendingRs->nextWrite = r;
			}
		}
	}
}
示例#5
0
void Network::ConnectionClosedGracefully(ConnectionState *cs)
{
	NetworkTransaction* r = freeTransactions;
	if (r == NULL)
	{
		platform->Message(HOST_MESSAGE, "Network::ConnectionClosedGracefully() - no free transactions!\n");
		return;
	}
	freeTransactions = r->next;
	r->Set(NULL, cs, disconnected);

	AppendTransaction(&readyTransactions, r);
}
示例#6
0
void Network::ReceiveInput(pbuf *pb, ConnectionState* cs)
{
	NetworkTransaction* r = freeTransactions;
	if (r == NULL)
	{
		platform->Message(HOST_MESSAGE, "Network::ReceiveInput() - no free transactions!\n");
		return;
	}

	freeTransactions = r->next;
	r->Set(pb, cs, dataReceiving);

	AppendTransaction(&readyTransactions, r);
//	debugPrintf("Network - input received\n");
}
示例#7
0
void Network::ReceiveInput(pbuf *pb, HttpState* hs)
{
	irqflags_t flags = cpu_irq_save();
	RequestState* r = freeTransactions;
	if (r == NULL)
	{
		cpu_irq_restore(flags);
		reprap.GetPlatform()->Message(HOST_MESSAGE, "Network::ReceiveInput() - no free transactions!\n");
		return;
	}

	freeTransactions = r->next;
	cpu_irq_restore(flags);

	r->Set(pb, hs);
	AppendTransaction(&readyTransactions, r);
//	debugPrintf("Network - input received\n");
}
示例#8
0
// Send the output data we already have, optionally with a file appended, then close the connection unless keepConnectionOpen is true.
// The file may be too large for our buffer, so we may have to send it in multiple transactions.
void Network::SendAndClose(FileStore *f, bool keepConnectionOpen)
{
	NetworkTransaction *r = readyTransactions;
	if (r == NULL)
	{
		return;
	}

	if (r->status == dataSending)
	{
		// This transaction is already in use for sending (e.g. a Telnet request),
		// so all we have to do is to remove it from readyTransactions.
		readyTransactions = r->next;
	}
	else
	{
		readyTransactions = r->next;

		if (r->LostConnection())
		{
			if (f != NULL)
			{
				f->Close();
			}
			while (r->sendBuffer != NULL)
			{
				r->sendBuffer = ReleaseSendBuffer(r->sendBuffer);
			}
			AppendTransaction(&freeTransactions, r);
//			debugPrintf("Conn lost before send\n");
		}
		else
		{
			r->FreePbuf();
			r->cs->persistConnection = keepConnectionOpen;
			r->fileBeingSent = f;
			r->status = dataSending;
			if (f != NULL && r->sendBuffer == NULL)
			{
				SendBuffer *buf;
				if (AllocateSendBuffer(buf))
				{
					r->sendBuffer = buf;
					r->fileBeingSent = f;
				}
				else
				{
					r->fileBeingSent = NULL;
//					debugPrintf("Could not allocate send buffer for file transfer!\n");
				}
			}

			NetworkTransaction *mySendingTransaction = r->cs->sendingTransaction;
			if (mySendingTransaction == NULL)
			{
				r->cs->sendingTransaction = r;
				AppendTransaction(&writingTransactions, r);
//debug
//				r->outputBuffer[r->outputPointer] = 0;
//				debugPrintf("Transaction queued for writing to network, file=%c, data=%s\n", (f ? 'Y' : 'N'), r->outputBuffer);
			}
			else
			{
				while (mySendingTransaction->nextWrite != NULL)
				{
					mySendingTransaction = mySendingTransaction->nextWrite;
				}
				mySendingTransaction->nextWrite = r;
//				debugPrintf("Transaction appended to sending RS\n");
			}
		}
	}
}
示例#9
0
void Network::Spin()
{
	// Basically we can't do anything if we can't interact with LWIP

	if (!LockLWIP())
	{
		platform->ClassReport(longWait);
		return;
	}

	if (state == NetworkActive)
	{
		// See if we can read any packets

		if (readingData)
		{
			readingData = false;

			do {
				// read all queued packets from the RX buffer
			} while (ethernet_read());

			ethernet_set_rx_callback(&emac_read_packet);
		}

		// See if we can send anything

		NetworkTransaction *r = writingTransactions;
		if (r != NULL && r->Send())
		{
			// We're done, free up this transaction

			ConnectionState *cs = r->cs;
			NetworkTransaction *rn = r->nextWrite;
			writingTransactions = r->next;
			AppendTransaction(&freeTransactions, r);

			// If there is more data to write on this connection, do it next time

			if (cs != NULL)
			{
				cs->sendingTransaction = rn;
			}
			if (rn != NULL)
			{
				PrependTransaction(&writingTransactions, rn);
			}
		}
	}
	else if (state == NetworkInitializing && establish_ethernet_link())
	{
		start_ethernet(platform->IPAddress(), platform->NetMask(), platform->GateWay());
		ethernet_set_rx_callback(&emac_read_packet);


		httpd_init();
		ftpd_init();
		telnetd_init();

		netbios_init();
		state = NetworkActive;
	}

	UnlockLWIP();
	platform->ClassReport(longWait);
}