Topic
IC4NOTICE: developerWorks Community will be offline May 29-30, 2015 while we upgrade to the latest version of IBM Connections. For more information, read our upgrade FAQ.
6 replies Latest Post - ‏2012-09-03T10:36:14Z by PeterOL
PeterOL
PeterOL
9 Posts
ACCEPTED ANSWER

Pinned topic GUID: generate in a PL/I program on z/OS

‏2012-08-02T09:13:37Z |
Hi there,  
I need to generate a GUID in a PL/I program - but how can I do that? 
The best would be a function call like "myGUID = GetGUID();" - or somthing like that.
If it works in both BATCH and CICS it would be really nice.
Can anyone help?
Updated on 2012-09-03T10:36:14Z at 2012-09-03T10:36:14Z by PeterOL
  • ccw
    ccw
    7 Posts
    ACCEPTED ANSWER

    Re: GUID: generate in a PL/I program on z/OS

    ‏2012-08-31T03:48:16Z  in response to PeterOL
     It is a 128 bit quantity, better to pass as argument.
     
    This example does not implement the clock sequence part per rfc4122,
    and  use cpu serial in place of MAC address.
     
     *PROCESS LIMITS(FIXEDBIN(63));
     guid: package;

     define structure
        1 guid
         ,3 time_low unsigned fixed bin(32)
         ,3 time_mid unsigned fixed bin(16)
         ,3 time_hi_and_version unsigned fixed bin(16)
         ,3 clock_seq_hi_and_reserved unsigned fixed bin(8)
         ,3 clock_seq_low unsigned fixed bin(8)
         ,3 node char(6)
     ;

     define structure
        1 _FEEDBACK
         ,3 tok_sev fixed bin(15)
         ,3 tok_msgno fixed bin(15)
         ,3 *
           ,5 tok_case bit(2) unaligned
           ,5 tok_sever bit(3) unaligned
           ,5 tok_ctrl bit(3) unaligned
         ,3 tok_facid(3) char
         ,3 tok_isi fixed bin(31)
     ;

     dcl CEEGMT entry(fixed bin(31) byaddr, real float decimal(16) byaddr,
         1 optional type _FEEDBACK byaddr) options(assembler);

     dcl getcpuid ext('__get_cpuid') entry(char(11) byaddr)
         returns(optional fixed bin(31))
     options( linkage(optlink) nodescriptor );

     guidfmt: proc(u,out);
         dcl u type guid byvalue;
         dcl out char(*) varz byaddr;
         out='';
         out=heximage(addr(u.time_low),4); out||='-';
         out||=heximage(addr(u.time_mid),2); out||='-';
         out||=heximage(addr(u.time_hi_and_version),2); out||='-';
         out||=heximage(addr(u.clock_seq_hi_and_reserved),2); out||='-';
         out||=heximage(addr(u.node),6);
     end guidfmt;

     genguid: proc(u);
        dcl u type guid;
        dcl lilgmt fixed bin(31);
        dcl secgmt real float decimal(16);
        dcl t unsigned fixed bin(64);
        dcl fb type _FEEDBACK;
        dcl buf char(11);
        dcl rc fixed bin(31);
        dcl pid fixed unsigned bin(32);
        call CEEGMT(lilgmt,secgmt,fb);
        if (fb.tok_sev = 0 & fb.tok_msgno = 0) then do;
        end;
        else stop;
        call getcpuid(buf);
        u.node=substr(buf,1,6);
        t=secgmt*10000000;
        u.time_low=iand(t,'00000000ffffffff'xn);
        u.time_mid=iand(isrl(t,32),'000000000000ffff'xn);
        u.time_hi_and_version=iand(isrl(t,48),'0000000000000fff'xn);
        u.time_hi_and_version=ior(isll(1,12),u.time_hi_and_version);
        u.clock_seq_low=0;
        u.clock_seq_hi_and_reserved = 0;
        u.clock_seq_hi_and_reserved =
          iand(u.clock_seq_hi_and_reserved,'3f'xn);
        u.clock_seq_hi_and_reserved =
          ior(u.clock_seq_hi_and_reserved,'80'xn);
     end genguid;

     test: proc options(main);
        dcl u type guid;
        dcl out char(100) varz;
        call genguid(u);
        call guidfmt(u,out);
        display("guid:"||out);
     end test;

     end guid;

    • PeterOL
      PeterOL
      9 Posts
      ACCEPTED ANSWER

      Re: GUID: generate in a PL/I program on z/OS

      ‏2012-08-31T09:35:16Z  in response to ccw
       Thank you "ccw" - this looks interesting.
      I have now tried to compile your code but I get a severe error on these lines:

      109.0 1 U.TIME_LOW=IAND(T,'00000000ffffffff'XN);

      110.0 1 U.TIME_MID=IAND(ISRL(T,32),'000000000000ffff'XN);

      111.0 1 U.TIME_HI_AND_VERSION=IAND(ISRL(T,48),'0000000000000fff'XN);

      5655-W67 IBM(R) Enterprise PL/I for z/OS 2012.08.31 11:24:18 Page 8

      Compiler Messages

      Message Line.File Message Description

      IBM1920I S 109.0 FIXED BINARY constant contains too many digits.

      IBM1920I S 110.0 FIXED BINARY constant contains too many digits.

      IBM1920I S 111.0 FIXED BINARY constant contains too many digits.

        
      • ccw
        ccw
        7 Posts
        ACCEPTED ANSWER

        Re: GUID: generate in a PL/I program on z/OS

        ‏2012-09-02T07:26:25Z  in response to PeterOL
        Ok, I got the same errors if I do not use the option LIMITS(FIXEDBIN(63))
        you need that line as the first line or specify that as a compile option.
         
         *PROCESS LIMITS(FIXEDBIN(63)); 
         
        Note the node portion of the GUID is suppose to contain the MAC address of one of
        the ethernet cards on the system. In theory no two ethernet cards on this planet should 
        have the same MAC. I don't know of any good way to obtain that on MVS  other than issuing 
        console or TSO command netstat arp all tcp tcpip. CPU serial is not a perfect substitution.
        You can hard code you MAC if you know the program only runs on one single system.
         
        Updated on 2012-09-02T07:26:25Z at 2012-09-02T07:26:25Z by ccw
        • PeterOL
          PeterOL
          9 Posts
          ACCEPTED ANSWER

          Re: GUID: generate in a PL/I program on z/OS

          ‏2012-09-03T06:30:41Z  in response to ccw
          Hi again,
          I get the same error if the *PROCESS line is active or not.
          This is z/OS PL/I version 4.1 compiler.
          I do have a solution to the GUID but as it is at the moment it depends on getting a timestamp from DB2.
          Maybe I can get a timestamp directly from PL/I with all the digits as DB2 can deliver.
           
          The current problem for me are the DB2 issue. Some project want to include the code in a high-level place where DB2 code is not allowed. We have a rule on CICS that dialogs modules have to be withot DB2. Also in batch some project restricts DB2 to same datamodules and not in the main-loop or business modules.
           
          Well I just need to do whatever people ask for - more or less :-)
               
           
          • ccw
            ccw
            7 Posts
            ACCEPTED ANSWER

            Re: GUID: generate in a PL/I program on z/OS

            ‏2012-09-03T08:30:27Z  in response to PeterOL
             That line need to be the first line and starts at the first column and you should see
             
              Line.File Process Statements

                 1.0    *PROCESS LIMITS(FIXEDBIN(63));

             
            In the compile listing, works on 4.1.
            If for whatever reason it does not work for you, you can replace the proc genuuid with this version which does not use 64 bit integers.
             ......
             genguid: proc(u);
                dcl u type guid;
                dcl lilgmt fixed bin(31);
                dcl secgmt real float decimal(16);
                dcl t1 unsigned fixed bin(32);
                dcl t2 unsigned fixed bin(32);
                dcl fb type _FEEDBACK;
                dcl buf char(11);
                dcl rc fixed bin(31);
                dcl pid fixed unsigned bin(32);
                call CEEGMT(lilgmt,secgmt,fb);
                if (fb.tok_sev = 0 & fb.tok_msgno = 0) then do;
                end;
                else stop;
                call getcpuid(buf);
                u.node=substr(buf,1,6);
                t1=(secgmt*10000000/4294967296);
                t2=secgmt*10000000;
                t2*=16;
                u.time_low=iand(t2,'ffffffff'xn);
                u.time_mid=iand(t1,'0000ffff'xn);
                u.time_hi_and_version=iand(isrl(t1,16),'00000fff'xn);
                u.time_hi_and_version=ior(isll(1,12),u.time_hi_and_version);
                u.clock_seq_low=0;
                u.clock_seq_hi_and_reserved = 0;
                u.clock_seq_hi_and_reserved =
                  iand(u.clock_seq_hi_and_reserved,'3f'xn);
                u.clock_seq_hi_and_reserved =
                  ior(u.clock_seq_hi_and_reserved,'80'xn);
             end genguid;
             ......
             
             
            Updated on 2012-09-03T08:30:27Z at 2012-09-03T08:30:27Z by ccw
            • PeterOL
              PeterOL
              9 Posts
              ACCEPTED ANSWER

              Re: GUID: generate in a PL/I program on z/OS

              ‏2012-09-03T10:36:14Z  in response to ccw
               I do see that, the error was fagged first time I did a compile.
              I have now changed the code, but I get a link issue - I have send that to a responsible for our compile/link setup. Thanks for all your help and code. Regards Peter.