JLChen
2021-03-16 3617e6eecac94965554487afc50d39b0584324fb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
#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];
}