void HM_LC_SWX_FM::handleStateChangeMotionDetector(int32_t messageCounter, std::shared_ptr<BidCoSPacket> packet) { try { if(packet->payload()->empty()) return; int32_t channel = packet->payload()->at(0) & 0x3F; if(channel > _channelCount) return; std::shared_ptr<HomeMaticCentral> central = getCentral(); std::shared_ptr<BidCoSPeer> peer(central->getPeer(packet->senderAddress())); //Check if channel is paired to me std::shared_ptr<BasicPeer> me(peer->getPeer(channel, _address, channel)); if(!me) return; _states[channel] = true; if(packet->controlByte() & 0x20) sendStateChangeResponse(packet, channel); } catch(const std::exception& ex) { Output::printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(Exception& ex) { Output::printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(...) { Output::printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__); } }
bool MAXMessage::typeIsEqual(std::shared_ptr<MAXMessage> message, std::shared_ptr<MAXPacket> packet) { try { if(message->getMessageType() != packet->messageType()) return false; if(message->getMessageSubtype() > -1 && packet->messageSubtype() > -1 && message->getMessageSubtype() != packet->messageSubtype()) return false; std::vector<std::pair<uint32_t, int32_t>>* subtypes = message->getSubtypes(); std::vector<uint8_t>* payload = packet->payload(); if(subtypes == nullptr || subtypes->size() == 0) return true; for(std::vector<std::pair<uint32_t, int32_t> >::const_iterator i = subtypes->begin(); i != subtypes->end(); ++i) { if(i->first >= payload->size()) return false; if(payload->at(i->first) != i->second) return false; } return true; } catch(const std::exception& ex) { GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(BaseLib::Exception& ex) { GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(...) { GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__); } return false; }
bool MAXMessage::typeIsEqual(std::shared_ptr<MAXPacket> packet) { try { if(_messageType != packet->messageType() || (_messageSubtype > -1 && packet->messageSubtype() > -1 && _messageSubtype != packet->messageSubtype())) return false; std::vector<uint8_t>* payload = packet->payload(); if(_subtypes.empty()) return true; for(std::vector<std::pair<uint32_t, int32_t>>::const_iterator i = _subtypes.begin(); i != _subtypes.end(); ++i) { if(i->first >= payload->size()) return false; if(payload->at(i->first) != i->second) return false; } return true; } catch(const std::exception& ex) { GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(BaseLib::Exception& ex) { GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(...) { GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__); } return false; }
void RS485::sendPacket(std::shared_ptr<BaseLib::Systems::Packet> packet) { try { if(!packet) { _out.printWarning("Warning: Packet was nullptr."); return; } if(_fileDescriptor->descriptor == -1) throw(BaseLib::Exception("Couldn't write to CRC RS485 device, because the file descriptor is not valid: " + _settings->device)); _lastAction = BaseLib::HelperFunctions::getTime(); if(packet->payload()->size() > 132) { if(_bl->debugLevel >= 2) _out.printError("Tried to send packet with payload larger than 128 bytes. That is not supported."); return; } std::shared_ptr<HMWiredPacket> hmWiredPacket(std::dynamic_pointer_cast<HMWiredPacket>(packet)); if(!hmWiredPacket) return; std::vector<uint8_t> data = hmWiredPacket->byteArray(); writeToDevice(data, true); } catch(const std::exception& ex) { _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(BaseLib::Exception& ex) { _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(...) { _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__); } }
// internal implementation of handler for ICMP type 128 (echo requests) int echo_request(ICMPv6& caller, std::shared_ptr<PacketICMP6>& pckt) { ICMPv6::echo_header* icmp = (ICMPv6::echo_header*) pckt->payload(); debug("*** Custom handler for ICMP ECHO REQ type=%d 0x%x\n", icmp->type, htons(icmp->checksum)); // set the hoplimit manually to the very standard 64 hops pckt->set_hoplimit(64); // set to ICMP Echo Reply (129) icmp->type = ICMPv6::ECHO_REPLY; if (pckt->dst().is_multicast()) { // We won't be changing source address for multicast ping debug("Was multicast ping6: no change for source and dest\n"); } else { printf("Normal ping6: source is us\n"); printf("src is %s\n", pckt->src().str().c_str()); printf("dst is %s\n", pckt->dst().str().c_str()); printf("multicast is %s\n", IP6::addr::link_all_nodes.str().c_str()); // normal ping: send packet to source, from us pckt->set_dst(pckt->src()); pckt->set_src(caller.local_ip()); } // calculate and set checksum // NOTE: do this after changing packet contents! icmp->checksum = 0; icmp->checksum = ICMPv6::checksum(pckt); // send packet downstream return caller.transmit(pckt); }
uint16_t ICMPv6::checksum(std::shared_ptr<PacketICMP6>& pckt) { IP6::header& hdr = pckt->ip6_header(); uint16_t datalen = hdr.size(); pseudo_header phdr; // ICMP checksum is done with a pseudo header // consisting of src addr, dst addr, message length (32bits) // 3 zeroes (8bits each) and id of the next header phdr.src = hdr.src; phdr.dst = hdr.dst; phdr.len = htonl(datalen); phdr.zeros[0] = 0; phdr.zeros[1] = 0; phdr.zeros[2] = 0; phdr.next = hdr.next(); //assert(hdr.next() == 58); // ICMPv6 /** RFC 4443 2.3. Message Checksum Calculation The checksum is the 16-bit one's complement of the one's complement sum of the entire ICMPv6 message, starting with the ICMPv6 message type field, and prepended with a "pseudo-header" of IPv6 header fields, as specified in [IPv6, Section 8.1]. The Next Header value used in the pseudo-header is 58. (The inclusion of a pseudo-header in the ICMPv6 checksum is a change from IPv4; see [IPv6] for the rationale for this change.) For computing the checksum, the checksum field is first set to zero. **/ union { uint32_t whole; uint16_t part[2]; } sum; sum.whole = 0; // compute sum of pseudo header uint16_t* it = (uint16_t*) &phdr; uint16_t* it_end = it + sizeof(pseudo_header) / 2; while (it < it_end) sum.whole += *(it++); // compute sum of data it = (uint16_t*) pckt->payload(); it_end = it + datalen / 2; while (it < it_end) sum.whole += *(it++); // odd-numbered case if (datalen & 1) sum.whole += *(uint8_t*) it; return ~(sum.part[0] + sum.part[1]); }
void SynchronousResponse::handle(std::shared_ptr<ResponseWriter> writer) { auto rc = responseCode(); if (!isOk(rc)) { writer->error(rc, std::string(payload(), payloadSize())); return; } writer->begin(responseCode()); writer->header("Content-Length", toString(payloadSize())); writer->header("Content-Type", contentType()); writer->header("Connection", keepConnectionAlive() ? "keep-alive" : "close"); writer->header("Last-Modified", now()); writer->header("Pragma", "no-cache"); auto headers = getAdditionalHeaders(); if (headers.find("Cache-Control") == headers.end()) { writer->header("Cache-Control", "no-store"); } if (headers.find("Expires") == headers.end()) { writer->header("Expires", now()); } for (auto& header : headers) { writer->header(header.first, header.second); } writer->payload(payload(), payloadSize()); writer->finish(keepConnectionAlive()); }
void ReusableThread::threadFunc(std::shared_ptr<THelper> helper) { while(!helper->shutdown.load()) { { lock_guard<mutex> runGuard(helper->runMutex); helper->stepBeginMutex.unlock(); try { helper->payload(); } catch(...) { /* nop */ } } helper->stepEndMutex.lock(); } }
int neighbor_solicitation(ICMPv6& caller, std::shared_ptr<PacketICMP6>& pckt) { (void) caller; NDP::neighbor_sol* sol = (NDP::neighbor_sol*) pckt->payload(); printf("ICMPv6 NDP Neighbor solicitation request\n"); printf(">> target: %s\n", sol->target.str().c_str()); printf(">>\n"); printf(">> source: %s\n", pckt->src().str().c_str()); printf(">> dest: %s\n", pckt->dst().str().c_str()); // perhaps we should answer (void) caller; return -1; }
void CUNO::sendPacket(std::shared_ptr<BaseLib::Systems::Packet> packet) { try { if(!packet) { _out.printWarning("Warning: Packet was nullptr."); return; } if(packet->payload()->size() > 54) { if(_bl->debugLevel >= 2) _out.printError("Error: Tried to send packet larger than 64 bytes. That is not supported."); return; } if(_updateMode) { std::shared_ptr<BidCoSPacket> bidCoSPacket(std::dynamic_pointer_cast<BidCoSPacket>(packet)); if(!bidCoSPacket) return; if(!bidCoSPacket->isUpdatePacket()) { _out.printInfo("Info: Can't send packet to BidCoS peer with address 0x" + BaseLib::HelperFunctions::getHexString(packet->destinationAddress(), 6) + ", because update mode is enabled."); return; } } std::string packetString = packet->hexString(); if(_bl->debugLevel >= 4) _out.printInfo("Info: Sending (" + _settings->id + "): " + packetString); send("As" + packet->hexString() + "\n"); _lastPacketSent = BaseLib::HelperFunctions::getTime(); } catch(const std::exception& ex) { _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(BaseLib::Exception& ex) { _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(...) { _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__); } }
void COC::sendPacket(std::shared_ptr<BaseLib::Systems::Packet> packet) { try { if(!packet) { _out.printWarning("Warning: Packet was nullptr."); return; } if(!_socket) { _out.printError("Error: Couldn't write to COC device, because the device descriptor is not valid: " + _settings->device); return; } if(packet->payload()->size() > 54) { if(_bl->debugLevel >= 2) _out.printError("Error: Tried to send packet larger than 64 bytes. That is not supported."); return; } std::shared_ptr<MAXPacket> maxPacket(std::dynamic_pointer_cast<MAXPacket>(packet)); if(!maxPacket) return; std::string packetHex = packet->hexString(); if(_bl->debugLevel > 3) _out.printInfo("Info: Sending (" + _settings->id + ", WOR: " + (maxPacket->getBurst() ? "yes" : "no") + "): " + packetHex); if(maxPacket->getBurst()) writeToDevice(stackPrefix + "Zs" + packetHex + "\n" + stackPrefix + "Zr\n"); else writeToDevice(stackPrefix + "Zf" + packetHex + "\n" + stackPrefix + "Zr\n"); } catch(const std::exception& ex) { _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(BaseLib::Exception& ex) { _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(...) { _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__); } }
void TICC1100::sendPacket(std::shared_ptr<BaseLib::Systems::Packet> packet) { try { if(!packet) { _out.printWarning("Warning: Packet was nullptr."); return; } if(_fileDescriptor->descriptor == -1 || _gpioDescriptors[1]->descriptor == -1 || _stopped) return; if(packet->payload()->size() > 54) { _out.printError("Error: Tried to send packet larger than 64 bytes. That is not supported."); return; } std::shared_ptr<MAXPacket> maxPacket(std::dynamic_pointer_cast<MAXPacket>(packet)); if(!maxPacket) return; std::vector<uint8_t> packetBytes = maxPacket->byteArray(); int64_t timeBeforeLock = BaseLib::HelperFunctions::getTime(); _sendingPending = true; _txMutex.lock(); _sendingPending = false; if(_stopCallbackThread || _fileDescriptor->descriptor == -1 || _gpioDescriptors[1]->descriptor == -1 || _stopped) { _txMutex.unlock(); return; } _sending = true; sendCommandStrobe(CommandStrobes::Enum::SIDLE); sendCommandStrobe(CommandStrobes::Enum::SFTX); _lastPacketSent = BaseLib::HelperFunctions::getTime(); if(_lastPacketSent - timeBeforeLock > 100) { _out.printWarning("Warning: Timing problem. Sending took more than 100ms. Do you have enough system resources?"); } if(maxPacket->getBurst()) { sendCommandStrobe(CommandStrobes::Enum::STX); usleep(1000000); } writeRegisters(Registers::Enum::FIFO, packetBytes); if(!maxPacket->getBurst()) sendCommandStrobe(CommandStrobes::Enum::STX); if(_bl->debugLevel > 3) { if(packet->timeSending() > 0) { _out.printInfo("Info: Sending (" + _settings->id + ", WOR: " + (maxPacket->getBurst() ? "yes" : "no") + "): " + packet->hexString() + " Planned sending time: " + BaseLib::HelperFunctions::getTimeString(packet->timeSending())); } else { _out.printInfo("Info: Sending (" + _settings->id + ", WOR: " + (maxPacket->getBurst() ? "yes" : "no") + "): " + packet->hexString()); } } //Unlocking of _txMutex takes place in mainThread } catch(const std::exception& ex) { _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(BaseLib::Exception& ex) { _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(...) { _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__); } }