示例#1
0
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;
}