#include #include #include #include #include #include #include #include #include #include #include #include #include #define TAG "CanControl" #define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, TAG, fmt, ##args) #define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args) #define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args) extern "C" JNIEXPORT jint JNICALL Java_com_example_serial_CanControl_sendMessage(JNIEnv *env, jclass clazz, jstring id, jstring dlc, jstring data, jstring ifname) { // TODO: implement sendMessage() int fd; int i; struct sockaddr_can addr; struct ifreq ifr; struct can_frame frame; unsigned int byte; char *token; const char *sendId = env->GetStringUTFChars(id, 0); const char *sendDlc = env->GetStringUTFChars(dlc, 0); const char *sendMsg = env->GetStringUTFChars(data, 0); const char *if_name = env->GetStringUTFChars(ifname, 0); if ( sendId == nullptr || sendDlc == nullptr || sendMsg == nullptr || if_name == nullptr) { LOGE("Invalid parameter"); return -1; } // create socket fd = socket(PF_CAN, SOCK_RAW, CAN_RAW); if(fd < 0) { LOGE("create can socket failed:%s\n", strerror(errno)); return -2; } strcpy(ifr.ifr_name, if_name); ioctl(fd, SIOCGIFINDEX, &ifr); addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; if (bind(fd, (struct sockaddr*)&addr, sizeof (addr)) < 0) { LOGE("bind socket failed:%s\n", strerror(errno)); return -3; } sscanf(sendId, "%X", &byte); frame.can_id = byte; sscanf(sendDlc, "%u", &byte); frame.can_dlc = byte; token = strtok((char *)sendMsg, " "); for (int i = 0; i < frame.can_dlc && token != NULL; ++i) { unsigned int data_byte; sscanf(token, "%02X", &data_byte); frame.data[i] = (unsigned char)data_byte; token = strtok(NULL, " "); } if (write(fd, &frame, sizeof (struct can_frame)) != sizeof (struct can_frame)) { LOGE("write data failed:%s\n", strerror(errno)); return -4; } LOGD("Send CAN frame: ID=0x%X DLC=%d data=", frame.can_id, frame.can_dlc); for(int i = 0; i < frame.can_dlc; i++) { LOGD("%02X ", frame.data[i]); } printf("\n"); close(fd); env->ReleaseStringUTFChars(id, sendId); env->ReleaseStringUTFChars(dlc, sendDlc); env->ReleaseStringUTFChars(data, sendMsg); env->ReleaseStringUTFChars(ifname, if_name); return 0; } extern "C" JNIEXPORT jstring JNICALL Java_com_example_serial_CanControl_receiveMessage(JNIEnv *env, jclass clazz, jstring ifname) { // TODO: implement receiveMessage() int fd; int rv; struct sockaddr_can addr; struct ifreq ifr; struct can_frame frame; char recvMsg[128]; char buf[4]; const char *if_name = env->GetStringUTFChars(ifname, 0); if (if_name == nullptr) { LOGE("Invalid parameter"); return nullptr; } fd = socket(PF_CAN, SOCK_RAW, CAN_RAW); if(fd < 0) { LOGE("create can socket failed:%s\n", strerror(errno)); return nullptr; } strcpy(ifr.ifr_name, if_name); ioctl(fd, SIOCGIFINDEX, &ifr); addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; if (bind(fd, (struct sockaddr*)&addr, sizeof (addr)) < 0) { LOGE("bind socket failed:%s\n", strerror(errno)); return nullptr; } rv = read(fd, &frame, sizeof (struct can_frame)); if (rv < 0) { LOGE("read data failed:%s\n", strerror(errno)); return nullptr; } else if (rv < sizeof (struct can_frame)) { LOGE("read incomplete CAN frame\n"); return nullptr; } memset(recvMsg, 0, sizeof (recvMsg)); sprintf(recvMsg, "ID=%X DLC=%d Data=", frame.can_id, frame.can_dlc); for (int i = 0; i < frame.can_dlc; ++i) { memset(buf, 0, sizeof (buf)); sprintf(buf, "%02X ", frame.data[i]); strcat(recvMsg, buf); } LOGD("recived: %s", recvMsg); close(fd); env->ReleaseStringUTFChars(ifname, if_name); return env->NewStringUTF(recvMsg); } extern "C" JNIEXPORT jint JNICALL Java_com_example_serial_CanControl_openCan(JNIEnv *env, jclass clazz, jstring ifname, jstring bitrate) { // TODO: implement openCan() char *ifname_native; char *bitrate_native; char command[128]; ifname_native = (char *)env->GetStringUTFChars(ifname, 0); bitrate_native = (char *)env->GetStringUTFChars(bitrate, 0); memset(command, 0, sizeof (command)); snprintf(command, sizeof (command), "ip link set %s down", ifname_native); if( system(command) == -1) { LOGE("system %s failure:%s\n", command, strerror(errno)); return -1; } LOGD("system %s success\n", command); memset(command, 0, sizeof (command)); snprintf(command, sizeof(command), "ip link set %s up type can bitrate %d", ifname_native, bitrate_native); if( system(command) == -1) { LOGE("system %s failure:%s\n", command, strerror(errno)); return -1; } LOGD("system %s success\n", command); memset(command, 0, sizeof (command)); snprintf(command, sizeof(command), "ip link set %s up type can", ifname_native); if( system(command) == -1) { LOGE("system %s failure:%s\n", command, strerror(errno)); return -1; } LOGD("system %s success\n", command); env->ReleaseStringUTFChars(ifname, ifname_native); env->ReleaseStringUTFChars(bitrate, bitrate_native); return 0; }