2 * Copyright (C) 2011 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #define LOG_TAG "SerialPortJNI"
19 #include "utils/Log.h"
23 #include "android_runtime/AndroidRuntime.h"
26 #include <sys/types.h>
31 using namespace android;
33 static jfieldID field_context;
36 android_hardware_SerialPort_open(JNIEnv *env, jobject thiz, jobject fileDescriptor, jint speed)
130 jniThrowException(env, "java/lang/IllegalArgumentException",
131 "Unsupported serial port speed");
135 int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
136 // duplicate the file descriptor, since ParcelFileDescriptor will eventually close its copy
139 jniThrowException(env, "java/io/IOException", "Could not open serial port");
142 env->SetIntField(thiz, field_context, fd);
145 if (tcgetattr(fd, &tio))
146 memset(&tio, 0, sizeof(tio));
148 tio.c_cflag = speed | CS8 | CLOCAL | CREAD;
149 // Disable output processing, including messing with end-of-line characters.
150 tio.c_oflag &= ~OPOST;
151 tio.c_iflag = IGNPAR;
152 tio.c_lflag = 0; /* turn of CANON, ECHO*, etc */
153 /* no timeout but request at least one character per read */
156 tcsetattr(fd, TCSANOW, &tio);
157 tcflush(fd, TCIFLUSH);
161 android_hardware_SerialPort_close(JNIEnv *env, jobject thiz)
163 int fd = env->GetIntField(thiz, field_context);
165 env->SetIntField(thiz, field_context, -1);
169 android_hardware_SerialPort_read_array(JNIEnv *env, jobject thiz, jbyteArray buffer, jint length)
171 int fd = env->GetIntField(thiz, field_context);
172 jbyte* buf = (jbyte *)malloc(length);
174 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
178 int ret = read(fd, buf, length);
180 // copy data from native buffer to Java buffer
181 env->SetByteArrayRegion(buffer, 0, ret, buf);
186 jniThrowException(env, "java/io/IOException", NULL);
191 android_hardware_SerialPort_read_direct(JNIEnv *env, jobject thiz, jobject buffer, jint length)
193 int fd = env->GetIntField(thiz, field_context);
195 jbyte* buf = (jbyte *)env->GetDirectBufferAddress(buffer);
197 jniThrowException(env, "java/lang/IllegalArgumentException", "ByteBuffer not direct");
201 int ret = read(fd, buf, length);
203 jniThrowException(env, "java/io/IOException", NULL);
208 android_hardware_SerialPort_write_array(JNIEnv *env, jobject thiz, jbyteArray buffer, jint length)
210 int fd = env->GetIntField(thiz, field_context);
211 jbyte* buf = (jbyte *)malloc(length);
213 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
216 env->GetByteArrayRegion(buffer, 0, length, buf);
218 jint ret = write(fd, buf, length);
221 jniThrowException(env, "java/io/IOException", NULL);
225 android_hardware_SerialPort_write_direct(JNIEnv *env, jobject thiz, jobject buffer, jint length)
227 int fd = env->GetIntField(thiz, field_context);
229 jbyte* buf = (jbyte *)env->GetDirectBufferAddress(buffer);
231 jniThrowException(env, "java/lang/IllegalArgumentException", "ByteBuffer not direct");
234 int ret = write(fd, buf, length);
236 jniThrowException(env, "java/io/IOException", NULL);
240 android_hardware_SerialPort_send_break(JNIEnv *env, jobject thiz)
242 int fd = env->GetIntField(thiz, field_context);
246 static JNINativeMethod method_table[] = {
247 {"native_open", "(Ljava/io/FileDescriptor;I)V",
248 (void *)android_hardware_SerialPort_open},
249 {"native_close", "()V", (void *)android_hardware_SerialPort_close},
250 {"native_read_array", "([BI)I",
251 (void *)android_hardware_SerialPort_read_array},
252 {"native_read_direct", "(Ljava/nio/ByteBuffer;I)I",
253 (void *)android_hardware_SerialPort_read_direct},
254 {"native_write_array", "([BI)V",
255 (void *)android_hardware_SerialPort_write_array},
256 {"native_write_direct", "(Ljava/nio/ByteBuffer;I)V",
257 (void *)android_hardware_SerialPort_write_direct},
258 {"native_send_break", "()V", (void *)android_hardware_SerialPort_send_break},
261 int register_android_hardware_SerialPort(JNIEnv *env)
263 jclass clazz = env->FindClass("android/hardware/SerialPort");
265 ALOGE("Can't find android/hardware/SerialPort");
268 field_context = env->GetFieldID(clazz, "mNativeContext", "I");
269 if (field_context == NULL) {
270 ALOGE("Can't find SerialPort.mNativeContext");
274 return AndroidRuntime::registerNativeMethods(env, "android/hardware/SerialPort",
275 method_table, NELEM(method_table));