Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of PicoTCP by
pico_udp.c
00001 /********************************************************************* 00002 PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved. 00003 See LICENSE and COPYING for usage. 00004 00005 . 00006 00007 Authors: Daniele Lacamera 00008 *********************************************************************/ 00009 00010 00011 #include "pico_udp.h" 00012 #include "pico_config.h" 00013 #include "pico_eth.h" 00014 #include "pico_socket.h" 00015 #include "pico_stack.h" 00016 00017 00018 /* Queues */ 00019 static struct pico_queue udp_in = {}; 00020 static struct pico_queue udp_out = {}; 00021 00022 00023 /* Functions */ 00024 00025 uint16_t pico_udp_checksum_ipv4(struct pico_frame *f) 00026 { 00027 struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr; 00028 struct pico_udp_hdr *udp_hdr = (struct pico_udp_hdr *) f->transport_hdr; 00029 struct pico_socket *s = f->sock; 00030 struct pico_ipv4_pseudo_hdr pseudo; 00031 00032 if (s) { 00033 /* Case of outgoing frame */ 00034 //dbg("UDP CRC: on outgoing frame\n"); 00035 pseudo.src.addr = s->local_addr.ip4.addr; 00036 pseudo.dst.addr = s->remote_addr.ip4.addr; 00037 } else { 00038 /* Case of incomming frame */ 00039 //dbg("UDP CRC: on incomming frame\n"); 00040 pseudo.src.addr = hdr->src.addr; 00041 pseudo.dst.addr = hdr->dst.addr; 00042 } 00043 pseudo.zeros = 0; 00044 pseudo.proto = PICO_PROTO_UDP; 00045 pseudo.len = short_be(f->transport_len); 00046 00047 return pico_dualbuffer_checksum(&pseudo, sizeof(struct pico_ipv4_pseudo_hdr), udp_hdr, f->transport_len); 00048 } 00049 00050 00051 static int pico_udp_process_out(struct pico_protocol *self, struct pico_frame *f) 00052 { 00053 return pico_network_send(f); 00054 } 00055 00056 static int pico_udp_push(struct pico_protocol *self, struct pico_frame *f) 00057 { 00058 struct pico_udp_hdr *hdr = (struct pico_udp_hdr *) f->transport_hdr; 00059 struct pico_remote_duple *remote_duple = (struct pico_remote_duple *) f->info; 00060 00061 /* this (fragmented) frame should contain a transport header */ 00062 if (f->transport_hdr != f->payload) { 00063 hdr->trans.sport = f->sock->local_port; 00064 if (remote_duple) { 00065 hdr->trans.dport = remote_duple->remote_port; 00066 } else { 00067 hdr->trans.dport = f->sock->remote_port; 00068 } 00069 hdr->len = short_be(f->transport_len); 00070 /* do not perform CRC validation. If you want to, a system needs to be 00071 implemented to calculate the CRC over the total payload of a 00072 fragmented payload */ 00073 hdr->crc = 0; 00074 } 00075 00076 if (pico_enqueue(self->q_out, f) > 0) { 00077 return f->payload_len; 00078 } else { 00079 return 0; 00080 } 00081 } 00082 00083 /* Interface: protocol definition */ 00084 struct pico_protocol pico_proto_udp = { 00085 .name = "udp", 00086 .proto_number = PICO_PROTO_UDP, 00087 .layer = PICO_LAYER_TRANSPORT, 00088 .process_in = pico_transport_process_in, 00089 .process_out = pico_udp_process_out, 00090 .push = pico_udp_push, 00091 .q_in = &udp_in, 00092 .q_out = &udp_out, 00093 }; 00094 00095 00096 #define PICO_UDP_MODE_UNICAST 0x01 00097 #define PICO_UDP_MODE_MULTICAST 0x02 00098 #define PICO_UDP_MODE_BROADCAST 0xFF 00099 00100 struct pico_socket_udp 00101 { 00102 struct pico_socket sock; 00103 int mode; 00104 #ifdef PICO_SUPPORT_MCAST 00105 uint8_t mc_ttl; /* Multicasting TTL */ 00106 #endif 00107 }; 00108 00109 #ifdef PICO_SUPPORT_MCAST 00110 int pico_udp_set_mc_ttl(struct pico_socket *s, uint8_t ttl) 00111 { 00112 struct pico_socket_udp *u; 00113 if(!s) { 00114 pico_err = PICO_ERR_EINVAL; 00115 return -1; 00116 } 00117 u = (struct pico_socket_udp *) s; 00118 u->mc_ttl = ttl; 00119 return 0; 00120 } 00121 00122 int pico_udp_get_mc_ttl(struct pico_socket *s, uint8_t *ttl) 00123 { 00124 struct pico_socket_udp *u; 00125 if(!s) 00126 return -1; 00127 u = (struct pico_socket_udp *) s; 00128 *ttl = u->mc_ttl; 00129 return 0; 00130 } 00131 #endif /* PICO_SUPPORT_MCAST */ 00132 00133 struct pico_socket *pico_udp_open(void) 00134 { 00135 struct pico_socket_udp *u = pico_zalloc(sizeof(struct pico_socket_udp)); 00136 if (!u) 00137 return NULL; 00138 u->mode = PICO_UDP_MODE_UNICAST; 00139 00140 #ifdef PICO_SUPPORT_MCAST 00141 u->mc_ttl = PICO_IP_DEFAULT_MULTICAST_TTL; 00142 /* enable multicast loopback by default */ 00143 u->sock.opt_flags |= (1 << PICO_SOCKET_OPT_MULTICAST_LOOP); 00144 #endif 00145 00146 return &u->sock; 00147 } 00148 00149 int pico_udp_recv(struct pico_socket *s, void *buf, int len, void *src, uint16_t *port) 00150 { 00151 struct pico_frame *f = pico_queue_peek(&s->q_in); 00152 if (f) { 00153 f->payload = f->transport_hdr + sizeof(struct pico_udp_hdr); 00154 f->payload_len = f->transport_len - sizeof(struct pico_udp_hdr); 00155 // dbg("expected: %d, got: %d\n", len, f->payload_len); 00156 if (src) 00157 pico_store_network_origin(src, f); 00158 if (port) { 00159 struct pico_trans *hdr = (struct pico_trans *)f->transport_hdr; 00160 *port = hdr->sport; 00161 } 00162 if (f->payload_len > len) { 00163 memcpy(buf, f->payload, len); 00164 f->payload += len; 00165 f->payload_len -= len; 00166 return len; 00167 } else { 00168 int ret = f->payload_len; 00169 memcpy(buf, f->payload, f->payload_len); 00170 f = pico_dequeue(&s->q_in); 00171 pico_frame_discard(f); 00172 return ret; 00173 } 00174 } else return 0; 00175 } 00176
Generated on Thu Jul 14 2022 08:24:59 by
1.7.2
