RedisModule/source/moduleiec.c

250 lines
7.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
** 入参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;
}