I would like to propose a module that will interface with x3270 software to 
allow for automated operation/testing of mainframe applications.

There are automated testing tools for the mainframe, but most of them are 
proprietary and interact with proprietary terminal emulators.

This module aims to provide an interface with an open source mainframe terminal 
emulator X3270. The X3270 allows a user to manually enter commands directly or 
by passing a file with the list of action instructions.

By using this module, someone familiar with Perl can write an automated script 
which can access data from a file or database to drive automated operation or 
testing.

If you wish to learn more, please feel free to contact me. I used to run a 
website on Perl but have moved it to another site (http://perl.conceptbc.ca) 
but have stopped because I discovered a lot of people getting ideas from my 
articles and claiming it as their own.

I have created a video for proof of concept of this module in this video: 
https://youtu.be/UVqYYGLYqr8

Attached is a skeleton of the module I used in the video.

Thank you.


============================
Philip Yuson
Mainframe Consultant
Concept Solutions Corporation
P: 250-881-0049
package t3270;
    my $self = {};
    sub new {

        print "Initializing t3270 session\n";
        my $class = shift;
        my $key;
        while (@_) {
            $key = shift;
            $self->{$key} = shift;
            print "t3270: Ndx: $key\t$self->{$key}\n";
        }
        tconnect($self);
        screenSize($self);
        bless $self, $class;
        return $self;
    }
    sub tconnect {
        my $self = shift;
        $self->{session} = IO::Socket::INET->new(
                Proto   => 'tcp',       # protocol
                PeerAddr=> $self->{server}, # Address of server
                PeerPort=> $self->{port},      # port of server
                Reuse   => 1,
                ) or die "$!";
        print "Connected to " . $self->{server} . # Info message
            " on port:    " . $self->{port} . "\n";
        $self->{session}->autoflush(1);  # Send immediately
    }

    sub getScreen {
        my $self = shift;
        my $sess = $self->{session};
        sendAction($self, "ascii\n");
        $self->{screen};
    }
        
    sub sendAction {
        my ($self, $str) = @_;
        my $sess = $self->{session};
        if ($str !~ m/\n$/) {
            $str .= "\n";
        }
        print "SENDING: $str----\n";    # if $self->{debug};        
        print $sess $str;
        getResult($self);     
        $self->{screen};
        sleep(1);
    }
    
    sub sendStr {
        my ($self, $str) = @_;
        my $sess = $self->{session};
        $str = 'string("' . $str . "\") enter()\n";
        sendAction($self, $str);
#        print $sess $str;
#        getResult($self);
        @{$self->{screen}};
    }
    
    sub getResult {
        my $self = shift;
        $self->{screen} = [];
        my $sess = $self->{session};
        my $l;
        my $lines = 0;
        my ($ok, $status, $error) = ();
        while ((! $ok and ! $error) or ! $status ) {
            print "--- Getting Response\n" if $self->{debug};
            $lines++;        
            
            $l = <$sess>;   # Receive echo from server
            if ($l =~ m/^ok[\n\r]*$/i) {
                print "OK: $l: $status\n" if $self->{debug};
                $ok = $l;
            } elsif ($l =~ m/^error[\n\r]*$/i) {
                print "ERROR: $l: $status\n" if $self->{debug};
                $error = $l;
            } elsif ($l =~ m/^u f u c\(localhost\) i +\d+ +(\d+) +(\d+) +(\d+) 
+(\d+)/i
                or   $l =~ m/^l f p n n (\d) (\d+) (\d+) (\d+) /i
                or   $l =~ m/^u f p c\(localhost\) i +\d+ +(\d+) +(\d+) +(\d+) 
+(\d+)/i) {
                $self->{rows} = $1;
                $self->{cols} = $2;
                $self->{currow} = $3;
                $self->{curcol} = $4;
                if ($self->{debug}) {
                    print "Cursor location: $self->{currow}\t$self->{curcol}\n";
                    print "Screen size: $self->{rows}\t$self->{cols}\n";
                }
                $status = $l;
                print "Status: $status" if $self->{debug};
            } elsif ($l =~ m/^data: (.+)+$/gi) {
                print '-'x20 . "\n$1\n" if $self->{debug};
            } else {
                print 'x'x10 . "Unknown response: $l\n";
                return;
            }
            push @{$self->{screen}}, $l;
        }
    }

    sub screenSize {
        my $self = shift;
        my $scr = sendAction($self, "ascii\n");
    }
    
    
    sub searchRow {
        my ($self, $row, $str) = @_;
        unless ($row) {
            $row = $my->{currow};
        }
        sendAction("ascii($row, 80, 80)");
        if ($self->{screen}->[$row] =~ m/$str/gi) {
            return $self->{screen}->[$row];
        } else {
            return -1;
        }
    }
    
    sub searchStr {
        my ($self, $str) = @_;
        my @rows = ();
        my $line;
        sendAction($self, 'ascii');
        foreach (@{$self->{screen} } ) {
            $line++;
            if (m/$str/gi) {
                push @rows, $line;
            }
        }
        \@rows;
    }
1

Reply via email to