Welcome to mirror list, hosted at ThFree Co, Russian Federation.

MulticastResponder.cpp « Networking « src - github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: f39d120afc46cd2d3af7e87154a8a5b319981312 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
 * MulricastResponder.cpp
 *
 *  Created on: 12 Jul 2022
 *      Author: David
 */

#include "MulticastResponder.h"
#include <Platform/RepRap.h>
#include <Platform/Platform.h>

extern "C" {
#include "LwipEthernet/Lwip/src/include/lwip/udp.h"
}

#if SUPPORT_MULTICAST_DISCOVERY

static udp_pcb *ourPcb = nullptr;
static pbuf * volatile receivedPbuf = nullptr;
static volatile uint32_t receivedIpAddr;
static volatile uint16_t receivedPort;
static unsigned int messagesProcessed = 0;

static bool active = false;

// Receive callback function
extern "C" void rcvFunc(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) noexcept
{
	if (active && receivedPbuf == nullptr)
	{
		receivedIpAddr = addr->addr;
		receivedPort = port;
		receivedPbuf = p;
	}
	else
	{
		pbuf_free(p);
	}
}

void MulticastResponder::Init() noexcept
{
	// Nothing needed here yet
}

// Do some work, returning true if we did anything significant
void MulticastResponder::Spin() noexcept
{
	pbuf *rxPbuf = receivedPbuf;
	if (rxPbuf != nullptr)
	{
		debugPrintf("Rx UDP: addr %u.%u.%u.%u port %u data",
						(unsigned int)((receivedIpAddr >> 24) & 0xFF), (unsigned int)((receivedIpAddr >> 16) & 0xFF), (unsigned int)((receivedIpAddr >> 8) & 0xFF), (unsigned int)(receivedIpAddr & 0xFF), receivedPort);
		for (size_t i = 0; i < rxPbuf->len; ++i)
		{
			debugPrintf(" %02x", ((const uint8_t*)(rxPbuf->payload))[i]);
		}
		debugPrintf("\n");
		pbuf_free(rxPbuf);
		receivedPbuf = nullptr;
		++messagesProcessed;
	}
}

void MulticastResponder::Diagnostics(MessageType mtype) noexcept
{
	reprap.GetPlatform().MessageF(mtype, "=== Multicast handler ===\nResponder is %s, messages processed %u\n", (active) ? "active" : "inactive", messagesProcessed);
}

void MulticastResponder::Start(TcpPort port) noexcept
{
	if (ourPcb == nullptr)
	{
		ourPcb = udp_new_ip_type(IPADDR_TYPE_ANY);
		if (ourPcb == nullptr)
		{
			reprap.GetPlatform().Message(ErrorMessage, "unable to allocate a pcb\n");
		}
		else
		{
			udp_set_multicast_ttl(ourPcb, 255);
			if (udp_bind(ourPcb, IP_ADDR_ANY, port) != ERR_OK)
			{
				reprap.GetPlatform().Message(ErrorMessage, "udp_bind call failed\n");
			}
			else
			{
				debugPrintf("udp_bind call succeeded\n");
				udp_recv(ourPcb, rcvFunc, nullptr);
			}
		}
	}
	active = true;
	messagesProcessed = 0;
}

void MulticastResponder::Stop() noexcept
{
	if (ourPcb != nullptr)
	{
		udp_remove(ourPcb);
		ourPcb = nullptr;
	}
	active = false;
}

#endif

// End