|
Go to the documentation of this file.
15 #ifdef FAUDES_IODEVICE_MODBUS
44 FD_DHV( "mbDevice(" << mName << ")::mbDevice()");
46 mDefaultLabel = "ModbusDevice";
53 mMessage= new char[260];
56 mSlaveAddress.IpColonPort( "localhost:502");
96 std::stringstream errstr;
97 errstr << "image size must not exceed 2000 bits (image #" << i+1 << ")";
98 throw Exception( "mbDevice:Read", errstr.str(), 52);
113 std::stringstream errstr;
114 errstr << "Slave must have localhost as SlaveAddress";
115 throw Exception( "mbDevice:Compile()", errstr.str(), 52);
209 while(rTr. Peek(token)) {
215 std::stringstream errstr;
216 errstr << "Invalid role tag, value attribute missing" << rTr. FileLine();
217 throw Exception( "mpiDevice:Read", errstr.str(), 52);
220 std::transform(val.begin(), val.end(), val.begin(), tolower);
224 std::stringstream errstr;
225 errstr << "Invalid value attribute in role tag" << rTr. FileLine();
226 throw Exception( "spiDevice:Read", errstr.str(), 52);
232 if(token. IsBegin( "SlaveAddress")) {
233 FD_DHV( "mBDevice::DoRead(): found slave address");
236 std::stringstream errstr;
237 errstr << "Invalid ip address" << rTr. FileLine();
238 throw Exception( "mbDevice:Read", errstr.str(), 52);
245 if(token. IsBegin( "RemoteImage")) {
247 while(!rTr. Eos( "RemoteImage")) {
251 if(!rtoken. IsBegin( "Outputs")) {
252 std::stringstream errstr;
253 errstr << "invalid io range" << rTr. FileLine();
254 throw Exception( "mbDevice:Read", errstr.str(), 52);
263 std::stringstream errstr;
264 errstr << "missing remote address" << rTr. FileLine();
265 throw Exception( "mbDevice:Read", errstr.str(), 52);
276 std::stringstream errstr;
277 errstr << "image size must not exceed 2000 bits" << rTr. FileLine();
278 throw Exception( "mbDevice:Read", errstr.str(), 52);
303 mSlaveSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
305 std::stringstream errstr;
306 errstr << "Modbus fatal network error (cannot open server socket)";
307 throw Exception( "mbDevice::Start", errstr.str(), 553);
310 faudes_setsockopt( mSlaveSocket,SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
312 struct sockaddr_in slaveaddress;
313 memset(&slaveaddress, 0, sizeof(slaveaddress));
314 slaveaddress.sin_family = AF_INET;
315 slaveaddress.sin_addr.s_addr = htonl(INADDR_ANY);
318 if(bind( mSlaveSocket, ( struct sockaddr *) &slaveaddress, sizeof(slaveaddress)) <0) {
319 std::stringstream errstr;
320 errstr << "Modbus fatal network error (cannot bind socket)";
321 throw Exception( "nDevice::Start", errstr.str(), 553);
325 std::stringstream errstr;
326 errstr << "Simplenet fatal network error (cannot listen from socket)";
327 throw Exception( "mbDevice::Start", errstr.str(), 553);
353 FD_DH( "mbDevice::Stop(): closing slave socket");
358 FD_DH( "mbDevice::Stop(): done");
364 #define MB_SETINT(p,v) { mMessage[p] = ((v)>>8); mMessage[p+1] = ((v) & 0xff); }
365 #define MB_GETINT(p) ( ( mMessage[p] << 8) + ((int) mMessage[p+1]) )
366 #define MB_SETBYTE(p,v) { mMessage[p] = (v);}
367 #define MB_GETBYTE(p) ( mMessage[p] )
381 int avail= select( mSlaveSocket+1, &mysocks, NULL, NULL, &tv);
384 FD_DH( "mbDevice::MbFlushBuffers(): flush recv buffer");
388 FD_DH( "mbDevice::MbFlushBuffers(): flush recv buffer: fatal error?");
391 FD_DHV( "mbDevice::MbFlushBuffers(): ok");
431 int avail=select(mysocks_max+1, &mysocks, NULL, NULL, &tv);
434 if(avail<=0) return -1;
440 FD_DH( "mbDevice::MbReceiveResponse(): invalid MBAB header (size mismatch)");
455 FD_DH( "mbDevice::MbReceiveRequest(): invalid MBAB header (size mismatch)");
471 int rc=send(mastersock, mMessage+from, left, 0);
489 if(ctimer< 1000000) return;
494 int slavesock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
496 FD_DH( "mbDevice::DoLoopCallBack(): connection to slave failed: internal err A0");
500 unsigned long int slaveinaddr = INADDR_NONE;
501 if(slaveinaddr==INADDR_NONE) {
502 FD_DHV( "mbDevice::DoLoopCallBack(): using provided address literaly");
505 if(slaveinaddr==INADDR_NONE) {
506 struct hostent *host;
509 FD_DHV( "mbDevice::DoLooCallBack(): retrieve alternative address by name-lookup");
510 slaveinaddr = *( unsigned long int*) host->h_addr;
513 if(slaveinaddr==INADDR_NONE) {
514 FD_DH( "mbDevice::DoLooCallBack():: connection to slave failed: invalid address " << mSlaveAddress. Ip());
515 faudes_closesocket(slavesock);
519 struct sockaddr_in slaveaddress;
520 memset(&slaveaddress, 0, sizeof(slaveaddress));
521 slaveaddress.sin_family = AF_INET;
522 slaveaddress.sin_addr.s_addr=slaveinaddr;
527 FD_DH( "mbDevice::DoLoopCallBack():: connection to slave failed: internal error A1");
528 faudes_closesocket(slavesock);
532 int rcc= connect(slavesock, ( struct sockaddr*) &slaveaddress, sizeof(slaveaddress));
536 if(errno!=EINPROGRESS) {
537 FD_DH( "mbDevice::DoLoopCallBack(): connection to slave failed: connect() errno " << errno);
539 FD_DH( "mbDevice::DoLoopCallBack(): connection to slave: wait for host to accept");
546 FD_SET(slavesock, &mysocks);
547 rcc= select(slavesock+1, NULL, &mysocks, NULL, &tv);
549 if(rcc<0) FD_DH( "mbDevice::DoLoopCallBack(): connection to slave failed: timeout");
553 #ifdef FAUDES_WINDOWS
555 int lerr = WSAGetLastError();
556 if(lerr!=WSAEWOULDBLOCK) {
557 FD_DH( "mbDevice::DoLoopCallBack(): connection to slave failed: connect() errno " << lerr);
559 FD_DH( "mbDevice::DoLoopCallBack(): wait for host to accept");
566 FD_SET(slavesock, &mysocks);
567 rcc= select(slavesock+1, NULL, &mysocks, NULL, &tv);
569 if(rcc<0) FD_DH( "mbDevice::DoLoopCallBack(): connection to slave failed: timeout");
575 FD_DH( "mbDevice::DoLoopCallBack():: connection to slave failed: host unreachable");
576 faudes_closesocket(slavesock);
581 FD_DH( "mbDevice::DoLoopCallBack():: connection to slave failed: internal error A2");
582 faudes_closesocket(slavesock);
588 FD_DH( "mbDevice::DoLoopCallBack():: connection to slave failed: internal error A3");
589 faudes_closesocket(slavesock);
593 FD_DH( "mbDevice::DoLoopCallBack(): connected to remote slave, using socket #" << slavesock);
609 int avail = select( mSlaveSocket+1, &mysocks, NULL, NULL, &tv);
614 FD_DH( "mbDevice::DoLoopCallBack(): accepting remote master to connect");
615 struct sockaddr_in masteraddr;
616 socklen_t masteraddr_len = sizeof(masteraddr);
617 int mastersock=accept( mSlaveSocket, ( struct sockaddr *) &masteraddr, &masteraddr_len );
619 FD_DH( "mbDevice::DoLoopCallback(): failed to accept incomming connection");
631 FD_DHV( "mbDevice::DoLooCallBack(): update image from remote slave");
642 FD_DHV( "mbDevice::DoLoopCallBack(): sending request");
644 FD_DHV( "mbDevice::DoLoopCallBack(): read response");
649 FD_DHV( "mbDevice::DoLoopCallBack(): input image received");
658 addr++; count--; shft = shft <<1;
659 if(shft==0x100) { shft=0x01; data= MB_GETBYTE(++src);};
662 FD_DH( "mbDevice::DoLoopCallBack(): received error response on read inputs");
673 int bcount= (ior. mCount-1)/8 +1;
681 if( mpImage[addr]) data |= shft;
682 addr++; count--; shft = shft <<1;
683 if(shft==0x100) { shft=0x01; MB_SETBYTE(dst,data); data=0x00; dst++;}
688 FD_DHV( "mbDevice::DoLoopCallBack(): sending request");
692 FD_DH( "mbDevice::DoLoopCallBack(): received error response on write coils");
708 if(mastersock<0) continue;
709 FD_SET(mastersock, &mysocks);
710 if(mysocks_max< mastersock) mysocks_max=mastersock;
717 int avail=select(mysocks_max+1, &mysocks, NULL, NULL, &tv);
723 if(mastersock<0) continue;
724 if(!FD_ISSET(mastersock, &mysocks)) continue;
725 FD_DHV( "mbDevice::DoLoopCallback(): received message on sock " << mastersock);
727 FD_DH( "mbDevice::DoLoopCallback(): receive error on sock " << mastersock);
728 faudes_closesocket(mastersock);
737 if((fnct==0x01) || (fnct==0x02)) {
738 FD_DHV( "mbDevice::DoLoopCallback(): coil-read or input read request");
741 int bcount= ((count-1)/8+1);
742 FD_DHV( "mbDevice::DoLoopCallback(): address range: @" << addr << " #" << count);
746 if(count>2000) errcode=0x02;
754 if( mpImage[addr]) data |= shft;
755 addr++; count--; shft = shft <<1;
756 if(shft==0x100) { shft=0x01; MB_SETBYTE(dst,data); dst++; data=0x00;}
765 if((fnct==0x03) || (fnct==0x04)) {
766 FD_DHV( "mbDevice::DoLoopCallback(): register or holding register read request");
769 FD_DHV( "mbDevice::DoLoopCallback(): address range: @" << addr << " #" << count);
782 for(;count>0; count--) {
785 for(;src< mImageSize && shft!=0x100; src++, shft = shft << 1)
786 if( mpImage[src]) lbyte |= shft;
789 for(;src< mImageSize && shft!=0x100; src++, shft = shft << 1)
790 if( mpImage[src]) hbyte |= shft;
798 FD_DHV( "mbDevice::DoLoopCallback(): write single coil request");
801 FD_DHV( "mbDevice::DoLoopCallback(): write single coil request: " << addr << " to " << val);
813 FD_DHV( "mbDevice::DoLoopCallback(): write holding register request");
816 FD_DHV( "mbDevice::DoLoopCallback(): set @" << addr << " to " << val);
825 int hbyte= (val >> 8);
826 int lbyte= (val & 0xff);
828 for(shft=0x01; shft!=0x100; shft = shft << 1, dst++)
829 mpImage[dst] = (( lbyte & shft) != 0);
830 for(shft=0x01; shft!=0x100; shft = shft << 1, dst++)
831 mpImage[dst] = (( hbyte & shft) != 0);
838 FD_DHV( "mbDevice::DoLoopCallback(): write multiple coils request");
842 FD_DHV( "mbDevice::DoLoopCallback(): address range: @" << addr << " #" << count << "(" << bcount << ")");
846 if( (bcount < ((count-1)/8+1)) || ( mMessageLen < 6+bcount) ) errcode=0x03;
854 if(shft==0x100) { shft=0x01; data= MB_GETBYTE(src);src++;};
856 addr++; count--; shft = shft <<1;
864 FD_DHV( "mbDevice::DoLoopCallback(): write multiple holding registers request");
868 FD_DHV( "mbDevice::DoLoopCallback(): address range: @" << addr << " #" << count << "(" << bcount << ")");
873 if( bcount != 2* count)
880 for(;count>0;count--) {
884 for(shft=0x01; shft!=0x100; shft = shft << 1, dst++)
885 mpImage[dst] = (( lbyte & shft) != 0);
886 for(shft=0x01; shft!=0x100; shft = shft << 1, dst++)
887 mpImage[dst] = (( hbyte & shft) != 0);
900 FD_DH( "mbDevice::DoLoopCallback(): sending error reply, code " << errcode);
956 #endif // end modbus support
libFAUDES 2.28a
--- 2016.09.13
--- c++ api documentaion by doxygen
|