ss: fix CLSS message routing
Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
parent
185c94d34b
commit
ed870d702b
|
@ -34,13 +34,13 @@ static void dect_invoke_ss(struct dect_handle *dh, const struct dect_ipui *ipui)
|
|||
.feature_activate = &feature_activate,
|
||||
};
|
||||
|
||||
sse = dect_ss_endpoint_alloc(dh);
|
||||
sse = dect_ss_endpoint_alloc(dh, ipui);
|
||||
if (sse == NULL)
|
||||
return;
|
||||
|
||||
feature_activate.feature = DECT_FEATURE_INDICATION_OF_SUBSCRIBER_NUMBER;
|
||||
|
||||
dect_mnss_setup_req(dh, sse, ipui, ¶m);
|
||||
dect_mnss_setup_req(dh, sse, ¶m);
|
||||
}
|
||||
|
||||
static struct dect_ss_ops ss_ops = {
|
||||
|
|
|
@ -38,7 +38,8 @@ struct dect_handle;
|
|||
struct dect_ss_endpoint;
|
||||
|
||||
extern void *dect_ss_priv(struct dect_ss_endpoint *sse);
|
||||
extern struct dect_ss_endpoint *dect_ss_endpoint_alloc(struct dect_handle *dh);
|
||||
extern struct dect_ss_endpoint *dect_ss_endpoint_alloc(struct dect_handle *dh,
|
||||
const struct dect_ipui *ipui);
|
||||
extern void dect_ss_endpoint_destroy(struct dect_handle *dh, struct dect_ss_endpoint *sse);
|
||||
|
||||
/**
|
||||
|
@ -62,7 +63,6 @@ struct dect_ss_ops {
|
|||
};
|
||||
|
||||
extern int dect_mnss_setup_req(struct dect_handle *dh, struct dect_ss_endpoint *sse,
|
||||
const struct dect_ipui *ipui,
|
||||
const struct dect_mnss_param *param);
|
||||
extern int dect_mnss_facility_req(struct dect_handle *dh, struct dect_ss_endpoint *sse,
|
||||
const struct dect_mnss_param *param);
|
||||
|
|
|
@ -56,7 +56,6 @@ enum dect_release_modes {
|
|||
* @role: Role (initiator/responder)
|
||||
* @tv: Transaction value
|
||||
*/
|
||||
enum dect_s_pd_values;
|
||||
struct dect_transaction {
|
||||
struct list_head list;
|
||||
struct dect_data_link *link;
|
||||
|
@ -96,6 +95,11 @@ extern int dect_lce_send(const struct dect_handle *dh,
|
|||
extern int dect_lce_retransmit(const struct dect_handle *dh,
|
||||
struct dect_transaction *ta);
|
||||
|
||||
extern int dect_lce_send_cl(struct dect_handle *dh, const struct dect_ipui *ipui,
|
||||
const struct dect_sfmt_msg_desc *desc,
|
||||
const struct dect_msg_common *msg,
|
||||
enum dect_pds pd, uint8_t type);
|
||||
|
||||
extern ssize_t dect_lce_broadcast(const struct dect_handle *dh,
|
||||
const struct dect_msg_buf *mb,
|
||||
bool long_page);
|
||||
|
|
|
@ -55,10 +55,12 @@ struct dect_ciss_register_msg {
|
|||
/**
|
||||
* struct dect_ss_endpoint - Supplementary Services Endpoint
|
||||
*
|
||||
* @ipui: PT's IPUI
|
||||
* @transaction: LCE link transaction
|
||||
* @priv: libdect user private storage
|
||||
*/
|
||||
struct dect_ss_endpoint {
|
||||
struct dect_ipui ipui;
|
||||
struct dect_transaction transaction;
|
||||
uint8_t priv[] __aligned(__alignof__(uint64_t));
|
||||
};
|
||||
|
|
84
src/lce.c
84
src/lce.c
|
@ -542,6 +542,38 @@ static ssize_t dect_ddl_send(const struct dect_handle *dh,
|
|||
return size;
|
||||
}
|
||||
|
||||
static struct dect_msg_buf *
|
||||
dect_lce_build_msg(const struct dect_handle *dh,
|
||||
const struct dect_transaction *ta,
|
||||
const struct dect_sfmt_msg_desc *desc,
|
||||
const struct dect_msg_common *msg, uint8_t type)
|
||||
{
|
||||
struct dect_msg_buf *mb;
|
||||
int err;
|
||||
|
||||
mb = dect_mbuf_alloc(dh);
|
||||
if (mb == NULL)
|
||||
goto err1;
|
||||
|
||||
dect_mbuf_reserve(mb, DECT_S_HDR_SIZE);
|
||||
err = dect_build_sfmt_msg(dh, desc, msg, mb);
|
||||
if (err < 0)
|
||||
goto err2;
|
||||
|
||||
dect_mbuf_push(mb, DECT_S_HDR_SIZE);
|
||||
mb->data[1] = type;
|
||||
mb->data[0] = ta->pd;
|
||||
mb->data[0] |= ta->tv << DECT_S_TI_TV_SHIFT;
|
||||
if (ta->role == DECT_TRANSACTION_RESPONDER)
|
||||
mb->data[0] |= DECT_S_TI_F_FLAG;
|
||||
return mb;
|
||||
|
||||
err2:
|
||||
dect_mbuf_free(dh, mb);
|
||||
err1:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* dect_lce_send - Queue a S-Format message for transmission to the LCE
|
||||
*/
|
||||
|
@ -552,27 +584,14 @@ int dect_lce_send(const struct dect_handle *dh,
|
|||
{
|
||||
struct dect_data_link *ddl = ta->link;
|
||||
struct dect_msg_buf *mb;
|
||||
int err;
|
||||
|
||||
mb = dect_mbuf_alloc(dh);
|
||||
mb = dect_lce_build_msg(dh, ta, desc, msg, type);
|
||||
if (mb == NULL)
|
||||
return -1;
|
||||
|
||||
dect_mbuf_reserve(mb, DECT_S_HDR_SIZE);
|
||||
err = dect_build_sfmt_msg(dh, desc, msg, mb);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (ddl->sdu_timer && dect_timer_running(ddl->sdu_timer))
|
||||
dect_ddl_stop_sdu_timer(dh, ddl);
|
||||
|
||||
dect_mbuf_push(mb, DECT_S_HDR_SIZE);
|
||||
mb->data[1] = type;
|
||||
mb->data[0] = ta->pd;
|
||||
mb->data[0] |= ta->tv << DECT_S_TI_TV_SHIFT;
|
||||
if (ta->role == DECT_TRANSACTION_RESPONDER)
|
||||
mb->data[0] |= DECT_S_TI_F_FLAG;
|
||||
|
||||
if (ta->mb != NULL)
|
||||
dect_mbuf_free(dh, ta->mb);
|
||||
ta->mb = mb;
|
||||
|
@ -590,6 +609,38 @@ int dect_lce_send(const struct dect_handle *dh,
|
|||
}
|
||||
}
|
||||
|
||||
int dect_lce_send_cl(struct dect_handle *dh, const struct dect_ipui *ipui,
|
||||
const struct dect_sfmt_msg_desc *desc,
|
||||
const struct dect_msg_common *msg,
|
||||
enum dect_pds pd, uint8_t type)
|
||||
{
|
||||
struct dect_data_link *ddl;
|
||||
struct dect_msg_buf *mb;
|
||||
struct dect_transaction ta = {
|
||||
.pd = pd,
|
||||
.tv = DECT_TV_CONNECTIONLESS,
|
||||
};
|
||||
|
||||
ddl = dect_ddl_connect(dh, ipui);
|
||||
if (ddl == NULL)
|
||||
return -1;
|
||||
|
||||
mb = dect_lce_build_msg(dh, &ta, desc, msg, type);
|
||||
if (mb == NULL)
|
||||
return -1;
|
||||
|
||||
switch (ddl->state) {
|
||||
case DECT_DATA_LINK_ESTABLISHED:
|
||||
return dect_ddl_send(dh, ddl, mb);
|
||||
case DECT_DATA_LINK_ESTABLISH_PENDING:
|
||||
ptrlist_add_tail(mb, &ddl->msg_queue);
|
||||
return 0;
|
||||
default:
|
||||
ddl_debug(ddl, "Invalid state: %u\n", ddl->state);
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
int dect_lce_retransmit(const struct dect_handle *dh,
|
||||
struct dect_transaction *ta)
|
||||
{
|
||||
|
@ -745,6 +796,11 @@ static void dect_ddl_complete_indirect_establish(struct dect_handle *dh,
|
|||
|
||||
/* Release pending link */
|
||||
dect_ddl_destroy(dh, req);
|
||||
|
||||
/* If the link was established for a connectionless transmission,
|
||||
* no transaction exists. Perform a partial release. */
|
||||
if (list_empty(&ddl->transactions))
|
||||
return dect_ddl_partial_release(dh, ddl);
|
||||
}
|
||||
|
||||
static void dect_ddl_page_timer(struct dect_handle *dh, struct dect_timer *timer);
|
||||
|
|
22
src/ss.c
22
src/ss.c
|
@ -103,13 +103,15 @@ void *dect_ss_priv(struct dect_ss_endpoint *sse)
|
|||
}
|
||||
EXPORT_SYMBOL(dect_ss_priv);
|
||||
|
||||
struct dect_ss_endpoint *dect_ss_endpoint_alloc(struct dect_handle *dh)
|
||||
struct dect_ss_endpoint *dect_ss_endpoint_alloc(struct dect_handle *dh,
|
||||
const struct dect_ipui *ipui)
|
||||
{
|
||||
struct dect_ss_endpoint *sse;
|
||||
|
||||
sse = dect_zalloc(dh, sizeof(*sse) + dh->ops->ss_ops->priv_size);
|
||||
if (sse == NULL)
|
||||
goto err1;
|
||||
sse->ipui = *ipui;
|
||||
|
||||
return sse;
|
||||
|
||||
|
@ -138,7 +140,6 @@ static struct dect_ss_endpoint *dect_ss_endpoint(struct dect_transaction *ta)
|
|||
* @param param Supplementary Services parameters
|
||||
*/
|
||||
int dect_mnss_setup_req(struct dect_handle *dh, struct dect_ss_endpoint *sse,
|
||||
const struct dect_ipui *ipui,
|
||||
const struct dect_mnss_param *param)
|
||||
{
|
||||
struct dect_ie_portable_identity portable_identity;
|
||||
|
@ -151,12 +152,13 @@ int dect_mnss_setup_req(struct dect_handle *dh, struct dect_ss_endpoint *sse,
|
|||
};
|
||||
|
||||
ss_debug_entry(sse, "MNSS_SETUP-req");
|
||||
if (dect_transaction_open(dh, &sse->transaction, ipui, DECT_PD_CISS) < 0)
|
||||
if (dect_transaction_open(dh, &sse->transaction, &sse->ipui,
|
||||
DECT_PD_CISS) < 0)
|
||||
goto err1;
|
||||
|
||||
if (dh->mode == DECT_MODE_PP) {
|
||||
portable_identity.type = DECT_PORTABLE_ID_TYPE_IPUI;
|
||||
portable_identity.ipui = *ipui;
|
||||
portable_identity.ipui = sse->ipui;
|
||||
msg.portable_identity = &portable_identity;
|
||||
}
|
||||
|
||||
|
@ -196,8 +198,14 @@ int dect_mnss_facility_req(struct dect_handle *dh, struct dect_ss_endpoint *sse,
|
|||
};
|
||||
|
||||
ss_debug_entry(sse, "MNSS_FACILITY-req");
|
||||
return dect_lce_send(dh, &sse->transaction, &ciss_facility_msg_desc,
|
||||
&msg.common, DECT_CISS_FACILITY);
|
||||
|
||||
if (sse->transaction.link != NULL)
|
||||
return dect_lce_send(dh, &sse->transaction, &ciss_facility_msg_desc,
|
||||
&msg.common, DECT_CISS_FACILITY);
|
||||
else
|
||||
return dect_lce_send_cl(dh, &sse->ipui, &ciss_facility_msg_desc,
|
||||
&msg.common, DECT_PD_CISS,
|
||||
DECT_CISS_FACILITY);
|
||||
}
|
||||
EXPORT_SYMBOL(dect_mnss_facility_req);
|
||||
|
||||
|
@ -320,7 +328,7 @@ static void dect_ciss_rcv_register(struct dect_handle *dh,
|
|||
if (dect_ddl_set_ipui(dh, req->link, &msg.portable_identity->ipui) < 0)
|
||||
goto out;
|
||||
|
||||
sse = dect_ss_endpoint_alloc(dh);
|
||||
sse = dect_ss_endpoint_alloc(dh, &msg.portable_identity->ipui);
|
||||
if (sse == NULL)
|
||||
goto out;
|
||||
|
||||
|
|
Reference in New Issue