FITkit
Fakulta informačních technologií

enc28j60_udp.c

Zobrazit dokumentaci tohoto souboru.
00001 /*******************************************************************************
00002    enc28j60_udp.c: Transportní vrstva modelu TCP/IP, protokol UDP
00003    Copyright (C) 2010 Brno University of Technology,
00004                       Faculty of Information Technology
00005    Author(s): Martin Musil <xmusil34 AT fit.vutbr.cz>
00006 
00007    LICENSE TERMS
00008 
00009    Redistribution and use in source and binary forms, with or without
00010    modification, are permitted provided that the following conditions
00011    are met:
00012    1. Redistributions of source code must retain the above copyright
00013       notice, this list of conditions and the following disclaimer.
00014    2. Redistributions in binary form must reproduce the above copyright
00015       notice, this list of conditions and the following disclaimer in
00016       the documentation and/or other materials provided with the
00017       distribution.
00018    3. All advertising materials mentioning features or use of this software
00019       or firmware must display the following acknowledgement:
00020 
00021         This product includes software developed by the University of
00022         Technology, Faculty of Information Technology, Brno and its
00023         contributors.
00024 
00025    4. Neither the name of the Company nor the names of its contributors
00026       may be used to endorse or promote products derived from this
00027       software without specific prior written permission.
00028 
00029    This software or firmware is provided ``as is'', and any express or implied
00030    warranties, including, but not limited to, the implied warranties of
00031    merchantability and fitness for a particular purpose are disclaimed.
00032    In no event shall the company or contributors be liable for any
00033    direct, indirect, incidental, special, exemplary, or consequential
00034    damages (including, but not limited to, procurement of substitute
00035    goods or services; loss of use, data, or profits; or business
00036    interruption) however caused and on any theory of liability, whether
00037    in contract, strict liability, or tort (including negligence or
00038    otherwise) arising in any way out of the use of this software, even
00039    if advised of the possibility of such damage.
00040 
00041    $Id$
00042 
00043 *******************************************************************************/ 
00044 
00045 #include "enc28j60_udp.h"
00046 #include "enc28j60_udp.h"
00047 #include "enc28j60_spi.h"
00048 
00049 struct udp_socket udp_socket_table[SOCKET_COUNT];
00050 extern unsigned long local_ip;
00051 
00055 void udp_recv(struct ip_h* ip_header){
00056         
00057         struct udp_h udp_header;
00058         
00059         if(rx_read(&udp_header, UDP_HEADER_LEN) != UDP_HEADER_LEN)
00060                 return;
00061         
00062         unsigned char i;
00063         /*kontrola portu, volani obsluzne aplikace*/
00064         //vyhledani existujiciho zaznamu
00065         for(i=0; i<SOCKET_COUNT; i++){
00066 
00067                 if(udp_socket_table[i].port == NTOHS(udp_header.dest_port)){            //prepsani stavajiciho handleru
00068                         (*(udp_socket_table[i].app_handler))(ip_header, &udp_header);
00069                         return;
00070                 }
00071         }
00072 return;
00073 }
00074 
00078 char udp_send(unsigned int dest_port,unsigned int src_port, unsigned long ip){
00079 /*      
00080         if(!link_up()){                 //kabel odpojen,nebudeme odesilat
00081                 tx_unlock(TX1);
00082                 return -1;
00083         }
00084 */      
00085         struct udp_h udp_header;
00086         
00087         tx_seek(UDP_HEADER);
00088         
00089         udp_header.src_port = HTONS(src_port);                  //sestaveni hlavicky
00090         udp_header.dest_port = HTONS(dest_port);
00091         udp_header.length = HTONS(tx_data_len());
00092         udp_header.checksum = 0x0000;
00093         
00094         tx_write(&udp_header, UDP_HEADER_LEN);                  //zapsani hlavicky s prazdnym checksumem
00095         
00096         tx_seek(UDP_HEADER);
00097         udp_header.checksum = HTONS( udp_checksum(ip,tx_data_len() ));  //vypocitani checksumu
00098         tx_write(&udp_header, UDP_HEADER_LEN);                  //prepsani hlavicky s platnym checksumem
00099         
00100 
00101 return ip_send(ip,IP_PROTO_UDP);
00102 }
00103 
00107 unsigned int udp_checksum(unsigned long dest_ip,int length){
00108         
00109         unsigned long sum = 0;
00110         unsigned int* ptr;
00111         
00112         ptr = (unsigned int*)&local_ip;
00113         sum += *ptr;
00114         ptr++;
00115         sum += *ptr;
00116         
00117         ptr = (unsigned int*)&dest_ip;
00118         sum += *ptr;
00119         ptr++;
00120         sum += *ptr;
00121         
00122         sum += IP_PROTO_UDP;
00123         sum += length;  
00124         
00125         sum += (unsigned int) ~tx_checksum();
00126         
00127         while(sum >>16)
00128                 sum = (sum & 0xFFFF) + (sum >> 16);
00129 
00130 return (unsigned int) ~sum;
00131 }
00132 
00133 
00134 //*********************************************
00135 //fce pro praci s handlery k jednotlivym portum
00136 
00140 unsigned int udp_bind(unsigned int port,void* handler){
00141         
00142         unsigned char i;
00143         
00144         //vyhledani existujiciho zaznamu
00145         for(i=0; i<SOCKET_COUNT; i++){
00146                 if(udp_socket_table[i].port == port){           //prepsani existujiciho handleru
00147                         udp_socket_table[i].app_handler = handler;
00148                         return port;
00149                 }
00150         }
00151         
00152         //hledani volneho mista v tabulce
00153         for(i=0; i<SOCKET_COUNT; i++){
00154                 if(udp_socket_table[i].port == 0){                      //zaregistrovani noveho portu
00155                         udp_socket_table[i].port = port;
00156                         udp_socket_table[i].app_handler = handler;
00157                         return port;
00158                 }
00159         }
00160         
00161 return 0;
00162 }
00163 
00167 void udp_unbind(unsigned int port){
00168 
00169         unsigned char i;
00170         //vyhledani existujiciho zaznamu
00171         for(i=0; i<SOCKET_COUNT; i++){
00172                 if(udp_socket_table[i].port == port){           //prepsani stavajiciho handleru
00173                         udp_socket_table[i].port = 0;
00174                         return;
00175                 }
00176         }
00177         
00178 return;
00179 }
00180