END_TEST /* Verify pbuf_put_at()/pbuf_get_at() when using * offsets equal to beginning of new pbuf in chain */ START_TEST(test_pbuf_get_put_at_edge) { u8_t *out; u8_t testdata = 0x01; u8_t getdata; struct pbuf *p = pbuf_alloc(PBUF_RAW, 1024, PBUF_POOL); struct pbuf *q = p->next; LWIP_UNUSED_ARG(_i); /* alloc big enough to get a chain of pbufs */ fail_if(p->tot_len == p->len); memset(p->payload, 0, p->len); memset(q->payload, 0, q->len); /* put byte at the beginning of second pbuf */ pbuf_put_at(p, p->len, testdata); out = (u8_t*)q->payload; fail_unless(*out == testdata, "Bad data at pos %d, was %02X, expected %02X", p->len, *out, testdata); getdata = pbuf_get_at(p, p->len); fail_unless(*out == getdata, "pbuf_get_at() returned bad data at pos %d, was %02X, expected %02X", p->len, getdata, *out); }
/** Parse pbuf to see if it contains a fully received answer. * If one is found, ERR_OK is returned. * If none is found, ERR_VAL is returned. * * A fully received answer is a 3-digit number followed by a space, * some string and a CRLF as line ending. * * @param s smtp session struct */ static err_t smtp_is_response_finished(struct smtp_session *s) { u8_t sp; u16_t crlf; u16_t offset; if (s->p == NULL) { return ERR_VAL; } offset = 0; again: /* We could check the response number here, but we trust the * protocol definition which says the client can rely on it being * the same on every line. */ /* find CRLF */ crlf = pbuf_memfind(s->p, SMTP_CRLF, SMTP_CRLF_LEN, offset + 4); if (crlf == 0xFFFF) { /* no CRLF found */ return ERR_VAL; } sp = pbuf_get_at(s->p, offset + 3); if (sp == '-') { /* no space after response code -> try next line */ offset = crlf + 2; goto again; } else if (sp == ' ') { /* CRLF found after response code + space -> valid response */ return ERR_OK; } /* sp contains invalid character */ return ERR_VAL; }
void NtpClient::onReceive(pbuf *buf, IPAddress remoteIP, uint16_t remotePort) { // We do some basic check to see if it really is a ntp packet we receive. // NTP version should be set to same as we used to send, NTP_VERSION // Mode should be set to NTP_MODE_SERVER if (onCompleted != NULL) { uint8_t versionMode = pbuf_get_at(buf, 0); uint8_t ver = (versionMode & 0b00111000) >> 3; uint8_t mode = (versionMode & 0x07); if (mode == NTP_MODE_SERVER && ver == NTP_VERSION) { //Most likely a correct NTP packet received. uint8_t data[4]; pbuf_copy_partial(buf, data, 4, 40); // Copy only timestamp. uint32_t timestamp = (data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]); // Unix time starts on Jan 1 1970, subtract 70 years: uint32_t epoch = timestamp - 0x83AA7E80; this->onCompleted(*this, epoch); } }
void NtpClient::onReceive(pbuf *buf, IPAddress remoteIP, uint16_t remotePort) { // We do some basic check to see if it really is a ntp packet we receive. // NTP version should be set to same as we used to send, NTP_VERSION // NTP_VERSION 3 has time in same location so accept that too // Mode should be set to NTP_MODE_SERVER uint8_t versionMode = pbuf_get_at(buf, 0); uint8_t ver = (versionMode & 0b00111000) >> 3; uint8_t mode = (versionMode & 0x07); if (mode == NTP_MODE_SERVER && (ver == NTP_VERSION || ver == (NTP_VERSION -1))) { //Most likely a correct NTP packet received. uint8_t data[4]; pbuf_copy_partial(buf, data, 4, 40); // Copy only timestamp. uint32_t timestamp = (data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]); // Unix time starts on Jan 1 1970, subtract 70 years: uint32_t epoch = timestamp - 0x83AA7E80; if (autoUpdateSystemClock) { SystemClock.setTime(epoch, eTZ_UTC); // update systemclock utc value } if (delegateCompleted) { this->delegateCompleted(*this, epoch); } } }
/** Parse http header response line 1 */ static err_t http_parse_response_status(struct pbuf *p, u16_t *http_version, u16_t *http_status, u16_t *http_status_str_offset) { u16_t end1 = pbuf_memfind(p, "\r\n", 2, 0); if (end1 != 0xFFFF) { /* get parts of first line */ u16_t space1, space2; space1 = pbuf_memfind(p, " ", 1, 0); if (space1 != 0xFFFF) { if ((pbuf_memcmp(p, 0, "HTTP/", 5) == 0) && (pbuf_get_at(p, 6) == '.')) { char status_num[10]; size_t status_num_len; /* parse http version */ u16_t version = pbuf_get_at(p, 5) - '0'; version <<= 8; version |= pbuf_get_at(p, 7) - '0'; *http_version = version; /* parse http status number */ space2 = pbuf_memfind(p, " ", 1, space1 + 1); if (space2 != 0xFFFF) { *http_status_str_offset = space2 + 1; status_num_len = space2 - space1 - 1; } else { status_num_len = end1 - space1 - 1; } memset(status_num, 0, sizeof(status_num)); if (pbuf_copy_partial(p, status_num, (u16_t)status_num_len, space1 + 1) == status_num_len) { int status = atoi(status_num); if ((status > 0) && (status <= 0xFFFF)) { *http_status = (u16_t)status; return ERR_OK; } } } } } return ERR_VAL; }