/* ** 入参:ASDU ** ** 定量 ** Key: info__ ** Field: 测点类型,公共地址,测点地址,报警规则,测点名称,··· ** ** 变量 ** PubIdx-->InfoIdx-->Info(bytes) */ #include #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; }