RedisModule/source/deconstruct.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++;
}
}
}