dect
/
libdect
Archived
13
0
Fork 0

ss: fix CLSS message routing

Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
Patrick McHardy 2010-10-13 22:06:24 +02:00
parent 185c94d34b
commit ed870d702b
6 changed files with 96 additions and 26 deletions

View File

@ -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, &param);
dect_mnss_setup_req(dh, sse, &param);
}
static struct dect_ss_ops ss_ops = {

View File

@ -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);

View File

@ -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);

View File

@ -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));
};

View File

@ -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);

View File

@ -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;