138 lines
3.3 KiB
C
138 lines
3.3 KiB
C
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include "../include/redismodule.h"
|
|
#include "../include/moduleiec.h"
|
|
|
|
extern Idx2Infos;
|
|
|
|
uint16_t getLeInt16(const uint8_t *bytes) {
|
|
return (bytes[1] << 8) | bytes[0];
|
|
}
|
|
|
|
uint32_t getLeInt32(const uint8_t *bytes) {
|
|
return (bytes[3]<<24 | bytes[2]<<16 | bytes[1]<<8 | bytes[0]);
|
|
}
|
|
|
|
void getLeUint16Bytes(char *bytes, uint16_t uint16) {
|
|
bytes[0] = (char)uint16;
|
|
bytes[1] = (char)(uint16>>8);
|
|
}
|
|
|
|
void updateTimeBytes(Info *info, char *begin) {
|
|
if (info->tms == NULL) {
|
|
info->tms = (char *)malloc(8 *sizeof(char));
|
|
}
|
|
|
|
if (begin == NULL) {
|
|
struct timeb tms;
|
|
ftime(&tms);
|
|
|
|
time_t ts;
|
|
time(&ts);
|
|
struct tm *datetime = localtime(&ts);
|
|
|
|
char smsBytes[2] = {0};
|
|
getLeUint16Bytes(smsBytes, tms.millitm+1000*datetime->tm_sec);
|
|
|
|
info->tms[0] = smsBytes[0];
|
|
info->tms[1] = smsBytes[1];
|
|
info->tms[2] = (char)datetime->tm_min;
|
|
info->tms[3] = (char)datetime->tm_hour;
|
|
info->tms[4] = (char)datetime->tm_mday;
|
|
info->tms[5] = (char)datetime->tm_mon;
|
|
info->tms[6] = (char)(datetime->tm_year - 2000);
|
|
}else{
|
|
info->tms[0] = begin[0];
|
|
info->tms[1] = begin[1];
|
|
info->tms[2] = begin[2];
|
|
info->tms[3] = begin[3];
|
|
info->tms[4] = begin[4];
|
|
info->tms[5] = begin[5];
|
|
info->tms[6] = begin[6];
|
|
}
|
|
|
|
info->tms[7] = '\0';
|
|
}
|
|
|
|
void updateInfoBytes(Info *info, char *begin, int length) {
|
|
if (info->info == NULL) {
|
|
info->info = (char *)malloc(6 *sizeof(char));
|
|
}
|
|
|
|
for (int i = 0;i < length;i++) {
|
|
info->info[i] = begin[i];
|
|
}
|
|
|
|
info->info[length] = '\0';
|
|
}
|
|
|
|
void updateCauseBytes(Info *info, char *begin) {
|
|
if (info->cause == NULL) {
|
|
info->cause = (char *)malloc(3 *sizeof(char));
|
|
}
|
|
|
|
info->cause[0] = begin[0];
|
|
info->cause[1] = begin[1];
|
|
info->cause[2] = '\0';
|
|
}
|
|
|
|
|
|
// 轻解构 ASDU
|
|
int updateInfos(const char *src) {
|
|
if (src == NULL || strlen(src) < 10) { // TODO ASDU最小有效长度 10
|
|
return 0;
|
|
}
|
|
|
|
char pubAddrBytes[2] = {src[4],src[5]};
|
|
int pubIdx = parseLeInt16(pubAddrBytes);
|
|
if (Idx2Infos[pubIdx] == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
char type = src[0];
|
|
|
|
bool sequence = src[1] & 128 >> 7 == 1;
|
|
|
|
int count = src[1];
|
|
if (sequence) {
|
|
count = src[1] - 1 << 7;
|
|
}
|
|
|
|
int infoIdx = 0;
|
|
if (sequence) {
|
|
char firstAddrBytes[4] = {src[6],src[7],src[8],0x00};
|
|
infoIdx = parseLeInt32(firstAddrBytes);
|
|
}
|
|
|
|
for (int i = 0;i < count; i++) {
|
|
int size;
|
|
int infoBegin;
|
|
|
|
switch (type) {
|
|
case M_SP_NA_1:
|
|
case M_DP_NA_1:
|
|
size = 4;
|
|
infoBegin = src + 9 + i;
|
|
if (!sequence) {
|
|
char addrBytes[4] = {src[6 + i*size], src[6 + i*size + 1], src[6 + i*size + 2], 0x00};
|
|
infoIdx = parseLeInt32(addrBytes);
|
|
infoBegin = src + 6 + i*size + 3;
|
|
}
|
|
|
|
updateTimeBytes(Idx2Infos[pubIdx][infoIdx], NULL);
|
|
updateInfoBytes(Idx2Infos[pubIdx][infoIdx], infoBegin, 1);
|
|
updateCauseBytes(Idx2Infos[pubIdx][infoIdx], src+2);
|
|
break;
|
|
case M_ME_NA_1:
|
|
|
|
default:
|
|
return 0;
|
|
}
|
|
|
|
if (sequence) {
|
|
infoIdx++;
|
|
}
|
|
}
|
|
} |