EXPORT_DEF int at_read_result_iov (const char * dev, int * read_result, struct ringbuffer* rb, struct iovec iov[2]) { int iovcnt = 0; int res; size_t s; s = rb_used (rb); if (s > 0) { /* ast_debug (5, "[%s] d_read_result %d len %d input [%.*s]\n", dev, *read_result, s, MIN(s, rb->size - rb->read), (char*)rb->buffer + rb->read); */ if (*read_result == 0) { res = rb_memcmp (rb, "\r\n", 2); if (res == 0) { rb_read_upd (rb, 2); *read_result = 1; return at_read_result_iov (dev, read_result, rb, iov); } else if (res > 0) { if (rb_memcmp (rb, "\n", 1) == 0) { ast_debug (5, "[%s] multiline response\n", dev); rb_read_upd (rb, 1); return at_read_result_iov (dev, read_result, rb, iov); } if (rb_read_until_char_iov (rb, iov, '\r') > 0) { s = iov[0].iov_len + iov[1].iov_len + 1; } rb_read_upd (rb, s); return at_read_result_iov (dev, read_result, rb, iov); } return 0; } else { if (rb_memcmp (rb, "+CSSI:", 6) == 0) { iovcnt = rb_read_n_iov (rb, iov, 8); if (iovcnt > 0) { *read_result = 0; } return iovcnt; } else if (rb_memcmp (rb, "\r\n+CSSU:", 8) == 0 || rb_memcmp (rb, "\r\n+CMS ERROR:", 13) == 0 || rb_memcmp (rb, "\r\n+CMGS:", 8) == 0) { rb_read_upd (rb, 2); return at_read_result_iov (dev, read_result, rb, iov); } else if (rb_memcmp (rb, "> ", 2) == 0) { *read_result = 0; return rb_read_n_iov (rb, iov, 2); } else if (rb_memcmp (rb, "+CMGR:", 6) == 0 || rb_memcmp (rb, "+CNUM:", 6) == 0 || rb_memcmp (rb, "ERROR+CNUM:", 11) == 0 || rb_memcmp (rb, "+CLCC:", 6) == 0) { iovcnt = rb_read_until_mem_iov (rb, iov, "\n\r\nOK\r\n", 7); if (iovcnt > 0) { *read_result = 0; } return iovcnt; } else { iovcnt = rb_read_until_mem_iov (rb, iov, "\r\n", 2); if (iovcnt > 0) { *read_result = 0; s = iov[0].iov_len + iov[1].iov_len + 1; return rb_read_n_iov (rb, iov, s); } } } } return 0; }
static int rb_read_until_mem_iov (ringbuffer_t* rb, struct iovec* iov, const void* mem, size_t len) { size_t i; void* p; if (len == 1) { return rb_read_until_char_iov (rb, iov, *((char*) mem)); } if (rb->used > 0 && len > 0 && rb->used >= len) { if ((rb->read + rb->used) > rb->size) { iov[0].iov_base = rb->buffer + rb->read; iov[0].iov_len = rb->size - rb->read; if (iov[0].iov_len >= len) { if ((p = memmem (iov[0].iov_base, iov[0].iov_len, mem, len)) != NULL) { iov[0].iov_len = p - iov[0].iov_base; iov[1].iov_len = 0; return 1; } i = 1; iov[1].iov_base = iov[0].iov_base + iov[0].iov_len - len + 1; } else { i = len - iov[0].iov_len; iov[1].iov_base = iov[0].iov_base; } while (i < len) { if (memcmp (iov[1].iov_base, mem, len - i) == 0 && memcmp (rb->buffer, mem + i, i) == 0) { iov[0].iov_len = iov[1].iov_base - iov[0].iov_base; iov[1].iov_len = 0; return 1; } if (rb->used == iov[0].iov_len + i) { return 0; } iov[1].iov_base++; i++; } if (rb->used >= iov[0].iov_len + len) { if ((p = memmem (rb->buffer, rb->used - iov[0].iov_len, mem, len)) != NULL) { if (p == rb->buffer) { iov[1].iov_len = 0; return 1; } iov[1].iov_base = rb->buffer; iov[1].iov_len = p - rb->buffer; return 2; } } } else { iov[0].iov_base = rb->buffer + rb->read; iov[0].iov_len = rb->used; if ((p = memmem (iov[0].iov_base, iov[0].iov_len, mem, len)) != NULL) { iov[0].iov_len = p - iov[0].iov_base; iov[1].iov_len = 0; return 1; } } } return 0; }