📄 lmp.c
字号:
irda_lmp_flow=IRDA_LMP_LSAP_CONNECT_FLOW;
/* add LM connect header */
tmpptr[0]=remote_lsap_sel|0x80;/*MSB is control bit*/
tmpptr[1]=local_lsap_sel;
tmpptr[2]=CONNECT_REQUEST_INDICATION_LM_PDU;
tmpptr[3]=0; /* add reserved byte */
IrLAP_DATA_request(irda_data_buffer);
irda_data_buffer=0;
return(IRDA_SUCCESS);
}
else
return(IRDA_LSAP_CONNECT_IN_PROGRESS);
break;
default:
return(IRDA_WRONG_CC_STATE);
break;
}
break;
default:
sc_state=IRDA_LMP_SC_DISC;
return(IRDA_WRONG_SC_STATE);
break;
}
switch (lm_con[local_lsap_sel].cc_state )
{
case IRDA_LMP_CC_NOT_READY: /* no LAP connection exist */
if (sc_state==IRDA_LMP_SC_DISC)
{
lm_con[local_lsap_sel].sel=remote_lsap_sel;
irda_lmp_flow=IRDA_LMP_LSAP_CONNECT_FLOW;
current_lsap_sel=local_lsap_sel;
if (remote_device_address)
{
IrLAP_CONNECT_request(remote_device_address);
sc_state=IRDA_LMP_SC_SETUP;
}
else
{
conflict_flag = KAL_FALSE;
genaddrbit = 0;
lmp_discovery_log = 0;
discovery_retry_counter=DISCOVER_RETRY_COUNT;
IrLAP_DISCOVERY_request();
sc_state=IRDA_LMP_SC_DISCOVER;
}
return(IRDA_SUCCESS);
}
else
{ /* The LAP_CONNECT_PROCESS or DISCOVERY_PROCESS is in progress */
return(IRDA_WRONG_SC_STATE);
}
break;
case IRDA_LMP_CC_READY:
if (irda_lmp_flow==IRDA_LMP_IDLE_FLOW)
{ /* to make sure that only on LSAP connect operation in progress */
if (!irda_data_buffer)
{
irda_data_buffer=Getbuf();
ASSERT(irda_data_buffer);
irda_data_buffer->size=4;
}
else
{
irda_data_buffer->size+=4;
}
tmpptr=(kal_uint8 *) (irda_data_buffer)+I_TX_PACKET_OFFSET;
lm_con[local_lsap_sel].cc_state=IRDA_LMP_CC_SETUP;
irda_lmp_flow=IRDA_LMP_LSAP_CONNECT_FLOW;
/* add LM connect header */
tmpptr[0]=remote_lsap_sel|0x80;/*MSB is control bit*/
tmpptr[1]=local_lsap_sel;
tmpptr[2]=CONNECT_REQUEST_INDICATION_LM_PDU;
tmpptr[3]=0; /* add reserved byte */
IrLAP_DATA_request(irda_data_buffer);
irda_data_buffer=0;
return(IRDA_SUCCESS);
}
else
return(IRDA_LSAP_CONNECT_IN_PROGRESS);
break;
default:
return(IRDA_WRONG_CC_STATE);
break;
}
} /* lm_connect_request() */
/*************************************************************************
* FUNCTION
* station_control_check
*
* DESCRIPTION
* Check discovery log
*
* PARAMETERS
*
* RETURNS
* None
* GLOBALS AFFECTED
*
*************************************************************************/
kal_uint16 station_control_check(void)
{
LOG *tmpptr;
#ifdef IRDA_KAL_TRACE
kal_trace(TRACE_FUNC, IRDA_MSG70);
#endif
if ((tmpptr=IrLAP_DISCOVERY_confirm())==0)
return(IRDA_DISCOVERY_NO_DEVICE); /* no devices discovered */
if (tmpptr && (!(AddressConflicts(tmpptr))))
{ /* no address conflict */
lmp_discovery_log=tmpptr;
sc_state = IRDA_LMP_SC_DISC;
if (remote_device_address)
return(IRDA_SUCCESS);
else
return(IRDA_DISCOVERY_NO_DEVICE);
}
else if (tmpptr && AddressConflicts(tmpptr) && (!conflict_flag))
{ /* address conflict */
genaddrbit = 1;
conflict_flag=KAL_TRUE;
discovery_retry_counter=DISCOVER_RETRY_COUNT;
IrLAP_DISCOVERY_request();
sc_state=IRDA_LMP_SC_DISCOVER;
return(IRDA_DISCOVERY_ADDRESS_CONFLICT_RETRY);
}
else if (tmpptr && AddressConflicts(tmpptr) && conflict_flag)
{ /*?????*/
RemoveConflicts(tmpptr);
lmp_discovery_log=tmpptr;
sc_state = IRDA_LMP_SC_DISC;
if (remote_device_address)
return(IRDA_SUCCESS);
else
return(IRDA_DISCOVERY_NO_DEVICE);
}
return(IRDA_DISCOVERY_NO_DEVICE);/**/
} /* station_control_check() */
/*************************************************************************
* FUNCTION
* AddressConflicts
*
* DESCRIPTION
* Check for address conflicts and record remote_device address
* when there is no conflict
* PARAMETERS
* LOG * ptr: point to the discovery log results
* RETURNS
* 0 if no conflicts, 1 if a conflict exists
*
* GLOBALS AFFECTED
*
*************************************************************************/
kal_uint8 AddressConflicts(LOG *ptr)
{
kal_uint8 i,j;
LOG *orgptr,*tmpptr;
kal_uint8 flag=0;
#ifdef IRDA_KAL_TRACE
kal_trace(TRACE_FUNC, IRDA_MSG71);
#endif
remote_device_address=0;
orgptr=ptr;
tmpptr=ptr;
for (i=0;i<TOTAL_SLOTS;i++,ptr++)
{
if (ptr->addr!=0)
{
for (j=0;j<TOTAL_SLOTS;j++,tmpptr++)
{
if ((ptr->addr==tmpptr->addr) && (i!=j))
{
ptr->conflict=1;
flag=1;
}
}
tmpptr=orgptr;
if (ptr->conflict!=1)
remote_device_address=ptr->addr;
}
}
return(flag);
} /* AddressComflicts() */
/*************************************************************************
* FUNCTION
* RemoveConflicts
*
* DESCRIPTION
* Do a LAP discovery request
*
* PARAMETERS
* LOG * ptr: point to the discovery log results
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
void RemoveConflicts(LOG *ptr)
{
kal_uint8 i,j;
#ifdef IRDA_KAL_TRACE
kal_trace(TRACE_FUNC, IRDA_MSG72);
#endif
for (i=0;i<TOTAL_SLOTS;i++,ptr++)
{
if (ptr->conflict)
{
ptr->addr=0l;
ptr->conflict=0;
for (j=0;j<21;j++)
ptr->info[j]=0;
}
}
} /* RemoveConflicts() */
/*************************************************************************
* FUNCTION
* lmp_data_indication_parse
*
* DESCRIPTION
* Parse the recived I frame and retun what kind of LM
*
* PARAMETERS
*
* RETURNS
* LM_PDU type
*
* GLOBALS AFFECTED
*
*************************************************************************/
kal_uint8 lmp_data_indication_parse(void)
{
kal_uint8 *tmpptr;
kal_uint8 return_value=0;
kal_uint8 dbg_value;
#ifdef IRDA_KAL_TRACE
kal_trace(TRACE_FUNC, IRDA_MSG73);
#endif
tmpptr=(kal_uint8 *) (irda_data_buffer)+I_RX_PACKET_OFFSET;/*2*/
dbg_value=*tmpptr;
local_lsap_sel = *(tmpptr)&0x7F;/*MSB is control bit*/
remote_lsap_sel = *(tmpptr+1) & 0x7F;/*MSB is control bit*/
if (sc_state==IRDA_LMP_SC_ACTIVE)
{ /* LAP connection exist */
if (dbg_value&0x80)
{ /* link control LM-PDU */
return_value = *(tmpptr+2);
}
else
{ /* Data LM-PDU */
if (local_lsap_sel>MAX_SEL)
{ /* error LSAP_SEL, the data indication msg is ignored */
#ifdef IRDA_KAL_TRACE
kal_trace(TRACE_INFO, IRDA_MSG56);
#endif
kal_prompt_trace(MOD_LAP,"local lsap sel %d",local_lsap_sel);
return_value=BAD_LOCAL_LSAP_SEL_LM_PDU;
}
else
{
#ifdef IRDA_KAL_TRACE
kal_trace(TRACE_INFO, IRDA_MSG57);
#endif
return_value=DATA_LM_PDU;
}
}
}
else
{ /* wrong sc_state, the data indication msg is ignored */
#ifdef IRDA_KAL_TRACE
kal_trace(TRACE_INFO, IRDA_MSG58);
#endif
return_value=BAD_LM_PDU;
}
return (return_value);
} /* lmp_data_indication_parse() */
/*************************************************************************
* FUNCTION
* lmp_send_msg_to_upper_layer
*
* DESCRIPTION
* format and send a message to upper layer from LMP
*
* PARAMETERS
* msg -> message id to be send to upper layer
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
void lmp_send_msg_to_upper_layer(kal_uint16 msg, FBUF *frame, irda_error_code_enum code)
{
ilm_struct *lmp_ilm;
irda_local_para_struct *tmp_local_para;
peer_buff_struct* tmp_peer_buf_ptr;
kal_uint8* pdu_ptr;
kal_uint16 pdu_length;
kal_uint8 return_code, lsap_sel;
#ifdef IRDA_KAL_TRACE
kal_trace(TRACE_FUNC, IRDA_MSG74);
#endif
if (lm_con[local_lsap_sel].control & TTP_MASK)
{ /* to TTP */
if(remote_lsap_sel==0)
{
if((msg==MSG_ID_LMP_CONNECT_CONFIRM)&&(frame!=0)) /*special case*/
Freebuf(frame);
goto IAS;
}
irda_ttp_flag = msg;
if(0!=frame)
irda_data_buffer=frame;
irda_error_code=code;
}
else if (local_lsap_sel==IAS_SERVER_LSAP_SEL)
{ /* IAS Server */
if (msg==MSG_ID_LMP_DATA_INDICATION)
IAS_Data_Indication(remote_lsap_sel, frame);/*IAS free buf*/
else if (msg==MSG_ID_LMP_CONNECT_INDICATION)
IAS_Connect_Indication(remote_lsap_sel);
else if (msg==MSG_ID_LMP_LSAP_DISCONNECT_INDICATION)
IAS_Disconnect_Indication();
}
else if (local_lsap_sel!=IAS_SERVER_LSAP_SEL)
{ /* to upper layer without passing through TTP */
IAS:
lmp_ilm=allocate_ilm(MOD_LMP);
lmp_ilm->src_mod_id=MOD_LMP;
if(local_lsap_sel==OBEX_LSAP_SEL||local_lsap_sel==OBEX_IRXFER_LSAP_SEL)
{
lmp_ilm->dest_mod_id=MOD_OBEX; /*@@@@MOD_OBEX*/
lmp_ilm->sap_id=IRDA_OBEX_SAP;
}
else if (local_lsap_sel==COMMX_LSAP_SEL)
{
lmp_ilm->dest_mod_id=MOD_IRCOMM; /*@@@@MOD_IRCOMM*/
lmp_ilm->sap_id=IRDA_IRCOMM_SAP;
}
else/*exception*/
{
lmp_ilm->dest_mod_id=MOD_LMP; /**/
}
lmp_ilm->msg_id=msg;
tmp_local_para=(irda_local_para_struct *) construct_local_para(sizeof(irda_local_para_struct),TD_UL);
tmp_local_para->local_lsap_sel=local_lsap_sel;
tmp_local_para->remote_lsap_sel=lm_con[local_lsap_sel].sel;
tmp_local_para->disconnect_reason=lm_con[local_lsap_sel].discon_code;
tmp_local_para->return_code=code;
if (msg==MSG_ID_IAS_GET_REMOTE_LSAP_SEL_CONFIRM)
{
return_code=Decode_GetValueByClass_Packet(frame,&lsap_sel);
tmp_local_para->remote_ap_lsap_sel=lsap_sel;
tmp_local_para->ias_return_code=return_code;
//if (return_code!=0)/*query fail */
if (0!=frame)
Freebuf(frame);
else
ASSERT(0);
}
/*no flow control link, not support now*/
else if (msg==MSG_ID_LMP_DATA_INDICATION)/*add data buffer to upper layer*/
{
#ifndef IRDA_CTRL_BUF
tmp_peer_buf_ptr=construct_peer_buff( (frame->size-2), 0, 0, TD_CTRL);
#else
tmp_peer_buf_ptr = gprs_flc_get_peer_buff
(IRDA_DATA,
0,
GPRS_FLC_DL,
0,
frame->size,
0,
0,
NULL);
#endif
if(tmp_peer_buf_ptr==NULL)
ASSERT(0);
pdu_ptr=(kal_uint8*)get_pdu_ptr(tmp_peer_buf_ptr, &pdu_length);
kal_mem_set( pdu_ptr, 0, pdu_length);
xmemcpy((kal_uint8*)(pdu_ptr),(kal_uint8*)( (kal_uint8*)frame+FBUF_HEAD+4),((frame->size)-4));
tmp_peer_buf_ptr->pdu_len = (frame->size)-4;
Freebuf(frame);
lmp_ilm->peer_buff_ptr=(peer_buff_struct *) tmp_peer_buf_ptr;
}
lmp_ilm->local_para_ptr=(local_para_struct *) tmp_local_para;
msg_send_ext_queue(lmp_ilm);
}
} /* lmp_send_msg_to_upper_layer() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -