1b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood/*
2b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood * Copyright (C) 2011 The Android Open Source Project
3b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood *
4b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood * Licensed under the Apache License, Version 2.0 (the "License");
5b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood * you may not use this file except in compliance with the License.
6b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood * You may obtain a copy of the License at
7b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood *
8b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood *      http://www.apache.org/licenses/LICENSE-2.0
9b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood *
10b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood * Unless required by applicable law or agreed to in writing, software
11b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood * distributed under the License is distributed on an "AS IS" BASIS,
12b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood * See the License for the specific language governing permissions and
14b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood * limitations under the License.
15b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood */
16b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
17b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood#define LOG_TAG "SerialPortJNI"
18b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
19b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood#include "utils/Log.h"
20b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
21b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood#include "jni.h"
22b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood#include "JNIHelp.h"
23ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe#include "core_jni_helpers.h"
24b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
25b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood#include <stdio.h>
26b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood#include <sys/types.h>
27b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood#include <sys/stat.h>
28b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood#include <fcntl.h>
29b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood#include <termios.h>
30b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
31b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwoodusing namespace android;
32b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
33b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwoodstatic jfieldID field_context;
34b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
35b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwoodstatic void
36b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwoodandroid_hardware_SerialPort_open(JNIEnv *env, jobject thiz, jobject fileDescriptor, jint speed)
37b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood{
38b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    switch (speed) {
39b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 50:
40b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B50;
41b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
42b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 75:
43b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B75;
44b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
45b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 110:
46b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B110;
47b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
48b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 134:
49b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B134;
50b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
51b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 150:
52b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B150;
53b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
54b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 200:
55b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B200;
56b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
57b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 300:
58b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B300;
59b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
60b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 600:
61b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B600;
62b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
63b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 1200:
64b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B1200;
65b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
66b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 1800:
67b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B1800;
68b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
69b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 2400:
70b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B2400;
71b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
72b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 4800:
73b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B4800;
74b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
75b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 9600:
76b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B9600;
77b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
78b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 19200:
79b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B19200;
80b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
81b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 38400:
82b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B38400;
83b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
84b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 57600:
85b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B57600;
86b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
87b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 115200:
88b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B115200;
89b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
90b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 230400:
91b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B230400;
92b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
93b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 460800:
94b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B460800;
95b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
96b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 500000:
97b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B500000;
98b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
99b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 576000:
100b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B576000;
101b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
102b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 921600:
103b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B921600;
104b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
105b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 1000000:
106b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B1000000;
107b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
108b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 1152000:
109b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B1152000;
110b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
111b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 1500000:
112b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B1500000;
113b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
114b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 2000000:
115b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B2000000;
116b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
117b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 2500000:
118b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B2500000;
119b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
120b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 3000000:
121b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B3000000;
122b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
123b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 3500000:
124b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B3500000;
125b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
126b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        case 4000000:
127b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            speed = B4000000;
128b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            break;
129b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        default:
130b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            jniThrowException(env, "java/lang/IllegalArgumentException",
131b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood                              "Unsupported serial port speed");
132b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            return;
133b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    }
134b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
135b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
136b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    // duplicate the file descriptor, since ParcelFileDescriptor will eventually close its copy
137b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    fd = dup(fd);
138b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    if (fd < 0) {
139b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        jniThrowException(env, "java/io/IOException", "Could not open serial port");
140b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        return;
141b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    }
142b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    env->SetIntField(thiz, field_context, fd);
143b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
144b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    struct termios tio;
145b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    if (tcgetattr(fd, &tio))
146b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        memset(&tio, 0, sizeof(tio));
147b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
148b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    tio.c_cflag =  speed | CS8 | CLOCAL | CREAD;
149d3622e9e490191670d3dc7fa52b60e1efd575011Girts Folkmanis    // Disable output processing, including messing with end-of-line characters.
150d3622e9e490191670d3dc7fa52b60e1efd575011Girts Folkmanis    tio.c_oflag &= ~OPOST;
151b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    tio.c_iflag = IGNPAR;
152b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    tio.c_lflag = 0; /* turn of CANON, ECHO*, etc */
153b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    /* no timeout but request at least one character per read */
154b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    tio.c_cc[VTIME] = 0;
155b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    tio.c_cc[VMIN] = 1;
156b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    tcsetattr(fd, TCSANOW, &tio);
157b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    tcflush(fd, TCIFLUSH);
158b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood}
159b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
160b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwoodstatic void
161b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwoodandroid_hardware_SerialPort_close(JNIEnv *env, jobject thiz)
162b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood{
163b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    int fd = env->GetIntField(thiz, field_context);
164b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    close(fd);
165b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    env->SetIntField(thiz, field_context, -1);
166b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood}
167b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
168b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwoodstatic jint
169b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwoodandroid_hardware_SerialPort_read_array(JNIEnv *env, jobject thiz, jbyteArray buffer, jint length)
170b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood{
171b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    int fd = env->GetIntField(thiz, field_context);
172b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    jbyte* buf = (jbyte *)malloc(length);
173b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    if (!buf) {
174b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
175b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        return -1;
176b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    }
177b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
178b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    int ret = read(fd, buf, length);
179b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    if (ret > 0) {
180b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        // copy data from native buffer to Java buffer
181b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        env->SetByteArrayRegion(buffer, 0, ret, buf);
182b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    }
183b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
184b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    free(buf);
185b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    if (ret < 0)
186b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        jniThrowException(env, "java/io/IOException", NULL);
187b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    return ret;
188b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood}
189b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
190b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwoodstatic jint
191b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwoodandroid_hardware_SerialPort_read_direct(JNIEnv *env, jobject thiz, jobject buffer, jint length)
192b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood{
193b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    int fd = env->GetIntField(thiz, field_context);
194b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
195b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    jbyte* buf = (jbyte *)env->GetDirectBufferAddress(buffer);
196b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    if (!buf) {
197b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        jniThrowException(env, "java/lang/IllegalArgumentException", "ByteBuffer not direct");
198b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        return -1;
199b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    }
200b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
201b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    int ret = read(fd, buf, length);
202b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    if (ret < 0)
203b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        jniThrowException(env, "java/io/IOException", NULL);
204b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    return ret;
205b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood}
206b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
207b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwoodstatic void
208b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwoodandroid_hardware_SerialPort_write_array(JNIEnv *env, jobject thiz, jbyteArray buffer, jint length)
209b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood{
210b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    int fd = env->GetIntField(thiz, field_context);
211b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    jbyte* buf = (jbyte *)malloc(length);
212b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    if (!buf) {
213b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
214b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        return;
215b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    }
216b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    env->GetByteArrayRegion(buffer, 0, length, buf);
217b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
218b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    jint ret = write(fd, buf, length);
219b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    free(buf);
220b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    if (ret < 0)
221b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        jniThrowException(env, "java/io/IOException", NULL);
222b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood}
223b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
224b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwoodstatic void
225b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwoodandroid_hardware_SerialPort_write_direct(JNIEnv *env, jobject thiz, jobject buffer, jint length)
226b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood{
227b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    int fd = env->GetIntField(thiz, field_context);
228b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
229b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    jbyte* buf = (jbyte *)env->GetDirectBufferAddress(buffer);
230b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    if (!buf) {
231b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        jniThrowException(env, "java/lang/IllegalArgumentException", "ByteBuffer not direct");
232b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        return;
233b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    }
234b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    int ret = write(fd, buf, length);
235b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    if (ret < 0)
236b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood        jniThrowException(env, "java/io/IOException", NULL);
237b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood}
238b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
2397dbc4b457d2c2c6dd39fa445e7edd8109796f0a2Mike Lockwoodstatic void
2407dbc4b457d2c2c6dd39fa445e7edd8109796f0a2Mike Lockwoodandroid_hardware_SerialPort_send_break(JNIEnv *env, jobject thiz)
2417dbc4b457d2c2c6dd39fa445e7edd8109796f0a2Mike Lockwood{
2427dbc4b457d2c2c6dd39fa445e7edd8109796f0a2Mike Lockwood    int fd = env->GetIntField(thiz, field_context);
2437dbc4b457d2c2c6dd39fa445e7edd8109796f0a2Mike Lockwood    tcsendbreak(fd, 0);
2447dbc4b457d2c2c6dd39fa445e7edd8109796f0a2Mike Lockwood}
2457dbc4b457d2c2c6dd39fa445e7edd8109796f0a2Mike Lockwood
24676f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod method_table[] = {
247b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    {"native_open",             "(Ljava/io/FileDescriptor;I)V",
248b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood                                        (void *)android_hardware_SerialPort_open},
249b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    {"native_close",            "()V",  (void *)android_hardware_SerialPort_close},
250b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    {"native_read_array",       "([BI)I",
251b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood                                        (void *)android_hardware_SerialPort_read_array},
252b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    {"native_read_direct",      "(Ljava/nio/ByteBuffer;I)I",
253b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood                                        (void *)android_hardware_SerialPort_read_direct},
254b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    {"native_write_array",      "([BI)V",
255b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood                                        (void *)android_hardware_SerialPort_write_array},
256b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood    {"native_write_direct",     "(Ljava/nio/ByteBuffer;I)V",
257b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood                                        (void *)android_hardware_SerialPort_write_direct},
2587dbc4b457d2c2c6dd39fa445e7edd8109796f0a2Mike Lockwood    {"native_send_break",       "()V",  (void *)android_hardware_SerialPort_send_break},
259b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood};
260b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
261b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwoodint register_android_hardware_SerialPort(JNIEnv *env)
262b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood{
263ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    jclass clazz = FindClassOrDie(env, "android/hardware/SerialPort");
264ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    field_context = GetFieldIDOrDie(env, clazz, "mNativeContext", "I");
265b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood
266ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    return RegisterMethodsOrDie(env, "android/hardware/SerialPort",
267b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood            method_table, NELEM(method_table));
268b01e8bf57b7492b77e3445db51471edcbadda75eMike Lockwood}
269