/** * Parses an open message * * \details * Reads the open message from buffer. The parsed data will be * returned via the out params. * * \param [in] data Pointer to raw bgp payload data, starting at the notification message * \param [in] size Size of the data available to read; prevent overrun when reading * \param [out] asn Reference to the ASN that was discovered * \param [out] holdTime Reference to the hold time * \param [out] bgp_id Reference to string for bgp ID in printed form * \param [out] capabilities Reference to the capabilities list<string> (decoded values) * * \return ZERO is error, otherwise a positive value indicating the number of bytes read for the open message */ size_t OpenMsg::parseOpenMsg(u_char *data, size_t size, uint32_t &asn, uint16_t &holdTime, std::string &bgp_id, std::list<std::string> &capabilities) { char bgp_id_char[16]; size_t read_size = 0; u_char *bufPtr = data; open_bgp_hdr open_hdr = {0}; capabilities.clear(); /* * Make sure available size is large enough for an open message */ if (size < sizeof(open_hdr)) { LOG_WARN("%s: Cloud not read open message due to buffer having less bytes than open message size", peer_addr.c_str()); return 0; } memcpy(&open_hdr, bufPtr, sizeof(open_hdr)); read_size = sizeof(open_hdr); bufPtr += read_size; // Move pointer past the open header // Change to host order bgp::SWAP_BYTES(&open_hdr.hold); bgp::SWAP_BYTES(&open_hdr.asn); // Update the output params holdTime = open_hdr.hold; asn = open_hdr.asn; inet_ntop(AF_INET, &open_hdr.bgp_id, bgp_id_char, sizeof(bgp_id_char)); bgp_id.assign(bgp_id_char); SELF_DEBUG("%s: Open message:ver=%d hold=%u asn=%hu bgp_id=%s params_len=%d", peer_addr.c_str(), open_hdr.ver, open_hdr.hold, open_hdr.asn, bgp_id.c_str(), open_hdr.param_len); /* * Make sure the buffer contains the rest of the open message, but allow a zero length in case the * data is missing on purpose (router implementation) */ if (open_hdr.param_len == 0) { LOG_WARN("%s: Capabilities in open message is ZERO/empty, this is abnormal and likely a router implementation issue.", peer_addr.c_str()); return read_size; } else if (open_hdr.param_len > (size - read_size)) { LOG_WARN("%s: Could not read capabilities in open message due to buffer not containing the full param length", peer_addr.c_str()); return 0; } if (!parseCapabilities(bufPtr, open_hdr.param_len, asn, capabilities)) { LOG_WARN("%s: Could not read capabilities correctly in buffer, message is invalid.", peer_addr.c_str()); return 0; } read_size += open_hdr.param_len; return read_size; }
bool AvolitesD4Parser::parseChannels(const QDomElement& elem, QLCFixtureDef* fixtureDef) { QDomElement el = elem.firstChildElement(KD4TagAttribute); for (; !el.isNull(); el = el.nextSiblingElement(KD4TagAttribute)) { // Small integrity check if (el.attribute(KD4TagID).isEmpty()) continue; // If this attribute is a function (i.e. an attribute used as a control variable for other attributes) // then we just ignore it and continue. We can check it by checking if attribute Update on a <Function/> exists if (isFunction(el)) continue; QLCChannel* chan = new QLCChannel(); chan->setName(el.attribute(KD4TagName)); chan->setGroup(getGroupFromXML(el)); chan->setColour(getColourFromXML(el)); chan->setControlByte(QLCChannel::MSB); // add channel to fixture definition fixtureDef->addChannel(chan); m_channels.insert(el.attribute(KD4TagID), chan); // if this channel is a NoGroup then we don't need to continue // no capabilities nor 16 bit channel if (chan->group() == QLCChannel::NoGroup) continue; // parse capabilities if (!parseCapabilities(el, chan)) { m_channels.remove(el.attribute(KD4TagID)); delete chan; return false; } // If we have a DMX attribute higher than 255 means we have an attribute with a 16bit precision // so, we add another channel, with 'Fine' appended to it's name and set the LSB controlbyte // NOTE: this can be changed in the future, pending the revamp over adding 16bit capabilities to any channel // not only pan/tiltm, therefore I didn't add a constant for Fine and kept it as it. if (is16Bit(el)) { QLCChannel* fchan = new QLCChannel(); fchan->setName(el.attribute(KD4TagName) + " Fine"); fchan->setGroup(getGroupFromXML(el)); fchan->setColour(getColourFromXML(el)); fchan->setControlByte(QLCChannel::LSB); // parse capabilities if (!parseCapabilities(el, fchan, true)) { delete fchan; return false; } // Finally add channel to fixture definition fixtureDef->addChannel(fchan); m_channels.insert(el.attribute(KD4TagID) + " Fine", fchan); } } return true; }
static void _model_info_merge_data (_model_info_t *self, xmlNodePtr node) { /* Define the XML element tags that we are able to merge. */ const xmlChar *device = (xmlChar *) "device"; const xmlChar *profiles = (xmlChar *) "profile-set"; const xmlChar *commands = (xmlChar *) "command-set"; const xmlChar *capabilities = (xmlChar *) "capabilities"; const xmlChar *cap_option = (xmlChar *) "option"; const xmlChar *cap_mode = (xmlChar *) "mode"; char *tmp; require (self); if (!node) return; node = node->xmlChildrenNode; while (node) { if (!xmlIsBlankNode (node)) { if (0 == xmlStrcmp (node->name, device)) { char *tmp = NULL; tmp = parseDevices (node, MODEL_OVERSEAS); if (tmp) self->overseas = tmp; tmp = parseDevices (node, MODEL_JAPAN); if (tmp) self->japan = tmp; } else if (0 == xmlStrcmp (node->name, profiles)) { EpsonScanHard profile = parseProfiles (node); if (profile) self->profile = profile; } else if (0 == xmlStrcmp (node->name, commands)) { scan_command_t *command = parseCommands_set (node); if (command) self->command = command; } else if (0 == xmlStrcmp (node->name, capabilities)) { tmp = (char *)xmlGetProp(node, (const xmlChar *) cap_mode); if(strcmp_c(tmp, "duplex") == 0){ capability_data_t *capability = parseCapabilities (node); if (capability) { self->adf_duplex = capability; self->adf_duplex->option = (char *)xmlGetProp(node, (const xmlChar *) cap_option); self->adf_duplex->mode = tmp; } }else { capability_data_t *capability = parseCapabilities (node); if (capability) { self->dfault = capability; self->dfault->option = (char *)xmlGetProp(node, (const xmlChar *) cap_option); self->dfault->mode = tmp; } } } } node = node->next; } self->from_file = true; }