static pmbs_tcp_req_body_rd _ezmbs_tcp_create_read (int _trans, int _addr, int _count, int _func) { pmbs_tcp_req_body_rd frame = (pmbs_tcp_req_body_rd) ezmbs_malloc (sizeof (*frame)); if (! frame) ez_panic ("malloc a mbstcp_read_single frame error."); frame -> _hdr._trans = (uint16_t) (_trans & 0x0000ffff); frame -> _hdr._len = 0x0600; // Big endian frame -> _hdr._proto = 0x00; frame -> _hdr._devid = 0; frame -> _func = (funccode_t) _func; frame -> _start_addr = tobigend16 (_addr); frame -> _reg_count = tobigend16 (_count); return frame; }
/* Initialize channel * @1 address to bind. * @2 port to bind (for tcp and udp). * Return : If successful, a new channel will * be created and returned its ptr. Otherwise * return NULL. */ pez_channel ez_init_channel (char* _addr, const unsigned short _port) { pez_channel channel; #ifdef __MSC_VER if (! initilized) { // WINDOWS socket 2 initialize // TODO initialized = 1; } #endif // __MSC_VER channel = (pez_channel) calloc (sizeof (ez_channel), 1); if (! channel) return NULL; channel -> _next = NULL; channel -> _remote.sin_family = AF_INET; channel -> _remote.sin_port = tobigend16 (_port); channel -> _remote.sin_addr.s_addr = ez_stringaddr_to_int (_addr); return channel; }
static bytes _func_15_16 ( FUNC_CODE func_code, int trans, int devid, int start, int reg_cnt, uint16_t* vals, int* frm_len) { int frame_len = sizeof (mbs_tcp_req_10_head) + (reg_cnt << 1); pmbs_tcp_req_10_head frame = (pmbs_tcp_req_10_head) malloc (*frm_len = frame_len); frame -> _comm._trans = (uint16_t) (trans & 0x0000ffff); frame -> _comm._len = 0x0600; // Big endian frame -> _comm._proto = 0x00; frame -> _comm._devid = (uint16_t) (devid & 0xff); frame -> _comm._func = func_code; frame -> _comm._body._start_addr = tobigend16 (start); frame -> _comm._body._reg_count = tobigend16 (reg_cnt); // reg_cnt * 2 frame -> _bytes = reg_cnt << 1; if (memcpy (&frame -> _first_val, vals, frame -> _bytes)) return (bytes) frame; else { *frm_len = 0; free (frame); return (bytes) (frame = NULL); } }
/* * Create modbus request frame to * Write multiple coils. * * @1 transfer flags. * @2 start coils. * @3 the number of coils. * @4 the value list, each coils has 1 bytes. 0x01 if ON, otherwise * 0x00 for OFF. We treat non-zero byte as ON and zero as OFF. * return : request frame */ pmbs_tcp_req_body_wr_m ezmbs_tcp_create_write_multi_coils (int _trans, int _start, int _count, uint8_t* _vals) { int byte_len = 0, tmp = 0, word = 0, mod = _count & 0x0F; uint16_t* dataptr = NULL; pmbs_tcp_req_body_wr_m frame = NULL; // tmp = _count / 8; word = (_count / 16) + (!! mod); byte_len = word << 1; // ! tmp ? 2 : tmp + (!! mod); frame = (pmbs_tcp_req_body_wr_m) ezmbs_malloc (sizeof (mbs_tcp_req_body_wr_m) + byte_len); if (!frame) { ez_panic ("Error."); return NULL; } frame -> _hdr._trans = _trans; frame -> _hdr._proto = 0; frame -> _hdr._len = tobigend16 (7 + byte_len); frame -> _hdr._devid = 0; frame -> _func = mbs_func_write_cols; frame -> _start_addr = tobigend16 (_start); frame -> _count = tobigend16 (_count); frame -> _byte_len = (uint8_t) _count; dataptr = (uint16_t*) (&frame -> _value); // tmp = 0; // as dataptr offset. do { int ptr = 0, i = tmp << 4, ptr_len; ptr_len = word - tmp == 1 ? mod : 16; for (; ptr < ptr_len; ++ ptr) dataptr [tmp] |= (!! _vals [i + ptr]) << ptr; dataptr [tmp] = tobigend16 (dataptr [tmp]); } while (word > ++ tmp); return frame; }
/* * Create modbus request frame to * write multiple registers. * * @1 transfer flags. * @2 start register * @3 the number of register. * @4 the value list, each register has 2 bytes. * return : request frame */ extern pmbs_tcp_req_body_wr_m ezmbs_tcp_create_write_multi_regs (int _trans, int _start, int _count, uint16_t* _vals) { int byte_len = _count << 1, i = 0; uint16_t* dataptr = NULL; pmbs_tcp_req_body_wr_m frame = (pmbs_tcp_req_body_wr_m) ezmbs_malloc (sizeof (mbs_tcp_req_body_wr_m) + byte_len); if (!frame) { ez_panic ("Error."); return NULL; } frame -> _hdr._trans = _trans; frame -> _hdr._proto = 0; frame -> _hdr._len = tobigend16 (7 + byte_len); // BE frame -> _hdr._devid = 0; frame -> _func = mbs_func_write_holdings; frame -> _start_addr = tobigend16 (_start); // BE frame -> _count = tobigend16 (_count); // BE frame -> _byte_len = byte_len; dataptr = (uint16_t*) (&frame -> _value); for (; i < _count; ++ i) dataptr [i] = tobigend16 (_vals [i]); // BE return frame; }
int main (int argc, char* argv []) { int sockfd, sendbuff_len; int sent_len = 0; struct sockaddr_in srv_addr; sockfd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sockfd == -1) { println ("Error in creating socket." "Will now shutdown..."); return -1; } else printf ("Created socket %d.\n", sockfd); srv_addr.sin_family = AF_INET; srv_addr.sin_port = tobigend16 (SERVER_PORT); srv_addr.sin_addr.s_addr = inet_addr (SERVER_IP); // already convert into network order. if (connect (sockfd, (struct sockaddr*) &srv_addr, sizeof (srv_addr))) { println ("Error in connecting server," "will now shutdown..."); return -1; } sendbuff_len = strlen (sendbuff); while (1) { sent_len = send (sockfd, sendbuff, sendbuff_len, 0); if (sent_len == -1) { printf ("Send error! errno = %d\n", errno); } else { printf ("%d ", sent_len); // nothing to do ... // printf ("Sent %d length bytes.\n", sent_len); } } return 0; }
/* * Create modbus request frame to * write single coil. * * @1 transfer flags. * @2 start register * @3 value to write into. * return : request frame */ pmbs_tcp_req_body_wr_s ezmbs_tcp_create_write_single_coil (int _trans, int _start, int _val) { // it's important to convert into big-endian. return _ezmbs_tcp_create_write_single (_trans, _start, tobigend16 (_val), mbs_func_write_col); }