162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci#include <string.h>
362306a36Sopenharmony_ci#include "slip_common.h"
462306a36Sopenharmony_ci#include <net_user.h>
562306a36Sopenharmony_ci
662306a36Sopenharmony_ciint slip_proto_read(int fd, void *buf, int len, struct slip_proto *slip)
762306a36Sopenharmony_ci{
862306a36Sopenharmony_ci	int i, n, size, start;
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci	if(slip->more > 0){
1162306a36Sopenharmony_ci		i = 0;
1262306a36Sopenharmony_ci		while(i < slip->more){
1362306a36Sopenharmony_ci			size = slip_unesc(slip->ibuf[i++], slip->ibuf,
1462306a36Sopenharmony_ci					  &slip->pos, &slip->esc);
1562306a36Sopenharmony_ci			if(size){
1662306a36Sopenharmony_ci				memcpy(buf, slip->ibuf, size);
1762306a36Sopenharmony_ci				memmove(slip->ibuf, &slip->ibuf[i],
1862306a36Sopenharmony_ci					slip->more - i);
1962306a36Sopenharmony_ci				slip->more = slip->more - i;
2062306a36Sopenharmony_ci				return size;
2162306a36Sopenharmony_ci			}
2262306a36Sopenharmony_ci		}
2362306a36Sopenharmony_ci		slip->more = 0;
2462306a36Sopenharmony_ci	}
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci	n = net_read(fd, &slip->ibuf[slip->pos],
2762306a36Sopenharmony_ci		     sizeof(slip->ibuf) - slip->pos);
2862306a36Sopenharmony_ci	if(n <= 0)
2962306a36Sopenharmony_ci		return n;
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci	start = slip->pos;
3262306a36Sopenharmony_ci	for(i = 0; i < n; i++){
3362306a36Sopenharmony_ci		size = slip_unesc(slip->ibuf[start + i], slip->ibuf,&slip->pos,
3462306a36Sopenharmony_ci				  &slip->esc);
3562306a36Sopenharmony_ci		if(size){
3662306a36Sopenharmony_ci			memcpy(buf, slip->ibuf, size);
3762306a36Sopenharmony_ci			memmove(slip->ibuf, &slip->ibuf[start+i+1],
3862306a36Sopenharmony_ci				n - (i + 1));
3962306a36Sopenharmony_ci			slip->more = n - (i + 1);
4062306a36Sopenharmony_ci			return size;
4162306a36Sopenharmony_ci		}
4262306a36Sopenharmony_ci	}
4362306a36Sopenharmony_ci	return 0;
4462306a36Sopenharmony_ci}
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ciint slip_proto_write(int fd, void *buf, int len, struct slip_proto *slip)
4762306a36Sopenharmony_ci{
4862306a36Sopenharmony_ci	int actual, n;
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	actual = slip_esc(buf, slip->obuf, len);
5162306a36Sopenharmony_ci	n = net_write(fd, slip->obuf, actual);
5262306a36Sopenharmony_ci	if(n < 0)
5362306a36Sopenharmony_ci		return n;
5462306a36Sopenharmony_ci	else return len;
5562306a36Sopenharmony_ci}
56