void ModbusSlaveProtocol::TCP_getData(const Buffer& blck, ModbusCmd& cmd, api_error& e) { unsigned char* msg = reinterpret_cast<unsigned char*>(blck.getR()); // check message size at less 6 bytes if (blck.getRSize() < MODBUS_TCP_PRESET_REQ_LENGTH) return e.seteof();; // check transation id cmd.transation_id = msg[0] * 0x100 + msg[1]; if (msg[2] != 0 || msg[3] != 0) throw error_api(ERROR_INFO(), api_error::get_protocol()); cmd.desire_size = msg[4] * 0x100 + msg[5] + MODBUS_TCP_PRESET_REQ_LENGTH; if (blck.getRSize() < cmd.desire_size) return e.seteof(); //blck.update // adjust message begin to make similar to rtu msg += MODBUS_TCP_PRESET_REQ_LENGTH; cmd.slave = msg[0]; cmd.function = static_cast<ModbusCmd::ModBusFunctions>(msg[1]); getFunctionParameters(cmd); if ((cmd.function == ModbusCmd::MODBUS_FC_READ_INPUT_REGISTERS) || (cmd.function == ModbusCmd::MODBUS_FC_READ_DISCRETE_INPUTS) || (cmd.function == ModbusCmd::MODBUS_FC_READ_COILS) || (cmd.function == ModbusCmd::MODBUS_FC_READ_HOLDING_REGISTERS)) { cmd.desire_size = 8; if (blck.getRSize() < cmd.desire_size) return e.seteof();; cmd.start_address = msg[2] * 0x100 + msg[3]; cmd.count = msg[4] * 0x100 + msg[5]; } else if ((cmd.function == ModbusCmd::MODBUS_FC_WRITE_MULTIPLE_COILS) || (cmd.function == ModbusCmd::MODBUS_FC_WRITE_MULTIPLE_REGISTERS)) { if (blck.getRSize() < 9) return e.seteof();; cmd.start_address = msg[2] * 0x100 + msg[3]; cmd.count = msg[4] * 0x100 + msg[5]; cmd.byte_count = msg[6]; cmd.vdata = &msg[7]; cmd.desire_size = 9 + cmd.byte_count; if (blck.getRSize() < cmd.desire_size) return e.seteof();; } else if ((cmd.function == ModbusCmd::MODBUS_FC_WRITE_SINGLE_REGISTER) || (cmd.function == ModbusCmd::MODBUS_FC_WRITE_SINGLE_COIL)) { cmd.desire_size = 8; if (blck.getRSize() < cmd.desire_size) return e.seteof();; cmd.count = 1; cmd.start_address = msg[2] * 0x100 + msg[3]; cmd.vdata = &msg[4]; } }
void ModbusSlaveProtocol::ELAM_getData(const Buffer& blck, ModbusCmd& cmd, api_error& e) { unsigned char* msg = reinterpret_cast<unsigned char*>(blck.getR()); if (blck.getRSize() < 5) return e.seteof();; cmd.slave = msg[0]; if ((cmd.slave & 0xF8) == 0xF8) // slave address > 248 are elam extended address { cmd.slave = msg[0] * 0x100 + msg[1]; msg++; } cmd.function = static_cast<ModbusCmd::ModBusFunctions>(msg[1]); getFunctionParameters(cmd); if ((cmd.function == ModbusCmd::MODBUS_FC_READ_INPUT_REGISTERS) || (cmd.function == ModbusCmd::MODBUS_FC_READ_DISCRETE_INPUTS) || (cmd.function == ModbusCmd::MODBUS_FC_READ_COILS) || (cmd.function == ModbusCmd::MODBUS_FC_READ_HOLDING_REGISTERS)) { cmd.desire_size = 8; if (blck.getRSize() < cmd.desire_size) return e.seteof(); cmd.start_address = msg[2] * 0x100 + msg[3]; cmd.count = msg[4] * 0x100 + msg[5]; } else if ((cmd.function == ModbusCmd::MODBUS_FC_WRITE_MULTIPLE_COILS) || (cmd.function == ModbusCmd::MODBUS_FC_WRITE_MULTIPLE_REGISTERS)) { if (blck.getRSize() < 9) return e.seteof();; cmd.start_address = msg[2] * 0x100 + msg[3]; cmd.count = msg[4] * 0x100 + msg[5]; cmd.byte_count = msg[6]; cmd.vdata = &msg[7]; cmd.desire_size = 9 + cmd.byte_count; if (blck.getRSize() < cmd.desire_size) return e.seteof();; } else if ((cmd.function == ModbusCmd::MODBUS_FC_WRITE_SINGLE_REGISTER) || (cmd.function == ModbusCmd::MODBUS_FC_WRITE_SINGLE_COIL)) { cmd.desire_size = 8; if (blck.getRSize() < cmd.desire_size) return e.seteof();; cmd.count = 1; cmd.start_address = msg[2] * 0x100 + msg[3]; cmd.vdata = &msg[4]; } CheckCRC16(msg, cmd.desire_size); }
void TLValueTrackingTraverser::traverseAggregate(TIntermAggregate *node) { bool visit = true; TIntermSequence *sequence = node->getSequence(); if (node->getOp() == EOpPrototype) { addToFunctionMap(node->getFunctionSymbolInfo()->getNameObj(), sequence); } if (preVisit) visit = visitAggregate(PreVisit, node); if (visit) { bool inFunctionMap = false; if (node->getOp() == EOpFunctionCall) { inFunctionMap = isInFunctionMap(node); if (!inFunctionMap) { // The function is not user-defined - it is likely built-in texture function. // Assume that those do not have out parameters. setInFunctionCallOutParameter(false); } } incrementDepth(node); if (inFunctionMap) { TIntermSequence *params = getFunctionParameters(node); TIntermSequence::iterator paramIter = params->begin(); for (auto *child : *sequence) { ASSERT(paramIter != params->end()); TQualifier qualifier = (*paramIter)->getAsTyped()->getQualifier(); setInFunctionCallOutParameter(qualifier == EvqOut || qualifier == EvqInOut); child->traverse(this); if (visit && inVisit) { if (child != sequence->back()) visit = visitAggregate(InVisit, node); } ++paramIter; } setInFunctionCallOutParameter(false); } else { // Find the built-in function corresponding to this op so that we can determine the // in/out qualifiers of its parameters. TFunction *builtInFunc = nullptr; TString opString = GetOperatorString(node->getOp()); if (!node->isConstructor() && !opString.empty()) { // The return type doesn't affect the mangled name of the function, which is used // to look it up from the symbol table. TType dummyReturnType; TFunction call(&opString, &dummyReturnType, node->getOp()); for (auto *child : *sequence) { TType *paramType = child->getAsTyped()->getTypePointer(); TConstParameter p(paramType); call.addParameter(p); } TSymbol *sym = mSymbolTable.findBuiltIn(call.getMangledName(), mShaderVersion); if (sym != nullptr && sym->isFunction()) { builtInFunc = static_cast<TFunction *>(sym); ASSERT(builtInFunc->getParamCount() == sequence->size()); } } size_t paramIndex = 0; for (auto *child : *sequence) { TQualifier qualifier = EvqIn; if (builtInFunc != nullptr) qualifier = builtInFunc->getParam(paramIndex).type->getQualifier(); setInFunctionCallOutParameter(qualifier == EvqOut || qualifier == EvqInOut); child->traverse(this); if (visit && inVisit) { if (child != sequence->back()) visit = visitAggregate(InVisit, node); } ++paramIndex; } setInFunctionCallOutParameter(false); } decrementDepth(); } if (visit && postVisit) visitAggregate(PostVisit, node); }