00001 /********************************************************************************* 00002 00003 Copyright 2006-2008 MakingThings 00004 00005 Licensed under the Apache License, 00006 Version 2.0 (the "License"); you may not use this file except in compliance 00007 with the License. You may obtain a copy of the License at 00008 00009 http://www.apache.org/licenses/LICENSE-2.0 00010 00011 Unless required by applicable law or agreed to in writing, software distributed 00012 under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 00013 CONDITIONS OF ANY KIND, either express or implied. See the License for 00014 the specific language governing permissions and limitations under the License. 00015 00016 *********************************************************************************/ 00017 00018 /** \file network.c 00019 Communicate with the Make Controller Board via Ethernet. 00020 */ 00021 00022 #include "config.h" 00023 #ifdef MAKE_CTRL_NETWORK 00024 00025 #include "stdio.h" 00026 #include "io.h" 00027 #include "eeprom.h" 00028 #include "timer.h" 00029 00030 /* lwIP includes. */ 00031 #include "lwip/api.h" 00032 #include "lwip/tcpip.h" 00033 #include "lwip/memp.h" 00034 #include "lwip/netbuf.h" 00035 #include "lwip/stats.h" 00036 #include "netif/loopif.h" 00037 #include "lwip/dhcp.h" 00038 #include "lwip/dns.h" 00039 00040 /* Low level includes. */ 00041 #include "SAM7_EMAC.h" 00042 00043 int Network_AddressConvert( char* address, int* a0, int* a1, int* a2, int* a3 ); 00044 00045 /* MAC address definition. The MAC address must be unique on the network. */ 00046 char emacETHADDR0 = 0xAC; 00047 char emacETHADDR1 = 0xDE; 00048 char emacETHADDR2 = 0x48; 00049 char emacETHADDR3 = 0x55; 00050 char emacETHADDR4 = 0x0; 00051 char emacETHADDR5 = 0x0; 00052 00053 #include "network.h" 00054 00055 typedef struct Network_ 00056 { 00057 int pending; // if somebody has started the process of getting an IP address, don't start another process 00058 int TempIpAddress; // hold onto the values that will ultimately get set for the network 00059 int TempGateway; // once it's all set as valid 00060 int TempMask; 00061 int OscUdpListenPort; 00062 int OscUdpSendPort; 00063 int TcpOutAddress; 00064 int TcpOutPort; 00065 bool TcpRequested; 00066 int DnsResolvedAddress; 00067 #ifdef OSC 00068 char scratch1[ OSC_SCRATCH_SIZE ]; 00069 char scratch2[ OSC_SCRATCH_SIZE ]; 00070 #endif // OSC 00071 } NetworkStruct; 00072 00073 xSemaphoreHandle Network_DnsSemaphore; 00074 00075 // a few globals 00076 NetworkStruct* Network; 00077 00078 enum { NET_UNCHECKED, NET_INVALID, NET_VALID } Network_Valid; 00079 00080 void Network_SetPending( int state ); 00081 int Network_GetPending( void ); 00082 void Network_DhcpStart( struct netif* netif ); 00083 void Network_DhcpStop( struct netif* netif ); 00084 void Network_SetDefaults( void ); 00085 static void Network_DnsCallback(const char *name, struct ip_addr *addr, void *arg); 00086 00087 /** \defgroup Sockets Sockets 00088 The Sockets system provides a simple interface for creating, reading and writing over both TCP and UDP. 00089 This subsystem is a light wrapper around LwIP, the open source TCP/IP stack used by the Make Controller Kit. 00090 There are 3 groups of socket functions: 00091 - DatagramSocket - sockets for \b UDP communication 00092 - Socket - sockets for \b TCP communication 00093 - ServerSocket - sockets for accepting \b incoming TCP client connections 00094 \ingroup Core 00095 @{ 00096 */ 00097 00098 /** 00099 Create a new TCP socket connected to the address and port specified. 00100 @param address An integer specifying the IP address to connect to. 00101 @param port An integer specifying the port to connect on. 00102 @return A pointer to the socket, if it was created successfully. NULL if unsuccessful. 00103 @see SocketRead(), SocketWrite(), SocketClose() 00104 00105 \par Example 00106 \code 00107 // use the IP_ADDRESS macro to format the address properly 00108 int addr = IP_ADDRESS( 192, 168, 0, 54 ); 00109 // then create the socket, connecting on port 10101 00110 struct netconn* socket = Socket( addr, 10101 ); 00111 \endcode 00112 */ 00113 void* Socket( int address, int port ) 00114 { 00115 Network_SetActive( 1 ); 00116 00117 struct netconn* conn; 00118 err_t retval; 00119 00120 conn = netconn_new( NETCONN_TCP ); 00121 // This is our addition to the conn structure to help with reading 00122 conn->readingbuf = NULL; 00123 00124 struct ip_addr remote_addr; 00125 remote_addr.addr = htonl(address); 00126 00127 retval = netconn_connect( conn, &remote_addr, port ); 00128 00129 if( ERR_OK != retval ) 00130 { 00131 //netconn_delete( conn ); 00132 while( netconn_delete( conn ) != ERR_OK ) 00133 Sleep( 10 ); 00134 00135 conn = NULL; 00136 } 00137 00138 return conn; 00139 } 00140 00141 /** 00142 Get the number of bytes available in a TCP socket. 00143 Handy before calling SocketRead() so you know how many to read. 00144 @param socket The socket. 00145 @return The number of bytes available in that socket. 00146 00147 \b Example 00148 \code 00149 struct netconn* mysocket = Socket(IP_ADDRESS( 192, 168, 0, 54 ), 10101); 00150 // ... reading and writing ... 00151 int avail = Socket_BytesAvailable(mysocket); 00152 \endcode 00153 */ 00154 int SocketBytesAvailable( void* socket ) 00155 { 00156 if(!socket) 00157 return 0; 00158 struct netconn *conn = socket; 00159 int len = conn->recv_avail; 00160 if(conn->readingbuf) 00161 len += (netbuf_len( conn->readingbuf ) - conn->readingoffset); 00162 return len; 00163 } 00164 00165 /** 00166 Read from a TCP socket. 00167 Make sure you have an open socket before trying to read from it. This function 00168 will block until the requested number of bytes are read. See Socket_BytesAvailable() 00169 to get the number of bytes waiting to be read. 00170 @param socket A pointer to the existing socket. 00171 @param data A pointer to the buffer to read to. 00172 @param length An integer specifying the maximum length in bytes that can be read. 00173 @return An integer: length of data read if successful, zero on failure. 00174 @see Socket(), SocketClose() 00175 00176 \par Example 00177 \code 00178 // we should already have created a socket sock with Socket(). 00179 struct netconn* sock = Socket( addr, 10101 ); 00180 int length_read = SocketRead( sock, data, length ) 00181 // if 0 bytes were read, there was some sort of error 00182 if( length_read == 0 ) 00183 SocketClose( sock ); 00184 \endcode 00185 */ 00186 int SocketRead( void* socket, char* data, int length ) 00187 { 00188 if(!socket) 00189 return 0; 00190 struct netconn *conn = socket; 00191 struct netbuf *buf; 00192 int totalBytesRead = 0; 00193 int extraBytes = 0; 00194 00195 while(totalBytesRead < length) 00196 { 00197 if ( conn->readingbuf == NULL ) 00198 { 00199 buf = netconn_recv( conn ); 00200 if ( buf == NULL ) 00201 return 0; 00202 00203 /* 00204 Now deal appropriately with what we got. If we got more than we asked for, 00205 keep the extras in the conn->readingbuf and set the conn->readingoffset. 00206 Otherwise, copy everything we got back into the calling buffer. 00207 */ 00208 int bytesRead = netbuf_len( buf ); 00209 totalBytesRead += bytesRead; 00210 if( totalBytesRead <= length ) 00211 { 00212 netbuf_copy( buf, data, bytesRead ); 00213 netbuf_delete( buf ); 00214 data += bytesRead; 00215 // conn->readingbuf remains NULL 00216 } 00217 else // if we got more than we asked for 00218 { 00219 extraBytes = totalBytesRead - length; 00220 bytesRead -= extraBytes; // how many do we need to write to get the originally requested len 00221 netbuf_copy( buf, data, bytesRead ); 00222 conn->readingbuf = buf; 00223 conn->readingoffset = bytesRead; 00224 } 00225 } 00226 else // conn->readingbuf != NULL 00227 { 00228 buf = conn->readingbuf; 00229 int bytesRead = netbuf_len( buf ) - conn->readingoffset; // grab whatever was lying around from a previous read 00230 totalBytesRead += bytesRead; 00231 00232 if( totalBytesRead <= length ) // there's less than or just enough left for what we need 00233 { 00234 netbuf_copy_partial( buf, data, bytesRead, conn->readingoffset ); // copy out the rest of what was in the netbuf 00235 netbuf_delete( buf ); // and get rid of it 00236 conn->readingbuf = NULL; 00237 } 00238 else // there's more in there than we were asked for 00239 { 00240 extraBytes = totalBytesRead - length; 00241 bytesRead -= extraBytes; // how many do we need to write to get the originally requested len 00242 netbuf_copy_partial( buf, data, bytesRead, conn->readingoffset ); // only read out what we need 00243 //netbuf_copy( buf, data, bytesRead ); 00244 conn->readingoffset += bytesRead; 00245 } 00246 data += bytesRead; 00247 } 00248 } 00249 return totalBytesRead - extraBytes; 00250 } 00251 00252 /** 00253 Read a line from a TCP socket terminated by CR LF (0x0D 0x0A). 00254 Make sure you have an open socket before trying to read from it. 00255 @param socket A pointer to the existing socket. 00256 @param data A pointer to the buffer to read to. 00257 @param length An integer specifying the maximum length in bytes to read. 00258 @return An integer: length of data read if successful, zero on failure. 00259 @see Socket(), SocketRead(), SocketClose() 00260 */ 00261 00262 int SocketReadLine( void* socket, char* data, int length ) 00263 { 00264 int readLength; 00265 int lineLength = -1; 00266 //int terminated = false; 00267 data--; 00268 00269 // Upon entering, data points to char prior to buffer, length is -1 00270 do 00271 { 00272 data++; 00273 // here data points to where byte will be written 00274 lineLength++; 00275 // linelength now reflects true number of bytes 00276 readLength = SocketRead( socket, data, 1 ); 00277 // here, if readlength == 1, data has a new char in next position, linelength is one off, 00278 // if readlength == 0, data had no new char and linelength is right 00279 } while ( ( readLength == 1 ) && ( lineLength < length - 1 ) && ( *data != '\n' ) ); 00280 00281 // here, length is corrected if there was a character 00282 if ( readLength == 1 ) 00283 lineLength++; 00284 00285 return lineLength; 00286 } 00287 00288 00289 /** 00290 Write to a TCP socket. 00291 Not surprisingly, we need an existing socket before we can write to it. 00292 00293 @param socket A pointer to the existing socket. 00294 @param data A pointer to the buffer to write from. 00295 @param length An integer specifying the length in bytes of how much data should be written. 00296 @return An integer: 'length written' if successful, 0 on failure. 00297 @see Socket() 00298 00299 \par Example 00300 \code 00301 // we should already have created a socket with Socket() 00302 struct netconn* sock = Socket( addr, 10101 ); 00303 int length_written = SocketWrite( sock, data, length ) 00304 // if 0 bytes were written, there was some sort of error 00305 if( length_written == 0 ) 00306 SocketClose( sock ); 00307 \endcode 00308 */ 00309 int SocketWrite( void* socket, char* data, int length ) 00310 { 00311 int err = netconn_write( (struct netconn *)socket, data, length, NETCONN_COPY); 00312 if ( err != ERR_OK ) 00313 return 0; 00314 else 00315 return length; 00316 } 00317 00318 /** 00319 Close an existing TCP socket. 00320 Anytime you get an error when trying to read or write, it's best to close the socket and reopen 00321 it to make sure that the connection is corrently configured. 00322 @param socket A pointer to the existing socket. 00323 @return void 00324 @see Socket() 00325 00326 \par Example 00327 \code 00328 // we should already have created a socket 'sock' with Socket(). 00329 struct netconn* sock = Socket( addr, 10101 ); 00330 // now close it 00331 SocketClose( sock ) 00332 \endcode 00333 */ 00334 void SocketClose( void* socket ) 00335 { 00336 // Make sure there is no buffer lying around 00337 struct netconn *conn = socket; 00338 if ( conn->readingbuf != NULL ) 00339 { 00340 netbuf_delete( conn->readingbuf ); 00341 conn->readingbuf = NULL; 00342 } 00343 00344 netconn_close( (struct netconn *)socket ); 00345 netconn_delete( (struct netconn *)socket ); 00346 return; 00347 } 00348 00349 /** 00350 Create a new TCP server socket and start listening for connections. 00351 @param port An integer specifying the port to listen on. 00352 @return A pointer to the socket created. 00353 @see ServerSocketAccept( ) 00354 00355 \par Example 00356 \code 00357 // create a socket and start listening on port 10101 00358 struct netconn* server = ServerSocket( 10101 ); 00359 // ServerSocketAccept( ) will block until an incoming connection is made 00360 struct netconn* newConnection = ServerSocketAccept( server ); 00361 // now grab the data from the new connection 00362 \endcode 00363 */ 00364 void* ServerSocket( int port ) 00365 { 00366 Network_SetActive( 1 ); 00367 00368 struct netconn *conn; 00369 00370 conn = netconn_new( NETCONN_TCP ); 00371 if ( conn != NULL ) 00372 { 00373 netconn_bind( conn, 0, port ); 00374 netconn_listen( conn ); 00375 } 00376 00377 return conn; 00378 } 00379 00380 /** 00381 Accept an incoming connection to a ServerSocket that you have created. This 00382 function will block until a new connection is waiting to be serviced. It returns 00383 a regular socket on which you can use SocketWrite(), SocketRead() and SocketClose(). 00384 @param serverSocket a pointer to a ServerSocket that you created 00385 @return a pointer to the new socket created to handle the connection 00386 @see ServerSocket(), SocketWrite(), SocketRead(), SocketClose() 00387 */ 00388 void* ServerSocketAccept( void* serverSocket ) 00389 { 00390 struct netconn *conn; 00391 conn = netconn_accept( (struct netconn *)serverSocket ); 00392 // This is our addition to the conn structure to help with reading 00393 if ( conn != NULL ) 00394 conn->readingbuf = NULL; 00395 return conn; 00396 } 00397 00398 /** 00399 Close a ServerSocket that you have created. 00400 @param serverSocket A pointer to a ServerSocket. 00401 @return 0 if the process was successful. 00402 @see ServerSocket() 00403 00404 \par Example 00405 \code 00406 // we created a server socket at some point 00407 struct netconn* server = ServerSocket( 10101 ); 00408 // now close it 00409 ServerSocketClose( server ); 00410 \endcode 00411 */ 00412 int ServerSocketClose( void* serverSocket ) 00413 { 00414 // netconn_close( serverSocket ); 00415 netconn_delete( serverSocket ); 00416 return 0; 00417 } 00418 00419 /** 00420 Create a socket to read and write UDP packets. 00421 @param port An integer specifying the port to open. 00422 @return a pointer to the socket created. 00423 @see DatagramSocketSend( ), DatagramSocketReceive( ) 00424 00425 \par Example 00426 \code 00427 // create a new UDP socket on port 10101 00428 struct netconn* udpSocket = DatagramSocket( 10101 ); 00429 // now read and write to it using DatagramSocketSend( ) and DatagramSocketReceive( ) 00430 \endcode 00431 */ 00432 void* DatagramSocket( int port ) 00433 { 00434 Network_SetActive( 1 ); 00435 00436 struct netconn *conn; 00437 00438 conn = netconn_new( NETCONN_UDP ); 00439 if( conn == NULL || conn->err != ERR_OK ) 00440 return NULL; 00441 // This is our addition to the conn structure to help with reading 00442 conn->readingbuf = NULL; 00443 00444 // hook it up 00445 netconn_bind( conn, NULL, port ); 00446 00447 return conn; 00448 } 00449 00450 /** 00451 Send a UDP packet to a specified address. 00452 @param datagramSocket A pointer to the DatagramSocket() you're using to write. 00453 @param address An integer specifying the IP address to write to. 00454 @param port An integer specifying the port to write to. 00455 @param data A pointer to the packet to send. 00456 @param length An integer specifying the number of bytes in the packet being sent. 00457 @return An integer corresponding to the number of bytes successfully written. 00458 @see DatagramSocket( ) 00459 00460 \par Example 00461 \code 00462 struct netconn* udpSocket = DatagramSocket( 10101 ); // our socket 00463 int address = IP_ADDRESS( 192, 168, 0, 200 ); 00464 int sent = DatagramSocketSend( udpSocket, address, 10101, myBuffer, myLength ); 00465 \endcode 00466 */ 00467 int DatagramSocketSend( void* datagramSocket, int address, int port, void* data, int length ) 00468 { 00469 struct netconn *conn = (struct netconn *)datagramSocket; 00470 struct netbuf *buf; 00471 struct ip_addr remote_addr; 00472 int lengthsent = 0; 00473 00474 remote_addr.addr = htonl(address); 00475 if( ERR_OK != netconn_connect(conn, &remote_addr, port) ) 00476 return lengthsent; 00477 00478 // create a buffer 00479 buf = netbuf_new(); 00480 if( buf != NULL ) 00481 { 00482 netbuf_ref( buf, data, length); // make the buffer point to the data that should be sent 00483 if( ERR_OK != netconn_send( conn, buf) ) // send the data 00484 { 00485 netbuf_delete(buf); 00486 return 0; 00487 } 00488 lengthsent = length; 00489 netbuf_delete(buf); // deallocate the buffer 00490 } 00491 00492 return lengthsent; 00493 } 00494 00495 /** 00496 Receive a UDP packet. 00497 This function will block until a packet is received. The address and port of the 00498 sender are returned in the locations pointed to by the address and port parameters. 00499 If the incoming packet is larger than the specified size of the buffer, it will 00500 be truncated. 00501 @param datagramSocket A pointer to the DatagramSocket() you're using to read. 00502 @param incomingPort An integer specifying the port to listen on. 00503 @param address A pointer to the IP address that sent the packet. 00504 @param port A pointer to the port of the sender. 00505 @param data A pointer to the buffer to read into. 00506 @param length An integer specifying the number of bytes in the packet being read. 00507 @return An integer corresponding to the number of bytes successfully read. 00508 @see DatagramSocket( ) 00509 00510 \par Example 00511 \code 00512 struct netconn* udpSocket = DatagramSocket( 10101 ); // our socket 00513 int address, port; 00514 int sent = DatagramSocketReceive( udpSocket, &address, &port, myBuffer, myLength ); 00515 \endcode 00516 */ 00517 int DatagramSocketReceive( void* datagramSocket, int incomingPort, int* address, int* port, void* data, int length ) 00518 { 00519 struct netconn *conn = (struct netconn*)datagramSocket; 00520 struct netbuf *buf; 00521 struct ip_addr *addr; 00522 int buflen = 0; 00523 00524 if( ERR_OK != netconn_bind( conn, IP_ADDR_ANY, incomingPort ) ) 00525 return buflen; 00526 00527 buf = netconn_recv( conn ); 00528 if( buf != NULL ) 00529 { 00530 buflen = netbuf_len( buf ); 00531 // copy the contents of the received buffer into 00532 //the supplied memory pointer 00533 netbuf_copy(buf, data, length); 00534 addr = netbuf_fromaddr(buf); 00535 *port = netbuf_fromport(buf); 00536 *address = ntohl( addr->addr ); 00537 netbuf_delete(buf); 00538 } 00539 00540 /* if the length of the received data is larger than 00541 len, this data is discarded and we return len. 00542 otherwise we return the actual length of the received 00543 data */ 00544 if(length > buflen) 00545 return buflen; 00546 else 00547 return length; 00548 } 00549 00550 /** 00551 Close a DatagramSocket(). 00552 @param socket A pointer to the DatagramSocket() to close. 00553 @see DatagramSocket( ) 00554 00555 \par Example 00556 \code 00557 struct netconn* udpSocket = DatagramSocket( 10101 ); // create our socket 00558 // now close it 00559 DatagramSocketClose( udpSocket ); 00560 \endcode 00561 */ 00562 void DatagramSocketClose( void* socket ) 00563 { 00564 netconn_close( socket ); 00565 netconn_delete( socket ); 00566 } 00567 00568 /** @} 00569 */ 00570 00571 /** \defgroup Network Network 00572 The Network subsystem manages the Ethernet controller. 00573 00574 Like any other network enabled device, the Make Controller has an IP address, net mask and gateway. 00575 - The default IP address is 192.168.0.200 00576 - The default mask is 255.255.255.0 00577 - The default gateway 192.168.0.1 00578 00579 You can set any of these values manually, or use DHCP to get them automatically. 00580 00581 \section MAC 00582 The Make Controller's MAC address defaults to AC.DE.48.55.x.y where x & y are calculated from the 00583 unit's serial number, handled by the \ref System subsystem. 00584 00585 \section webserver Web Server 00586 The Make Controller Kit can also act as a web server. The demo web server running on the Make Controller 00587 displays some stats about the board's current state through a web interface. It is intended mainly as 00588 a starting point for more useful web applications. See the source in webserver.c. 00589 00590 \ingroup Core 00591 @{ 00592 */ 00593 00594 /** 00595 Sets whether the Network subsystem is active. 00596 This fires up the networking system on the Make Controller, and will not return until a network is found, 00597 ie. a network cable is plugged in. 00598 @param state An integer specifying the active state - 1 (active) or 0 (inactive). 00599 @return 0 on success. 00600 */ 00601 int Network_SetActive( int state ) 00602 { 00603 if ( state ) 00604 { 00605 if( Network == NULL ) 00606 { 00607 Network = MallocWait( sizeof( NetworkStruct ), 100 ); 00608 Network->pending = 1; 00609 Network->TcpRequested = 0; 00610 Network_DnsSemaphore = NULL; 00611 Network->DnsResolvedAddress = -1; 00612 00613 00614 if( !Network_GetValid() ) // if we don't have good values, set the defaults 00615 Network_SetDefaults( ); 00616 else // load the values from EEPROM 00617 { 00618 Eeprom_Read( EEPROM_SYSTEM_NET_ADDRESS, (uchar*)&Network->TempIpAddress, 4 ); 00619 Eeprom_Read( EEPROM_SYSTEM_NET_GATEWAY, (uchar*)&Network->TempGateway, 4 ); 00620 Eeprom_Read( EEPROM_SYSTEM_NET_MASK, (uchar*)&Network->TempMask, 4 ); 00621 } 00622 00623 Network->OscUdpListenPort = NetworkOsc_GetUdpListenPort( ); 00624 Network->OscUdpSendPort = NetworkOsc_GetUdpSendPort( ); 00625 Eeprom_Read( EEPROM_TCP_OUT_ADDRESS, (uchar*)&Network->TcpOutAddress, 4 ); 00626 Eeprom_Read( EEPROM_TCP_OUT_PORT, (uchar*)&Network->TcpOutPort, 4 ); 00627 Network_Init(); 00628 } 00629 } 00630 else 00631 { 00632 if( Network ) 00633 { 00634 Free( Network ); 00635 Network = NULL; 00636 } 00637 } 00638 00639 return CONTROLLER_OK; 00640 } 00641 00642 /** 00643 Returns the active state of the Network subsystem. 00644 @return State - 1 (active) or 0 (inactive). 00645 */ 00646 int Network_GetActive( void ) 00647 { 00648 if( Network == NULL || Network_GetPending( ) ) 00649 return 0; 00650 else 00651 return 1; 00652 } 00653 00654 /** 00655 Set the IP address of the Make Controller. 00656 The IP address of the Make Controller, in dotted decimal form (xxx.xxx.xxx.xxx), 00657 can be set by passing in each of the numbers as a separate parameter. 00658 The default IP address of each Make Controller as it ships from the factory 00659 is 192.168.0.200. 00660 00661 This value is stored in EEPROM, so it persists even after the board 00662 is powered down. 00663 00664 @param a0 An integer corresponding to the first of 4 numbers in the address. 00665 @param a1 An integer corresponding to the second of 4 numbers in the address. 00666 @param a2 An integer corresponding to the third of 4 numbers in the address. 00667 @param a3 An integer corresponding to the fourth of 4 numbers in the address. 00668 @return 0 on success. 00669 00670 \par Example 00671 \code 00672 // set the address to 192.168.0.23 00673 Network_SetAddress( 192, 168, 0, 23 ); 00674 \endcode 00675 00676 */ 00677 int Network_SetAddress( int a0, int a1, int a2, int a3 ) 00678 { 00679 // just store this address, since we're only going to do something with it in response to 00680 if( !Network_GetValid() ) 00681 { 00682 Network_SetDefaults( ); 00683 Network_SetValid( 1 ); 00684 } 00685 Network->TempIpAddress = NETIF_IP_ADDRESS( a0, a1, a2, a3 ); 00686 Network_SetValid( 1 ); 00687 00688 return CONTROLLER_OK; 00689 } 00690 00691 /** 00692 Set the network mask of the Make Controller on your local network. 00693 When on a subnet or local network, the network mask must be set in order 00694 for the gateway to route information to the board's IP address properly. 00695 The mask is commonly 255.255.255.0 for many home networks. 00696 Set the mask in dotted decimal form (xxx.xxx.xxx.xxx), passing in each 00697 number as a separate parameter. 00698 00699 This value is stored in EEPROM, so it persists even after the board 00700 is powered down. 00701 00702 @param a0 An integer corresponding to the first of 4 numbers in the mask. 00703 @param a1 An integer corresponding to the second of 4 numbers in the mask. 00704 @param a2 An integer corresponding to the third of 4 numbers in the mask. 00705 @param a3 An integer corresponding to the fourth of 4 numbers in the mask. 00706 @return 0 on success. 00707 00708 \par Example 00709 \code 00710 // set the mask to 255.255.255.254 00711 if( 0 != Network_SetMask( 255, 255, 255, 254 ) ) 00712 // then there was a problem. 00713 \endcode 00714 */ 00715 int Network_SetMask( int a0, int a1, int a2, int a3 ) 00716 { 00717 // just store this address, since we're only going to do something with it in response to 00718 if( !Network_GetValid() ) 00719 { 00720 Network_SetDefaults( ); 00721 Network_SetValid( 1 ); 00722 } 00723 Network->TempMask = NETIF_IP_ADDRESS( a0, a1, a2, a3 ); 00724 Network_SetValid( 1 ); 00725 00726 return CONTROLLER_OK; 00727 } 00728 00729 /** 00730 Set the gateway address for the local network the Make Controller is on. 00731 The gateway address is commonly 192.168.0.1 for many home networks. 00732 Set the gateway address in dotted decimal form (xxx.xxx.xxx.xxx), passing in each 00733 number as a separate parameter. 00734 00735 This value is stored in EEPROM, so it persists even after the board 00736 is powered down. 00737 00738 @param a0 An integer corresponding to the first of 4 numbers in the gateway address. 00739 @param a1 An integer corresponding to the second of 4 numbers in the gateway address. 00740 @param a2 An integer corresponding to the third of 4 numbers in the gateway address. 00741 @param a3 An integer corresponding to the fourth of 4 numbers in the gateway address. 00742 @return 0 on success. 00743 00744 \par Example 00745 \code 00746 // set the gateway to 192.168.5.1 00747 if( 0 != Network_SetGateway( 192, 168, 5, 1 ) ) 00748 // then there was a problem. 00749 \endcode 00750 */ 00751 int Network_SetGateway( int a0, int a1, int a2, int a3 ) 00752 { 00753 // just store this address, since we're only going to do something with it in response to 00754 if( !Network_GetValid() ) 00755 { 00756 Network_SetDefaults( ); 00757 Network_SetValid( 1 ); 00758 } 00759 Network->TempGateway = NETIF_IP_ADDRESS( a0, a1, a2, a3 ); 00760 Network_SetValid( 1 ); 00761 00762 return CONTROLLER_OK; 00763 } 00764 00765 /** 00766 Read the board's current IP address. 00767 Pass in pointers to integers where the address should be stored. 00768 00769 @param a0 A pointer to an integer where the first of 4 numbers of the address is to be stored. 00770 @param a1 A pointer to an integer where the second of 4 numbers of the address is to be stored. 00771 @param a2 A pointer to an integer where the third of 4 numbers of the address is to be stored. 00772 @param a3 A pointer to an integer where the fourth of 4 numbers of the address is to be stored. 00773 @return 0 on success. 00774 00775 \par Example 00776 \code 00777 int a0, a1, a2, a3; 00778 Network_GetAddress( &a0, &a1, &a2, &a3 ); 00779 // now our variables are filled with the current address values 00780 \endcode 00781 */ 00782 int Network_GetAddress( int* a0, int* a1, int* a2, int* a3 ) 00783 { 00784 if( Network_GetPending() ) 00785 return CONTROLLER_ERROR_NO_NETWORK; 00786 00787 struct netif* mc_netif; 00788 int address = 0; 00789 // we specify our network interface as en0 when we init 00790 mc_netif = netif_find( "en0" ); 00791 if( mc_netif != NULL ) 00792 { 00793 address = mc_netif->ip_addr.addr; 00794 00795 *a0 = NETIF_IP_ADDRESS_A( address ); 00796 *a1 = NETIF_IP_ADDRESS_B( address ); 00797 *a2 = NETIF_IP_ADDRESS_C( address ); 00798 *a3 = NETIF_IP_ADDRESS_D( address ); 00799 } 00800 // if the Ethernet interface is not up, we'll just get garbage back 00801 if( *a0 < 0 || *a0 > 255 ) 00802 *a0 = *a1 = *a2 = *a3 = -1; 00803 00804 return CONTROLLER_OK; 00805 } 00806 00807 /** 00808 Read the board's current network mask. 00809 Pass in pointers to integers where the mask should be stored. 00810 00811 @param a0 A pointer to an integer where the first of 4 numbers of the mask is to be stored. 00812 @param a1 A pointer to an integer where the second of 4 numbers of the mask is to be stored. 00813 @param a2 A pointer to an integer where the third of 4 numbers of the mask is to be stored. 00814 @param a3 A pointer to an integer where the fourth of 4 numbers of the mask is to be stored. 00815 @return 0 on success. 00816 00817 \par Example 00818 \code 00819 int a0, a1, a2, a3; 00820 Network_GetMask( &a0, &a1, &a2, &a3 ); 00821 // now our variables are filled with the current mask values 00822 \endcode 00823 */ 00824 int Network_GetMask( int* a0, int* a1, int* a2, int* a3 ) 00825 { 00826 if( Network_GetPending() ) 00827 return CONTROLLER_ERROR_NO_NETWORK; 00828 00829 struct netif* mc_netif; 00830 int address = 0; 00831 // we specify our network interface as en0 when we init 00832 mc_netif = netif_find( "en0" ); 00833 if( mc_netif != NULL ) 00834 { 00835 address = mc_netif->netmask.addr; 00836 00837 *a0 = NETIF_IP_ADDRESS_A( address ); 00838 *a1 = NETIF_IP_ADDRESS_B( address ); 00839 *a2 = NETIF_IP_ADDRESS_C( address ); 00840 *a3 = NETIF_IP_ADDRESS_D( address ); 00841 } 00842 if( *a0 < 0 || *a0 > 255 ) 00843 *a0 = *a1 = *a2 = *a3 = -1; 00844 00845 return CONTROLLER_OK; 00846 } 00847 00848 /** 00849 Read the board's current gateway address. 00850 Pass in pointers to integers where the gateway address should be stored. 00851 00852 @param a0 A pointer to an integer where the first of 4 numbers of the gateway address is to be stored. 00853 @param a1 A pointer to an integer where the second of 4 numbers of the gateway address is to be stored. 00854 @param a2 A pointer to an integer where the third of 4 numbers of the gateway address is to be stored. 00855 @param a3 A pointer to an integer where the fourth of 4 numbers of the gateway address is to be stored. 00856 @return 0 on success. 00857 00858 \par Example 00859 \code 00860 int a0, a1, a2, a3; 00861 Network_GetGateway( &a0, &a1, &a2, &a3 ); 00862 // now our variables are filled with the current gateway values 00863 \endcode 00864 */ 00865 int Network_GetGateway( int* a0, int* a1, int* a2, int* a3 ) 00866 { 00867 if( Network_GetPending() ) 00868 return CONTROLLER_ERROR_NO_NETWORK; 00869 00870 struct netif* mc_netif; 00871 int address = 0; 00872 // we specify our network interface as en0 when we init 00873 mc_netif = netif_find( "en0" ); 00874 if( mc_netif != NULL ) 00875 { 00876 address = mc_netif->gw.addr; 00877 00878 *a0 = NETIF_IP_ADDRESS_A( address ); 00879 *a1 = NETIF_IP_ADDRESS_B( address ); 00880 *a2 = NETIF_IP_ADDRESS_C( address ); 00881 *a3 = NETIF_IP_ADDRESS_D( address ); 00882 } 00883 if( *a0 < 0 || *a0 > 255 ) 00884 *a0 = *a1 = *a2 = *a3 = -1; 00885 00886 return CONTROLLER_OK; 00887 } 00888 00889 /** 00890 Set whether DHCP is enabled. 00891 The Make Controller can use DHCP (Dynamic Host Configuration Protocol) to automatically 00892 retrieve an IP address from a router. If you're using your Make Controller on a network 00893 with a router, it is generally preferred (and more convenient) to use DHCP. Otherwise, turn 00894 DHCP off and set the IP address, mask, and gateway manually. 00895 00896 Wikipedia has a good article about DHCP at http://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol 00897 00898 This value is stored persistently, so it will remain constant across system reboots. 00899 @param enabled An integer specifying whether to enable DHCP - 1 (enable) or 0 (disable). 00900 */ 00901 void Network_SetDhcpEnabled( int enabled ) 00902 { 00903 if( enabled && !Network_GetDhcpEnabled() ) 00904 { 00905 struct netif* mc_netif; 00906 // we specify our network interface as en0 when we init 00907 mc_netif = netif_find( "en0" ); 00908 if( mc_netif != NULL ) 00909 Network_DhcpStart( mc_netif ); 00910 00911 Eeprom_Write( EEPROM_DHCP_ENABLED, (uchar*)&enabled, 4 ); 00912 } 00913 00914 if( !enabled && Network_GetDhcpEnabled() ) 00915 { 00916 struct netif* mc_netif; 00917 // we specify our network interface as en0 when we init 00918 mc_netif = netif_find( "en0" ); 00919 if( mc_netif != NULL ) 00920 Network_DhcpStop( mc_netif ); 00921 Eeprom_Write( EEPROM_DHCP_ENABLED, (uchar*)&enabled, 4 ); 00922 Network_SetValid( 1 ); 00923 } 00924 return; 00925 } 00926 00927 /** 00928 Read whether DHCP is currently enabled. 00929 This value is stored presistently, so it will be the same across system reboots. 00930 @return An integer specifying whether DHCP is enabled - 1 (enabled) or 0 (disabled). 00931 */ 00932 int Network_GetDhcpEnabled( ) 00933 { 00934 int state; 00935 Eeprom_Read( EEPROM_DHCP_ENABLED, (uchar*)&state, 4 ); 00936 return (state == 1) ? 1 : 0; 00937 } 00938 00939 /** 00940 Resolve the IP address for a given host name. 00941 Up to 4 DNS entries are cached, so if you make successive calls to this function, 00942 you won't incur a whole lookup roundtrip - you'll just get the cached value. 00943 The cached values are maintained internally, so if one of them becomes invalid, a 00944 new lookup will be fired off the next time it's asked for. 00945 @param name A string specifying the name of the host to look up. 00946 @return An integer representation of the IP address of the host. This can be 00947 passed to the \ref Sockets functions to read and write. Returns -1 on error. 00948 00949 \b Example 00950 \code 00951 // try to open a socket connection to makingthings.com 00952 int addr = Network_DnsGetHostByName("makingthings.com"); 00953 struct netconn* socket = Socket(addr, 80); // open up a new connection to that address 00954 \endcode 00955 */ 00956 int Network_DnsGetHostByName( const char *name ) 00957 { 00958 struct ip_addr addr; 00959 int retval = -1; 00960 if(!Network_DnsSemaphore) 00961 { 00962 Network_DnsSemaphore = SemaphoreCreate(); 00963 if(!Network_DnsSemaphore) // the semaphore was not created successfully 00964 return retval; 00965 if(!SemaphoreTake(Network_DnsSemaphore, 0)) // do the initial take 00966 return retval; 00967 } 00968 err_t result = dns_gethostbyname( name, &addr, Network_DnsCallback, 0); 00969 if(result == ERR_OK) // the result was cached, just return it 00970 retval = addr.addr; 00971 else if(result == ERR_INPROGRESS) // a lookup is in progress - wait for the callback to signal that we've gotten a response 00972 { 00973 if(SemaphoreTake(Network_DnsSemaphore, 30000)) // timeout is 30 seconds by default 00974 retval = Network->DnsResolvedAddress; 00975 } 00976 return ntohl(retval); 00977 } 00978 00979 // static 00980 /* 00981 The callback for a DNS look up. The original request is waiting (via semaphore) on 00982 this to pop the looked up address in the right spot. 00983 */ 00984 void Network_DnsCallback(const char *name, struct ip_addr *addr, void *arg) 00985 { 00986 LWIP_UNUSED_ARG(arg); 00987 LWIP_UNUSED_ARG(name); 00988 if(addr) 00989 Network->DnsResolvedAddress = addr->addr; 00990 else 00991 Network->DnsResolvedAddress = -1; // we didn't get an address, stuff an error value in there 00992 SemaphoreGive(Network_DnsSemaphore); 00993 } 00994 00995 /** @} 00996 */ 00997 00998 /** 00999 Create a checksum for the current address settings and store it in EEPROM. 01000 This should be called each time an address setting is changed so that if 01001 the board gets powered down, it will know when it comes back up whether or 01002 not the address settings is currently has are valid. 01003 01004 @param v An integer specifying whether to validate the current settings (1) 01005 or to force them to be invalidated (0). 01006 Passing in 0 returns the address settings to their factory defaults. 01007 @return 0 on success. 01008 */ 01009 int Network_SetValid( int v ) 01010 { 01011 if ( v ) 01012 { 01013 struct ip_addr ip, gw, mask; 01014 struct netif* mc_netif; 01015 01016 ip.addr = Network->TempIpAddress; // these should each have been set previously 01017 mask.addr = Network->TempMask; // by Network_SetAddress(), etc. 01018 gw.addr = Network->TempGateway; 01019 if( !Network_GetDhcpEnabled() ) // only actually change the address if we're not using DHCP 01020 { 01021 // we specify our network interface as en0 when we init 01022 mc_netif = netif_find( "en0" ); 01023 if( mc_netif != NULL ) 01024 netif_set_addr( mc_netif, &ip, &mask, &gw ); 01025 } 01026 01027 // but write the addresses to memory regardless, so we can use them next time we boot up without DHCP 01028 Eeprom_Write( EEPROM_SYSTEM_NET_ADDRESS, (uchar*)&ip.addr, 4 ); 01029 Eeprom_Write( EEPROM_SYSTEM_NET_MASK, (uchar*)&mask.addr, 4 ); 01030 Eeprom_Write( EEPROM_SYSTEM_NET_GATEWAY, (uchar*)&gw.addr, 4 ); 01031 01032 int total = Network->TempIpAddress + Network->TempMask + Network->TempGateway; 01033 Eeprom_Write( EEPROM_SYSTEM_NET_CHECK, (uchar*)&total, 4 ); 01034 01035 Network_Valid = NET_VALID; 01036 } 01037 else 01038 { 01039 int value = 0; 01040 Eeprom_Write( EEPROM_SYSTEM_NET_CHECK, (uchar*)&value, 4 ); 01041 Network_Valid = NET_INVALID; 01042 } 01043 01044 return CONTROLLER_OK; 01045 } 01046 01047 /** 01048 Read the checksum for address settings in EEPROM, and determine if it matches 01049 the current settings. 01050 01051 @return An integer specifying the validity of the settings - 1 (valid) or 0 (invalid). 01052 */ 01053 int Network_GetValid( ) 01054 { 01055 int address, mask, gateway, total; 01056 Eeprom_Read( EEPROM_SYSTEM_NET_ADDRESS, (uchar*)&address, 4 ); 01057 Eeprom_Read( EEPROM_SYSTEM_NET_MASK, (uchar*)&mask, 4 ); 01058 Eeprom_Read( EEPROM_SYSTEM_NET_GATEWAY, (uchar*)&gateway, 4 ); 01059 Eeprom_Read( EEPROM_SYSTEM_NET_CHECK, (uchar*)&total, 4 ); 01060 01061 if ( total == address + mask + gateway ) 01062 { 01063 Network_Valid = NET_VALID; 01064 return 1; 01065 } 01066 else 01067 { 01068 Network_Valid = NET_INVALID; 01069 return 0; 01070 } 01071 } 01072 01073 // if things aren't valid, just set the defaults 01074 void Network_SetDefaults( ) 01075 { 01076 Network->TempIpAddress = NETIF_IP_ADDRESS( 192, 168, 0, 200 ); 01077 Network->TempGateway = NETIF_IP_ADDRESS( 192, 168, 0, 1 ); 01078 Network->TempMask = NETIF_IP_ADDRESS( 255, 255, 255, 0 ); 01079 Network_SetValid( 1 ); 01080 } 01081 01082 /** 01083 Sets whether the Network subsystem is currently trying to negotiate its settings. 01084 This is mostly used by the Network init and deinit processes, so you shouldn't 01085 be calling this yourself unless you have a good reason to. 01086 @param state An integer specifying the pending state - 1 (pending) or 0 (not pending). 01087 */ 01088 void Network_SetPending( int state ) 01089 { 01090 if( state && !Network->pending ) 01091 Network->pending = state; 01092 if( !state && Network->pending ) 01093 Network->pending = state; 01094 } 01095 01096 int Network_GetPending( ) 01097 { 01098 return Network->pending; 01099 } 01100 01101 void NetworkOsc_SetTcpOutAddress( int a0, int a1, int a2, int a3 ) 01102 { 01103 int address = IP_ADDRESS( a0, a1, a2, a3 ); 01104 if( address != Network->TcpOutAddress ) 01105 { 01106 Network->TcpOutAddress = address; 01107 Eeprom_Write( EEPROM_TCP_OUT_ADDRESS, (uchar*)&address, 4 ); 01108 } 01109 } 01110 01111 int NetworkOsc_GetTcpOutAddress( ) 01112 { 01113 return Network->TcpOutAddress; 01114 } 01115 01116 void NetworkOsc_SetTcpOutPort( int port ) 01117 { 01118 if( port != Network->TcpOutPort ) // only change if it's a new value 01119 { 01120 Network->TcpOutPort = port; 01121 Eeprom_Write( EEPROM_TCP_OUT_PORT, (uchar*)&port, 4 ); 01122 } 01123 } 01124 01125 int NetworkOsc_GetTcpOutPort( ) 01126 { 01127 return Network->TcpOutPort; 01128 } 01129 01130 void NetworkOsc_SetUdpListenPort( int port ) 01131 { 01132 if( port != Network->OscUdpListenPort ) // only change things if it's a new value 01133 { 01134 Network->OscUdpListenPort = port; 01135 Eeprom_Write( EEPROM_OSC_UDP_LISTEN_PORT, (uchar*)&port, 4 ); 01136 } 01137 } 01138 01139 int NetworkOsc_GetUdpListenPort( ) 01140 { 01141 int port; 01142 Eeprom_Read( EEPROM_OSC_UDP_LISTEN_PORT, (uchar*)&port, 4 ); 01143 01144 if( port > 0 && port < 65536 ) 01145 return port; 01146 else 01147 return 10000; 01148 } 01149 01150 void NetworkOsc_SetUdpSendPort( int port ) 01151 { 01152 if( port != Network->OscUdpSendPort ) // only change things if it's a new value 01153 { 01154 Network->OscUdpSendPort = port; 01155 Eeprom_Write( EEPROM_OSC_UDP_SEND_PORT, (uchar*)&port, 4 ); 01156 } 01157 } 01158 01159 int NetworkOsc_GetUdpSendPort( ) 01160 { 01161 int port; 01162 Eeprom_Read( EEPROM_OSC_UDP_SEND_PORT, (uchar*)&port, 4 ); 01163 01164 if( port > 0 && port < 65536 ) 01165 return port; 01166 else 01167 return 10000; 01168 } 01169 01170 void Network_DhcpStart( struct netif* netif ) 01171 { 01172 Network_SetPending( 1 ); // set a flag so nobody else tries to set up this netif 01173 int count = 0; 01174 dhcp_start( netif ); 01175 // now hang out for a second until we get an address 01176 // if DHCP is enabled but we don't find a DHCP server, just use the network config stored in EEPROM 01177 while( netif->ip_addr.addr == 0 && count < 100 ) // timeout after 10 (?) seconds of waiting for a DHCP address 01178 { 01179 count++; 01180 Sleep( 100 ); 01181 } 01182 if( netif->ip_addr.addr == 0 ) // if we timed out getting an address via DHCP, just use whatever's in EEPROM 01183 { 01184 struct ip_addr ip, gw, mask; // network config stored in EEPROM 01185 ip.addr = Network->TempIpAddress; 01186 mask.addr = Network->TempMask; 01187 gw.addr = Network->TempGateway; 01188 netif_set_addr( netif, &ip, &mask, &gw ); 01189 } 01190 Network_SetPending( 0 ); 01191 return; 01192 } 01193 01194 void Network_DhcpStop( struct netif* netif ) 01195 { 01196 dhcp_release( netif ); 01197 netif_set_up(netif); // bring the interface back up, as dhcp_release() takes it down 01198 return; 01199 } 01200 01201 int Network_AddressConvert( char* address, int* a0, int* a1, int* a2, int* a3 ) 01202 { 01203 return ( sscanf( address, "%d.%d.%d.%d", a0, a1, a2, a3 ) == 4 ) ? CONTROLLER_OK : CONTROLLER_ERROR_NO_ADDRESS; 01204 } 01205 01206 #if ( CONTROLLER_VERSION == 50 || CONTROLLER_VERSION == 95 || CONTROLLER_VERSION == 100 || CONTROLLER_VERSION == 200 ) 01207 #define NETWORK_BITS IO_PB00_BIT | IO_PB01_BIT | IO_PB02_BIT | IO_PB03_BIT | IO_PB04_BIT | \ 01208 IO_PB05_BIT | IO_PB06_BIT | IO_PB07_BIT | IO_PB08_BIT | IO_PB09_BIT | \ 01209 IO_PB10_BIT | IO_PB11_BIT | IO_PB12_BIT | IO_PB13_BIT | IO_PB14_BIT | \ 01210 IO_PB15_BIT | IO_PB16_BIT | IO_PB17_BIT | IO_PB18_BIT | IO_PB26_BIT 01211 #elif ( CONTROLLER_VERSION == 90 ) 01212 #define NETWORK_BITS IO_PB00_BIT | IO_PB01_BIT | IO_PB02_BIT | IO_PB03_BIT | IO_PB04_BIT | \ 01213 IO_PB05_BIT | IO_PB06_BIT | IO_PB07_BIT | IO_PB08_BIT | IO_PB09_BIT | \ 01214 IO_PB15_BIT | IO_PB26_BIT 01215 #endif 01216 01217 int Network_Init( ) 01218 { 01219 // Start and Lock all the bits to do with the Ethernet Phy - can do this immediately, since there's no undoing this 01220 Network_SetPending( 1 ); 01221 Io_StartBits( NETWORK_BITS, true ); 01222 01223 // Attempt to get a serial number and set it into the mac address low bytes to make a unique MAC address 01224 int serialNumber = System_GetSerialNumber(); 01225 emacETHADDR5 = serialNumber & 0xFF; 01226 emacETHADDR4 = ( serialNumber >> 8 ) & 0xFF; 01227 // Low nibble of the third byte - gives us around 1M serial numbers 01228 emacETHADDR3 = 0x50 | ( ( serialNumber >> 12 ) & 0xF ); 01229 01230 /* Initialize lwIP and its interface layer. */ 01231 tcpip_init( NULL, NULL ); // init all of lwip...see lwip_init() inside for the whole init story 01232 01233 extern err_t ethernetif_init( struct netif *netif ); 01234 static struct netif EMAC_if; 01235 int address, mask, gateway, dhcp; 01236 dhcp = Network_GetDhcpEnabled(); 01237 01238 if( dhcp ) 01239 { 01240 address = 0; 01241 mask = 0; 01242 gateway = 0; 01243 } 01244 else // DHCP not enabled, just read whatever the manual IP address in EEPROM is. 01245 { 01246 address = Network->TempIpAddress; 01247 mask = Network->TempMask; 01248 gateway = Network->TempGateway; 01249 } 01250 // add our network interface to the system 01251 Network_SetPending( 1 ); //netif_add goes away for a long time if there's no Ethernet cable connected. 01252 netif_add(&EMAC_if, (struct ip_addr*)&address, (struct ip_addr*)&mask, 01253 (struct ip_addr*)&gateway, NULL, ethernetif_init, tcpip_input); 01254 // make it the default interface 01255 netif_set_default(&EMAC_if); 01256 // bring it up 01257 netif_set_up(&EMAC_if); 01258 // name it so we can find it later 01259 EMAC_if.name[0] = 'e'; 01260 EMAC_if.name[1] = 'n'; 01261 EMAC_if.num = 0; 01262 01263 #ifdef OSC 01264 if( NetworkOsc_GetTcpAutoConnect( ) ) 01265 { 01266 Network->TcpRequested = 1; 01267 Osc_StartTcpTask( ); 01268 } 01269 #endif 01270 01271 if( dhcp ) 01272 Network_DhcpStart( &EMAC_if ); 01273 01274 Network_SetPending( 0 ); 01275 return CONTROLLER_OK; 01276 } 01277 01278 /** \defgroup NetworkOSC Network - OSC 01279 Configure the Controller Board's Network Settings via OSC. 01280 \ingroup OSC 01281 01282 \section devices Devices 01283 There is only one Network system, so a device index is not used. 01284 01285 \section properties Properties 01286 The Network system has the following properties 01287 - address 01288 - mask 01289 - gateway 01290 - valid 01291 - mac 01292 - osc_udp_listen_port 01293 - osc_udp_send_port 01294 - dhcp 01295 01296 \par Address 01297 The \b address property corresponds to the IP address of the Controller Board. 01298 This value can be both read and written. To set a new address, send a message like 01299 \verbatim /network/address 192.168.0.235 \endverbatim 01300 \par 01301 To read the current IP address, omit the argument value from the end of the message: 01302 \verbatim /network/address \endverbatim 01303 01304 \par Mask 01305 The \b mask property corresponds to the network mask of the Controller Board. 01306 When on a subnet or local network, the network mask must be set in order 01307 for the gateway to route information to the board's IP address properly. 01308 The mask is commonly 255.255.255.0 for many home networks. 01309 \par 01310 To set the board's network mask, send a message like 01311 \verbatim /network/mask 255.255.255.0 \endverbatim 01312 To read the current mask, omit the argument value from the end of the message: 01313 \verbatim /network/mask \endverbatim 01314 01315 \par Gateway 01316 The \b gateway property corresponds to the gateway address for the local network the Make Controller is on. 01317 The gateway address is the address 01318 The gateway address is commonly the address of the router on many home networks, and its 01319 value is commonly 192.168.0.1.\n 01320 This value is stored in EEPROM, so it persists even after the board 01321 is powered down. 01322 \par 01323 To set the board's gateway address, send a message like 01324 \verbatim /network/gateway 192.168.0.1 \endverbatim 01325 To read the current gateway, omit the argument value from the end of the message: 01326 \verbatim /network/gateway \endverbatim 01327 01328 \par Valid 01329 The \b valid property is used to make sure the board's network settings are valid. 01330 If you're manually setting the \b address, \b gateway, or \b mask settings, you'll need 01331 to send the valid message for them to take effect. 01332 \par 01333 To set the board's current network settings as valid, send the message 01334 \verbatim /network/valid 1 \endverbatim 01335 To check if the current settings have been set as valid, send the message: 01336 \verbatim /network/valid \endverbatim 01337 with no argument value. 01338 01339 \par OSC UDP Port 01340 The \b osc_udp_port property corresponds to the port that the Make Controller listens on for 01341 incoming OSC messages via UDP. This value is stored persistently, so it's available 01342 even after the board has rebooted. This is 10000 by default. 01343 \par 01344 To tell the board to listen on port 10001, instead of the default 10000, send the message 01345 \code /network/osc_udp_port 10001 \endcode 01346 To read back the port that the board is currently listening on, send the message 01347 \verbatim /network/osc_udp_port \endverbatim 01348 with no argument value. 01349 01350 \par DHCP 01351 The \b dhcp property sets whether the board should try to dynamically retrieve a network address from 01352 a network router. If no DHCP server is available, the board will use the network settings stored in memory 01353 for the \b address, \b gateway, and \b mask properties. If you're connecting the board directly to your computer, 01354 DHCP will not be available, so you should turn this off. 01355 \par 01356 To turn DHCP on, send the message 01357 \code /network/dhcp 1 \endcode 01358 and the board will immediately try to get an address. To check what address the board got, send the message 01359 \code /network/address \endcode 01360 as you normally would. To turn DHCP off, send the message 01361 \code /network/dhcp 0 \endcode 01362 To read whether DHCP is currently enabled on the board, send the message 01363 \code /network/dhcp \endcode 01364 with no argument value. 01365 01366 \par MAC 01367 The \b mac property corresponds to the Ethernet MAC address of the Controller Board. 01368 This value is read-only. Each board on a network must have a unique MAC address. The MAC address is generated 01369 using the board's serial number, so ensure that your board's serial numbers are unique. 01370 \par 01371 To read the MAC address of the Controller, send the message 01372 \verbatim /network/mac \endverbatim 01373 The board will respond by sending back an OSC message with the MAC address. 01374 */ 01375 #ifdef OSC 01376 01377 void NetworkOsc_SetTcpAutoConnect( int yesorno ) 01378 { 01379 int val = yesorno; 01380 if( val != 1 ) 01381 val = 0; 01382 if( yesorno != NetworkOsc_GetTcpAutoConnect( ) ) // only write it if it has changed 01383 Eeprom_Write( EEPROM_TCP_AUTOCONNECT, (uchar*)&yesorno, 4 ); 01384 if( Network->TcpRequested == 0 && yesorno ) // if we're not already connected, connect now 01385 { 01386 Network->TcpRequested = 1; 01387 Osc_StartTcpTask( ); 01388 } 01389 } 01390 01391 int NetworkOsc_GetTcpAutoConnect( ) 01392 { 01393 int state; 01394 Eeprom_Read( EEPROM_TCP_AUTOCONNECT, (uchar*)&state, 4 ); 01395 if( state != 1 ) 01396 return 0; 01397 else 01398 return state; 01399 } 01400 01401 int NetworkOsc_GetTcpRequested( ) 01402 { 01403 return Network->TcpRequested; 01404 } 01405 01406 01407 #include "osc.h" 01408 static char* NetworkOsc_Name = "network"; 01409 static char* NetworkOsc_PropertyNames[] = { "active", "address", "mask", "gateway", "valid", "mac", 01410 "osc_udp_listen_port", "osc_tcpout_address", "osc_tcpout_port", 01411 "osc_tcpout_connect", "osc_tcpout_auto", "dhcp", 01412 "find", "osc_udp_send_port", 0 }; // must have a trailing 0 01413 01414 int NetworkOsc_PropertySet( int property, char* typedata, int channel ); 01415 int NetworkOsc_PropertyGet( int property, int channel ); 01416 01417 const char* NetworkOsc_GetName( void ) 01418 { 01419 return NetworkOsc_Name; 01420 } 01421 01422 int NetworkOsc_ReceiveMessage( int channel, char* message, int length ) 01423 { 01424 if ( Network_GetPending() ) 01425 return CONTROLLER_ERROR_NO_NETWORK; 01426 01427 int status = Osc_GeneralReceiverHelper( channel, message, length, 01428 NetworkOsc_Name, 01429 NetworkOsc_PropertySet, NetworkOsc_PropertyGet, 01430 NetworkOsc_PropertyNames ); 01431 01432 if ( status != CONTROLLER_OK ) 01433 return Osc_SendError( channel, NetworkOsc_Name, status ); 01434 01435 return CONTROLLER_OK; 01436 } 01437 01438 int NetworkOsc_Poll( ) 01439 { 01440 return CONTROLLER_OK; 01441 } 01442 01443 // Sets the property with the value 01444 int NetworkOsc_PropertySet( int property, char* typedata, int channel ) 01445 { 01446 int a0; 01447 int a1; 01448 int a2; 01449 int a3; 01450 01451 switch ( property ) 01452 { 01453 case 0: // active 01454 { 01455 int value; 01456 int count = Osc_ExtractData( typedata, "i", &value ); 01457 if ( count != 1 ) 01458 return Osc_SubsystemError( channel, NetworkOsc_Name, "Incorrect data - need an int" ); 01459 01460 Network_SetActive( value ); 01461 break; 01462 } 01463 case 1: // address 01464 { 01465 char* address; 01466 int count = Osc_ExtractData( typedata, "s", &address ); 01467 if ( count != 1 ) 01468 return Osc_SubsystemError( channel, NetworkOsc_Name, "Incorrect data - need a string" ); 01469 int status = Network_AddressConvert( address, &a0, &a1, &a2, &a3 ); 01470 if ( status != CONTROLLER_OK ) 01471 return Osc_SubsystemError( channel, NetworkOsc_Name, "Incorrect address - need 'a.b.c.d'" ); 01472 01473 Network_SetAddress( a0, a1, a2, a3 ); 01474 01475 break; 01476 } 01477 case 2: // mask 01478 { 01479 char* address; 01480 int count = Osc_ExtractData( typedata, "s", &address ); 01481 if ( count != 1 ) 01482 return Osc_SubsystemError( channel, NetworkOsc_Name, "Incorrect data - need a string" ); 01483 int status = Network_AddressConvert( address, &a0, &a1, &a2, &a3 ); 01484 if ( status != CONTROLLER_OK ) 01485 return Osc_SubsystemError( channel, NetworkOsc_Name, "Incorrect mask - need 'a.b.c.d'" ); 01486 01487 Network_SetMask( a0, a1, a2, a3 ); 01488 01489 break; 01490 } 01491 case 3: // gateway 01492 { 01493 char* address; 01494 int count = Osc_ExtractData( typedata, "s", &address ); 01495 if ( count != 1 ) 01496 return Osc_SubsystemError( channel, NetworkOsc_Name, "Incorrect data - need a string" ); 01497 int status = Network_AddressConvert( address, &a0, &a1, &a2, &a3 ); 01498 if ( status != CONTROLLER_OK ) 01499 return Osc_SubsystemError( channel, NetworkOsc_Name, "Incorrect gateway - need 'a.b.c.d'" ); 01500 01501 Network_SetGateway( a0, a1, a2, a3 ); 01502 01503 break; 01504 } 01505 case 4: // valid 01506 { 01507 int value; 01508 int count = Osc_ExtractData( typedata, "i", &value ); 01509 if ( count != 1 ) 01510 return Osc_SubsystemError( channel, NetworkOsc_Name, "Incorrect data - need an int" ); 01511 01512 Network_SetValid( value ); 01513 break; 01514 } 01515 case 5: // mac 01516 { 01517 return Osc_SubsystemError( channel, NetworkOsc_Name, "MAC is read only." ); 01518 } 01519 case 6: // osc_udp_listen_port 01520 { 01521 int value; 01522 int count = Osc_ExtractData( typedata, "i", &value ); 01523 if ( count != 1 ) 01524 return Osc_SubsystemError( channel, NetworkOsc_Name, "Incorrect data - need an int" ); 01525 01526 NetworkOsc_SetUdpListenPort( value ); 01527 break; 01528 } 01529 case 7: // osc_tcpout_address 01530 { 01531 char* address; 01532 int count = Osc_ExtractData( typedata, "s", &address ); 01533 if ( count != 1 ) 01534 return Osc_SubsystemError( channel, NetworkOsc_Name, "Incorrect data - need a string" ); 01535 // don't strictly need to do this, but it's god to make sure it's a proper address 01536 int status = Network_AddressConvert( address, &a0, &a1, &a2, &a3 ); 01537 if ( status != CONTROLLER_OK ) 01538 return Osc_SubsystemError( channel, NetworkOsc_Name, "Incorrect TCP address - need 'xxx.xxx.xxx.xxx'" ); 01539 01540 NetworkOsc_SetTcpOutAddress( a0, a1, a2, a3 ); 01541 break; 01542 } 01543 case 8: // osc_tcpout_port 01544 { 01545 int value; 01546 int count = Osc_ExtractData( typedata, "i", &value ); 01547 if ( count != 1 ) 01548 return Osc_SubsystemError( channel, NetworkOsc_Name, "Incorrect data - need an int" ); 01549 01550 NetworkOsc_SetTcpOutPort( value ); 01551 break; 01552 } 01553 case 9: // osc_tcpout_connect 01554 { 01555 int value; 01556 int count = Osc_ExtractData( typedata, "i", &value ); 01557 if ( count != 1 ) 01558 return Osc_SubsystemError( channel, NetworkOsc_Name, "Incorrect data - need an int" ); 01559 01560 if( value && Network->TcpRequested == 0 ) 01561 { 01562 Network->TcpRequested = 1; 01563 Osc_StartTcpTask( ); 01564 } 01565 if( !value && Network->TcpRequested == 1 ) 01566 Network->TcpRequested = 0; 01567 01568 break; 01569 } 01570 case 10: // osc_tcpout_auto 01571 { 01572 int value; 01573 int count = Osc_ExtractData( typedata, "i", &value ); 01574 if ( count != 1 ) 01575 return Osc_SubsystemError( channel, NetworkOsc_Name, "Incorrect data - need an int" ); 01576 01577 NetworkOsc_SetTcpAutoConnect( value ); 01578 break; 01579 } 01580 case 11: // dhcp 01581 { 01582 int value; 01583 int count = Osc_ExtractData( typedata, "i", &value ); 01584 if ( count != 1 ) 01585 return Osc_SubsystemError( channel, NetworkOsc_Name, "Incorrect data - need an int" ); 01586 01587 Network_SetDhcpEnabled( value ); 01588 break; 01589 } 01590 case 13: // osc_udp_send_port 01591 { 01592 int value; 01593 int count = Osc_ExtractData( typedata, "i", &value ); 01594 if ( count != 1 ) 01595 return Osc_SubsystemError( channel, NetworkOsc_Name, "Incorrect data - need an int" ); 01596 01597 NetworkOsc_SetUdpSendPort( value ); 01598 break; 01599 } 01600 } 01601 return CONTROLLER_OK; 01602 } 01603 01604 // Get the property 01605 int NetworkOsc_PropertyGet( int property, int channel ) 01606 { 01607 int value; 01608 int result = CONTROLLER_OK; 01609 int a0; 01610 int a1; 01611 int a2; 01612 int a3; 01613 01614 switch ( property ) 01615 { 01616 case 0: 01617 value = Network_GetActive( ); 01618 snprintf( Network->scratch1, OSC_SCRATCH_SIZE, "/%s/%s", NetworkOsc_Name, NetworkOsc_PropertyNames[ property ] ); 01619 Osc_CreateMessage( channel, Network->scratch1, ",i", value ); 01620 break; 01621 case 1: 01622 if ( Network_GetAddress( &a0, &a1, &a2, &a3 ) == CONTROLLER_ERROR_NO_NETWORK ) 01623 return Osc_SubsystemError( channel, NetworkOsc_Name, "No network address available - try plugging in an Ethernet cable." ); 01624 snprintf( Network->scratch1, OSC_SCRATCH_SIZE, "/%s/%s", NetworkOsc_Name, NetworkOsc_PropertyNames[ property ] ); 01625 snprintf( Network->scratch2, OSC_SCRATCH_SIZE, "%d.%d.%d.%d", a0, a1, a2, a3 ); 01626 Osc_CreateMessage( channel, Network->scratch1, ",s", Network->scratch2 ); 01627 break; 01628 case 2: 01629 if ( Network_GetMask( &a0, &a1, &a2, &a3 ) == CONTROLLER_ERROR_NO_NETWORK ) 01630 return Osc_SubsystemError( channel, NetworkOsc_Name, "No mask available - try plugging in an Ethernet cable." ); 01631 snprintf( Network->scratch1, OSC_SCRATCH_SIZE, "/%s/%s", NetworkOsc_Name, NetworkOsc_PropertyNames[ property ] ); 01632 snprintf( Network->scratch2, OSC_SCRATCH_SIZE, "%d.%d.%d.%d", a0, a1, a2, a3 ); 01633 Osc_CreateMessage( channel, Network->scratch1, ",s", Network->scratch2 ); 01634 break; 01635 case 3: 01636 if ( Network_GetGateway( &a0, &a1, &a2, &a3 ) == CONTROLLER_ERROR_NO_NETWORK ) 01637 return Osc_SubsystemError( channel, NetworkOsc_Name, "No gateway available - try plugging in an Ethernet cable." ); 01638 snprintf( Network->scratch1, OSC_SCRATCH_SIZE, "/%s/%s", NetworkOsc_Name, NetworkOsc_PropertyNames[ property ] ); 01639 snprintf( Network->scratch2, OSC_SCRATCH_SIZE, "%d.%d.%d.%d", a0, a1, a2, a3 ); 01640 Osc_CreateMessage( channel, Network->scratch1, ",s", Network->scratch2 ); 01641 break; 01642 case 4: 01643 value = Network_GetValid( ); 01644 snprintf( Network->scratch1, OSC_SCRATCH_SIZE, "/%s/%s", NetworkOsc_Name, NetworkOsc_PropertyNames[ property ] ); 01645 Osc_CreateMessage( channel, Network->scratch1, ",i", value ); 01646 break; 01647 case 5: 01648 snprintf( Network->scratch1, OSC_SCRATCH_SIZE, "/%s/%s", NetworkOsc_Name, NetworkOsc_PropertyNames[ property ] ); 01649 snprintf( Network->scratch2, OSC_SCRATCH_SIZE, "%02X:%02X:%02X:%02X:%02X:%02X", 01650 emacETHADDR0, emacETHADDR1, emacETHADDR2, emacETHADDR3, emacETHADDR4, emacETHADDR5 ); 01651 Osc_CreateMessage( channel, Network->scratch1, ",s", Network->scratch2 ); 01652 break; 01653 case 6: // osc_udp_listen_port 01654 value = NetworkOsc_GetUdpListenPort( ); 01655 snprintf( Network->scratch1, OSC_SCRATCH_SIZE, "/%s/%s", NetworkOsc_Name, NetworkOsc_PropertyNames[ property ] ); 01656 Osc_CreateMessage( channel, Network->scratch1, ",i", value ); 01657 break; 01658 case 7: // osc_tcpout_address 01659 value = NetworkOsc_GetTcpOutAddress( ); 01660 a0 = IP_ADDRESS_A( value ); 01661 a1 = IP_ADDRESS_B( value ); 01662 a2 = IP_ADDRESS_C( value ); 01663 a3 = IP_ADDRESS_D( value ); 01664 Network_AddressConvert( Network->scratch1, &a0, &a1, &a2, &a3 ); 01665 snprintf( Network->scratch1, OSC_SCRATCH_SIZE, "/%s/%s", NetworkOsc_Name, NetworkOsc_PropertyNames[ property ] ); 01666 snprintf( Network->scratch2, OSC_SCRATCH_SIZE, "%d.%d.%d.%d", a0, a1, a2, a3 ); 01667 Osc_CreateMessage( channel, Network->scratch1, ",s", Network->scratch2 ); 01668 break; 01669 case 8: // osc_tcpout_port 01670 value = NetworkOsc_GetTcpOutPort( ); 01671 snprintf( Network->scratch1, OSC_SCRATCH_SIZE, "/%s/%s", NetworkOsc_Name, NetworkOsc_PropertyNames[ property ] ); 01672 Osc_CreateMessage( channel, Network->scratch1, ",i", value ); 01673 break; 01674 case 9: // osc_tcpout_connect 01675 value = NetworkOsc_GetTcpRequested( ); 01676 snprintf( Network->scratch1, OSC_SCRATCH_SIZE, "/%s/%s", NetworkOsc_Name, NetworkOsc_PropertyNames[ property ] ); 01677 Osc_CreateMessage( channel, Network->scratch1, ",i", value ); 01678 break; 01679 case 10: // osc_tcpout_auto 01680 value = NetworkOsc_GetTcpAutoConnect( ); 01681 snprintf( Network->scratch1, OSC_SCRATCH_SIZE, "/%s/%s", NetworkOsc_Name, NetworkOsc_PropertyNames[ property ] ); 01682 Osc_CreateMessage( channel, Network->scratch1, ",i", value ); 01683 break; 01684 case 11: // dhcp 01685 value = Network_GetDhcpEnabled( ); 01686 snprintf( Network->scratch1, OSC_SCRATCH_SIZE, "/%s/%s", NetworkOsc_Name, NetworkOsc_PropertyNames[ property ] ); 01687 Osc_CreateMessage( channel, Network->scratch1, ",i", value ); 01688 break; 01689 case 12: // find 01690 { 01691 if ( Network_GetAddress( &a0, &a1, &a2, &a3 ) == CONTROLLER_ERROR_NO_NETWORK ) 01692 return Osc_SubsystemError( channel, NetworkOsc_Name, "No network address available - try plugging in an Ethernet cable." ); 01693 snprintf( Network->scratch1, OSC_SCRATCH_SIZE, "/%s/%s", NetworkOsc_Name, NetworkOsc_PropertyNames[ property ] ); 01694 snprintf( Network->scratch2, OSC_SCRATCH_SIZE, "%d.%d.%d.%d", a0, a1, a2, a3 ); 01695 int listen = NetworkOsc_GetUdpListenPort( ); 01696 int send = NetworkOsc_GetUdpSendPort( ); 01697 char* sysName = System_GetName( ); 01698 Osc_CreateMessage( channel, Network->scratch1, ",siis", Network->scratch2, listen, send, sysName ); 01699 break; 01700 } 01701 case 13: // osc_udp_send_port 01702 value = NetworkOsc_GetUdpSendPort( ); 01703 snprintf( Network->scratch1, OSC_SCRATCH_SIZE, "/%s/%s", NetworkOsc_Name, NetworkOsc_PropertyNames[ property ] ); 01704 Osc_CreateMessage( channel, Network->scratch1, ",i", value ); 01705 break; 01706 } 01707 01708 return result; 01709 } 01710 01711 #endif // OSC 01712 01713 #endif // MAKE_CTRL_NETWORK 01714 01715
The Make Controller Kit is an open source project maintained by MakingThings.
MakingThings code is released under the Apache 2.0 license.
Bug tracker, development wiki and status can be found at http://dev.makingthings.com.
This document was last updated on 18 May 2009.