I am trying to set the baud-rate of "/dev/ttyS4" and return the Text(EditText) using C code with the help of JNI in android studio
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <termios.h>
#define DEBUG 1
#if DEBUG
#include <android/log.h>
# define D(x...) __android_log_print(ANDROID_LOG_INFO,"hello-jni",x)
#else
# define D(...) do {} while (0)
#endif
char* str;
char buffer[512];
extern "C" JNIEXPORT jstring JNICALL
Java_com_android_uart_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */, jstring text)
{
{
asprintf(&str, "Hi\n");
strlcpy(buffer, str, sizeof buffer);
free(str);
int ttyFD = 0;
struct termios tty;
const char *stringInC = env->GetStringUTFChars(text, NULL);
auto SampleCmd = stringInC;
int i_WriteBytes = 0;
memset (&tty, 0, sizeof tty);
ttyFD = open("/dev/ttyS4", O_RDWR| O_NONBLOCK | O_NDELAY );
if(ttyFD < 0)
{
asprintf(&str, "Error in opening /dev/ttyS4\n");
strlcat(buffer, str, sizeof buffer);
free(str);
}
else
{
asprintf(&str, "ttyS4 port opened successfully\n");
strlcat(buffer, str, sizeof buffer);
free(str);
}
if (tcgetattr ( ttyFD, &tty ) != 0 )
{
asprintf(&str, "Error from tcgetattr\n");
strlcat(buffer, str, sizeof buffer);
free(str);
}
cfsetspeed(&tty, B0);
tty.c_cflag &= ~PARENB; /* parity */
tty.c_cflag &= ~CSTOPB; /* stop bits */
//tty.c_cflag &= ~CSIZE; /* */
tty.c_cflag |= CS8; /* data bits */
tty.c_cflag &= ~CRTSCTS; /* no hardware flow control */
tty.c_iflag &= ~(IXON | IXOFF | IXANY); /* no s/w flow ctrl */
tty.c_lflag = 0; /* non canonical */
tty.c_oflag = 0; /* no remapping, no delays */
tty.c_cc[VMIN] = 0; /* read doesn't block */
tty.c_cc[VTIME] = 0; /* read timeout */
tty.c_cflag |=
CREAD | CLOCAL; /* turn on READ & ignore ctrl lines */
tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /* */
//tty.c_oflag &= ~OPOST; /* */
tcflush(ttyFD, TCIFLUSH);
if (tcsetattr(ttyFD, TCSANOW, &tty) != 0) {
asprintf(&str, "Error from tcsetattr\n");
strlcat(buffer, str, sizeof buffer);
free(str);
}
i_WriteBytes = write(ttyFD, SampleCmd, sizeof(SampleCmd) - 1);
asprintf(&str, "written bytes = %d\n", i_WriteBytes);
strlcat(buffer, str, sizeof buffer);
free(str);
if (i_WriteBytes < 0) {
asprintf(&str, "failed to write value on port\n");
strlcat(buffer, str, sizeof buffer);
free(str);
}
sleep(1);
char read_buf[1024];
memset(&read_buf, '\0', sizeof(read_buf));
int num_bytes = read(ttyFD, &read_buf, sizeof(read_buf));
if (num_bytes < 0) {
asprintf(&str, "Error reading: %s", strerror(errno));
strlcat(buffer, str, sizeof buffer);
free(str);
}
asprintf(&str, "Read bytes = %i \n Received message: %s", num_bytes, read_buf);
strlcat(buffer, str, sizeof buffer);
free(str);
close(ttyFD);
return env->NewStringUTF(buffer);
}
My problem is that WriteBytes and Read bytes only take 7 bytes of the edittext"Text" and it only display 7 characters of it. What i want is to display the entire "Text" from the EditText.
This is the result iam getting:
**Input:**
EditText(baud Rate)=0
EditText(message) =this is a test app
**Output:**
TextView(Details)
hi
ttyS4 port opened successfully
written bytes = 7
Read bytes =7
Received message:this is
CodePudding user response:
The line
i_WriteBytes = write(ttyFD, SampleCmd, sizeof(SampleCmd) - 1);
is wrong.
Variable SampleCmd
, defined as
const char *stringInC = env->GetStringUTFChars(text, NULL);
auto SampleCmd = stringInC;
is of type int
in C or type const char *
in C . (Note that auto
is an old keyword in C which defines a storage class is the default for variables inside functions and forbidden at file scope. As you don't specify a type, it defaults to int
.)
The value sizeof(SampleCmd)
is not related to the length of the string pointed to by stringInC
. It is the size of a variable of type int
(in C, or type char*
in C ). Apparently this size is 8 on your platform, so you will always write 7 bytes.
You could use
i_WriteBytes = write(ttyFD, SampleCmd, strlen(SampleCmd));
or use fdopen
on ttyFD
and use output functions from stdio.h
.