dp_msac2.c
上传用户:hualang
上传日期:2022-04-11
资源大小:104k
文件大小:83k
开发平台:

C/C++

  1. /**********************  Filename: dp_msac2.c  *******************************/
  2. /* ========================================================================= */
  3. /*                                                                           */
  4. /* 0000  000   000  00000 0  000  0   0 0 0000                               */
  5. /* 0   0 0  0 0   0 0     0 0   0 0   0 0 0   0                              */
  6. /* 0   0 0  0 0   0 0     0 0     0   0 0 0   0      Einsteinstra遝 6        */
  7. /* 0000  000  0   0 000   0 0     00000 0 0000       91074 Herzogenaurach    */
  8. /* 0     00   0   0 0     0 0     0   0 0 0                                  */
  9. /* 0     0 0  0   0 0     0 0   0 0   0 0 0          Tel: ++49-9132-744-200  */
  10. /* 0     0  0  000  0     0  000  0   0 0 0    GmbH  Fax: ++49-9132-744-204  */
  11. /*                                                                           */
  12. /* ========================================================================= */
  13. /*                                                                           */
  14. /* Function:       interface service routines for msac_c2                    */
  15. /*                                                                           */
  16. /* ------------------------------------------------------------------------- */
  17. /*                                                                           */
  18. /* Technical support:       P. Fredehorst                                    */
  19. /*                          Tel. : ++49-9132/744-214                         */
  20. /*                          Fax. :              -204                         */
  21. /*                          eMail: pfredehorst@profichip.com                 */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24. /*****************************************************************************/
  25. /* contents:
  26.   - function prototypes
  27.   - data structures
  28.   - internal functions
  29. */
  30. /*****************************************************************************/
  31. /* include hierarchy */
  32. #include "..dp_incplatform.h"
  33. #include "..dp_incdp_inc.h"
  34. //#include "E5_Inc.h"
  35. #ifdef DP_MSAC_C2
  36. /*---------------------------------------------------------------------------*/
  37. /* global msac2 data definitions                                             */
  38. /*---------------------------------------------------------------------------*/
  39. typedef struct
  40. {
  41.     UBYTE                   read_rec_ptr;
  42.     UBYTE                   write_rec_ptr;
  43.     UBYTE                   start_rec_ptr;                      // first element of receive queue
  44.     UBYTE                   end_rec_ptr;                        // last  element of receive queue
  45.     UBYTE                   num_sap;
  46.     UBYTE                   pdu_len;
  47.     UWORD                   poll_time;
  48.     UBYTE                   enabled;
  49.     UBYTE                   close_channel_request;              // memory item for close_channel request of the user,
  50.                                                                 // used to reject a double request
  51.     MSAC_C2_REC_QUEUE_PTR   act_rec_ptr;
  52.     MSAC_C2_REC_QUEUE       rec_queue[MSAC_C2_MAX_INPUT_ITEMS];
  53.     MSAC_C2_CONNECT_ITEM    connection_list[DP_C2_NUM_SAPS];    // list of connection-descriptions
  54.     MSAC_C2_RES_IND_QUEUE   reserve_buffer[DP_C2_NUM_SAPS];     // array of reserve data buffer to realize a disconnect pdu
  55.     MSAC_C2_TIMER           timer_list[ DP_C2_NUM_SAPS ];
  56. } MSAC2_STRUC;
  57. SECTION_DEF_CommuData static MSAC2_STRUC msac_c2[MAX_DEV_NUM];
  58. /*---------------------------------------------------------------------------*/
  59. /* function prototypes                                                       */
  60. /*---------------------------------------------------------------------------*/
  61. void  msac_c2_realize_ind_recv(UBYTE dev_num,MSAC_C2_CONNECT_ITEM_PTR connection_ptr, UBYTE sap_nr);
  62. void  msac_c2_send_response_data (UBYTE dev_num,MSAC_C2_CONNECT_ITEM_PTR connection_ptr);
  63. void  msac_c2_call_ind_await (UBYTE dev_num,MSAC_C2_CONNECT_ITEM_PTR connection_ptr);
  64. void  msac_c2_resp_pdu_provide(UBYTE dev_num,UBYTE sap_nr, MSAC_C2_DATA_BUF_PTR buf_ptr);
  65. void  msac_c2_pdu_provide(UBYTE dev_num,UBYTE sap_nr, MSAC_C2_DATA_BUF_PTR buf_ptr);
  66. void  msac_c2_handle_user_response (UBYTE dev_num,MSAC_C2_CONNECT_ITEM_PTR connection_ptr);
  67. void  msac_c2_create_disconnect_pdu(UBYTE dev_num,MSAC_C2_CONNECT_ITEM_PTR connection_ptr, MSAC2_DIRECTION direction);
  68. void  msac_c2_realize_resp_sent(UBYTE dev_num,MSAC_C2_CONNECT_ITEM_PTR connection_ptr, UBYTE sap_nr);
  69. void  msac_c2_realize_ind_disable_done(UBYTE dev_num,MSAC_C2_CONNECT_ITEM_PTR connection_ptr, UBYTE sap_nr);
  70. void  msac_c2_confirm_close_request(UBYTE dev_num,MSAC_C2_CONNECT_ITEM_PTR connection_ptr);
  71. void  msac_c2_dc_user_indication(UBYTE dev_num,MSAC_C2_CONNECT_ITEM_PTR connection_ptr);
  72. void  msac_c2_close_channel (UBYTE dev_num);
  73. UBYTE msac_c2_start_timer(UBYTE dev_num, UBYTE timer_index, UWORD timer_value );
  74. UBYTE msac_c2_stop_timer(UBYTE dev_num, UBYTE timer_index );
  75. /*---------------------------------------------------------------------------*/
  76. /*                                                                           */
  77. /*   void msac_c2_process(UBYTE dev_num)                                              */
  78. /*                                                                           */
  79. /*   function:     main program of MSAC_C2                                   */
  80. /*                                                                           */
  81. /*---------------------------------------------------------------------------*/
  82. SECTION_DEF_CommuCode void msac_c2_process(UBYTE dev_num)
  83. {
  84. MSAC_C2_CONNECT_ITEM_PTR    connection_ptr;
  85. UBYTE                       sap_nr;
  86. UBYTE                       cn_id;
  87. #ifdef DP_MSAC_C2_Time
  88. UBYTE                       i;
  89. #endif//#ifdef DP_MSAC_C2_Time
  90.     // check, if MSAC_C2 functions enabled
  91.     if( msac_c2[dev_num].enabled )
  92.     {
  93.         // handle receive queue
  94.         while( msac_c2[dev_num].read_rec_ptr != msac_c2[dev_num].write_rec_ptr )
  95.         {
  96.             // check cn_id
  97.             msac_c2[dev_num].act_rec_ptr = &(msac_c2[dev_num].rec_queue[msac_c2[dev_num].read_rec_ptr]);
  98.             sap_nr = msac_c2[dev_num].act_rec_ptr->sap_nr&0xff;//2009.11.7
  99.             if(( sap_nr > MSAC_C2_SAP_NR_HIGH)||((MSAC_C2_SAP_NR_HIGH - sap_nr) >=  msac_c2[dev_num].num_sap))
  100.             {
  101.                 vpc3_errcb[dev_num].error_code = msac_c2[dev_num].act_rec_ptr->fdl_code;
  102.                 vpc3_errcb[dev_num].cn_id      = sap_nr;
  103.                 // *** no further action of dpv1/c2 ***
  104.                 fatal_error(dev_num,_DP_C2, __LINE__, &vpc3_errcb[dev_num]);
  105.             }
  106.             else
  107.             {
  108.                 cn_id = MSAC_C2_SAP_NR_HIGH - sap_nr;
  109.                 if(cn_id >= DP_C2_NUM_SAPS)
  110.                 {
  111.                     vpc3_errcb[dev_num].error_code = msac_c2[dev_num].act_rec_ptr->fdl_code;
  112.                     vpc3_errcb[dev_num].cn_id      = cn_id;
  113.                     // *** no further action of dpv1/c2 ***
  114.                     fatal_error(dev_num,_DP_C2, __LINE__, &vpc3_errcb[dev_num]);
  115.                 }
  116.                 else
  117.                 {
  118.                     // determine pointer of connection description
  119.                     connection_ptr = &(msac_c2[dev_num].connection_list[cn_id]);
  120.                     switch(msac_c2[dev_num].act_rec_ptr->fdl_code)
  121.                     {
  122.                         case MSAC_C2_IND_RECV:
  123.                         {
  124.                             msac_c2_realize_ind_recv(dev_num,connection_ptr, sap_nr);
  125.                             break;
  126.                         }
  127.                         case MSAC_C2_RESP_SENT:
  128.                         {
  129.                             msac_c2_realize_resp_sent(dev_num,connection_ptr, sap_nr);
  130.                             break;
  131.                         }
  132.                         case MSAC_C2_IND_DISABLE_DONE:
  133.                         {
  134.                             msac_c2_realize_ind_disable_done(dev_num,connection_ptr, sap_nr);
  135.                             break;
  136.                         }
  137.                         default:
  138.                         {
  139.                             vpc3_errcb[dev_num].error_code = msac_c2[dev_num].act_rec_ptr->fdl_code;
  140.                             // *** no further action of dpv1/c2 ***
  141.                             fatal_error(dev_num,_DP_C2, __LINE__, &vpc3_errcb[dev_num]);
  142.                             break;
  143.                         }
  144.                     }// switch (msac_c2_input_read_ptr->fdl_code)
  145.                 }//else
  146.             }//else
  147.             if(msac_c2[dev_num].read_rec_ptr != msac_c2[dev_num].end_rec_ptr)
  148.             {
  149.                 msac_c2[dev_num].read_rec_ptr++;
  150.             }
  151.             else
  152.             {
  153.                 msac_c2[dev_num].read_rec_ptr = msac_c2[dev_num].start_rec_ptr;
  154.             }
  155.         }//while( msac_c2[dev_num].read_rec_ptr != msac_c2[dev_num].write_rec_ptr )
  156.         #ifdef DP_MSAC_C2_Time
  157.             //check timer
  158.             for(i = 0; i < DP_C2_NUM_SAPS; i++)
  159.             {
  160.                 if( msac_c2[dev_num].connection_list[i].state != MSAC_C2_CS_CLOSE_CHANNEL ) //sign of free element
  161.                 {
  162.                     if( msac_c2[dev_num].connection_list[i].timer_active == TRUE )
  163.                     {
  164.                         // determine pointer of connection description
  165.                         connection_ptr = &(msac_c2[dev_num].connection_list[i]);
  166.                         if( msac_c2[dev_num].timer_list[connection_ptr->timer_id].running == FALSE )
  167.                         {
  168.                             //reset PCNTRL_RESP bit
  169.                             fdl_reset_pcntrl_resp_bit(dev_num,connection_ptr->sap_nr, FDL_PRIMARY_BUF);
  170.                             connection_ptr->timer_break = TRUE;
  171.                             //disable timer
  172.                             connection_ptr->timer_active = FALSE;
  173.                             //new description state
  174.                             connection_ptr->state = MSAC_C2_CS_PROVIDE_RESP;
  175.                             //set recognized-flag of user_break
  176.                             connection_ptr->user_break = MSAC_C2_UB_BREAK;
  177.                             connection_ptr->error_code = MSAC_C2_EC_REQ_TIMEOUT;
  178.                             //handle request pdu as disconnect-pdu
  179.                             msac_c2_create_disconnect_pdu(dev_num,connection_ptr, MSAC_C2_REQ_DIRECTION);
  180.                             //give the disconnect information to the user
  181.                             msac_c2_pdu_provide(dev_num,sap_nr, connection_ptr->buf_ptr_res);
  182.                             //handle pdu as disconnect-pdu
  183.                             msac_c2_create_disconnect_pdu(dev_num,connection_ptr, MSAC_C2_RESP_DIRECTION);
  184.                             msac_c2_send_response_data(dev_num,connection_ptr);
  185.                         }//if( msac_c2[dev_num].timer_list[connection_ptr->timer_id].running == FALSE )
  186.                     }//if( msac_c2[dev_num].connection_list[i].timer_active == TRUE )
  187.                 }//if( msac_c2[dev_num].connection_list[i].state != MSAC_C2_CS_CLOSE_CHANNEL )
  188.             }//for(i = 0; i < DP_C2_NUM_SAPS; i++)
  189.         #endif//#ifdef DP_MSAC_C2_Time
  190.     }//if( msac_c2[dev_num].enabled )
  191. }//void msac_c2_process(UBYTE dev_num)
  192. /*---------------------------------------------------------------------------*/
  193. /*                                                                           */
  194. /*   void msac_c2_pdu_provide(UBYTE dev_num,UBYTE sap_nr, MSAC_C2_DATA_BUF_PTR buf_ptr)    */
  195. /*                                                                           */
  196. /*   function:                                                               */
  197. /*                                                                           */
  198. /*---------------------------------------------------------------------------*/
  199. SECTION_DEF_CommuCode void msac_c2_pdu_provide(UBYTE dev_num, UBYTE sap_nr, MSAC_C2_DATA_BUF_PTR buf_ptr )
  200. {
  201. DPV1_PTR        dpv1_ptr;
  202. UBYTE           data_opc;
  203. DPV1_RET_VAL    ret_val;
  204.     // determine pointer of indication netto data
  205.     dpv1_ptr = (DPV1_PTR) &(buf_ptr->user_data[0]);
  206.     data_opc = dpv1_ptr->read.function_num & MSAC_C2_FN_MASK;
  207.     switch( data_opc )
  208.     {
  209.         case MSAC_C2_FN_DS_READ:
  210.         {
  211.             if( (BFWORD2BYTE(dpv1_ptr->read.length) > 0) && (BFWORD2BYTE(dpv1_ptr->read.length) <=240) && (BFWORD2BYTE(buf_ptr->data_len)) )
  212.             {
  213.                 ret_val = user_dpv1_read_req(dev_num,sap_nr,dpv1_ptr);
  214.             }//if( (dpv1_ptr->read.length > 0) && (dpv1_ptr->read.length <=240) )
  215.             else
  216.             {
  217.                 dpv1_ptr->neg.err_code1 = DPV1_ERRCL_ACCESS | DPV1_ERRCL_ACC_TYPE;
  218.                 dpv1_ptr->neg.err_code2 = 0x00;
  219.                 ret_val = DPV1_NOK;
  220.             }//else of if( (dpv1_ptr->read.length > 0) && (dpv1_ptr->read.length <=240) )
  221.             break;
  222.         }//case MSAC_C2_FN_DS_READ:
  223.         case MSAC_C2_FN_DS_WRITE:
  224.         {
  225.             if( BFWORD2BYTE(dpv1_ptr->write.length) > 0 )
  226.             {
  227.                 ret_val = user_dpv1_write_req(dev_num,sap_nr,dpv1_ptr);
  228.             }//if( dpv1_ptr->write.length > 0 )
  229.             else
  230.             {
  231.                 dpv1_ptr->neg.err_code1 = DPV1_ERRCL_ACCESS | DPV1_ERRCL_ACC_TYPE;
  232.                 dpv1_ptr->neg.err_code2 = 0x00;
  233.                 ret_val = DPV1_NOK;
  234.             }//else of if( dpv1_ptr->write.length > 0 )
  235.             break;
  236.         }//case MSAC_C2_FN_DS_WRITE:
  237.         case MSAC_C2_FN_DATA:
  238.         {
  239.             if( BFWORD2BYTE(dpv1_ptr->transport.length) > 0 )
  240.             {
  241.                 ret_val = user_c2_data_transport_req(dev_num,sap_nr,dpv1_ptr);
  242.             }//if( dpv1_ptr->transport.length > 0 )
  243.             else
  244.             {
  245.                 dpv1_ptr->neg.err_code1 = DPV1_ERRCL_ACCESS | DPV1_ERRCL_ACC_TYPE;
  246.                 dpv1_ptr->neg.err_code2 = 0x00;
  247.                 ret_val = DPV1_NOK;
  248.             }//else of if( dpv1_ptr->transport.length > 0 )
  249.             break;
  250.         }//case MSAC_C2_FN_DATA:
  251.         case MSAC_C2_FN_CONNECT:
  252.         {
  253.             ret_val = user_c2_initiate_req(dev_num,sap_nr,dpv1_ptr);
  254.             break;
  255.         }//case MSAC_C2_FN_CONNECT:
  256.         case MSAC_C2_FN_DISCONNECT:
  257.         {
  258.             ret_val = user_c2_abort_ind(dev_num,sap_nr,dpv1_ptr);
  259.             if( ret_val != DPV1_OK)
  260.             {
  261.                 vpc3_errcb[dev_num].error_code = data_opc;
  262.                 vpc3_errcb[dev_num].cn_id      = sap_nr;
  263.                 // *** no further action of dpv1/c2 ***
  264.                 fatal_error(dev_num,_DP_C2, __LINE__, &vpc3_errcb[dev_num]);
  265.             }//if( ret_val != DPV1_OK)
  266.             ret_val = DPV1_DELAY;  // ABORT-function always do nothing
  267.             break;
  268.         }//case MSAC_C2_FN_DISCONNECT:
  269.         default:
  270.         {
  271.             // Error unknown service
  272.             vpc3_errcb[dev_num].error_code = data_opc;
  273.             vpc3_errcb[dev_num].cn_id      = sap_nr;
  274.             // *** no further action of dpv1/c2 ***
  275.             fatal_error(dev_num,_DP_C2, __LINE__, &vpc3_errcb[dev_num]);
  276.             break;
  277.         }//default:
  278.     }//switch( data_opc )
  279.     switch( ret_val )
  280.     {
  281.         case DPV1_OK:
  282.         {
  283.             if( data_opc == MSAC_C2_FN_CONNECT )
  284.             {
  285.                 buf_ptr->data_len = MSAC_C2_LEN_INITIATE_RES_HEAD + BFWORD2BYTE(dpv1_ptr->initiate_res.s_len) + BFWORD2BYTE(dpv1_ptr->initiate_res.d_len);
  286.             }//if( data_opc == MSAC_C2_FN_CONNECT )
  287.             else
  288.             {
  289.                 if( data_opc == MSAC_C2_FN_DS_WRITE )
  290.                 {
  291.                     buf_ptr->data_len = DPV1_LEN_HEAD_DATA;
  292.                 }//if( data_opc == MSAC_C2_FN_DS_WRITE )
  293.                 else // for READ andd TRANSPORT length is defined by userdata
  294.                 {
  295.                     buf_ptr->data_len = BFWORD2BYTE(dpv1_ptr->read.length) + DPV1_LEN_HEAD_DATA;
  296.                 }//else of if( data_opc == MSAC_C2_FN_DS_WRITE )
  297.             }//else of if( data_opc == MSAC_C2_FN_CONNECT )
  298.             msac_c2_resp_pdu_provide(dev_num,sap_nr,buf_ptr);
  299.             break;
  300.         }//case DPV1_OK:
  301.         case DPV1_NOK:
  302.         {
  303.             //user must create correct response-pdu
  304.             buf_ptr->data_len = DPV1_LEN_NEG_RESPONSE;
  305.             dpv1_ptr->neg.function_num |= DPV1_ERROR_BIT_RESPONSE;
  306.             dpv1_ptr->neg.err_decode = DPV1_ERRDC_DPV1;  /* always fixed */
  307.             msac_c2_resp_pdu_provide(dev_num,sap_nr,buf_ptr);
  308.             break;
  309.         }//case DPV1_NOK:
  310.         case DPV1_DELAY:
  311.         {
  312.             // do nothing
  313.             break;
  314.         }//case DPV1_DELAY:
  315.         case DPV1_ABORT:
  316.         {
  317.             buf_ptr->data_len = MSAC_C2_LEN_DISCONNECT_PDU-1;
  318.             dpv1_ptr->abort.function_num = MSAC_C2_FN_DISCONNECT | MSAC_C2_FUNCTION_NUM_EXTENSION;
  319.             msac_c2_resp_pdu_provide(dev_num,sap_nr,buf_ptr);
  320.             break;
  321.         }//case DPV1_ABORT:
  322.         default:
  323.         {
  324.             vpc3_errcb[dev_num].error_code = ret_val;
  325.             vpc3_errcb[dev_num].cn_id      = sap_nr;
  326.             // *** no further action of dpv1/c2 ***
  327.             fatal_error(dev_num,_DP_C2, __LINE__, &vpc3_errcb[dev_num]);
  328.             break;
  329.         }//default:
  330.     }//switch( ret_val )
  331. }//void msac_c2_pdu_provide(UBYTE dev_num, UBYTE sap_nr, MSAC_C2_DATA_BUF_PTR buf_ptr )
  332. /*---------------------------------------------------------------------------*/
  333. /*                                                                           */
  334. /*   void msac_c2_realize_ind_recv(UBYTE dev_num,MSAC_C2_CONNECT_ITEM_PTR connection_ptr,  */
  335. /*                                 UBYTE                    sap_nr)          */
  336. /*                                                                           */
  337. /*   function:          MSAC_C2 received a request-pdu.                      */
  338. /*                      Depend on the opcode                                 */
  339. /*                       - the pdu is given to the user                      */
  340. /*                         (DATA, DISCONNECT),                               */
  341. /*                       - a response is provided (IDLE),                    */
  342. /*                       - a new connection is initialized (CONNECT).        */
  343. /*                                                                           */
  344. /*---------------------------------------------------------------------------*/
  345. SECTION_DEF_CommuCode void msac_c2_realize_ind_recv(UBYTE dev_num, MSAC_C2_CONNECT_ITEM_PTR connection_ptr, UBYTE sap_nr )
  346. {
  347. union
  348. {
  349.   MSAC_C2_CR_BUF_PTR            data_ptr;
  350.   MSAC_C2_INITIATE_REQ_PDU_PTR  initiate_req;
  351. }pdu;
  352. MSAC_C2_DATA_BUF_PTR            buf_ptr = msac_c2[dev_num].act_rec_ptr->buf_ptr;
  353. UBYTE                           timer_ret;
  354. UWORD                           poll_time_out;
  355. UBYTE                           data_opc;
  356. UBYTE                           cn_id = connection_ptr->cn_id;
  357. UBYTE                           initiate_s_d_len;
  358.     //determine pointer of indication netto data
  359.     pdu.data_ptr = (MSAC_C2_CR_BUF_PTR) &(buf_ptr->user_data[0]);
  360.     data_opc = pdu.data_ptr->opcode & MSAC_C2_FN_MASK;
  361.     //taking over opcode and buf_ptr into connection description
  362.     connection_ptr->opcode  = data_opc;
  363.     connection_ptr->buf_ptr = buf_ptr;
  364.     switch( connection_ptr->state )
  365.     {
  366.         // state after initialization
  367.         case MSAC_C2_CS_AWAIT_CONNECT:
  368.         {
  369.             //taking over opcode and buf_ptr into connection description
  370.             //connection_ptr->opcode = data_opc;
  371.             //connection_ptr->buf_ptr = buf_ptr;
  372.             // reset saved informations of msac_c2_disconnect(dev_num)
  373.             connection_ptr->dr_reason_code = 0x00;
  374.             connection_ptr->dr_location = 0x00;
  375.             // set init value of error_code
  376.             connection_ptr->error_code = MSAC_C2_EC_OK;
  377.             // reset timer
  378.             msac_c2[dev_num].timer_list[connection_ptr->timer_id].time_act = 0x0000;
  379.             msac_c2[dev_num].timer_list[connection_ptr->timer_id].running  = FALSE;
  380.             connection_ptr->timer_break = FALSE;
  381.             // s_len and d_len, must be correct set, if S/D-Typ is defined
  382.             initiate_s_d_len = 0;
  383.             initiate_s_d_len += (BFWORD2BYTE(pdu.initiate_req->s_type) == 0 ) ? 2 : BFWORD2BYTE(pdu.initiate_req->s_len);
  384.             initiate_s_d_len += (BFWORD2BYTE(pdu.initiate_req->d_type) == 0 ) ? 2 : BFWORD2BYTE(pdu.initiate_req->d_len);
  385.             if( data_opc != MSAC_C2_FN_CONNECT )
  386.             {
  387.                 //changed V302 PNO testcase, wrong function number
  388.                 connection_ptr->state = MSAC_C2_CS_PROVIDE_RESP;
  389.                 connection_ptr->poll_time_out = msac_c2[dev_num].poll_time;
  390.                 //changed for Testcase RM11
  391.                 connection_ptr->error_code = MSAC_C2_EC_REMOTE_ERROR;
  392.                 //create disconnect pdu */
  393.                 msac_c2_create_disconnect_pdu(dev_num,connection_ptr, MSAC_C2_RESP_DIRECTION);
  394.                 msac_c2_send_response_data(dev_num,connection_ptr);
  395.                 //manipulate the item of timer_break, because
  396.                 //msac_c2_send_response_data(dev_num) was called without
  397.                 //a previous MSAC_C2_START_TIMER
  398.                 connection_ptr->timer_break = FALSE;
  399.                 connection_ptr->state = MSAC_C2_CS_DISABLE_CONNECT;
  400.                 fdl_ind_disable(dev_num,sap_nr); //close SAP, answer POLL request with RS
  401.             }//if( data_opc != MSAC_C2_FN_CONNECT )
  402.             else
  403.             if(    ( (BFWORD2BYTE(pdu.initiate_req->s_type) == 0) && ( BFWORD2BYTE(pdu.initiate_req->s_len) != 2 ) )
  404.                 || ( (BFWORD2BYTE(pdu.initiate_req->d_type) == 0) && ( BFWORD2BYTE(pdu.initiate_req->d_len) != 2 ) )
  405.               )
  406.             {
  407.                 connection_ptr->state = MSAC_C2_CS_PROVIDE_RESP;
  408.                 connection_ptr->poll_time_out = msac_c2[dev_num].poll_time;
  409.                 //changed for Testcase RM11
  410.                 connection_ptr->error_code = MSAC_C2_EC_REMOTE_ERROR;
  411.                 //create disconnect pdu
  412.                 msac_c2_create_disconnect_pdu(dev_num,connection_ptr, MSAC_C2_RESP_DIRECTION);
  413.                 msac_c2_send_response_data(dev_num,connection_ptr);
  414.                 //manipulate the item of timer_break, because
  415.                 //msac_c2_send_response_data(dev_num) was called without
  416.                 //a previous MSAC_C2_START_TIMER
  417.                 connection_ptr->timer_break = FALSE;
  418.             }//else if( (buf_ptr->data_len <  MSAC_C2_MIN_CR_PDU_SIZE) || ...
  419.             else if( (BFWORD2BYTE(buf_ptr->data_len) <  MSAC_C2_MIN_CR_PDU_SIZE) ||
  420.                      (BFWORD2BYTE(buf_ptr->data_len) <  MSAC_C2_MIN_CR_PDU_SIZE -4 + initiate_s_d_len)  )
  421.             {
  422.                 connection_ptr->state = MSAC_C2_CS_PROVIDE_RESP;
  423.                 connection_ptr->poll_time_out = msac_c2[dev_num].poll_time;
  424.                 //changed for Testcase RM11
  425.                 connection_ptr->error_code = MSAC_C2_EC_INV_S_D_LEN_ERR;
  426.                 //create disconnect pdu
  427.                 msac_c2_create_disconnect_pdu(dev_num,connection_ptr, MSAC_C2_RESP_DIRECTION);
  428.                 msac_c2_send_response_data(dev_num,connection_ptr);
  429.                 //manipulate the item of timer_break, because
  430.                 //msac_c2_send_response_data(dev_num) was called without
  431.                 //a previous MSAC_C2_START_TIMER
  432.                 connection_ptr->timer_break = FALSE;
  433.             }//else if( (buf_ptr->data_len <  MSAC_C2_MIN_CR_PDU_SIZE) || ...
  434.             else
  435.             {
  436.                 //connect-pdu
  437.                 //handle poll_timeout
  438.                 #ifdef LITTLE_ENDIAN
  439.                     poll_time_out = BFLONG2WORD(pdu.data_ptr->poll_time_out);
  440.                 #else
  441.                     poll_time_out = BFLONG2WORD(SWAP_LONG(pdu.data_ptr->poll_time_out ));
  442.                 #endif
  443. // TRACE("Pooltimeout: %d", poll_time_out);
  444.                 if( msac_c2[dev_num].poll_time > poll_time_out )
  445.                 {
  446.                     poll_time_out = msac_c2[dev_num].poll_time;
  447.                 }//if( msac_c2[dev_num].poll_time > poll_time_out )
  448.                 connection_ptr->poll_time_out = poll_time_out;
  449.                 timer_ret = msac_c2_start_timer(dev_num,connection_ptr->timer_id, poll_time_out);
  450.                 if( timer_ret != MSAC_C2_TIMER_OK )
  451.                 {
  452.                     vpc3_errcb[dev_num].error_code = timer_ret;
  453.                     vpc3_errcb[dev_num].cn_id      = cn_id;
  454.                     // *** no further action of dpv1/c2 ***
  455.                     fatal_error(dev_num,_DP_C2, __LINE__, &vpc3_errcb[dev_num]);
  456.                 }//if( timer_ret != MSAC_C2_TIMER_OK )
  457.                 else
  458.                 {
  459.                     // set connection state
  460.                     connection_ptr->state = MSAC_C2_CS_PROVIDE_IND;
  461.                     msac_c2_pdu_provide(dev_num,sap_nr, buf_ptr);
  462.                     connection_ptr->timer_active = TRUE;
  463.                 }//else of if( timer_ret != MSAC_C2_TIMER_OK )
  464.             }//else of if( data_opc != MSAC_C2_FN_CONNECT )
  465.             break;
  466.         }//case MSAC_C2_CS_AWAIT_CONNECT:
  467.         // state after successfully intiate indication
  468.         case MSAC_C2_CS_AWAIT_IND:
  469.         {
  470.             // Check PollTimeOut
  471.             timer_ret = msac_c2_start_timer(dev_num,connection_ptr->timer_id, connection_ptr->poll_time_out);
  472.             //There was a poll_time_out. The timeout-request
  473.             //is behind this request in the input queue.
  474.             //This subject is without importance in this case.
  475.             if( timer_ret == MSAC_C2_TIMER_OK )
  476.             {
  477.                 connection_ptr->timer_break = TRUE;
  478.             }//if( timer_ret == MSAC_C2_TIMER_OK )
  479.             if( data_opc == MSAC_C2_FN_DISCONNECT )
  480.             {
  481.                 //disable timer
  482.                 connection_ptr->timer_active = FALSE;
  483.                 if(connection_ptr->user_break != MSAC_C2_UB_NO_BREAK)
  484.                 {
  485.                     // set recognized-flag of user_break
  486.                     connection_ptr->user_break = MSAC_C2_UB_BREAK;
  487.                 }
  488.                 else
  489.                 {
  490.                     connection_ptr->error_code = MSAC_C2_EC_DC_BY_MASTER;
  491.                     // create dr pdu in reserved buffer
  492.                     msac_c2_create_disconnect_pdu(dev_num,connection_ptr, MSAC_C2_REQ_DIRECTION);
  493.                     // disconnet to user always by buf_ptr_res
  494.                     msac_c2_pdu_provide(dev_num,sap_nr , connection_ptr->buf_ptr_res);
  495.                 }
  496.                 connection_ptr->state = MSAC_C2_CS_DISABLE_CONNECT;
  497.                 fdl_ind_disable(dev_num,sap_nr);
  498.             }//if( data_opc == MSAC_C2_FN_DISCONNECT )
  499.             else
  500.             {
  501.                 // data_opc != DPV2_FN_DISCONNECT
  502.                 #ifdef DP_MSAC_C2_Time
  503.                     if(    (connection_ptr->user_break != MSAC_C2_UB_NO_BREAK)
  504.                         || (connection_ptr->timer_break == TRUE           )   )
  505.                 #else
  506.                     if(    (connection_ptr->user_break != MSAC_C2_UB_NO_BREAK)   )
  507.                 #endif //#ifdef DP_MSAC_C2_Time
  508.                     {
  509.                         //disable timer
  510.                         connection_ptr->timer_active = FALSE;
  511.                         //new description state */
  512.                         connection_ptr->state = MSAC_C2_CS_PROVIDE_RESP;
  513.                         //set recognized-flag of user_break */
  514.                         connection_ptr->user_break = MSAC_C2_UB_BREAK;
  515.                         if( connection_ptr->timer_break == TRUE )
  516.                         {
  517.                             connection_ptr->error_code = MSAC_C2_EC_REQ_TIMEOUT;
  518.                             //handle request pdu as disconnect-pdu */
  519.                             msac_c2_create_disconnect_pdu(dev_num,connection_ptr, MSAC_C2_REQ_DIRECTION);
  520.                             //give the disconnect information to the user */
  521.                             msac_c2_pdu_provide(dev_num,sap_nr, connection_ptr->buf_ptr_res);
  522.                         }//if( connection_ptr->timer_break == TRUE )
  523.                         else
  524.                         {
  525.                             connection_ptr->error_code = MSAC_C2_EC_DC_BY_USER;
  526.                         }//else of if( connection_ptr->timer_break == TRUE )
  527.                         //handle pdu as disconnect-pdu */
  528.                         msac_c2_create_disconnect_pdu(dev_num,connection_ptr, MSAC_C2_RESP_DIRECTION);
  529.                         msac_c2_send_response_data(dev_num,connection_ptr);
  530.                     }//if(    (connection_ptr->user_break != MSAC_C2_UB_NO_BREAK)
  531.                     else
  532.                     {
  533.                         //no user break
  534.                         if( data_opc == MSAC_C2_FN_IDLE )
  535.                         {
  536.                             //handle response data */
  537.                             connection_ptr->state = MSAC_C2_CS_PROVIDE_RESP;
  538.                             msac_c2_send_response_data(dev_num,connection_ptr);
  539.                         }//if( data_opc == MSAC_C2_FN_IDLE )
  540.                         else
  541.                         {
  542.                             timer_ret = msac_c2_start_timer(dev_num,connection_ptr->timer_id, connection_ptr->poll_time_out);
  543.                             //There was a request_time_out. The timeout-request */
  544.                             //is behind this request in the input queue.        */
  545.                             //Set a note and reject later the timeout-request.  */
  546.                             if( timer_ret == MSAC_C2_TIMER_OK )
  547.                             {
  548.                                 connection_ptr->timer_break = TRUE;  //DP_TRUE
  549.                             }//if( timer_ret == MSAC_C2_TIMER_OK )
  550.                             switch( data_opc )
  551.                             {
  552.                                 case MSAC_C2_FN_DATA:
  553.                                 case MSAC_C2_FN_DS_READ:
  554.                                 case MSAC_C2_FN_DS_WRITE:
  555.                                 {
  556.                                     //save buf_ptr */
  557.                                     //connection_ptr->buf_ptr = buf_ptr;
  558.                                     //new description state */
  559.                                     connection_ptr->state = MSAC_C2_CS_PROVIDE_IND;
  560.                                     msac_c2_pdu_provide(dev_num,sap_nr, buf_ptr);
  561.                                     break;
  562.                                 }//case MSAC_C2_FN_DATA:
  563.                                 default:
  564.                                 {
  565.                                     //invalid opc
  566.                                     //set error code
  567.                                     connection_ptr->error_code = MSAC_C2_EC_REMOTE_ERROR;
  568.                                     //handle request pdu as disconnect-pdu
  569.                                     msac_c2_create_disconnect_pdu(dev_num,connection_ptr, MSAC_C2_REQ_DIRECTION);
  570.                                     //give the disconnect information to the user
  571.                                     msac_c2_pdu_provide(dev_num,sap_nr, connection_ptr->buf_ptr_res);
  572.                                     //msac_c2_pdu_provide(dev_num,sap_nr, connection_ptr->buf_ptr);
  573.                                     //handle response pdu as disconnect-pdu
  574.                                     msac_c2_create_disconnect_pdu(dev_num,connection_ptr, MSAC_C2_RESP_DIRECTION);
  575.                                     //new description state
  576.                                     connection_ptr->state = MSAC_C2_CS_PROVIDE_RESP;
  577.                                     msac_c2_send_response_data(dev_num,connection_ptr);
  578.                                     break;
  579.                                 }//default:
  580.                             }//switch( data_opc )
  581.                         }//else of if( data_opc == MSAC_C2_FN_IDLE )
  582.                     }//else of if(    (connection_ptr->user_break != MSAC_C2_UB_NO_BREAK)
  583.             }//else of if( data_opc == MSAC_C2_FN_DISCONNECT )
  584.             break;
  585.         }//case MSAC_C2_CS_AWAIT_IND:
  586.         case MSAC_C2_CS_PROVIDE_RESP:
  587.         {
  588.             //V302; special behavior for Testcase 2C6
  589.             if( data_opc == MSAC_C2_FN_DISCONNECT )
  590.             {
  591.                 connection_ptr->timer_active = FALSE;
  592.                 connection_ptr->error_code = MSAC_C2_EC_DC_BY_MASTER;
  593.                 // create dr pdu in reserved buffer
  594.                 msac_c2_create_disconnect_pdu(dev_num,connection_ptr, MSAC_C2_REQ_DIRECTION);
  595.                 // disconnet to user always by buf_ptr_res
  596.                 msac_c2_pdu_provide(dev_num,sap_nr , connection_ptr->buf_ptr_res);
  597.                 connection_ptr->state = MSAC_C2_CS_DISABLE_CONNECT;
  598.                 fdl_ind_disable(dev_num,sap_nr);
  599.             }//if( data_opc == MSAC_C2_FN_DISCONNECT )
  600.             break;
  601.         }//case MSAC_C2_CS_PROVIDE_RESP:
  602.         //not allowed here
  603.         case MSAC_C2_CS_DISABLE_CONNECT:
  604.         case MSAC_C2_CS_CLOSE_CHANNEL:
  605.         case MSAC_C2_CS_PROVIDE_IND:
  606.         default:
  607.         {
  608.             vpc3_errcb[dev_num].error_code = connection_ptr->state;
  609.             vpc3_errcb[dev_num].cn_id      = cn_id;
  610.             // *** no further action of dpv1/c2 ***
  611.             fatal_error(dev_num,_DP_C2, __LINE__, &vpc3_errcb[dev_num]);
  612.             break;
  613.         }//default
  614.     }//switch( connection_ptr->state )
  615. }//void msac_c2_realize_ind_recv(UBYTE dev_num, MSAC_C2_CONNECT_ITEM_PTR connection_ptr, UBYTE sap_nr )
  616. /*---------------------------------------------------------------------------*/
  617. /*                                                                           */
  618. /* msac_c2_realize_resp_sent(UBYTE dev_num,MSAC_C2_CONNECT_ITEM_PTR connection_ptr,        */
  619. /*                           UBYTE sap_nr )                                  */
  620. /*                                                                           */
  621. /*   function: A response pdu was sent to the master. Gives the              */
  622. /*             confirmation to the user and realizes the timer handling.     */
  623. /*                                                                           */
  624. /*---------------------------------------------------------------------------*/
  625. SECTION_DEF_CommuCode void msac_c2_realize_resp_sent(UBYTE dev_num, MSAC_C2_CONNECT_ITEM_PTR connection_ptr, UBYTE sap_nr )
  626. {
  627. UBYTE  timer_ret;
  628. UBYTE  cn_id = connection_ptr->cn_id;
  629. UBYTE  opc = connection_ptr->opcode;
  630. UBYTE  no_action = FALSE;
  631. UBYTE  fatal_state = FALSE;
  632.     //check return value
  633.     if( msac_c2[dev_num].act_rec_ptr->ret_value == MSAC_C2_EC_OK )
  634.     {
  635.         //check connection state
  636.         switch( connection_ptr->state )
  637.         {
  638.             case MSAC_C2_CS_PROVIDE_RESP:
  639.             {
  640.                 break;
  641.             }//case MSAC_C2_CS_PROVIDE_RESP:
  642.             case MSAC_C2_CS_DISABLE_CONNECT:
  643.             {
  644.                 switch (connection_ptr->error_code)
  645.                 {
  646.                     //V302; special behavior for Testcase 2C6
  647.                     case MSAC_C2_EC_DC_BY_MASTER:
  648.                     {
  649.                         //do nothing here, there was a ABORT before
  650.                         no_action = TRUE;
  651.                         break;
  652.                     }
  653.                     default:
  654.                     {
  655.                         fatal_state = TRUE;
  656.                     }
  657.                 }
  658.                 break;
  659.             }//case MSAC_C2_CS_DISABLE_CONNECT:
  660.             case MSAC_C2_CS_CLOSE_CHANNEL:
  661.             case MSAC_C2_CS_AWAIT_CONNECT:
  662.             case MSAC_C2_CS_AWAIT_IND:
  663.             case MSAC_C2_CS_PROVIDE_IND:
  664.             default:
  665.             {
  666.                 fatal_state = TRUE;
  667.                 break;
  668.             }//default:
  669.         }//switch( connection_ptr->state )
  670.         if( fatal_state )
  671.         {
  672.             vpc3_errcb[dev_num].error_code = connection_ptr->state;
  673.             vpc3_errcb[dev_num].cn_id      = cn_id;
  674.             // *** no further action of dpv1/c2 ***
  675.             fatal_error(dev_num,_DP_C2, __LINE__, &vpc3_errcb[dev_num]);
  676.         }//if( fatal_state )
  677.         if( !no_action )
  678.         {
  679.             switch( opc )
  680.             {
  681.                 case MSAC_C2_FN_IDLE:
  682.                 case MSAC_C2_FN_DATA:
  683.                 case MSAC_C2_FN_DS_READ:
  684.                 case MSAC_C2_FN_DS_WRITE:
  685.                 case MSAC_C2_FN_CONNECT:
  686.                 {
  687.                     //start request_time_out
  688.                     timer_ret = msac_c2_start_timer(dev_num,connection_ptr->timer_id, (dev_num,connection_ptr->poll_time_out << 1));
  689.                     //There was a request_time_out. The timeout-request
  690.                     //is behind this request in the input queue.
  691.                     //Set a note and reject later the timeout-request.
  692.                     if( timer_ret == MSAC_C2_TIMER_OK )
  693.                     {
  694.                         connection_ptr->timer_break = TRUE;
  695.                     }//if( timer_ret == MSAC_C2_TIMER_OK )
  696.                     //new description state
  697.                     connection_ptr->state = MSAC_C2_CS_AWAIT_IND;
  698.                     break;
  699.                 }//case MSAC_C2_FN_IDLE:
  700.                 case MSAC_C2_FN_DISCONNECT:
  701.                 {
  702.                     //stop PollTimeOut */
  703.                     timer_ret = msac_c2_stop_timer(dev_num,connection_ptr->timer_id);
  704.                     //There was a poll_time_out. The timeout-request
  705.                     //is behind this request in the input queue.
  706.                     //This subject is without importance in this case.
  707.                     if( timer_ret == MSAC_C2_TIMER_ALREADY_STOPPED )
  708.                     {
  709.                         connection_ptr->timer_break = TRUE;
  710.                     }//if( timer_ret == MSAC_C2_TIMER_ALREADY_STOPPED )
  711.                     connection_ptr->state = MSAC_C2_CS_DISABLE_CONNECT;
  712.                     fdl_ind_disable(dev_num,sap_nr);
  713.                     break;
  714.                 }//case MSAC_C2_FN_DISCONNECT:
  715.                 default:
  716.                 {
  717.                     //internal error: invalid opcode */
  718.                     vpc3_errcb[dev_num].error_code = connection_ptr->opcode;
  719.                     vpc3_errcb[dev_num].cn_id      = cn_id;
  720.                     // *** no further action of dpv1/c2 ***
  721.                     fatal_error(dev_num,_DP_C2, __LINE__, &vpc3_errcb[dev_num]);
  722.                 }//default:
  723.             }//switch( opc )
  724.         }//if( !no_action )
  725.     }//if( msac_c2[dev_num].act_rec_ptr->ret_value == MSAC_C2_EC_OK )
  726.     else
  727.     {
  728.         vpc3_errcb[dev_num].error_code = msac_c2[dev_num].act_rec_ptr->ret_value;
  729.         vpc3_errcb[dev_num].cn_id      = cn_id;
  730.         // *** no further action of dpv1/c2 ***
  731.         fatal_error(dev_num,_DP_C2, __LINE__, &vpc3_errcb[dev_num]);
  732.     }//else of if( msac_c2[dev_num].act_rec_ptr->ret_value == MSAC_C2_EC_OK )
  733. }//void msac_c2_realize_resp_sent(UBYTE dev_num, MSAC_C2_CONNECT_ITEM_PTR connection_ptr, UBYTE sap_nr )
  734. /*---------------------------------------------------------------------------*/
  735. /*                                                                           */
  736. /* msac_c2_realize_ind_disable_done(UBYTE dev_num,MSAC_C2_CONNECT_ITEM_PTR connection_ptr, */
  737. /*                                  UBYTE sap_nr )                           */
  738. /*                                                                           */
  739. /*   function: A sap was deactivated. Give the confirmation to the user.     */
  740. /*                                                                           */
  741. /*---------------------------------------------------------------------------*/
  742. SECTION_DEF_CommuCode void msac_c2_realize_ind_disable_done(UBYTE dev_num, MSAC_C2_CONNECT_ITEM_PTR connection_ptr, UBYTE sap_nr )
  743. {
  744.     if( msac_c2[dev_num].act_rec_ptr->ret_value == MSAC_C2_EC_OK )
  745.     {
  746.         if( connection_ptr->state == MSAC_C2_CS_DISABLE_CONNECT )
  747.         {
  748.             switch( connection_ptr->error_code )
  749.             {
  750.                 case MSAC_C2_EC_USER_ERR:
  751.                 case MSAC_C2_EC_DC_BY_USER:
  752.                 case MSAC_C2_EC_DC_BY_MASTER:
  753.                 case MSAC_C2_EC_REMOTE_ERROR:
  754.                 case MSAC_C2_EC_INV_S_D_LEN_ERR: //Testcase RM11
  755.                 {
  756.                     //give a new connection resource to rm sap */
  757.                     msac_c2_call_ind_await(dev_num,connection_ptr);
  758.                     break;
  759.                 }//case MSAC_C2_EC_USER_ERR:
  760.                 case MSAC_C2_EC_REQ_TIMEOUT:
  761.                 {
  762.                     msac_c2_dc_user_indication(dev_num,connection_ptr);
  763.                     break;
  764.                 }//case MSAC_C2_EC_REQ_TIMEOUT:
  765.                 default:
  766.                 {
  767.                     vpc3_errcb[dev_num].error_code = connection_ptr->error_code;
  768.                     vpc3_errcb[dev_num].cn_id      = connection_ptr->cn_id;
  769.                     // *** no further action of dpv1/c2 ***
  770.                     fatal_error(dev_num,_DP_C2, __LINE__, &vpc3_errcb[dev_num]);
  771.                 }//default:
  772.             }//switch( connection_ptr->error_code )
  773.         }//if( connection_ptr->state == MSAC_C2_CS_DISABLE_CONNECT )
  774.         else
  775.         {
  776.             vpc3_errcb[dev_num].error_code = connection_ptr->state;
  777.             vpc3_errcb[dev_num].cn_id      = connection_ptr->cn_id;
  778.             // *** no further action of dpv1/c2 ***
  779.             fatal_error(dev_num,_DP_C2, __LINE__, &vpc3_errcb[dev_num]);
  780.         }//else of if( connection_ptr->state == MSAC_C2_CS_DISABLE_CONNECT )
  781.     }//if( msac_c2[dev_num].act_rec_ptr->ret_value == MSAC_C2_EC_OK )
  782.     else
  783.     {
  784.         vpc3_errcb[dev_num].error_code = msac_c2[dev_num].act_rec_ptr->ret_value;
  785.         vpc3_errcb[dev_num].cn_id      = sap_nr;
  786.         // *** no further action of dpv1/c2 ***
  787.         fatal_error(dev_num,_DP_C2, __LINE__, &vpc3_errcb[dev_num]);
  788.     }//else of if( msac_c2[dev_num].act_rec_ptr->ret_value == MSAC_C2_EC_OK )
  789. }//void msac_c2_realize_ind_disable_done(UBYTE dev_num, MSAC_C2_CONNECT_ITEM_PTR connection_ptr, UBYTE sap_nr )
  790. /*---------------------------------------------------------------------------*/
  791. /*                                                                           */
  792. /* msac_c2_dc_user_indication(UBYTE dev_num,MSAC_C2_CONNECT_ITEM_PTR connection_ptr)       */
  793. /*                                                                           */
  794. /*   function: A sap was deactivated. Give the confirmation to the user.     */
  795. /*                                                                           */
  796. /*---------------------------------------------------------------------------*/
  797. SECTION_DEF_CommuCode void msac_c2_dc_user_indication(UBYTE dev_num, MSAC_C2_CONNECT_ITEM_PTR connection_ptr )
  798. {
  799.     //give a new connection resource to rm sap
  800.     msac_c2_call_ind_await(dev_num,connection_ptr);
  801.     //create disconnect pdu
  802.     msac_c2_create_disconnect_pdu(dev_num,connection_ptr, MSAC_C2_REQ_DIRECTION);
  803.     msac_c2_pdu_provide(dev_num,connection_ptr->sap_nr, connection_ptr->buf_ptr_res);
  804. }//void msac_c2_dc_user_indication(UBYTE dev_num, MSAC_C2_CONNECT_ITEM_PTR connection_ptr )
  805. /*---------------------------------------------------------------------------*/
  806. /*                                                                           */
  807. /* msac_c2_confirm_close_request(UBYTE dev_num,MSAC_C2_CONNECT_ITEM_PTR connection_ptr)    */
  808. /*                                                                           */
  809. /*   function: The function realizes the close handling of a connection      */
  810. /*             after a close_channel request.                                */
  811. /*                                                                           */
  812. /*---------------------------------------------------------------------------*/
  813. SECTION_DEF_CommuCode void msac_c2_confirm_close_request(UBYTE dev_num, MSAC_C2_CONNECT_ITEM_PTR connection_ptr )
  814. {
  815. UBYTE     i = 0;
  816. UBYTE     all_closed;
  817.     connection_ptr->user_break = MSAC_C2_UB_NO_BREAK;
  818.     msac_c2_stop_timer(dev_num,connection_ptr->timer_id);
  819.     connection_ptr->state = MSAC_C2_CS_CLOSE_CHANNEL;
  820.     do
  821.     {
  822.         all_closed = (msac_c2[dev_num].connection_list[i].state == MSAC_C2_CS_CLOSE_CHANNEL);
  823.         i++;
  824.     }
  825.     while( all_closed && (i < DP_C2_NUM_SAPS) );
  826.     if( all_closed )
  827.     {
  828.         msac_c2[dev_num].close_channel_request = FALSE;  //DP_FALSE */
  829.     }// if( all_closed )
  830. }//void msac_c2_confirm_close_request(UBYTE dev_num, MSAC_C2_CONNECT_ITEM_PTR connection_ptr )
  831. /*---------------------------------------------------------------------------*/
  832. /*                                                                           */
  833. /* UBYTE msac_c2_transmit_delay(UBYTE dev_num,UBYTE sap_nr, UBYTE status, DPV1_PTR pdu_ptr)*/
  834. /*                                                                           */
  835. /*   function: msac_c2_transmit_delay receives response data from the user.  */
  836. /*             In this function the response data are checked. In dependence */
  837. /*             of the pdu-opcode und the status the length of the data and   */
  838. /*             the function-code is manipulated. Then the dpv1_msc2 transmit */
  839. /*             function is called.                                           */
  840. /*                                                                           */
  841. /*   return codes: DPV1_OK          ( transmit function is called )          */
  842. /*                 C2_ENABLED_ERROR ( C2 service not supported    )          */
  843. /*                 C2_INV_CN_ID     ( invalid connection ident    )          */
  844. /*                 C2_USER_ERR      ( invalid response data       )          */
  845. /*                                                                           */
  846. /*---------------------------------------------------------------------------*/
  847. SECTION_DEF_CommuCode UBYTE msac_c2_transmit_delay(UBYTE dev_num, UBYTE sap_nr, UBYTE status, DPV1_PTR pdu_ptr )
  848. {
  849. MSAC_C2_CONNECT_ITEM_PTR    connection_ptr;
  850. DPV1_PTR                    dpv1_ptr;
  851. UBYTE                       data_opc;
  852. UBYTE                       ret_value;
  853.     //check, if MSAC_C2 functions enabled
  854.     if( msac_c2[dev_num].enabled )
  855.     {
  856.         //check, if valid sap
  857.         if( ( sap_nr > MSAC_C2_SAP_NR_HIGH ) || ( (MSAC_C2_SAP_NR_HIGH - sap_nr) >=  msac_c2[dev_num].num_sap) )
  858.         {
  859.             ret_value = C2_INV_CN_ID;
  860.         }//if( ( sap_nr > MSAC_C2_SAP_NR_HIGH ) || ( (MSAC_C2_SAP_NR_HIGH - sap_nr) >=  msac_c2[dev_num].num_sap) )
  861.         else
  862.         {
  863.             // determine connection_ptr
  864.             connection_ptr = &(msac_c2[dev_num].connection_list[MSAC_C2_SAP_NR_HIGH - sap_nr]);
  865.             //check, if valid buf_ptr
  866.             if( pdu_ptr != (DPV1_PTR)&(connection_ptr->buf_ptr->user_data[0]) )
  867.             {
  868.                 ret_value = C2_USER_ERR;
  869.             }//if( pdu_ptr != (DPV1_PTR)&(connection_ptr->buf_ptr->user_data[0]) )
  870.             else
  871.             {
  872.                 dpv1_ptr = (DPV1_PTR)&(connection_ptr->buf_ptr->user_data[0]);
  873.                 data_opc = dpv1_ptr->response.function_num & MSAC_C2_FN_MASK;
  874.                 ret_value = DPV1_OK;
  875.                 switch( status )
  876.                 {
  877.                     case DPV1_OK:
  878.                     {
  879.                         if( data_opc == MSAC_C2_FN_CONNECT )
  880.                         {
  881.                             connection_ptr->buf_ptr->data_len = MSAC_C2_LEN_INITIATE_RES_HEAD + BFWORD2BYTE(dpv1_ptr->initiate_res.s_len) + BFWORD2BYTE(dpv1_ptr->initiate_res.d_len);
  882.                         }//if( data_opc == MSAC_C2_FN_CONNECT )
  883.                         else
  884.                         {
  885.                             if( data_opc == MSAC_C2_FN_DS_WRITE )
  886.                             {
  887.                                 connection_ptr->buf_ptr->data_len = DPV1_LEN_HEAD_DATA;
  888.                             }//if( data_opc == MSAC_C2_FN_DS_WRITE )
  889.                             else
  890.                             {
  891.                                 //for READ andd TRANSPORT length is defined by userdata
  892.                                 connection_ptr->buf_ptr->data_len = BFWORD2BYTE(dpv1_ptr->response.length) + DPV1_LEN_HEAD_DATA;
  893.                             }//else of if( data_opc == MSAC_C2_FN_DS_WRITE )
  894.                         }//else of if( data_opc == MSAC_C2_FN_CONNECT )
  895.                         msac_c2_resp_pdu_provide(dev_num,sap_nr,connection_ptr->buf_ptr);
  896.                         break;
  897.                     }//case DPV1_OK:
  898.                     case DPV1_NOK:
  899.                     {
  900.                         //User must create correct response-pdu */
  901.                         connection_ptr->buf_ptr->data_len = DPV1_LEN_NEG_RESPONSE;
  902.                         dpv1_ptr->neg.function_num |= DPV1_ERROR_BIT_RESPONSE;
  903.                         dpv1_ptr->neg.err_decode = DPV1_ERRDC_DPV1;
  904.                         msac_c2_resp_pdu_provide(dev_num,sap_nr,connection_ptr->buf_ptr);
  905.                         break;
  906.                     }//case DPV1_NOK:
  907.                     case DPV1_ABORT:
  908.                     {
  909.                         connection_ptr->buf_ptr->data_len = MSAC_C2_LEN_DISCONNECT_PDU-1;
  910.                         dpv1_ptr->abort.function_num = MSAC_C2_FN_DISCONNECT | MSAC_C2_FUNCTION_NUM_EXTENSION;
  911.                         //DPV2S_CTRL_REASON_ABORT(dev_num,dat_ptr.abort->subnet,dat_ptr.abort->instance_reason)
  912.                         msac_c2_resp_pdu_provide(dev_num,sap_nr,connection_ptr->buf_ptr);
  913.                         break;
  914.                     }//case DPV1_ABORT:
  915.                     default:
  916.                     {
  917.                         ret_value = C2_USER_ERR;
  918.                         break;
  919.                     }//default:
  920.                 }//switch( status )
  921.             }//else of if( pdu_ptr != (DPV1_PTR)&(connection_ptr->buf_ptr->user_data[0]) )
  922.         }//else of if( ( sap_nr > MSAC_C2_SAP_NR_HIGH ) || ( (MSAC_C2_SAP_NR_HIGH - sap_nr) >=  msac_c2[dev_num].num_sap) )
  923.     }//if( msac_c2[dev_num].enabled )
  924.     else
  925.     {
  926.         ret_value = C2_ENABLED_ERROR;
  927.     }//else of if( msac_c2[dev_num].enabled )
  928.     return(ret_value );
  929. }//UBYTE msac_c2_transmit_delay(UBYTE dev_num, UBYTE sap_nr, UBYTE status, DPV1_PTR pdu_ptr )
  930. /*---------------------------------------------------------------------------*/
  931. /*                                                                           */
  932. /* UBYTE msac_c2_initiate_req_to_res(UBYTE dev_num,DPV1_PTR pdu_ptr)                       */
  933. /*                                                                           */
  934. /*   function: function helps user to create an initiate-response            */
  935. /*             the response is only created, if the slave is endpoint of the */
  936. /*             connection. Otherwise the puffer is untouched.                */
  937. /*                                                                           */
  938. /*---------------------------------------------------------------------------*/
  939. SECTION_DEF_CommuCode UBYTE msac_c2_initiate_req_to_res(UBYTE dev_num, DPV1_PTR pdu )
  940. {
  941. UBYTE ret_value;
  942. UBYTE S_typ;
  943. UBYTE S_len;
  944. UBYTE i;
  945.     //pay attention: same address, Response Buffer is shorter than Request ! sequence!
  946.     //first 3 Octets reseved, then Send_Timeout (2Byte) no more used
  947.     //only Max_pdu_lge (1Byte) >> 4Bytes difference
  948.     //buffer is changed, only if D-Typ = 0, end point of connection
  949.     ret_value = DPV1_NOK;
  950.     if( BFWORD2BYTE(pdu->initiate_req.d_type) == 0 )
  951.     {
  952.         pdu->initiate_res.max_len_data_unit            = msac_c2[dev_num].pdu_len; //Length of Init-Data
  953.         pdu->initiate_res.features_supported1          = C2_FEATURES_SUPPORTED_1;
  954.         pdu->initiate_res.features_supported2          = C2_FEATURES_SUPPORTED_2;
  955.         pdu->initiate_res.profile_features_supported1  = C2_PROFILE_FEATURES_1;
  956.         pdu->initiate_res.profile_features_supported2  = C2_PROFILE_FEATURES_2;
  957.         pdu->initiate_res.profile_ident_nummer         = BFWORD2LONG(C2_PROFILE_NUMBER);
  958.         //D-Typ and S-Typ changed position */
  959.         pdu->initiate_res.s_type  = pdu->initiate_req.d_type;
  960.         pdu->initiate_res.s_len   = pdu->initiate_req.d_len;
  961.         S_typ = BFWORD2BYTE(pdu->initiate_req.s_type);       //save S_typ
  962.         pdu->initiate_res.d_type  = S_typ;      //copy S_typ in buffer
  963.         S_len =  BFWORD2BYTE(pdu->initiate_req.s_len);       //save S_len
  964.         pdu->initiate_res.d_len   = S_len;      //copy S_len in buffer
  965.         //lge/type S
  966.         pdu->initiate_res.addr_data[0]  =  pdu->initiate_req.addr_data[S_len +0];
  967.         pdu->initiate_res.addr_data[1]  =  pdu->initiate_req.addr_data[S_len +1];
  968.         //after this point S-len is destroyed */
  969.         //copy add. address */
  970.         if( S_typ == 0 )
  971.         {
  972.             //if S-Typ =0 */
  973.             pdu->initiate_res.addr_data[2+0] = pdu->initiate_req.addr_data[0];
  974.             pdu->initiate_res.addr_data[2+1] = pdu->initiate_req.addr_data[1];
  975.         }//if( S_typ == 0 )
  976.         else
  977.         {
  978.             for( i=0; i < S_len; i++ )
  979.             {
  980.                 pdu->initiate_res.addr_data[2+i] = pdu->initiate_req.addr_data[i];
  981.             }//for( i=0; i < S_len; i++ )
  982.         }//else of if( S_typ == 0 )
  983.         ret_value = DPV1_OK;
  984.     }//if( pdu->initiate_req.d_type == 0 )
  985.     return ret_value;
  986. }//UBYTE msac_c2_initiate_req_to_res(UBYTE dev_num, DPV1_PTR pdu )
  987. /*---------------------------------------------------------------------------*/
  988. /*                                                                           */
  989. /* DP_ERROR_CODE msac_c2_init (UBYTE dev_num)                                         */
  990. /*                                                                           */
  991. /*   function: This function is called by the user. It initializes the       */
  992. /*             variables of MSAC_C2 connections                              */
  993. /*                                                                           */
  994. /*---------------------------------------------------------------------------*/
  995. SECTION_DEF_CommuCode DP_ERROR_CODE msac_c2_init(UBYTE dev_num)
  996. {
  997. DP_ERROR_CODE error;
  998. UBYTE         i;
  999.     error = DP_OK;
  1000.     memset(&msac_c2[dev_num], 0, sizeof(MSAC2_STRUC));//2009.4.3
  1001.     // check sap
  1002.     if(    ( dp_sys[dev_num].c2_num_saps <= MSAC_C2_SAP_NR_HIGH )
  1003.         && ( dp_sys[dev_num].c2_num_saps <= DP_C2_NUM_SAPS      )
  1004.       )
  1005.     {
  1006.         // check c2_len
  1007.         if(    ( dp_sys[dev_num].c2_len >= MSAC_C2_MIN_CR_PDU_SIZE )
  1008.             && ( dp_sys[dev_num].c2_len <= MSAC_C2_MAX_PDU         )
  1009.           )
  1010.         {
  1011.             msac_c2[dev_num].poll_time = MSAC_C2_TIMEOUT_1_5MBAUD;
  1012.             //changed V302
  1013.             msac_c2[dev_num].pdu_len   = DP_C2_LEN-4;
  1014.             msac_c2[dev_num].num_sap   = DP_C2_NUM_SAPS;
  1015.             // init connection list
  1016.             for( i = 0; i < DP_C2_NUM_SAPS; i++ )
  1017.             {
  1018.                 msac_c2[dev_num].connection_list[i].sap_nr = MSAC_C2_SAP_NR_HIGH - i;
  1019.                 msac_c2[dev_num].connection_list[i].state  = MSAC_C2_CS_CLOSE_CHANNEL;  //sign of free element */
  1020.                 msac_c2[dev_num].connection_list[i].cn_id  = i;
  1021.                 msac_c2[dev_num].connection_list[i].timer_id    = i;
  1022.                 msac_c2[dev_num].connection_list[i].timer_break = FALSE;
  1023.                 msac_c2[dev_num].connection_list[i].timer_active = FALSE;
  1024.                 msac_c2[dev_num].connection_list[i].user_break  = MSAC_C2_UB_NO_BREAK;
  1025.                 msac_c2[dev_num].connection_list[i].buf_ptr_res = (MSAC_C2_DATA_BUF PTR_ATTR *) &(msac_c2[dev_num].reserve_buffer[i]);
  1026.                 msac_c2[dev_num].connection_list[i].dr_reason_code = 0x00;
  1027.                 msac_c2[dev_num].connection_list[i].dr_location    = 0x00;
  1028.             }
  1029.             //init memory item for close_channel request of the user */
  1030.             msac_c2[dev_num].close_channel_request = FALSE;
  1031.             // initialize receive queue */
  1032.             msac_c2[dev_num].start_rec_ptr = 0;
  1033.             msac_c2[dev_num].write_rec_ptr = msac_c2[dev_num].start_rec_ptr;
  1034.             msac_c2[dev_num].read_rec_ptr  = msac_c2[dev_num].start_rec_ptr;
  1035.             msac_c2[dev_num].end_rec_ptr   = MSAC_C2_MAX_INPUT_ITEMS-1;
  1036.             // enable msac_c2-functions
  1037.             msac_c2[dev_num].enabled = TRUE;
  1038.         }//if(    (dp_sys[dev_num].c2_len >= MSAC_C2_MIN_CR_PDU_SIZE ) ...
  1039.         else
  1040.         {
  1041.             error = C2_DATA_LEN_ERROR;
  1042.         }//else of if(    (dp_sys[dev_num].c2_len >= MSAC_C2_MIN_CR_PDU_SIZE ) ...
  1043.     }//if(    ( dp_sys[dev_num].c2_num_saps <= MSAC_C2_SAP_NR_HIGH ) ...
  1044.     else
  1045.     {
  1046.         error = C2_DATA_SAP_ERROR;
  1047.     }//else of if(    ( dp_sys[dev_num].c2_num_saps <= MSAC_C2_SAP_NR_HIGH ) ...
  1048.     return error;
  1049. }//DP_ERROR_CODE msac_c2_init(UBYTE dev_num)
  1050. /*---------------------------------------------------------------------------*/
  1051. /* function: msac_c2_set_timeout                                             */
  1052. /*---------------------------------------------------------------------------*/
  1053. SECTION_DEF_CommuCode void msac_c2_set_timeout(UBYTE dev_num)
  1054. {
  1055.     switch( VPC3_GET_BAUDRATE(dev_num) )
  1056.     {
  1057.         case BAUDRATE_500KBAUD:
  1058.         {
  1059.             msac_c2[dev_num].poll_time = MSAC_C2_TIMEOUT_500KBAUD;
  1060.             break;
  1061.         }
  1062.         case BAUDRATE_187_50KBAUD:
  1063.         case BAUDRATE_93_75KBAUD:
  1064.         case BAUDRATE_45_45KBAUD:
  1065.         case BAUDRATE_19_20KBAUD:
  1066.         case BAUDRATE_9_60KBAUD:
  1067.         {
  1068.             msac_c2[dev_num].poll_time = MSAC_C2_TIMEOUT_187_50KBAUD;
  1069.             break;
  1070.         }
  1071.         default:
  1072.         {
  1073.             msac_c2[dev_num].poll_time = MSAC_C2_TIMEOUT_1_5MBAUD;
  1074.             break;
  1075.         }
  1076.     }//switch( VPC3_GET_BAUDRATE(dev_num) )
  1077.     fdl_set_poll_timeout(dev_num, msac_c2[dev_num].poll_time );
  1078. }//void msac_c2_set_timeout(UBYTE dev_num)
  1079. /*---------------------------------------------------------------------------*/
  1080. /*                                                                           */
  1081. /* void msac_c2_open_channel_sap(UBYTE dev_num,UBYTE sap_nr)                               */
  1082. /*                                                                           */
  1083. /*   function: internal function                                             */
  1084. /*             activate sap                                                  */
  1085. /*                                                                           */
  1086. /*---------------------------------------------------------------------------*/
  1087. SECTION_DEF_CommuCode void msac_c2_open_channel_sap(UBYTE dev_num, UBYTE sap_nr )
  1088. {
  1089. UBYTE i = 0;
  1090.     while( (msac_c2[dev_num].connection_list[i].sap_nr&0xff) != (sap_nr&0xff) )//2009.11.7
  1091.     {
  1092.         i++;
  1093.     }//while( msac_c2[dev_num].connection_list[i].sap_nr != sap_nr )
  1094.     msac_c2[dev_num].connection_list[i].state = MSAC_C2_CS_AWAIT_CONNECT;
  1095. }//void msac_c2_open_channel_sap(UBYTE dev_num, UBYTE sap_nr )
  1096. /*---------------------------------------------------------------------------*/
  1097. /*                                                                           */
  1098. /* DP_ERROR_CODE msac_c2_open_channel (UBYTE dev_num)                                */
  1099. /*                                                                           */
  1100. /*   function: implementation of open_channel-function, analyze the data,    */
  1101. /*             allocate timer for sap 49, activate sap 49                    */
  1102. /*                                                                           */
  1103. /*---------------------------------------------------------------------------*/
  1104. SECTION_DEF_CommuCode DP_ERROR_CODE msac_c2_open_channel(UBYTE dev_num)
  1105. {
  1106. DP_ERROR_CODE   error;
  1107.     //check, if msac_c2-functions enabled
  1108.     if( msac_c2[dev_num].enabled )
  1109.     {
  1110.         //check connection state: connection 0 represents the connection description
  1111.         if( msac_c2[dev_num].connection_list[0].state == MSAC_C2_CS_CLOSE_CHANNEL )
  1112.         {
  1113.             error = DP_OK;
  1114.             if( fdl_open_channel(dev_num) == FDL_OK )
  1115.             {
  1116.                 //set description state of connection
  1117.                 msac_c2[dev_num].connection_list[0].state = MSAC_C2_CS_AWAIT_CONNECT;
  1118.                 //assign connection resource of lower layer
  1119.                 if( fdl_ind_await(dev_num,msac_c2[dev_num].connection_list[0].sap_nr) != FDL_OK )
  1120.                 {
  1121.                     error = C2_NO_CONN_RESOURCE;
  1122.                 }//if( fdl_ind_await(dev_num,msac_c2[dev_num].connection_list[0].sap_nr) != FDL_OK )
  1123.             }//if( fdl_open_channel(dev_num) == FDL_OK )
  1124.             else
  1125.             {
  1126.                 error = C2_INV_LOWER_LAYER;
  1127.             }//else of if( fdl_open_channel(dev_num) == FDL_OK )
  1128.         }//if( msac_c2[dev_num].connection_list[0].state == MSAC_C2_CS_CLOSE_CHANNEL )
  1129.         else
  1130.         {
  1131.             //function is called twice
  1132.             error = C2_RESOURCE_ERROR;
  1133.         }//else of if( msac_c2[dev_num].connection_list[0].state == MSAC_C2_CS_CLOSE_CHANNEL )
  1134.     }//if( msac_c2[dev_num].enabled )
  1135.     else
  1136.     {
  1137.         error = C2_ENABLED_ERROR;
  1138.     }//else of if( msac_c2[dev_num].enabled )
  1139.     return error;
  1140. }//DP_ERROR_CODE msac_c2_open_channel(UBYTE dev_num)
  1141. /*---------------------------------------------------------------------------*/
  1142. /*                                                                           */
  1143. /* msac_c2_create_disconnect_pdu(UBYTE dev_num,MSAC_C2_CONNECT_ITEM_PTR connection_ptr,    */
  1144. /*                               UBYTE                    direction)         */
  1145. /*                                                                           */
  1146. /*   function: internal function                                             */
  1147. /*             manipulate or create a pdu as disconnect pdu                  */
  1148. /*             Note: A disconnect pdu to the user is always to               */
  1149. /*                   send by the reserved buffer.                            */
  1150. /*                                                                           */
  1151. /*---------------------------------------------------------------------------*/
  1152. SECTION_DEF_CommuCode void msac_c2_create_disconnect_pdu(UBYTE dev_num, MSAC_C2_CONNECT_ITEM_PTR connection_ptr, MSAC2_DIRECTION direction )
  1153. {
  1154. MSAC_C2_DATA_BUF_PTR    data_ptr;     //pointer to data buffer */
  1155. MSAC_C2_DR_BUF_PTR      dc_buf_ptr;   //pointer to disconnect pdu */
  1156. UBYTE                   dr_location = MSAC_C2_SUBNET_NO;
  1157. UBYTE                   dr_error;
  1158.     //disable timer */
  1159.     connection_ptr->timer_active = FALSE;
  1160.     switch( connection_ptr->error_code )
  1161.     {
  1162.         case MSAC_C2_EC_DC_BY_MASTER:
  1163.         {
  1164.             //read the source information of dr pdu */
  1165.             data_ptr = connection_ptr->buf_ptr;
  1166.             dc_buf_ptr = (MSAC_C2_DR_BUF_PTR) &(data_ptr->user_data[0]);
  1167.             dr_location = dc_buf_ptr->location;
  1168.             dr_error = dc_buf_ptr->reason_code;
  1169.             break;
  1170.         }
  1171.         case MSAC_C2_EC_USER_ERR:
  1172.         {
  1173.             dr_error = MSAC_C2_ABT_IV | MSAC_C2_INSTANCE_MSAC_C2;
  1174.             break;
  1175.         }
  1176.         case MSAC_C2_EC_INV_S_D_LEN_ERR:
  1177.         {
  1178.             dr_error = MSAC_C2_ABT_IA | MSAC_C2_INSTANCE_MSAC_C2;
  1179.             break;
  1180.         }
  1181.         case MSAC_C2_EC_REQ_TIMEOUT:
  1182.         {
  1183.             dr_error = MSAC_C2_ABT_TO | MSAC_C2_INSTANCE_MSAC_C2;
  1184.             break;
  1185.         }
  1186.         case MSAC_C2_EC_REMOTE_ERROR:
  1187.         {
  1188.             dr_error = MSAC_C2_ABT_FE | MSAC_C2_INSTANCE_MSAC_C2;
  1189.             break;
  1190.         }
  1191.         case MSAC_C2_EC_DC_BY_USER:
  1192.         {
  1193.             dr_location = connection_ptr->dr_location;
  1194.             dr_error = (connection_ptr->dr_reason_code) | MSAC_C2_INSTANCE_USER;
  1195.             break;
  1196.         }
  1197.         default:
  1198.         {
  1199.             vpc3_errcb[dev_num].error_code = connection_ptr->error_code;
  1200.             vpc3_errcb[dev_num].cn_id      = connection_ptr->cn_id;
  1201.             // *** no further action of dpv1/c2 ***
  1202.             fatal_error(dev_num,_DP_C2, __LINE__, &vpc3_errcb[dev_num]);
  1203.             break;
  1204.         }
  1205.     }//end switch */
  1206.     //define destination pointer */
  1207.     if( direction == MSAC_C2_RESP_DIRECTION )
  1208.         data_ptr = connection_ptr->buf_ptr;
  1209.     else   //MSAC_C2_REQ_DIRECTION */
  1210.         data_ptr = connection_ptr->buf_ptr_res;
  1211.     data_ptr->data_len = MSAC_C2_LEN_DISCONNECT_PDU -1;
  1212.     dc_buf_ptr = (MSAC_C2_DR_BUF_PTR) &(data_ptr->user_data[0]);
  1213.     //fill dr pdu */
  1214.     dc_buf_ptr->opcode = MSAC_C2_FN_DISCONNECT | MSAC_C2_FUNCTION_NUM_EXTENSION;
  1215.     dc_buf_ptr->location = dr_location;
  1216.     dc_buf_ptr->reason_code = dr_error;
  1217.     dc_buf_ptr->reserved = (UBYTE) 0;
  1218.     connection_ptr->opcode = MSAC_C2_FN_DISCONNECT;
  1219.     if( direction == MSAC_C2_REQ_DIRECTION )
  1220.     {
  1221.         data_ptr->fc = MSAC_C2_FC_SRD_L;
  1222.     }//if( direction == MSAC_C2_REQ_DIRECTION )
  1223. }//void msac_c2_create_disconnect_pdu(UBYTE dev_num, MSAC_C2_CONNECT_ITEM_PTR connection_ptr, UBYTE direction )
  1224. /*---------------------------------------------------------------------------*/
  1225. /*                                                                           */
  1226. /* void msac_c2_send_response_data (UBYTE dev_num,MSAC_C2_CONNECT_ITEM_PTR connection_ptr) */
  1227. /*                                                                           */
  1228. /*   function: internal function                                             */
  1229. /*             send response data to fdl  (without wait pdu)                 */
  1230. /*                                                                           */
  1231. /*---------------------------------------------------------------------------*/
  1232. SECTION_DEF_CommuCode void msac_c2_send_response_data(UBYTE dev_num, MSAC_C2_CONNECT_ITEM_PTR connection_ptr )
  1233. {
  1234.     //There was a timeout. The timeout-request
  1235.     //is behind this request in the input queue.
  1236.     //Set a note and reject later the timeout-request.
  1237.     if( msac_c2_start_timer(dev_num,connection_ptr->timer_id, connection_ptr->poll_time_out) == MSAC_C2_TIMER_OK)
  1238.     {
  1239.         connection_ptr->timer_break = TRUE;
  1240.     }
  1241.     //update fc for response */
  1242.     connection_ptr->buf_ptr->fc = FC_RESP_L;
  1243.     fdl_resp_provide(dev_num,connection_ptr->sap_nr, FDL_PRIMARY_BUF);
  1244. }//void msac_c2_send_response_data(UBYTE dev_num, MSAC_C2_CONNECT_ITEM_PTR connection_ptr )
  1245. /*---------------------------------------------------------------------------*/
  1246. /*                                                                           */
  1247. /*  void msac_c2_call_ind_await (UBYTE dev_num,MSAC_C2_CONNECT_ITEM_PTR connection_ptr)    */
  1248. /*                                                                           */
  1249. /*   function: Set the connection state of MSAC_C2_CS_AWAIT_CONNECT, call    */
  1250. /*             the output function MSAC_C2_IND_AWAIT(UBYTE dev_num) and check the return  */
  1251. /*             code of the function.                                         */
  1252. /*                                                                           */
  1253. /*---------------------------------------------------------------------------*/
  1254. SECTION_DEF_CommuCode void msac_c2_call_ind_await(UBYTE dev_num, MSAC_C2_CONNECT_ITEM_PTR connection_ptr )
  1255. {
  1256. UBYTE   rcode;
  1257.     //new description state */
  1258.     connection_ptr->state = MSAC_C2_CS_AWAIT_CONNECT;
  1259.     connection_ptr->timer_break = FALSE;
  1260.     connection_ptr->user_break = MSAC_C2_UB_NO_BREAK;
  1261.     rcode = fdl_ind_await(dev_num,connection_ptr->sap_nr);
  1262.     if( rcode != FDL_OK )
  1263.     {
  1264.         vpc3_errcb[dev_num].error_code = rcode;
  1265.         vpc3_errcb[dev_num].cn_id      = connection_ptr->cn_id;
  1266.         // *** no further action of dpv1/c2 ***
  1267.         fatal_error(dev_num,_DP_C2, __LINE__, &vpc3_errcb[dev_num]);
  1268.     }//if( rcode != FDL_OK )
  1269. }//void msac_c2_call_ind_await(UBYTE dev_num, MSAC_C2_CONNECT_ITEM_PTR connection_ptr )
  1270. /*---------------------------------------------------------------------------*/
  1271. /*                                                                           */
  1272. /* msac_c2_handle_user_response (UBYTE dev_num,MSAC_C2_CONNECT_ITEM_PTR connection_ptr)    */
  1273. /*                                                                           */
  1274. /*   function: internal function                                             */
  1275. /*             check user data and set the reaction (no call of              */
  1276. /*             msac_c2_send_response_data, no set of connection description) */
  1277. /*                                                                           */
  1278. /*---------------------------------------------------------------------------*/
  1279. SECTION_DEF_CommuCode void msac_c2_handle_user_response(UBYTE dev_num, MSAC_C2_CONNECT_ITEM_PTR connection_ptr )
  1280. {
  1281. MSAC_C2_DATA_BUF_PTR    buf_ptr     = connection_ptr->buf_ptr;
  1282. MSAC_C2_CC_BUF_PTR      data_ptr    = (MSAC_C2_CC_BUF_PTR) &(connection_ptr->buf_ptr->user_data[0]);
  1283. MSAC_C2_DE_BUF_PTR      de_data_ptr = (MSAC_C2_DE_BUF_PTR) &(buf_ptr->user_data[0]);
  1284. UBYTE                   data_opc    = data_ptr->opcode & MSAC_C2_FN_MASK;
  1285. UBYTE                   rcode = TRUE; //Boolean
  1286.     if((data_opc != connection_ptr->opcode) && (data_opc != MSAC_C2_FN_DISCONNECT))
  1287.     {
  1288.         rcode = FALSE;
  1289.     }
  1290.     else
  1291.     {
  1292.         switch (data_opc)
  1293.         {
  1294.             case MSAC_C2_FN_CONNECT:
  1295.             {
  1296.                 //negativ response connection state not opened */
  1297.                 if( (de_data_ptr->opcode & DPV1_ERROR_BIT_RESPONSE) != 0 )
  1298.                 {   //negativ response by FN_CONNECT, internal disconnect */
  1299.                     connection_ptr->opcode = MSAC_C2_FN_DISCONNECT;
  1300.                     if(BFWORD2BYTE(buf_ptr->data_len) < DPV1_LEN_NEG_RESPONSE)
  1301.                     {
  1302.                         rcode = FALSE;
  1303.                     }
  1304.                 }
  1305.                 else //positiv response */
  1306.                 {
  1307.                     if(BFWORD2BYTE(buf_ptr->data_len) < MSAC_C2_MIN_CC_PDU_SIZE)
  1308.                     {
  1309.                         rcode = FALSE;
  1310.                     }
  1311.                 }
  1312.                 break;
  1313.             }
  1314.             case MSAC_C2_FN_DATA:
  1315.             {
  1316.                 if( (de_data_ptr->opcode & DPV1_ERROR_BIT_RESPONSE) != 0 )   //TRANS-NRS */
  1317.                 {   //new negative response */
  1318.                     if(BFWORD2BYTE(buf_ptr->data_len) != DPV1_LEN_NEG_RESPONSE)
  1319.                     {
  1320.                         rcode = FALSE;
  1321.                     }
  1322.                 }
  1323.                 else
  1324.                 {
  1325.                     if((BFWORD2BYTE(buf_ptr->data_len) != (BFWORD2BYTE(de_data_ptr->length) + DPV1_LEN_HEAD_DATA)) ||
  1326.                         (BFWORD2BYTE(de_data_ptr->length) > MSAC_C2_MAX_PDU_SIZE))
  1327.                     {
  1328.                         rcode = FALSE;
  1329.                     }
  1330.                     else
  1331.                     {
  1332.                         //no change of user data */
  1333.                     }
  1334.                 }
  1335.                 break;
  1336.             }
  1337.             case MSAC_C2_FN_DS_READ:
  1338.             case MSAC_C2_FN_DS_WRITE:
  1339.             {
  1340.                 if( (de_data_ptr->opcode & DPV1_ERROR_BIT_RESPONSE) != 0 )   //RDNRS, WRNRS */
  1341.                 {
  1342.                     if(BFWORD2BYTE(buf_ptr->data_len) != DPV1_LEN_NEG_RESPONSE)
  1343.                     {
  1344.                         rcode = FALSE;
  1345.                     }
  1346.                 }
  1347.                 else   //RDRES, WRRES */
  1348.                 {
  1349.                     if(data_opc == MSAC_C2_FN_DS_READ)
  1350.                     {
  1351.                         if(BFWORD2BYTE(buf_ptr->data_len) != (BFWORD2BYTE(de_data_ptr->length) + DPV1_LEN_HEAD_DATA))
  1352.                         {
  1353.                             rcode = FALSE;
  1354.                         }
  1355.                     }
  1356.                     else   //DPV2_FN_DS_WRITE */
  1357.                     {
  1358.                         if(BFWORD2BYTE(buf_ptr->data_len) != DPV1_LEN_HEAD_DATA)
  1359.                         {
  1360.                             rcode = FALSE;
  1361.                         }
  1362.                     }
  1363.                     if( rcode == TRUE )
  1364.                     {
  1365.                         if( (BFWORD2BYTE(de_data_ptr->slot) == 255)  ||
  1366.                             (BFWORD2BYTE(de_data_ptr->index) == 255) ||
  1367.                             (BFWORD2BYTE(de_data_ptr->length) > MSAC_C2_MAX_PDU_SIZE))
  1368.                         {
  1369.                             rcode = FALSE;
  1370.                         }
  1371.                     }
  1372.                 }
  1373.                 break;
  1374.             }
  1375.             case MSAC_C2_FN_DISCONNECT:
  1376.             {
  1377.                 connection_ptr->opcode = MSAC_C2_FN_DISCONNECT;
  1378.                 break;
  1379.             }
  1380.             default:
  1381.             {
  1382.                 rcode = FALSE;
  1383.                 break;
  1384.             }
  1385.         } // switch
  1386.     }
  1387.     if(rcode)
  1388.     {
  1389.         //response data_ok */
  1390.         switch (data_opc)
  1391.         {
  1392.             case MSAC_C2_FN_CONNECT:
  1393.             {
  1394.                 //negative response is now handled */
  1395.                 if((data_ptr->opcode & DPV1_ERROR_BIT_RESPONSE) != 0)
  1396.                 {
  1397.                     connection_ptr->error_code = MSAC_C2_EC_DC_BY_USER;
  1398.                 }
  1399.                 break;
  1400.             }
  1401.             case MSAC_C2_FN_DISCONNECT:
  1402.             {
  1403.                 connection_ptr->error_code = MSAC_C2_EC_DC_BY_USER;
  1404.                 break;
  1405.             }
  1406.         }
  1407.     }   //end response data ok */
  1408.     else   //invalid response data */
  1409.     {
  1410.         connection_ptr->error_code = MSAC_C2_EC_USER_ERR;
  1411.         //handle response data as disconnect-pdu */
  1412.         msac_c2_create_disconnect_pdu(dev_num,connection_ptr, MSAC_C2_RESP_DIRECTION);
  1413.     }   //end invalid user response */
  1414. }//void msac_c2_handle_user_response(UBYTE dev_num, MSAC_C2_CONNECT_ITEM_PTR connection_ptr )
  1415. /*---------------------------------------------------------------------------*/
  1416. /*                                                                           */
  1417. /*   void msac_c2_resp_pdu_provide(UBYTE dev_num,UBYTE sap_nr,                             */
  1418. /*                                 MSAC_C2_DATA_BUF_PTR buf_ptr)             */
  1419. /*                                                                           */
  1420. /*   function: MSAC_C2 received response data from the user. In this         */
  1421. /*             function the response data are checked. In dependence of the  */
  1422. /*             pdu-opcode the response data are given to the layer 2         */
  1423. /*             (DATA_TRANSPORT and DISCONNECT) or the productiv data sap is  */
  1424. /*             the productiv data sap is activated (CONNECT).                */
  1425. /*                                                                           */
  1426. /*---------------------------------------------------------------------------*/
  1427. SECTION_DEF_CommuCode void msac_c2_resp_pdu_provide(UBYTE dev_num, UBYTE sap_nr, MSAC_C2_DATA_BUF_PTR buf_ptr )
  1428. {
  1429. MSAC_C2_CONNECT_ITEM_PTR     connection_ptr;
  1430.     buf_ptr=buf_ptr;
  1431.     //determine connection_ptr */
  1432.     connection_ptr = &(msac_c2[dev_num].connection_list[MSAC_C2_SAP_NR_HIGH - sap_nr]);
  1433.     switch (connection_ptr->state)
  1434.     {
  1435.         case MSAC_C2_CS_PROVIDE_IND:   //wait for response data */
  1436.         {
  1437.             switch (connection_ptr->error_code)
  1438.             {
  1439.                 case MSAC_C2_EC_OK:
  1440.                 {
  1441.                     //new description state */
  1442.                     connection_ptr->state = MSAC_C2_CS_PROVIDE_RESP;
  1443.                     msac_c2_handle_user_response(dev_num,connection_ptr);
  1444.                     msac_c2_send_response_data(dev_num,connection_ptr);
  1445.                     break;
  1446.                 }
  1447.                 case MSAC_C2_EC_USER_ERR:
  1448.                 case MSAC_C2_EC_INV_S_D_LEN_ERR:
  1449.                 case MSAC_C2_EC_REQ_TIMEOUT:
  1450.                 case MSAC_C2_EC_DC_BY_USER:
  1451.                 case MSAC_C2_EC_DC_BY_MASTER:
  1452.                 case MSAC_C2_EC_REMOTE_ERROR:
  1453.                 default:
  1454.                 {
  1455.                     vpc3_errcb[dev_num].error_code = connection_ptr->error_code;
  1456.                     vpc3_errcb[dev_num].cn_id      = MSAC_C2_SAP_NR_HIGH - sap_nr;
  1457.                     // *** no further action of dpv1/c2 ***
  1458.                     fatal_error(dev_num,_DP_C2, __LINE__, &vpc3_errcb[dev_num]);
  1459.                 }
  1460.             }
  1461.             break;
  1462.         }//case MSAC_C2_CS_PROVIDE_IND:
  1463.         case MSAC_C2_CS_CLOSE_CHANNEL:
  1464.         case MSAC_C2_CS_AWAIT_CONNECT:
  1465.         case MSAC_C2_CS_AWAIT_IND:
  1466.         case MSAC_C2_CS_PROVIDE_RESP:
  1467.         case MSAC_C2_CS_DISABLE_CONNECT:
  1468.         default:
  1469.         {
  1470.             vpc3_errcb[dev_num].error_code = connection_ptr->state;
  1471.             vpc3_errcb[dev_num].cn_id      = MSAC_C2_SAP_NR_HIGH - sap_nr;
  1472.             // *** no further action of dpv1/c2 ***
  1473.             fatal_error(dev_num,_DP_C2, __LINE__, &vpc3_errcb[dev_num]);
  1474.             break;
  1475.         }//default:
  1476.     }  //end switch connection_ptr->state */
  1477. }//void msac_c2_resp_pdu_provide(UBYTE dev_num, UBYTE sap_nr, MSAC_C2_DATA_BUF_PTR buf_ptr )
  1478. /*---------------------------------------------------------------------------*/
  1479. /*                                                                           */
  1480. /*   void msac_c2_close_channel(UBYTE dev_num)                                        */
  1481. /*                                                                           */
  1482. /*   function:     implementation of close_channel function                  */
  1483. /*                                                                           */
  1484. /*---------------------------------------------------------------------------*/
  1485. SECTION_DEF_CommuCode void msac_c2_close_channel(UBYTE dev_num)
  1486. {
  1487.     if( (msac_c2[dev_num].close_channel_request == FALSE ) && (msac_c2[dev_num].connection_list[0].state != MSAC_C2_CS_CLOSE_CHANNEL) )
  1488.     {
  1489.         //accept close_channel request
  1490.         msac_c2[dev_num].close_channel_request = TRUE;
  1491.         fdl_close_channel(dev_num, FDL_MSAC_C2_SAP );
  1492.     }//if( (msac_c2[dev_num].close_channel_request == FALSE ) && (msac_c2[dev_num].connection_list[0].state != MSAC_C2_CS_CLOSE_CHANNEL) )
  1493. }//void msac_c2_close_channel(UBYTE dev_num)
  1494. /*---------------------------------------------------------------------------*/
  1495. /*                                                                           */
  1496. /*   void msac_c2_input_queue(UBYTE dev_num,MSAC_C2_DATA_BUF_PTR buf_ptr, BYTE ret_value   */
  1497. /*                            UBYTE user_id, UBYTE fdl_code)                 */
  1498. /*                                                                           */
  1499. /*   function:     copy message into msac_c2 input queue                     */
  1500. /*                                                                           */
  1501. /*---------------------------------------------------------------------------*/
  1502. SECTION_DEF_CommuCode void msac_c2_input_queue(UBYTE dev_num, MSAC_C2_DATA_BUF_PTR buf_ptr, UBYTE ret_value ,UBYTE user_id, UBYTE fdl_code )
  1503. {
  1504. MSAC_C2_REC_QUEUE_PTR  rec_ptr;
  1505.     rec_ptr = &(msac_c2[dev_num].rec_queue[msac_c2[dev_num].write_rec_ptr]);
  1506.     rec_ptr->buf_ptr   = buf_ptr;
  1507.     rec_ptr->ret_value = ret_value;        //clear ret_value
  1508.     rec_ptr->sap_nr    = user_id;
  1509.     rec_ptr->fdl_code  = fdl_code;
  1510.     if( msac_c2[dev_num].write_rec_ptr != msac_c2[dev_num].end_rec_ptr )
  1511.     {
  1512.         msac_c2[dev_num].write_rec_ptr++;
  1513.     }//if( msac_c2[dev_num].write_rec_ptr != msac_c2[dev_num].end_rec_ptr )
  1514.     else
  1515.     {
  1516.        msac_c2[dev_num].write_rec_ptr = msac_c2[dev_num].start_rec_ptr;
  1517.     }//else of if( msac_c2[dev_num].write_rec_ptr != msac_c2[dev_num].end_rec_ptr )
  1518. }//void msac_c2_input_queue(UBYTE dev_num, MSAC_C2_DATA_BUF_PTR buf_ptr, UBYTE ret_value ,UBYTE user_id, UBYTE fdl_code )
  1519. /*---------------------------------------------------------------------------*/
  1520. /*                                                                           */
  1521. /*   void msac_c2_timer_tick_10msec(UBYTE dev_num)                                    */
  1522. /*                                                                           */
  1523. /*   function:     10msec Timer Function for MSAC_2 connections,             */
  1524. /*                 called by interrupt function.                             */
  1525. /*---------------------------------------------------------------------------*/
  1526. SECTION_DEF_CommuCode void msac_c2_timer_tick_10msec(UBYTE dev_num)
  1527. {
  1528. UBYTE i;
  1529.     for( i = 0; i < DP_C2_NUM_SAPS; i++ )
  1530.     {
  1531.         if( msac_c2[dev_num].timer_list[i].running != FALSE )
  1532.         {
  1533.             if( msac_c2[dev_num].timer_list[i].time_act )
  1534.             {
  1535.                 msac_c2[dev_num].timer_list[i].time_act--;
  1536.             }//if( msac_c2[dev_num].timer_list[i].time_act )
  1537.             else
  1538.             {
  1539.                 msac_c2[dev_num].timer_list[i].running = FALSE;
  1540.             }//else of if( msac_c2[dev_num].timer_list[i].time_act )
  1541.         }//if( msac_c2[dev_num].timer_list[i].running != FALSE )
  1542.     }//for( i = 0; i < DP_C2_NUM_SAPS; i++ )
  1543. }//void msac_c2_timer_tick_10msec(UBYTE dev_num)
  1544. /*---------------------------------------------------------------------------*/
  1545. /*                                                                           */
  1546. /*   UBYTE msac_c2_start_timer(UBYTE dev_num,UBYTE  timer_index, UWORD timer_value)        */
  1547. /*                                                                           */
  1548. /*   function:     start timer                                               */
  1549. /*                                                                           */
  1550. /*---------------------------------------------------------------------------*/
  1551. SECTION_DEF_CommuCode UBYTE msac_c2_start_timer(UBYTE dev_num, UBYTE timer_index, UWORD timer_value )
  1552. {
  1553. UBYTE ret_val;
  1554.     //set new reload-value
  1555.     msac_c2[dev_num].timer_list[ timer_index ].time_act = timer_value;
  1556.     if( msac_c2[dev_num].timer_list[ timer_index ].running == TRUE )
  1557.     {
  1558.         ret_val = MSAC_C2_TIMER_ALREADY_RUNS;
  1559.     }//if( msac_c2[dev_num].timer_list[ timer_index ].running == TRUE )
  1560.     else
  1561.     {
  1562.         msac_c2[dev_num].timer_list[ timer_index ].running = TRUE;
  1563.         ret_val = MSAC_C2_TIMER_OK;
  1564.     }//else of if( msac_c2[dev_num].timer_list[ timer_index ].running == TRUE )
  1565.     return ret_val;
  1566. }//UBYTE msac_c2_start_timer(UBYTE dev_num, UBYTE timer_index, UWORD timer_value )
  1567. /*---------------------------------------------------------------------------*/
  1568. /*                                                                           */
  1569. /*   UBYTE msac_c2_stop_timer(UBYTE dev_num,UBYTE  timer_index)                            */
  1570. /*                                                                           */
  1571. /*   function:     stop timer                                                */
  1572. /*                                                                           */
  1573. /*---------------------------------------------------------------------------*/
  1574. SECTION_DEF_CommuCode UBYTE msac_c2_stop_timer(UBYTE dev_num, UBYTE timer_index )
  1575. {
  1576. UBYTE ret_val;
  1577.     if( msac_c2[dev_num].timer_list[ timer_index ].running == FALSE )
  1578.     {
  1579.         ret_val = MSAC_C2_TIMER_ALREADY_STOPPED;
  1580.     }//if( msac_c2[dev_num].timer_list[ timer_index ].running == FALSE )
  1581.     else
  1582.     {
  1583.         msac_c2[dev_num].timer_list[ timer_index ].time_act = 0x0000;
  1584.         msac_c2[dev_num].timer_list[ timer_index ].running   = FALSE;
  1585.         ret_val = MSAC_C2_TIMER_OK;
  1586.     }//else of if( msac_c2[dev_num].timer_list[ timer_index ].running == FALSE )
  1587.     return ret_val;
  1588. }//UBYTE msac_c2_stop_timer(UBYTE dev_num, UBYTE timer_index )
  1589. #endif//#ifdef DP_MSAC_C2
  1590. /*****************************************************************************/
  1591. /*  Copyright (C) profichip GmbH 2004. Confidential.                         */
  1592. /*****************************************************************************/