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
|