From ee2277dde9f0b33d62ab0e8529cf23b4030b20e1 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Thu, 17 Dec 2009 16:53:27 +0100 Subject: [PATCH] mm: add parameter retrieval support Signed-off-by: Patrick McHardy --- include/dect/ie.h | 32 +++++ include/dect/mm.h | 27 ++++ include/mm.h | 38 ++++++ src/mm.c | 322 +++++++++++++++++++++++++++++++++++++++++++++- src/s_msg.c | 73 +++++++++++ 5 files changed, 491 insertions(+), 1 deletion(-) diff --git a/include/dect/ie.h b/include/dect/ie.h index eb94e6f..19cb53b 100644 --- a/include/dect/ie.h +++ b/include/dect/ie.h @@ -528,8 +528,40 @@ struct dect_ie_identity_type { /* Info type IE */ +enum dect_info_parameter_type { + DECT_INFO_LOCATE_SUGGEST = 0x0, + DECT_INFO_ACCESS_RIGHTS_MODIFY_SUGGEST = 0x1, + DECT_INFO_PP_AUTHENTICATION_FAILURE = 0x4, + DECT_INFO_DYNAMIC_PARAMETERS_ALLOCATION = 0x6, + DECT_INFO_EXTERNAL_HO_PARAMETERS = 0x8, + DECT_INFO_LOCATION_AREA = 0x9, + DECT_INFO_HANDOVER_REFERENCE = 0xa, + DECT_INFO_MF_PSCN_SYNCHRONIZED_HANDOVER_CANDIATE = 0xb, + DECT_INFO_EXT_HANDOVER_CANDIDATE = 0xc, + DECT_INFO_MF_SYNCHRONIZED_HANDOVER_CANDIATE = 0xd, + DECT_INFO_MF_PSCN_MFN_SYNCHRONIZED_HANDOVER_CANDIATE = 0xe, + DECT_INFO_NON_SYNCHRONIZED_HANDOVER_CANDIDATE = 0xf, + DECT_INFO_OLD_FIXED_PART_IDENTITY = 0x10, + DECT_INFO_OLD_NETWORK_ASSIGNED_IDENTITY = 0x11, + DECT_INFO_OLD_NETWORK_ASSIGNED_LOCATION_AREA = 0x12, + DECT_INFO_OLD_NETWORK_ASSIGNED_HANDOVER_REFERENCE = 0x13, + DECT_INFO_BILLING = 0x20, + DECT_INFO_DEBITING = 0x21, + DECT_INFO_CK_TRANSFER = 0x22, + DECT_INFO_HANDOVER_FAILED_REVERSION = 0x23, + DECT_INFO_QA_M_CALL = 0x24, + DECT_INFO_DISTRIBUTED_COMMUNICATION_DOWNLOAD = 0x25, + DECT_INFO_ETHERNET_ADDRESS = 0x30, + DECT_INFO_TOKEN_RING_ADDRESS = 0x31, + DECT_INFO_IPV4_ADDRESS = 0x32, + DECT_INFO_IPV6_ADDRESS = 0x33, + DECT_INFO_IDENTITY_ALLOCATION = 0x34, +}; + struct dect_ie_info_type { struct dect_ie_common common; + unsigned int num; + enum dect_info_parameter_type type[8]; }; /* InterWorking Unit (IWU) attributes IE */ diff --git a/include/dect/mm.h b/include/dect/mm.h index 72c9cbd..ada1759 100644 --- a/include/dect/mm.h +++ b/include/dect/mm.h @@ -84,6 +84,21 @@ struct dect_mm_identity_assign_param { struct dect_ie_escape_to_proprietary *escape_to_proprietary; }; +struct dect_mm_info_param { + struct dect_ie_collection common; + struct dect_ie_info_type *info_type; + struct dect_ie_call_identity *call_identity; + struct dect_ie_portable_identity *portable_identity; + struct dect_ie_list *fixed_identity; + struct dect_ie_location_area *location_area; + struct dect_ie_nwk_assigned_identity *nwk_assigned_identity; + struct dect_ie_network_parameter *network_parameter; + struct dect_ie_reject_reason *reject_reason; + struct dect_ie_duration *duration; + struct dect_ie_iwu_to_iwu *iwu_to_iwu; + struct dect_ie_escape_to_proprietary *escape_to_proprietary; +}; + struct dect_mm_endpoint; extern struct dect_mm_endpoint *dect_mm_endpoint_alloc(struct dect_handle *dh); @@ -129,6 +144,13 @@ struct dect_mm_ops { void (*mm_identity_assign_cfm)(struct dect_handle *dh, struct dect_mm_endpoint *mme, bool accept, struct dect_mm_identity_assign_param *param); + + void (*mm_info_ind)(struct dect_handle *dh, + struct dect_mm_endpoint *mme, + struct dect_mm_info_param *param); + void (*mm_info_cfm)(struct dect_handle *dh, + struct dect_mm_endpoint *mme, bool accept, + struct dect_mm_info_param *param); }; extern int dect_mm_access_rights_req(struct dect_handle *dh, struct dect_mm_endpoint *mme, @@ -161,4 +183,9 @@ extern int dect_mm_identity_assign_req(struct dect_handle *dh, struct dect_mm_en extern int dect_mm_identity_assign_res(struct dect_handle *dh, struct dect_mm_endpoint *mme, bool accept, const struct dect_mm_identity_assign_param *param); +extern int dect_mm_info_req(struct dect_handle *dh, struct dect_mm_endpoint *mme, + struct dect_mm_info_param *param); +extern int dect_mm_info_res(struct dect_handle *dh, struct dect_mm_endpoint *mme, + bool accept, struct dect_mm_info_param *param); + #endif /* _LIBDECT_DECT_MM_H */ diff --git a/include/mm.h b/include/mm.h index 05ffcc3..b3f222a 100644 --- a/include/mm.h +++ b/include/mm.h @@ -207,18 +207,55 @@ struct dect_mm_locate_request_msg { struct dect_mm_info_accept_msg { struct dect_msg_common common; + struct dect_ie_info_type *info_type; + struct dect_ie_call_identity *call_identity; + struct dect_ie_list *fixed_identity; + struct dect_ie_location_area *location_area; + struct dect_ie_nwk_assigned_identity *nwk_assigned_identity; + struct dect_ie_network_parameter *network_parameter; + struct dect_ie_duration *duration; + struct dect_ie_segmented_info *segmented_info; + struct dect_ie_iwu_to_iwu *iwu_to_iwu; + struct dect_ie_escape_to_proprietary *escape_to_proprietary; }; struct dect_mm_info_reject_msg { struct dect_msg_common common; + struct dect_ie_call_identity *call_identity; + struct dect_ie_reject_reason *reject_reason; + struct dect_ie_segmented_info *segmented_info; + struct dect_ie_iwu_to_iwu *iwu_to_iwu; + struct dect_ie_escape_to_proprietary *escape_to_proprietary; }; struct dect_mm_info_request_msg { struct dect_msg_common common; + struct dect_ie_info_type *info_type; + struct dect_ie_call_identity *call_identity; + struct dect_ie_portable_identity *portable_identity; + struct dect_ie_list *fixed_identity; + struct dect_ie_location_area *location_area; + struct dect_ie_nwk_assigned_identity *nwk_assigned_identity; + struct dect_ie_network_parameter *network_parameter; + struct dect_ie_segmented_info *segmented_info; + struct dect_ie_iwu_to_iwu *iwu_to_iwu; + struct dect_ie_escape_to_proprietary *escape_to_proprietary; }; struct dect_mm_info_suggest_msg { struct dect_msg_common common; + struct dect_ie_info_type *info_type; + struct dect_ie_call_identity *call_identity; + struct dect_ie_fixed_identity *fixed_identity; + struct dect_ie_location_area *location_area; + struct dect_ie_nwk_assigned_identity *nwk_assigned_identity; + struct dect_ie_network_parameter *network_parameter; + struct dect_ie_ext_ho_indicator *ext_ho_indicator; + struct dect_ie_key *key; + struct dect_ie_setup_capability *setup_capability; + struct dect_ie_segmented_info *segmented_info; + struct dect_ie_iwu_to_iwu *iwu_to_iwu; + struct dect_ie_escape_to_proprietary *escape_to_proprietary; }; struct dect_mm_temporary_identity_assign_msg { @@ -261,6 +298,7 @@ enum dect_mm_procedures { DECT_MMP_LOCATION_REGISTRATION, DECT_MMP_TEMPORARY_IDENTITY_ASSIGNMENT, DECT_MMP_CIPHER, + DECT_MMP_PARAMETER_RETRIEVAL, }; struct dect_mm_procedure { diff --git a/src/mm.c b/src/mm.c index 5c81a75..5748579 100644 --- a/src/mm.c +++ b/src/mm.c @@ -175,6 +175,61 @@ static DECT_SFMT_MSG_DESC(mm_locate_request, DECT_SFMT_IE_END_MSG ); +static DECT_SFMT_MSG_DESC(mm_info_accept, + DECT_SFMT_IE(S_VL_IE_INFO_TYPE, IE_MANDATORY, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_CALL_IDENTITY, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_SO_IE_REPEAT_INDICATOR, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_FIXED_IDENTITY, IE_OPTIONAL, IE_NONE, DECT_SFMT_IE_REPEAT), + DECT_SFMT_IE(S_VL_IE_LOCATION_AREA, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_NWK_ASSIGNED_IDENTITY, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_NETWORK_PARAMETER, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_DURATION, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_SEGMENTED_INFO, IE_OPTIONAL, IE_OPTIONAL, 0), + DECT_SFMT_IE(S_VL_IE_IWU_TO_IWU, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_ESCAPE_TO_PROPRIETARY, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE_END_MSG +); + +static DECT_SFMT_MSG_DESC(mm_info_reject, + DECT_SFMT_IE(S_VL_IE_CALL_IDENTITY, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_REJECT_REASON, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_SEGMENTED_INFO, IE_OPTIONAL, IE_OPTIONAL, 0), + DECT_SFMT_IE(S_VL_IE_IWU_TO_IWU, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_ESCAPE_TO_PROPRIETARY, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE_END_MSG +); + +static DECT_SFMT_MSG_DESC(mm_info_request, + DECT_SFMT_IE(S_VL_IE_INFO_TYPE, IE_MANDATORY, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_CALL_IDENTITY, IE_NONE, IE_OPTIONAL, 0), + DECT_SFMT_IE(S_VL_IE_PORTABLE_IDENTITY, IE_NONE, IE_OPTIONAL, 0), + DECT_SFMT_IE(S_SO_IE_REPEAT_INDICATOR, IE_NONE, IE_OPTIONAL, 0), + DECT_SFMT_IE(S_VL_IE_FIXED_IDENTITY, IE_NONE, IE_OPTIONAL, DECT_SFMT_IE_REPEAT), + DECT_SFMT_IE(S_VL_IE_LOCATION_AREA, IE_NONE, IE_OPTIONAL, 0), + DECT_SFMT_IE(S_VL_IE_NWK_ASSIGNED_IDENTITY, IE_NONE, IE_OPTIONAL, 0), + DECT_SFMT_IE(S_VL_IE_NETWORK_PARAMETER, IE_NONE, IE_OPTIONAL, 0), + DECT_SFMT_IE(S_VL_IE_SEGMENTED_INFO, IE_OPTIONAL, IE_OPTIONAL, 0), + DECT_SFMT_IE(S_VL_IE_IWU_TO_IWU, IE_NONE, IE_OPTIONAL, 0), + DECT_SFMT_IE(S_VL_IE_ESCAPE_TO_PROPRIETARY, IE_NONE, IE_OPTIONAL, 0), + DECT_SFMT_IE_END_MSG +); + +static DECT_SFMT_MSG_DESC(mm_info_suggest, + DECT_SFMT_IE(S_VL_IE_INFO_TYPE, IE_MANDATORY, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_CALL_IDENTITY, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_FIXED_IDENTITY, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_LOCATION_AREA, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_NWK_ASSIGNED_IDENTITY, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_NETWORK_PARAMETER, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_EXT_HO_INDICATOR, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_KEY, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_SETUP_CAPABILITY, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_SEGMENTED_INFO, IE_OPTIONAL, IE_OPTIONAL, 0), + DECT_SFMT_IE(S_VL_IE_IWU_TO_IWU, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE(S_VL_IE_ESCAPE_TO_PROPRIETARY, IE_OPTIONAL, IE_NONE, 0), + DECT_SFMT_IE_END_MSG +); + static DECT_SFMT_MSG_DESC(mm_temporary_identity_assign, DECT_SFMT_IE(S_VL_IE_PORTABLE_IDENTITY, IE_OPTIONAL, IE_NONE, 0), DECT_SFMT_IE(S_VL_IE_LOCATION_AREA, IE_OPTIONAL, IE_NONE, 0), @@ -1096,6 +1151,267 @@ err1: dect_msg_free(dh, &mm_temporary_identity_assign_rej_msg_desc, &msg.common); } +/** + * dect_mm_info_req - MM_INFO-req primitive + * + * @dh: libdect DECT handle + * @mme: Mobility Management Endpoint + * @param: info parameters + */ +int dect_mm_info_req(struct dect_handle *dh, struct dect_mm_endpoint *mme, + struct dect_mm_info_param *param) +{ + struct dect_mm_procedure *mp = &mme->procedure[DECT_TRANSACTION_INITIATOR]; + struct dect_mm_info_request_msg rmsg; + struct dect_mm_info_suggest_msg smsg; + int err; + + mm_debug(mme, "INFO-req"); + if (mp->type != DECT_MMP_NONE) + return -1; + + err = dect_ddl_open_transaction(dh, &mp->transaction, mme->link, + DECT_PD_MM); + if (err < 0) + goto err1; + + if (dh->mode == DECT_MODE_FP) { + memset(&smsg, 0, sizeof(smsg)); + smsg.info_type = param->info_type; + smsg.call_identity = param->call_identity; + //smsg.fixed_identity = param->fixed_identity; + smsg.location_area = param->location_area; + smsg.nwk_assigned_identity = param->nwk_assigned_identity; + smsg.network_parameter = param->network_parameter; + smsg.iwu_to_iwu = param->iwu_to_iwu; + smsg.escape_to_proprietary = param->escape_to_proprietary; + + err = dect_mm_send_msg(dh, mme, DECT_TRANSACTION_INITIATOR, + &mm_info_suggest_msg_desc, + &smsg.common, DECT_MM_INFO_SUGGEST); + if (err < 0) + goto err2; + + dect_close_transaction(dh, &mp->transaction, DECT_DDL_RELEASE_PARTIAL); + } else { + memset(&rmsg, 0, sizeof(rmsg)); + rmsg.info_type = param->info_type; + rmsg.call_identity = param->call_identity; + rmsg.portable_identity = param->portable_identity; + rmsg.fixed_identity = param->fixed_identity; + rmsg.location_area = param->location_area; + rmsg.nwk_assigned_identity = param->nwk_assigned_identity; + rmsg.network_parameter = param->network_parameter; + rmsg.iwu_to_iwu = param->iwu_to_iwu; + rmsg.escape_to_proprietary = param->escape_to_proprietary; + + err = dect_mm_send_msg(dh, mme, DECT_TRANSACTION_INITIATOR, + &mm_info_request_msg_desc, + &rmsg.common, DECT_MM_INFO_REQUEST); + if (err < 0) + goto err2; + + mp->type = DECT_MMP_PARAMETER_RETRIEVAL; + } + + return 0; +err2: + dect_close_transaction(dh, &mp->transaction, DECT_DDL_RELEASE_PARTIAL); +err1: + return err; +} + +/** + * dect_mm_info_res - MM_INFO-res primitive + * + * @dh: libdect DECT handle + * @mme: Mobility Management Endpoint + * @param: info parameters + */ +int dect_mm_info_res(struct dect_handle *dh, struct dect_mm_endpoint *mme, + bool accept, struct dect_mm_info_param *param) +{ + struct dect_mm_procedure *mp = &mme->procedure[DECT_TRANSACTION_RESPONDER]; + struct dect_mm_info_accept_msg amsg; + struct dect_mm_info_reject_msg rmsg; + int err; + + if (mp->type != DECT_MMP_PARAMETER_RETRIEVAL) + return -1; + + if (accept) { + memset(&amsg, 0, sizeof(amsg)); + amsg.info_type = param->info_type; + amsg.call_identity = param->call_identity; + amsg.fixed_identity = param->fixed_identity; + amsg.location_area = param->location_area; + amsg.nwk_assigned_identity = param->nwk_assigned_identity; + amsg.network_parameter = param->network_parameter; + amsg.iwu_to_iwu = param->iwu_to_iwu; + amsg.escape_to_proprietary = param->escape_to_proprietary; + + err = dect_mm_send_msg(dh, mme, DECT_TRANSACTION_RESPONDER, + &mm_info_accept_msg_desc, + &amsg.common, DECT_MM_INFO_ACCEPT); + } else { + memset(&rmsg, 0, sizeof(rmsg)); + rmsg.call_identity = param->call_identity; + rmsg.reject_reason = param->reject_reason; + rmsg.iwu_to_iwu = param->iwu_to_iwu; + rmsg.escape_to_proprietary = param->escape_to_proprietary; + + err = dect_mm_send_msg(dh, mme, DECT_TRANSACTION_RESPONDER, + &mm_info_reject_msg_desc, + &rmsg.common, DECT_MM_INFO_REJECT); + } + + dect_close_transaction(dh, &mp->transaction, DECT_DDL_RELEASE_PARTIAL); + mp->type = DECT_MMP_NONE; + + return 0; +} + +static void dect_mm_rcv_info_request(struct dect_handle *dh, + struct dect_mm_endpoint *mme, + struct dect_msg_buf *mb) +{ + struct dect_mm_procedure *mp = &mme->procedure[DECT_TRANSACTION_RESPONDER]; + struct dect_mm_info_request_msg msg; + struct dect_mm_info_param *param; + + mm_debug(mme, "INFO-REQUEST"); + if (mp->type != DECT_MMP_NONE) + return; + + if (dect_parse_sfmt_msg(dh, &mm_info_request_msg_desc, + &msg.common, mb) < 0) + return; + + param = dect_ie_collection_alloc(dh, sizeof(*param)); + if (param == NULL) + goto err1; + + param->info_type = dect_ie_hold(msg.info_type); + param->call_identity = dect_ie_hold(msg.call_identity); + param->portable_identity = dect_ie_hold(msg.portable_identity); + param->fixed_identity = dect_ie_hold(msg.fixed_identity); + param->location_area = dect_ie_hold(msg.location_area); + param->nwk_assigned_identity = dect_ie_hold(msg.nwk_assigned_identity); + param->network_parameter = dect_ie_hold(msg.network_parameter); + param->iwu_to_iwu = dect_ie_hold(msg.iwu_to_iwu); + param->escape_to_proprietary = dect_ie_hold(msg.escape_to_proprietary); + + mp->type = DECT_MMP_PARAMETER_RETRIEVAL; + + dh->ops->mm_ops->mm_info_ind(dh, mme, param); + dect_ie_collection_put(dh, param); +err1: + dect_msg_free(dh, &mm_info_request_msg_desc, &msg.common); +} + +static void dect_mm_rcv_info_accept(struct dect_handle *dh, + struct dect_mm_endpoint *mme, + struct dect_msg_buf *mb) +{ + struct dect_mm_procedure *mp = &mme->procedure[DECT_TRANSACTION_INITIATOR]; + struct dect_mm_info_accept_msg msg; + struct dect_mm_info_param *param; + + mm_debug(mme, "INFO-ACCEPT"); + if (mp->type != DECT_MMP_PARAMETER_RETRIEVAL) + return; + + if (dect_parse_sfmt_msg(dh, &mm_info_accept_msg_desc, + &msg.common, mb) < 0) + return; + + param = dect_ie_collection_alloc(dh, sizeof(*param)); + if (param == NULL) + goto err1; + + param->info_type = dect_ie_hold(msg.info_type); + param->call_identity = dect_ie_hold(msg.call_identity); + param->fixed_identity = dect_ie_hold(msg.fixed_identity); + param->location_area = dect_ie_hold(msg.location_area); + param->nwk_assigned_identity = dect_ie_hold(msg.nwk_assigned_identity); + param->network_parameter = dect_ie_hold(msg.network_parameter); + param->duration = dect_ie_hold(msg.duration); + param->iwu_to_iwu = dect_ie_hold(msg.iwu_to_iwu); + param->escape_to_proprietary = dect_ie_hold(msg.escape_to_proprietary); + + dect_close_transaction(dh, &mp->transaction, DECT_DDL_RELEASE_PARTIAL); + mp->type = DECT_MMP_NONE; + + dh->ops->mm_ops->mm_info_cfm(dh, mme, true, param); + dect_ie_collection_put(dh, param); +err1: + dect_msg_free(dh, &mm_info_accept_msg_desc, &msg.common); +} + +static void dect_mm_rcv_info_reject(struct dect_handle *dh, + struct dect_mm_endpoint *mme, + struct dect_msg_buf *mb) +{ + struct dect_mm_procedure *mp = &mme->procedure[DECT_TRANSACTION_INITIATOR]; + struct dect_mm_info_reject_msg msg; + struct dect_mm_info_param *param; + + mm_debug(mme, "INFO-REJECT"); + if (mp->type != DECT_MMP_PARAMETER_RETRIEVAL) + return; + + if (dect_parse_sfmt_msg(dh, &mm_info_reject_msg_desc, + &msg.common, mb) < 0) + return; + + param = dect_ie_collection_alloc(dh, sizeof(*param)); + if (param == NULL) + goto err1; + + param->call_identity = dect_ie_hold(msg.call_identity); + param->reject_reason = dect_ie_hold(msg.reject_reason); + param->iwu_to_iwu = dect_ie_hold(msg.iwu_to_iwu); + + dect_close_transaction(dh, &mp->transaction, DECT_DDL_RELEASE_PARTIAL); + mp->type = DECT_MMP_NONE; + + dh->ops->mm_ops->mm_info_cfm(dh, mme, false, param); + dect_ie_collection_put(dh, param); +err1: + dect_msg_free(dh, &mm_info_reject_msg_desc, &msg.common); + +} + +static void dect_mm_rcv_info_suggest(struct dect_handle *dh, + struct dect_mm_endpoint *mme, + struct dect_msg_buf *mb) +{ + struct dect_mm_info_suggest_msg msg; + struct dect_mm_info_param *param; + + mm_debug(mme, "INFO-SUGGEST"); + if (dect_parse_sfmt_msg(dh, &mm_info_suggest_msg_desc, + &msg.common, mb) < 0) + return; + + param = dect_ie_collection_alloc(dh, sizeof(*param)); + if (param == NULL) + goto err1; + + param->info_type = dect_ie_hold(msg.info_type); + param->call_identity = dect_ie_hold(msg.call_identity); + //param->fixed_identity = dect_ie_hold(msg.fixed_identity); + param->location_area = dect_ie_hold(msg.location_area); + param->nwk_assigned_identity = dect_ie_hold(msg.nwk_assigned_identity); + param->network_parameter = dect_ie_hold(msg.network_parameter); + param->iwu_to_iwu = dect_ie_hold(msg.iwu_to_iwu); + + dh->ops->mm_ops->mm_info_ind(dh, mme, param); + dect_ie_collection_put(dh, param); +err1: + dect_msg_free(dh, &mm_info_suggest_msg_desc, &msg.common); +} + static void dect_mm_rcv(struct dect_handle *dh, struct dect_transaction *ta, struct dect_msg_buf *mb) { @@ -1127,10 +1443,13 @@ static void dect_mm_rcv(struct dect_handle *dh, struct dect_transaction *ta, case DECT_MM_CIPHER_REJECT: return dect_mm_rcv_cipher_reject(dh, mme, mb); case DECT_MM_INFO_REQUEST: + return dect_mm_rcv_info_request(dh, mme, mb); case DECT_MM_INFO_ACCEPT: + return dect_mm_rcv_info_accept(dh, mme, mb); case DECT_MM_INFO_SUGGEST: + return dect_mm_rcv_info_suggest(dh, mme, mb); case DECT_MM_INFO_REJECT: - break; + return dect_mm_rcv_info_reject(dh, mme, mb); case DECT_MM_LOCATE_REQUEST: return dect_mm_rcv_locate_request(dh, mme, mb); case DECT_MM_LOCATE_ACCEPT: @@ -1166,6 +1485,7 @@ static void dect_mm_open(struct dect_handle *dh, case DECT_MM_ACCESS_RIGHTS_REQUEST: case DECT_MM_LOCATE_REQUEST: case DECT_MM_KEY_ALLOCATE: + case DECT_MM_INFO_REQUEST: break; default: return; diff --git a/src/s_msg.c b/src/s_msg.c index d348cb6..4cb358c 100644 --- a/src/s_msg.c +++ b/src/s_msg.c @@ -169,6 +169,76 @@ static int dect_sfmt_parse_single_keypad(const struct dect_handle *dh, return 0; } +static const struct dect_trans_tbl dect_info_type_parameters[] = { + TRANS_TBL(DECT_INFO_LOCATE_SUGGEST, "Locate suggest"), + TRANS_TBL(DECT_INFO_ACCESS_RIGHTS_MODIFY_SUGGEST, "Access rights modify suggest"), + TRANS_TBL(DECT_INFO_PP_AUTHENTICATION_FAILURE, "PP authentication failure"), + TRANS_TBL(DECT_INFO_DYNAMIC_PARAMETERS_ALLOCATION, "Dynamic parameters allocation"), + TRANS_TBL(DECT_INFO_EXTERNAL_HO_PARAMETERS, "External handover parameters"), + TRANS_TBL(DECT_INFO_LOCATION_AREA, "Location area"), + TRANS_TBL(DECT_INFO_HANDOVER_REFERENCE, "Handover reference"), + TRANS_TBL(DECT_INFO_MF_PSCN_SYNCHRONIZED_HANDOVER_CANDIATE, "Multiframe/PSCN synchronized ext. handover candidate"), + TRANS_TBL(DECT_INFO_EXT_HANDOVER_CANDIDATE, "Ext. handover candidate"), + TRANS_TBL(DECT_INFO_MF_SYNCHRONIZED_HANDOVER_CANDIATE, "Multiframe synchronized ext. handover candidate"), + TRANS_TBL(DECT_INFO_MF_PSCN_MFN_SYNCHRONIZED_HANDOVER_CANDIATE, "Multiframe/PSCN/MFN synchronized ext. handover candidate"), + TRANS_TBL(DECT_INFO_NON_SYNCHRONIZED_HANDOVER_CANDIDATE, "Non synchronized ext. handover candidate"), + TRANS_TBL(DECT_INFO_OLD_FIXED_PART_IDENTITY, "Old fixed part identity"), + TRANS_TBL(DECT_INFO_OLD_NETWORK_ASSIGNED_IDENTITY, "Old network assigned identity"), + TRANS_TBL(DECT_INFO_OLD_NETWORK_ASSIGNED_LOCATION_AREA, "Old network assigned location area"), + TRANS_TBL(DECT_INFO_OLD_NETWORK_ASSIGNED_HANDOVER_REFERENCE, "Old network assigend handover reference"), + TRANS_TBL(DECT_INFO_BILLING, "Billing"), + TRANS_TBL(DECT_INFO_DEBITING, "Debiting"), + TRANS_TBL(DECT_INFO_CK_TRANSFER, "CK transfer"), + TRANS_TBL(DECT_INFO_HANDOVER_FAILED_REVERSION, "Handover failed, reversion to old channel"), + TRANS_TBL(DECT_INFO_QA_M_CALL, "QA&M call"), + TRANS_TBL(DECT_INFO_DISTRIBUTED_COMMUNICATION_DOWNLOAD, "Distributed Communication Download"), + TRANS_TBL(DECT_INFO_ETHERNET_ADDRESS, "Ethernet address"), + TRANS_TBL(DECT_INFO_TOKEN_RING_ADDRESS, "Token Ring address"), + TRANS_TBL(DECT_INFO_IPV4_ADDRESS, "IPv4 address"), + TRANS_TBL(DECT_INFO_IPV6_ADDRESS, "IPv6 address"), + TRANS_TBL(DECT_INFO_IDENTITY_ALLOCATION, "Identity allocation"), +}; + +static void dect_sfmt_dump_info_type(const struct dect_ie_common *_ie) +{ + const struct dect_ie_info_type *ie = dect_ie_container(ie, _ie); + unsigned int i; + char buf[32]; + + for (i = 0; i < ie->num; i++) + dect_debug("\tparameter type[%u]: %x (%s)\n", i, ie->type[i], + dect_val2str(dect_info_type_parameters, buf, ie->type[i])); +} + +static int dect_sfmt_build_info_type(struct dect_sfmt_ie *dst, + const struct dect_ie_common *src) +{ + struct dect_ie_info_type *ie = dect_ie_container(ie, src); + unsigned int n = 2, i; + + for (i = 0; i < ie->num; i++) + dst->data[n++] = ie->type[i]; + dst->data[n - 1] |= DECT_OCTET_GROUP_END; + dst->len = n; + return 0; +} + +static int dect_sfmt_parse_info_type(const struct dect_handle *dh, + struct dect_ie_common **ie, + const struct dect_sfmt_ie *src) +{ + struct dect_ie_info_type *dst = dect_ie_container(dst, *ie); + unsigned int n = 2; + + while (dst->num < array_size(dst->type)) { + dst->type[dst->num++] = src->data[n] & ~DECT_OCTET_GROUP_END; + if (src->data[n] & DECT_OCTET_GROUP_END) + break; + n++; + } + return 0; +} + static const struct dect_trans_tbl dect_release_reasons[] = { TRANS_TBL(DECT_RELEASE_NORMAL, "normal"), TRANS_TBL(DECT_RELEASE_UNEXPECTED_MESSAGE, "unexpected message"), @@ -1206,6 +1276,9 @@ static const struct dect_ie_handler { [S_VL_IE_INFO_TYPE] = { .name = "info type", .size = sizeof(struct dect_ie_info_type), + .parse = dect_sfmt_parse_info_type, + .build = dect_sfmt_build_info_type, + .dump = dect_sfmt_dump_info_type, }, [S_VL_IE_IDENTITY_TYPE] = { .name = "identity type",