@@ -106,6 +106,7 @@ static void OnPlcaStatus(TC6_t *pInst, bool success, uint32_t addr, uint32_t val
106106
107107static err_t lwIpInit (struct netif *netif);
108108static err_t lwIpOut (struct netif *netif, struct pbuf *p);
109+ static void lwIp_udp_raw_recv (void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, uint16_t port);
109110
110111static String IPtoString (IPAddress const & ip_addr)
111112{
@@ -128,6 +129,11 @@ static String IPtoString(IPAddress const & ip_addr)
128129
129130TC6_Arduino_10BASE_T1S_UDP::TC6_Arduino_10BASE_T1S_UDP (TC6_Io * tc6_io)
130131: _tc6_io{tc6_io}
132+ , _udp_pcb{nullptr }
133+ , _remote_ip{0 ,0 ,0 ,0 }
134+ , _remote_port{0 }
135+ , _udp_rx_data{nullptr }
136+ , _udp_rx_data_len{0 }
131137{
132138 _lw.io = tc6_io;
133139}
@@ -266,8 +272,19 @@ bool TC6_Arduino_10BASE_T1S_UDP::sendWouldBlock()
266272
267273uint8_t TC6_Arduino_10BASE_T1S_UDP::begin (uint16_t port)
268274{
269- /* TODO */
270- return 0 ;
275+ /* Create a UDP PCB (if none exists yet). */
276+ if (!_udp_pcb)
277+ _udp_pcb = udp_new ();
278+
279+ /* Bind specified port to all local interfaces. */
280+ err_t err = udp_bind (_udp_pcb, IP_ADDR_ANY, port);
281+ if (err != ERR_OK)
282+ return 0 ;
283+
284+ /* Set a reception callback to be called upon the arrival of a UDP package. */
285+ udp_recv (_udp_pcb , lwIp_udp_raw_recv, this );
286+
287+ return 1 ;
271288}
272289
273290void TC6_Arduino_10BASE_T1S_UDP::stop ()
@@ -308,13 +325,13 @@ size_t TC6_Arduino_10BASE_T1S_UDP::write(const uint8_t * buffer, size_t size)
308325int TC6_Arduino_10BASE_T1S_UDP::parsePacket ()
309326{
310327 /* TODO */
311- return 0 ;
328+ return _udp_rx_data_len ;
312329}
313330
314331int TC6_Arduino_10BASE_T1S_UDP::available ()
315332{
316333 /* TODO */
317- return 0 ;
334+ return _udp_rx_data_len ;
318335}
319336
320337int TC6_Arduino_10BASE_T1S_UDP::read ()
@@ -348,14 +365,35 @@ void TC6_Arduino_10BASE_T1S_UDP::flush()
348365
349366IPAddress TC6_Arduino_10BASE_T1S_UDP::remoteIP ()
350367{
351- /* TODO */
352- return IPAddress ();
368+ return _remote_ip;
353369}
354370
355371uint16_t TC6_Arduino_10BASE_T1S_UDP::remotePort ()
356372{
357- /* TODO */
358- return 0 ;
373+ return _remote_port;
374+ }
375+
376+ void TC6_Arduino_10BASE_T1S_UDP::onUdpRawRecv (struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, uint16_t port)
377+ {
378+ /* Obtain remote port and remote IP. */
379+ _remote_ip = IPAddress (ip4_addr1 (addr),
380+ ip4_addr2 (addr),
381+ ip4_addr3 (addr),
382+ ip4_addr4 (addr));
383+ _remote_port = port;
384+
385+ /* TODO: very pre-eliminary. Need to buffer received data somewhere. */
386+ if (_udp_rx_data)
387+ delete[] _udp_rx_data;
388+
389+ /* Create data buffer for received message. */
390+ _udp_rx_data = new uint8_t [p->len ]; // Note: There's also "tot_len" - how does that fit in here?
391+ /* Copy data into buffer. */
392+ memcpy (_udp_rx_data, p->payload , p->len );
393+ /* Update the length field. */
394+ _udp_rx_data_len = 0 ;
395+ /* Free pbuf */
396+ pbuf_free (p);
359397}
360398
361399/* *************************************************************************************
@@ -428,6 +466,12 @@ static err_t lwIpOut(struct netif *netif, struct pbuf *p)
428466 return result;
429467}
430468
469+ void lwIp_udp_raw_recv (void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, uint16_t port)
470+ {
471+ TC6_Arduino_10BASE_T1S_UDP * this_ptr = (TC6_Arduino_10BASE_T1S_UDP * )arg;
472+ this_ptr->onUdpRawRecv (pcb, p, addr, port);
473+ }
474+
431475/* *************************************************************************************
432476 * NAMESPACE
433477 **************************************************************************************/
0 commit comments