/** * Fährt den Spcket Server bei einem Fehler runter. Dabei werden zuerst alle Subserver heruntergefahren die jeweiligen Socketverbindungen getrennt. * @param lsd Der jeweilige eindeutige Socketdeskriptor * @param error Fehlercode * @return Gibt eine 0 für erfolgreiches runterfahren aller Sockets zurück */ int shutDownServer(int lsd, int error){ server_shutdown = 1; //set shutdown flag printf("\r\nTCP Echoserver shutdown\r\n"); for(int i=0;i<MAX_SERVER;i++)// wakeup sleeping tasks { if((EchoServer[i].sd==-1) && (EchoServer[i].taskID!=-1)) { RTX_Wakeup(EchoServer[i].taskID); } } //wait until the subserver tasks have finished int result=0; while(result<10) { RTX_Sleep_Time(1000); if((EchoServer[0].finish) && (EchoServer[1].finish) && (EchoServer[2].finish)) { break; } result++; } //removing DK40 Task RTX_Delete_Task(dk40ID); RTX_Sleep_Time(100); if(lsd!=-1) { #ifdef TCPSERV_DEBUG printf("\r\nTCP Echoserver: Closing listening socket %d",lsd); #endif result = closesocket(lsd,&error); if(result == API_ERROR) { printf("\r\nTCPEchoServer: Socket close failed %d",error); } } printf("\r\nTCP Echoserver finished\r\n"); return 0; }
static int dmx_write(int port, dmx_t *dmx, size_t size) { int ret; if ((ret = do_dmx_break(port)) == EXIT_SUCCESS) { int j; // BIOS_putch('*'); RTX_Sleep_Time(1); for( j = 0; j < size; ) { j += fossil_writeblock(port, ((unsigned char far *)dmx) + j, size - j); // printf("j = %d\n", j); } } return EXIT_SUCCESS; }
static void huge _pascal CgiCliFunction(rpCgiPtr CgiRequest){ /* Buffers for building the page */ extern CgiCli_t *CgiCli; extern CO_t *CO; CO_SDOclient_t *SDO_C = CO->SDOclient; uint32_t bufLen = 0; /* current length of the buffer */ uint32_t timeouts = 0; const uint32_t maxTimeouts = 5; /* Prepare function, which will wake this task after CAN SDO response is */ /* received (inside CAN receive interrupt). */ SDO_C->pFunctSignal = CgiCli_signal; /* will wake from RTX_Sleep_Time() */ SDO_C->functArg = RTX_Get_TaskID(); /* id of this task */ /* Construct HTML page */ if(strlen(CgiRequest->fArgumentBufferPtr)){ char_t *buf = CgiCli->buf; /* buffer for CGI message */ char_t far *name = NULL; char_t far *val = NULL; while(CGI_GetArgument(&name, &val, CgiRequest) == 0){ /* decode and verify name */ char_t rw = name[0]; uint32_t nodeId, idx, sidx, len; char_t err = 0; uint8_t *data = CgiCli->SDOBuf; /* data sent or received on CANopen */ uint32_t dataLen = 0; if(!name) err++; len = strlen(name); if (rw == 'r' || rw == 'R'){ rw = 'r'; if(len < 9 || len > 17) err++; } else if(rw == 'w' || rw == 'W'){ rw = 'w'; if(len < 10 || len > 17) err++; } else{ err++; } err += hex2dec(&name[1], 2, &nodeId); if(nodeId > 127) err++; err += hex2dec(&name[3], 4, &idx); err += hex2dec(&name[7], 2, &sidx); if(rw == 'w'){ err += hex2dec(&name[9], len-9, &len); /* decode value */ int32_t i; int32_t valLen; if(val) valLen = strlen(val); else valLen = 0; for(i=0; i<valLen; i=i+2){ uint32_t dc; err += hex2dec(&val[i], 2, &dc); data[dataLen] = dc; if(++dataLen >= CgiCli->SDOBufSize) break; } /* verify value length */ if(dataLen != len || dataLen == 0) err++; } /* SDO clinet access */ uint32_t SDOabortCode = 0; if(err){ buf += sprintf(buf, "Error in argument: %s=%s\n", name, val); } /* read object dictionary */ else if(rw == 'r'){ CO_SDOclient_return_t ret; CO_SDOclient_setup(SDO_C, 0, 0, nodeId); CO_SDOclientUploadInitiate(SDO_C, idx, sidx, data, CgiCli->SDOBufSize, 1); do{ uint16_t dt = 50; ret = CO_SDOclientUpload(SDO_C, dt, 500, &dataLen, &SDOabortCode); RTX_Sleep_Time(dt); }while(ret > 0); CO_SDOclientClose(SDO_C); if(ret == CO_SDOcli_endedWithTimeout) { timeouts++; } else { timeouts = 0; } if(SDOabortCode){ buf += sprintf(buf, "R %02X%04X%02X%X AB: %08X\n", (unsigned int)nodeId, (unsigned int)idx, (unsigned int)sidx, (unsigned int)dataLen, (unsigned int)SDOabortCode); } else{ uint32_t i; buf += sprintf(buf, "R %02X%04X%02X%X OK:", (unsigned int)nodeId, (unsigned int)idx, (unsigned int)sidx, (unsigned int)dataLen); for(i=0; i<dataLen; i++) buf += sprintf(buf, " %02X", data[i]); buf += sprintf(buf, "\n"); } } /* write into object dictionary */ else if(rw == 'w'){ CO_SDOclient_return_t ret; CO_SDOclient_setup(SDO_C, 0, 0, nodeId); CO_SDOclientDownloadInitiate(SDO_C, idx, sidx, data, dataLen, 1); do{ uint16_t dt = 2; ret = CO_SDOclientDownload(SDO_C, dt, 500, &SDOabortCode); if(ret == CO_SDOcli_waitingServerResponse) { dt = 50; } RTX_Sleep_Time(dt); }while(ret > 0); CO_SDOclientClose(SDO_C); if(ret == CO_SDOcli_endedWithTimeout) { timeouts++; } else { timeouts = 0; } if(SDOabortCode){ buf += sprintf(buf, "W %02X%04X%02X%X AB: %08X\n", (unsigned int)nodeId, (unsigned int)idx, (unsigned int)sidx, (unsigned int)dataLen, (unsigned int)SDOabortCode); } else{ uint32_t i; buf += sprintf(buf, "W %02X%04X%02X%X OK:", (unsigned int)nodeId, (unsigned int)idx, (unsigned int)sidx, (unsigned int)dataLen); for(i=0; i<dataLen; i++) buf += sprintf(buf, " %02X", data[i]); buf += sprintf(buf, "\n"); } } /* calculate buffer length, if not enough space for next object, break */ bufLen = (uint32_t)(buf - CgiCli->buf); if((bufLen+1000) > CgiCli->bufSize){ break; } /* if no response from remote node for multiple times, break the loop */ if(timeouts > maxTimeouts){ break; } } } else{ sprintf(CgiCli->buf, "CGI function provides access to object dictionary on any device on the CANopen network.\n\n" "Usage with POST method:\n" " odcli?wnniiiissll=xxxx[&rnniiiissll=]\n" " w - 'w'rite or 'r'ead.\n" " nn - node ID in hex format.\n" " iiii - Object dictionary index in hex format.\n" " ss - Object dictionary subindex in hex format.\n" " ll - length of variable (1 to FFFFFFFF) in hex format. If reading, this value is ignored.\n" " xxxx - Value to be written in hex and little endian format. If reading, this value is ignored.\n"); bufLen = strlen(CgiCli->buf); } /* disable SDO client */ CO_SDOclient_setup(SDO_C, 0, 0, 0); /* Give page to the web server */ CgiRequest->fHttpResponse = CgiHttpOk; CgiRequest->fDataType = CGIDataTypeText; CgiRequest->fResponseBufferPtr = CgiCli->buf; CgiRequest->fResponseBufferLength = bufLen; }
/** * main() */ int main() { int lsd = -1; //listening socketdescriptor int asd = -1; //new socketdescriptor from accept int port = TM_PORT_ECHO; //default port int error = 0; int result; //int i; struct sockaddr_in addr; struct sockaddr_in claddr; char ClientIP[17]; int taskrdy = -1; initServer(); startDK40Task(); initSubServerTask(lsd,error); RTX_Sleep_Time(100); lsd = openListenSocket(lsd,error); #ifdef TCPSERV_DEBUG printf("\r\nTCP Echoserver: Öffnen einen Socket %d",lsd); #endif /** * Setzt den horchenden Socket auf Wiederverwendbar ein * @param lsd Den Socketdeskriptor des horchenden Sockets * @param error Fehlercode * @return (0) für erfolgreich, ungleich (0) für fehler */ result = setreuse(lsd,&error); #ifdef TCPSERV_DEBUG if(result == API_ERROR){ printf("\r\nTCP Echoserver: Set reuse failed %d",error); } #endif addr.sin_family = PF_INET; addr.sin_port = htons(port); //Konvertierung von Little Endian zu Big Endian addr.sin_addr.s_addr = 0L; result = bind(lsd,(struct sockaddr *)&addr,&error); if(result == API_ERROR){ printf("\r\nTCP Echoserver, Bind socket failed %d",error); shutDownServer(lsd,error); }//(result == API_ERROR) /* * Endlosschleife, horcht und baut Verbindungen auf */ while(1) { /** * listen */ result = listen(lsd, MAX_SERVER, &error); if(result == API_ERROR){ printf("\r\nTCP Echoserver, listen failed %d",error); shutDownServer(lsd,error); }//if(result == API_ERROR) /** * accept , establish a connection */ claddr.sin_family = PF_INET; claddr.sin_port = 0; //clear claddr.sin_addr.s_addr = 0L; //clear result = accept(lsd,(struct sockaddr *)&claddr,&error); if(result == API_ERROR){ printf("\r\nTCP Echoserver, accept failed %d",error); shutDownServer(lsd,error); }//if(result == API_ERROR) InetToAscii(&claddr.sin_addr.s_addr,ClientIP); #ifdef TCPSERV_DEBUG printf("\r\nTCP Echoserver: Connected with %s , Port %u\r\n",ClientIP,claddr.sin_port); #endif asd = result; cnt_connection++; #ifdef SERVER_SHUTDOWN_TEST if(cnt_connection>6L){ result = closesocket(asd,&error); if(result==API_ERROR){ printf("\r\nTCP Echoserver, socket close failed %d",error); } printf("\r\nTCP Echoserver: Shutdown test\r\n"); shutDownServer(lsd,error); }//if(cnt_connection>6L) #endif /** * Suche einer ruhenden Server Task */ taskrdy = Get_Free_Server_Task(); if(taskrdy == -1){ //no sleeping task found #ifdef TCPSERV_DEBUG printf("\r\nTCPserver: busy, refusing connection with %s , Port %u\r\n",ClientIP,claddr.sin_port); #endif closesocket(asd, &error); }//if(taskrdy == -1) else{ //insert the socket descriptor EchoServer[taskrdy].sd = asd; //and wakeup the sleeping server task result = RTX_Wakeup(EchoServer[taskrdy].taskID); if(result != 0){ printf("\r\nTCPserver: wakeup error\r\n"); closesocket(asd, &error); }//if(result != 0) else{ //a task is waked up and serves from now on this connection } }//elseif(taskrdy == -1) //no sleeping task found }//while(1) //do forever }