#include <jni.h>
|
#include "android/log.h"
|
|
#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)
|
|
#define unchar unsigned char
|
#define unint unsigned short
|
#define A_Preamble_OFFSET 0
|
#define A_Size_OFFSET 1
|
#define A_Service_ID_OFFSET 2
|
#define A_Service_Frame_OFFSET 3
|
|
unsigned short Get_CRC_CCITT(unsigned short u_crc_val, unsigned char btVal) {
|
u_crc_val = ((unsigned char) (u_crc_val >> 8)) | (u_crc_val << 8);
|
u_crc_val ^= btVal;
|
u_crc_val ^= ((unsigned char) (u_crc_val & 0xFF)) >> 4;
|
u_crc_val ^= u_crc_val << 12;
|
u_crc_val ^= (u_crc_val & 0xFF) << 5;
|
return u_crc_val;
|
}
|
|
unsigned short Calc_CRC_CCITT(unsigned char* pBuf, unsigned short uLength) {
|
unsigned short u_crc_ccitt;
|
for (u_crc_ccitt = 0xFFFF; uLength--; pBuf++) {
|
u_crc_ccitt = Get_CRC_CCITT(u_crc_ccitt, *pBuf);
|
}
|
return u_crc_ccitt;
|
}
|
|
#define false 0
|
#define true 1
|
//Android UART protocol define
|
#define UART_Preamble_OFFSET 0
|
#define UART_Size_OFFSET 1
|
#define UART_Service_ID_OFFSET 2
|
#define UART_Service_Frame_OFFSET 3
|
//L_Data_Standard Frame size
|
const unsigned char DataSize_TAB[16] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 1,
|
1, 2, 3, 4, 6, 8, 10, 14, 14 };
|
#define DATA_Type_1BIT 0
|
#define DATA_Type_2BIT 1
|
#define DATA_Type_3BIT 2
|
#define DATA_Type_4BIT 3
|
#define DATA_Type_5BIT 4
|
#define DATA_Type_6BIT 5
|
#define DATA_Type_7BIT 6
|
#define DATA_Type_8BIT 7
|
#define DATA_Type_2byte 8
|
#define DATA_Type_3byte 9
|
#define DATA_Type_4byte 10
|
#define DATA_Type_6byte 11
|
#define DATA_Type_8byte 12
|
#define DATA_Type_10byte 13
|
#define DATA_Type_14byte 14
|
//get short group address from main, middle, sub
|
#define EIB_Group_Addr3(main, middle, sub) ((main&0x0f)<<11|(middle&0x07)<<8|(sub&0x0ff))
|
// frame service
|
#define A_SERVICE_NO 0
|
#define A_SERVICE_L_Data_Frame_req 1
|
#define A_SERVICE_L_Data_Frame_ind 3
|
//----------------------------------------------------------------------------------------------------//
|
//this function encode group telegram to *p_suart_buf.
|
//source_addr:Individual address
|
//dest_addr:Group address
|
//*p_data:data for send
|
//data_type:data type 1 bit..14 bytes
|
//*p_suart_buf: send this buf to uart
|
//this function return send size
|
//----------------------------------------------------------------------------------------------------//
|
unsigned char UART_EncodeGroupTelegram(unsigned short source_addr,
|
unsigned short dest_addr, unsigned char *p_data,
|
unsigned char data_type, unsigned char *p_suart_buf) {
|
unsigned char crc_h, crc_l, count, data_size, l_data_len, uart_size;
|
unsigned short crc;
|
p_suart_buf[UART_Service_Frame_OFFSET + 0] = 0xBC;
|
p_suart_buf[UART_Service_Frame_OFFSET + 1] = (unsigned char) ((source_addr
|
>> 8) & 0x00ff);
|
p_suart_buf[UART_Service_Frame_OFFSET + 2] = (unsigned char) (source_addr
|
& 0x00ff);
|
p_suart_buf[UART_Service_Frame_OFFSET + 3] = (unsigned char) ((dest_addr
|
>> 8) & 0x00ff);
|
p_suart_buf[UART_Service_Frame_OFFSET + 4] = (unsigned char) (dest_addr
|
& 0x00ff);
|
p_suart_buf[UART_Service_Frame_OFFSET + 5] = 0xE0;
|
p_suart_buf[UART_Service_Frame_OFFSET + 6] = 0x00;
|
p_suart_buf[UART_Service_Frame_OFFSET + 7] = 0x80;
|
if (data_type < 6) {
|
p_suart_buf[UART_Service_Frame_OFFSET + 5] |= 0x01;
|
p_suart_buf[UART_Service_Frame_OFFSET + 7] |= p_data[0]
|
& DataSize_TAB[data_type];
|
} else {
|
data_size = DataSize_TAB[data_type];
|
p_suart_buf[UART_Service_Frame_OFFSET + 5] |= data_size + 1;
|
for (count = 0; count < data_size; count++)
|
p_suart_buf[UART_Service_Frame_OFFSET + 8 + count] = p_data[count];
|
}
|
l_data_len = (p_suart_buf[UART_Service_Frame_OFFSET + 5] & 0x0f) + 7;
|
uart_size = l_data_len + 5;
|
p_suart_buf[UART_Preamble_OFFSET] = 0xAA;
|
p_suart_buf[UART_Size_OFFSET] = uart_size;
|
p_suart_buf[UART_Service_ID_OFFSET] = A_SERVICE_L_Data_Frame_req;
|
crc = Calc_CRC_CCITT(p_suart_buf, uart_size - 2);
|
crc_h = (unchar) ((crc >> 8) & 0x00ff);
|
crc_l = (unchar) (crc & 0x00ff);
|
p_suart_buf[A_Service_Frame_OFFSET + l_data_len] = crc_h;
|
p_suart_buf[A_Service_Frame_OFFSET + l_data_len + 1] = crc_l;
|
return uart_size;
|
}
|
//----------------------------------------------------------------------------------------------------//
|
//this function decode the *p_ruart_buf telegram to:
|
//*p_source_addr,*p_dest_addr,*p_data,*p_data_size
|
//return true: decoding success
|
//return false: decoding failure
|
//----------------------------------------------------------------------------------------------------//
|
unsigned char UART_DecodeGroupTelegram(unsigned short *p_source_addr,
|
unsigned short *p_dest_addr, unsigned char *p_data,
|
unsigned char *p_data_size, unsigned char *p_ruart_buf) {
|
unchar crc_h, crc_l, count, data_size, uart_size;
|
unint crc;
|
uart_size = p_ruart_buf[UART_Size_OFFSET];
|
if (uart_size < 13)
|
return false;
|
crc = Calc_CRC_CCITT(p_ruart_buf, uart_size - 2);
|
crc_h = (unchar) ((crc >> 8) & 0x00ff);
|
crc_l = (unchar) (crc & 0x00ff);
|
if ((crc_h != p_ruart_buf[uart_size - 2])
|
|| (crc_l != p_ruart_buf[uart_size - 1]))
|
return false; //check CRC
|
if (p_ruart_buf[UART_Service_ID_OFFSET] != A_SERVICE_L_Data_Frame_ind)
|
return false; //ind frame
|
if ((p_ruart_buf[UART_Service_Frame_OFFSET] & 0xd3) != 0x90)
|
return false;
|
if ((p_ruart_buf[UART_Service_Frame_OFFSET + 5] & 0x80) != 0x80)
|
return false; //not group telegram
|
*p_source_addr = p_ruart_buf[UART_Service_Frame_OFFSET + 1];
|
*p_source_addr <<= 8;
|
*p_source_addr |= p_ruart_buf[UART_Service_Frame_OFFSET + 2];
|
*p_dest_addr = p_ruart_buf[UART_Service_Frame_OFFSET + 3];
|
*p_dest_addr <<= 8;
|
*p_dest_addr |= p_ruart_buf[UART_Service_Frame_OFFSET + 4];
|
data_size = p_ruart_buf[UART_Service_Frame_OFFSET + 5] & 0x0f;
|
if (data_size == 1) {
|
p_data[0] = p_ruart_buf[UART_Service_Frame_OFFSET + 7] & 0x3f;
|
} else {
|
for (count = 0; count < (data_size - 1); count++)
|
p_data[count] = p_ruart_buf[UART_Service_Frame_OFFSET + 8 + count];
|
data_size -= 1;
|
}
|
*p_data_size = data_size;
|
return true;
|
}
|
|
void UART_Send(void) {
|
unsigned short individual_addr = 0x1101; //1.1.1
|
unsigned short group_addr = EIB_Group_Addr3(1,0,1); //1/0/1
|
unsigned char data_buf[2], suart_buf[22 + 5];
|
unsigned char uart_size;
|
data_buf[0] = 0x01; //ON (unsigned char)int
|
uart_size = UART_EncodeGroupTelegram(individual_addr, group_addr, data_buf,
|
DATA_Type_1BIT, suart_buf);
|
}
|
|
JNIEXPORT jbyteArray JNICALL Java_android_serialport_api_sample_KNX_get_1SendBuffer(
|
JNIEnv *env, jclass thiz, jint _individual_addr, jint obj1, jint obj2,
|
jint obj3, jint on_off) {
|
|
unsigned short individual_addr = (unsigned short) _individual_addr;
|
|
unsigned short group_addr =
|
EIB_Group_Addr3((unsigned char)obj1,(unsigned char)obj2,(unsigned char)obj3); //1/0/1
|
unsigned char data_buf[2], suart_buf[22 + 5];
|
unsigned char uart_size;
|
data_buf[0] = (unsigned char) on_off; //0x01; //ON (unsigned char)int
|
uart_size = UART_EncodeGroupTelegram(individual_addr, group_addr, data_buf,
|
DATA_Type_1BIT, suart_buf);
|
|
jbyteArray array = (*env)->NewByteArray(env, 27);
|
|
(*env)->SetByteArrayRegion(env, array, 0, 27, suart_buf);
|
|
return array;
|
}
|
|
JNIEXPORT jboolean JNICALL Java_android_serialport_api_sample_KNX_Parity_1Data(
|
JNIEnv *env, jclass thiz, jbyteArray buffer) {
|
|
unchar *p_ruart_buf = (unchar *) buffer;
|
unsigned short individual_addr, group_addr;
|
unsigned char data_buf[14];
|
unsigned char data_size;
|
if (!UART_DecodeGroupTelegram(&individual_addr, &group_addr, data_buf,
|
&data_size, p_ruart_buf))
|
return false;
|
return true;
|
}
|
|
unsigned short Individual_addr, Group_addr;
|
unsigned char Data_buf[14];
|
|
JNIEXPORT jboolean JNICALL Java_android_serialport_api_sample_KNX_UART_1Receive(
|
JNIEnv *env, jclass thiz, jbyteArray array) {
|
|
jint len = (*env)->GetArrayLength(env, array);
|
|
unchar p_ruart_buf[len];
|
|
(*env)->GetByteArrayRegion(env, array, 0, len, p_ruart_buf);
|
|
unsigned char data_size;
|
|
if (!UART_DecodeGroupTelegram(&Individual_addr, &Group_addr, Data_buf,
|
&data_size, p_ruart_buf))
|
return false;
|
|
return true;
|
}
|
|
JNIEXPORT jint JNICALL Java_android_serialport_api_sample_KNX_get_1Individual_1addr(
|
JNIEnv *env, jclass thiz) {
|
|
return (jint) Individual_addr;
|
}
|
|
JNIEXPORT jint JNICALL Java_android_serialport_api_sample_KNX_get_1Group_1addr(
|
JNIEnv *env, jclass thiz) {
|
|
return (jint) Group_addr;
|
|
}
|
JNIEXPORT jint JNICALL Java_android_serialport_api_sample_KNX_set_1Group_1addr(
|
JNIEnv *env, jclass thiz, jint obj1, jint obj2, jint obj3) {
|
unsigned short group_addr =
|
EIB_Group_Addr3((unsigned char)obj1,(unsigned char)obj2,(unsigned char)obj3);
|
|
return (jint) group_addr;
|
}
|
|
JNIEXPORT jint JNICALL Java_android_serialport_api_sample_KNX_get_1State(
|
JNIEnv *env, jclass thiz) {
|
|
return (jint) Data_buf[0];
|
}
|