android_serialport_api hacking

简介: 1 /************************************************************************************ 2 * 3 * android_serialport_api hacking 4 * 5 * 声明: 6 * 1.
  1 /************************************************************************************
  2  *
  3  *                    android_serialport_api hacking
  4  *
  5  *  声明:
  6  *      1. 这是android_serialport_api的jni源代码解读;
  7  *      2. 源代码url: https://code.google.com/p/android-serialport-api/
  8  *      3. 可以从中知道JNI是如何查找类,创建对象,访问对象的属性等等内容;
  9  *
 10  *
 11  * Copyright 2009-2011 Cedric Priscal
 12  *
 13  * Licensed under the Apache License, Version 2.0 (the "License");
 14  * you may not use this file except in compliance with the License.
 15  * You may obtain a copy of the License at
 16  *
 17  * http://www.apache.org/licenses/LICENSE-2.0
 18  *
 19  * Unless required by applicable law or agreed to in writing, software
 20  * distributed under the License is distributed on an "AS IS" BASIS,
 21  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 22  * See the License for the specific language governing permissions and
 23  * limitations under the License.
 24  *
 25  *
 26  *
 27  * 相关参考:
 28  *    1. 访问JAVA中的字段(jfieldID): http://www.cnblogs.com/lijunamneg/archive/2012/12/22/2829023.html
 29  *    2. JNIEnv解析: http://blog.csdn.net/freechao/article/details/7692239
 30  *    3. The Java™ Native Interface Programmer’s Guide and Specification
 31  *
 32  *****************************************************************************/
 33 
 34 #include <termios.h>
 35 #include <unistd.h>
 36 #include <sys/types.h>
 37 #include <sys/stat.h>
 38 #include <fcntl.h>
 39 #include <string.h>
 40 #include <jni.h>
 41 
 42 #include "SerialPort.h"
 43 
 44 #include "android/log.h"
 45 
 46 /**
 47  * 定义一些宏,方便写调试代码
 48  */
 49 static const char *TAG="serial_port";
 50 #define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO,  TAG, fmt, ##args)
 51 #define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
 52 #define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)
 53 
 54 static speed_t getBaudrate(jint baudrate)
 55 {
 56     switch(baudrate) {
 57     case 0: return B0;
 58     case 50: return B50;
 59     case 75: return B75;
 60     case 110: return B110;
 61     case 134: return B134;
 62     case 150: return B150;
 63     case 200: return B200;
 64     case 300: return B300;
 65     case 600: return B600;
 66     case 1200: return B1200;
 67     case 1800: return B1800;
 68     case 2400: return B2400;
 69     case 4800: return B4800;
 70     case 9600: return B9600;
 71     case 19200: return B19200;
 72     case 38400: return B38400;
 73     case 57600: return B57600;
 74     case 115200: return B115200;
 75     case 230400: return B230400;
 76     case 460800: return B460800;
 77     case 500000: return B500000;
 78     case 576000: return B576000;
 79     case 921600: return B921600;
 80     case 1000000: return B1000000;
 81     case 1152000: return B1152000;
 82     case 1500000: return B1500000;
 83     case 2000000: return B2000000;
 84     case 2500000: return B2500000;
 85     case 3000000: return B3000000;
 86     case 3500000: return B3500000;
 87     case 4000000: return B4000000;
 88     default: return -1;
 89     }
 90 }
 91 
 92 /*
 93  * Class:     com_android_aplex_SerialPort
 94  * Method:    open
 95  * Signature: (Ljava/lang/String;II)Ljava/io/FileDescriptor;
 96  */
 97 JNIEXPORT jobject JNICALL Java_com_android_aplex_SerialPort_open
 98   (JNIEnv *env, jclass thiz, jstring path, jint baudrate, jint flags)
 99 {
100     
101     int fd;
102     speed_t speed;
103     jobject mFileDescriptor;    //保存文件描述符的对象引用
104 
105     // Check arguments 
106     {
107         speed = getBaudrate(baudrate);
108         if (speed == -1) {
109             // TODO: throw an exception 
110             LOGE("Invalid baudrate");
111             return NULL;
112         }
113     }
114 
115     // Opening device 
116     {
117         jboolean iscopy;
118         /**
119          * 将Java的字符串转换成C中的字符串
120          */
121         const char *path_utf = (*env)->GetStringUTFChars(env, path, &iscopy);
122         LOGD("Opening serial port %s with flags 0x%x", path_utf, O_RDWR | flags);
123         fd = open(path_utf, O_RDWR | flags);
124         LOGD("open() fd = %d", fd);
125         /**
126          * 和前面的GetStringUTFChars一对用法,相当于malloc和free
127          */
128         (*env)->ReleaseStringUTFChars(env, path, path_utf);
129         if (fd == -1)
130         {
131             // Throw an exception 
132             LOGE("Cannot open port");
133             // TODO: throw an exception 
134             return NULL;
135         }
136     }
137 
138     // Configure device 
139     {
140         struct termios cfg;
141         LOGD("Configuring serial port");
142         if (tcgetattr(fd, &cfg))
143         {
144             LOGE("tcgetattr() failed");
145             close(fd);
146             // TODO: throw an exception 
147             return NULL;
148         }
149 
150         cfmakeraw(&cfg);
151         cfsetispeed(&cfg, speed);
152         cfsetospeed(&cfg, speed);
153 
154         if (tcsetattr(fd, TCSANOW, &cfg))
155         {
156             LOGE("tcsetattr() failed");
157             close(fd);
158             // TODO: throw an exception 
159             return NULL;
160         }
161     }
162 
163     // Create a corresponding file descriptor 
164     {
165         /**
166          * Returns a reference to the named class or interface.
167          * 这个相当于在当前虚拟机加载的所有的类中找这个类:java/io/FileDescriptor
168          */
169         jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor");
170         /**
171          * To obtain the method ID of a constructor, supply "<init>" as the method name and “V” as the return type.
172          * 获取类中的无参构造函数
173          */
174         jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "<init>", "()V");
175         jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I");
176         /**
177          * Constructs a new object. The method ID indicates which constructor method to invoke. This ID may be obtained by calling
178          * GetMethodID with "<init>" as the method name and “V” as the return type. The constructor must be defined in the class
179          * referred to by clazz, not one of its superclasses.
180          * 生成一个类对象
181          */
182         mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor);
183         /**
184          * Sets the value of an instance field of an object. The obj reference must not be NULL.
185          * 设置对象的值
186          */
187         (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint)fd);
188     }
189 
190     return mFileDescriptor;
191     
192 }
193 
194 /*
195  * Class:     com_android_aplex_SerialPort
196  * Method:    close
197  * Signature: ()V
198  */
199 JNIEXPORT void JNICALL Java_com_android_aplex_SerialPort_close
200   (JNIEnv *env, jobject thiz)
201 {
202     /**
203      * Returns the class of an object. The obj reference must not be NULL.
204      * thiz为java层传入的对象,GetObjectClass相当于获得这个对象的类,名字取得不错
205      */
206     jclass SerialPortClass = (*env)->GetObjectClass(env, thiz);
207     /**
208      * FindClass initializes the class or interface it returns.
209      * 这个相当于在当前虚拟机加载的所有的类中找这个类:java/io/FileDescriptor
210      */
211     jclass FileDescriptorClass = (*env)->FindClass(env, "java/io/FileDescriptor");
212     /**
213      * Returns the field ID for an instance field of a class
214      * 通过域名、域类型获取类对应的域ID号
215      */
216     jfieldID mFdID = (*env)->GetFieldID(env, SerialPortClass, "mFd", "Ljava/io/FileDescriptor;");
217     jfieldID descriptorID = (*env)->GetFieldID(env, FileDescriptorClass, "descriptor", "I");
218     /**
219      * Returns the value of a field of an instance. The field to access is specified by a field ID.
220      * 通过对象对应域的ID号获取域对象,或者值
221      */
222     jobject mFd = (*env)->GetObjectField(env, thiz, mFdID);
223     jint descriptor = (*env)->GetIntField(env, mFd, descriptorID);
224 
225     LOGD("close(fd = %d)", descriptor);
226     close(descriptor);
227     
228 }

 

目录
相关文章
|
Linux SoC
I.MX6 mfgtool2-android-mx6q-sabresd-emmc.vbs hacking
/******************************************************************** *   I.MX6 mfgtool2-android-mx6q-sabresd-emmc.vbs hacking * 说明: * 以前用的mfgtool2是直接执行MfgTool2.exe就行了,现在的NXP将其封 * 装在vbs文件内,这是左栋告诉我的,这里记录一下命令行参数的本质。
1036 0
|
Android开发 Perl Shell
AM335x Android eMMC mkmmc-android.sh hacking
# AM335x Android eMMC mkmmc-android.sh hacking # # 1. 有空解读一下android的分区文件。 # 2.
1186 0
|
Unix Android开发 机器学习/深度学习
Android development tools line_endings hacking
/******************************************************************** * Android development tools line_endings hacking * 说明: * 本文主要是对android源代码中的line_endings开发工具进行了解读, * 目的是为了知道传说中的dos,unix文件之间转换的工作机制。
675 0
|
Java Android开发 Linux
I.MX6 android BatteryService jni hacking
/**************************************************************************** * I.MX6 android BatteryService jni hacking * 声明: * 本文主要是为了知道Android的获取的电源管理的数据的jni是从Linux系统的 * 什么位置获取的,获取的机制是什么。
739 0
|
Android开发
Android ashmem hacking
/********************************************************************** * Android ashmem hacking * 声明: * 最近有些东西涉及到binder,而binder又涉及到ashmem,于是先跟一下这 * 部分的内容。
798 0
|
Android开发 编解码
mokoid android open source HAL hacking in a picture
/************************************************************************** * mokoid android HAL hacking in a picture * 声明: * 之前已经对mokoid开源项目源代码进行跟踪分析,但是总感觉对其中的工作 * 机制运行理解不到位,所以索性这次采用更直观的分析方式,用图来表示她的工 * 做原理,调用机制。
882 0
|
前端开发 Android开发
Android custom View AirConditionerView hacking
package com.example.arc.view; import android.content.Context; import android.graphics.Canvas; import android.
644 0
|
定位技术 Android开发
Android GPS GPSBasics project hacking
一、参考源码:   GPS Basic Example - Android Example     http://androidexample.com/GPS_Basic__-__Android_Example/index.
648 0
|
Shell C++ Android开发
I.MX6 Manufacturing Tool V2 (MFGTool2) Emmc mksdcard-android.sh hacking
#!/bin/bash # 参考文章: # 1. Shell特殊变量:Shell $0, $#, $*, $@, $?, $$和命令行参数 # http://c.biancheng.
1066 0
|
Android开发
OK335xS-Android pack-ubi-256M.sh hacking
1 #/******************************************************************************* 2 # * OK335xS-Android pack-ubi-256M.
811 0