#include "platform.h" #include "eth.h" #include "enc28j60.h" #include "ap.h" #include "arp.h" #include "icmp.h" #include "ip.h" #include "udp.h" #include "stdlib.h" #include "globals.h" void uart_send(char *p); //tuto funkci požíváme pro příjem dat, nikoli pro vysílání void ip_in (unsigned int len) { int i; int pocetpolozek; struct IP_header *ip; ip = (struct IP_header *) &buffer[14]; if (Checkmymac() || Checkbroadcast()) { //kontorla ip adresy if(!(ip->IP_destIp[0]==myip[0]&&ip->IP_destIp[1]==myip[1]&&ip->IP_destIp[2]==myip[2]&&ip->IP_destIp[3]==myip[3])) return ; //není moje ip adresa switch (ip->IP_protocol) { case TYPE_TCP: tcp_stat=1; // TCP break; //######## OBSLUHA ICMP######## case TYPE_ICMP: icmp (len,buffer); // přišel ICMP datagram break; //######## OBSLUHA UDP ######## case TYPE_UDP: //uložíme si IP a MAC adresu vysílače ;unsigned char a; for (a = 0; a < 4; a++)rem_ip[a] = ip->IP_sourceIp[a]; for (a = 0; a < 6; a++)rem_mac[a] = buffer[a+6]; mamIPprotejsku = 1; struct Thlavicka *header; //založení struktury UDP hlavičky header = (struct Thlavicka *) & buffer[42]; //přiřadíme jí v bufferu switch(header->TS){ //################ SYNCHRONIZACE HODIN ################ definovano v ap.h case CLK_SYNC: pocitmin = MINUTODEN; casjespravne = ( sekundy == header->CLK ); if (!casjespravne) { sekundy = header->CLK; //získáme čas maskaT2 = 0xa000; } else maskaT2 = 0x8000; status = CLK_ACK; if(!data_OK) //pokud nemám data { status=DATA_REQ; //pošle se žádost o data } break; //################ PŘÍJEM DAT ################ case DATA_IN: casjespravne = ( sekundy == header->CLK ); if (!casjespravne) sekundy = header->CLK; //získáme čas pocetpolozek = header->DL ; if( pocetpolozek > MAXPOLMOD) pocetpolozek = MAXPOLMOD; for(i=0; i<=MAXPOLMOD;i++ ) { stavvetve[i] = 0x00; mindoak[i] = 0x0ffff; } for(i=0;istavv; mindoak[i] = temp_zazn->minut; */ } maskaT2 = 0xfd40; nastavvetve(); // setresto(); nastavvetve uz obsahujue setresto data_OK=1; status=DATA_ACK; //vyšleme potvrzovací zprávu pocitmin = MINUTODEN; break; //############ NASTAVENI REGISTRU PR1 ################# case SET_RP1: { struct TnastavPR *header2; //založení struktury UDP hlavičky header2 = (struct TnastavPR *) & buffer[42]; //přiřadíme jí v bufferu nastPR1 = header2 -> PR1; maskaT2 = 0xa8f8; // if((nastPR1 <5999) || (nastPR1 > 9001) ) nastPR1 = DEFPR1; if((nastPR1 <20000) || (nastPR1 > 40000) ) nastPR1 = DEFPR1; pocitmin = MINUTODEN; status = ACK_SET_RP1; // v main vysleme potvrzeni - hlavne tam bude cas } break; //############ pozadavek na poslani casu modulu ################# case CLK_REQ: { status = CLK_REQ; // jen nastavim status pro main.c pocitmin = MINUTODEN; } break; //############ pozadavek na poslani DEFPR1 ################# case POSLIDEFPR1: { status = POSILAMDEFPR1; // jen nastavim status pro main.c pocitmin = MINUTODEN; } break; //############ pozadavek na poslani aktualniho stavu registru PR ################# case POSLIPR1: { status = POSILAMPR1; // jen nastavim status pro main.c pocitmin = MINUTODEN; } break; //############ pozadavek na RESET od ridiciho pocitace ################# case RESET_REQ: { cosestalo[0] = 7; maskaT2 = 0x5500; while(1) ; // a tady to kousnu a cekam na WDT reset } break; } /* od switch switch(header->TS) */ break; } /* od switch (ip->IP_protocol) */ } /* od uplne prvniho if */ } /* ############################################################ tato funkce slouží pro vyplnění dat při vysílání - dle potřeby je možné upravit, jedná se především o potřebu změny IP adres - nastavení: bez fragmentace, bez ToS, IPv4 ############################################################ */ void ip_my (unsigned char *buff) { unsigned int sum; unsigned char a; struct IP_header *ip; ip = (struct IP_header *) &buff[14]; ip->IP_ver_and_IHL=0x45; ip->IP_type_of_service=0x0; ip->IP_fragment=0x0000; ip->IP_TTL=64; ip->IP_protocol=17; //protokol vyšší vrstvy je UDP for (a = 0; a < 4; a++) { // odpovídáme - výměna IP adres ip->IP_destIp[a] = rem_ip[a]; ip->IP_sourceIp[a] = myip[a]; } ip->IP_checksum = 0; // výpočet a zapsaání kontrloního součtu sum = checksum(&buff[14], 0, 20); ip->IP_checksum = ((sum & 0xFF00) >> 8) | ((sum & 0x00FF) << 8); } /* ############################################################ původní vysílací funkce - je zde pro spávnou funkci ICMP protokolu, který zůstal nezměněn - vymění ip adresy a přepočítá kontrolní součet ############################################################ */ void ip (unsigned char *buff) { unsigned int sum; unsigned char a; struct IP_header *ip; ip = (struct IP_header *) &buff[14]; for (a = 0; a < 4; a++) { // swap IP address ip->IP_destIp[a] = ip->IP_sourceIp[a]; ip->IP_sourceIp[a] = myip[a]; } ip->IP_checksum = 0; // checksum calculate sum = checksum(&buff[14], 0, 20); ip->IP_checksum = ((sum & 0xFF00) >> 8) | ((sum & 0x00FF) << 8); } /* ############################################################ funkce pro výpočet kontrolního součtu ############################################################ */ int checksum (unsigned char *pointer,unsigned long result32,unsigned int result16) { unsigned int result16_1 = 0x0000; unsigned char DataH; unsigned char DataL; while (result16 > 1) { DataH =* pointer++; DataL =* pointer++; result16_1 = ((DataH << 8) + DataL); result32 = result32 + result16_1; result16 -= 2; } if (result16 > 0) { DataH=*pointer; result16_1 = (DataH << 8); result32 = result32 + result16_1; } result32 = ((result32 & 0x0000FFFF) + ((result32 & 0xFFFF0000) >> 16)); result32 = ((result32 & 0x0000FFFF) + ((result32 & 0xFFFF0000) >> 16)); result16 =~ (result32 & 0x0000FFFF); return (result16); }