/******************************************************************************* ** ** Function llcp_util_parse_cc ** ** Description Parse CC PDU ** ** Returns tLLCP_STATUS ** *******************************************************************************/ tLLCP_STATUS llcp_util_parse_cc (UINT8 *p_bytes, UINT16 length, UINT16 *p_miu, UINT8 *p_rw) { UINT8 param_type, param_len, *p = p_bytes; *p_miu = LLCP_DEFAULT_MIU; *p_rw = LLCP_DEFAULT_RW; while (length) { BE_STREAM_TO_UINT8 (param_type, p); length--; switch (param_type) { case LLCP_MIUX_TYPE: BE_STREAM_TO_UINT8 (param_len, p); BE_STREAM_TO_UINT16 ((*p_miu), p); (*p_miu) &= LLCP_MIUX_MASK; (*p_miu) += LLCP_DEFAULT_MIU; LLCP_TRACE_DEBUG1 ("llcp_util_parse_cc (): LLCP_MIUX_TYPE:%d", *p_miu); break; case LLCP_RW_TYPE: BE_STREAM_TO_UINT8 (param_len, p); BE_STREAM_TO_UINT8 ((*p_rw), p); (*p_rw) &= 0x0F; LLCP_TRACE_DEBUG1 ("llcp_util_parse_cc (): LLCP_RW_TYPE:%d", *p_rw); break; default: LLCP_TRACE_ERROR1 ("llcp_util_parse_cc (): Unexpected type 0x%x", param_type); BE_STREAM_TO_UINT8 (param_len, p); p += param_len; break; } if (length >= param_len + 1) length -= param_len + 1; else { LLCP_TRACE_ERROR0 ("llcp_util_parse_cc (): Bad LTV's"); return LLCP_STATUS_FAIL; } } return LLCP_STATUS_SUCCESS; }
/******************************************************************************* ** ** Function llcp_sdp_proc_snl ** ** Description Process SDREQ and SDRES in SNL ** ** ** Returns LLCP_STATUS ** *******************************************************************************/ tLLCP_STATUS llcp_sdp_proc_snl (UINT16 sdu_length, UINT8 *p) { UINT8 type, length, tid, sap, *p_value; LLCP_TRACE_DEBUG0 ("llcp_sdp_proc_snl ()"); if ((llcp_cb.lcb.agreed_major_version < LLCP_MIN_SNL_MAJOR_VERSION)|| ((llcp_cb.lcb.agreed_major_version == LLCP_MIN_SNL_MAJOR_VERSION)&&(llcp_cb.lcb.agreed_minor_version < LLCP_MIN_SNL_MINOR_VERSION))) { LLCP_TRACE_DEBUG0 ("llcp_sdp_proc_snl(): version number less than 1.1, SNL not supported."); return LLCP_STATUS_FAIL; } while (sdu_length >= 2) /* at least type and length */ { BE_STREAM_TO_UINT8 (type, p); BE_STREAM_TO_UINT8 (length, p); switch (type) { case LLCP_SDREQ_TYPE: if ( (length > 1) /* TID and sevice name */ &&(sdu_length >= 2 + length) ) /* type, length, TID and service name */ { p_value = p; BE_STREAM_TO_UINT8 (tid, p_value); sap = llcp_sdp_get_sap_by_name ((char*) p_value, (UINT8) (length - 1)); llcp_sdp_send_sdres (tid, sap); } else { LLCP_TRACE_ERROR1 ("llcp_sdp_proc_snl (): bad length (%d) in LLCP_SDREQ_TYPE", length); } break; case LLCP_SDRES_TYPE: if ( (length == LLCP_SDRES_LEN) /* TID and SAP */ &&(sdu_length >= 2 + length) ) /* type, length, TID and SAP */ { p_value = p; BE_STREAM_TO_UINT8 (tid, p_value); BE_STREAM_TO_UINT8 (sap, p_value); llcp_sdp_return_sap (tid, sap); } else { LLCP_TRACE_ERROR1 ("llcp_sdp_proc_snl (): bad length (%d) in LLCP_SDRES_TYPE", length); } break; default: LLCP_TRACE_WARNING1 ("llcp_sdp_proc_snl (): Unknown type (0x%x) is ignored", type); break; } if (sdu_length >= 2 + length) /* type, length, value */ { sdu_length -= 2 + length; p += length; } else { break; } } if (sdu_length) { LLCP_TRACE_ERROR0 ("llcp_sdp_proc_snl (): Bad format of SNL"); return LLCP_STATUS_FAIL; } else { return LLCP_STATUS_SUCCESS; } }
/******************************************************************************* ** ** Function llcp_util_parse_connect ** ** Description Parse CONNECT PDU ** ** Returns tLLCP_STATUS ** *******************************************************************************/ tLLCP_STATUS llcp_util_parse_connect (UINT8 *p_bytes, UINT16 length, tLLCP_CONNECTION_PARAMS *p_params) { UINT8 param_type, param_len, *p = p_bytes; p_params->miu = LLCP_DEFAULT_MIU; p_params->rw = LLCP_DEFAULT_RW; p_params->sn[0] = 0; while (length) { BE_STREAM_TO_UINT8 (param_type, p); length--; switch (param_type) { case LLCP_MIUX_TYPE: BE_STREAM_TO_UINT8 (param_len, p); BE_STREAM_TO_UINT16 (p_params->miu, p); p_params->miu &= LLCP_MIUX_MASK; p_params->miu += LLCP_DEFAULT_MIU; LLCP_TRACE_DEBUG1 ("llcp_util_parse_connect (): LLCP_MIUX_TYPE:%d", p_params->miu); break; case LLCP_RW_TYPE: BE_STREAM_TO_UINT8 (param_len, p); BE_STREAM_TO_UINT8 (p_params->rw, p); p_params->rw &= 0x0F; LLCP_TRACE_DEBUG1 ("llcp_util_parse_connect (): LLCP_RW_TYPE:%d", p_params->rw); break; case LLCP_SN_TYPE: BE_STREAM_TO_UINT8 (param_len, p); if (param_len <= LLCP_MAX_SN_LEN) { memcpy (p_params->sn, p, param_len); p_params->sn[param_len] = 0; } else { memcpy (p_params->sn, p, LLCP_MAX_SN_LEN); p_params->sn[LLCP_MAX_SN_LEN] = 0; } p += param_len; LLCP_TRACE_DEBUG1 ("llcp_util_parse_connect (): LLCP_SN_TYPE:<%s>", p_params->sn); break; default: LLCP_TRACE_ERROR1 ("llcp_util_parse_connect (): Unexpected type 0x%x", param_type); BE_STREAM_TO_UINT8 (param_len, p); p += param_len; break; } /* check remaining lengh */ if (length >= param_len + 1) { length -= param_len + 1; } else { LLCP_TRACE_ERROR0 ("llcp_util_parse_connect (): Bad LTV's"); return LLCP_STATUS_FAIL; } } return LLCP_STATUS_SUCCESS; }
/******************************************************************************* ** ** Function llcp_util_parse_link_params ** ** Description Parse LLCP Link parameters ** ** Returns TRUE if success ** *******************************************************************************/ BOOLEAN llcp_util_parse_link_params (UINT16 length, UINT8 *p_bytes) { UINT8 param_type, param_len, *p = p_bytes; while (length) { BE_STREAM_TO_UINT8 (param_type, p); length--; switch (param_type) { case LLCP_VERSION_TYPE: BE_STREAM_TO_UINT8 (param_len, p); BE_STREAM_TO_UINT8 (llcp_cb.lcb.peer_version, p); LLCP_TRACE_DEBUG1 ("Peer Version - 0x%02X", llcp_cb.lcb.peer_version); break; case LLCP_MIUX_TYPE: BE_STREAM_TO_UINT8 (param_len, p); BE_STREAM_TO_UINT16 (llcp_cb.lcb.peer_miu, p); llcp_cb.lcb.peer_miu &= LLCP_MIUX_MASK; llcp_cb.lcb.peer_miu += LLCP_DEFAULT_MIU; LLCP_TRACE_DEBUG1 ("Peer MIU - %d bytes", llcp_cb.lcb.peer_miu); break; case LLCP_WKS_TYPE: BE_STREAM_TO_UINT8 (param_len, p); BE_STREAM_TO_UINT16 (llcp_cb.lcb.peer_wks, p); LLCP_TRACE_DEBUG1 ("Peer WKS - 0x%04X", llcp_cb.lcb.peer_wks); break; case LLCP_LTO_TYPE: BE_STREAM_TO_UINT8 (param_len, p); BE_STREAM_TO_UINT8 (llcp_cb.lcb.peer_lto, p); llcp_cb.lcb.peer_lto *= LLCP_LTO_UNIT; /* 10ms unit */ LLCP_TRACE_DEBUG1 ("Peer LTO - %d ms", llcp_cb.lcb.peer_lto); break; case LLCP_OPT_TYPE: BE_STREAM_TO_UINT8 (param_len, p); BE_STREAM_TO_UINT8 (llcp_cb.lcb.peer_opt, p); LLCP_TRACE_DEBUG1 ("Peer OPT - 0x%02X", llcp_cb.lcb.peer_opt); break; default: LLCP_TRACE_ERROR1 ("llcp_util_parse_link_params (): Unexpected type 0x%x", param_type); BE_STREAM_TO_UINT8 (param_len, p); p += param_len; break; } if (length >= param_len + 1) length -= param_len + 1; else { LLCP_TRACE_ERROR0 ("llcp_util_parse_link_params (): Bad LTV's"); return (FALSE); } } return (TRUE); }