Access I2C on i.mx6 board from Android app - android

I am working on a development board based on nxp i.mx6 (Variscite Dart mx6).
My application is signed with platform keys and I can see it running as sharedUserId (UID 1000).
When I try ti execute the "su" command with getRuntime.exec("/system/xbin/su") an exception error Is rised (permissione denied).
I need the su to being able to use Shell commands i2cset and i2cset.
I am using Android Oreo 8.0.
Any suggestion?

I solved creating a simple daemon being launched on boot that receive the commands to execute by the Java app (through socket).
Below I report daemon code (it's very simple for now, but it works).
Luca
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main() {
char buffer[100];
struct sockaddr_in addr;
size_t addrlen, n;
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
memset(&addr, 0, sizeof addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(2000);
addr.sin_addr.s_addr = INADDR_ANY;
bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
addrlen = sizeof(addr);
while(1)
{
n = recvfrom(sockfd, (void*)buffer, 100, 0,
(struct sockaddr*)&addr, (int *) &addrlen);
buffer[n] = '\n';
system(buffer);
}
return 0;
}

Related

Bash script in C language for android ndk

I have a problem with this:
C code
#define CREATE_HTML_FILE_SCRIPT "/bin/curl https://coinmarketcap.com/it/currencies/bytecoin-bcn/ > /data/data/com.example.bytecoin/bcn.html"
#define CREATE_TEMP_FILE_SCRIPT "/data/local/lynx /data/data/com.example.bytecoin/bcn.html -dump > /data/data/com.example.bytecoin/bcn.txt"
system(CREATE_HTML_FILE_SCRIPT);
system(CREATE_TEMP_FILE_SCRIPT);
If I run from adb shell these commands all works well but when these command are executed from the app, file.html and file.txt are empty... I don't understand why and how I can solve it.
Well, lynx is an interactive program, so I think you'll run in trouble when using it from a system() call. But not with curl:
/* pru_curl-1.c */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *cmd = "curl https://www.google.com/";
system(cmd); /* you will get the output of curl on stdout */
exit(EXIT_SUCCESS);
}
This is with curl redirecting its output in the shell call with the > operator:
/* pru_curl-2.c */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *cmd = "curl https://www.google.com/ >output_file-2";
/* you will get the output of curl on output_file-2 */
system(cmd);
exit(EXIT_SUCCESS);
}
Curl, on the other side, allows you to specify -o output_file.txt and you'll be able to read the file, once the program has finished.
/* pru_curl-3.c */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *cmd = "curl https://www.google.com/ -o output_file-3";
/* you will get the output of curl on output_file-3 */
system(cmd);
exit(EXIT_SUCCESS);
}
You have a third alternative, which is using popen(3), that allows you to start the program as a subcommand, and read the output of that program from the FILE * descriptor you get from popen(3). You could use it like this (processing character by character):
/* pru_curl-4.c */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *cmd = "curl https://www.google.com/";
FILE *f = popen(cmd, "r");
if (!f) {
fprintf(stderr, "%s: %s\n",
cmd, strerror(errno));
exit(EXIT_FAILURE);
}
int c;
while((c = fgetc(f)) != EOF) {
printf("[%d]", c); /* you will get the downloaded file as
* sequences of numbers (the character
* values) embedded in square brackets on
* stdout */
}
pclose(f);
exit(EXIT_SUCCESS);
}
or (processing line by line):
/* pru_curl-5.c */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *cmd = "curl https://www.google.com/";
FILE *f = popen(cmd, "r");
if (!f) {
fprintf(stderr, "%s: %s\n",
cmd, strerror(errno));
exit(EXIT_FAILURE);
}
char line[256];
while (fgets(line, sizeof line, f)) {
/* you'll get your output in chunks of one line, or 256 bytes
* ---if longer---, encapsulated by a pair of square brackets
* drawn in a different color (gren, by the escape sequences
* used) */
fprintf(stderr,
"\033[1;33m[\033[m%s\033[32m]\033[m",
line);
}
pclose(f);
exit(EXIT_SUCCESS);
}
or (by blocks):
/* pru_curl-6.c */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 8 /* blocks in buffer */
#define CPB 11 /* chars per block */
int main()
{
char *cmd = "curl https://www.google.com/";
FILE *f = popen(cmd, "r");
if (!f) {
fprintf(stderr, "%s: %s\n",
cmd, strerror(errno));
exit(EXIT_FAILURE);
}
char block[N][CPB];
int n;
char *sep = "";
do {
/* print a blanck line between groups */
printf("%s", sep);
sep = "\n";
/* we read as many CPB byte blocks as possible to fill the
* N registers in buffer.
* Then we start again until we don't fill completely the
* buffer. */
n = fread(block, sizeof block[0], N, f);
int i;
for (i = 0; i < n; i++) {
printf("[%.*s]\n", (int)sizeof block[i], block[i]);
}
printf("finished one loop of %d blocks of %d chars, each.\n",
N, (int) sizeof block[0]);
} while (n == N);
/* n < N, so we are finished, check that probably the last register is
* not printed because it was not complete. */
pclose(f);
exit(EXIT_SUCCESS);
}
(All these examples are complete and have been tested before posting)
Edit
I have completed the code for the six programs and now all of them are executables with just building with:
$ cc pru_curl-<i>.c -o pru_curl-<i> # <i> is the program number
$ _
In each case, you can execute the program by just running:
$ pru_curl-<i>
.... <-- a lot of output (or to a file) about the contents of the root page of google.
$ _

OpenCV and C++: "Can't resolve variable 'Mat`"

I'm trying to integrate OpenCV in Android Java native interface using C++ language. I have placed the OpenCV inside the jni folder, where I'm writing my C++ code. I have included the Opencv header files in my HelloNative.c file. But I'm still getting this error while trying to access Mat object.
"Can't resolve variable Mat".
I have tried using namespace cv, but it gives an error to predeclare using and namespace; which is not a solution. I'm posting my code below, please somebody have a look at it and let me know what I'm doing wrong.
#include <string.h>
#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
#include <android/log.h>
#include <malloc.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <OpenCV/include/opencv2/opencv.hpp>
#include <OpenCV/include/opencv/cv.h>
#include <OpenCV/modules/core/include/opencv2/core.hpp>
#include <OpenCV/modules/core/include/opencv2/core/core_c.h>
#include <OpenCV/modules/core/include/opencv2/core/mat.hpp>
#include <OpenCV/modules/imgproc/include/opencv2/imgproc/imgproc.hpp>
#include <OpenCV/modules/imgproc/include/opencv2/imgproc/imgproc_c.h>
#include <OpenCV/modules/legacy/include/opencv2/legacy/legacy.hpp>
#include <OpenCV/modules/videostab/include/opencv2/videostab/motion_stabilizing.hpp>
#include <OpenCV/modules/videostab/include/opencv2/videostab/global_motion.hpp>
JNIEXPORT jint JNICALL
Java_com_example_soimporttest_MainActivity_getStringFromJNI(JNIEnv *env, jobject thisObj,
jstring imagepath) {
const char *jnamestr = (*env)->GetStringUTFChars(env, imagepath, 0);
int width, height, gray;
FILE *fp = fopen(jnamestr, "rb");
if (fp) {
//Read .pgm file
int scan = fscanf(fp, "P5%d%d%d", &width, &height, &gray);
if (scan != 3 || &gray > 256 || &width > 0xfffff || &height > 0xfffff || &gray <= 1 ||
&width < 32 || &height < 32) {
fclose(fp);
return 9;
} else {
return 0;
}
} else {
return -1;
}
}
JNIEXPORT void JNICALL
Java_com_example_soimporttest_MainActivity_displayImage(JNIEnv *env, jobject thisObj, jclass type, jlong inpAddr, jlong outAddr) {
::Mat &src = *(Mat*)inpAddr;
Mat &dst = *(Mat*)outAddr;
applyFilter(src , dst);
}
There are two functions in this file, the first function getStringFromJNI is working perfectly fine.
Thank you.
After a lot of research, I finally managed to find out a good solution for my question. Please follow below mentioned tutorial:
https://github.com/leadrien/opencv_native_androidstudio
You'll be facing some issues while integrating it. You can post those solutions in the comments and I will guide you through each.
Thanks.

Android native Parcel usage

I am trying out Parcel with native code:
#include <stdio.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <binder/IBinder.h>
#include <binder/Binder.h>
#include <binder/ProcessState.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
using namespace android;
int main()
{
int32_t i = 123, j = 456;
Parcel data;
status_t t = data.writeInt32(j);
if(t == NO_ERROR)
printf("Status: %d\n", t);
else if(t == BAD_VALUE)
printf("Bad Value\n");
int32_t jj = 0;
t = data.readInt32(&jj);
printf("t: %d\n", t);
printf("ParcelTest: %d\n", jj);
return 0;
}
To compile this code, Android's source tree is needed. Put it under external/ParcelTest. And the Android.mk is here. Run mmma external/ParcelTest to compile.
Output of the program is:
generic_x86:/ # /system/bin/ParcelTest
Status: 0
t: -61
ParcelTest: 0
The Status: 0 indicates that writing value into the Parcel works out. But reading doesn't. So Parcel is the thing that if I read data as the order I write, I would get correct result. Any idea why this code sample fails?
The correct usage is below:
#include <stdio.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <binder/IBinder.h>
#include <binder/Binder.h>
#include <binder/ProcessState.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
using namespace android;
int main()
{
int32_t i = 123, j = 456;
Parcel data;
status_t t = data.writeInt32(j);
if(t == NO_ERROR)
printf("Status: %d\n", t);
else if(t == BAD_VALUE)
printf("Bad Value\n");
int32_t jj = 0;
data.setDataPosition(0);
t = data.readInt32(&jj);
printf("t: %d\n", t);
printf("ParcelTest: %d\n", jj);
return 0;
}
The read position has to be set manually.

How to read a file in c using NDK in android

I am trying to read a file in c using NDK. When i debug the code, i see that i get a NULL pointer in f(file reading pointer). Also, my file which i need to read is in the same folder under cpp including all other header files. I have the read and write permissions for external storage in my app. Any help is appreciated.
C Code:
#ifndef client_h
#define client_h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <pthread.h>
#include "utility.h"
#define SENDBUFSIZE 1399
#define RECVBUFSIZE 1399
void pingServer(char *hostname, int portno)
{
//Some other functionality which works correctly
// File Read operations
FILE *f = fopen("somefile.csv", "r"); //Get the null pointer here
if (f == NULL)
perror("Could not open input file");
char *currentRow[3];
char *nextRow[3];
int rows = 3;
for (int i=0; i<rows; i++)
{
currentRow[i] = (char*)malloc(20 * sizeof(char));
nextRow[i] = (char*)malloc(20 * sizeof(char));
}
double current, next;
double elapsed;
int isNextRow, isCurentRow;
readCsvLine(f,currentRow,rows); //Get the headers
int counter = 2;
isCurentRow = readCsvLine(f,currentRow,rows);
//sends the data
//Free the memory
for (int i=0; i<rows; i++)
{
free(currentRow[i]);
free(nextRow[i]);
}
free(buf);
return;
}
char* printName(){
char* ptr = "hello From C";
return ptr;
}
#endif
Java code for calling the c methods:
#include <jni.h>
#include <string>
#include "client.h"
extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_habbas_mobiledifferentiation_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
char *hostname = "127.0.0.1";
int portno = 1254;
pingServer(hostname, portno);
std::string hello = printName();
return env->NewStringUTF(hello.c_str());
}

The syscall __NR_perf_event_open seems doesn't work on Android

I want to use the syscall of __NR_perf_event_open for my Android app.
The code runs normally on linux but does not work on Android.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <perf_event.h>
#include <asm/unistd.h>
long perf_event_open( struct perf_event_attr *hw_event, pid_t pid,
int cpu, int group_fd, unsigned long flags )
{
int ret;
ret = syscall( __NR_perf_event_open, hw_event, pid, cpu,
group_fd, flags );
return ret;
}
int main() {
//In the main function, I call perf_event_open:
struct perf_event_attr pe;
int fd;
fd = perf_event_open(&pe, 0, -1, -1, 0);
...
}
However, the fd always return the value -1. When I use "errno.h", it gave the error informaiton of:EBADF:bad file descriptor.
you have not configured "struct perf_event_attr pe;" yet
because pid == -1 and cpu == -1 is not valid. you can check it in http://web.eece.maine.edu/~vweaver/projects/perf_events/perf_event_open.html

Categories

Resources