Marco De Silva / Eth_tcp
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Eth_tcp.cpp Source File

Eth_tcp.cpp

00001 #include "Eth_tcp.h"
00002 
00003 Eth_tcp::Eth_tcp(float srv_timeout_){  
00004 
00005     eth = NetworkInterface::get_default_instance();
00006     port = ethPort;
00007     srv_timeout = srv_timeout_;
00008     result = false;
00009     
00010     printf("[Ethernet Interface] Create ethernet...");
00011     result = eth->set_network(NET_IP_ADDRESS, NET_NETMASK, NET_GATEWAY);
00012     
00013     if (result != 0) {
00014         printf("\nError! eth.set_network() returned: %d\n", result);
00015         NVIC_SystemReset();
00016     }
00017     printf("done!\n");
00018     
00019     srv_accepted = false;
00020     sendCurrentRsp = false;  
00021 
00022 }
00023 
00024 
00025 Status Eth_tcp::connect(){
00026     
00027     printf("[Ethernet Interface] eth.connect()...");
00028     //Connect the interface
00029     result = eth->connect();
00030     if (result != 0) {
00031         printf("\nError! eth.connect() returned: %d\n", result);
00032         NVIC_SystemReset();
00033     }
00034     printf("done!\n");
00035 
00036     // Show the network address
00037     const char *ip = eth->get_ip_address();
00038     const char *netmask = eth->get_netmask();
00039     const char *gateway = eth->get_gateway();
00040     printf("[Ethernet Interface] IP address: %s\n", ip ? ip : "None");
00041     printf("[Ethernet Interface] Netmask: %s\n", netmask ? netmask : "None");
00042     printf("[Ethernet Interface] Gateway: %s\n", gateway ? gateway : "None");
00043     
00044     // Time out
00045     srv.set_timeout(srv_timeout);                   ////////////////////// ANDREA
00046     // Open the server on ethernet stack
00047     printf("[TCP SERVER] srv.open()...");
00048     //result = clt_sock.open(eth);
00049     result = srv.open(eth);               /////////////////////// ANDREA
00050     if (result != 0) {
00051         printf("\nError! srv.open() returned: %d\n", result);
00052         NVIC_SystemReset();
00053     }
00054     printf("done!\n");
00055     //Bind the port to the server
00056     printf("[TCP SERVER] srv.bind()...");
00057      //result = clt_sock.bind(eth->get_ip_address(), port);/////////////////// ANDREA
00058      result = srv.bind(eth->get_ip_address(), port);
00059 
00060     if (result != 0) {
00061         printf("\nError! srv.bind() returned: %d\n", result);
00062         NVIC_SystemReset();
00063     }
00064     printf("done!\n");
00065 
00066     //Can handle 1 simultaneous connections 
00067     srv.listen(1);          //////////////// ANDREA
00068         
00069     srv.set_blocking(false); ////////////////////
00070     clt_sock.set_blocking(false);
00071     
00072     status = ETH_CONNECTED; 
00073      
00074     comunicationTimer.start(); 
00075     
00076     return status;
00077     
00078 }
00079 
00080 
00081 uint8_t Eth_tcp::CheckSumFun(uint8_t* byteData, int length)
00082 {
00083     uint8_t chkSumByte = 0x00;
00084     for (int i = 0; i < length; i++)
00085         chkSumByte ^= byteData[i];
00086     return chkSumByte;
00087 }
00088  
00089 bool Eth_tcp::isNumber(char v)
00090 {
00091     return v=='0' || v=='1' || v=='2' || v=='3' || v=='4' || v=='5' || v=='6' || v=='7' || v=='8' || v=='9'; 
00092 }
00093 
00094 bool Eth_tcp::isValidIpAddress(char* addr)
00095 {
00096     return  isNumber(addr[0]) && isNumber(addr[1]) && isNumber(addr[2]) &&
00097             (addr[3] == '.') &&
00098             isNumber(addr[4]) && isNumber(addr[5]) && isNumber(addr[6]) &&
00099             (addr[7] == '.') &&
00100             isNumber(addr[8]) && isNumber(addr[9]) && isNumber(addr[10]) &&
00101             (addr[11] == '.') &&
00102             isNumber(addr[12]) && isNumber(addr[13]) && isNumber(addr[14]);
00103 }
00104  
00105 bool Eth_tcp::isInSameNetwork(const char* sip1, const char* sip2)
00106 {
00107    int ip1[4];
00108    sscanf(sip1, "%d.%d.%d.%d\n", &ip1[3], &ip1[2], &ip1[1], &ip1[0]); 
00109    int ip2[4];
00110    sscanf(sip2, "%d.%d.%d.%d\n", &ip2[3], &ip2[2], &ip2[1], &ip2[0]);
00111    return ip1[3]==ip2[3] && ip1[2]==ip2[2] && ip1[1]==ip2[1];
00112 }
00113  
00114 
00115 
00116 Status Eth_tcp::updateEthCommunication(ConfigMsg& cnf_msg_, ComandMsg& cmd_msg_, ResponseMsg rsp_msg){
00117 
00118     char sock_buffer[TCP_SERVER_BUFFER_SIZE];
00119     char ack = '&';
00120    
00121     ConfigMsg* cnf_msg;
00122     ComandMsg* cmd_msg; 
00123     
00124     is_connected();
00125     
00126     eth_time = comunicationTimer.read();
00127     
00128     // if sync communication is active the data is sended after it is readed
00129     if(sendCurrentRsp){
00130         if (0 < clt_sock.send(&rsp_msg, sizeof(rsp_msg))) {                        
00131             
00132         }else{
00133             status = ETH_ERROR_SENDING_DATA;
00134             if (ETH_DEBUG) printf("[SOCKET] Error sending data!!!\n");
00135         }
00136         sendCurrentRsp = false;  
00137     }
00138 
00139     //receive data
00140     int n = clt_sock.recv(&sock_buffer, sizeof(sock_buffer));
00141     if (ETH_DEBUG) printf("n: %d\n",n);
00142 
00143     if(sock_open && n!=-3001) 
00144     {     
00145         if (sock_buffer[0] == PacketId::ID_receive_command_send_prec_val && n == sizeof(ComandMsg) && isInSameNetwork(clt_addr.get_ip_address(),eth->get_ip_address()) )
00146         {
00147             cmd_msg = (ComandMsg *)&sock_buffer;
00148             
00149             //Checksum
00150             uint8_t cks_msg = cmd_msg->Checksum;
00151             
00152             /*if (ETH_DEBUG) printf("Checksum obtained %d!!\n",cmd_msg->Checksum);
00153             if (ETH_DEBUG) printf("DataF1 obtained %f!!\n",cmd_msg->Data.D1);
00154             if (ETH_DEBUG) printf("DataF2 obtained %f!!\n",cmd_msg->Data.D2);
00155             if (ETH_DEBUG) printf("Time obtained %d!!\n",cmd_msg->Data.Time);
00156             if (ETH_DEBUG) printf("N obtained %d!!\n",cmd_msg->Data.N);*/
00157     
00158             cmd_msg->Checksum = 255;
00159             uint8_t cks = CheckSumFun((uint8_t*)cmd_msg, n);
00160             cmd_msg->Checksum = cks_msg;
00161     
00162             if (cks_msg == cks)
00163             {
00164                 comunicationTimer.reset();  
00165     
00166                 /*if (ETH_DEBUG) printf("Valid Comand: Cmd:%i, Ptn: (%.3f %.3f), Press: (n=%i, %i), Cks:%i\n", 
00167                     cmd_msg->Cmd, cmd_msg->Data.D1, cmd_msg->Data.D2, cmd_msg->Data.N, cmd_msg->Data.Time, cmd_msg->Checksum);*/
00168                 
00169                 cmd_msg_.pId = cmd_msg->pId;
00170                 cmd_msg_.Cmd = cmd_msg->Cmd;
00171                 cmd_msg_.Data = cmd_msg->Data;
00172                 cmd_msg_.Checksum = cmd_msg->Checksum;
00173                 
00174                 if (ETH_DEBUG) printf("[SOCKET] Send response packet\n");
00175                 if (0 < clt_sock.send(&rsp_msg, sizeof(rsp_msg))) {                        
00176                     status = ETH_NEW_CMD;
00177                 }else{
00178                     status = ETH_ERROR_SENDING_DATA;
00179                     if (ETH_DEBUG) printf("[SOCKET] Error sending data!!!\n");
00180                 }
00181                                         
00182             }else{
00183                 //Checksum error
00184                 if (ETH_DEBUG) printf("Request with CHECKSUM error (cks_msg: %i vs computed: %i) from %s:%d\n", cks_msg, cks, clt_addr.get_ip_address(), clt_addr.get_port());
00185                 status = ETH_CHECKSUM_ERROR;
00186             }
00187        
00188         }else if (sock_buffer[0] == PacketId::ID_config && n == sizeof(ConfigMsg) && isInSameNetwork(clt_addr.get_ip_address(),eth->get_ip_address()) )
00189         {
00190             cnf_msg = (ConfigMsg *)&sock_buffer;
00191             
00192             if (ETH_DEBUG) printf("Checksum check!!\n");
00193     
00194             //Checksum
00195             uint8_t cks_msg = cnf_msg->Checksum;
00196             
00197             cnf_msg->Checksum = 255;
00198             uint8_t cks = CheckSumFun((uint8_t*)cnf_msg, n);
00199             cnf_msg->Checksum = cks_msg;
00200     
00201             if (cks_msg == cks)
00202             {
00203                 comunicationTimer.reset();  
00204     
00205                 cnf_msg_.pId = cnf_msg->pId;
00206                 cnf_msg_.Data = cnf_msg->Data;
00207                 cnf_msg_.Checksum = cnf_msg->Checksum;
00208                 
00209                 if (ETH_DEBUG) printf("[SOCKET] Send ack\n");
00210                 
00211                 if (0 < clt_sock.send(&ack, sizeof(ack))) {                        
00212                     status = ETH_NEW_CNF;
00213                     printf("The configuration parameters have beed updated!!!\n");
00214                 }else{
00215                     status = ETH_ERROR_SENDING_DATA;
00216                     if (ETH_DEBUG) printf("[SOCKET] Error sending data!!!\n");
00217                 }
00218                     
00219             }else{
00220                 //Checksum error
00221                 if (ETH_DEBUG) printf("Request with CHECKSUM error (cks_msg: %i vs computed: %i) from %s:%d\n", cks_msg, cks, clt_addr.get_ip_address(), clt_addr.get_port());
00222                 status = ETH_CHECKSUM_ERROR;
00223             }
00224                 
00225                     
00226         }else if (sock_buffer[0] == PacketId::ID_receive_command_send_current_val && n == sizeof(ComandMsg) && isInSameNetwork(clt_addr.get_ip_address(),eth->get_ip_address()) )
00227         {
00228             cmd_msg = (ComandMsg *)&sock_buffer;
00229             
00230             if (ETH_DEBUG) printf("Checksum check!!\n");
00231     
00232             //Checksum
00233             uint8_t cks_msg = cmd_msg->Checksum;
00234               
00235             cmd_msg->Checksum = 255;
00236             uint8_t cks = CheckSumFun((uint8_t*)cmd_msg, n);
00237             cmd_msg->Checksum = cks_msg;
00238     
00239             if (cks_msg == cks)
00240             {
00241                 comunicationTimer.reset();  
00242                         
00243                 cmd_msg_.pId = cmd_msg->pId;
00244                 cmd_msg_.Cmd = cmd_msg->Cmd;
00245                 cmd_msg_.Data = cmd_msg->Data;
00246                 cmd_msg_.Checksum = cmd_msg->Checksum;
00247                 
00248                 if (ETH_DEBUG) printf("[SOCKET] Set the status to 4, after the control the main program must call the funcion send_response!!!!\n");
00249                 
00250                 sendCurrentRsp = true;
00251                 status = ETH_NEW_CMD_CURRENT_VAL_REQUEST;
00252                     
00253                                         
00254             }else{
00255                 //Checksum error
00256                 if (ETH_DEBUG) printf("Request with CHECKSUM error (cks_msg: %i vs computed: %i) from %s:%d\n", cks_msg, cks, clt_addr.get_ip_address(), clt_addr.get_port());
00257                 status = ETH_CHECKSUM_ERROR;
00258             }
00259         
00260         }else{
00261          if (ETH_DEBUG) printf("[SOCKET] the number of bytes are not equal to the dimension of the command message: n = %d sizeCmd = %d sizeCnf = %d !!!\n",n,sizeof(ComandMsg), sizeof(ConfigMsg)); 
00262          status = ETH_WRONG_RECV_SIZE;  
00263         }
00264      
00265     }else{
00266        
00267         status = ETH_IDLE;
00268     }
00269     
00270    if((double)(eth_time)>srv_timeout && sock_open == true){
00271         reset_connection();
00272         status = ETH_LOST_CONNECTION;
00273         
00274    }
00275   
00276    return status;
00277 
00278  }
00279  
00280 void Eth_tcp::is_connected() {
00281     
00282     if(!srv_accepted){
00283         srv_accepted = srv.accept(&clt_sock, &clt_addr)==0;
00284     }
00285     
00286     if(srv_accepted && !sock_open){ //is_connected()
00287         printf("[EthCommunicationUpdate] Accepted connection %s:%d\n", clt_addr.get_ip_address(), clt_addr.get_port());
00288         if(!sock_open){comunicationTimer.reset();}
00289         sock_open = true;
00290         status = ETH_SRV_ACCEPTED;
00291     }else{
00292         if (ETH_DEBUG) printf("[EthCommunicationUpdate] Wait for a TCP connection\n");
00293     }
00294    
00295 } 
00296 
00297 void Eth_tcp::reset_connection(){ 
00298     if(clt_sock.close()==0){printf("SOCKET CLOSED\r\n");}
00299     if (ETH_DEBUG) printf("[EthCommunicationUpdate] Reset connection\n");
00300     sock_open = false;
00301     srv_accepted = false;
00302     
00303 }
00304    
00305     
00306