dect
/
libdect
Archived
13
0
Fork 0

lce: add full page support

Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
Patrick McHardy 2010-08-15 21:19:53 +02:00
parent e9ecafde61
commit ded21cc584
3 changed files with 144 additions and 9 deletions

View File

@ -19,7 +19,7 @@ static struct dect_llme_ops_ dummy_llme_ops;
static bool lce_page_response(struct dect_handle *dh,
struct dect_lce_page_param *param)
{
return true;
return false;
}
static void lce_group_ring_ind(struct dect_handle *dh,

View File

@ -11,6 +11,11 @@ struct dect_short_page_msg {
__be16 information;
} __packed;
struct dect_full_page_msg {
uint8_t hdr;
__be32 information;
} __packed;
/*
* LCE request paging messages
*/
@ -50,4 +55,38 @@ enum lce_request_page_hdr_codes {
#define DECT_LCE_SHORT_PAGE_TPUI_MASK 0xffff
/* Full format message */
enum dect_request_page_slot_types {
DECT_LCE_PAGE_HALF_SLOT = 0x0,
DECT_LCE_PAGE_LONG_SLOT_J640 = 0x1,
DECT_LCE_PAGE_LONG_SLOT_J672 = 0x2,
DECT_LCE_PAGE_FULL_SLOT = 0x4,
DECT_LCE_PAGE_DOUBLE_SLOT = 0x5,
};
enum dect_request_page_setup_info {
DECT_LCE_PAGE_NO_SETUP_INFO = 0x0,
DECT_LCE_PAGE_BASIC_CONN_ATTR_OPTIONAL = 0x1,
DECT_LCE_PAGE_BASIC_CONN_ATTR_MANDATORY = 0x2,
DECT_LCE_PAGE_ADV_CONN_ATTR_MANDATORY = 0x3,
DECT_LCE_PAGE_B_FIELD_SIGNALLING = 0x4,
DECT_LCE_PAGE_B_FIELD_SIGNALLING_CF = 0x5,
};
#define DECT_LCE_FULL_PAGE_RING_PATTERN_MASK 0x0f000000
#define DECT_LCE_FULL_PAGE_RING_PATTERN_SHIFT 24
#define DECT_LCE_FULL_PAGE_GROUP_MASK 0x00ffff00
#define DECT_LCE_FULL_PAGE_GROUP_SHIFT 8
#define DECT_LCE_FULL_PAGE_SLOT_TYPE_MASK 0xf0000000
#define DECT_LCE_FULL_PAGE_SLOT_TYPE_SHIFT 28
#define DECT_LCE_FULL_PAGE_TPUI_MASK 0x0fffff00
#define DECT_LCE_FULL_PAGE_TPUI_SHIFT 8
#define DECT_LCE_FULL_PAGE_SETUP_INFO_MASK 0x000000f0
#define DECT_LCE_FULL_PAGE_SETUP_INFO_SHIFT 4
#endif /* _LIBDECT_B_FMT_H */

112
src/lce.c
View File

@ -847,17 +847,15 @@ int dect_lce_group_ring_req(struct dect_handle *dh,
}
EXPORT_SYMBOL(dect_lce_group_ring_req);
static int dect_lce_page(const struct dect_handle *dh,
const struct dect_ipui *ipui)
static int dect_lce_send_short_page(const struct dect_handle *dh,
const struct dect_ipui *ipui)
{
DECT_DEFINE_MSG_BUF_ONSTACK(_mb), *mb = &_mb;
struct dect_short_page_msg *msg;
struct dect_tpui tpui;
uint16_t page;
dect_debug(DECT_DEBUG_LCE, "\n");
msg = dect_mbuf_put(mb, sizeof(*msg));
msg->hdr = DECT_LCE_PAGE_GENERAL_VOICE;
page = dect_build_tpui(dect_ipui_to_tpui(&tpui, ipui)) &
@ -867,11 +865,58 @@ static int dect_lce_page(const struct dect_handle *dh,
return dect_lce_broadcast(dh, mb, false);
}
static int dect_lce_send_full_page(const struct dect_handle *dh,
const struct dect_ipui *ipui)
{
DECT_DEFINE_MSG_BUF_ONSTACK(_mb), *mb = &_mb;
struct dect_full_page_msg *msg;
struct dect_tpui tpui;
uint8_t ipui_buf[8];
uint32_t page;
msg = dect_mbuf_put(mb, sizeof(*msg));
msg->hdr = DECT_LCE_PAGE_GENERAL_VOICE;
if (1) {
msg->hdr |= DECT_LCE_PAGE_W_FLAG;
page = dect_build_tpui(dect_ipui_to_tpui(&tpui, ipui)) <<
DECT_LCE_FULL_PAGE_TPUI_SHIFT;
page |= DECT_LCE_PAGE_FULL_SLOT <<
DECT_LCE_FULL_PAGE_SLOT_TYPE_SHIFT;
page |= DECT_LCE_PAGE_BASIC_CONN_ATTR_OPTIONAL <<
DECT_LCE_FULL_PAGE_SETUP_INFO_SHIFT;
} else {
dect_build_ipui(ipui_buf, ipui);
page = ipui->put << 24;
page |= (ipui_buf[1] & 0x0f) << 24;
page |= ipui_buf[2] << 16;
page |= ipui_buf[3] << 8;
page |= ipui_buf[4];
}
msg->information = __cpu_to_be32(page);
return dect_lce_broadcast(dh, mb, false);
}
static int dect_lce_page(const struct dect_handle *dh,
const struct dect_ipui *ipui)
{
if (0)
return dect_lce_send_short_page(dh, ipui);
else
return dect_lce_send_full_page(dh, ipui);
}
static void dect_ddl_page_timer(struct dect_handle *dh, struct dect_timer *timer)
{
struct dect_data_link *ddl = timer->data;
ddl_debug(ddl, "Page timer");
if (ddl->page_count) {
dect_debug(DECT_DEBUG_LCE, "\n");
ddl_debug(ddl, "Page timer");
}
if (ddl->page_count++ == DECT_DDL_PAGE_RETRANS_MAX)
dect_ddl_shutdown(dh, ddl);
else {
@ -1002,7 +1047,7 @@ static void dect_lce_rcv_short_page(struct dect_handle *dh,
w = msg->hdr & DECT_LCE_PAGE_W_FLAG;
hdr = msg->hdr & DECT_LCE_PAGE_HDR_MASK;
info = __be16_to_cpu(msg->information);
lce_debug("short page: w=%u hdr=%u information=%04x\n", w, hdr, info);
lce_debug("short page: w: %u hdr: %u information: %04x\n", w, hdr, info);
if (hdr == DECT_LCE_PAGE_UNKNOWN_RINGING) {
pattern = (info & DECT_LCE_SHORT_PAGE_RING_PATTERN_MASK) >>
@ -1040,7 +1085,58 @@ static void dect_lce_rcv_short_page(struct dect_handle *dh,
static void dect_lce_rcv_full_page(struct dect_handle *dh,
struct dect_msg_buf *mb)
{
lce_debug("full page\n");
struct dect_full_page_msg *msg = (void *)mb->data;
uint32_t info, ipui, tpui, t;
uint8_t ipui_buf[8];
uint8_t hdr, pattern;
bool w;
w = msg->hdr & DECT_LCE_PAGE_W_FLAG;
hdr = msg->hdr & DECT_LCE_PAGE_HDR_MASK;
info = __be32_to_cpu(msg->information);
lce_debug("full page: w: %u hdr: %u information: %08x\n", w, hdr, info);
if (hdr == DECT_LCE_PAGE_UNKNOWN_RINGING) {
pattern = (info & DECT_LCE_FULL_PAGE_RING_PATTERN_MASK) >>
DECT_LCE_FULL_PAGE_RING_PATTERN_SHIFT;
tpui = (info & DECT_LCE_FULL_PAGE_GROUP_MASK) >>
DECT_LCE_FULL_PAGE_GROUP_SHIFT;
if (w == 0) {
/* assigned connectionless group TPUI or CBI */
if (tpui != DECT_TPUI_CBI)
return;
} else {
/* group mask */
return;
}
lce_debug("LCE_GROUP_RING-ind: pattern: %x\n", pattern);
dh->ops->lce_ops->lce_group_ring_ind(dh, pattern);
} else {
if (w == 0) {
/* IPUI */
dect_build_ipui(ipui_buf, &dh->ipui);
ipui = dh->ipui.put << 24;
ipui |= (ipui_buf[1] & 0x0f) << 24;
ipui |= ipui_buf[2] << 16;
ipui |= ipui_buf[3] << 8;
ipui |= ipui_buf[4];
if (info != ipui)
return;
} else {
/* assigned TPUI or CBI */
tpui = (info & DECT_LCE_FULL_PAGE_TPUI_MASK) >>
DECT_LCE_FULL_PAGE_TPUI_SHIFT;
t = dect_build_tpui(&dh->tpui);
if (tpui != t && tpui != DECT_TPUI_CBI)
return;
}
dect_lce_send_page_response(dh);
}
}
static void dect_lce_rcv_long_page(struct dect_handle *dh,
@ -1127,7 +1223,7 @@ static void dect_lce_open(struct dect_handle *dh,
static void dect_lce_shutdown(struct dect_handle *dh,
struct dect_transaction *ta)
{
lce_debug("shutdown page transaction");
lce_debug("shutdown page transaction\n");
dect_transaction_close(dh, ta, DECT_DDL_RELEASE_NORMAL);
}