Subversion Repositories factorylink.sapi

Rev

Blame | Last modification | View Log | Download

/****************************************************************************

    PROGRAM: test.c  

    PURPOSE: S7 client sample for windows

    FUNCTIONS:

        WinMain() - calls initialization function, processes message loop
        InitApplication() - initializes window data and registers window
        InitInstance() - saves instance handle and creates main window
        MainWndProc() - processes messages

    COMMENTS:

        Windows can have several copies of your application running at the
        same time.  The variable hInst keeps track of which instance this
        application is so that processing will be to the correct window.

****************************************************************************/

#ifdef _WINDOWS
#include <windows.h>
#endif

#include <stdio.h>
#include <dos.h>
#include <stdlib.h>
#include <string.h>
#include "sapi_s7.h"

/* prototyping */
void schreibe_var(ord32 cp_descr,ord16 cref);
void lese_var(ord32 cp_descr,ord16 cref);
void cycl_lese_var(ord32 cp_descr,ord16 cref, long db );

/* defines */
#define READ_BUFFER_LEN 10240
#define WM_S7     0x0500
#define WM_S7INIT 0x0501
#define   MAXLINE    21         /* max. lines for DoWmPaint  */
#define   LINELENGTH 200          /* line length for DoWmPaint */
#define AUSGABE_ERWUENSCHT
#ifdef AUSGABE_ERWUENSCHT
#define AUSGABE(a,b)      sprintf(&tmp_buf[0],a,b);                        \
                          WinPrintf(hWnd,                          \
                                    (LPSTR) tmp_buf);
#else
#define AUSGABE(a,b)
#endif

/* prototyping */
static void receive_s7(void);
static int WinPrintf(HWND hwnd,char * text,...);
void DoWmPaint(HWND hwnd);

/* global variables */
static ord32      cp_descr;
static ord16      cref,
                  /*orderid=1,*/
                  orderid=54,
                  number_connections,
                  number_confirmations=0;
static char       conn_name[S7_MAX_NAMLEN+1];
static char       tmp_buf[200];
static HWND       hWnd;               /* Main window handle.                */
static int  Line = -1;                  
static long   Count;                  
static long   Max_cyclic[ 10 ];                 
static long   Db[ 10 ];
static char ringTextBuf[MAXLINE][LINELENGTH]; /* for DoWmPaint */
char read_buffer[READ_BUFFER_LEN];


/*--init_s7()-------------------------------------------------------*/

int32 init_s7(void)
{      int32 res;
       ord16 number;
static char  vfd_name[S7_MAX_NAMLEN+1];

   res=s7_get_vfd("CP5412ASapi",0,&number,vfd_name);
   AUSGABE("s7_get_vfd()=%ld",res);
   if(res=S7_OK)
   {
      exit(-1); 
   }
   res=s7_init("CP5412ASapi",vfd_name,&cp_descr);
   return(res);
}

/*--shut_s7()-------------------------------------------------------*/

void shut_s7(void)
{
   s7_shut(cp_descr);
}


/*--receive_s7()-----------------------------------------------------*/

void receive_s7(void)
{  
  
    int32 res,ret;
    ord16 i,c,
          my_cref,
          my_orderid,
          len = 2, 
          cycl_len[ 256 ],
          result[ 256 ];
    ord32 r_id=2;
    static ord16 send_buffer, error;
    static char *err_msg;
    char  *value_array[10];

   res = s7_receive( cp_descr, &my_cref, &my_orderid );

   switch(res)
   {
      case S7_NO_MSG:
      {  /* nothing received */
         break;
      }
      case S7_ABORT_IND:
      {  /* abort indication received */
         ret=s7_get_abort_ind();
         AUSGABE("s7_get_abort_ind=%ld",ret);
         shut_s7();
         exit(-1);
         break;
      }
      case S7_INITIATE_CNF:
      {  /* initiate confirmation received */

         ret=s7_get_initiate_cnf();

         AUSGABE("s7_get_initiate_cnf()=%ld",ret);

         if(ret!=S7_OK)
         {
           err_msg = s7_last_detailed_err_msg();
            shut_s7();
            exit(-1); 
         }

         number_confirmations++;
         if(number_confirmations==number_connections)
         {
            number_connections=1;
            for(i=0;i<number_connections;i++)
            {
               ret=s7_get_conn(cp_descr,i,&number_connections,
                               &my_cref,conn_name);
               AUSGABE("s7_get_conn()=%ld",ret);
               if(ret!=S7_OK)
               {  shut_s7();
                  exit(-1); 
               }

               /*
                *
                */
               err_msg = s7_mini_db_get( S7_MINI_DB_INIT_CNF_PDU_SIZE );

               AUSGABE("s7_get_db_get(S7_MINI_DB_INIT_CNF_PDU_SIZE) =%s", err_msg );

               if( ret!=S7_OK )
               {  
                 err_msg = s7_last_detailed_err_msg();
                 shut_s7();
                 exit(-1); 
               }

               Db[ my_cref ] = 200;

              cycl_lese_var(cp_descr, my_cref, Db[ my_cref ]++ );
            }

            /*cycl_lese_var(cp_descr,0);*/
         }
         break;
      }

      case S7_CYCL_READ_INIT_CNF:

        ret = s7_get_cycl_read_init_cnf();

        if( ret!=S7_OK)
        {
           error = s7_last_detailed_err_no();
           err_msg = s7_last_detailed_err_msg();
           shut_s7();
           exit(-1);
        }

        ret = s7_cycl_read_start_req( cp_descr,
                                      my_cref,
                                      my_orderid);
        break;

      case S7_CYCL_READ_START_CNF:

        ret = s7_get_cycl_read_start_cnf();

        if( ret!=S7_OK)
        {
           err_msg = s7_last_detailed_err_msg();
           shut_s7();
           exit(-1);
        }

        /*if( Max_cyclic[ my_cref ] < 1 )
        {
          cycl_lese_var( cp_descr,my_cref , Db[ my_cref ]++ );
          Max_cyclic[ my_cref ]++;
        }*/

        break;

      case S7_CYCL_READ_IND:

        memset( cycl_len, 0x00, 512 );


        cycl_len[0] = 512;
        value_array[0] = read_buffer;

        ret = s7_get_cycl_read_ind( ( void *)0, result, cycl_len, value_array );

        if( ret!=S7_OK)
        {
           err_msg = s7_last_detailed_err_msg();
           shut_s7();
           exit(-1);
         }

        /*AUSGABE("\ns7_get_cycl_read_ind=%ld",ret);*/

        if ( result[0] == S7_RESULT_OK )
          AUSGABE("Performance count=%ld", Count++ );


        /*schreibe_var(cp_descr,my_cref); */

        break;

      case S7_READ_CNF:
      {  /* read confirmation received */
        ret=s7_get_read_cnf((void *)0,&len,read_buffer);
        if(ret!=S7_OK)
        {
           err_msg = s7_last_detailed_err_msg();
           shut_s7();
           exit(-1);
         }

         AUSGABE("\ns7_get_read_cnf=%ld",ret);

         schreibe_var(cp_descr,my_cref);  
         break;
      }
      case S7_WRITE_CNF:
      {  /* write confirmation received */
         ret=s7_get_write_cnf();
         if(ret!=S7_OK)
         {
  
            shut_s7();
            exit(-1);
         }
    
  
         AUSGABE("\ns7_get_write_cnf=%ld",ret);
        
         /*lese_var(cp_descr,my_cref);*/

         break;
      }
      default:
      {  /* anything else received or happened */
         AUSGABE("something unknown received (%ld)",res);
         shut_s7();
         exit(-1);
         break;
      }
   }
}


/****************************************************************************

    FUNCTION: MainWndProc(HWND, UINT, WPARAM, LPARAM)

    PURPOSE:  Processes messages

    MESSAGES:

        WM_COMMAND    - application menu (About dialog box)
        WM_DESTROY    - destroy window

    COMMENTS:

        To process the IDM_ABOUT message, call MakeProcInstance() to get the
        current instance address of the About() function.  Then call Dialog
        box which will create the box according to the information in your
        generic.rc file and turn control over to the About() function.  When
        it returns, free the intance address.

****************************************************************************/

long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd;                                /* window handle                   */
UINT message;                             /* type of message                 */
WPARAM wParam;                            /* additional information          */
LPARAM lParam;                            /* additional information          */
{   
  
  int32   result;
  ord16   i;
  static char *err_msg;

    switch (message) {
        /*case WM_CLOSE:
          break;
        case WM_QUIT:
          break;*/
        case WM_PAINT:
            DoWmPaint(hWnd);
            break;
        case WM_S7:
            receive_s7();
            break;
        case WM_S7INIT:
            result=init_s7();     /* initialize stf                 */
            AUSGABE("s7_init()=%ld",result);
            if(result!=S7_OK)
            {  exit(-1); 
            }

            /*
             * set the request PDU size
             */
            result = s7_mini_db_set( S7_MINI_DB_INIT_REQ_PDU_SIZE, "512" );

            AUSGABE("s7_mini_db_set() req =%ld",result);

            if(result!=S7_OK)
            {  shut_s7();
               exit(-1); 
            }

            result = s7_mini_db_set( S7_MINI_DB_INIT_RSP_PDU_SIZE, "512" );

            AUSGABE("s7_mini_db_set() rsp =%ld",result);

            if(result!=S7_OK)
            {  shut_s7();
               exit(-1); 
            }

            result=s7_set_window_handle_msg(cp_descr,hWnd,WM_S7);
            AUSGABE("s7_set_window_handle()=%ld",result);
            if(result!=S7_OK)
            {  shut_s7();
               exit(-1); 
            }

            number_connections=1;
            for(i=0;i<number_connections;i++)
            {
               result=s7_get_conn(cp_descr,i,&number_connections,
                                  &cref,conn_name);
               AUSGABE("s7_get_conn()=%ld",result);
               if(result!=S7_OK)
               {  shut_s7();
                  exit(-1); 
               }
   
               result=s7_initiate_req(cp_descr,cref);
               AUSGABE("s7_initiate_req()=%ld",result);
              err_msg = s7_last_detailed_err_msg();

               if(result!=S7_OK)
               {  shut_s7();
                  exit(-1); 
               }

            }
            break;
        default:                          /* Passes it on if unproccessed    */
            return (DefWindowProc(hWnd, message, wParam, lParam));
    }
    return (0);
}


/****************************************************************************

    FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)

    PURPOSE: calls initialization function, processes message loop

    COMMENTS:

        Windows recognizes this function by name as the initial entry point 
        for the program.  This function calls the application initialization 
        routine, if no other instance of the program is running, and always 
        calls the instance initialization routine.  It then executes a message 
        retrieval and dispatch loop that is the top-level control structure 
        for the remainder of execution.  The loop is terminated when a WM_QUIT 
        message is received, at which time this function exits the application 
        instance by returning the value passed by PostQuitMessage(). 

        If this function must abort before entering the message loop, it 
        returns the conventional value NULL.  

****************************************************************************/

int PASCAL WinMain(
    HANDLE hInstance,                    /* current instance         */
    HANDLE hPrevInstance,                /* previous instance        */
    LPSTR lpCmdLine,                     /* command line             */
    int nCmdShow                         /* show-window type (open/icon) */
  )
{
    MSG msg;                             /* message                  */

    if (!hPrevInstance)                  /* Other instances of app running? */
        if (!InitApplication(hInstance)) /* Initialize shared things */
            return (FALSE);              /* Exits if unable to initialize     */

    if (lpCmdLine) ;                     /* suppress warning 'never used' */

    /* Perform initializations that apply to a specific instance */

    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

    /* Acquire and dispatch messages until a WM_QUIT message is received. */

    while (GetMessage(&msg,        /* message structure                      */
            0,                     /* handle of window receiving the message */
            0,                     /* lowest message to examine              */
            0))                    /* highest message to examine             */
        {
        TranslateMessage(&msg);    /* Translates virtual key codes           */
        DispatchMessage(&msg);     /* Dispatches message to window           */
    }
    return (msg.wParam);           /* Returns the value from PostQuitMessage */
}


/****************************************************************************

    FUNCTION: InitApplication(HANDLE)

    PURPOSE: Initializes window data and registers window class

    COMMENTS:

        This function is called at initialization time only if no other 
        instances of the application are running.  This function performs 
        initialization tasks that can be done once for any number of running 
        instances.  

        In this case, we initialize a window class by filling out a data 
        structure of type WNDCLASS and calling the Windows RegisterClass() 
        function.  Since all instances of this application use the same window 
        class, we only need to do this when the first instance is initialized.  


****************************************************************************/

BOOL InitApplication(hInstance)
HANDLE hInstance;                              /* current instance           */
{
    WNDCLASS  wc;

    /* Fill in window class structure with parameters that describe the       */
    /* main window.                                                           */

  wc.style         = CS_OWNDC;        /* Class style(s).                    */
    wc.lpfnWndProc   = MainWndProc;     /* Function to retrieve messages for  */
                                        /* windows of this class.             */
    wc.cbClsExtra    = 0;               /* No per-class extra data.           */
    wc.cbWndExtra    = 0;               /* No per-window extra data.          */
    wc.hInstance     = hInstance;       /* Application that owns the class.   */
    wc.hIcon         = LoadIcon(hInstance, "WclientIcon");
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH); 
    wc.lpszMenuName  = "WclientMenu";   /* Name of menu resource in .RC file. */
    wc.lpszClassName = "WclientWClass"; /* Name used in call to CreateWindow. */

    /* Register the window class and return success/failure code. */

    return (RegisterClass(&wc));

}


/****************************************************************************

    FUNCTION:  InitInstance(HANDLE, int)

    PURPOSE:  Saves instance handle and creates main window

    COMMENTS:

        This function is called at initialization time for every instance of 
        this application.  This function performs initialization tasks that 
        cannot be shared by multiple instances.  

        In this case, we save the instance handle in a static variable and 
        create and display the main program window.  

****************************************************************************/

BOOL InitInstance(hInstance, nCmdShow)
    HANDLE          hInstance;          /* Current instance identifier.       */
    int             nCmdShow;           /* Param for first ShowWindow() call. */
{

    /* Save the instance handle in static variable, which will be used in  */
    /* many subsequence calls from this application to Windows.            */

    /* Create a main window for this application instance.  */

    hWnd = CreateWindow(
        "WclientWClass",                /* See RegisterClass() call.          */
        "SINEC S7 bsnd sample",         /* Text for window title bar.         */
        WS_OVERLAPPEDWINDOW,            /* Window style.                      */
        CW_USEDEFAULT,                  /* Default horizontal position.       */
        CW_USEDEFAULT,                  /* Default vertical position.         */
        CW_USEDEFAULT,                  /* Default width.                     */
        CW_USEDEFAULT,                  /* Default height.                    */
        NULL,                           /* Overlapped windows have no parent. */
        NULL,                           /* Use the window class menu.         */
        hInstance,                      /* This instance owns this window.    */
        NULL                            /* Pointer not needed.                */
    );

    /* If window could not be created, return "failure" */

    if (!hWnd)
        return (FALSE);

    /* Make the window visible; update its client area; and return "success" */

    ShowWindow(hWnd, nCmdShow);  /* Show the window                        */
    UpdateWindow(hWnd);          /* Sends WM_PAINT message                 */

    PostMessage(hWnd,WM_S7INIT,0,0L);

    return (TRUE);
}

/**************************************************************************/
/*                                                                        */
/*  WinPrintf(hwin,text)                                                  */
/*                                                                        */
/*  to use like printf                                                    */
/*                                                                        */
/*                                                                        */
/**************************************************************************/
int WinPrintf(HWND hwnd,char * text,...)
{
    va_list arg_zeiger;

    va_start(arg_zeiger,text);

  Line ++;
  if (Line == MAXLINE)
    {  int i;

      for (i = 0; i < MAXLINE-1 ; i++) {
        ringTextBuf[i][0] = '\0'; /* clear Buffer */
        }

        Line = 0;
    }

    vsprintf(&ringTextBuf[Line][0],text,arg_zeiger); /* all Information to print is now in buffer */
    InvalidateRect(hwnd,NULL,TRUE);
  return 1;
}
 



/**************************************************************************/
/*  DoWmPaint                                                             */
/*                                                                        */
/*  Repaint Window because WM_PAINT-Message                               */
/**************************************************************************/
void DoWmPaint(HWND hwnd) {
COLORREF  bcolor,fcolor;

    PAINTSTRUCT ps;
    HDC     hdc;
    int     i;
static BOOL bFirstWmPaint = TRUE;


   fcolor=RGB(0,0,0);
   bcolor=RGB(255,255,255);

    if (bFirstWmPaint) {
      for (i = 0; i < MAXLINE ; i++) {
          ringTextBuf[i][0] = '\0'; /* clear Buffer */
        }
    bFirstWmPaint = FALSE;
    }


    hdc = GetDC(hwnd);
    SetTextColor(hdc,fcolor);
    SetBkColor(hdc,bcolor);

    InvalidateRect(hwnd,NULL,TRUE);
    BeginPaint (hwnd, (LPPAINTSTRUCT)&ps);
    EndPaint(hwnd, (LPPAINTSTRUCT)&ps);


    for (i = 0;i<MAXLINE; i ++) {
    TextOut(hdc,10, i * 18 + 4, &ringTextBuf[i][0], lstrlen(&ringTextBuf[i][0]));   
    }

  
    ReleaseDC(hWnd,hdc);
}

void schreibe_var(ord32 descr,ord16 ref)
{
   int ret;
   static struct S7_WRITE_PARA write_para;

   write_para.access=S7_ACCESS_SYMB_ADDRESS;
   write_para.var_length=2;
   strcpy(write_para.var_name,"MW10");
       
   *((ord16 *)(write_para.value))=ref+1;

   ret=s7_write_req(descr,ref,
                    orderid,
                    &write_para,(void *)0);
   AUSGABE("\ns7_write_req: %ld",ret);
   if(ret!=S7_OK)
   {
      s7_write_trace_buffer("WRIT_REQ.TXT");
      exit(-1);
   }
   orderid++;
}


void lese_var(ord32 descr,ord16 ref)
{  
   int ret;
   static struct S7_READ_PARA read_para;


   read_para.access=S7_ACCESS_SYMB_ADDRESS;
   strcpy(read_para.var_name,"MW10");
       
   ret=s7_read_req(descr,ref,
                   orderid,
                   (struct S7_READ_PARA *)&read_para);
   AUSGABE("\ns7_read_req: %ld",ret);
   if(ret!=S7_OK)
   {
      s7_write_trace_buffer("READ_REQ.TXT");
      exit(-1);
   }
   orderid++;
}
  
void cycl_lese_var( ord32 descr, ord16 ref, long db )
{  
  int ret;
  static struct S7_READ_PARA read_para;
  static char *err_msg;

   /*strcpy(read_para.var_name,"MW10");*/

    read_para.access=S7_ACCESS_SYMB_ADDRESS;
    sprintf( read_para.var_name,"DB%d,B1,448", db );
       
   /*
    * initiate a cyclic read
    */
#ifdef CONFIRMED
    ret = s7_cycl_read_init_req(  cp_descr,
                                  ref,
                                  orderid,
                                  1,
                                  1,
                                  (struct S7_READ_PARA *)&read_para);

    AUSGABE("\ns7_cyclic_read_init_req: %ld",ret);

#else

    ret = s7_cycl_read( cp_descr,
                        ref,
                        orderid,
                        1,
                        1,
                        (struct S7_READ_PARA *)&read_para);
#endif

   AUSGABE("\ns7_cycl_read: %ld",ret);

   if( ret!=S7_OK )
   {
     err_msg = s7_last_detailed_err_msg();
      s7_write_trace_buffer("READ_CYCL.TXT");
      exit(-1);
   }

   orderid++;
}