int emc_bind(int plug, const char * ip, const ushort port){ struct easymc_plug * pg = (struct easymc_plug *)global_get_plug(plug); if(!pg){ errno = ENOPLUG; return -1; } if(pg->ipc_ || pg->tcp_){ errno = EREBIND; return -1; } if(!get_device_tcp_mgr(pg->device)){ set_device_tcp_mgr(pg->device, create_tcp_mgr(pg->device, get_device_thread(pg->device))); } if(!get_device_tcp_mgr(pg->device)){ return -1; } pg->tcp_ = add_tcp(ip?inet_addr(ip):0, port, EMC_NONE, EMC_LOCAL, plug, get_device_tcp_mgr(pg->device)); if(!pg->tcp_){ return -1; } pg->ipc_ = create_ipc(ip?inet_addr(ip):0, port, pg->device, plug, EMC_NONE, EMC_LOCAL); if(!pg->ipc_){ return -1; } return 0; }
int emc_connect(int plug, ushort mode, const char * ip, const ushort port){ struct easymc_plug * pg = (struct easymc_plug *)global_get_plug(plug); if(!pg){ errno = ENOPLUG; return -1; } if(pg->ipc_ || pg->tcp_){ errno = EREBIND; return -1; } if(EMC_PUB == mode)mode = EMC_SUB; if(EMC_REP == mode)mode = EMC_REQ; pg->mode = mode; if(!get_device_tcp_mgr(pg->device)){ set_device_tcp_mgr(pg->device, create_tcp_mgr(pg->device, get_device_thread(pg->device))); } if(!get_device_tcp_mgr(pg->device)){ return -1; } if(!ip || check_local_machine(inet_addr(ip))){ pg->ipc_ = create_ipc(inet_addr(ip), port, pg->device, plug, mode, EMC_REMOTE); if(!pg->ipc_){ return -1; } }else{ pg->tcp_ = add_tcp(inet_addr(ip), port, mode, EMC_REMOTE, plug, get_device_tcp_mgr(pg->device)); if(!pg->tcp_){ delete_tcp(pg->tcp_); pg->tcp_ = NULL; return -1; } } return 0; }
int main( int argc, char *argv[] ) { int c; int option_index = 0; int received; int mq_id; struct sIPCMsg mymsg; char *ttydev = DEFAULT_TTY; char *parity_s = DEFAULT_PAR; int parity; int baud = DEFAULT_BAUD; USHORT result[255] = {0,}; int result_int = 0; USHORT usLen; eMBErrorCode err = MB_ENOERR; int reg_start = DEFAULT_REGISTER_START; int address = DEFAULT_ADDRESS; int regt = -1; int reg_action = -1; int reg_action_param = -1; int no_reg = -1; int run_forground = 0; int errorcount = 0; struct pidfile *pidfile = NULL; UCHAR *pucFrame; eMBException eException; UCHAR ucFuncType; /* Parse cmd-line options */ while ( (c = getopt_long (argc, argv, "hVd:s:p:r:t:c:a:f", long_options, &option_index)) != EOF ) { switch (c) { case 'h': fprintf(stderr, "%s", helptext); exit(EXIT_SUCCESS); case 'V': exit(EXIT_SUCCESS); case 'd': ttydev = strndup(optarg, MAXLEN); break; case 's': baud = atoi(optarg); break; case 'p': parity_s = strndup(optarg, MAXLEN); break; case 'f': // run in forground run_forground = 1; break; case '?': /* getopt_long already printed an error message. */ default: fprintf(stderr, "%s", helptext); exit(EXIT_SUCCESS); } } if(!run_forground){ fprintf(stderr, "Deamonizing...\n"); daemon(0, 0); } /* Setup signalhandler so that we shut down nicely on CTRL+C */ signal(SIGINT, int_handler); pidfile = pidfile_create(DEFAULT_PIDFILE, PMODE_RETURN, 0); mq_id = create_ipc(); /* Allocate space for an ADU frame */ pucFrame = eMBAllocateFrame(&usLen); while(outer_loop) { if(running == 1) printf("Restarting modbus layer\n"); else { printf("\n\n\n\n Restarting modbus layer\n\n\n\n"); running = 1; errorcount = 0; } /* Parse user inputs... */ if(strcmp(parity_s, "even") == 0) parity = MB_PAR_EVEN; else if(strcmp(parity_s, "odd") == 0) parity = MB_PAR_ODD; else parity = MB_PAR_NONE; PRINT_DBG(1, "init modbus at tty: %s parity %d baud %d", ttydev, parity, baud); /* mode, port, baud, parity */ eMBMasterInit(MB_RTU, ttydev, baud, parity); while(running) { /* Check message queue */ if((received = msgrcv(mq_id, &mymsg, sizeof(mymsg.text), 1, IPC_NOWAIT)) > 0) { /* Address */ address = parse_address(mymsg.text); /* Starting register */ reg_start = parse_reg_start(mymsg.text); /* Register type */ regt = parse_reg_type(mymsg.text); /* Register action */ reg_action_param = 0; reg_action = parse_reg_action(mymsg.text, ®_action_param); /* Optional: number of registers */ no_reg = parse_no_reg(mymsg.text); #ifdef DBG if(dbglev>=1){ printf("Got: %s\n", mymsg.text); printf("Parsing command:\n"); printf("Address: 0x%02x\n", address); printf("Register: %d\n", reg_start); printf("Register type: %d\n", regt); printf("Register action: %d Arg: %d\n", reg_action, reg_action_param); printf("Register count: %d\n", no_reg); } #endif switch(regt) { case MB_TYPE_COILS: switch(reg_action) { case ACTION_READ: err = build_eMBMasterReadCoils (pucFrame, reg_start, reg_action_param, &usLen); break; case ACTION_WRITE: err = build_eMBMasterWriteCoils (pucFrame, reg_start, reg_action_param ? 0xff : 0x0, &usLen); break; case ACTION_WRITEMULTIPLE: err = build_eMBMasterWriteMultipleCoils (pucFrame, reg_start, no_reg, reg_action_param ? 0xff : 0x0, &usLen); break; } break; case MB_TYPE_INPUT: err = build_eMBMasterReadInput (pucFrame, reg_start, reg_action_param, &usLen); break; case MB_TYPE_HOLDING: switch(reg_action) { case ACTION_READ: err = build_eMBMasterReadHolding (pucFrame, reg_start, reg_action_param, &usLen); break; case ACTION_WRITE: err = build_eMBMasterWriteSingleHolding (pucFrame, reg_start, reg_action_param, &usLen); break; } break; } #ifdef DBG if(dbglev){ int n; printf("Dumping built frame:\n"); for(n=0; n<10; n++) printf("%02x ",pucFrame[n]); printf("\n"); } #endif /* ? */ eMBEnable(); memset(result, 0, sizeof(result)); if(err == MB_EX_NONE) { /* Set the address of the device in question */ eMBSetSlaveAddress(address); /* Send the frame */ if( (err = eMBSendFrame(pucFrame, usLen)) == MB_ENOERR) { printf(" ---- done processing frame ----\n"); eException = MB_EX_ILLEGAL_FUNCTION; ucFuncType = pucFrame[MB_PDU_FUNC_OFF]; #ifdef DBG if(dbglev){ printf("%s():%d - after send...\n", __FUNCTION__, __LINE__); { int n; printf("Dumping received frame:\n"); for(n=0; n<10; n++) printf("%02x ",pucFrame[n]); printf("\n"); } } #endif if(ucFuncType & 0x80) { UCHAR ucExceptType = pucFrame[MB_PDU_FUNC_OFF+1]; /* We encountered some sort of error */ switch(ucExceptType) { case MB_EX_ILLEGAL_FUNCTION: fprintf(stderr, "Error! Illegal function!\n"); break; case MB_EX_ILLEGAL_DATA_ADDRESS: fprintf(stderr, "Error! Illegal data address!\n"); break; case MB_EX_ILLEGAL_DATA_VALUE: fprintf(stderr, "Error! Illegal data value!\n"); break; case MB_EX_SLAVE_DEVICE_FAILURE: fprintf(stderr, "Error! Slave device failure!\n"); break; default: fprintf(stderr, "Unknown error (%d)!\n", eException); break; } } else { switch(ucFuncType) { case MB_FUNC_READ_COILS: eException = parse_eMBMasterReadCoils(pucFrame, &usLen, (void *)result); #ifdef DBG if(dbglev) printf("Reply: %04x\n", result[0]); #endif break; case MB_FUNC_WRITE_SINGLE_COIL: eException = parse_eMBMasterWriteCoils(pucFrame, &usLen, (void *)result); #ifdef DBG if(dbglev) printf("Reply: %04x\n", result[0]); #endif break; case MB_FUNC_READ_INPUT_REGISTER: eException = parse_eMBMasterReadInput(pucFrame, &usLen, (void *)result); #ifdef DBG if(dbglev) printf("Reply (%d): %04x\n", eException, result[0]); #endif break; case MB_FUNC_READ_HOLDING_REGISTER: eException = parse_eMBMasterReadHolding(pucFrame, &usLen, (void *)result); #ifdef DBG printf("Reply: %04x %04x %d %d\n", result[0],result[1], result_int, reg_action_param); #endif break; case MB_FUNC_WRITE_REGISTER: eException = parse_eMBMasterWriteSingleHolding(pucFrame, &usLen, (void *)result); #ifdef DBG printf("Reply: %04x\n", result[0]); #endif break; case MB_FUNC_WRITE_MULTIPLE_COILS: usLen = 5; eException = parse_eMBMasterWriteMultipleCoils(pucFrame, &usLen, (void *)result); if(eException == MB_EX_NONE) printf("Write multiple coils SUCCESS!\n"); else printf("Write multiple coils FAIL!\n"); break; default: printf("Unknown function type : %x\n", ucFuncType); printf("%d : %s()\n", __LINE__, __FUNCTION__); { int n; for(n=0; n<10; n++) printf("%02x ",pucFrame[n]); printf("\n"); } break; } switch(ucFuncType) { case MB_FUNC_READ_HOLDING_REGISTER: case MB_FUNC_READ_INPUT_REGISTER: if(reg_action_param == 2){ printf("!!!!\n"); result_int = (result[0]<<16) | result[1]; }else { result_int = result[0]; } break; default: result_int = result[0]; break; } if(eException == MB_EX_NONE) { snprintf(mymsg.text, sizeof(mymsg.text), "%ld:REG:%d:RESULT:%d", time(NULL), reg_start, result_int); } else { snprintf(mymsg.text, sizeof(mymsg.text), "ERROR:Parsing frame"); } #ifdef DBG printf("%s():%d - reply: %s\n", __FUNCTION__, __LINE__, mymsg.text); #endif goto out; } } else { printf("Error sending frame. (%d)\n", err); snprintf(mymsg.text, sizeof(mymsg.text), "ERROR:Sending frame"); if(errorcount > 10) running = 0; else errorcount++; } } else { printf("Error in frame arguments.\n"); snprintf(mymsg.text, sizeof(mymsg.text), "ERROR:Wrong argument"); } out: /* Set the reply */ mymsg.type = 2; #ifdef DBG printf("%s():%d - reply: %s\n", __FUNCTION__, __LINE__, mymsg.text); #endif msgsnd(mq_id, &mymsg, sizeof(mymsg.text), IPC_NOWAIT); eMBDisable(); } else { //printf("No messages. Sleeping (%d - %s)\n", received, received < 0 ? strerror(errno) : ""); } usleep(1000); } // free(pucFrame); eMBClose(); } destroy_ipc(PROJ_ID); pidfile_delete(pidfile); return 0; }
int main( int argc, char *argv[] ) { // err = 1; str_err = "!!"; time_wait = 2; max_point = 0; buf_len = 0; cur_device = 0; // -- if( argc < 1 ) exit( 0 );// простотакчтобнекричал! char *d_name = ( strrchr( argv[0], '/' ) + 1 ); // openlog(d_name,LOG_PID|LOG_CONS|LOG_NDELAY|LOG_NOWAIT,LOG_LOCAL0); // -- //printf( "Получаем конфигурацию сервера по имени: %s\n", d_name ); // -- if( !create_ipc( d_name )){ #ifdef DEBUG printf( "Error: open_ipc(%s)\n", d_name ); #endif // syslog(LOG_LOCAL0|LOG_INFO, "Error: open_ipc(%s)", d_name); exit( 0 ); } // --------------- /* Инициализация основных объектов данными из конфиг-файла */ #include "0_inc_dev.h" // create_transport( "10.0.10.47", 4001, 500 ) // Устройства в цикле из БД: // dev[].x = x; err = 0; // --------------- int ij = 0; for(; ij < max_device; ij++ ){ #ifdef DEBUG printf( "Device[%d] = %d, %d, %s, %d\n", ij, dev[ij].id, dev[ij].adr, dev[ij].name, dev[ij].reg ); #endif max_point += dev[ij].reg; } #ifdef DEBUG printf( "max_point = %d\n", max_point ); #endif // --------------- /* Настройка системных сигналов */ signal( SIGSEGV, sign_segv ); // !!! signal( SIGPIPE, SIG_IGN ); // -- signal( SIGINT, sign_exit ); signal( SIGUSR1, sign_exit ); signal( SIGQUIT, sign_exit ); signal( SIGTERM, sign_exit ); // --------------- // Run // syslog(LOG_LOCAL0|LOG_INFO, "Run."); while( 1 ){ str_err = "start while"; int i; char fifo_msg[MSGSIZE]; // -- #ifdef MSG_JSON int i_msg = sprintf((char*)fifo_msg, "#%d={", max_point); for( i = 0; i < max_device; i++ ){ if(refresh(&dev[i]) > 0 ){ int j, k; for( j = 0; j < dev[i].reg; j++ ){ int id = dev[i].id * 1000 + j + 1; int da = dev[i].get_data( j, buffer, buf_len ); k = sprintf((char*)fifo_msg + i_msg, "\"%d\":[\"%d\"],", id, da); i_msg += k; } }// refresh usleep(50); }// for max_device str_err = "write_ipc"; sprintf(( char* )fifo_msg + i_msg -1, "}#%d\n", i_msg ); if( write_ipc( fifo_msg, strlen( fifo_msg )) < 1) break;; #else int i_msg = sprintf((char*)fifo_msg, "#%s:%d\n", d_name, max_point); for( i = 0; i < max_device; i++ ){ if(refresh(&dev[i]) > 0 ){ int j, k; for( j = 0; j < dev[i].reg; j++ ){ int id = dev[i].id * 1000 + j + 1; int da = dev[i].get_data( j, buffer, buf_len ); k = sprintf((char*)fifo_msg + i_msg, "%d:%d\n", id, da); i_msg += k; } // k = sprintf((char*)fifo_msg + i_msg, "\n"); // ??? // i_msg += k; // ??? } else {//if refresh or dev[].err i_msg = sprintf((char*)fifo_msg, "#%s:%d\n", d_name, dev[i].err ); }// end if( refresh ) usleep(50); }// for max_device // -- str_err = "write_ipc"; sprintf(( char* )fifo_msg + i_msg, "%d#\n", i_msg ); if( write_ipc( fifo_msg, strlen( fifo_msg )) < 1) break;; #endif // -- //fprintf( stderr, "*" ); sleep(time_wait); }// while // ------------------------------------------------------------------------- fprintf( stderr,"\nBREAK: Error(%s).\n", str_err ); delete_transport(); delete_ipc(); // syslog( LOG_NOTICE, "BREAK: Error(%s)", str_err); // closelog(); exit( EXIT_FAILURE ); }// End main ----------------------------------------------------------------