FreeCalypso > hg > freecalypso-citrine
view g23m-aci/dti/dti_kerf.c @ 49:908742e46a7f default tip
README: FC Selenite updates
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 14 Apr 2020 21:55:22 +0000 |
parents | 75a11d740a02 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : DTILIB | Modul : DTI +----------------------------------------------------------------------------- | Copyright 2002 Texas Instruments Berlin, AG | All rights reserved. | | This file is confidential and a trade secret of Texas | Instruments Berlin, AG | The receipt of or possession of this file does not convey | any rights to reproduce or disclose its contents or to | manufacture, use, or sell anything it may describe, in | whole, or in part, without the specific written consent of | Texas Instruments Berlin, AG. +----------------------------------------------------------------------------- | Purpose : Definitions for the Protocol Stack Library | DTI +----------------------------------------------------------------------------- */ /* * Version 1.6 */ #ifndef DTI_KERF_C #define DTI_KERF_C #endif #include "config.h" #include "fixedconf.h" #include "condat-features.h" /*==== CONST =======================================================*/ #include <string.h> #include "typedefs.h" #include "pconst.cdg" #include "vsi.h" #include "custom.h" #include "gsm.h" #include "prim.h" #include "dti.h" #include "dti_int_def.h" #include "dti_int_prot.h" #ifdef FF_TCP_IP #include "atp/atp_api.h" #include "atp/atp_messages.h" #include "aaa.h" #include "dti_atp.h" #include "gprs.h" #include "dti_conn_mng.h" /* for getting EXTRACT_DTI_ID */ #endif /*==== LOCALS ================================================================*/ #ifdef _SIMULATION_ LOCAL void send_data_test_req_or_ind ( DTI_HANDLE hDTI, DTI_LINK *link, T_DTI2_DATA_IND *dti_data_ind ); #endif /* _SIMULATION_ */ #ifdef FF_TCP_IP static BOOL ATP_used_flag; #endif /*==== GLOBALS ===============================================================*/ /* +--------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : DTI_KERF | | STATE : code ROUTINE : dti_init | +--------------------------------------------------------------------+ * * Malloc and set default parameters and specified entity_options for the database * */ GLOBAL DTI_HANDLE dti_init( U8 maximum_links, T_HANDLE handle, U32 entity_options, void (sig_callback( U8 instance, U8 interfac, U8 channel, U8 reason, T_DTI2_DATA_IND *dti_data_ind) ) ) { U16 i; DTI_HANDLE hDTI; DTI_LINK *link, *last_link; trace_function(handle, "dti_init()", entity_options); #if defined ALLOCATE_DATABASE_BLOCK /* * Allocate all needed memory for the DTI Database in one block. */ MALLOC( hDTI, (U16) /* Database */ (sizeof(temp_mem_1) - sizeof(DTI_LINK) + /* Every links */ ((sizeof(temp_mem_2) - sizeof(temp_mem_1))* maximum_links))); /* * Set defaults to the Database. */ set_default_para_data_base(hDTI); /* * Number of links in the Data Base (DTI_DATA_BASE). */ hDTI->max_links = maximum_links; hDTI->handle = handle; hDTI->entity_options = entity_options; /* * Cast the links and init them. */ { U32 link_addr_offset = 0; for(i = 0; i < maximum_links; i++) { if(i == 0) { hDTI->first_link = ((U32) &((temp_mem_1*) hDTI)->tmp_link[i]); link = (DTI_LINK*)hDTI->first_link; init_link_table(link); link_addr_offset = ((U32) &((temp_mem_2*) hDTI)->tmp_link[1]) - ((U32) link); } else { link = link + link_addr_offset; init_link_table(link); } } } #else /* * Allocate the memory over separate blocks. */ MALLOC (hDTI, (U16)(sizeof(DTI_DATA_BASE) - 1)); /* * Set defaults */ set_default_para_data_base(hDTI); /* * Number of links in the Data Base (DTI_DATA_BASE). */ hDTI->max_links = maximum_links; hDTI->handle = handle; hDTI->entity_options = entity_options; /* * Allocate LINK_TABLE for maximum_links and set default parameters */ if(maximum_links > 0) { MALLOC (link, (U16) sizeof(DTI_LINK)); init_link_table(link); hDTI->first_link = (U32) link; for(i = 1; i < maximum_links; i++) { last_link = link; MALLOC (link, (U16) sizeof(DTI_LINK)); init_link_table(link); last_link->next_link = (U32) link; } } #endif #ifdef FF_TCP_IP if (!ATP_used_flag) /* initialise array of references to ATP links */ { for ( i=0; i<MAX_ATP_LINKS; i++) { atp_links[i]= D_LINK; } } #endif /* * Set the callback function for the entity / instance */ hDTI->sig_callback = sig_callback; return hDTI; } /* dti_init() */ /* +--------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : DTI_KERF | | STATE : code ROUTINE : dti_deinit | +--------------------------------------------------------------------+ * * Malloc and set default parameter for the Data Base * */ GLOBAL void dti_deinit( DTI_HANDLE hDTI) { trace_function(hDTI->handle, "dti_deinit()", hDTI->entity_options); if(hDTI EQ D_NO_DATA_BASE) return; #if defined ALLOCATE_DATABASE_BLOCK /* * Free the datablock as a block. */ MFREE (hDTI); #else /* * Free the links of the link table with DTI queue */ free_dti_link_structure(hDTI); /* * Free the DTI_DATA_BASE */ MFREE (hDTI); #endif } /* dti_deinit() */ /* +--------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : DTI_KERF | | STATE : code ROUTINE : acquire_link | +--------------------------------------------------------------------+ * * This function acquires a link */ LOCAL DTI_RESULT acquire_link(DTI_HANDLE hDTI, U32 link_id, U8 direction, DTI_LINK **link) { trace_function(hDTI->handle, "acquire_link()", hDTI->entity_options); if((*link = get_pointer_link_table(hDTI, link_id, direction)) NEQ NULL) return DTI_S_FOUND; if((*link=get_pointer_free_link(hDTI)) NEQ NULL) { set_default_para_link_table (hDTI, *link, link_id, direction); return DTI_S_CREATED_NEW; } /* * No free link and so no connection possible. */ trace_message_link_id(hDTI->handle, "DTI ERROR: No link free in dtilib", link_id, hDTI->entity_options); return DTI_E_FAIL; } /* +--------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : dti_kerf.c | | STATE : code ROUTINE : send_connect_req_or_ind | +--------------------------------------------------------------------+ * PURPOSE: Send a Connect primitive depending on the direction. */ LOCAL void send_connect_req_or_ind (DTI_HANDLE hDTI, DTI_LINK *link) { #define VSI_CALLER hDTI->handle, /* * Check if the link is upwards or downwards * and send the according connect primitive. */ switch(link->direction) { case DTI_CHANNEL_TO_HIGHER_LAYER: { PALLOC (dti_connect_ind, DTI2_CONNECT_IND); dti_connect_ind->link_id = link->link_id; dti_connect_ind->version = link->version; if(hDTI->entity_options & DTI_NO_TRACE) { PSEND_NTRACE(link->link_handle, dti_connect_ind); } else { PSEND(link->link_handle, dti_connect_ind); trace_message_link_id(hDTI->handle, "OUT: DTI2_CONNECT_IND", link->link_id, hDTI->entity_options); } } break; case DTI_CHANNEL_TO_LOWER_LAYER: { PALLOC (dti_connect_req, DTI2_CONNECT_REQ); dti_connect_req->link_id = link->link_id; dti_connect_req->version = link->version; if(hDTI->entity_options & DTI_NO_TRACE) { PSEND_NTRACE(link->link_handle, dti_connect_req); } else { PSEND(link->link_handle, dti_connect_req); trace_message_link_id(hDTI->handle, "OUT: DTI2_CONNECT_REQ", link->link_id, hDTI->entity_options); } } break; default: /* * no known channel type open so do not send anything */ break; } #undef VSI_CALLER } /* send_connect_req_or_ind() */ /* +--------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : dti_kerf.c | | STATE : code ROUTINE : send_connect_res_or_cnf | +--------------------------------------------------------------------+ * PURPOSE: Send a Connect Confirm primitive depending on the direction. */ LOCAL void send_connect_res_or_cnf (DTI_HANDLE hDTI, DTI_LINK *link) { #define VSI_CALLER hDTI->handle, /* * Check if the link is upwards or downwards * and send the according connect primitive. */ switch(link->direction) { case DTI_CHANNEL_TO_HIGHER_LAYER: { PALLOC (dti_connect_cnf, DTI2_CONNECT_CNF); dti_connect_cnf->link_id = link->link_id; dti_connect_cnf->version = link->version; if(hDTI->entity_options & DTI_NO_TRACE) { PSEND_NTRACE(link->link_handle, dti_connect_cnf); } else { PSEND(link->link_handle, dti_connect_cnf); trace_message_link_id(hDTI->handle, "OUT: DTI2_CONNECT_CNF", link->link_id, hDTI->entity_options); } } break; case DTI_CHANNEL_TO_LOWER_LAYER: { PALLOC (dti_connect_res, DTI2_CONNECT_RES); dti_connect_res->link_id = link->link_id; dti_connect_res->version = link->version; if(hDTI->entity_options & DTI_NO_TRACE) { PSEND_NTRACE(link->link_handle, dti_connect_res); } else { PSEND(link->link_handle, dti_connect_res); trace_message_link_id(hDTI->handle, "OUT: DTI2_CONNECT_RES", link->link_id, hDTI->entity_options); } } break; default: /* * no known channel type open so do not send anything */ break; } #undef VSI_CALLER } /* send_connect_res_or_cnf() */ /* +-------------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : DTI_KERF | | STATE : code ROUTINE : send_open_ready_callback | +-------------------------------------------------------------------------+ * * Activate connection_opened and tx_buffer_ready callback funktions. */ LOCAL void send_open_ready_callback(DTI_HANDLE hDTI, DTI_LINK *link) { #ifdef FF_TCP_IP /* * trigger DTI Primitive transmission separatly, because it can not be done by ATP */ if(link->link_type EQ RIVIERA_ATP_LINK) { PALLOC(dti_ready_ind, DTI2_READY_IND); dti_ready_ind->link_id = link->link_id; #define VSI_CALLER 0, PSEND_NTRACE(link->link_handle, dti_ready_ind); #undef VSI_CALLER /* * stop ATP reception Flow Control */ TRACE_EVENT("initial: ATP_RX_FLOW_OFF"); atp_set_signal(hDTI->entity_id_p, link->port_nb, ATP_RX_FLOW_OFF, ATP_RX_FLOW_UNMASK); } #endif /* FF_TCP_IP */ /* * send indication for the open connection */ hDTI->sig_callback( link->instance, link->interfac, link->channel, DTI_REASON_CONNECTION_OPENED, NULL); /* * Call the callback function with the signal tx_buffer_ready * if the queue is used and not full */ if((link->direction EQ DTI_NULL_LINK) OR ((link->queue_len < link->queue_size) OR (link->link_options EQ DTI_QUEUE_UNBOUNDED))) { link->tx_state = DTI_TX_IDLE; hDTI->sig_callback( link->instance, link->interfac, link->channel, DTI_REASON_TX_BUFFER_READY, NULL ); } } /* send_open_ready_callback() */ /* +--------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : DTI_KERF | | STATE : code ROUTINE : dti_open | +--------------------------------------------------------------------+ * * This function opens or resets a DTI connection. * */ GLOBAL BOOL dti_open (DTI_HANDLE hDTI, U8 instance, U8 interfac, U8 channel, U8 queue_size, U8 direction, U32 link_options, U32 version, U8 *neighbor_entity, U32 link_id) { DTI_LINK *link; BOOL send_req_or_ind = FALSE; BOOL send_res_or_cnf = FALSE; BOOL open_vsi_channel = FALSE; BOOL riviera_atp_channel = FALSE; /* came by DAA hack */ #ifdef BT_ADAPTER BOOL riviera_bt_channel = FALSE; /* came by dirty BT interface hack */ #endif /* riviera_bt_channel */ U8 signal = DTI_NO_SIGNAL; trace_function(hDTI->handle, "dti_open()", hDTI->entity_options); trace_message_l_e(hDTI->handle, "open connection", link_id, (char*)neighbor_entity, hDTI->entity_options); #ifdef BT_ADAPTER /* * Check if open with a riviera entity. */ if (strcmp ((CHAR*)neighbor_entity, BTI_NAME) EQ 0) { riviera_bt_channel = TRUE; } #endif /* BT_ADAPTER */ #ifdef FF_TCP_IP TRACE_EVENT_P5 ("dti_open: QS:%d DIR:%d LOPT:%d NE:%s LID:%d V:4", queue_size, direction, link_options, neighbor_entity, link_id); if (strcmp ((CHAR*)neighbor_entity, RIV_NAME) EQ 0) { riviera_atp_channel = TRUE; TRACE_EVENT("Riviera link to be opened!"); } #endif /* FF_TCP_IP */ /* * Validate and correct passed parameters */ if(validate_open_parameters(hDTI, link_id, &queue_size, &direction, &link_options, version, neighbor_entity) EQ DTI_E_FAIL) { return FALSE; } /* * Find a link with the given link_id and direction */ switch (acquire_link (hDTI, link_id, direction, &link) ) { case DTI_S_FOUND: /* * Found already existing link */ switch (link->connect_state) { case DTI_CLOSING: link->connect_state = DTI_IDLE; /* fall through */ case DTI_IDLE: /* * Reset the link and set the parameter. */ trace_message(hDTI->handle, "existing DTI connection is being reset!", hDTI->entity_options); set_open_para_link_table(hDTI, link, version, link_options, instance, interfac, channel, queue_size, DTI_IDLE); /* * Send a confirm primitive if we use SAP DTI2.DOC. Then also set the parameter. */ send_req_or_ind = TRUE; signal = DTI_REASON_CONNECTION_OPENED; if (link->direction NEQ DTI_NULL_LINK) { /* * Close the old channel. */ vsi_c_close (hDTI->handle, link->link_handle); } /* * Set the flag to open a new channel. */ open_vsi_channel = TRUE; break; case DTI_SETUP: /* * Collision of DTI2_CONNECT_REQ and DTI2_CONNECT_IND. The parameters * have been set in dti_open before. They stay in this state. */ break; case DTI_CLOSED: /* * Start with connecting */ set_open_para_link_table ( hDTI, link, version, link_options, instance, interfac, channel, queue_size, DTI_SETUP ); link->connect_state = DTI_SETUP; send_req_or_ind = TRUE; open_vsi_channel = TRUE; break; case DTI_CONNECTING: /* * Got a connecting primitive, send a confirm primitive and set the parameter. */ set_open_para_link_table ( hDTI, link, version, link_options, instance, interfac, channel, queue_size, DTI_IDLE ); send_res_or_cnf = TRUE; signal = DTI_REASON_CONNECTION_OPENED; open_vsi_channel = TRUE; break; default: /* * Wrong state */ trace_message_link_id(hDTI->handle, "DTI ERROR: Wrong state of dtilib", link_id, hDTI->entity_options); break; } break; /* * Created new link */ case DTI_S_CREATED_NEW: /* * Open the requested channel and send a req/ind primitive. */ open_vsi_channel = TRUE; /* * DTILIB can handle DTI SAP DTI.DOC and DTI2.DOC. By using DTI.DOC (the old * SAP) the parameter are set but the connect primitives are not supported. * * SAP DTI.DOC does also not support a queue. So the queue len is set to * 0 in the function set_link_parameter(). */ set_open_para_link_table ( hDTI, link, version, link_options, instance, interfac, channel, queue_size, DTI_SETUP ); send_req_or_ind = TRUE; break; default: /* * No free link - no connection possible. */ return FALSE; } /*lint !e788 enum constant not used */ /* in case of RIV link, get parameters from AAA */ #ifdef FF_TCP_IP if( riviera_atp_channel) { link->link_type = RIVIERA_ATP_LINK; link->entity_db = hDTI; /* remember the entity the link belongs to */ link->dti_id = EXTRACT_DTI_ID(link_id); /* link->link_options = FLOW_CNTRL_DISABLED; */ /* to avoid the full DTI state machine */ /* get the parameters valid within RIV environment from AAA */ if(!aaa_get_connection_data( link->dti_id, &(link->port_nb), &(hDTI->entity_id_p), &(hDTI->own_name))) { TRACE_ERROR("aaa_get_connection_data() failed!"); } else { TRACE_EVENT_P2("got connection_data: name: %s, link_id: %d", (char*) (hDTI->own_name), link->link_id); } if(hDTI->handle EQ PEI_ERROR) { TRACE_ERROR("error getting my own entity handle!"); } } #endif /* mark links connection type */ if( !riviera_atp_channel #ifdef BT_ADAPTER AND !riviera_bt_channel #endif ) /*lint !e774 (Info -- Boolean within 'if' always evaluates to True), only used for FF_TCP_IP/BT */ { link->link_type = ENTITY_LINK; } /* * link to BlueTooth */ #ifdef BT_ADAPTER if(riviera_bt_channel) { link->link_type = RIVIERA_BT_LINK; } #endif /* * Open a channel to VSI. If it is not possible to open, return FALSE to the entity * so that the entity can try again. */ if(open_vsi_channel) { /* * If NULL device then disable flow control */ if(direction EQ DTI_NULL_LINK) { trace_message(hDTI->handle, "DTI connection is to be opened for NULL device", hDTI->entity_options); /* * it is not exactly necessary to set this here, * but only a logical consequence */ link->link_options = DTI_FLOW_CNTRL_DISABLED; link->link_type = NULL_LINK; link->connect_state = DTI_IDLE; /* * Activate callback function with reason_connection_opened * and, additionally, signal tx_buffer_ready if the queue is used. */ send_open_ready_callback(hDTI, link); return TRUE; } if (link->link_type EQ ENTITY_LINK) /* check for connection within GPF */ { open_comm_channel(hDTI->handle, &link->link_handle, (char *) neighbor_entity, hDTI->entity_options); } #ifdef FF_TCP_IP else if (link->link_type EQ RIVIERA_ATP_LINK) /* check for connection towards Riv */ { link->dti_data_ind = NULL; link->connect_state = DTI_IDLE; /* we don't use connect prims here, */ /* so set it by hand */ signal = DTI_REASON_CONNECTION_OPENED; send_res_or_cnf = FALSE; send_req_or_ind = FALSE; open_comm_channel( hDTI->handle, /* open com handle to hDTI-entity */ &link->link_handle, (char *) hDTI->own_name, hDTI->entity_options); /* the port has already been opened by AAA, so only remember link as leading to ATP, * for sending data or events 'backwards' to that entity */ if(link->link_handle >= VSI_OK) { if(atp_links[link->port_nb] EQ D_LINK) { atp_links[link->port_nb] = link; ATP_used_flag = TRUE; } else { TRACE_ERROR("link reference could not be saved for DAA"); } } } #endif if(link->link_handle < VSI_OK) { trace_message_link_id(hDTI->handle, "DTI ERROR: open a comm channel not possible", link_id, hDTI->entity_options); set_default_para_link_table(hDTI, link, D_FREE_LINK_ID, D_DIRECTION); return FALSE; } #ifdef BT_ADAPTER if(link->link_type EQ RIVIERA_BT_LINK) /* connection links into RIV environment */ { /* xxxx: handle new BT link */ } #endif } /* if(open_channel) */ if(send_res_or_cnf) /* shouldn't happen for ATP links! */ { /* Send DTI2_CONNECT_RES or DTI2_CONNECT_CNF */ send_connect_res_or_cnf (hDTI, link); } else if(send_req_or_ind) /* is supposed to happen for ATP links??? */ { /* Send DTI2_CONNECT_REQ or DTI_CONNECT_IND. */ if(link->link_type EQ ENTITY_LINK) { send_connect_req_or_ind (hDTI, link); } } /* * Activate the callback function to the entity. */ if(signal EQ DTI_REASON_CONNECTION_OPENED) { if (!(hDTI->entity_options & DTI_NO_TRACE) ) { trace_message_l_e(hDTI->handle, "DTI connection opened", /*lint !e605 Increase in pointer capability */ link_id, (char*)neighbor_entity, hDTI->entity_options); } /* * Activate callback function with reason_connection_opened * and, additionally, signal tx_buffer_ready if the queue is used. */ send_open_ready_callback (hDTI, link); } return TRUE; } /* +--------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : dti_kerf.c | | STATE : code ROUTINE : send_disconnect_req_or_ind | +--------------------------------------------------------------------+ * PURPOSE: Send a Disconnect primitive depending on the direction. */ LOCAL void send_disconnect_req_or_ind (DTI_HANDLE hDTI, DTI_LINK* link, U8 cause) { #define VSI_CALLER hDTI->handle, /* * Check if the link is upwards or downwards * and send the according disconnect primitive. */ switch (link->direction) { case DTI_CHANNEL_TO_HIGHER_LAYER: { PALLOC (dti_disconnect_ind, DTI2_DISCONNECT_IND); dti_disconnect_ind->link_id = link->link_id; dti_disconnect_ind->cause = cause; if(hDTI->entity_options & DTI_NO_TRACE) { PSEND_NTRACE(link->link_handle, dti_disconnect_ind); } else { PSEND(link->link_handle, dti_disconnect_ind); trace_message_link_id(hDTI->handle, "OUT: DTI2_DISCONNECT_IND", link->link_id, hDTI->entity_options); } } break; case DTI_CHANNEL_TO_LOWER_LAYER: { PALLOC (dti_disconnect_req, DTI2_DISCONNECT_REQ); dti_disconnect_req->link_id = link->link_id; dti_disconnect_req->cause = cause; if(hDTI->entity_options & DTI_NO_TRACE) { PSEND_NTRACE(link->link_handle, dti_disconnect_req); } else { PSEND(link->link_handle, dti_disconnect_req); trace_message_link_id(hDTI->handle, "OUT: DTI2_DISCONNECT_REQ", link->link_id, hDTI->entity_options); } } break; default: /* * no known channel type open so do not send anything */ break; } #undef VSI_CALLER } /* send_disconnect_req_or_ind() */ /* +--------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : dti_kerf.c | | STATE : code ROUTINE : send_ready_req_or_ind | +--------------------------------------------------------------------+ * PURPOSE: Send a Flow Control primitive depending on the direction. */ LOCAL void send_ready_req_or_ind (DTI_HANDLE hDTI, DTI_LINK *link) { #define VSI_CALLER hDTI->handle, #ifdef FF_TCP_IP /* * do not send flow control primitives in case of riviera link * but send a Data primitive to trigger next data reception * this is needed because ATP may has sent data * where DTILIB was not initialized yet */ if(link->link_type EQ RIVIERA_ATP_LINK) { PALLOC(dti_data_ind, DTI2_DATA_IND); dti_data_ind->link_id = link->link_id; dti_data_ind->desc_list2.list_len = 0; dti_data_ind->desc_list2.first = (U32)NULL; PSEND(link->link_handle, dti_data_ind); return; } #endif /* FF_TCP_IP */ /* * Check if the link is upwards or downwards * and send the according connect primitive. */ switch (link->direction) { case DTI_CHANNEL_TO_HIGHER_LAYER: #ifdef BT_ADAPTER if(link->link_type EQ RIVIERA_BT_LINK) { btidti_getdata_req(link_id); } else #endif /* BT_ADAPTER */ { if(link->link_type EQ ENTITY_LINK) { PALLOC (dti_ready_ind, DTI2_READY_IND); dti_ready_ind->link_id = link->link_id; if(hDTI->entity_options & DTI_NO_TRACE) { PSEND_NTRACE(link->link_handle, dti_ready_ind); } else { PSEND(link->link_handle, dti_ready_ind); trace_message_link_id(hDTI->handle, "OUT: DTI2_READY_IND", link->link_id, hDTI->entity_options); } } } break; case DTI_CHANNEL_TO_LOWER_LAYER: #ifdef BT_ADAPTER if(link->link_type EQ RIVIERA_BT_LINK) { btidti_getdata_req(link_id); } else #endif /* BT_ADAPTER */ { if(link->link_type EQ ENTITY_LINK) { PALLOC (dti_getdata_req, DTI2_GETDATA_REQ); dti_getdata_req->link_id = link->link_id; if(hDTI->entity_options & DTI_NO_TRACE) { PSEND_NTRACE(link->link_handle, dti_getdata_req); } else { PSEND(link->link_handle, dti_getdata_req); trace_message_link_id(hDTI->handle, "OUT: DTI2_GETDATA_REQ", link->link_id, hDTI->entity_options); } } } break; default: /* * no known channel type open so do not send anything */ break; } #undef VSI_CALLER } /* send_ready_req_or_ind() */ /* +--------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : DTI_KERF | | STATE : code ROUTINE : dti_close | +--------------------------------------------------------------------+ * * The function searchs a link in the databank link list and closes it. * Then it calls the callback function with the signal DTI_REASON_CONNECTION_CLOSED. */ GLOBAL void dti_close (DTI_HANDLE hDTI, U8 instance, U8 interfac, U8 channel, BOOL flush) { DTI_LINK *link; trace_function( hDTI->handle, "dti_close()", hDTI->entity_options); /* * Find the link in the database */ if((link = get_pointer_link_table_channel(hDTI, instance, interfac, channel)) NEQ NULL) { trace_message_link_id(hDTI->handle, "closing DTI connection", /*lint !e605 Increase in pointer capability */ link->link_id, hDTI->entity_options); if (link->direction EQ DTI_NULL_LINK) { set_default_para_link_table(hDTI, link, D_FREE_LINK_ID, D_DIRECTION); return; } switch (link->connect_state) { /* * The link is already closed */ case DTI_CLOSED: trace_message_link_id(hDTI->handle, "Link is already closed for this entity", link->link_id, hDTI->entity_options); return; /* * In all other states the entity sends a disconnect primitive */ default: /* * exit only after send queue has been emptied? */ if(flush EQ TRUE) { /* * if it is not empty, wait for data flow primitives * from the peer entity */ if(link->queue_len NEQ 0) { link->connect_state = DTI_CLOSING; return; } else { /* * call the callback function right now. */ hDTI->sig_callback( link->instance, link->interfac, link->channel, DTI_REASON_CONNECTION_CLOSED, NULL ); } } if (link->link_type NEQ RIVIERA_ATP_LINK) /* check for connection towards ATP. The NULL_LINK case is handled * above, already. */ { send_disconnect_req_or_ind (hDTI, link, DTI_CAUSE_NORMAL_CLOSE); } #ifdef FF_TCP_IP else /* the links goes towards Riviera */ { U8 i; atp_links[link->port_nb] = D_LINK; ATP_used_flag = FALSE; for (i=0; i<MAX_ATP_LINKS; i++) { if(atp_links[i] NEQ D_LINK) { ATP_used_flag = TRUE; TRACE_EVENT("there are still open ATP links!"); break; } } } #endif /* FF_TCP_IP */ /* * close the communication channel */ vsi_c_close (hDTI->handle, link->link_handle); /* * Set the default parameter. The channel is closed in the neighbour entity. */ set_default_para_link_table(hDTI,link, D_FREE_LINK_ID, D_DIRECTION); /* * Note: Flow control and data primitives are silently discarded. */ break; } } else { /* * there is no link to be found in the table */ trace_message_iic(hDTI->handle, "DTI link is alredy closed", instance, interfac, channel, hDTI->entity_options); } } /* +--------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : DTI_KERF | | STATE : code ROUTINE : dti_start | +--------------------------------------------------------------------+ * * If the entity wants to receive data primitives, this function must be * called. */ GLOBAL void dti_start( DTI_HANDLE hDTI, U8 instance, U8 interfac, U8 channel) { DTI_LINK *link; trace_function( hDTI->handle, "dti_start()", hDTI->entity_options); /* * Find the link in the database. */ link = get_pointer_link_table_channel(hDTI, instance, interfac, channel); if(link EQ NULL) { /* * Link id is not in the table. */ trace_message_iic(hDTI->handle, "DTI ERROR: dti_start() - No link id in the database", instance, interfac, channel, hDTI->entity_options); return; } /* * Is the entity connected ? */ if(link->connect_state NEQ DTI_IDLE) { trace_message_link_id(hDTI->handle, "DTI ERROR: link is not connected", link->link_id, hDTI->entity_options); return; } /* * Check if the flow control is not used but do nothing. */ if(link->link_options EQ DTI_FLOW_CNTRL_DISABLED) return; /* * Handle the states */ switch(link->rx_state) { case DTI_RX_IDLE: /* * Change the state to indicate ready to receive data. */ link->rx_state = DTI_RX_READY; /* * No flow control primitive was sent. So send one now. * NOTE: The parameter link->direction gives information about the * direction for sending the data. */ send_ready_req_or_ind (hDTI, link); break; case DTI_RX_STOPPED: /* * The entity has stopped the flow control. * The flow control was sent already. * So change state to DTI_RX_READY. */ link->rx_state = DTI_RX_READY; break; case DTI_RX_READY: /* * dti_start() was already called. */ break; default: /* * Unexpected state - set ERROR. */ trace_message_link_id(hDTI->handle, "DTI ERROR: wrong state", link->link_id, hDTI->entity_options); break; } } /* dti_start() */ /* +--------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : DTI_KERF | | STATE : code ROUTINE : dti_stop | +--------------------------------------------------------------------+ * * This function is called if the entity wants to stop receiving of data * primitives. */ GLOBAL void dti_stop( DTI_HANDLE hDTI, U8 instance, U8 interfac, U8 channel) { DTI_LINK *link; trace_function( hDTI->handle, "dti_stop()", hDTI->entity_options); /* * Find the link in the databank. */ link = get_pointer_link_table_channel(hDTI, instance, interfac, channel); /* * It is link id in the table ? */ if(link EQ NULL) { trace_message_iic(hDTI->handle, "DTI ERROR: dti_stop() - No link id in the database", instance, interfac, channel, hDTI->entity_options); return; } /* * Is the entity connected ? */ if(link->connect_state NEQ DTI_IDLE) { trace_message_link_id(hDTI->handle, "DTI ERROR: dti_stop() - link is not connected", link->link_id, hDTI->entity_options); return; } /* * Check if the flow control is not used - then do nothing */ if(link->link_options EQ DTI_FLOW_CNTRL_DISABLED) return; /* * Handle the states */ switch(link->rx_state) { case DTI_RX_READY: /* * The flow control was already sent therefor change to stop state. */ link->rx_state = DTI_RX_STOPPED; break; case DTI_RX_STOPPED: case DTI_RX_IDLE: /* * dti_stop() was already called. * So there is no need to change state. */ break; default: /* * Other state - ERROR */ trace_message_link_id(hDTI->handle, "DTI ERROR: dti_stop() - wrong state", link->link_id, hDTI->entity_options); break; } } /* dti_stop() */ #ifdef _SIMULATION_ /* +--------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : dti_kerf.c | | STATE : code ROUTINE : send_data_test_req_or_ind | +--------------------------------------------------------------------+ * PURPOSE: Get a DTI_DATA_IND and translate it to DTI_DATA_TEST_IND * and send it. */ LOCAL void send_data_test_req_or_ind (DTI_HANDLE hDTI, DTI_LINK* link, T_DTI2_DATA_IND* dti_data_ind) { #define VSI_CALLER hDTI->handle, U16 len_buf_bits; U16 i; U16 len; U16 j; T_desc2 *p_desc; trace_function(hDTI->handle, "send_data_test_req_or_ind()", hDTI->entity_options); len_buf_bits = dti_data_ind->desc_list2.list_len * 8; /* * Build the SDU primitive and send it */ { PALLOC_SDU (dti_data_test_ind, DTI2_DATA_TEST_IND, len_buf_bits); memset (dti_data_test_ind, 0, sizeof (T_DTI2_DATA_TEST_IND)); dti_data_test_ind->link_id = dti_data_ind->link_id; dti_data_test_ind->parameters = dti_data_ind->parameters; dti_data_test_ind->sdu.l_buf = len_buf_bits; dti_data_test_ind->sdu.o_buf = 0; /* * Copy the descs into sdu structure. */ if(len_buf_bits > 0) { j = 0; p_desc = (T_desc2*)(dti_data_ind->desc_list2.first); while(p_desc NEQ NULL) { len = p_desc->len; for(i=0; i < len; i++) { dti_data_test_ind->sdu.buf[j] = p_desc->buffer[i]; j++; } p_desc = (T_desc2*)(p_desc->next); } } /* * Check if the link is upwards or downwards * and send the according disconnect primitive. */ switch (link->direction) { case DTI_CHANNEL_TO_HIGHER_LAYER: if(hDTI->entity_options & DTI_NO_TRACE) { PSEND_NTRACE(link->link_handle, dti_data_test_ind); } else { PSEND(link->link_handle, dti_data_test_ind); trace_message_l_dl(hDTI->handle, "OUT: DTI2_DATA_TEST_IND", dti_data_ind->link_id, dti_data_ind->desc_list2.list_len, hDTI->entity_options); } break; case DTI_CHANNEL_TO_LOWER_LAYER: if(hDTI->entity_options & DTI_NO_TRACE) { PPASS_NTRACE(dti_data_test_ind, dti_data_test_req, DTI2_DATA_TEST_REQ); PSEND_NTRACE(link->link_handle, dti_data_test_req); } else { PPASS(dti_data_test_ind, dti_data_test_req, DTI2_DATA_TEST_REQ); PSEND(link->link_handle, dti_data_test_req); trace_message_l_dl(hDTI->handle, "OUT: DTI2_DATA_TEST_REQ", dti_data_ind->link_id, dti_data_ind->desc_list2.list_len, hDTI->entity_options); } break; default: /* * no known channel type open so do not send anything */ break; } } /* * Free the dti_data_ind primitive and the descs in the linked list. */ mfree_desc(hDTI, &dti_data_ind->desc_list2); PFREE (dti_data_ind); #undef VSI_CALLER } /* send_data_test_req_or_ind() */ #endif /* _SIMULATION_ */ /* +--------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : dti_kerf.c | | STATE : code ROUTINE : send_data_req_or_ind | +--------------------------------------------------------------------+ * PURPOSE: Send a Data primitive depending on the direction. */ LOCAL void send_data_req_or_ind (DTI_HANDLE hDTI, DTI_LINK* link, T_DTI2_DATA_IND* dti_data_ind) { #ifndef _SIMULATION_ U32 link_id; U16 list_len; #endif /* !_SIMULATION_ */ #ifdef BT_ADAPTER if(link->link_type EQ RIVIERA_BT_LINK) { btidti_data_req(dti_data_ind); } else #endif /* BT_ADAPTER */ /* * Check if the primitive is directed to a GPF or ATP entity, and send it. */ #ifdef FF_TCP_IP if(link->link_type EQ RIVIERA_ATP_LINK) { dti_send_data_to_atp(hDTI, link, dti_data_ind); return; } #endif /* FF_TCP_IP */ #ifdef _SIMULATION_ send_data_test_req_or_ind(hDTI, link, dti_data_ind); #else /* _SIMULATION_ */ #define VSI_CALLER hDTI->handle, /* * Check if the link is upwards or downwards * and send the according disconnect primitive. */ switch (link->direction) { case DTI_CHANNEL_TO_HIGHER_LAYER: #ifdef BT_ADAPTER if(link->link_type EQ RIVIERA_LINK) { btidti_data_req(dti_data_ind); } else #endif /* BT_ADAPTER */ { if(hDTI->entity_options & DTI_NO_TRACE) { PSEND_NTRACE(link->link_handle, dti_data_ind); } else { link_id = dti_data_ind->link_id; list_len = dti_data_ind->desc_list2.list_len; PSEND(link->link_handle, dti_data_ind); trace_message_l_dl(hDTI->handle, "OUT: DTI2_DATA_IND", link_id, list_len, hDTI->entity_options); } } break; case DTI_CHANNEL_TO_LOWER_LAYER: if(hDTI->entity_options & DTI_NO_TRACE) { PPASS_NTRACE(dti_data_ind, dti_data_req, DTI2_DATA_REQ); PSEND_NTRACE(link->link_handle, dti_data_req); } else { PPASS(dti_data_ind, dti_data_req, DTI2_DATA_REQ); link_id = dti_data_req->link_id; list_len = dti_data_req->desc_list2.list_len; PSEND(link->link_handle, dti_data_req); trace_message_l_dl(hDTI->handle, "OUT: DTI2_DATA_REQ", link_id, list_len, hDTI->entity_options); } break; default: /* * no known channel type open so do not send anything */ break; } #undef VSI_CALLER #endif /* else _SIMULATION_ */ } /* send_data_req_or_ind() */ /* +--------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : DTI_KERF | | STATE : code ROUTINE : dti_send_data | +--------------------------------------------------------------------+ * * This function sends data. If the database direction is set to * DTI_UPLINK then it sends a dti_data_req primitive otherwise a DTI_DATA_IND * primitive. */ GLOBAL void dti_send_data (DTI_HANDLE hDTI, U8 instance, U8 interfac, U8 channel, T_DTI2_DATA_IND *dti_data_ind) { DTI_LINK *link; T_DTI2_DATA_IND *hlp_data_ind; trace_function(hDTI->handle, "dti_send_data()", hDTI->entity_options); /* * Find the link in the database. */ link = get_pointer_link_table_channel(hDTI, instance, interfac, channel); if(link EQ NULL) { /* * link_id is not in the table. */ trace_message_iic(hDTI->handle, "DTI ERROR: dti_send_data() - No link id in the database", instance, interfac, channel, hDTI->entity_options); mfree_desc(hDTI, &dti_data_ind->desc_list2); PFREE (dti_data_ind); return; } /* * Is the entity connected ? */ if(link->connect_state NEQ DTI_IDLE) { trace_message_link_id(hDTI->handle, "DTI ERROR: dti_send_data() - link is not connected", link->link_id, hDTI->entity_options); mfree_desc(hDTI, &dti_data_ind->desc_list2); PFREE (dti_data_ind); return; } /* * If link is a NULL device then just free the message */ if (link->direction EQ DTI_NULL_LINK) { mfree_desc (hDTI, &dti_data_ind->desc_list2); PFREE (dti_data_ind); return; } /* * There is no flow control, so the primitive doesn't get into the queue * and has to get sent at once. */ if(link->link_options EQ DTI_FLOW_CNTRL_DISABLED) { send_data_req_or_ind(hDTI, link, dti_data_ind); return; } switch (link->tx_state) { case DTI_TX_IDLE: case DTI_TX_BUFFER_FULL: /* * While waiting for a flow control primitive no sending is possible. * Put the primitive dti_data_ind in the queue. */ put_dti_data_ind_in_queue_managed (hDTI, link, dti_data_ind); break; case DTI_TX_FLOW: /* * The flow control primitive is already received. * So just send Data primitive and change state. * Because of ATP links there might be still a prim in the queue * therefore we have to use the queue for this */ put_dti_data_ind_in_queue(hDTI, link, dti_data_ind); /* * Read the last packet from the queue and send it. */ { hlp_data_ind = get_dti_data_ind_from_queue(hDTI, link); hlp_data_ind->link_id = link->link_id; /* * The packet will be sent. Now change the state to DTI_TX_IDLE. */ link->tx_state = DTI_TX_IDLE; /* * Send the primitive depending on its direction. */ send_data_req_or_ind(hDTI, link, hlp_data_ind); } break; default: /* * Unknown state.. */ trace_message_link_id(hDTI->handle, "DTI ERROR: dti_send_data() - wrong state", link->link_id, hDTI->entity_options); mfree_desc(hDTI, &dti_data_ind->desc_list2); PFREE (dti_data_ind); break; } /* * if queue is full now, send a warning callback */ if((link->queue_len >= link->queue_size) AND (link->link_options NEQ DTI_QUEUE_UNBOUNDED)) { link->tx_state = DTI_TX_BUFFER_FULL; hDTI->sig_callback(link->instance, link->interfac, link->channel, DTI_REASON_TX_BUFFER_FULL, NULL); } } /* dti_send_data() */ /* +--------------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : DTI_KERF | | STATE : code ROUTINE : flow_control_prim_received | +--------------------------------------------------------------------------+ PURPOSE : Process primitives DTI_GETDATA_REQ and DTI_READY_IND received from neighbour DTI */ GLOBAL void flow_control_prim_received (DTI_HANDLE hDTI, U32 link_id, U8 direction) { DTI_LINK* link; T_DTI2_DATA_IND* dti_data_ind; trace_function(hDTI->handle, "flow_control_prim_received()", hDTI->entity_options); /* * get link pointer */ link = get_pointer_link_table(hDTI, link_id, direction); if(link EQ NULL) { /* * There is no link_id which requested to the link_id in the link_table. */ trace_message_link_id(hDTI->handle, "DTI ERROR: fc_prim - No link in data base", link_id, hDTI->entity_options); return; } /* * check for valid link * the link is valid if it is in IDLE or CLOSING state * Flow Control primitives are unexpected if Flow Control is disabled */ if(((link->connect_state NEQ DTI_IDLE) AND (link->connect_state NEQ DTI_CLOSING)) OR (link->link_options EQ DTI_FLOW_CNTRL_DISABLED)) { TRACE_EVENT_P4("HORST=7, weil: connect_state %d, link_options %d, link_id %u, direction %d", link->connect_state, link->link_options, link_id, direction); return; } /* * get next prim from queue */ dti_data_ind = get_dti_data_ind_from_queue(hDTI, link); /* * Select the state. */ switch (link->tx_state) { case DTI_TX_IDLE: case DTI_TX_FLOW: /* * A flow control primitive is received. Send a data packet * if there is any in the queue or change the state. * In case of an RIVIERA_ATP_LINK it is necessary to check the send queue * also in DTI_TX_FLOW state */ if(dti_data_ind NEQ NULL) { /* * Select link_id and send data. */ dti_data_ind->link_id = link->link_id; send_data_req_or_ind(hDTI, link, dti_data_ind); /* * Stay in this state. */ } else { /* * Change the state because there is a flow control primitive * and no packet has been sent. */ link->tx_state = DTI_TX_FLOW; } break; case DTI_TX_BUFFER_FULL: /* * The buffer had been full. Send packets from queue and signal ready */ if(dti_data_ind NEQ NULL) { /* * Select link_id and send data. */ dti_data_ind->link_id = link->link_id; send_data_req_or_ind(hDTI, link, dti_data_ind); /* * Change the state if the queue is ready * to get the next data from the entity */ if(link->queue_len < link->queue_size) { link->tx_state = DTI_TX_IDLE; } } else { /* * Change the state because there is a flow control primitive * and no packet has been sent. */ link->tx_state = DTI_TX_FLOW; } /* * Signal to the callback function that the buffer is ready. */ if((link->connect_state NEQ DTI_CLOSING) AND (link->tx_state NEQ DTI_TX_BUFFER_FULL)) { hDTI->sig_callback(link->instance, link->interfac, link->channel, DTI_REASON_TX_BUFFER_READY, NULL); } break; default: trace_message_link_id(hDTI->handle, "DTI ERROR: Wrong state for flow control primitive", link->link_id, hDTI->entity_options); /* * free whole prim, incl. descs */ if(dti_data_ind NEQ NULL) { mfree_desc(hDTI, (T_desc_list2*) &(dti_data_ind->desc_list2)); PFREE(dti_data_ind); } break; } /* * if the connection is to be closed and the send queue is empty * then close the connection now */ if((link->queue_len EQ 0) AND (link->connect_state EQ DTI_CLOSING)) { send_disconnect_req_or_ind(hDTI, link, DTI_CAUSE_NORMAL_CLOSE); close_link_with_signal(hDTI, link); } } /* flow_control_prim_received() */ /* +--------------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : DTI_KERF | | STATE : code ROUTINE : connect_init_prim_received | +--------------------------------------------------------------------------+ PURPOSE : Process primitives DTI_CONNECT_REQ and DTI_CONNECT_IND received from neighbour DTI */ GLOBAL void connect_init_prim_received (DTI_HANDLE hDTI, U32 link_id, U32 version, U8 direction) { DTI_LINK* link; BOOL send_cnf = FALSE; BOOL send_disc = FALSE; U8 signal = DTI_NO_SIGNAL; trace_function( hDTI->handle, "connect_init_prim_received()", hDTI->entity_options); /* * Check version of peer dtilib */ if(check_dti_version(hDTI, version) EQ FALSE) { trace_message_link_id(hDTI->handle, "DTI ERROR: init_prim - Wrong DTI version", link_id, hDTI->entity_options); /* * Inform peer dtilib that connection failed */ link = get_pointer_link_table(hDTI, link_id, direction); if(link NEQ NULL) { send_disconnect_req_or_ind (hDTI, link, DTI_CAUSE_UNSUPPORTED_VERSION); close_link_with_signal(hDTI, link); } return; } switch (acquire_link (hDTI, link_id, direction, &link) ) { case DTI_S_FOUND: /* * Entry for link_id found, continue connecting procedure */ break; case DTI_S_CREATED_NEW: /* * There is no entry with the requested link_id in the link_table yet. * Wait for call of dti_open(). * The remaining parameters are set in dti_open(). Then the response * primitive will be sent. */ link->connect_state = DTI_CONNECTING; return; default: /* * No free link */ return; } /* * Start up connecting. */ switch (link->connect_state) { case DTI_IDLE: /* * Reset the link and send a response primitive, free the data packets, * and call the callback funktion. */ set_reset_req_para_link_table(hDTI, link); send_cnf = TRUE; signal = DTI_REASON_CONNECTION_OPENED; trace_message_link_id(hDTI->handle, "DTI connection opened", link->link_id, hDTI->entity_options); break; case DTI_SETUP: /* * Collision ! The neighbour entity has sent a dti_connect_ind * primitive as well which means the neighbor enitiy is willing to connect as well. * So we send a response and open the connection. */ link->connect_state = DTI_IDLE; send_cnf = TRUE; signal = DTI_REASON_CONNECTION_OPENED; link->rx_state = DTI_RX_IDLE; trace_message_link_id(hDTI->handle, "DTI connection opened", link->link_id, hDTI->entity_options); break; case DTI_CLOSING: /* * because of the connect request, internal buffers * are being reset. Thus, the send queue is empty now * and the connection can be closed down. * there has to be a confirmation for the connect * primitive anyway */ send_disc = TRUE; send_cnf = TRUE; break; case DTI_CLOSED: /* * dti_open() is not called yet. The confirm primitive will * be sent then and the parameter will be set. */ link->connect_state = DTI_CONNECTING; break; default: trace_message_link_id(hDTI->handle, "DTI ERROR: init_prim - Wrong state dtilib", link_id, hDTI->entity_options); break; } /* * Send the confirm primitive. */ if (send_cnf) { send_connect_res_or_cnf (hDTI, link); } /* * Send the disconnect primitive. */ if (send_disc) { send_disconnect_req_or_ind (hDTI, link, DTI_CAUSE_NORMAL_CLOSE); close_link_with_signal(hDTI, link); /* * No more signals to be sent in this case.. */ return; } /* * Activate callback function with reason_connection_opened * and, additionally, signal tx_buffer_ready if the queue is used. */ if(signal EQ DTI_REASON_CONNECTION_OPENED) { send_open_ready_callback (hDTI, link); } } /* connect_init_prim_received() */ /* +--------------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : DTI_KERF | | STATE : code ROUTINE : connect_confirm_prim_received | +--------------------------------------------------------------------------+ PURPOSE : Process primitives DTI_CONNECT_RES and DTI_CONNECT_CNF received from neighbour DTI */ GLOBAL void connect_confirm_prim_received (DTI_HANDLE hDTI, U32 link_id, U32 version, U8 direction) { DTI_LINK* link; U8 signal = DTI_NO_SIGNAL; trace_function(hDTI->handle, "connect_confirm_prim_received()", hDTI->entity_options); /* * Note: No need to check the version because this has already been done * by the primitives dti_connect_req and dti_connect_ind. */ if((link = get_pointer_link_table(hDTI, link_id, direction)) EQ NULL) { trace_message_link_id(hDTI->handle, "DTI ERROR: cnf_prim - No link in dtilib", link_id, hDTI->entity_options); return; } /* * The link is in the list so check the state. */ switch (link->connect_state) { case DTI_SETUP: /* * The entity can now enter the final state. The entity connection * is established. */ link->connect_state = DTI_IDLE; signal = DTI_REASON_CONNECTION_OPENED; link->rx_state = DTI_RX_IDLE; trace_message_link_id(hDTI->handle, "DTI connection opened", link->link_id, hDTI->entity_options); break; case DTI_CLOSED: case DTI_IDLE: /* * We are already in the final state. So there is nothing to do here. */ break; default: trace_message_link_id(hDTI->handle, "DTI ERROR: cnf_prim - Wrong state dtilib", link_id, hDTI->entity_options); break; } /* * Activate callback function with reason_connection_opened * and, additionally, signal tx_buffer_ready if the queue is used. */ if(signal EQ DTI_REASON_CONNECTION_OPENED) { send_open_ready_callback (hDTI, link); } } /* connect_confirm_prim_received() */ /* +--------------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : DTI_KERF | | STATE : code ROUTINE : disconnect_prim_received | +--------------------------------------------------------------------------+ PURPOSE : Process primitives DTI_DISCONNECT_IND and DTI_DISCONNECT_REQ received from neighbour DTI */ GLOBAL void disconnect_prim_received (DTI_HANDLE hDTI, U32 link_id, U8 direction) { DTI_LINK *link; trace_function(hDTI->handle, "disconnect_prim_received()", hDTI->entity_options); /* * Is the link in the link list ? */ if((link = get_pointer_link_table( hDTI, link_id, direction) ) NEQ NULL) { switch (link->connect_state) { /* * Link is already closed. */ case DTI_CLOSED: trace_message_link_id(hDTI->handle, "DTI link alredy closed", link->link_id, hDTI->entity_options); break; /* * Close the link. */ default: close_link_with_signal(hDTI, link); break; } } } /* +--------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : DTI_KERP | | STATE : code ROUTINE : data_prim_received | +--------------------------------------------------------------------+ * * Process primitives DTI_DATA_REQ and DTI_DATA_IND received from DTI peer */ GLOBAL void data_prim_received(DTI_HANDLE hDTI, T_DTI2_DATA_IND *dti_data_ind, U8 direction) { DTI_LINK *link; U32 link_id; trace_function(hDTI->handle, "data_prim_received()", hDTI->entity_options); /* * Check if old or new SAP is supported. */ link_id = dti_data_ind->link_id; /* * Is the link in the link list ? */ link = get_pointer_link_table(hDTI, link_id, direction); if(link EQ NULL) { /* * The link_id is not in the list of ids. */ trace_message_link_id(hDTI->handle, "DTI ERROR: data_prim - No link in data base", link_id, hDTI->entity_options); /* * Just ignore the received data primitive. */ mfree_desc(hDTI, &dti_data_ind->desc_list2); PFREE(dti_data_ind); return; } /* * If there is no connection silently discard primitive. */ if(link->connect_state NEQ DTI_IDLE) { trace_message_link_id(hDTI->handle, "DTI ERROR: data_prim_received() - link is not connected", link->link_id, hDTI->entity_options); /* * Just ignore the received data primitive. */ mfree_desc(hDTI, &dti_data_ind->desc_list2); PFREE(dti_data_ind); return; } /* * Check if no flow control should be supported. Pass the primitive at once * to the entity over the callback function. */ if(link->link_options EQ DTI_FLOW_CNTRL_DISABLED) { hDTI->sig_callback(link->instance, link->interfac, link->channel, DTI_REASON_DATA_RECEIVED, dti_data_ind); return; } #ifdef FF_TCP_IP /* * Get primitive content in case it is a RIVIERA_ATP_LINK */ if(link->link_type EQ RIVIERA_ATP_LINK) { if((link->rx_state EQ DTI_RX_READY) OR (link->rx_state EQ DTI_RX_STOPPED)) { /* * DTI does not really know if there is data available * In case there is no ATP data the list_len value is set to 0 */ get_data_from_atp(hDTI, link, dti_data_ind); if(dti_data_ind->desc_list2.list_len EQ 0) { /* * there is no data in the ATP buffer any more * so release the primitive and start ATP flow control again */ mfree_desc(hDTI, &dti_data_ind->desc_list2); PFREE (dti_data_ind); TRACE_EVENT("atp_set_signal: ATP_RX_FLOW_ON"); atp_set_signal(hDTI->entity_id_p, link->port_nb, ATP_RX_FLOW_ON, ATP_RX_FLOW_UNMASK); return; } } else { /* * the entity has stopped data flow * currently it is not allowed to receive data */ mfree_desc(hDTI, &dti_data_ind->desc_list2); PFREE (dti_data_ind); return; } } #endif /* FF_TCP_IP */ /* * Handle the states. */ switch(link->rx_state) { case DTI_RX_READY: /* * Receive dti_data_ind, give a signal and send flow control primitive. */ hDTI->sig_callback(link->instance, link->interfac, link->channel, DTI_REASON_DATA_RECEIVED, dti_data_ind); /* * Check if the entity has stoped during the callback. * If yes do not send a flow control. */ if(link->rx_state EQ DTI_RX_READY) { send_ready_req_or_ind(hDTI, link); } else { link->rx_state = DTI_RX_IDLE; } break; case DTI_RX_STOPPED: /* * The entity has stoped the communication but the flow control primitive to * the neighbour entity was sent. The last dti_data_ind signal must be sended * to the entity. DTILIB change to DTI_RX_IDLE. */ link->rx_state = DTI_RX_IDLE; hDTI->sig_callback(link->instance, link->interfac, link->channel, DTI_REASON_DATA_RECEIVED, dti_data_ind); break; default: trace_message_link_id(hDTI->handle, "DTI ERROR: Wrong state for dti_data_ind primitive", link_id, hDTI->entity_options); mfree_desc(hDTI, &dti_data_ind->desc_list2); PFREE (dti_data_ind); break; } } /* data_prim_received() */ #ifdef _SIMULATION_ /* +--------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : DTI_KERP | | STATE : code ROUTINE : data_test_prim_received | +--------------------------------------------------------------------+ PURPOSE : Process primitives DTI_DATA_TEST_REQ and DTI_DATA_TEST_IND received from neighbour DTI */ GLOBAL void data_test_prim_received (DTI_HANDLE hDTI, T_DTI2_DATA_TEST_IND *dti_data_test_ind, U8 direction) { USHORT len_buff, offset, i; T_desc2 *test_desc; trace_function(hDTI->handle, "data_test_prim_received()", hDTI->entity_options); /* * Fill in dti_data_ind the structure. */ { PALLOC (dti_data_ind, DTI2_DATA_IND); dti_data_ind->link_id = dti_data_test_ind->link_id; dti_data_ind->parameters = dti_data_test_ind->parameters; len_buff = dti_data_test_ind->sdu.l_buf>>3; offset = dti_data_test_ind->sdu.o_buf>>3; /* * Build a new desc and fill in the parameter. */ dti_make_new_desc(hDTI, &test_desc, len_buff, TRUE); for(i=0; i < len_buff; i++) test_desc->buffer[i] = dti_data_test_ind->sdu.buf[i+offset]; dti_data_ind->desc_list2.list_len = len_buff; dti_data_ind->desc_list2.first = (ULONG) test_desc; /* * Handle the primitive. */ PFREE (dti_data_test_ind); data_prim_received (hDTI, dti_data_ind, direction); } } #endif /* _SIMULATION_ */ /* +-------------------------------------------------------------------------+ | PROJECT : DTILIB MODULE : DTI_KERF | | STATE : code ROUTINE : vsi_c_psend_ntrace | +-------------------------------------------------------------------------+ * * vsi_c_psend without traces */ #ifdef MEMORY_SUPERVISION GLOBAL SHORT vsi_c_psend_ntrace ( T_HANDLE Caller, T_HANDLE ComHandle, T_VOID_STRUCT *ptr, ULONG MsgLen, const char *file, int line ) #else /* MEMORY_SUPERVISION */ GLOBAL SHORT vsi_c_psend_ntrace ( T_HANDLE Caller, T_HANDLE ComHandle, T_VOID_STRUCT *ptr, ULONG MsgLen ) #endif /* MEMORY_SUPERVISION */ { T_QMSG QMsg; QMsg.Msg.Primitive.Prim = (T_VOID_STRUCT*)(D2P(ptr)); QMsg.Msg.Primitive.PrimLen = MsgLen; QMsg.MsgType = MSG_PRIMITIVE; #ifdef MEMORY_SUPERVISION return ( vsi_c_send ( Caller, ComHandle, &QMsg, file, line) ); #else return ( vsi_c_send ( Caller, ComHandle, &QMsg) ); #endif /* MEMORY_SUPERVISION */ }