| 300 | } |
| 301 | |
| 302 | void udpReceive(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) |
| 303 | { |
| 304 | UDP udp = arg; |
| 305 | UDPPacket packet; |
| 306 | |
| 307 | #ifdef mxDebug |
| 308 | if (fxInNetworkDebugLoop(udp->the)) { |
| 309 | pbuf_free_safe(p); |
| 310 | return; |
| 311 | } |
| 312 | #endif |
| 313 | |
| 314 | packet = c_malloc(sizeof(UDPPacketRecord)); |
| 315 | if (!packet) { |
| 316 | pbuf_free_safe(p); |
| 317 | return; |
| 318 | } |
| 319 | |
| 320 | packet->next = NULL; |
| 321 | packet->pb = p; |
| 322 | packet->port = port; |
| 323 | packet->address = *addr; |
| 324 | |
| 325 | modInstrumentationAdjust(NetworkBytesRead, p->len); |
| 326 | |
| 327 | builtinCriticalSectionBegin(); |
| 328 | uint8_t readablePending = udp->readablePending; |
| 329 | if (udp->packets) { |
| 330 | UDPPacket walker; |
| 331 | |
| 332 | for (walker = udp->packets; walker->next; walker = walker->next) |
| 333 | ; |
| 334 | walker->next = packet; |
| 335 | |
| 336 | builtinCriticalSectionEnd(); |
| 337 | } |
| 338 | else { |
| 339 | udp->packets = packet; |
| 340 | builtinCriticalSectionEnd(); |
| 341 | } |
| 342 | |
| 343 | if (!readablePending && udp->onReadable) { |
| 344 | udp->readablePending = true; |
| 345 | modMessagePostToMachine(udp->the, NULL, 0, udpDeliver, udp); |
| 346 | } |
| 347 | } |
| 348 | |
| 349 | void udpDeliver(void *the, void *refcon, uint8_t *message, uint16_t messageLength) |
| 350 | { |
nothing calls this directly
no test coverage detected