Exemplo n.º 1
0
static void ServeFile(FILE * stream_file, const char * fname, SdFile & theFile, EthernetClient & client)
{
	freeMemory();
	const char * ext;
	for (ext=fname + strlen(fname); ext>fname; ext--)
		if (*ext == '.')
		{
			ext++;
			break;
		}
	if (ext > fname)
	{
		if (strcmp(ext, "jpg") == 0)
			ServeHeader(stream_file, 200, "OK", true, "image/jpeg");
		else if (strcmp(ext, "gif") == 0)
			ServeHeader(stream_file, 200, "OK", true, "image/gif");
		else if (strcmp(ext, "css") == 0)
			ServeHeader(stream_file, 200, "OK", true, "text/css");
		else if (strcmp(ext, "js") == 0)
			ServeHeader(stream_file, 200, "OK", true, "application/javascript");
		else if (strcmp(ext, "ico") == 0)
			ServeHeader(stream_file, 200, "OK", true, "image/x-icon");
		else
			ServeHeader(stream_file, 200, "OK", true);
	}
	else
		ServeHeader(stream_file, 200, "OK", true);


#ifdef ARDUINO
	flush_sendbuf(client);
#else
	fflush(stream_file);
#endif
	while (theFile.available())
	{
		int bytes = theFile.read(sendbuf, 512);
		if (bytes <= 0)
			break;
		client.write((uint8_t*) sendbuf, bytes);
	}
}
Exemplo n.º 2
0
void web::ProcessWebClients()
{
	// listen for incoming clients
	EthernetClient client = m_server->available();
	if (client)
	{
		bool bReset = false;
#ifdef ARDUINO
		FILE stream_file;
		FILE * pFile = &stream_file;
		setup_sendbuf();
		fdev_setup_stream(pFile, stream_putchar, NULL, _FDEV_SETUP_WRITE);
		stream_file.udata = &client;
#else
		FILE * pFile = fdopen(client.GetSocket(), "w");
#endif
		freeMemory();
		trace(F("Got a client\n"));
		//ShowSockStatus();
		KVPairs key_value_pairs;
		char sPage[35];

		if (!ParseHTTPHeader(client, &key_value_pairs, sPage, sizeof(sPage)))
		{
			trace(F("ERROR!\n"));
			ServeError(pFile);
		}
		else
		{

			trace(F("Page:%s\n"), sPage);
			//ShowSockStatus();

			if (strcmp(sPage, "bin/setSched") == 0)
			{
				if (SetSchedule(key_value_pairs))
				{
					if (GetRunSchedules())
						ReloadEvents();
					ServeHeader(pFile, 200, "OK", false);
				}
				else
					ServeError(pFile);
			}
			else if (strcmp(sPage, "bin/setZones") == 0)
			{
				if (SetZones(key_value_pairs))
				{
					ReloadEvents();
					ServeHeader(pFile, 200, "OK", false);
				}
				else
					ServeError(pFile);
			}
			else if (strcmp(sPage, "bin/delSched") == 0)
			{
				if (DeleteSchedule(key_value_pairs))
				{
					if (GetRunSchedules())
						ReloadEvents();
					ServeHeader(pFile, 200, "OK", false);
				}
				else
					ServeError(pFile);
			}
			else if (strcmp(sPage, "bin/setQSched") == 0)
			{
				if (SetQSched(key_value_pairs))
				{
					ServeHeader(pFile, 200, "OK", false);
				}
				else
					ServeError(pFile);
			}
			else if (strcmp(sPage, "bin/settings") == 0)
			{
				if (SetSettings(key_value_pairs))
				{
					ReloadEvents();
					ServeHeader(pFile, 200, "OK", false);
				}
				else
					ServeError(pFile);
			}
			else if (strcmp(sPage, "bin/manual") == 0)
			{
				if (ManualZone(key_value_pairs))
				{
					ServeHeader(pFile, 200, "OK", false);
				}
				else
					ServeError(pFile);
			}
			else if (strcmp(sPage, "bin/run") == 0)
			{
				if (RunSchedules(key_value_pairs))
				{
					ReloadEvents();
					ServeHeader(pFile, 200, "OK", false);
				}
				else
					ServeError(pFile);
			}
			else if (strcmp(sPage, "bin/factory") == 0)
			{
				ResetEEPROM();
				ReloadEvents();
				ServeHeader(pFile, 200, "OK", false);
			}
			else if (strcmp(sPage, "bin/reset") == 0)
			{
				ServeHeader(pFile, 200, "OK", false);
				bReset = true;
			}
			else if (strcmp(sPage, "json/schedules") == 0)
			{
				JSONSchedules(key_value_pairs, pFile);
			}
			else if (strcmp(sPage, "json/zones") == 0)
			{
				JSONZones(key_value_pairs, pFile);
			}
			else if (strcmp(sPage, "json/settings") == 0)
			{
				JSONSettings(key_value_pairs, pFile);
			}
			else if (strcmp(sPage, "json/state") == 0)
			{
				JSONState(key_value_pairs, pFile);
			}
			else if (strcmp(sPage, "json/schedule") == 0)
			{
				JSONSchedule(key_value_pairs, pFile);
			}
			else if (strcmp(sPage, "json/wcheck") == 0)
			{
				JSONwCheck(key_value_pairs, pFile);
			}
#ifdef LOGGING
			else if (strcmp(sPage, "json/logs") == 0)
			{
				JSONLogs(key_value_pairs, pFile);
			}
			else if (strcmp(sPage, "json/tlogs") == 0)
			{
				JSONtLogs(key_value_pairs, pFile);
			}
#endif
			else if (strcmp(sPage, "ShowSched") == 0)
			{
				freeMemory();
				ServeSchedPage(pFile);
			}
			else if (strcmp(sPage, "ShowZones") == 0)
			{
				freeMemory();
				ServeZonesPage(pFile);
			}
			else if (strcmp(sPage, "ShowEvent") == 0)
			{
				ServeEventPage(pFile);
			}
			else if (strcmp(sPage, "ReloadEvent") == 0)
			{
				ReloadEvents(true);
				ServeEventPage(pFile);
			}
			else
			{
				if (strlen(sPage) == 0)
					strcpy(sPage, "index.htm");
				// prepend path
				memmove(sPage + 5, sPage, sizeof(sPage) - 5);
				memcpy(sPage, "/web/", 5);
				sPage[sizeof(sPage)-1] = 0;
				trace(F("Serving Page: %s\n"), sPage);
				SdFile theFile;
				if (!theFile.open(sPage, O_READ))
					Serve404(pFile);
				else
				{
					if (theFile.isFile())
						ServeFile(pFile, sPage, theFile, client);
					else
						Serve404(pFile);
					theFile.close();
				}
			}
		}

#ifdef ARDUINO
		flush_sendbuf(client);
		// give the web browser time to receive the data
		delay(1);
#else
		fflush(pFile);
		fclose(pFile);
#endif
		// close the connection:
		client.stop();

		if (bReset)
			sysreset();
	}
}
Exemplo n.º 3
0
        //  Main routine of the worker thread
        void do_work ()
        {
            //  Initialise structures needed for polling
            pollfd pfd [2];
            pfd [0].fd = command_pipe;
            pfd [0].events = POLLIN;
            pfd [1].fd = sock;
            pfd [1].events = 0;

            bool stopping = false;
            bool pollin = true;
            bool pollout = xmode_blocked;

            //  Main loop of the worker thread
            while (true) {

                //  If the worker thread was requested to stop and there are
                //  no more data to send, exit the main loop.
                if (stopping && !pollout)
                    break;

                //  Adjust the poll events according to 'pollin' and 'pollout'
                //  variables, start the polling and check the results
                //  for errors.
                pfd [1].events =
                    (pollin ? POLLIN : 0) | (pollout ? POLLOUT : 0);
                int rc = poll (pfd, 2, -1);
                errno_assert (rc != -1);
                assert ((pfd [0].revents &
                    (POLLERR | POLLHUP | POLLNVAL)) == 0);
                assert ((pfd [1].revents & POLLNVAL) == 0);

                //  Command from client thread was received by the worker
                //  thread.
                if (pfd [0].revents & POLLIN) {
                    switch (command_pipe.read ()) {
                    case command_stop:

                        //  Worker thread is scheduled to terminate.
                        stopping = true;
                        break;

                    case command_resurrect:

                        //  Worker thread starts polling for write availability
                        //  of the socket after new data to send are available
                        //  in the send pipe.
                        pollout = true;
                        break;
                    }
                }

                //  Socket is available for reading
                if (pfd [1].revents & POLLIN) {

                    //  Allocate a memory chunk and read as much data as
                    //  possible. Only one chunk is read at once to cease the
                    //  control to writing part of the loop periodically even
                    //  if there is input on the socket all the time.
                    unsigned char *chunk =
                        (unsigned char*) malloc (ZMQ_RECV_CHUNK_SIZE);
                    assert (chunk);
                    ssize_t nbytes = recv (sock, chunk, ZMQ_RECV_CHUNK_SIZE, 0);
                    errno_assert (nbytes >= 0);

                    //  Enqueue empty chunk to let the client thread know that
                    //  the other party have closed the socket.
                    if (nbytes == 0) {
                        pollin = false;
                        free (chunk);
                        chunk = NULL;
                    }

                    //  Push the chunk to the receiver pipe. If the pipe was
                    //  dead, post the semaphore to unblock client thread
                    //  that is waiting for a message.
                    msg_t ch = {chunk, nbytes, 0, free};
                    if (!receive_pipe.write (ch))
                        receive_sync.post ();

                    //  If batch mode is set by user and the received
                    //  chunk is too small, wait for a while to improve the
                    //  batching ratio. NB: This code needs a careful 
                    //  reconsideration in the future releases. (See
                    //  nanosleep documentation for description of lack of
                    //  precision of this function on Linux.)
                    if (xmode_blocked && nbytes < ZMQ_RECV_CHUNK_SIZE / 2) {
                        timespec tmspc = {0, 10000};
                        int rc = nanosleep (&tmspc, NULL);
                        errno_assert (rc == 0);
                    }
                }

                //  Socket is available for writing
                if (pfd [1].revents & POLLOUT) {

                    //  Flush the data remaining in the sendbuf to the socket.
                    //  If successful, get new data from send pipe to send
                    //  buffer. If none are available, stop polling for writing
                    //  availability of the socket. If there are data, try to
                    //  flush them to the socket and cease the control to other
                    //  tasks.
                    if (flush_sendbuf ()) {
                        if (!send_pipe.read (&sendbuf_first, &sendbuf_last)) {
                            pollout = false;
                        }
                        else
                            flush_sendbuf ();
                    }
                }
            }
        }