dect
/
libdect
Archived
13
0
Fork 0

lce: maintain LCE location table

Maintain LCE location table and use it for determining paging mode
and setup capabilities.

Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
Patrick McHardy 2011-01-06 04:40:29 +01:00
parent 3973ec108a
commit ff3028a515
6 changed files with 143 additions and 28 deletions

View File

@ -102,7 +102,7 @@ extern int dect_lce_send_cl(struct dect_handle *dh, const struct dect_ipui *ipui
extern ssize_t dect_lce_broadcast(const struct dect_handle *dh,
const struct dect_msg_buf *mb,
bool long_page);
bool long_page, bool fast_page);
/**
* struct dect_nwk_protocol - NWK layer protocol
@ -144,14 +144,16 @@ extern void dect_lce_register_protocol(const struct dect_nwk_protocol *protocol)
* @tpui: Temporary Portable User ID
*/
struct dect_lte {
struct list_head list;
struct dect_ipui ipui;
struct dect_tpui tpui;
struct list_head list;
struct dect_ipui ipui;
struct dect_tpui tpui;
struct dect_ie_setup_capability *setup_capability;
struct dect_ie_terminal_capability *terminal_capability;
};
struct dect_location_table {
struct list_head entries;
};
extern void dect_lte_update(struct dect_handle *dh, const struct dect_ipui *ipui,
struct dect_ie_setup_capability *setup_capability,
struct dect_ie_terminal_capability *terminal_capability);
enum dect_data_link_states {
DECT_DATA_LINK_RELEASED,

View File

@ -26,6 +26,7 @@ enum dect_pp_identities {
* @tpui: PP's TPUI
* @pmid: PP's PMID
* @flags: PP identity validity flags
* @ldb: LCE location table data base
* @b_sap: B-SAP socket
* @s_sap: S-SAP listener socket
* @links: list of data links
@ -48,6 +49,8 @@ struct dect_handle {
uint32_t pmid;
uint32_t flags;
struct list_head ldb;
struct dect_fd *b_sap;
struct dect_fd *s_sap;
struct list_head links;

View File

@ -173,7 +173,7 @@ static void dect_clms_send_fixed(struct dect_handle *dh,
section++;
}
deliver:
dect_lce_broadcast(dh, mb, true);
dect_lce_broadcast(dh, mb, true, false);
}
/**

121
src/lce.c
View File

@ -204,7 +204,7 @@ static ssize_t dect_mbuf_send(const struct dect_handle *dh,
msg->msg_namelen = 0;
msg->msg_iov = &iov;
msg->msg_iovlen = 1;
msg->msg_flags = MSG_NOSIGNAL;
msg->msg_flags |= MSG_NOSIGNAL;
iov.iov_base = mb->data;
iov.iov_len = mb->len;
@ -216,24 +216,31 @@ static ssize_t dect_mbuf_send(const struct dect_handle *dh,
return len;
}
#if 0
/*
* Location Table
*/
#define dect_ie_update(pos, ie) \
do { \
if (ie == NULL) \
break; \
dect_ie_put(dh, pos); \
pos = dect_ie_hold(ie); \
} while (0)
static struct dect_lte *dect_lte_get_by_ipui(const struct dect_handle *dh,
const struct dect_ipui *ipui)
{
struct dect_lte *lte;
list_for_each_entry(lte, &dh->ldb.entries, list) {
list_for_each_entry(lte, &dh->ldb, list) {
if (!dect_ipui_cmp(&lte->ipui, ipui))
return lte;
}
return NULL;
}
static struct dect_lte *dect_lte_alloc(const struct dect_handle *dh,
static struct dect_lte *dect_lte_alloc(struct dect_handle *dh,
const struct dect_ipui *ipui)
{
struct dect_lte *lte;
@ -241,10 +248,74 @@ static struct dect_lte *dect_lte_alloc(const struct dect_handle *dh,
lte = dect_malloc(dh, sizeof(*lte));
if (lte == NULL)
return NULL;
memcpy(&lte->ipui, ipui, sizeof(lte->ipui));
lte->ipui = *ipui;
list_add_tail(&lte->list, &dh->ldb);
return lte;
}
#endif
static void dect_lte_release(struct dect_handle *dh, struct dect_lte *lte)
{
dect_ie_put(dh, lte->setup_capability);
dect_ie_put(dh, lte->terminal_capability);
list_del(&lte->list);
dect_free(dh, lte);
}
void dect_lte_update(struct dect_handle *dh, const struct dect_ipui *ipui,
struct dect_ie_setup_capability *setup_capability,
struct dect_ie_terminal_capability *terminal_capability)
{
struct dect_lte *lte;
lte = dect_lte_get_by_ipui(dh, ipui);
if (lte == NULL) {
lte = dect_lte_alloc(dh, ipui);
if (lte == NULL)
return;
}
dect_ie_update(lte->setup_capability, setup_capability);
dect_ie_update(lte->terminal_capability, terminal_capability);
}
static enum dect_setup_capabilities
dect_setup_capability(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->setup_capability == NULL)
return DECT_SETUP_NO_FAST_SETUP;
return lte->setup_capability->setup_capability;
}
static enum dect_page_capabilities
dect_page_capability(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->setup_capability == NULL)
return DECT_PAGE_CAPABILITY_NORMAL_PAGING;
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
@ -822,7 +893,8 @@ static struct dect_data_link *dect_ddl_establish(struct dect_handle *dh,
ddl->state = DECT_DATA_LINK_ESTABLISH_PENDING;
dect_ddl_set_ipui(dh, ddl, ipui);
if (dh->mode == DECT_MODE_FP) {
if (dh->mode == DECT_MODE_FP ||
dect_setup_capability(dh, ipui) != DECT_SETUP_NO_FAST_SETUP) {
ddl->page_timer = dect_timer_alloc(dh);
if (ddl->page_timer == NULL)
goto err2;
@ -951,7 +1023,7 @@ err1:
ssize_t dect_lce_broadcast(const struct dect_handle *dh,
const struct dect_msg_buf *mb,
bool long_page)
bool long_page, bool fast_page)
{
struct msghdr msg;
struct dect_bsap_auxdata aux;
@ -966,6 +1038,7 @@ ssize_t dect_lce_broadcast(const struct dect_handle *dh,
memset(cmsg_buf.buf, 0, sizeof(cmsg_buf.buf));
msg.msg_control = &cmsg_buf;
msg.msg_controllen = sizeof(cmsg_buf);
msg.msg_flags = 0;
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_len = CMSG_LEN(sizeof(aux));
@ -977,6 +1050,8 @@ ssize_t dect_lce_broadcast(const struct dect_handle *dh,
} else {
msg.msg_control = NULL;
msg.msg_controllen = 0;
if (fast_page)
msg.msg_flags = MSG_OOB;
}
dect_mbuf_dump(DECT_DEBUG_LCE, mb, "LCE: BCAST TX");
@ -1009,7 +1084,7 @@ int dect_lce_group_ring_req(struct dect_handle *dh,
page |= DECT_TPUI_CBI & DECT_LCE_SHORT_PAGE_TPUI_MASK;
msg->information = __cpu_to_be16(page);
return dect_lce_broadcast(dh, mb, false);
return dect_lce_broadcast(dh, mb, false, false);
}
EXPORT_SYMBOL(dect_lce_group_ring_req);
@ -1019,6 +1094,7 @@ static int dect_lce_send_short_page(const struct dect_handle *dh,
DECT_DEFINE_MSG_BUF_ONSTACK(_mb), *mb = &_mb;
struct dect_short_page_msg *msg;
struct dect_tpui tpui;
bool fast_page = false;
uint16_t page;
msg = dect_mbuf_put(mb, sizeof(*msg));
@ -1028,7 +1104,11 @@ static int dect_lce_send_short_page(const struct dect_handle *dh,
DECT_LCE_SHORT_PAGE_TPUI_MASK;
msg->information = __cpu_to_be16(page);
return dect_lce_broadcast(dh, mb, false);
if (dect_page_capability(dh, ipui) ==
DECT_PAGE_CAPABILITY_FAST_AND_NORMAL_PAGING)
fast_page = true;
return dect_lce_broadcast(dh, mb, false, fast_page);
}
static int dect_lce_send_full_page(const struct dect_handle *dh,
@ -1038,6 +1118,7 @@ static int dect_lce_send_full_page(const struct dect_handle *dh,
struct dect_full_page_msg *msg;
struct dect_tpui tpui;
uint8_t ipui_buf[8];
bool fast_page = false;
uint32_t page;
msg = dect_mbuf_put(mb, sizeof(*msg));
@ -1062,16 +1143,20 @@ static int dect_lce_send_full_page(const struct dect_handle *dh,
}
msg->information = __cpu_to_be32(page);
return dect_lce_broadcast(dh, mb, false);
if (dect_page_capability(dh, ipui) ==
DECT_PAGE_CAPABILITY_FAST_AND_NORMAL_PAGING)
fast_page = true;
return dect_lce_broadcast(dh, mb, false, fast_page);
}
static int dect_lce_page(const struct dect_handle *dh,
const struct dect_ipui *ipui)
{
if (1)
return dect_lce_send_short_page(dh, ipui);
else
if (dect_profile_indicator(dh, ipui) & DECT_PROFILE_NG_DECT_PART_1)
return dect_lce_send_full_page(dh, ipui);
else
return dect_lce_send_short_page(dh, ipui);
}
static void dect_ddl_page_timer(struct dect_handle *dh, struct dect_timer *timer)
@ -1666,11 +1751,15 @@ err1:
void dect_lce_exit(struct dect_handle *dh)
{
struct dect_data_link *ddl, *next;
struct dect_data_link *ddl, *ddl_next;
struct dect_lte *lte, *lte_next;
list_for_each_entry_safe(ddl, next, &dh->links, list)
list_for_each_entry_safe(ddl, ddl_next, &dh->links, list)
dect_ddl_shutdown(dh, ddl);
list_for_each_entry_safe(lte, lte_next, &dh->ldb, list)
dect_lte_release(dh, lte);
if (dh->mode == DECT_MODE_FP) {
dect_fd_unregister(dh, dh->s_sap);
dect_close(dh, dh->s_sap);

View File

@ -37,6 +37,7 @@ static struct dect_handle *dect_alloc_handle(struct dect_ops *ops)
memset(dh, 0, sizeof(*dh) + ops->priv_size);
dh->ops = ops;
init_list_head(&dh->ldb);
init_list_head(&dh->links);
init_list_head(&dh->mme_list);
return dh;

View File

@ -1448,15 +1448,21 @@ int dect_mm_access_rights_res(struct dect_handle *dh,
const struct dect_mm_access_rights_param *param)
{
struct dect_mm_procedure *mp = &mme->procedure[DECT_TRANSACTION_RESPONDER];
struct dect_mm_access_rights_param *req;
int err;
mm_debug_entry(mme, "MM_ACCESS_RIGHTS-res: accept: %u", accept);
if (mp->type != DECT_MMP_ACCESS_RIGHTS)
return -1;
if (accept)
if (accept) {
req = (struct dect_mm_access_rights_param *)mp->iec;
dect_lte_update(dh, &req->portable_identity->ipui,
req->setup_capability,
req->terminal_capability);
err = dect_mm_send_access_rights_accept(dh, mme, param);
else
} else
err = dect_mm_send_access_rights_reject(dh, mme, param);
if (err < 0)
@ -1473,11 +1479,13 @@ static void dect_mm_rcv_access_rights_request(struct dect_handle *dh,
{
struct dect_mm_access_rights_request_msg msg;
struct dect_mm_access_rights_param *param;
struct dect_mm_procedure *mp;
enum dect_sfmt_error err;
mm_debug(mme, "ACCESS-RIGHTS-REQUEST");
if (dect_mm_procedure_respond(dh, mme, DECT_MMP_ACCESS_RIGHTS) < 0)
return;
mp = mme->current;
err = dect_parse_sfmt_msg(dh, &mm_access_rights_request_msg_desc,
&msg.common, mb);
@ -1503,6 +1511,8 @@ static void dect_mm_rcv_access_rights_request(struct dect_handle *dh,
param->escape_to_proprietary = dect_ie_hold(msg.escape_to_proprietary);
param->codec_list = dect_ie_hold(msg.codec_list);
mp->iec = dect_ie_collection_hold(param);
mm_debug(mme, "MM_ACCESS_RIGHTS-ind");
dh->ops->mm_ops->mm_access_rights_ind(dh, mme, param);
dect_ie_collection_put(dh, param);
@ -1981,15 +1991,21 @@ int dect_mm_locate_res(struct dect_handle *dh, struct dect_mm_endpoint *mme,
bool accept, const struct dect_mm_locate_param *param)
{
struct dect_mm_procedure *mp = &mme->procedure[DECT_TRANSACTION_RESPONDER];
struct dect_mm_locate_param *req;
int err;
mm_debug_entry(mme, "MM_LOCATE-res: accept: %u", accept);
if (mp->type != DECT_MMP_LOCATION_REGISTRATION)
return -1;
if (accept)
if (accept) {
req = (struct dect_mm_locate_param *)mp->iec;
dect_lte_update(dh, &req->portable_identity->ipui,
req->setup_capability,
req->terminal_capability);
err = dect_mm_send_locate_accept(dh, mme, param);
else
} else
err = dect_mm_send_locate_reject(dh, mme, param);
if (err < 0)
@ -2017,11 +2033,13 @@ static void dect_mm_rcv_locate_request(struct dect_handle *dh,
{
struct dect_mm_locate_request_msg msg;
struct dect_mm_locate_param *param;
struct dect_mm_procedure *mp;
enum dect_sfmt_error err;
mm_debug(mme, "LOCATE-REQUEST");
if (dect_mm_procedure_respond(dh, mme, DECT_MMP_LOCATION_REGISTRATION) < 0)
return;
mp = mme->current;
err = dect_parse_sfmt_msg(dh, &mm_locate_request_msg_desc,
&msg.common, mb);
@ -2051,6 +2069,8 @@ static void dect_mm_rcv_locate_request(struct dect_handle *dh,
param->escape_to_proprietary = dect_ie_hold(msg.escape_to_proprietary);
param->codec_list = dect_ie_hold(msg.codec_list);
mp->iec = dect_ie_collection_hold(param);
mm_debug(mme, "MM_LOCATE-ind");
dh->ops->mm_ops->mm_locate_ind(dh, mme, param);
dect_ie_collection_put(dh, param);