Example #1
0
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__);
    }
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
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__);
    }
}
Example #5
0
 // 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);
 }
Example #6
0
 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();
	}
}
Example #9
0
 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;
 }
Example #10
0
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__);
    }
}
Example #11
0
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__);
    }
}
Example #12
0
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__);
    }
}