void HardwareSerialX::end() { // wait for transmission of outgoing data while ( ! ring_isempty( _tx_buffer ) ) ; cbi(*_ucsrb, _rxen); cbi(*_ucsrb, _txen); cbi(*_ucsrb, _rxcie); cbi(*_ucsrb, _udrie); // clear any received data ring_clear( _rx_buffer ); }
int8_t GSwifi::parseRequestLine (char *token, uint8_t token_size) { uint8_t i; for ( i = 0; i <= token_size; i++ ) { if (ring_isempty( _buf_cmd )) { return -1; // space didn't appear } ring_get( _buf_cmd, token+i, 1 ); if (token[i] == ' ') { token[i] = '\0'; break; } } if ( i == token_size + 1 ) { return -1; // couldnt detect token } return 0; }
int HardwareSerialX::read(void) { // if the head isn't ahead of the tail, we don't have any characters if (ring_isempty( _rx_buffer )) { return -1; } else { char c; ring_get( _rx_buffer, &c, 1 ); if (is_limiting && ring_used(_rx_buffer) < XONOFF_HYSTERESIS) { send_xon = true; is_limiting = false; sbi(UCSR1B, UDRIE1); } return c; } }
int main() { ok( 1, "ok" ); { struct RingBuffer buf_; struct RingBuffer *buf = &buf_; char data[65]; ring_init( buf, data, 65 ); ok( ring_used(buf) == 0, "0 used" ); ok( ring_isempty(buf) == 1, "is empty" ); ring_put(buf, 'a'); ok( ring_used(buf) == 1, "1 used after put" ); ok( ring_isfull(buf) == 0, "not full" ); ok( ring_isempty(buf) == 0, "is empty" ); char buf2[64]; ring_get(buf, &buf2[0], 1); ok( buf2[0] == 'a', "get" ); ok( ring_used(buf) == 0, "0 used after get" ); ok( ring_isfull(buf) == 0, "not full" ); ok( ring_isempty(buf) == 1, "is empty" ); ring_put(buf, 'b'); ring_clear(buf); ok( ring_used(buf) == 0, "0 used after clear" ); ok( ring_isfull(buf) == 0, "not full" ); ok( ring_isempty(buf) == 1, "is empty" ); ring_put(buf, '0'); ring_put(buf, '1'); ring_put(buf, '2'); ring_put(buf, '3'); ring_put(buf, '4'); ring_put(buf, '5'); ring_put(buf, '6'); ring_put(buf, '7'); ring_put(buf, '8'); ring_put(buf, '9'); ring_put(buf, 'a'); ring_put(buf, 'b'); ring_put(buf, 'c'); ring_put(buf, 'd'); ring_put(buf, 'e'); ring_put(buf, 'f'); ring_put(buf, '0'); ring_put(buf, '1'); ring_put(buf, '2'); ring_put(buf, '3'); ring_put(buf, '4'); ring_put(buf, '5'); ring_put(buf, '6'); ring_put(buf, '7'); ring_put(buf, '8'); ring_put(buf, '9'); ring_put(buf, 'a'); ring_put(buf, 'b'); ring_put(buf, 'c'); ring_put(buf, 'd'); ring_put(buf, 'e'); ring_put(buf, 'f'); ring_put(buf, '0'); ring_put(buf, '1'); ring_put(buf, '2'); ring_put(buf, '3'); ring_put(buf, '4'); ring_put(buf, '5'); ring_put(buf, '6'); ring_put(buf, '7'); ring_put(buf, '8'); ring_put(buf, '9'); ring_put(buf, 'a'); ring_put(buf, 'b'); ring_put(buf, 'c'); ring_put(buf, 'd'); ring_put(buf, 'e'); ring_put(buf, 'f'); ring_put(buf, '0'); ring_put(buf, '1'); ring_put(buf, '2'); ring_put(buf, '3'); ring_put(buf, '4'); ring_put(buf, '5'); ring_put(buf, '6'); ring_put(buf, '7'); ring_put(buf, '8'); ring_put(buf, '9'); ring_put(buf, 'a'); ring_put(buf, 'b'); ring_put(buf, 'c'); ring_put(buf, 'd'); ring_put(buf, 'e'); ring_put(buf, 'f'); ok( ring_used(buf) == 64, "64 used after 64 puts" ); ok( ring_isfull(buf) == 1, "is full" ); ok( ring_isempty(buf) == 0, "is empty" ); // dropped feature to protect buffer from overflow // ok( ring_put(buf, 'x') == -1, "can't put into full" ); uint8_t fetched = ring_get(buf, &buf2[0], 64); ok( buf2[0] == '0', "get 1" ); ok( buf2[1] == '1', "get 2" ); ok( buf2[2] == '2', "get 3" ); ok( buf2[3] == '3', "get 4" ); ok( fetched == 64, "fetched all" ); ok( ring_used(buf) == 0, "0 used after all get" ); ok( ring_isfull(buf) == 0, "not full again" ); ok( ring_isempty(buf) == 1, "is empty" ); } done_testing(); }
int ring_ops(char *bfr,int bytes,enum ringbfract_t action,struct ringset *ring) { /* * Does ring buffer management. Actions can include * RING_ALLOC, RING_DEALLOC, RING_INIT, RING_STORE, RING_RETR, RING_ISMT, * RING_ISFULL, RING_ELEMENTS_FREE, RING_ELEMENTS_STORED,RING_VIEW, RING_DELETE * RING_ALLOC uses bytes to indicate the nuber of bytes to be stored in the ring. * The buffer will be allocated to one more than this * RING_DEALLOC deallocates the ring buffer * RING_STORE, RING_VIEW, and RING_RETR both use the *bfr and bytes. Others do not and * they can be set to zero. * RING_ISMT and RING_ISFULL, return 1 if true, 0 otherwise. * RING_RETR, RING_VIEW, and RING_STORE return -1 if the requested number of bytes is invalid * RING_ELEMENTS_FREE and RING_ELEMENTS_STORED return the number of bytes free and stored, repsectively. * * This should be called with the appropriate struct ringset *ring pointer to point to * data from the appropriate thread. */ int partial; switch (action) { case RING_ALLOC: // Allocate memory for the ring ring->ring = (char *)malloc(bytes+1); if(ring->ring == NULL) fail("ring_ops: Failed to allocate memory for ring buffer\n"); ring->bfrsize = bytes + 1; ring->readptr = ring->writeptr = 0; writelog(2,"ring_ops: Successfully allocated ring buffer to hold %d bytes\n",bytes); break; case RING_DEALLOC: // Free the buffer writelog(2,"ring_ops: De-allocating ring buffer of %d bytes\n",ring->bfrsize); free(ring->ring); break; case RING_INIT: // Initialize writelog(5,"ring_ops: Initializing ring buffer of %d bytes\n",ring->bfrsize); ring->readptr = ring->writeptr = 0; break; case RING_STORE: // Store bytes from bfr to ring if(bytes > ring_bytes_free(ring)) { return -1; } else { // Copy in two parts if it will wrap. partial = ring->bfrsize - ring->writeptr; if(bytes > partial) { memcpy(&ring->ring[ring->writeptr],bfr,partial); memcpy(ring->ring,&bfr[partial],bytes - partial); } else { memcpy(&ring->ring[ring->writeptr],bfr,bytes); } ring->writeptr = ring_normalize(ring->writeptr + bytes,ring); writelog(7,"ring_ops: Stored %d bytes into ring. new readptr: %d new writeptr: %d. " "Ring now contains %d bytes\n", bytes, ring->readptr,ring->writeptr, ring_bytes_stored(ring)); } break; case RING_RETR: // Retrieve bytes from the ring to bfr case RING_VIEW: // Retrieve but don't update the ring->readptr pointer if((bytes > 0) && (bytes > ring_bytes_stored(ring))) { return -1; } else { partial = ring->bfrsize - ring->readptr; if(bytes > partial) { // Copy in two parts if it will wrap memcpy(bfr,&(ring->ring[ring->readptr]),partial); memcpy(&bfr[partial],ring->ring,bytes - partial); } else { memcpy(bfr,&(ring->ring[ring->readptr]),bytes); } // Update the readptring pointer if action == retrieve if(action == RING_RETR) { ring->readptr = ring_normalize(ring->readptr + bytes,ring); writelog(7,"ring_ops: Retrieved %d bytes from ring. new readptr: %d new writeptr: %d. " "Ring now contains %d bytes\n", bytes, ring->readptr,ring->writeptr,ring_bytes_stored(ring)); } } break; case RING_DELETE: // Delete the given number of bytes from the readptr of the ring (update the ring->readptr). // If bytes is out of range, do nothing but return -1. if((bytes > 0) && (bytes <= ring_bytes_stored(ring))) { ring->readptr = ring_normalize(ring->readptr + bytes,ring); writelog(7,"ring_ops: Deleted %d bytes from ring. new readptr: %d new writeptr: %d. " "Ring now contains %d bytes\n", bytes, ring->readptr,ring->writeptr,ring_bytes_stored(ring)); } else { return -1; } break; case RING_ISMT: // Is empty? return ring_isempty(ring); break; case RING_ISFULL: // Is full? return ring_isfull(ring); break; case RING_ELEMENTS_FREE: // REturns the number of free bytes return ring_bytes_free(ring); break; case RING_ELEMENTS_STORED: // REturns the number of bytes currently stored. return ring_bytes_stored(ring); break; default: fail("ring_ops: Illegal action passed to ring_ops: %d\n",action); break; } return 0; }
int HardwareSerialX::available(void) { return ! ring_isempty( _rx_buffer ); }
void GSwifi::parseLine () { static char buf[GS_CMD_SIZE]; while (! ring_isempty(_buf_cmd)) { // received "\n" uint8_t i = 0; while ( (! ring_isempty(_buf_cmd)) && (i < sizeof(buf) - 1) ) { ring_get( _buf_cmd, &buf[i], 1 ); if (buf[i] == '\n') { break; } i ++; } if (i == 0) continue; buf[i] = 0; if ( (gs_mode_ == GSMODE_COMMAND) && (gs_commandmode_ != GSCOMMANDMODE_NONE) ) { parseCmdResponse(buf); } if (strncmp(buf, P("CONNECT "), 8) == 0 && buf[8] >= '0' && buf[8] <= 'F' && buf[9] != 0) { // connect from client // CONNECT 0 1 192.168.2.1 63632 // 1st cid is our http server's // 2nd cid is for client // next line will be "[ESC]Z10140GET / ..." int8_t cid = x2i(buf[10]); // 2nd cid = HTTP client cid ASSERT((0 <= cid) && (cid <= 16)); setCidIsRequest(cid, true); content_lengths_[ cid ] = 0; // don't close other connections, // other connections close theirselves on their turn // ignore client's IP and port } else if (strncmp(buf, P("DISCONNECT "), 11) == 0) { int8_t cid = x2i(buf[11]); ASSERT((0 <= cid) && (cid <= 16)); if (cid == server_cid_) { // if it's our server, this is fatal reset(); } else if (! cidIsRequest(cid) ) { // request *from* us was disconnected (ex: polling) dispatchResponseHandler(cid, HTTP_STATUSCODE_DISCONNECT, GSREQUESTSTATE_ERROR); } } else if (strncmp(buf, P("DISASSOCIATED"), 13) == 0 || strncmp(buf, P("Disassociat"), 11) == 0) { // Disassociated // Disassociation Event clear(); on_disconnect_(); gs_failure_ = true; } else if (strncmp(buf, P("APP Reset"), 9) == 0 || strncmp(buf, P("Serial2WiFi APP"), 15) == 0) { // APP Reset-APP SW Reset // APP Reset-Wlan Except // Serial2Wifi APP on_reset_(); gs_failure_ = true; } // else if (strncmp(buf, P("Out of StandBy-Timer"), 20) == 0 || // strncmp(buf, P("Out of StandBy-Alarm"), 20) == 0) { // } // else if (strncmp(buf, P("Out of Deep Sleep"), 17) == 0 ) { // } } }
bool GSwifi::bufferEmpty() { return ring_isempty(_buf_cmd); }