예제
본 장에서는 SRLGW의 각 역할에 대한 예제에 대해 설명한다.
1. NOREPLY 서비스 호출
Tmax의 서비스나 클라이언트에서 SRLGW로 tpacall로 서비스를 요청하고 결과에 관계없이 처리하는 예제이다.
프로그램 구성은 다음과 같다.
| 구분 | 파일명 |
|---|---|
환경 파일 |
tmax.m, serial.cfg |
리모트 노드 |
remote.c |
1.1. 환경 파일
<tmax.m>
*DOMAIN
res SHMKEY = 88000,
MINCLH = 1,
MAXCLH = 1,
TPORTNO = 8888
*NODE
node1 TMAXDIR = "/home/tmax",
APPDIR = "/home/tmax/appbin"
*SVRGROUP
svg1 NODENAME = node1
*SERVER
serialgw SVGNAME = svg1, MIN = 1, MAX = 1, CPC = 10,
SVRTYPE = CUSTOM_GATEWAY,
CLOPT = "-- -F /home/tmax/config/serial.cfg -w 5050"
svr SVGNAME = svg1, MIN = 1, MAX = 1,
*SERVICE
COM1 SVRNAME = serialgw
TOUPPER SVRNAME = svr
<serial.cfg >
####################################################### # gwno baudrate stopbit Parity Byte Port Tmaxsvc # 0 9600 1 ODD 8 COM1 SVC ####################################################### # line start with "#" is comment line # gwno must start at 0 and be increased by 1 # stopbit: 1, 1.5, 2 # parity : NONE, ODD, EVEN # byte: 5, 6, 7, 8 # port: serial port name # svc: tmax service name ####################################################### 0 9600 1 NONE 8 COM1 COM1
1.2. 리모트 노드
<toupper.c>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <usrinc/atmi.h>
main(int argc, char *argv[])
{
char *sndbuf, *rcvbuf;
long rcvlen;
if (argc != 2) {
printf("Usage: toupper string\n");
exit(1);
}
if (tpstart((TPSTART_T *)NULL) == -1){
printf("Tpstart failed\n");
exit(1);
}
if ((sndbuf = (char *)tpalloc("STRING", NULL, 0)) == NULL) {
printf("Sendbuf alloc failed !\n");
tpend();
exit(1);
}
if ((rcvbuf = (char *)tpalloc("STRING", NULL, 0)) == NULL) {
printf("Recvbuf alloc failed !\n");
tpfree((char *)sndbuf);
tpend();
exit(1);
}
strcpy(sndbuf, argv[1]);
if(tpcall("TOUPPER", sndbuf, 0, &rcvbuf, &rcvlen, 0)==-1){
printf("Can't send request to service TOUPPER\n");
tpfree((char *)sndbuf);
tpfree((char *)rcvbuf);
tpend();
exit(1);
}
printf("Sendbuf data: %s\n", sndbuf);
printf("Recvbuf data: %s\n", rcvbuf);
tpfree((char *)sndbuf);
tpfree((char *)rcvbuf);
tpend();
}
<svr.c>
#include <stdio.h>
#include <usrinc/atmi.h>
TOUPPER(TPSVCINFO *msg)
{
char *sndbuf;
long sndlen;
if ((sndbuf = (char *)tpalloc("STRING", NULL, 0)) == NULL) {
printf("sendbuf alloc failed !\n");
tpreturn(TPFAIL, -1, NULL, 0, 0);
}
strcpy(sndbuf, msg->data);
sndlen = msg->len;
if(tpacall("COM1", sndbuf, sndlen, TPNOREPLY)==-1){
printf("Can't send request to service TCPSVC1\n");
tpfree((char *)sndbuf);
tpreturn(TPFAIL, -1, NULL, 0, 0 );
}
tpfree((char *)sndbuf);
tpreturn(TPSUCCESS,0,(char *)msg->data, msg->len,0);
}
<remote.c>
#include <stdio.h>
#include <winsock2.h>
#include <usrinc/commhead.h>
#define COM_PORT "COM1:9600:8:NONE:1"
int main(int argc, char *argv[])
{
int n, msgtype;
long ilen, olen;
char buffer[1024];
char svcname[24];
/* Gateway에 리모트 노드를 등록한다 */
printf("Remote Service Start...\n\n");
n = ComOpen(SERIAL, "COM1", COM_PORT);
if (n < 0) {
perror("Gateway register error:");
return -1;
}
while(1) {
memset(svcname, 0x00, sizeof(svcname));
memset(buffer, 0x00, sizeof(buffer));
/* 데이터를 수신한다. */
n = ComRecv(svcname, &msgtype, buffer, &olen, COMMNOFLAG);
if (n < 0) {
perror("Data Receive error:");
ComClose();
return -1;
}
printf("REMOTE RECV : svcname = [%s]\n", svcname);
printf("REMOTE RECV : len = %d\n",olen);
printf("REMOTE RECV : data= [%s]\n\n", buffer);
}
/* Gateway와 연결을 해제한다 */
ComClose( );
}
2. REPLY 서비스 호출
Tmax의 서비스나 클라이언트에서 SRLGW로 tpacall로 서비스를 요청하고 결과에 관계없이 처리하고, 리모트 노드에서 서비스 요청에 대한 처리 결과를 Tmax의 다른 서비스에서 처리할 수 있도록 "TOLOWER"를 호출하는 예제이다.
프로그램 구성은 다음과 같다.
| 구분 | 파일명 |
|---|---|
환경 파일 |
tmax.m, serial.cfg |
리모트 노드 |
remote.c |
2.1. 환경 파일
<tmax.m>
*DOMAIN
res SHMKEY = 88000,
MINCLH = 1,
MAXCLH = 1,
TPORTNO = 8888
*NODE
node1 TMAXDIR = "/home/tmax",
APPDIR = "/home/tmax/appbin"
*SVRGROUP
svg1 NODENAME = node1
*SERVER
serialgw SVGNAME = svg1, MIN = 1, MAX = 1, CPC = 10,
SVRTYPE = CUSTOM_GATEWAY,
CLOPT = "-- -F /home/tmax/config/serial.cfg -w 5050"
svr SVGNAME = svg1, MIN = 1, MAX = 1,
*SERVICE
COM1 SVRNAME = serialgw
TOUPPE SVRNAME = svr
TOLOWER SVRNAME = svr
<serial.cfg>
####################################################### # gwno baudrate stopbit Parity Byte Port Tmaxsvc # 0 9600 1 ODD 8 COM1 SVC ####################################################### # line start with "#" is comment line # gwno must start at 0 and be increased by 1 # stopbit: 1, 1.5, 2 # parity : NONE, ODD, EVEN # byte: 5, 6, 7, 8 # port: serial port name # svc: tmax service name ####################################################### 0 9600 1 NONE 8 COM1 COM1
2.2. 리모트 노드
<toupper.c>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <usrinc/atmi.h>
main(int argc, char *argv[])
{
char *sndbuf, *rcvbuf;
long rcvlen;
if (argc != 2) {
printf("Usage: toupper string\n");
exit(1);
}
if (tpstart((TPSTART_T *)NULL) == -1){
printf("Tpstart failed\n");
exit(1);
}
if ((sndbuf = (char *)tpalloc("STRING", NULL, 0)) == NULL) {
printf("Sendbuf alloc failed !\n");
tpend();
exit(1);
}
if ((rcvbuf = (char *)tpalloc("STRING", NULL, 0)) == NULL) {
printf("Recvbuf alloc failed !\n");
tpfree((char *)sndbuf);
tpend();
exit(1);
}
strcpy(sndbuf, argv[1]);
if(tpcall("TOUPPER", sndbuf, 0, &rcvbuf, &rcvlen, 0)==-1){
printf("Can't send request to service TOUPPER\n");
tpfree((char *)sndbuf);
tpfree((char *)rcvbuf);
tpend();
exit(1);
}
printf("Sendbuf data: %s\n", sndbuf);
printf("Recvbuf data: %s\n", rcvbuf);
tpfree((char *)sndbuf);
tpfree((char *)rcvbuf);
tpend();
}
<svr.c>
#include <stdio.h>
#include <usrinc/atmi.h>
TOUPPER(TPSVCINFO *msg)
{
char *sndbuf;
long sndlen;
if ((sndbuf = (char *)tpalloc("STRING", NULL, 0)) == NULL) {
printf("sendbuf alloc failed !\n");
tpreturn(TPFAIL, -1, NULL, 0, 0);
}
strcpy(sndbuf, msg->data);
sndlen = msg->len;
if(tpacall("COM1", sndbuf, sndlen, TPNOREPLY)==-1){
printf("Can't send request to service TCPSVC1\n");
tpfree((char *)sndbuf);
tpreturn(TPFAIL, -1, NULL, 0, 0 );
}
tpfree((char *)sndbuf);
tpreturn(TPSUCCESS,0,(char *)msg->data, msg->len,0);
}
TOLOWER(TPSVCINFO *msg)
{
int i;
printf("TOLOWER service is started!\n");
printf("INPUT : data=%s\n", msg->data);
for (i = 0; i < msg->len; i++)
msg->data[i] = tolower(msg->data[i]);
printf("OUTPUT: data=%s\n\n", msg->data);
tpreturn(TPSUCCESS,0,(char *)msg->data, 0,0);
}
<remote.c>
#include <stdio.h>
#include <winsock2.h>
#include <usrinc/commhead.h>
#define COM_PORT "COM1:9600:8:NONE:1"
int main(int argc, char *argv[])
{
int n, msgtype;
long ilen, olen;
char buffer[1024];
char svcname[24];
/* Gateway에 리모트 노드를 등록한다 */
printf("Remote Service Start...\n\n");
n = ComOpen(SERIAL, "COM1", COM_PORT);
if (n < 0) {
perror("Gateway register error:");
return -1;
}
while(1) {
memset(svcname, 0x00, sizeof(svcname));
memset(buffer, 0x00, sizeof(buffer));
/* 데이터를 수신한다. */
n = ComRecv(svcname, &msgtype, buffer, &olen, COMMNOFLAG);
if (n < 0) {
perror("Data Receive error:");
ComClose();
return -1;
}
printf("REMOTE RECV : svcname = [%s]\n", svcname);
printf("REMOTE RECV : len = %d\n",olen);
printf("REMOTE RECV : data= [%s]\n\n", buffer);
strcpy(buffer,"I'M REMOTE SERVICE.");
ilen = strlen(buffer) + 1;
/* 응답 데이터를 전송한다. */
n = ComSend("TOLOWER", COMMDATA, buffer, ilen, COMMNOREPLY);
if (n < 0) {
perror("Data send error:");
ComClose();
return -1;
}
}
/* Gateway와 연결을 해제한다 */
ComClose( );
}
3. 리모트 노드 동기형 호출
SRLGW가 Tmax boot 시에 기동되어 있다가 리모트 노드의 요청이 수신되면, 사용자가 지정한 서비스를 호출한 후에 다시 리모트 노드로 처리 결과를 전달하는 예제이다.
프로그램 구성은 다음과 같다.
| 구분 | 파일명 |
|---|---|
환경 파일 |
tmax.m, serial.cfg |
리모트 노드 |
remote.c |
3.1. 환경 파일
<tmax.m>
*DOMAIN
res SHMKEY = 88000,
MINCLH = 1,
MAXCLH = 1,
TPORTNO = 8888
*NODE
node1 TMAXDIR = "/home/tmax",
APPDIR = "/home/tmax/appbin
*SVRGROUP
svg1 NODENAME = node1
*SERVER
serialgw SVGNAME = svg1, MIN = 1, MAX = 1, CPC = 10,
SVRTYPE = CUSTOM_GATEWAY,
CLOPT = "-- -F /home/tmax/config/serial.cfg -w 5050"
svr SVGNAME = svg1, MIN = 1, MAX = 1
*SERVICE
COM1 SVRNAME = serialgw
TOUPPER SVRNAME = svr
<serial.cfg>
####################################################### # gwno baudrate stopbit Parity Byte Port Tmaxsvc # 0 9600 1 ODD 8 COM1 SVC ####################################################### # line start with "#" is comment line # gwno must start at 0 and be increased by 1 # stopbit: 1, 1.5, 2 # parity : NONE, ODD, EVEN # byte: 5, 6, 7, 8 # port: serial port name # svc: tmax service name ####################################################### 0 9600 1 NONE 8 COM1 COM1
3.2. 리모트 노드
<svr.c>
#include <stdio.h>
#include <usrinc/atmi.h>
TOUPPER(TPSVCINFO *msg)
{
int i;
char *sndbuf;
printf("TOUPPER service is started!\n");
printf("INPUT : data=%s, len = %d\n", msg->data, msg->len);
for (i = 0; i < msg->len; i++)
msg->data[i] = toupper(msg->data[i]);
printf("OUTPUT: data=%s, len = %d\n",msg->data,msg->len);
tpreturn(TPSUCCESS,0,(char *)msg->data, msg->len,0);
}
<remote.c>
#include <stdio.h>
#include <winsock2.h>
#include <usrinc/commhead.h>
#define COM_PORT "COM1:9600:8:NONE:1"
int main(int argc, char *argv[])
{
int n, msgtype;
long ilen, olen;
char buffer[1024];
char svcname[20];
char *ptr;
/* Gateway에 리모트 노드를 등록한다 */
printf("Remote Service Start...\n\n");
n = ComOpen(SERIAL, "COM1", COM_PORT);
if (n < 0) {
perror("Gateway register error:");
return -1;
}
ptr = argv[1];
ilen = strlen(argv[1]) + 1;
printf("Send Data = [%s], len = %d\n",ptr,ilen);
n = ComSend("TOUPPER", COMMDATA, ptr, ilen, COMMNOFLAG);
if (n < 0) {
perror("Data send error:");
ComClose();
return -1;
}
memset(svcname, 0x00, sizeof(svcname));
memset(buffer, 0x00, sizeof(buffer));
/* 응답 데이터를 수신한다. */
n = ComRecv(svcname, &msgtype, buffer, &olen, COMMNOFLAG);
if (n < 0) {
perror("Data Receive error:");
ComClose();
return -1;
}
printf("REMOTE RECV : svcname = [%s]\n", svcname);
printf("REMOTE RECV : len = %d\n",olen);
printf("REMOTE RECV : data= [%s]\n\n", buffer);
/* Gateway와 연결을 해제한다 */
ComClose( );
}
4. ACK/NAK 통신 방식
SRLGW가 Tmax boot 시에 기동되어 있다가 리모트 노드의 요청이 수신되면, 사용자가 지정한 서비스를 호출한 후에 다시 리모트 노드로 처리 결과를 전달하는 예제이다. 이 경우에 송수신 데이터에 대해서 ACK/NAK를 처리하는 예제이다.
프로그램 구성은 다음과 같다.
| 구분 | 파일명 |
|---|---|
환경 파일 |
tmax.m, serial.cfg |
리모트 노드 |
remote.c |
4.1. 환경 파일
<tmax.m>
*DOMAIN
res SHMKEY = 88000,
MINCLH = 1,
MAXCLH = 1,
TPORTNO = 8888
*NODE
node1 TMAXDIR = "/home/tmax",
APPDIR = "/home/tmax/appbin"
*SVRGROUP
svg1 NODENAME = node1
*SERVER
Serialgw SVGNAME = svg1, MIN = 1,MAX = 1,CPC = 10,
SVRTYPE = CUSTOM_GATEWAY,
CLOPT = "-- -F /home/tmax/config/serial.cfg -w 5050 -A"
avr SVGNAME = svg1, MIN = 1, MAX = 1
*SERVICE
COM1 SVRNAME = serialgw
TOUPPER SVRNAME = svr
<serial.cfg>
####################################################### # gwno baudrate stopbit Parity Byte Port Tmaxsvc # 0 9600 1 ODD 8 COM1 SVC ####################################################### # line start with "#" is comment line # gwno must start at 0 and be increased by 1 # stopbit: 1, 1.5, 2 # parity : NONE, ODD, EVEN # byte: 5, 6, 7, 8 # port: serial port name # svc: tmax service name ####################################################### 0 9600 1 NONE 8 COM1 COM1
4.2. 리모트 노드
<svr.c>
#include <stdio.h>
#include <usrinc/atmi.h>
TOUPPER(TPSVCINFO *msg)
{
int i;
char *sndbuf;
printf("TOUPPER service is started!\n");
printf("INPUT : data=%s, len = %d\n", msg->data, msg->len);
for (i = 0; i < msg->len; i++)
msg->data[i] = toupper(msg->data[i]);
printf("OUTPUT: data=%s,len = %d\n", msg->data,msg->len);
tpreturn(TPSUCCESS,0,(char *)msg->data, msg->len,0);
}
<remote.c>
#include <stdio.h>
#include <winsock2.h>
#include <usrinc/commhead.h>
#define COM_PORT "COM1:9600:8:NONE:1"
int main(int argc, char *argv[])
{
int n, msgtype;
long ilen, olen;
char buffer[1024];
char svcname[20];
char *ptr;
/* Gateway에 리모트 노드를 등록한다 */
printf("Remote Service Start...\n\n");
n = ComOpen(SERIAL, "COM1", COM_PORT);
if (n < 0) {
perror("Gateway register error:");
return -1;
}
while(1) {
ptr = argv[1];
ilen = strlen(argv[1]) + 1;
printf("Send Data = [%s], len = %d\n",ptr,ilen);
n = ComSend("TOUPPER", COMMDATA, ptr, ilen, COMMNOFLAG);
if (n < 0) {
perror("Data send error:");
ComClose();
return -1;
}
memset(svcname, 0x00, sizeof(svcname));
memset(buffer, 0x00, sizeof(buffer));
/* ACK/NAK 수신. */
n = ComRecv(svcname, &msgtype, buffer, &olen, COMMNOFLAG);
if (n < 0) {
perror("Data Receive error:");
printf("RT = %d\n",n);
ComClose();
return -1;
}
if (msgtype == COMMACK)
break;
}
printf("REMOTE RECV OK! : ACK msgtype = [%d]\n", msgtype);
/* ACK/NAK 송신. */
n = ComSend("TOUPPER", COMMACK, NULL, 0, COMMNOFLAG);
if (n < 0) {
perror("Data send error:");
ComClose();
return -1;
}
printf("REMOTE SEND OK! : Return = [%d]\n", n);
/* Gateway와 연결을 해제한다 */
ComClose( );
}