Пример #1
0
/**
 * @brief s_open - open a serial port
 *
 * @param t_port -port number
 *
 * @return success/fail
 */
signed char s_open(char *t_port)
{
	int x;
	char cmd[200];
	if (fd) {
		S_ERROR("Port is already open\n");
		return SERIAL_FAILED;
	}
	/* Check if serial port is used by other process */

	/* NOTE: it is a bad idea to use lsof, but the alternative
	 * is to write large amount of code..
	 */
	sprintf(cmd, "lsof |grep %s 2>&1 >/dev/null", t_port);
	x = system(cmd);
	if (x == 0) {
		S_ERROR("device %s being used already?\n", t_port);
		sprintf(cmd, "lsof |grep %s", t_port);
		system(cmd);
		return SERIAL_FAILED;
	}
	fd = open(t_port, O_RDWR | O_NOCTTY);
	if (fd < 0) {
		S_ERROR("failed to open %s\n", t_port);
		perror(t_port);
		return SERIAL_FAILED;
	}
	strncpy((char *)port, t_port, 30);
	S_INFO("Serial port %s opend fine\n", port);
	return SERIAL_OK;
}
Пример #2
0
/**
 * @brief Flush the serial port data
 *
 * @param rx_bytes return bytes that remains(TBD)
 * @param tx_bytes the bytes that are to be send(TBD)
 *
 * @return error/fail
 */
signed int s_flush(unsigned int *rx_bytes, unsigned int *tx_bytes)
{
	int ret;
	if (!fd) {
		S_ERROR("terminal is not open!\n");
		return SERIAL_FAILED;
	}
	ret = tcflush(fd, TCIFLUSH);
	if (ret < 0) {
		S_ERROR("failed to flush buffers2\n");
		return SERIAL_FAILED;
	}
	S_INFO("Serial port %s flushed fine\n", port);

	return SERIAL_OK;
}
Пример #3
0
/**
 * @brief s_read_remaining - get the remaining bytes (TBD)
 *
 * @return error or num bytes remaining
 */
signed int s_read_remaining(void)
{
	if (!fd) {
		S_ERROR("terminal is not open!\n");
		return SERIAL_FAILED;
	}
	/* Not implemented yet */
	return (0);
}
Пример #4
0
/**
 * @brief s_putc - put a character into serial port
 *
 * @param x - character to write
 *
 * @return character written or error
 */
signed int s_putc(char x)
{
	int ret = 0;
	S_INFO("[%c] 0x%02x", x, (unsigned char)x);
	ret = s_write((unsigned char *)&x, 1);
	if (ret < 0) {
		S_ERROR("putc failed-%d\n", ret);
		return ret;
	}
	return x;
}
Пример #5
0
/**
 * @brief s_read - serial port read
 *
 * @param p_buffer buffer
 * @param size buffer length
 *
 * @return bytes read if ok, else SERIAL_FAILED
 */
signed int s_read(unsigned char *p_buffer, unsigned long size)
{
	int ret = 0;
	if (!fd) {
		S_ERROR("terminal is not open!\n");
		return SERIAL_FAILED;
	}
	/* read entire chunk.. no giving up! */
	newtio.c_cc[VMIN] = size;
	newtio.c_cc[VTIME] = VTIME_SET;
	ret = tcsetattr(fd, TCSANOW, &newtio);
	ret = read(fd, p_buffer, size);
	if (ret < 0) {
		S_ERROR("failed to read data\n");
		return SERIAL_FAILED;
	}

	S_INFO("Serial read requested=%d, read=%d\n", size, ret);
	return ret;
}
Пример #6
0
/**
 * @brief s_getc - get a character from serial port
 *
 * @return character read or error
 */
signed int s_getc(void)
{
	unsigned char x = 0;
	int ret = 0;
	ret = s_read(&x, 1);
	if (ret < 0) {
		S_ERROR("getc failed-%d\n", ret);
		return ret;
	}
	S_INFO("[%c]%x", x, x);
	return x;
}
Пример #7
0
/**
 * @brief s_write - write to serial port
 *
 * @param p_buffer - buffer pointer
 * @param size -size of buffer
 *
 * @return bytes wrote if ok, else SERIAL_FAILED
 */
signed int s_write(unsigned char *p_buffer, unsigned long size)
{
	int ret = 0, ret1;
	if (!fd) {
		S_ERROR("terminal is not open!\n");
		return SERIAL_FAILED;
	}
	ret = write(fd, p_buffer, size);
	if (ret < 0) {
		S_ERROR("failed to write data\n");
		return SERIAL_FAILED;
	}
	/* Wait till it is emptied */
	ret1 = tcdrain(fd);
	if (ret1 < 0) {
		S_ERROR("failed in datai drain\n");
		perror(NULL);
		return ret1;
	}
	S_INFO("Serial wrote Requested=%ld wrote=%d\n", size, ret);
	return ret;
}
Пример #8
0
static size_t ss_utf8_to_wc(const char *s, const size_t off,
			    const size_t max_off, int *unicode_out,
			    ss_t *s_unicode_error_out)
{
	int encoding_errors = 0;
	const size_t csize = sc_utf8_to_wc(s, off, max_off, unicode_out,
							&encoding_errors);
	if (encoding_errors && s_unicode_error_out) {
		S_ERROR("broken UTF8");
		set_encoding_errors(s_unicode_error_out, S_TRUE);
	}
	return csize;
}
Пример #9
0
/**
 * @brief s_close - close the serial port
 *
 * @return sucess/fail
 */
signed char s_close(void)
{
	int ret = 0;
	if (!fd) {
		S_ERROR("terminal is not open!\n");
		return SERIAL_FAILED;
	}
	/*
	 * To prevent switching modes before the last vestiges
	 * of the data bits have been send, sleep a second.
	 * This seems to be especially true for usb2serial
	 * convertors.. it does look as if the data is buffered
	 * at the usb2serial device itself and closing/changing
	 * attribs before the final data is pushed is going to
	 * kill the last bits which need to be send
	 */
	sleep(1);
	/* restore the old port settings */
	ret = tcsetattr(fd, TCSANOW, &oldtio);
	if (ret < 0) {
		S_ERROR("failed to rest old settings\n");
		return SERIAL_FAILED;
	}
	ret = tcflush(fd, TCIFLUSH);
	if (ret < 0) {
		S_ERROR("failed to flush serial file handle\n");
	}
	ret = close(fd);
	fd = 0;
	if (ret < 0) {
		S_ERROR("failed to close serial file handle\n");
		return SERIAL_FAILED;
	}
	S_INFO("Serial closed %s fine\n", port);
	return SERIAL_OK;
}
Пример #10
0
/**
 * @brief s_configure - configure the serial port
 *
 * @param s_baud_rate -baudrate
 * @param s_parity -parity
 * @param s_stop_bits -num stop bits
 * @param s_data_bits -data bits
 *
 * @return -success/failure
 */
signed char s_configure(unsigned long s_baud_rate, unsigned char s_parity,
			unsigned char s_stop_bits, unsigned char s_data_bits)
{
	int ret;

	if (!fd) {
		S_ERROR("terminal is not open!\n");
		return SERIAL_FAILED;
	}
	/* save current port settings */
	ret = tcgetattr(fd, &oldtio);
	if (ret < 0) {
		S_ERROR("failed to set get old attribs\n");
		return SERIAL_FAILED;
	}

	/* get current settings, and modify as needed */
	ret = tcgetattr(fd, &newtio);
	if (ret < 0) {
		S_ERROR("failed to get current attribs\n");
		return SERIAL_FAILED;
	}

	switch (s_baud_rate) {
	case 57600:
		s_baud_rate = B57600;
		break;
	case 115200:
		s_baud_rate = B115200;
		break;
		/* Add other baudrates - see /usr/include/bits/termios.h */
	default:
		S_ERROR("Unknown baudrate %d\n", (unsigned int)s_baud_rate);
		return SERIAL_FAILED;
	}
	cfsetospeed(&newtio, s_baud_rate);
	cfsetispeed(&newtio, s_baud_rate);

	newtio.c_cflag &= ~(CS5 | CS6 | CS7 | CS8);
	switch (s_data_bits) {
	case 5:
		newtio.c_cflag |= CS5;
		break;
	case 6:
		newtio.c_cflag |= CS6;
		break;
	case 7:
		newtio.c_cflag |= CS7;
		break;
	case 8:
		newtio.c_cflag |= CS8;
		break;
	default:
		S_ERROR("unknown data bit %d\n", s_data_bits);
		return SERIAL_FAILED;
	}

	switch (s_stop_bits) {
	case ONE_STOP_BIT:
		newtio.c_cflag &= ~CSTOPB;
		break;
	case TWO_STOP_BIT:
		newtio.c_cflag |= CSTOPB;
		break;
	default:
		S_ERROR("unknown stop bit %d\n", s_stop_bits);
		return SERIAL_FAILED;
	}

	newtio.c_cflag &= ~(PARENB | PARODD);
	newtio.c_iflag &= ~(IGNPAR);
	switch (s_parity) {
	case ODDPARITY:	/* odd */
		newtio.c_cflag |= PARENB | PARODD;
		newtio.c_iflag |= IGNPAR;
		break;
	case EVENPARITY:	/* even */
		newtio.c_cflag |= PARENB;
		newtio.c_iflag = 0;
		break;
	case NOPARITY:		/* none */
		break;
	default:
		S_ERROR("unknown parity %d", s_parity);
		return SERIAL_FAILED;
	}

	newtio.c_iflag |= IGNBRK;
	newtio.c_cflag |= CLOCAL | CREAD;

	S_INFO("c_cflag: 0x%08x\n", (unsigned int)(newtio.c_cflag));

	newtio.c_oflag = 0;
	/* set input mode (non-canonical, no echo,...) */
	newtio.c_lflag = 0;
	newtio.c_cc[VTIME] = VTIME_SET;
	newtio.c_cc[VMIN] = 1;
	newtio.c_cc[VSWTC] = 0;
	ret = tcflush(fd, TCIFLUSH);
	if (ret < 0) {
		S_ERROR("failed to set flush buffers\n");
		return SERIAL_FAILED;
	}
	ret = tcsetattr(fd, TCSANOW, &newtio);
	if (ret < 0) {
		S_INFO("tcsetattr -> %s (%d) fd=%d", strerror(errno), ret, fd);
		S_ERROR("failed to set new attribs\n");
		return SERIAL_FAILED;
	}
	S_INFO("Serial port %s configured fine\n", port);
	return SERIAL_OK;
}
Пример #11
0
static ss_t *aux_replace(ss_t **s, const sbool_t cat, const ss_t *src,
			 const size_t off, const ss_t *s1, const ss_t *s2)
{
	ASSERT_RETURN_IF(!s, ss_void);
	if (!s1)
		s1 = ss_void;
	if (!s2)
		s2 = ss_void;
	if (!src)
		src = ss_void;
	const size_t at = (cat && *s) ? sd_get_size(*s) : 0;
	const char *p0 = get_str_r(src),
		   *p2 = get_str_r(s2);
	const size_t l1 = sd_get_size(s1), l2 = sd_get_size(s2);
	size_t i = off, l = sd_get_size(src);
	ss_t *out = NULL;
	ssize_t size_delta = l2 > l1 ? (ssize_t)(l2 - l1) :
				       -(ssize_t)(l1 - l2);
	sbool_t aliasing = S_FALSE;
	size_t out_size = at + l;
	char *o, *o0;
	if (l2 >= l1) { /* resize required */
		size_t nfound = 0;
		/* scan required size */
		for (;; i+= l1, nfound++)
			if ((i = ss_find(src, i, s1)) == S_NPOS)
				break;
		if (nfound == 0)	/* 0 occurrences: return */
			return ss_check(s);
		if (size_delta >= 0)
			out_size += (size_t)size_delta * nfound;
		else
			out_size -= (size_t)(-size_delta) * nfound;
		/* allocate output string */
		out = ss_alloc(out_size);
		if (!out) {
			S_ERROR("not enough memory");
			sd_set_alloc_errors(*s);
			return ss_check(s);
		}
		o0 = o = get_str(out);
		/* copy prefix data (cat) */
		if (at > 0)
			memcpy(o, get_str_r(*s), at);
	} else {
		if (s && *s && *s == src) {
			aliasing = S_TRUE;
		} else {
			if (ss_reserve(s, out_size) < out_size) /* BEHAVIOR */
				return ss_check(s);
		}
		o0 = o = get_str(*s);
	}
	typedef void (*memcpy_t)(void *, const void *, size_t);
	memcpy_t f_cpy;
	if (aliasing) {
		f_cpy = (memcpy_t)memmove;
	} else {
		f_cpy = (memcpy_t)memcpy;
		o += at;
		if (off > 0)	/* copy not affected data */
			memcpy(o, p0, off);
	}
	o += off;
	size_t i_next = s1 == s2? S_NPOS : /* no replace */
			ss_find(src, i + off, s1);
	for (i = off;;) {
		/* before match copy: */
		if (i_next == S_NPOS) {
			f_cpy(o, p0 + i, l - i);
			o += (l - i);
			break;
		}
		f_cpy(o, p0 + i, i_next - i);
		o += (i_next - i);
		/* replace: */
		f_cpy(o, p2, l2);
		o += l2;
		i = i_next + l1;
		/* prepare next search: */
		i_next = ss_find(src, i, s1);
	}
	if (out) {
		ss_t *s_bck = *s;
		*s = out;
		ss_free(&s_bck);
	}
	set_size(*s, (size_t)(o - o0));
	return *s;
}
Пример #12
0
static ss_t *aux_toXcase(ss_t **s, const sbool_t cat, const ss_t *src,
			 sint32_t (*towX)(sint32_t))
{
	ASSERT_RETURN_IF(!s, ss_void);
	if (!src)
		src = ss_void;
	const size_t ss = sd_get_size(src),
		     sso_max = *s ? ss_get_max_size(*s) : 0;
	const char *ps = get_str_r(src);
	ss_t *out = NULL;
	const sbool_t aliasing = *s == src;
	unsigned char is_cached_usize = 0;
	ssize_t extra = sc_utf8_calc_case_extra_size(ps, 0, ss, towX);
	size_t cached_usize = 0,
	       at;
	/* If possible, keep Unicode size cached: */
	if (*s) {
		if (is_unicode_size_cached(*s) && is_unicode_size_cached(src)) {
			is_cached_usize = 1;
			cached_usize = get_unicode_size(src) +
				       get_unicode_size(*s);
		}
		at = cat ? sd_get_size(*s) : 0;
	} else { /* copy */
		if (is_unicode_size_cached(src)) {
			is_cached_usize = 1;
			cached_usize = get_unicode_size(src);
		}
		at = 0;
	}
	/* Check if it is necessary to allocate more memory: */
	size_t sso_req = extra < 0 ? (at + ss - (size_t)(-extra)) :
				     (at + ss + (size_t)extra);
	char *po0;
	if (!*s || sso_req > sso_max || (aliasing && extra > 0)) {
		if (*s && (*s)->ext_buffer) { /* BEHAVIOR */
			S_ERROR("not enough memory: strings stored in the "
				"stored in fixed-length buffer can not be "
				"resized.");
			sd_set_alloc_errors(*s);
			return ss_check(s);
		}
		out = ss_alloc(sso_req);
		if (!out) {	/* BEHAVIOR */
			S_ERROR("not enough memory: can not "
				"change character case");
			if (*s)
				sd_set_alloc_errors(*s);
			return ss_check(s);
		}
		char *pout = get_str(out);
		if (at > 0) /* cat */
			memcpy(pout, get_str(*s), at);
		po0 = pout + at;
	} else {
		po0 = get_str(*s) + at;
	}
	/* Case conversion loop: */
	size_t i = 0;
	int c = 0;
	char *po = po0,
	      u8[SSU8_MAX_SIZE];
	for (; i < ss;) {
#ifdef S_ENABLE_UTF8_7BIT_PARALLEL_CASE_OPTIMIZATIONS
		unsigned *pou = (unsigned *)po;
		const size_t i2 = sc_parallel_toX(ps, i, ss, pou, towX);
		if (i != i2) {
			po += (i2 - i);
			i = i2;
			if (i >= ss)
				break;
		}
#endif
		const size_t csize = ss_utf8_to_wc(ps, i, ss, &c, *s);
		const int c2 = towX(c);
		size_t csize2;
		if (c2 == c) {
			csize2 = csize;
			if (!aliasing)
				memcpy(po, ps + i, csize2);
		} else {
			csize2 = sc_wc_to_utf8(c2, u8, 0, SSU8_MAX_SIZE);
			memcpy(po, u8, csize2);
		}
		i += csize;
		po += csize2;
	}
	if (out) {	/* Case of using a secondary string was required */
		ss_t *s_bck = *s;
		*s = out;
		ss_free(&s_bck);
	}
	if (*s) {
		set_size(*s, sso_req);
		set_unicode_size_cached(*s, is_cached_usize);
		set_unicode_size(*s, cached_usize);
	}
	return ss_check(s);
}