/* DESC: This script can be used to access to the digital I/Os via Modbus TCP * Copyright (C) 2015 NetModule AG, Switzerland * * Commands: * Read Coil Status (FC01) * Read Input Status (FC02) * Read Input Register (FC04) * Force Single Coil (FC05) * Write Multiple Coils (FC15) * * Mapping: * Coil status(digital I/O): 1=out1, 2=out2 * Input satus(digital In): 1=in1, 2=in2 * Input register : 1=temperature 2=mobile 1 rsrp * */ TCP_PORT = 1502; // sdk port must be higher than 1024 SLAVEID = 7; int set_io(int adr, int dat) { ret = 0; switch (adr) { //switch on address case 0: if (dat == 0) nb_dio_set("out1", 0); else nb_dio_set("out1", 1); break; case 1: if (dat == 0) nb_dio_set("out2", 0); else nb_dio_set("out2", 1); break; default: ret = -1; break; } return ret; } if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { printf("Unable to open socket\n"); exit(1); } if (bind(fd, TCP_PORT, "") < 0) { printf("Unable to bind port %d\n", TCP_PORT); exit(2); } if (listen(fd, 1) < 0) { printf("Unable to listen\n"); exit(3); } cfd = -1; for(;;) { if (cfd == -1) { if ((cfd = accept(fd)) < 0) { printf("accept failed\n"); continue; } if (nb_modbus_register(cfd, MODBUS_TYPE_TCP) < 0) { printf("Unable to register client (%s)\n", nb_modbus_last_error()); close(cfd); cfd = -1; continue; } } if ((r = nb_modbus_receive(cfd)) == NULL) { printf("Unable to receive request (%s)\n", nb_modbus_last_error()); nb_modbus_unregister(cfd); close(cfd); cfd = -1; continue; } if (r[6] != SLAVEID) continue; // not for us cmd = r[7]; // command switch (cmd) { // write commands case 5: // write to a single coil addr = r[8]<<8 + r[9]; data = r[10]<<8 + r[11]; if (set_io(addr, data) == -1) continue; // error break; case 15: // write to multiple coils addr = r[8]<<8 + r[9]; cnt = r[10]<<8 + r[11]; for (i = 0; i < cnt; i ++) if (set_io(addr+i, (int) (r[13+i/8] & 1<<(i%256))) == -1) continue; // error break; } switch (cmd) { // reply for all commands case 1: // read coil status case 2: // read input status case 5: // write to a single coil case 4: // read input register case 15: // write to multiple coils syst = nb_status("system"); wwan = nb_status("wwan"); resp = mkstruct( "bits", mkarray(nb_dio_get("out1"), nb_dio_get("out2")), "ibits", mkarray(nb_dio_get("in1"), nb_dio_get("in2")), "regs", mkarray(0,0), "iregs", mkarray((int)syst.TEMPERATURE, (int)wwan.MOBILE1_RSRP) ); if (nb_modbus_reply(cfd, r, resp) < 0) { printf("Unable to reply%s)\n", nb_modbus_last_error()); nb_modbus_unregister(cfd); close(cfd); cfd = -1; continue; } break; } } /* not reached */