250 lines
7.2 KiB
C
250 lines
7.2 KiB
C
/*
|
||
** 入参:ASDU
|
||
**
|
||
** 定量
|
||
** Key: info_<PubIdx>_<InfoIdx>
|
||
** Field: 测点类型,公共地址,测点地址,报警规则,测点名称,···
|
||
**
|
||
** 变量
|
||
** PubIdx-->InfoIdx-->Info(bytes)
|
||
*/
|
||
|
||
#include <string.h>
|
||
#include "../include/redismodule.h"
|
||
#include "../include/moduleiec.h"
|
||
|
||
Info ***Idx2Infos;
|
||
|
||
int updateInfos(const char * str);
|
||
|
||
int IECSetVar(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||
// 校验参数
|
||
if (argc < 1+1) {
|
||
RedisModule_WrongArity(ctx);
|
||
return REDISMODULE_ERR;
|
||
}
|
||
|
||
// 处理参数
|
||
for (int i = 1; i < argc; i++) {
|
||
// 轻解构 --> Info *info
|
||
if (updateInfos(argv[i]) == 0) {
|
||
return REDISMODULE_ERR;
|
||
}
|
||
}
|
||
|
||
RedisModule_ReplyWithLongLong(ctx, argc);
|
||
return REDISMODULE_OK;
|
||
}
|
||
|
||
//
|
||
int IECGetAll(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||
// 校验参数: 公共地址 + 信息体地址/偏移量
|
||
if (argc < 1+2) {
|
||
RedisModule_WrongArity(ctx);
|
||
return REDISMODULE_ERR;
|
||
}
|
||
|
||
// 初始化处理参数
|
||
long long pubIdx = -1;
|
||
long long infoIdx = -1;
|
||
RedisModule_StringToLongLong(argv[1], &pubIdx);
|
||
if (pubIdx < 0 || pubIdx >= PUB_IDX_COUNT) {
|
||
RedisModule_WrongArity(ctx);
|
||
return REDISMODULE_ERR;
|
||
}
|
||
RedisModule_StringToLongLong(argv[2], &infoIdx);
|
||
if (infoIdx < 0 || infoIdx >= INFO_IDX_COUNT) {
|
||
RedisModule_WrongArity(ctx);
|
||
return REDISMODULE_ERR;
|
||
}
|
||
|
||
// 处理计算数据
|
||
struct Info **infos = Idx2Infos[pubIdx];
|
||
if (infos == NULL) {
|
||
RedisModule_WrongArity(ctx);
|
||
return REDISMODULE_ERR;
|
||
}
|
||
|
||
struct Info *info = infos[infoIdx];
|
||
if (info == NULL) {
|
||
RedisModule_ReplyWithNull(ctx);
|
||
return REDISMODULE_OK;
|
||
}
|
||
|
||
//
|
||
char key[128];
|
||
sprintf(key, "info_%d_%d", pubIdx, infoIdx); // TODO
|
||
RedisModuleCallReply *reply = RedisModule_Call(ctx, "HGETALL", "s", key);
|
||
// 检查回复类型
|
||
if (RedisModule_CallReplyType(reply) != REDISMODULE_REPLY_ARRAY) {
|
||
// 错误处理...
|
||
}
|
||
|
||
// 回复数据
|
||
RedisModule_ReplyWithArray(ctx, VAR_IDX_COUNT); // TODO
|
||
RedisModule_ReplyWithString(ctx,info->cause);
|
||
RedisModule_ReplyWithString(ctx,info->info);
|
||
RedisModule_ReplyWithString(ctx,info->tms);
|
||
// 遍历回复中的每一对键值
|
||
for (size_t i = 0; i < RedisModule_CallReplyLength(reply); i += 2) {
|
||
RedisModuleCallReply *keyReply = RedisModule_CallReplyArrayElement(reply, i);
|
||
RedisModuleCallReply *valueReply = RedisModule_CallReplyArrayElement(reply, i + 1);
|
||
|
||
// 获取键和值
|
||
RedisModuleString *keyStr = RedisModule_CreateStringFromCallReply(keyReply);
|
||
RedisModuleString *valueStr = RedisModule_CreateStringFromCallReply(valueReply);
|
||
|
||
// 使用键和值...
|
||
|
||
// 释放字符串对象
|
||
RedisModule_FreeString(ctx, keyStr);
|
||
RedisModule_FreeString(ctx, valueStr);
|
||
}
|
||
|
||
// 释放回复对象
|
||
RedisModule_FreeCallReply(reply);
|
||
|
||
return REDISMODULE_OK;
|
||
}
|
||
|
||
//
|
||
int IECGetVar(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||
// 校验参数: 公共地址 + 信息体地址/偏移量 + field
|
||
if (argc < 1+2) {
|
||
RedisModule_WrongArity(ctx);
|
||
return REDISMODULE_ERR;
|
||
}
|
||
|
||
// 初始化处理参数
|
||
long long pubIdx = -1;
|
||
long long infoIdx = -1;
|
||
long long fieldIdx = -1;
|
||
RedisModule_StringToLongLong(argv[1], &pubIdx);
|
||
if (pubIdx < 0 || pubIdx >= PUB_IDX_COUNT) {
|
||
RedisModule_WrongArity(ctx);
|
||
return REDISMODULE_ERR;
|
||
}
|
||
RedisModule_StringToLongLong(argv[2], &infoIdx);
|
||
if (infoIdx < 0 || infoIdx >= INFO_IDX_COUNT) {
|
||
RedisModule_WrongArity(ctx);
|
||
return REDISMODULE_ERR;
|
||
}
|
||
if (argc > 1+2) {
|
||
RedisModule_StringToLongLong(argv[3], &fieldIdx);
|
||
if (fieldIdx < 0 || fieldIdx > VAR_IDX_COUNT) {
|
||
RedisModule_WrongArity(ctx);
|
||
return REDISMODULE_ERR;
|
||
}
|
||
}
|
||
|
||
// 处理计算数据
|
||
struct Info **infos = Idx2Infos[pubIdx];
|
||
if (infos == NULL) {
|
||
RedisModule_WrongArity(ctx);
|
||
return REDISMODULE_ERR;
|
||
}
|
||
|
||
struct Info *info = infos[infoIdx];
|
||
if (info == NULL) {
|
||
RedisModule_ReplyWithNull(ctx);
|
||
return REDISMODULE_OK;
|
||
}
|
||
|
||
// 回复数据
|
||
if (argc == 1+2) {
|
||
RedisModule_ReplyWithArray(ctx, VAR_IDX_COUNT);
|
||
RedisModule_ReplyWithString(ctx,info->cause);
|
||
RedisModule_ReplyWithString(ctx,info->info);
|
||
RedisModule_ReplyWithString(ctx,info->tms);
|
||
}else if (argc > 1+2) {
|
||
switch (fieldIdx) {
|
||
case 0:
|
||
RedisModule_ReplyWithArray(ctx, 1);
|
||
RedisModule_ReplyWithString(ctx, info->cause);
|
||
break;
|
||
case 1:
|
||
RedisModule_ReplyWithArray(ctx, 1);
|
||
RedisModule_ReplyWithString(ctx, info->info);
|
||
break;
|
||
case 2:
|
||
RedisModule_ReplyWithArray(ctx, 1);
|
||
RedisModule_ReplyWithString(ctx, info->tms);
|
||
break;
|
||
default:
|
||
RedisModule_ReplyWithNull(ctx);
|
||
}
|
||
}
|
||
|
||
// 返回
|
||
return REDISMODULE_OK;
|
||
}
|
||
|
||
// 启动参数:缓冲区编码(默认128全初始化)
|
||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||
int pubIdxCount = PUB_IDX_COUNT;
|
||
int initCount = PUB_IDX_COUNT;
|
||
|
||
if (argc == 1) {
|
||
unsigned long long index;
|
||
RedisModule_StringToULongLong(argv[0], &index);
|
||
|
||
if (index > PUB_IDX_COUNT) {
|
||
pubIdxCount = index;
|
||
initCount = index;
|
||
}
|
||
}
|
||
|
||
if (argc > 0 && argc < PUB_IDX_COUNT) {
|
||
initCount = argc;
|
||
}
|
||
|
||
Idx2Infos = (Info ***)malloc(pubIdxCount * sizeof(Info **));
|
||
if (Idx2Infos == NULL) {
|
||
return REDISMODULE_ERR;
|
||
}
|
||
memset(Idx2Infos, 0, pubIdxCount);
|
||
|
||
for (int i = 0; i < initCount; i++) {
|
||
Info **infos = (Info **)malloc(INFO_IDX_COUNT*sizeof(Info *));
|
||
if (infos == NULL) {
|
||
return REDISMODULE_ERR;
|
||
}
|
||
memset(infos, 0, INFO_IDX_COUNT);
|
||
|
||
for (int j = 0;j < INFO_IDX_COUNT; j++) {
|
||
infos[j] = (Info *)malloc(sizeof(Info));
|
||
memset(infos[j], 0, sizeof(Info));
|
||
}
|
||
|
||
if (initCount < pubIdxCount) {
|
||
unsigned long long index;
|
||
RedisModule_StringToULongLong(argv[i], &index);
|
||
if (index < 0 || index > PUB_IDX_COUNT) {
|
||
return REDISMODULE_ERR;
|
||
}
|
||
Idx2Infos[index] = infos;
|
||
}else{
|
||
Idx2Infos[i] = infos;
|
||
}
|
||
}
|
||
|
||
|
||
const char *module = "moduleiec";
|
||
const char *cmdSetVar = "iec.setvar";
|
||
const char *cmdGetAll = "iec.getall";
|
||
const char *cmdGetVar = "iec.getvar";
|
||
|
||
if (RedisModule_Init(ctx, module, 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR)
|
||
return REDISMODULE_ERR;
|
||
|
||
if (RedisModule_CreateCommand(ctx, cmdSetVar, IECSetVar, "", 0, 0, 0) == REDISMODULE_ERR)
|
||
return REDISMODULE_ERR;
|
||
|
||
if (RedisModule_CreateCommand(ctx, cmdGetAll, IECGetAll, "", 0, 0, 0) == REDISMODULE_ERR)
|
||
return REDISMODULE_ERR;
|
||
|
||
if (RedisModule_CreateCommand(ctx, cmdGetVar, IECGetVar, "", 0, 0, 0) == REDISMODULE_ERR)
|
||
return REDISMODULE_ERR;
|
||
|
||
return REDISMODULE_OK;
|
||
} |