Example program showing how to use the mbedNet library with UDP sockets. This demo broadcasts a message each second with a counter value incrementing at every call while the application loop displays the datagrams received on the same socket.
main.cpp@1:552bcce1761d, 2011-06-18 (annotated)
- Committer:
- Benoit
- Date:
- Sat Jun 18 08:34:29 2011 +0000
- Revision:
- 1:552bcce1761d
- Parent:
- 0:1b4d6b9e92a9
Added static ARP entry for global broadcast address (255.255.255.255)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Benoit | 0:1b4d6b9e92a9 | 1 | #include <mbed.h> |
Benoit | 0:1b4d6b9e92a9 | 2 | #include <Sockets.h> |
Benoit | 0:1b4d6b9e92a9 | 3 | #include <mbedNetIF.h> |
Benoit | 0:1b4d6b9e92a9 | 4 | #include <ARP.h> |
Benoit | 0:1b4d6b9e92a9 | 5 | #include <ICMPv4.h> |
Benoit | 0:1b4d6b9e92a9 | 6 | #include <UDPv4.h> |
Benoit | 0:1b4d6b9e92a9 | 7 | #include <Debug.h> |
Benoit | 0:1b4d6b9e92a9 | 8 | |
Benoit | 0:1b4d6b9e92a9 | 9 | |
Benoit | 1:552bcce1761d | 10 | #define NET_TIMER_PERIOD 1 |
Benoit | 1:552bcce1761d | 11 | #define BUFFER_LEN 64 |
Benoit | 0:1b4d6b9e92a9 | 12 | |
Benoit | 0:1b4d6b9e92a9 | 13 | |
Benoit | 1:552bcce1761d | 14 | Serial pc(USBTX, USBRX); // tx, rx |
Benoit | 1:552bcce1761d | 15 | Ticker netTicker, echoTicker; |
Benoit | 1:552bcce1761d | 16 | Ethernet_Addr_t myMAC = {0x00, 0x10, 0x33, 0x2e, 0x18, 0x7f}; |
Benoit | 1:552bcce1761d | 17 | IPv4_Addr_t ip = {192, 168, 0, 2}, |
Benoit | 1:552bcce1761d | 18 | netmask = {255, 255, 255, 0}, |
Benoit | 1:552bcce1761d | 19 | gateway = {192, 168, 0, 1}, |
Benoit | 1:552bcce1761d | 20 | broadcastNet = {192, 168, 0, 255}, |
Benoit | 1:552bcce1761d | 21 | broadcastAll = {255, 255, 255, 255}; |
Benoit | 1:552bcce1761d | 22 | NetIF_t *mbedNetIF; |
Benoit | 1:552bcce1761d | 23 | Socket_t udpSocket; |
Benoit | 1:552bcce1761d | 24 | Socket_AddrIn_t localAddress, senderAddress, broadcastAddress; |
Benoit | 0:1b4d6b9e92a9 | 25 | |
Benoit | 0:1b4d6b9e92a9 | 26 | |
Benoit | 0:1b4d6b9e92a9 | 27 | void NetTicker(void) |
Benoit | 0:1b4d6b9e92a9 | 28 | { |
Benoit | 1:552bcce1761d | 29 | NetIF_ProcessTimers(NET_TIMER_PERIOD); |
Benoit | 0:1b4d6b9e92a9 | 30 | } |
Benoit | 0:1b4d6b9e92a9 | 31 | |
Benoit | 0:1b4d6b9e92a9 | 32 | |
Benoit | 0:1b4d6b9e92a9 | 33 | void EchoTicker(void) |
Benoit | 0:1b4d6b9e92a9 | 34 | { |
Benoit | 1:552bcce1761d | 35 | char buffer[BUFFER_LEN]; |
Benoit | 1:552bcce1761d | 36 | static int32_t counter = 0; |
Benoit | 1:552bcce1761d | 37 | |
Benoit | 1:552bcce1761d | 38 | sprintf(buffer, "counter = %d\n", counter++); |
Benoit | 1:552bcce1761d | 39 | Sockets_SendTo(udpSocket, (uint8_t *)buffer, strlen(buffer), 0, (Socket_Addr_t *)&broadcastAddress, broadcastAddress.len); |
Benoit | 1:552bcce1761d | 40 | } |
Benoit | 1:552bcce1761d | 41 | |
Benoit | 1:552bcce1761d | 42 | |
Benoit | 1:552bcce1761d | 43 | void DisplayHelp(void) |
Benoit | 1:552bcce1761d | 44 | { |
Benoit | 1:552bcce1761d | 45 | printf("\r\nCommands:\r\n"); |
Benoit | 1:552bcce1761d | 46 | printf(" d: display ARP cache\r\n"); |
Benoit | 1:552bcce1761d | 47 | printf(" f: flush ARP cache\r\n"); |
Benoit | 1:552bcce1761d | 48 | printf(" g: send ARP request for gateway\r\n"); |
Benoit | 1:552bcce1761d | 49 | printf(" h: display these short help lines\r\n"); |
Benoit | 1:552bcce1761d | 50 | printf("\r\n"); |
Benoit | 0:1b4d6b9e92a9 | 51 | } |
Benoit | 0:1b4d6b9e92a9 | 52 | |
Benoit | 0:1b4d6b9e92a9 | 53 | |
Benoit | 0:1b4d6b9e92a9 | 54 | int main() |
Benoit | 0:1b4d6b9e92a9 | 55 | { |
Benoit | 1:552bcce1761d | 56 | int32_t byteCount, senderAddressLength; |
Benoit | 1:552bcce1761d | 57 | char buffer[BUFFER_LEN], c; |
Benoit | 1:552bcce1761d | 58 | |
Benoit | 1:552bcce1761d | 59 | // serial output speed to 115200 baud |
Benoit | 1:552bcce1761d | 60 | pc.baud(115200); |
Benoit | 1:552bcce1761d | 61 | setbuf(stdout, NULL); |
Benoit | 0:1b4d6b9e92a9 | 62 | |
Benoit | 1:552bcce1761d | 63 | // Clears screen and display a welcome message |
Benoit | 1:552bcce1761d | 64 | printf("%cStarting!\r\n", 12); |
Benoit | 1:552bcce1761d | 65 | |
Benoit | 1:552bcce1761d | 66 | // Set debug levels to have the NetIF networking layer display the interface status |
Benoit | 1:552bcce1761d | 67 | Debug_SetMasks(DEBUG_MODULE_NETIF, DEBUG_LEVEL_ALL & ~(DEBUG_LEVEL_VERBOSE0 | DEBUG_LEVEL_VERBOSE1 | DEBUG_LEVEL_VERBOSE2)); |
Benoit | 1:552bcce1761d | 68 | |
Benoit | 1:552bcce1761d | 69 | mbedNetIF = NetIF_RegisterInterface(&ip, &netmask, &gateway, &mbedNetIF_Driver, (void *)&myMAC); // Registers the ethernet drivers as a network interface |
Benoit | 0:1b4d6b9e92a9 | 70 | |
Benoit | 1:552bcce1761d | 71 | ethernet.RegisterProtocol(&arp); // We need ARP over ethernet to resolve IP addresses with MAC addresses |
Benoit | 1:552bcce1761d | 72 | ethernet.RegisterProtocol(&ipv4); // We need IPv4 (over ethernet) of course |
Benoit | 1:552bcce1761d | 73 | ipv4.RegisterProtocol(&icmpv4); // Then ICMPv4 over IPv4 to answer ping requests |
Benoit | 1:552bcce1761d | 74 | ipv4.RegisterProtocol(&udpv4); // Next let's register UDPv4 over IPv4 |
Benoit | 1:552bcce1761d | 75 | udpv4.RegisterAPI(&sockets); // Finally let's register the Sockets API (it is available for UDP at the moment) |
Benoit | 1:552bcce1761d | 76 | |
Benoit | 1:552bcce1761d | 77 | ARP_AddStaticEntry(mbedNetIF, broadcastNet, ðernet_Addr_Broadcast); // We add a static entry to the local network broadcast address to the ARP cache |
Benoit | 1:552bcce1761d | 78 | ARP_AddStaticEntry(mbedNetIF, broadcastAll, ðernet_Addr_Broadcast); // We add a static entry to the GLOBAL broadcast address to the ARP cache |
Benoit | 1:552bcce1761d | 79 | |
Benoit | 1:552bcce1761d | 80 | netTicker.attach(&NetTicker, NET_TIMER_PERIOD); // A 1 second periodic timer to process network house keeping routines (like expiration in the ARP cache, timeouts for TCP in the future, ...) |
Benoit | 1:552bcce1761d | 81 | |
Benoit | 1:552bcce1761d | 82 | NetIF_Up(mbedNetIF); // Finally we bring the network interface up |
Benoit | 1:552bcce1761d | 83 | |
Benoit | 1:552bcce1761d | 84 | udpSocket = Sockets_Open(AF_INET, SOCK_DGRAM, 0); // Create an UDP socket |
Benoit | 0:1b4d6b9e92a9 | 85 | |
Benoit | 1:552bcce1761d | 86 | localAddress.family = AF_INET; |
Benoit | 1:552bcce1761d | 87 | localAddress.len = sizeof(Socket_AddrIn_t); |
Benoit | 1:552bcce1761d | 88 | localAddress.port = htons(12345); |
Benoit | 1:552bcce1761d | 89 | localAddress.address = ipv4_Addr_Any; |
Benoit | 1:552bcce1761d | 90 | |
Benoit | 1:552bcce1761d | 91 | broadcastAddress.family = AF_INET; |
Benoit | 1:552bcce1761d | 92 | broadcastAddress.len = sizeof(Socket_AddrIn_t); |
Benoit | 1:552bcce1761d | 93 | broadcastAddress.port = htons(54321); |
Benoit | 1:552bcce1761d | 94 | broadcastAddress.address = broadcastNet; |
Benoit | 1:552bcce1761d | 95 | |
Benoit | 1:552bcce1761d | 96 | Sockets_Bind(udpSocket, (Socket_Addr_t *)&localAddress, localAddress.len); // We bind the socket to port 12345 and any local IP address |
Benoit | 1:552bcce1761d | 97 | |
Benoit | 1:552bcce1761d | 98 | echoTicker.attach(&EchoTicker, 2); // Every two seconds, broadcast an UDP message to port 54321 |
Benoit | 1:552bcce1761d | 99 | |
Benoit | 1:552bcce1761d | 100 | // Then do whatever you need for your application. here we simply check if we have received a datagram from the udpSocket and display its informations |
Benoit | 1:552bcce1761d | 101 | senderAddressLength = sizeof(Socket_AddrIn_t); |
Benoit | 0:1b4d6b9e92a9 | 102 | |
Benoit | 1:552bcce1761d | 103 | DisplayHelp(); |
Benoit | 1:552bcce1761d | 104 | |
Benoit | 1:552bcce1761d | 105 | printf(">"); |
Benoit | 0:1b4d6b9e92a9 | 106 | |
Benoit | 1:552bcce1761d | 107 | while(true) |
Benoit | 1:552bcce1761d | 108 | { |
Benoit | 1:552bcce1761d | 109 | byteCount = Sockets_RecvFrom(udpSocket, (uint8_t *)buffer, BUFFER_LEN, 0, (Socket_Addr_t *)&senderAddress, &senderAddressLength); |
Benoit | 1:552bcce1761d | 110 | if (byteCount > 0) |
Benoit | 1:552bcce1761d | 111 | { |
Benoit | 1:552bcce1761d | 112 | buffer[byteCount] = '\0'; |
Benoit | 1:552bcce1761d | 113 | printf("We have received '%s' (%d bytes) from %d.%d.%d.%d:%d\r\n", |
Benoit | 1:552bcce1761d | 114 | buffer, |
Benoit | 1:552bcce1761d | 115 | byteCount, |
Benoit | 1:552bcce1761d | 116 | senderAddress.address.IP0, |
Benoit | 1:552bcce1761d | 117 | senderAddress.address.IP1, |
Benoit | 1:552bcce1761d | 118 | senderAddress.address.IP2, |
Benoit | 1:552bcce1761d | 119 | senderAddress.address.IP3, |
Benoit | 1:552bcce1761d | 120 | ntohs(senderAddress.port) |
Benoit | 1:552bcce1761d | 121 | ); |
Benoit | 1:552bcce1761d | 122 | } |
Benoit | 1:552bcce1761d | 123 | |
Benoit | 1:552bcce1761d | 124 | if (pc.readable()) |
Benoit | 1:552bcce1761d | 125 | { |
Benoit | 1:552bcce1761d | 126 | c = pc.getc(); |
Benoit | 1:552bcce1761d | 127 | printf("%c", c); |
Benoit | 1:552bcce1761d | 128 | switch(c) |
Benoit | 1:552bcce1761d | 129 | { |
Benoit | 1:552bcce1761d | 130 | case 'd': |
Benoit | 1:552bcce1761d | 131 | ARP_DisplayCache(); |
Benoit | 1:552bcce1761d | 132 | printf("\r\n>"); |
Benoit | 1:552bcce1761d | 133 | break; |
Benoit | 0:1b4d6b9e92a9 | 134 | |
Benoit | 1:552bcce1761d | 135 | case 'f': |
Benoit | 1:552bcce1761d | 136 | ARP_FlushCache(False); |
Benoit | 1:552bcce1761d | 137 | printf("\r\n>"); |
Benoit | 1:552bcce1761d | 138 | break; |
Benoit | 1:552bcce1761d | 139 | |
Benoit | 1:552bcce1761d | 140 | case 'g': |
Benoit | 1:552bcce1761d | 141 | ARP_ResolveIPv4Address(mbedNetIF, gateway, NULL); |
Benoit | 1:552bcce1761d | 142 | printf("\r\n>"); |
Benoit | 1:552bcce1761d | 143 | break; |
Benoit | 1:552bcce1761d | 144 | |
Benoit | 1:552bcce1761d | 145 | case 'h': |
Benoit | 1:552bcce1761d | 146 | DisplayHelp(); |
Benoit | 1:552bcce1761d | 147 | printf("\r\n>"); |
Benoit | 1:552bcce1761d | 148 | break; |
Benoit | 1:552bcce1761d | 149 | } |
Benoit | 0:1b4d6b9e92a9 | 150 | } |
Benoit | 0:1b4d6b9e92a9 | 151 | } |
Benoit | 0:1b4d6b9e92a9 | 152 | } |