#include #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]; }