ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

open access handler on WORKSTN: mch1202 received after EXFMT

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • open access handler on WORKSTN: mch1202 received after EXFMT

    Hi at all an thanks for accepted me in this forum.

    I'm trying to manage open access handler on workstn files (dspf) on a program that execute only a EXFMT on it.

    I've created a srvpgm with an external procedure that is called by the handler keyword.

    Everything works fine until the control comes back to RPG from SRVPGM called by the EXFMT operation:
    in that procedure the handler service program sets the inputbuffer to simulate input from the user, sets the function key pressed and then returns the control to RPG.

    In that moment the RPG receives MCH1202 on the WORKSTN file (as I can see on debug), no inputbuffer comes back to RPG and got decimal data error.

    I'm really crashing my head, I think that I'm missing something because even reading the DUMP spool I cant find the problem.

    I really appreciate some help please, thanks

    These are some part of code if this can help:


    ON the RPG

    // DSPF definition

    DCL-F DSP066V WORKSTN INFDS(infdsDspf)
    HANDLER('BFZOASP(OASP_OATST01_$BATCH_EXEC)': shared_IO)
    USROPN ALIAS;

    // INFDS definition
    DCL-DS infDsDspf ;
    g0_wstOpen CHAR(1) POS(09) ;
    g0_fKey CHAR(1) POS(369) ;
    g0_wstPosCur BINDEC(4) POS(370)
    ;
    END-DS;


    ON the Handler Service Program

    DCL-DS g_shared_IO LIKEDS(shared_IO) BASED(ptr_Shared_IO) ;

    DCL-DS g_dspf_fld EXTNAME('DSP066V':'FMT06601':*INPUT) QUALIFIED
    BASED(ptr_inp_buffer) ;
    END-DS;

    //-----------------------------------------------------------------------
    DCL-PROC OASP_OATST01_$batch_exec EXPORT ;
    DCL-PI OASP_OATST01_$batch_exec ;
    io LIKEDS(QrnOpenAccess_T) ;
    END-PI;
    //__________________________________________________ ___________________
    ptr_Shared_IO = io.userArea;

    SELECT ;
    WHEN io.rpgOperation = QrnOperation_OPEN;
    DF_log('OPEN del DSPF') ;

    WHEN io.rpgOperation = QrnOperation_CLOSE;
    DF_log('CLOSE del DSPF') ;

    WHEN io.rpgOperation = QrnOperation_EXFMT;
    DF_log('EXFMT del DSPF') ;
    exfmt_operation(io) ;

    OTHER ;
    // Any other operation is unsupported so notify RPG
    io.rpgStatus = 1299; // general error status

    ENDSL;
    //__________________________________________________ ___________________
    END-PROC;

    //
    //-----------------------------------------------------------------------
    DCL-PROC exfmt_operation ;
    DCL-PI exfmt_operation ;
    io LIKEDS(QrnOpenAccess_T) ;
    END-PI;


    DCL-S l_indicators IND DIM(99) BASED(l_ptr_indicators) ;
    DCL-S l_ptr_indicators POINTER INZ ;

    //__________________________________________________ ___________________
    SELECT ;
    WHEN g_shared_IO.i_opzione = F6 ;
    IF g_first_time=*ON ;
    set_inp_fields_to_output(io) ; // Forza i campi a video
    io.functionKey = QrnFunctionKey_09 ; // FORZA F9 PREMUTO
    ELSE;
    // Altrimenti vuol dire che c'è stato un errore
    io.functionKey = QrnFunctionKey_03 ; // quindi FORZA F3
    l_ptr_indicators = io.indara ; // restituisce gli indicatori in output
    g_shared_io.o_indicators = l_indicators ;
    ENDIF;

    ENDSL;

    g_first_time = *OFF ;
    //__________________________________________________ ___________________
    END-PROC;

    //-----------------------------------------------------------------------
    DCL-PROC set_inp_fields_to_output ;
    DCL-PI set_inp_fields_to_output ;
    io LIKEDS(QrnOpenAccess_T) ;
    END-PI;

    DCL-S l_value VARCHAR(32740) BASED(l_ptr_value) ;
    DCL-S l_ptr_value POINTER INZ ;

    // DS di stato Display file
    DCL-DS l_infDsDspf QUALIFIED INZ;
    g0_wstOpen CHAR(1) POS(09) INZ('1');
    g0_fKey CHAR(1) POS(369) ;
    g0_wstPosCur BINDEC(4) POS(370) INZ(5120);
    END-DS;
    //__________________________________________________ ___________________
    ptr_inp_buffer = io.inputBuffer;

    g_dspf_fld.vtipo = g_shared_io.i_buffer.cgtipo ;
    g_dspf_fld.vstato = 'X';

    l_infdsdspf.g0_fkey = F9 ;
    io.deviceFeedback = %ADDR(l_infDsDspf) ;
    io.deviceFeedbackLen = %LEN(l_infDsDspf) ;
    io.ioFeedback = %ADDR(l_infDsDspf) ;
    io.ioFeedbackLen = %LEN(l_infDsDspf) ;
    io.openFeedback = %ADDR(l_infDsDspf) ;
    io.openFeedbackLen = %LEN(l_infDsDspf) ;
    io.inputBuffer = %ADDR(g_dspf_fld) ;
    io.inputBufferlEN = %LEN(g_dspf_fld) ;

    //__________________________________________________ ___________________
    END-PROC;

  • #2
    I'm not sure if there is just a lot of code missing from your example or if you just don't quite understand how OA works.

    For example the DS io is defined by QrnOpenAccess_T and is a qualified DS - but the pointer names you use are not qualified so I don't see how you ever get addressability to the io buffer.

    If you can provide the source of the display file I could duplicate your code and see what I could do with it.

    P.S. Have you looked at Albert York's site ? http://www.albertyork.yolasite.com/samples.php TNAPI may be a better fit for your needs than OA and may perform better. Also Albert's RUNTNSCR may be a good option for you.

    Comment


    • #3
      I'm not sure if there is just a lot of code missing from your example or if you just don't quite understand how OA works.

      For example the DS io is defined by QrnOpenAccess_T and is a qualified DS - but the pointer names you use are not qualified so I don't see how you ever get addressability to the io buffer.

      If you can provide the source of the display file I could duplicate your code and see what I could do with it.

      P.S. Have you looked at Albert York's site ? http://www.albertyork.yolasite.com/samples.php TNAPI may be a better fit for your needs than OA and may perform better. Also Albert's RUNTNSCR may be a good option for you.

      Comment


      • #4
        Thanks for your reply,

        the code that I posted is not all because is too long, I also understand that my problem is difficult to explain, but I assure to you that the io DS is correctly populated and received by the handler service program (debugging the program seems all ok).

        the pointer that I use are not qualified I know that, these are local and global variables on the srvpgm, but the they are valued from the io DS that is qualified, for example:


        in the definition section, there is a global defined qualified DS based on it

        DCL-DS g_dspf_fld EXTNAME('DSP066V':'FMT06601':*INPUT) QUALIFIED

        BASED(ptr_inp_buffer) ;
        END-DS;

        when the supprocedure makes that instruction

        ptr_inp_buffer = io.inputBuffer;

        that uses ptr_inp_buffer that is a global not qualified pointer (I realized that I omitted to post the definition ) that is evaluated with io.input buffer
        so,
        when I'm runnning the program in debug I see the g_dspf_fld DS correctly populated and everything seems work fine, except that when the control comes back to RPG program, that gets decimal data error
        on the DSPF.

        Comment


        • #5
          It's hard to diagnose a problem when you have only a small part of the source code. My brain is not the RPG compiler or RPG runtime... I typically need to be able to compile and run programs to diagnose problems. I can't just look at the code and understand everything that is happening all in my head.

          That said, I do see some big problems in the set_inp_fields_to_output subprocdure! In that procedure you have this:

          Code:
          io.deviceFeedback = %ADDR(l_infDsDspf) ;
          io.deviceFeedbackLen = %LEN(l_infDsDspf) ;
          io.ioFeedback = %ADDR(l_infDsDspf) ;
          io.ioFeedbackLen = %LEN(l_infDsDspf) ;
          io.openFeedback = %ADDR(l_infDsDspf) ;
          io.openFeedbackLen = %LEN(l_infDsDspf) ;
          l_infDsDspf is a structure that is local to the subprocedure. That means it will no longer exist, and it's will memory freed up as soon as the set_inp_fields_to_output subprocedure ends. So saving its address to a pointer isn't a good idea. It will remember that memory address, but the address will be used for other things.

          Comment


          • #6
            Aside from what Scott said, you should not change the pointer subfields in the parameter passed to the handler. When RPG calls the handler, it sets up the pointers in the handler parameter to point to its own storeage for the input buffer etc. After the handler returns to RPG, it will use its own storage to get the information. It will ignore the changed pointers in the handler parameter.

            Instead of changing the pointers in the handler parameter, you have to use the pointers to get access to the storage they are pointing to.

            If you have your own data structure with initialization values, such as your l_infDsDspf data structure, you would define the one in the handler parameter as BASED on the handler pointer, and copy your structure into the one in the handler parameter.

            Comment


            • #7
              -Barbara and Scott, I'm really grateful to both of you for your response.

              i know it's difficult to explain without the full code but I can't give it for security reason at the company where I'm working.
              I will surely use your precious advice to continue to investigate on that issue.
              I hope that i will update this thread with a solution as soon as possibile

              Comment


              • #8
                Hi,

                I found the problem two week ago, It was simply a packed field not set in the input buffer.
                After setting the filed al worked fine.

                Thanks

                Comment

                Working...
                X