summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2012-02-09 21:05:55 +0100
committerPatrick McHardy <kaber@trash.net>2012-02-09 21:05:55 +0100
commitcf705660fea7612a5f1f40f98d5dab9975dfa5eb (patch)
tree4a90aa6cbd065161ff807356ae00dc9ac78a23e4
parent53f59f42775c01f9c68ff8f369cc3cd91c4013fd (diff)
parentee513d78ff14644b28644d1610f75b817c96c62a (diff)
Merge branch 'master' of ssh://dect.osmocom.org/var/cache/git/libdect
-rw-r--r--Makefile.defs.in2
-rw-r--r--example/dummy_ops.c9
-rw-r--r--example/fp-locate-suggest.c39
-rw-r--r--example/hijack.c17
-rw-r--r--example/pp-access-rights-terminate.c28
-rw-r--r--example/pp-access-rights.c25
-rw-r--r--example/pp-detach.c29
-rw-r--r--example/pp-info-request.c30
-rw-r--r--example/pp-list-access.c49
-rw-r--r--example/pp-location-update.c26
-rw-r--r--include/dect/ie.h10
-rw-r--r--include/dect/lce.h13
-rw-r--r--include/dect/mm.h4
-rw-r--r--include/lce.h4
-rw-r--r--src/lce.c256
-rw-r--r--src/mm.c27
-rw-r--r--src/s_msg.c10
17 files changed, 448 insertions, 130 deletions
diff --git a/Makefile.defs.in b/Makefile.defs.in
index f04ceea..e7f0aba 100644
--- a/Makefile.defs.in
+++ b/Makefile.defs.in
@@ -23,7 +23,7 @@ docdir = @docdir@
pdfdir = @pdfdir@
confdir = @sysconfdir@/dect
-LDFLAGS += @LDFLAGS@
+LDFLAGS += @LDFLAGS@ -ldl # libdl for SDL?
LDFLAGS += @LIBS@
CPPFLAGS += @CPPFLAGS@
diff --git a/example/dummy_ops.c b/example/dummy_ops.c
index e33b940..4641592 100644
--- a/example/dummy_ops.c
+++ b/example/dummy_ops.c
@@ -18,6 +18,7 @@ static struct dect_llme_ops_ dummy_llme_ops;
*/
static bool lce_page_response(struct dect_handle *dh,
+ struct dect_data_link *ddl,
struct dect_lce_page_param *param)
{
return false;
@@ -28,6 +29,12 @@ static void lce_group_ring_ind(struct dect_handle *dh,
{
}
+static void dl_establish_cfm(struct dect_handle *dh, bool success,
+ struct dect_data_link *ddl,
+ const struct dect_mac_conn_params *mcp)
+{
+}
+
static struct dect_lce_ops dummy_lce_ops;
/*
@@ -339,6 +346,8 @@ void dect_dummy_ops_init(struct dect_ops *ops)
lce_ops->lce_page_response = lce_page_response;
if (!lce_ops->lce_group_ring_ind)
lce_ops->lce_group_ring_ind = lce_group_ring_ind;
+ if (!lce_ops->dl_establish_cfm)
+ lce_ops->dl_establish_cfm = dl_establish_cfm;
if (!ops->cc_ops)
ops->cc_ops = &dummy_cc_ops;
diff --git a/example/fp-locate-suggest.c b/example/fp-locate-suggest.c
index 9f16d3d..82f709d 100644
--- a/example/fp-locate-suggest.c
+++ b/example/fp-locate-suggest.c
@@ -21,38 +21,61 @@ static void mm_locate_ind(struct dect_handle *dh,
struct dect_mm_endpoint *mme,
struct dect_mm_locate_param *param)
{
+ struct dect_mm_locate_param res = {
+ .portable_identity = param->portable_identity,
+ .location_area = param->location_area,
+ };
+
+ dect_mm_locate_res(dh, mme, true, &res);
}
-static void mm_info_req(struct dect_handle *dh,
- const struct dect_ipui *ipui)
+static void mm_info_req(struct dect_handle *dh, struct dect_mm_endpoint *mme)
{
struct dect_ie_info_type info_type;
struct dect_mm_info_param req = { .info_type = &info_type };
- struct dect_mm_endpoint *mme;
-
- mme = dect_mm_endpoint_alloc(dh, ipui);
- if (mme == NULL)
- return;
info_type.num = 1;
info_type.type[0] = DECT_INFO_LOCATE_SUGGEST;
dect_mm_info_req(dh, mme, &req);
}
+static void dl_establish_cfm(struct dect_handle *dh, bool success,
+ struct dect_data_link *ddl,
+ const struct dect_mac_conn_params *mcp)
+{
+ struct dect_mm_endpoint *mme;
+
+ if (!success)
+ return dect_event_loop_stop();
+
+ mme = dect_mm_endpoint_alloc(dh, ddl);
+ if (mme == NULL)
+ pexit("dect_mm_endpoint_alloc");
+
+ mm_info_req(dh, mme);
+}
+
static struct dect_mm_ops mm_ops = {
.mm_locate_ind = mm_locate_ind,
};
+static struct dect_lce_ops lce_ops = {
+ .dl_establish_cfm = dl_establish_cfm,
+};
+
static struct dect_ops ops = {
+ .lce_ops = &lce_ops,
.mm_ops = &mm_ops,
};
int main(int argc, char **argv)
{
+ struct dect_mac_conn_params mcp = {};
+
dect_fp_common_options(argc, argv);
dect_common_init(&ops, argv[1]);
- mm_info_req(dh, &ipui);
+ dect_dl_establish_req(dh, &ipui, &mcp);
dect_event_loop();
dect_common_cleanup(dh);
diff --git a/example/hijack.c b/example/hijack.c
index cb4f43b..ecad978 100644
--- a/example/hijack.c
+++ b/example/hijack.c
@@ -29,13 +29,14 @@ static struct dect_mm_ops mm_ops = {
.mm_locate_ind = mm_locate_ind,
};
-static bool lce_page_response(struct dect_handle *dh, struct dect_lce_page_param *param)
+static bool lce_page_response(struct dect_handle *dh, struct dect_data_link *ddl,
+ struct dect_lce_page_param *param)
{
struct dect_ie_info_type info_type;
struct dect_mm_info_param req = { .info_type = &info_type };
struct dect_mm_endpoint *mme;
- mme = dect_mm_endpoint_alloc(dh, &param->portable_identity->ipui);
+ mme = dect_mm_endpoint_alloc(dh, ddl);
if (mme == NULL)
return false;
@@ -91,7 +92,19 @@ static void page_timer(struct dect_handle *dh, struct dect_timer *timer)
dect_timer_start(dh, timer, 1);
}
+static void dect_mac_me_info_ind(struct dect_handle *dh,
+ const struct dect_ari *pari,
+ const struct dect_fp_capabilities *fpc)
+{
+ printf("pari %p fpc %p\n", pari, fpc);
+}
+
+static struct dect_llme_ops_ llme_ops = {
+ .mac_me_info_ind = dect_mac_me_info_ind,
+};
+
static struct dect_ops ops = {
+ .llme_ops = &llme_ops,
.lce_ops = &lce_ops,
.mm_ops = &mm_ops,
};
diff --git a/example/pp-access-rights-terminate.c b/example/pp-access-rights-terminate.c
index 210f06e..5991d39 100644
--- a/example/pp-access-rights-terminate.c
+++ b/example/pp-access-rights-terminate.c
@@ -37,22 +37,36 @@ static struct dect_mm_ops mm_ops = {
.mm_access_rights_terminate_cfm = mm_access_rights_terminate_cfm,
};
+static void dl_establish_cfm(struct dect_handle *dh, bool success,
+ struct dect_data_link *ddl,
+ const struct dect_mac_conn_params *mcp)
+{
+ struct dect_mm_endpoint *mme;
+
+ mme = dect_mm_endpoint_alloc(dh, ddl);
+ if (mme == NULL)
+ pexit("dect_mm_endpoint_alloc");
+
+ mm_access_rights_terminate_req(dh, mme);
+}
+
+static struct dect_lce_ops lce_ops = {
+ .dl_establish_cfm = dl_establish_cfm,
+};
+
static struct dect_ops ops = {
- .mm_ops = &mm_ops,
+ .lce_ops = &lce_ops,
+ .mm_ops = &mm_ops,
};
int main(int argc, char **argv)
{
- struct dect_mm_endpoint *mme;
+ struct dect_mac_conn_params mcp = {};
dect_pp_common_options(argc, argv);
dect_pp_common_init(&ops, cluster, &ipui);
- mme = dect_mm_endpoint_alloc(dh, &ipui);
- if (mme == NULL)
- pexit("dect_mm_endpoint_alloc");
-
- mm_access_rights_terminate_req(dh, mme);
+ dect_dl_establish_req(dh, &ipui, &mcp);
dect_event_loop();
dect_common_cleanup(dh);
diff --git a/example/pp-access-rights.c b/example/pp-access-rights.c
index 1162d5d..f4b2333 100644
--- a/example/pp-access-rights.c
+++ b/example/pp-access-rights.c
@@ -149,6 +149,19 @@ static int mm_access_rights_req(struct dect_handle *dh, struct dect_mm_endpoint
return dect_mm_access_rights_req(dh, mme, &param);
}
+static void dl_establish_cfm(struct dect_handle *dh, bool success,
+ struct dect_data_link *ddl,
+ const struct dect_mac_conn_params *mcp)
+{
+ struct dect_mm_endpoint *mme;
+
+ mme = dect_mm_endpoint_alloc(dh, ddl);
+ if (mme == NULL)
+ pexit("dect_mm_endpoint_alloc");
+
+ mm_access_rights_req(dh, mme);
+}
+
static void llme_mac_me_info_ind(struct dect_handle *dh,
const struct dect_ari *pari,
const struct dect_fp_capabilities *fpc)
@@ -157,6 +170,10 @@ static void llme_mac_me_info_ind(struct dect_handle *dh,
dect_event_loop_stop();
}
+static struct dect_lce_ops lce_ops = {
+ .dl_establish_cfm = dl_establish_cfm,
+};
+
static struct dect_llme_ops_ llme_ops = {
.mac_me_info_ind = llme_mac_me_info_ind,
};
@@ -171,6 +188,7 @@ static struct dect_mm_ops mm_ops = {
static struct dect_ops ops = {
.llme_ops = &llme_ops,
+ .lce_ops = &lce_ops,
.mm_ops = &mm_ops,
};
@@ -191,7 +209,6 @@ static const struct option options[] = {
int main(int argc, char **argv)
{
- struct dect_mm_endpoint *mme;
const char *cluster = NULL;
int optidx = 0, c;
@@ -232,11 +249,7 @@ int main(int argc, char **argv)
dect_event_loop();
}
- mme = dect_mm_endpoint_alloc(dh, &ipui);
- if (mme == NULL)
- pexit("dect_mm_endpoint_alloc");
-
- mm_access_rights_req(dh, mme);
+ dect_dl_establish_req(dh, &ipui, NULL);
dect_event_loop();
dect_common_cleanup(dh);
diff --git a/example/pp-detach.c b/example/pp-detach.c
index 70c2530..8b1f1ae 100644
--- a/example/pp-detach.c
+++ b/example/pp-detach.c
@@ -25,20 +25,35 @@ static int mm_detach_req(struct dect_handle *dh, struct dect_mm_endpoint *mme)
return dect_mm_detach_req(dh, mme, &param);
}
-static struct dect_ops ops;
-
-int main(int argc, char **argv)
+static void dl_establish_cfm(struct dect_handle *dh, bool success,
+ struct dect_data_link *ddl,
+ const struct dect_mac_conn_params *mcp)
{
struct dect_mm_endpoint *mme;
- dect_pp_common_options(argc, argv);
- dect_pp_common_init(&ops, cluster, &ipui);
-
- mme = dect_mm_endpoint_alloc(dh, &ipui);
+ mme = dect_mm_endpoint_alloc(dh, ddl);
if (mme == NULL)
pexit("dect_mm_endpoint_alloc");
mm_detach_req(dh, mme);
+}
+
+static struct dect_lce_ops lce_ops = {
+ .dl_establish_cfm = dl_establish_cfm,
+};
+
+static struct dect_ops ops = {
+ .lce_ops = &lce_ops,
+};
+
+int main(int argc, char **argv)
+{
+ struct dect_mac_conn_params mcp = {};
+
+ dect_pp_common_options(argc, argv);
+ dect_pp_common_init(&ops, cluster, &ipui);
+
+ dect_dl_establish_req(dh, &ipui, &mcp);
dect_event_loop();
dect_common_cleanup(dh);
diff --git a/example/pp-info-request.c b/example/pp-info-request.c
index 6310c6c..8a52286 100644
--- a/example/pp-info-request.c
+++ b/example/pp-info-request.c
@@ -38,25 +38,39 @@ static int mm_info_req(struct dect_handle *dh, struct dect_mm_endpoint *mme)
}
static struct dect_mm_ops mm_ops = {
- .mm_info_cfm = mm_info_cfm,
+ .mm_info_cfm = mm_info_cfm,
+};
+
+static void dl_establish_cfm(struct dect_handle *dh, bool success,
+ struct dect_data_link *ddl,
+ const struct dect_mac_conn_params *mcp)
+{
+ struct dect_mm_endpoint *mme;
+
+ mme = dect_mm_endpoint_alloc(dh, ddl);
+ if (mme == NULL)
+ pexit("dect_mm_endpoint_alloc");
+
+ mm_info_req(dh, mme);
+}
+
+static struct dect_lce_ops lce_ops = {
+ .dl_establish_cfm = dl_establish_cfm,
};
static struct dect_ops ops = {
- .mm_ops = &mm_ops,
+ .lce_ops = &lce_ops,
+ .mm_ops = &mm_ops,
};
int main(int argc, char **argv)
{
- struct dect_mm_endpoint *mme;
+ struct dect_mac_conn_params mcp = {};
dect_pp_common_options(argc, argv);
dect_pp_common_init(&ops, cluster, &ipui);
- mme = dect_mm_endpoint_alloc(dh, &ipui);
- if (mme == NULL)
- pexit("dect_mm_endpoint_alloc");
-
- mm_info_req(dh, mme);
+ dect_dl_establish_req(dh, &ipui, &mcp);
dect_event_loop();
dect_common_cleanup(dh);
diff --git a/example/pp-list-access.c b/example/pp-list-access.c
index d58acae..72bbe32 100644
--- a/example/pp-list-access.c
+++ b/example/pp-list-access.c
@@ -32,15 +32,28 @@ static void dect_iwu_info_req(struct dect_handle *dh, struct dect_call *call)
dect_mncc_iwu_info_req(dh, call, &req);
}
-static void dect_mncc_connect_ind(struct dect_handle *dh, struct dect_call *call,
- struct dect_mncc_connect_param *param)
+static void dect_mncc_call_proc_ind(struct dect_handle *dh, struct dect_call *call,
+ struct dect_mncc_call_proc_param *param)
{
- struct dect_mncc_connect_param reply = {};
-
- dect_mncc_connect_res(dh, call, &reply);
dect_iwu_info_req(dh, call);
}
+static void dect_mncc_reject_ind(struct dect_handle *dh, struct dect_call *call,
+ enum dect_causes cause,
+ struct dect_mncc_release_param *param)
+{
+ dect_event_loop_stop();
+}
+
+static void dect_mncc_release_ind(struct dect_handle *dh, struct dect_call *call,
+ struct dect_mncc_release_param *param)
+{
+ struct dect_mncc_release_param res = {};
+
+ dect_mncc_release_res(dh, call, &res);
+ dect_event_loop_stop();
+}
+
static void dect_open_call(struct dect_handle *dh, const struct dect_ipui *ipui)
{
struct dect_ie_basic_service basic_service;
@@ -53,23 +66,41 @@ static void dect_open_call(struct dect_handle *dh, const struct dect_ipui *ipui)
if (call == NULL)
return;
- basic_service.class = DECT_CALL_CLASS_NORMAL;
- basic_service.service = DECT_SERVICE_BASIC_SPEECH_DEFAULT;
+ basic_service.class = DECT_CALL_CLASS_LIA_SERVICE_SETUP;
+ basic_service.service = DECT_SERVICE_WIDEBAND_SPEECH;
dect_mncc_setup_req(dh, call, ipui, &req);
}
+static void dect_dl_establish_cfm(struct dect_handle *dh, bool success,
+ struct dect_data_link *ddl,
+ const struct dect_mac_conn_params *mcp)
+{
+ dect_open_call(dh, &ipui);
+}
+
static struct dect_cc_ops cc_ops = {
- .mncc_connect_ind = dect_mncc_connect_ind,
+ .mncc_call_proc_ind = dect_mncc_call_proc_ind,
+ .mncc_release_ind = dect_mncc_release_ind,
+ .mncc_reject_ind = dect_mncc_reject_ind,
+};
+
+static struct dect_lce_ops lce_ops = {
+ .dl_establish_cfm = dect_dl_establish_cfm,
};
static struct dect_ops ops = {
+ .lce_ops = &lce_ops,
.cc_ops = &cc_ops,
};
int main(int argc, char **argv)
{
const struct dect_fp_capabilities *fpc;
+ struct dect_mac_conn_params mcp = {
+ .service = DECT_SERVICE_IN_MIN_DELAY,
+ .slot = DECT_LONG_SLOT_640,
+ };
dect_pp_common_options(argc, argv);
dect_pp_common_init(&ops, cluster, &ipui);
@@ -80,7 +111,7 @@ int main(int argc, char **argv)
goto out;
}
- dect_open_call(dh, &ipui);
+ dect_dl_establish_req(dh, &ipui, &mcp);
dect_event_loop();
out:
dect_common_cleanup(dh);
diff --git a/example/pp-location-update.c b/example/pp-location-update.c
index 099fbc0..d7c19f3 100644
--- a/example/pp-location-update.c
+++ b/example/pp-location-update.c
@@ -47,18 +47,36 @@ static int mm_locate_req(struct dect_handle *dh, struct dect_mm_endpoint *mme)
return dect_mm_locate_req(dh, mme, &param);
}
+static void dl_establish_cfm(struct dect_handle *dh, bool success,
+ struct dect_data_link *ddl,
+ const struct dect_mac_conn_params *mcp)
+{
+ struct dect_mm_endpoint *mme;
+
+ mme = dect_mm_endpoint_alloc(dh, ddl);
+ if (mme == NULL)
+ pexit("dect_mm_endpoint_alloc");
+
+ mm_locate_req(dh, mme);
+}
+
static struct dect_mm_ops mm_ops = {
.mm_locate_cfm = mm_locate_cfm,
};
+static struct dect_lce_ops lce_ops = {
+ .dl_establish_cfm = dl_establish_cfm,
+};
+
static struct dect_ops ops = {
+ .lce_ops = &lce_ops,
.mm_ops = &mm_ops,
};
int main(int argc, char **argv)
{
const struct dect_fp_capabilities *fpc;
- struct dect_mm_endpoint *mme;
+ struct dect_mac_conn_params mcp = {};
dect_pp_common_options(argc, argv);
dect_pp_common_init(&ops, cluster, &ipui);
@@ -69,11 +87,7 @@ int main(int argc, char **argv)
goto out;
}
- mme = dect_mm_endpoint_alloc(dh, &ipui);
- if (mme == NULL)
- pexit("dect_mm_endpoint_alloc");
-
- mm_locate_req(dh, mme);
+ dect_dl_establish_req(dh, &ipui, &mcp);
dect_event_loop();
out:
dect_common_cleanup(dh);
diff --git a/include/dect/ie.h b/include/dect/ie.h
index e05bb67..36d3805 100644
--- a/include/dect/ie.h
+++ b/include/dect/ie.h
@@ -2083,11 +2083,11 @@ enum dect_mac_dlc_service {
/** Slot sizes */
enum dect_slot_size {
- DECT_HALF_SLOT = 0x0, /**< Half slot; j = 0. */
- DECT_LONG_SLOT_640 = 0x1, /**< Long slot; j = 640 */
- DECT_LONG_SLOT_672 = 0x2, /**< Long slot; j = 640 */
- DECT_FULL_SLOT = 0x4, /**< Full slot */
- DECT_DOUBLE_SLOT = 0x5, /**< Double slot */
+ DECT_HALF_SLOT_SIZE = 0x0, /**< Half slot; j = 0. */
+ DECT_LONG_SLOT_640_SIZE = 0x1, /**< Long slot; j = 640 */
+ DECT_LONG_SLOT_672_SIZE = 0x2, /**< Long slot; j = 640 */
+ DECT_FULL_SLOT_SIZE = 0x4, /**< Full slot */
+ DECT_DOUBLE_SLOT_SIZE = 0x5, /**< Double slot */
};
/** C-Plane routing options */
diff --git a/include/dect/lce.h b/include/dect/lce.h
index 5126e6b..b207c34 100644
--- a/include/dect/lce.h
+++ b/include/dect/lce.h
@@ -28,6 +28,9 @@ struct dect_lce_page_param {
struct dect_ie_escape_to_proprietary *escape_to_proprietary;
};
+struct dect_mac_conn_params;
+struct dect_data_link;
+
/**
* Link Control Entity Ops.
*
@@ -36,16 +39,26 @@ struct dect_lce_page_param {
*/
struct dect_lce_ops {
bool (*lce_page_response)(struct dect_handle *dh,
+ struct dect_data_link *ddl,
struct dect_lce_page_param *param);
/**< LCE_PAGE_RESPONSE-ind primitive */
void (*lce_group_ring_ind)(struct dect_handle *dh,
enum dect_alerting_patterns pattern);
/**< LCE_GROUP_RING-ind primitive */
+
+ void (*dl_establish_cfm)(struct dect_handle *dh, bool success,
+ struct dect_data_link *ddl,
+ const struct dect_mac_conn_params *mcp);
+ /**< DL_ESTABLISH-cfm primitive */
};
extern int dect_lce_group_ring_req(struct dect_handle *dh,
enum dect_alerting_patterns pattern);
+extern int dect_dl_establish_req(struct dect_handle *dh, const struct dect_ipui *ipui,
+ const struct dect_mac_conn_params *mcp);
+
+
/** @} */
#ifdef __cplusplus
diff --git a/include/dect/mm.h b/include/dect/mm.h
index f2e0e06..b055044 100644
--- a/include/dect/mm.h
+++ b/include/dect/mm.h
@@ -231,9 +231,7 @@ struct dect_mm_iwu_param {
struct dect_mm_endpoint;
extern struct dect_mm_endpoint *dect_mm_endpoint_alloc(struct dect_handle *dh,
- const struct dect_ipui *ipui);
-extern struct dect_mm_endpoint *dect_mm_endpoint_get(struct dect_handle *dh,
- const struct dect_ipui *ipui);
+ struct dect_data_link *ddl);
extern void dect_mm_endpoint_destroy(struct dect_handle *dh,
struct dect_mm_endpoint *mme);
extern void *dect_mm_priv(struct dect_mm_endpoint *mme);
diff --git a/include/lce.h b/include/lce.h
index 6b00538..4b3d615 100644
--- a/include/lce.h
+++ b/include/lce.h
@@ -183,9 +183,10 @@ enum dect_data_link_flags {
* struct dect_data_link
*
* @list: DECT handle link list node
- * @dfd: Associated socket file descriptor
* @dlei: Data Link Endpoint identifier
* @ipui: International Portable User ID
+ * @dfd: Associated socket file descriptor
+ * @mcp: MAC connections parameters
* @state: Data link state
* @sdu_timer: Establish without SDU timer (LCE.05)
* @release_timer: Normal link release timer (LCE.01)
@@ -198,6 +199,7 @@ struct dect_data_link {
struct sockaddr_dect_ssap dlei;
struct dect_ipui ipui;
struct dect_fd *dfd;
+ struct dect_mac_conn_params mcp;
enum dect_data_link_states state;
enum dect_cipher_states cipher;
struct dect_timer *sdu_timer;
diff --git a/src/lce.c b/src/lce.c
index 8aae519..5c5cc39 100644
--- a/src/lce.c
+++ b/src/lce.c
@@ -330,18 +330,6 @@ dect_page_capability(const struct dect_handle *dh,
return lte->setup_capability->page_capability;
}
-static uint64_t dect_profile_indicator(const struct dect_handle *dh,
- const struct dect_ipui *ipui)
-{
- const struct dect_lte *lte;
-
- lte = dect_lte_get_by_ipui(dh, ipui);
- if (lte == NULL ||
- lte->terminal_capability == NULL)
- return 0;
- return lte->terminal_capability->profile_indicator;
-}
-
/*
* Data links
*/
@@ -361,6 +349,28 @@ static const char * const ddl_states[DECT_DATA_LINK_STATE_MAX + 1] = {
[DECT_DATA_LINK_RESUME_PENDING] = "RESUME_PENDING",
};
+static const struct dect_trans_tbl dect_conn_types[] = {
+ TRANS_TBL(DECT_MAC_CONN_BASIC, "basic"),
+ TRANS_TBL(DECT_MAC_CONN_ADVANCED, "advanced"),
+};
+
+static const struct dect_trans_tbl dect_slot_types[] = {
+ TRANS_TBL(DECT_FULL_SLOT, "full slot"),
+ TRANS_TBL(DECT_HALF_SLOT, "half slot"),
+ TRANS_TBL(DECT_DOUBLE_SLOT, "double slot"),
+ TRANS_TBL(DECT_LONG_SLOT_640, "long slot j=640"),
+ TRANS_TBL(DECT_LONG_SLOT_672, "long slot j=672"),
+};
+
+static const struct dect_trans_tbl dect_service_types[] = {
+ TRANS_TBL(DECT_SERVICE_IN_MIN_DELAY, "In_minimum_delay"),
+ TRANS_TBL(DECT_SERVICE_IN_NORMAL_DELAY, "In_normal_delay"),
+ TRANS_TBL(DECT_SERVICE_UNKNOWN, "unknown"),
+ TRANS_TBL(DECT_SERVICE_C_CHANNEL_ONLY, "C channel only"),
+ TRANS_TBL(DECT_SERVICE_IP_ERROR_DETECTION, "Ip_error_detection"),
+ TRANS_TBL(DECT_SERVICE_IPQ_ERROR_DETECTION, "Ipq_error_detection"),
+};
+
int dect_ddl_set_ipui(struct dect_handle *dh, struct dect_data_link *ddl,
const struct dect_ipui *ipui)
{
@@ -846,17 +856,36 @@ static void dect_ddl_complete_direct_establish(struct dect_handle *dh,
struct dect_data_link *ddl)
{
struct dect_msg_buf *mb;
+ socklen_t optlen;
+ char buf1[128], buf2[128], buf3[128];
+
+ dect_fd_unregister(dh, ddl->dfd);
+ if (dect_fd_register(dh, ddl->dfd, DECT_FD_READ) < 0)
+ goto err1;
+
+ optlen = sizeof(ddl->mcp);
+ if (getsockopt(ddl->dfd->fd, SOL_DECT, DECT_DL_MAC_CONN_PARAMS,
+ &ddl->mcp, &optlen))
+ goto err1;
ddl->state = DECT_DATA_LINK_ESTABLISHED;
ddl_debug(ddl, "complete direct link establishment");
- dect_fd_unregister(dh, ddl->dfd);
- if (dect_fd_register(dh, ddl->dfd, DECT_FD_READ) < 0)
- return dect_ddl_shutdown(dh, ddl);
+ ddl_debug(ddl, "MAC connection: type: %s service: %s slot: %s",
+ dect_val2str(dect_conn_types, buf1, ddl->mcp.type),
+ dect_val2str(dect_service_types, buf2, ddl->mcp.service),
+ dect_val2str(dect_slot_types, buf3, ddl->mcp.slot));
+
+ ddl_debug(ddl, "DL_ESTABLISH-cfm: success: 1");
+ dh->ops->lce_ops->dl_establish_cfm(dh, true, ddl, &ddl->mcp);
/* Send queued messages */
while ((mb = ptrlist_dequeue_head(&ddl->msg_queue)))
dect_ddl_send(dh, ddl, mb);
+ return;
+
+err1:
+ dect_ddl_shutdown(dh, ddl);
}
static void dect_ddl_complete_indirect_establish(struct dect_handle *dh,
@@ -893,6 +922,9 @@ static void dect_ddl_complete_indirect_establish(struct dect_handle *dh,
/* Release pending link */
dect_ddl_destroy(dh, req);
+ ddl_debug(ddl, "DL_ESTABLISH-cfm: success: 1");
+ dh->ops->lce_ops->dl_establish_cfm(dh, true, ddl, &ddl->mcp);
+
/* If the link was established for a connectionless transmission,
* no transaction exists. Perform a partial release. */
if (list_empty(&ddl->transactions))
@@ -903,17 +935,24 @@ static void dect_ddl_page_timer(struct dect_handle *dh, struct dect_timer *timer
static void dect_lce_data_link_event(struct dect_handle *dh,
struct dect_fd *dfd, uint32_t events);
+static const struct dect_mac_conn_params default_mcp = {
+ .service = DECT_SERVICE_IN_MIN_DELAY,
+ .slot = DECT_FULL_SLOT,
+};
+
/**
* dect_ddl_establish - Establish an outgoing data link
*/
static struct dect_data_link *dect_ddl_establish(struct dect_handle *dh,
- const struct dect_ipui *ipui)
+ const struct dect_ipui *ipui,
+ const struct dect_mac_conn_params *mcp)
{
struct dect_data_link *ddl;
ddl = dect_ddl_alloc(dh);
if (ddl == NULL)
goto err1;
+ ddl->mcp = mcp ? *mcp : default_mcp;
ddl->state = DECT_DATA_LINK_ESTABLISH_PENDING;
dect_ddl_set_ipui(dh, ddl, ipui);
@@ -936,6 +975,11 @@ static struct dect_data_link *dect_ddl_establish(struct dect_handle *dh,
ddl->dlei.dect_lln = 1;
ddl->dlei.dect_sapi = 0;
+ if (mcp != NULL &&
+ setsockopt(ddl->dfd->fd, SOL_DECT, DECT_DL_MAC_CONN_PARAMS,
+ mcp, sizeof(*mcp)) < 0)
+ goto err2;
+
dect_fd_setup(ddl->dfd, dect_lce_data_link_event, ddl);
if (dect_fd_register(dh, ddl->dfd, DECT_FD_WRITE) < 0)
goto err2;
@@ -957,6 +1001,16 @@ err1:
return NULL;
}
+int dect_dl_establish_req(struct dect_handle *dh, const struct dect_ipui *ipui,
+ const struct dect_mac_conn_params *mcp)
+{
+ lce_debug("DL_ESTABLISH-req: IPUI: N EMC: %04x PSN: %05x\n",
+ ipui->pun.n.ipei.emc, ipui->pun.n.ipei.psn);
+ dect_ddl_establish(dh, ipui, mcp);
+ return 0;
+}
+EXPORT_SYMBOL(dect_dl_establish_req);
+
struct dect_data_link *dect_ddl_connect(struct dect_handle *dh,
const struct dect_ipui *ipui)
{
@@ -964,7 +1018,7 @@ struct dect_data_link *dect_ddl_connect(struct dect_handle *dh,
ddl = dect_ddl_get_by_ipui(dh, ipui);
if (ddl == NULL)
- ddl = dect_ddl_establish(dh, ipui);
+ ddl = dect_ddl_establish(dh, ipui, NULL);
return ddl;
}
@@ -1004,6 +1058,8 @@ static void dect_lce_ssap_listener_event(struct dect_handle *dh,
{
struct dect_data_link *ddl;
struct dect_fd *nfd;
+ socklen_t optlen;
+ char buf1[128], buf2[128], buf3[128];
dect_debug(DECT_DEBUG_LCE, "\n");
ddl = dect_ddl_alloc(dh);
@@ -1016,6 +1072,11 @@ static void dect_lce_ssap_listener_event(struct dect_handle *dh,
goto err2;
ddl->dfd = nfd;
+ optlen = sizeof(ddl->mcp);
+ if (getsockopt(nfd->fd, SOL_DECT, DECT_DL_MAC_CONN_PARAMS,
+ &ddl->mcp, &optlen))
+ goto err3;
+
dect_fd_setup(nfd, dect_lce_data_link_event, ddl);
if (dect_fd_register(dh, nfd, DECT_FD_READ) < 0)
goto err3;
@@ -1028,6 +1089,10 @@ static void dect_lce_ssap_listener_event(struct dect_handle *dh,
ddl_debug(ddl, "new link: PMID: %x LCN: %u LLN: %u SAPI: %u",
ddl->dlei.dect_pmid, ddl->dlei.dect_lcn,
ddl->dlei.dect_lln, ddl->dlei.dect_sapi);
+ ddl_debug(ddl, "MAC connection: type: %s service: %s slot: %s",
+ dect_val2str(dect_conn_types, buf1, ddl->mcp.type),
+ dect_val2str(dect_service_types, buf2, ddl->mcp.service),
+ dect_val2str(dect_slot_types, buf3, ddl->mcp.slot));
return;
err4:
@@ -1084,6 +1149,94 @@ ssize_t dect_lce_broadcast(const struct dect_handle *dh,
return 0;
}
+static enum lce_request_page_hdr_codes
+dect_page_service_to_hdr(enum dect_mac_service_types service)
+{
+ switch (service) {
+ case DECT_SERVICE_IN_MIN_DELAY:
+ return DECT_LCE_PAGE_GENERAL_VOICE;
+ case DECT_SERVICE_IN_NORMAL_DELAY:
+ return DECT_LCE_PAGE_AUXILIARY;
+ case DECT_SERVICE_UNKNOWN:
+ return DECT_LCE_PAGE_UNKNOWN_RINGING;
+ case DECT_SERVICE_C_CHANNEL_ONLY:
+ return DECT_LCE_PAGE_U_PLANE_NONE;
+ default:
+ return DECT_LCE_PAGE_GENERAL_PURPOSE;
+ }
+}
+
+static enum dect_mac_service_types
+dect_page_hdr_to_service(enum lce_request_page_hdr_codes hdr)
+{
+ switch (hdr) {
+ case DECT_LCE_PAGE_U_PLANE_NONE:
+ return DECT_SERVICE_C_CHANNEL_ONLY;
+ case DECT_LCE_PAGE_UNKNOWN_RINGING:
+ return DECT_SERVICE_UNKNOWN;
+ case DECT_LCE_PAGE_GENERAL_PURPOSE:
+ return DECT_SERVICE_UNKNOWN;
+ case DECT_LCE_PAGE_GENERAL_VOICE:
+ return DECT_SERVICE_IN_MIN_DELAY;
+ case DECT_LCE_PAGE_AUXILIARY:
+ return DECT_SERVICE_IN_NORMAL_DELAY;
+ default:
+ BUG(); // FIXME
+ }
+}
+
+static enum dect_request_page_slot_types
+dect_page_slot_to_info(enum dect_slot_types slot)
+{
+ switch (slot) {
+ case DECT_FULL_SLOT:
+ return DECT_LCE_PAGE_FULL_SLOT;
+ case DECT_HALF_SLOT:
+ return DECT_LCE_PAGE_HALF_SLOT;
+ case DECT_DOUBLE_SLOT:
+ return DECT_LCE_PAGE_DOUBLE_SLOT;
+ case DECT_LONG_SLOT_640:
+ return DECT_LCE_PAGE_LONG_SLOT_J640;
+ case DECT_LONG_SLOT_672:
+ return DECT_LCE_PAGE_LONG_SLOT_J672;
+ default:
+ BUG();
+ }
+}
+
+static enum dect_slot_types
+dect_page_info_to_slot(enum dect_request_page_slot_types slot)
+{
+ /* 8.2.4.2: backwards compatibility: bit 8 indicates "full slot" */
+ if (slot & 0x80)
+ return DECT_FULL_SLOT;
+
+ switch (slot) {
+ case DECT_LCE_PAGE_HALF_SLOT:
+ return DECT_HALF_SLOT;
+ case DECT_LCE_PAGE_LONG_SLOT_J640:
+ return DECT_LONG_SLOT_640;
+ case DECT_LCE_PAGE_LONG_SLOT_J672:
+ return DECT_LONG_SLOT_672;
+ case DECT_LCE_PAGE_FULL_SLOT:
+ return DECT_FULL_SLOT;
+ case DECT_LCE_PAGE_DOUBLE_SLOT:
+ return DECT_DOUBLE_SLOT;
+ default:
+ BUG(); // FIXME
+ }
+}
+
+static enum dect_request_page_setup_info
+dect_page_service_to_setup_info(const struct dect_mac_conn_params *mcp)
+{
+ if (mcp->service == DECT_SERVICE_IN_MIN_DELAY &&
+ mcp->slot == DECT_FULL_SLOT)
+ return DECT_LCE_PAGE_BASIC_CONN_ATTR_OPTIONAL;
+ else
+ return DECT_LCE_PAGE_NO_SETUP_INFO;
+}
+
/**
* Request collective or group ringing
*
@@ -1113,7 +1266,8 @@ int dect_lce_group_ring_req(struct dect_handle *dh,
EXPORT_SYMBOL(dect_lce_group_ring_req);
static int dect_lce_send_short_page(const struct dect_handle *dh,
- const struct dect_ipui *ipui)
+ const struct dect_ipui *ipui,
+ const struct dect_mac_conn_params *mcp)
{
DECT_DEFINE_MSG_BUF_ONSTACK(_mb), *mb = &_mb;
struct dect_short_page_msg *msg;
@@ -1123,7 +1277,7 @@ static int dect_lce_send_short_page(const struct dect_handle *dh,
uint16_t page;
msg = dect_mbuf_put(mb, sizeof(*msg));
- msg->hdr = DECT_LCE_PAGE_GENERAL_VOICE;
+ msg->hdr = dect_page_service_to_hdr(mcp->service);
tpui = dect_tpui(dh, ipui);
if (tpui == NULL)
@@ -1142,7 +1296,8 @@ static int dect_lce_send_short_page(const struct dect_handle *dh,
}
static int dect_lce_send_full_page(const struct dect_handle *dh,
- const struct dect_ipui *ipui)
+ const struct dect_ipui *ipui,
+ const struct dect_mac_conn_params *mcp)
{
DECT_DEFINE_MSG_BUF_ONSTACK(_mb), *mb = &_mb;
struct dect_full_page_msg *msg;
@@ -1153,7 +1308,7 @@ static int dect_lce_send_full_page(const struct dect_handle *dh,
uint32_t page;
msg = dect_mbuf_put(mb, sizeof(*msg));
- msg->hdr = DECT_LCE_PAGE_GENERAL_VOICE;
+ msg->hdr = dect_page_service_to_hdr(mcp->service);
if (1) {
msg->hdr |= DECT_LCE_PAGE_W_FLAG;
@@ -1163,9 +1318,9 @@ static int dect_lce_send_full_page(const struct dect_handle *dh,
tpui = dect_ipui_to_tpui(&_tpui, ipui);
page = dect_build_tpui(tpui) << DECT_LCE_FULL_PAGE_TPUI_SHIFT;
- page |= DECT_LCE_PAGE_FULL_SLOT <<
+ page |= dect_page_slot_to_info(mcp->slot) <<
DECT_LCE_FULL_PAGE_SLOT_TYPE_SHIFT;
- page |= DECT_LCE_PAGE_BASIC_CONN_ATTR_OPTIONAL <<
+ page |= dect_page_service_to_setup_info(mcp) <<
DECT_LCE_FULL_PAGE_SETUP_INFO_SHIFT;
} else {
dect_build_ipui(ipui_buf, ipui);
@@ -1185,12 +1340,14 @@ static int dect_lce_send_full_page(const struct dect_handle *dh,
}
static int dect_lce_page(const struct dect_handle *dh,
- const struct dect_ipui *ipui)
+ const struct dect_ipui *ipui,
+ const struct dect_mac_conn_params *mcp)
{
- if (dect_profile_indicator(dh, ipui) & DECT_PROFILE_NG_DECT_PART_1)
- return dect_lce_send_full_page(dh, ipui);
+ if (mcp->service == DECT_SERVICE_IN_MIN_DELAY &&
+ mcp->slot == DECT_FULL_SLOT)
+ return dect_lce_send_short_page(dh, ipui, mcp);
else
- return dect_lce_send_short_page(dh, ipui);
+ return dect_lce_send_full_page(dh, ipui, mcp);
}
static void dect_ddl_page_timer(struct dect_handle *dh, struct dect_timer *timer)
@@ -1202,10 +1359,12 @@ static void dect_ddl_page_timer(struct dect_handle *dh, struct dect_timer *timer
ddl_debug(ddl, "<LCE.03>: Page timer");
}
- if (ddl->page_count++ == DECT_DDL_PAGE_RETRANS_MAX)
+ if (ddl->page_count++ == DECT_DDL_PAGE_RETRANS_MAX) {
+ ddl_debug(ddl, "DL_ESTABLISH-cfm: success: 0");
+ dh->ops->lce_ops->dl_establish_cfm(dh, false, NULL, NULL);
dect_ddl_shutdown(dh, ddl);
- else {
- dect_lce_page(dh, &ddl->ipui);
+ } else {
+ dect_lce_page(dh, &ddl->ipui, &ddl->mcp);
dect_timer_start(dh, ddl->page_timer, DECT_DDL_PAGE_TIMEOUT);
}
}
@@ -1269,7 +1428,7 @@ static void dect_lce_rcv_page_response(struct dect_handle *dh,
param->cipher_info = dect_ie_hold(msg.cipher_info);
param->escape_to_proprietary = dect_ie_hold(msg.escape_to_proprietary);
- reject = !dh->ops->lce_ops->lce_page_response(dh, param);
+ reject = !dh->ops->lce_ops->lce_page_response(dh, ta->link, param);
dect_ie_collection_put(dh, param);
}
err:
@@ -1297,8 +1456,10 @@ static void dect_lce_rcv_page_reject(struct dect_handle *dh,
dect_msg_free(dh, &lce_page_reject_msg_desc, &msg.common);
}
-static void dect_lce_send_page_response(struct dect_handle *dh)
+static void dect_lce_send_page_response(struct dect_handle *dh,
+ const struct dect_mac_conn_params *mcp)
{
+ struct dect_data_link *ddl;
struct dect_ie_portable_identity portable_identity;
struct dect_ie_fixed_identity fixed_identity;
struct dect_lce_page_response_msg msg = {
@@ -1312,12 +1473,20 @@ static void dect_lce_send_page_response(struct dect_handle *dh)
fixed_identity.type = DECT_FIXED_ID_TYPE_PARK;
fixed_identity.ari = dh->pari;
- if (dect_transaction_open(dh, &dh->page_transaction, &dh->ipui,
- DECT_PD_LCE) < 0)
+ ddl = dect_ddl_establish(dh, &dh->ipui, mcp);
+ if (ddl == NULL)
return;
+ if (dect_ddl_transaction_open(dh, &dh->page_transaction, ddl,
+ DECT_PD_LCE) < 0)
+ goto err1;
+
dect_lce_send(dh, &dh->page_transaction, &lce_page_response_msg_desc,
&msg.common, DECT_LCE_PAGE_RESPONSE);
+ return;
+
+err1:
+ dect_ddl_destroy(dh, ddl);
}
static void dect_lce_rcv_short_page(struct dect_handle *dh,
@@ -1363,7 +1532,7 @@ static void dect_lce_rcv_short_page(struct dect_handle *dh,
return;
}
- dect_lce_send_page_response(dh);
+ dect_lce_send_page_response(dh, NULL);
}
}
@@ -1371,9 +1540,10 @@ static void dect_lce_rcv_full_page(struct dect_handle *dh,
struct dect_msg_buf *mb)
{
struct dect_full_page_msg *msg = (void *)mb->data;
+ struct dect_mac_conn_params mcp;
uint32_t info, ipui, tpui, t;
uint8_t ipui_buf[8];
- uint8_t hdr, pattern;
+ uint8_t hdr, pattern, slot, setup;
bool w;
w = msg->hdr & DECT_LCE_PAGE_W_FLAG;
@@ -1399,6 +1569,8 @@ static void dect_lce_rcv_full_page(struct dect_handle *dh,
lce_debug("LCE_GROUP_RING-ind: pattern: %x\n", pattern);
dh->ops->lce_ops->lce_group_ring_ind(dh, pattern);
} else {
+ memset(&mcp, 0, sizeof(mcp));
+
if (w == 0) {
/* IPUI */
dect_build_ipui(ipui_buf, &dh->ipui);
@@ -1416,11 +1588,19 @@ static void dect_lce_rcv_full_page(struct dect_handle *dh,
DECT_LCE_FULL_PAGE_TPUI_SHIFT;
t = dect_build_tpui(&dh->tpui);
- if (tpui != t && tpui != DECT_TPUI_CBI)
+ if (0 && tpui != t && tpui != DECT_TPUI_CBI)
return;
+
+ slot = (info & DECT_LCE_FULL_PAGE_SLOT_TYPE_MASK) >>
+ DECT_LCE_FULL_PAGE_SLOT_TYPE_SHIFT;
+ setup = (info & DECT_LCE_FULL_PAGE_SETUP_INFO_MASK) >>
+ DECT_LCE_FULL_PAGE_SETUP_INFO_SHIFT;
+
+ mcp.service = dect_page_hdr_to_service(hdr);
+ mcp.slot = dect_page_info_to_slot(slot);
}
- dect_lce_send_page_response(dh);
+ dect_lce_send_page_response(dh, &mcp);
}
}
diff --git a/src/mm.c b/src/mm.c
index 54d7c6f..4d54220 100644
--- a/src/mm.c
+++ b/src/mm.c
@@ -522,22 +522,8 @@ dect_mm_endpoint_get_by_link(const struct dect_handle *dh,
return NULL;
}
-struct dect_mm_endpoint *dect_mm_endpoint_get(struct dect_handle *dh,
- const struct dect_ipui *ipui)
-{
- struct dect_mm_endpoint *mme;
-
- list_for_each_entry(mme, &dh->mme_list, list) {
- if (!dect_ipui_cmp(&mme->link->ipui, ipui))
- return mme;
- }
-
- return dect_mm_endpoint_alloc(dh, ipui);
-}
-EXPORT_SYMBOL(dect_mm_endpoint_get);
-
struct dect_mm_endpoint *dect_mm_endpoint_alloc(struct dect_handle *dh,
- const struct dect_ipui *ipui)
+ struct dect_data_link *ddl)
{
struct dect_mm_endpoint *mme;
@@ -548,17 +534,11 @@ struct dect_mm_endpoint *dect_mm_endpoint_alloc(struct dect_handle *dh,
goto err2;
if (dect_mm_procedure_init(dh, mme, DECT_TRANSACTION_RESPONDER) < 0)
goto err3;
-
- if (ipui != NULL) {
- mme->link = dect_ddl_connect(dh, ipui);
- if (mme->link == NULL)
- goto err4;
- }
+ mme->link = ddl;
list_add_tail(&mme->list, &dh->mme_list);
return mme;
-err4:
dect_timer_free(dh, mme->procedure[DECT_TRANSACTION_RESPONDER].timer);
err3:
dect_timer_free(dh, mme->procedure[DECT_TRANSACTION_INITIATOR].timer);
@@ -3245,10 +3225,9 @@ static void dect_mm_open(struct dect_handle *dh,
mme = dect_mm_endpoint_get_by_link(dh, req->link);
if (mme == NULL) {
- mme = dect_mm_endpoint_alloc(dh, NULL);
+ mme = dect_mm_endpoint_alloc(dh, req->link);
if (mme == NULL)
return;
- mme->link = req->link;
}
ta = &mme->procedure[DECT_TRANSACTION_RESPONDER].transaction;
diff --git a/src/s_msg.c b/src/s_msg.c
index ca09ba8..da83e8c 100644
--- a/src/s_msg.c
+++ b/src/s_msg.c
@@ -2011,11 +2011,11 @@ static const struct dect_trans_tbl dect_mac_dlc_services[] = {
};
static const struct dect_trans_tbl dect_slot_sizes[] = {
- TRANS_TBL(DECT_HALF_SLOT, "half slot"),
- TRANS_TBL(DECT_LONG_SLOT_640, "long slot j=640"),
- TRANS_TBL(DECT_LONG_SLOT_672, "long slot j=672"),
- TRANS_TBL(DECT_FULL_SLOT, "full slot"),
- TRANS_TBL(DECT_DOUBLE_SLOT, "double slot"),
+ TRANS_TBL(DECT_HALF_SLOT_SIZE, "half slot"),
+ TRANS_TBL(DECT_LONG_SLOT_640_SIZE, "long slot j=640"),
+ TRANS_TBL(DECT_LONG_SLOT_672_SIZE, "long slot j=672"),
+ TRANS_TBL(DECT_FULL_SLOT_SIZE, "full slot"),
+ TRANS_TBL(DECT_DOUBLE_SLOT_SIZE, "double slot"),
};
static const struct dect_trans_tbl dect_cplane_routing[] = {