📄 ttp.c
字号:
kal_uint8 status;
#ifdef IRDA_KAL_TRACE
kal_trace(TRACE_FUNC, IRDA_MSG78);
#endif
/* parse received message */
if(rx_msg.local_para_ptr!=NULL)
{
tmp_local_para = (irda_local_para_struct *) rx_msg.local_para_ptr;
local_lsap_sel = tmp_local_para->local_lsap_sel;
remote_lsap_sel = tmp_local_para->remote_lsap_sel;
lm_con[local_lsap_sel].sel=remote_lsap_sel;
lm_con[local_lsap_sel].discon_code=tmp_local_para->disconnect_reason;
}
switch (rx_msg.msg_id)
{
case MSG_ID_TTP_DATA_REQUEST:
if (lm_con[local_lsap_sel].cc_state==IRDA_LMP_CC_ACTIVE)
{
extern kal_int16 new_size;/*MAX LAP size that remote side accepts.*/
kal_uint32 segment_count, left, i;
pdu_ptr=(kal_uint8 *) get_pdu_ptr(rx_msg.peer_buff_ptr, &pdu_length);
/*segment count*/
segment_count=pdu_length/(new_size-3);/*2LMP+1TTP*/
left=pdu_length%(new_size-3);/*2LMP+1TTP*/
if(left!=0)
segment_count++;
kal_prompt_trace(MOD_TTP,"segment_count %d",segment_count);
ctrl_buff_cnt++; /*un_freed control buff count*/
dbg_ctrl_buff_count++;
hold_peer_buff(rx_msg.peer_buff_ptr);
for(i=0;i<segment_count;i++)
{
/*copy data and add size field*/
tmpbuf=Getbuf();
//tmpbuf->size=pdu_length+1;/*1 for TTP header*/
tmpbuf->type=CONTROL_BUF_TYPE;/*special patten*/
tmpptr=(kal_uint8 *)tmpbuf+FBUF_HEAD+5;/*2 for AC 2 for LMP 1 for TTP*/
//xmemcpy((kal_uint8*)(tmpptr),(kal_uint8*)(pdu_ptr),(pdu_length));
if(pdu_length>(new_size-3))
{
tmpbuf->size=(new_size-3)+1;/*1 for TTP header*/
xmemcpy((kal_uint8*)(tmpptr),(kal_uint8*)(pdu_ptr+i*(new_size-3)),
(new_size-3));
pdu_length=pdu_length-(new_size-3);
kal_prompt_trace(MOD_TTP,"segment no %d len %d ",i, (new_size-3));
}
else
{
tmpbuf->size=pdu_length+1;/*1 for TTP header*/
xmemcpy((kal_uint8*)(tmpptr),(kal_uint8*)(pdu_ptr+i*(new_size-3)),
(pdu_length));
kal_prompt_trace(MOD_TTP,"segment no %d len %d",i, pdu_length);
}
QUEUE_ADD(lm_con[local_lsap_sel].ttp_txq,tmpbuf,MAX_TTP_FRAMES);
}
QUEUE_ADD(ctrl_buff_q,rx_msg.peer_buff_ptr,MAX_TTP_FRAMES);
process_ttp_tx_queue(local_lsap_sel);
}
else/*error CC state*/
{
/*upper layer doesn't need this information*/
//ttp_send_msg_to_upper_layer(MSG_ID_TTP_CONNECT_CONFIRM,NULL,IRDA_WRONG_CC_STATE_ERROR);
gprs_flc_free_peer_buff (
IRDA_DATA,
0,
GPRS_FLC_UL,
0,
rx_msg.peer_buff_ptr);
}
break;
case MSG_ID_TTP_CONNECT_REQUEST:
if (lm_con[local_lsap_sel].cc_state==IRDA_LMP_CC_READY)
{
if (!tmpbuf)
{
tmpbuf=Getbuf();
ASSERT(tmpbuf); /*assert if out of buffer */
tmpbuf->size=1;
}
else
{
tmpbuf->size+=1; /* add TTP header size */
}
tmpptr=(kal_uint8 *) tmpbuf + TTP_OP_CREDIT_OFFSET;/*begin of TTP header*/
lm_con[local_lsap_sel].ttp_dat.ttp_connected=0;
lm_con[local_lsap_sel].ttp_dat.availcredit=0;
lm_con[local_lsap_sel].Rxsdu.size=0;
lm_con[local_lsap_sel].Rxsdu.ttp_busy=0;
lm_con[local_lsap_sel].Rxsdu.ap_busy=0;
gprs_flc_query_fix_size_pool_occupy(IRDA_DATA,
0,
GPRS_FLC_DL,
0,
&is_pool_presence,
0,
&init_buff_count);
tmp = init_buff_count;/*@@@@local policy */
if ( tmp > 127 )/*????will this happen?*/
{
lm_con[local_lsap_sel].ttp_dat.availcredit=tmp-127;
tmp=127;
}
lm_con[local_lsap_sel].ttp_dat.remotecredit = tmp;
tmpptr[0]=tmp; /*????*/ /* set initial credit */
//only used by ircomm
if(rx_msg.peer_buff_ptr!=0)
{
pdu_ptr=(kal_uint8 *) get_pdu_ptr(rx_msg.peer_buff_ptr, &pdu_length);
tmpbuf->size += pdu_length;
ctrl_buff_cnt++;
xmemcpy((kal_uint8*)(tmpptr+1),(kal_uint8*)(pdu_ptr),(pdu_length));
tmpbuf->type=CONTROL_BUF_TYPE;
}
status=IrLMP_Connect_Request(local_lsap_sel, remote_lsap_sel, tmpbuf);
if(status!=0)
{
lm_con[local_lsap_sel].ttp_dat.remotecredit=0;
if(rx_msg.peer_buff_ptr!=0)
{
gprs_flc_free_peer_buff (
IRDA_DATA,
0,
GPRS_FLC_UL,
0,
rx_msg.peer_buff_ptr);
ctrl_buff_cnt--;
}
}
else if (rx_msg.peer_buff_ptr!=0 && status==0)
{
QUEUE_ADD(ctrl_buff_q,rx_msg.peer_buff_ptr,MAX_TTP_FRAMES);
hold_peer_buff(rx_msg.peer_buff_ptr);
}
}
else/*wrong CC state*/
{
ttp_send_msg_to_upper_layer(MSG_ID_TTP_CONNECT_CONFIRM,NULL,IRDA_WRONG_CC_STATE_ERROR);
if(rx_msg.peer_buff_ptr!=0)
{
gprs_flc_free_peer_buff (
IRDA_DATA,
0,
GPRS_FLC_UL,
0,
rx_msg.peer_buff_ptr);
}
}
break;
case MSG_ID_TTP_CONNECT_RESPONSE:
if (lm_con[local_lsap_sel].cc_state==IRDA_LMP_CC_INCOMING)
{
if (!tmpbuf)
{
tmpbuf=Getbuf();
ASSERT(tmpbuf); /*assert if out of buffer */
//tmpbuf->size=5;
tmpbuf->size=1;
}
else
{
//tmpbuf->size+=5;
tmpbuf->size+=1;
}
tmpptr=(kal_uint8 *) tmpbuf + TTP_OP_CREDIT_OFFSET;/*?????*/
lm_con[local_lsap_sel].ttp_dat.availcredit=0;
lm_con[local_lsap_sel].ttp_dat.remotecredit=0;
lm_con[local_lsap_sel].Rxsdu.size=0;
lm_con[local_lsap_sel].Rxsdu.ttp_busy=0;
lm_con[local_lsap_sel].Rxsdu.ap_busy=0;
gprs_flc_query_fix_size_pool_occupy(IRDA_DATA,
0,
GPRS_FLC_DL,
0,
&is_pool_presence,
0,
&init_buff_count);
tmp = init_buff_count;
if ( tmp > 127 )
{
lm_con[local_lsap_sel].ttp_dat.availcredit=tmp-127;
tmp=127;
}
lm_con[local_lsap_sel].ttp_dat.remotecredit = tmp;
tmpptr[0]=tmp;
status=IrLMP_Connect_Response(local_lsap_sel, remote_lsap_sel, tmpbuf);
if(status==0)
{
lm_con[local_lsap_sel].ttp_dat.ttp_connected=1;
}
}
else/*error cc_state*/
{
ttp_send_msg_to_upper_layer(MSG_ID_TTP_CONNECT_CONFIRM,0,IRDA_WRONG_CC_STATE_ERROR);
}
break;
case MSG_ID_TTP_DISCONNECT_REQUEST:
if(lm_con[local_lsap_sel].discon_code==DISCONNECT_REASON_USER_REQUEST)
{
/*User cancels the disconnection. TTP directly releases all buffers*/
IrLMP_DisConnect_Request(local_lsap_sel, remote_lsap_sel, NULL);
IrTTP_Disconnect_Reset(local_lsap_sel);
irda_ttp_disconnect_req=0;
/*release all control buffer*/
flush_ctrl_buff_q();
}
else
{
if((!FRAME_IN_QUEUE(lm_con[local_lsap_sel].ttp_txq))||
(lm_con[local_lsap_sel].cc_state!=IRDA_LMP_CC_ACTIVE))
{
IrLMP_DisConnect_Request(local_lsap_sel, remote_lsap_sel, NULL);
IrTTP_Disconnect_Reset(local_lsap_sel);
irda_ttp_disconnect_req=0;
}
else
{
irda_ttp_disconnect_req=1;
}
}
break;
default:
break;
}
} /* irda_ttp_process_external_msg() */
/*************************************************************************
* FUNCTION
* irda_ttp_disconnect_req_check
*
* DESCRIPTION
* Make sure TTP sends disconnect PDU after all data in queus is transmitted.
* But if there is no TTP connection, this limitation doesn't exist.
* PARAMETERS
* None
* RETURNS
* None
*
* GLOBALS AFFECTED
* Process all the message send from upper layer to TTP
*************************************************************************/
void irda_ttp_disconnect_req_check(void)
{
if(((!FRAME_IN_QUEUE(lm_con[local_lsap_sel].ttp_txq))&&
(irda_ttp_disconnect_req==1))||
(lm_con[local_lsap_sel].cc_state!=IRDA_LMP_CC_ACTIVE) )
{
kal_prompt_trace(MOD_TTP,"TTP_dis_flag %d",irda_ttp_disconnect_req);
IrLMP_DisConnect_Request(local_lsap_sel, remote_lsap_sel, NULL);
IrTTP_Disconnect_Reset(local_lsap_sel);
irda_ttp_disconnect_req=0;
}
else
{
kal_prompt_trace(MOD_TTP,"TTP_dis_flag %d",irda_ttp_disconnect_req);
}
}
/*************************************************************************
* FUNCTION
* irda_ttp_disconnect_ind_check
*
* DESCRIPTION
* Make sure TTP sends disconnect indication to OBEX after all data in rx queus is transmitted
* to OBEX.
* But if there is no TTP connection, this limitation doesn't exist.
* PARAMETERS
* None
* RETURNS
* None
*
* GLOBALS AFFECTED
* Process all the message send from upper layer to TTP
*************************************************************************/
void irda_ttp_disconnect_ind_check(void)
{
if(((!FRAME_IN_QUEUE(lm_con[local_lsap_sel].ttp_rxq))&&
(irda_ttp_disconnect_ind==1))||
(lm_con[local_lsap_sel].cc_state!=IRDA_LMP_CC_ACTIVE))
{
kal_prompt_trace(MOD_TTP,"TTP_dis_flag %d",irda_ttp_disconnect_ind);
ttp_send_msg_to_upper_layer(MSG_ID_TTP_LSAP_DISCONNECT_INDICATION,NULL,IRDA_SUCCESS);
IrTTP_Disconnect_Reset(local_lsap_sel);
irda_ttp_disconnect_ind=0;
}
else
{
kal_prompt_trace(MOD_TTP,"TTP_dis_flag %d",irda_ttp_disconnect_ind);
}
}
/*************************************************************************
* FUNCTION
* process_ttp_tx_queue
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -