Esempio n. 1
0
void WiFiSDCoopLib::_checkESPAvailableData(const int timeout, String * response, const byte responseType) {
	char IPDSteps = 0, c;
	unsigned char ipd;
	long int time;
	char  endResponse[10];
	byte endFlag = 0;
	byte endLength;
	byte endPos = 0;
	String route = "";
	switch (responseType) {
		case WiFiSDCoopLib_RESPONSE_GENERIC:
			strcpy(endResponse, "OK\r\n");
			endLength = 4;
			break;

		case WiFiSDCoopLib_RESPONSE_DATA:
			strcpy(endResponse, "SEND OK\r\n");
			endLength = 9;
			break;

		case WiFiSDCoopLib_RESPONSE_CIPSEND:
			strcpy(endResponse, "> ");
			endLength = 2;
			break;

		case WiFiSDCoopLib_RESPONSE_RESET:
			strcpy(endResponse, "ready\r\n");
			endLength = 7;
			break;
		
		case WiFiSDCoopLib_RESPONSE_NO:
		default:
			endLength = 0;
			break;
	}

	time = millis() + timeout;
	while (time > millis()) {
		while (_dev_available()) {

			// READING - IPD checks
			c = _dev_read(); // read the next character.
			if (IPDSteps == 0 && c != '+' && c != '\n' && c != '\r') {
				IPDSteps = 10;
			} 
			if (IPDSteps == 10 && (c == '\n' || c == '\r')) {
				IPDSteps = 0;
			}
			if (response != NULL) {
				response->concat(c);
			}

			// Check if new IPD
			switch (IPDSteps) {
				case 0:
					if (c == '+') {
						IPDSteps++;
					}
					break;

				case 1:
					if (c == 'I') {
						IPDSteps++;
					} else {
						IPDSteps = 0;
					}
					break;

				case 2:
					if (c == 'P') {
						IPDSteps++;
					} else {
						IPDSteps = 0;
					}
					break;

				case 3:
					if (c == 'D') {
						IPDSteps++;
					} else {
						IPDSteps = 0;
					}
					break;

				case 4:
					if (c == ',') {
						IPDSteps++;
						ipd = 0;
					} else {
						IPDSteps = 0;
					}
					break;

				case 5: // Reading IPD channel
					if (c == ',') {
						IPDSteps++;
					} else {
						ipd = ipd * 10 + c - 48;
					}
					break;

				case 6: // Length, ignored
					if (c == ':') {
						IPDSteps++;
					}
					break;

				case 7: // GET, post, etc
					if (c == ' ') {
						IPDSteps++;
					}
					break;

				case 8: // Route
					if (c == ' ') {
						IPDSteps++;
					} else {
						route += c;
					}
					break;
		
				case 9: // Ignore, request completed
				case 10: // Ignore, request completed
				default:
					break;
			}

			// Logic: If end string is reached endFlag is set. Then, decreases to wait some cycles, that should be without data. If data comes means that end is not valid (probably a string identical to end, but no the end itself.
			// Once arrives 1, and endPos remains 0 (no more data has come) it's a valid end.
			if(endLength > 0) {
				if (endPos == endLength - 1 && c == endResponse[endPos]) {
					endPos = 0;
					endFlag = 10;
				} else if (endPos < endLength - 1) {
					if (c == endResponse[endPos]) {
						endPos++;
					} else {
						endPos = 0;
						endFlag = 0;
					}
				} else {
					endPos = 0;
					endFlag = 0;
				}
				// if endPos becomes 0, check again to don't miss a end string start.
				if (endPos == 0 && c == endResponse[endPos]) {
					endPos++;
				}
			} // End request end checks


		}
		if (endFlag > 1) {
			endFlag--;
		}
		if (endLength > 0 && endFlag == 1 && endPos == 0) { // valid END
			return;
		}

		if (IPDSteps == 9) { // Request fond, check routes
			IPDStruct * last = IPDs;
			bool found = false;
			while (last != NULL) {
				if (last->mode == 4) {// 4 Default route
					found = true;
				} else if (strlen(last->route) <= route.length()) {
					switch (last->mode) {
						case 3:// 3 found in any position
							found = route.indexOf(last->route) >= 0;
							break;

						case 2:// 2 ends with
							found = route.endsWith(last->route);
							break;

						case 1:// 1 starts with
							found = route.startsWith(last->route);
							break;

						case 0:// 0 same string
						default:
							found = route.equals(last->route);
							break;
					}
				}
				if (found) {
					last->fp(route, ipd);
					_sendCloseIPD(ipd);
					return;
				}
				last = (IPDStruct *) last->next;
			}
			sendDataByIPD(ipd, F("404 - Not found"));
			_sendCloseIPD(ipd);
		} // IPD found, routes checks end	

	} // End timeout while
}
Esempio n. 2
0
static __inline size_t
_readbinary(void* a, size_t n, FILE* str)
{

/* reads in data from a stream into the caller's namespace
** using binary mode (assumes that n, the number of memory locations
** to be read, is positive) - returns the number of words read
**
** there is no difference in the way that fread reads a file in text
** mode or in binary mode when (BYTES_PER_WORD==1).
**
** any data that is in the I/O buffer is read first - if the fread
** request is not satisfied then either further data is read from
** the file directly into the caller's namespace (but only if the
** amount of data exceeds the size of the I/O buffer), or the buffer
** is refilled.
**
** note that some care is required because this procedure short-cuts
** the usual mechanisms.
**
** parameters:
**    a   - data is read into this array
**    n   - amount of data (still) needed (in memory units)
**    str - ptr to the FILE table for the stream
*/

  size_t buflen;    /* the size of the I/O buffer */

  int m;            /* how much data available (in memory units)      */
  int c = 0;        /* how much data has been read (in memory units)  */
  int r;            /* result from a read operation                   */
  int w;            /* number of memory units read                    */

  do
  {
    m = str->_Rend - str->_Next;
    if (m > 0) {

      /* there is data in the input buffer */

      if (m > n)
        m = n;      /* take what we want if there is more than we need */

      memcpy(((unsigned char *) a) + c,
              (unsigned char *) str->_Next,m);
      str->_Next += m;

      if (m == n)
        return c+n;

      /* still need data - there is an I/O buffer but it is empty */

      n -= m;       /* decrement the amount still needed */
      c += m;       /* increment the amount read so far  */
    }

    /* read some data (PS: there might be no I/O buffer) */

    buflen = (str->bufadr) ? (str->_Bend - str->bufadr) : BUFSIZ;
    if (n > buflen)
    {

      /* optimize - bypass buffer - read directly into array */

      r = _dev_read(str->fileID,((char *) a) + c,n * BYTES_PER_WORD);
      if (r < 0) {
          str->_Mode |= M_ERROR;
          return 0;
      }

      w = (r + (BYTES_PER_WORD - 1)) / BYTES_PER_WORD;
      if (n != w) {
        str->_Mode = (str->_Mode & ~M_LAST_READ) | M_EOF;
      } else {

#if (BYTES_PER_WORD != 1)

        unsigned char *const ptr = &((unsigned char *)a)[(r-1)/BYTES_PER_WORD];
        int                  rem = r & (BYTES_PER_WORD-1);

        if (rem != 0)
        {
          *ptr &= (UCHAR_MAX >> ((BYTES_PER_WORD - rem) * 8));
               // organize padding of last incomplete word
        }

#endif
      }
      return c + w;
    }