dectmon: multi-cluster support
Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
parent
79004e4687
commit
6629561108
|
@ -4,9 +4,10 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <list.h>
|
#include <list.h>
|
||||||
|
#include <dect/libdect.h>
|
||||||
|
#include <dect/timer.h>
|
||||||
#include <dect/auth.h>
|
#include <dect/auth.h>
|
||||||
|
#include <phl.h>
|
||||||
extern struct dect_handle *dh;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
DECTMON_DUMP_MAC = 0x1,
|
DECTMON_DUMP_MAC = 0x1,
|
||||||
|
@ -26,6 +27,16 @@ extern void dect_dummy_ops_init(struct dect_ops *ops);
|
||||||
|
|
||||||
extern void dect_hexdump(const char *prefix, const uint8_t *buf, size_t size);
|
extern void dect_hexdump(const char *prefix, const uint8_t *buf, size_t size);
|
||||||
|
|
||||||
|
struct dect_handle_priv {
|
||||||
|
struct list_head list;
|
||||||
|
const char *cluster;
|
||||||
|
struct dect_timer *lock_timer;
|
||||||
|
struct dect_ari pari;
|
||||||
|
struct list_head pt_list;
|
||||||
|
|
||||||
|
struct dect_tbc *slots[DECT_FRAME_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
enum dect_mm_procedures {
|
enum dect_mm_procedures {
|
||||||
DECT_MM_NONE,
|
DECT_MM_NONE,
|
||||||
DECT_MM_KEY_ALLOCATION,
|
DECT_MM_KEY_ALLOCATION,
|
||||||
|
@ -33,7 +44,6 @@ enum dect_mm_procedures {
|
||||||
DECT_MM_CIPHERING,
|
DECT_MM_CIPHERING,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct dect_pt {
|
struct dect_pt {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
struct dect_ie_portable_identity *portable_identity;
|
struct dect_ie_portable_identity *portable_identity;
|
||||||
|
@ -59,7 +69,8 @@ struct dect_dl {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dect_msg_buf;
|
struct dect_msg_buf;
|
||||||
extern void dect_dl_data_ind(struct dect_dl *dl, struct dect_msg_buf *mb);
|
extern void dect_dl_data_ind(struct dect_handle *dh, struct dect_dl *dl,
|
||||||
|
struct dect_msg_buf *mb);
|
||||||
|
|
||||||
struct dect_lc {
|
struct dect_lc {
|
||||||
uint16_t lsig;
|
uint16_t lsig;
|
||||||
|
@ -69,12 +80,12 @@ struct dect_lc {
|
||||||
|
|
||||||
struct dect_mac_con {
|
struct dect_mac_con {
|
||||||
struct dect_lc *lc;
|
struct dect_lc *lc;
|
||||||
uint32_t pmid;
|
|
||||||
struct dect_tbc *tbc;
|
struct dect_tbc *tbc;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum dect_data_channels;
|
enum dect_data_channels;
|
||||||
extern void dect_mac_co_data_ind(struct dect_mac_con *mc,
|
extern void dect_mac_co_data_ind(struct dect_handle *dh,
|
||||||
|
struct dect_mac_con *mc,
|
||||||
enum dect_data_channels chan,
|
enum dect_data_channels chan,
|
||||||
struct dect_msg_buf *mb);
|
struct dect_msg_buf *mb);
|
||||||
|
|
||||||
|
@ -87,14 +98,22 @@ struct dect_mbc {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dect_tbc {
|
struct dect_tbc {
|
||||||
struct dect_mbc mbc[2];
|
uint8_t slot1;
|
||||||
struct dect_dl dl;
|
uint8_t slot2;
|
||||||
bool ciphered;
|
|
||||||
|
|
||||||
|
uint16_t fmid;
|
||||||
|
uint32_t pmid;
|
||||||
|
|
||||||
|
struct dect_timer *timer;
|
||||||
|
struct dect_mbc mbc[2];
|
||||||
|
|
||||||
|
bool ciphered;
|
||||||
uint8_t ks[2 * 45];
|
uint8_t ks[2 * 45];
|
||||||
|
|
||||||
|
struct dect_dl dl;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void dect_mac_rcv(struct dect_msg_buf *mb, uint8_t slot);
|
extern void dect_mac_rcv(struct dect_handle *dh, struct dect_msg_buf *mb);
|
||||||
|
|
||||||
/* DSC */
|
/* DSC */
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010 Patrick McHardy <kaber@trash.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -7,6 +15,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include <dect/libdect.h>
|
||||||
#include <dectmon.h>
|
#include <dectmon.h>
|
||||||
|
|
||||||
#define BLOCKSIZE 16
|
#define BLOCKSIZE 16
|
||||||
|
|
18
src/dlc.c
18
src/dlc.c
|
@ -43,8 +43,8 @@ static struct dect_lc *dect_lc_init(struct dect_mac_con *mc)
|
||||||
struct dect_lc *lc;
|
struct dect_lc *lc;
|
||||||
|
|
||||||
lc = calloc(1, sizeof(*lc));
|
lc = calloc(1, sizeof(*lc));
|
||||||
if ((mc->pmid & 0xf0000) != 0xe0000)
|
if ((mc->tbc->pmid & 0xf0000) != 0xe0000)
|
||||||
lc->lsig = mc->pmid;
|
lc->lsig = mc->tbc->pmid;
|
||||||
return lc;
|
return lc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,8 @@ static const uint8_t channel_sdu_size[] = {
|
||||||
|
|
||||||
#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
|
#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
|
||||||
|
|
||||||
static struct dect_msg_buf *dect_lc_reassemble(struct dect_lc *lc,
|
static struct dect_msg_buf *dect_lc_reassemble(struct dect_handle *dh,
|
||||||
|
struct dect_lc *lc,
|
||||||
enum dect_data_channels chan,
|
enum dect_data_channels chan,
|
||||||
struct dect_msg_buf *mb)
|
struct dect_msg_buf *mb)
|
||||||
{
|
{
|
||||||
|
@ -101,10 +102,12 @@ static struct dect_msg_buf *dect_lc_reassemble(struct dect_lc *lc,
|
||||||
mb = NULL;
|
mb = NULL;
|
||||||
|
|
||||||
if (lc->rx_buf->len >= lc->rx_len) {
|
if (lc->rx_buf->len >= lc->rx_len) {
|
||||||
assert(lc->rx_buf->len == lc->rx_len);
|
|
||||||
mb = lc->rx_buf;
|
mb = lc->rx_buf;
|
||||||
lc->rx_buf = NULL;
|
lc->rx_buf = NULL;
|
||||||
|
|
||||||
|
if (mb->len != lc->rx_len)
|
||||||
|
goto err;
|
||||||
|
|
||||||
if (!dect_fa_frame_csum_verify(lc, mb))
|
if (!dect_fa_frame_csum_verify(lc, mb))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
@ -121,7 +124,8 @@ err:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dect_mac_co_data_ind(struct dect_mac_con *mc, enum dect_data_channels chan,
|
void dect_mac_co_data_ind(struct dect_handle *dh, struct dect_mac_con *mc,
|
||||||
|
enum dect_data_channels chan,
|
||||||
struct dect_msg_buf *mb)
|
struct dect_msg_buf *mb)
|
||||||
{
|
{
|
||||||
struct dect_lc *lc;
|
struct dect_lc *lc;
|
||||||
|
@ -134,9 +138,9 @@ void dect_mac_co_data_ind(struct dect_mac_con *mc, enum dect_data_channels chan,
|
||||||
mc->lc = lc;
|
mc->lc = lc;
|
||||||
}
|
}
|
||||||
|
|
||||||
mb = dect_lc_reassemble(mc->lc, chan, mb);
|
mb = dect_lc_reassemble(dh, mc->lc, chan, mb);
|
||||||
if (mb != NULL && mb->len > DECT_FA_HDR_SIZE) {
|
if (mb != NULL && mb->len > DECT_FA_HDR_SIZE) {
|
||||||
dect_mbuf_pull(mb, DECT_FA_HDR_SIZE);
|
dect_mbuf_pull(mb, DECT_FA_HDR_SIZE);
|
||||||
dect_dl_data_ind(&mc->tbc->dl, mb);
|
dect_dl_data_ind(dh, &mc->tbc->dl, mb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,12 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010 Patrick McHardy <kaber@trash.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <dect/libdect.h>
|
#include <dect/libdect.h>
|
||||||
#include <dectmon.h>
|
#include <dectmon.h>
|
||||||
|
|
||||||
|
@ -6,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void llme_mac_me_info_ind(struct dect_handle *dh,
|
static void llme_mac_me_info_ind(struct dect_handle *dh,
|
||||||
|
const struct dect_ari *pari,
|
||||||
const struct dect_fp_capabilities *fpc)
|
const struct dect_fp_capabilities *fpc)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010 Patrick McHardy <kaber@trash.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
@ -6,9 +14,15 @@
|
||||||
#include <dect/libdect.h>
|
#include <dect/libdect.h>
|
||||||
#include <dectmon.h>
|
#include <dectmon.h>
|
||||||
|
|
||||||
|
struct io_event {
|
||||||
|
const struct dect_handle *dh;
|
||||||
|
struct event ev;
|
||||||
|
};
|
||||||
|
|
||||||
static void event_io_callback(int fd, short mask, void *data)
|
static void event_io_callback(int fd, short mask, void *data)
|
||||||
{
|
{
|
||||||
struct dect_fd *dfd = data;
|
struct dect_fd *dfd = data;
|
||||||
|
struct io_event *ioe = dect_fd_priv(dfd);
|
||||||
uint32_t events;
|
uint32_t events;
|
||||||
|
|
||||||
events = 0;
|
events = 0;
|
||||||
|
@ -17,13 +31,13 @@ static void event_io_callback(int fd, short mask, void *data)
|
||||||
if (mask & EV_WRITE)
|
if (mask & EV_WRITE)
|
||||||
events |= DECT_FD_WRITE;
|
events |= DECT_FD_WRITE;
|
||||||
|
|
||||||
dect_fd_process(dh, dfd, events);
|
dect_fd_process((struct dect_handle *)ioe->dh, dfd, events);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int register_fd(const struct dect_handle *dh, struct dect_fd *dfd,
|
static int register_fd(const struct dect_handle *dh, struct dect_fd *dfd,
|
||||||
uint32_t events)
|
uint32_t events)
|
||||||
{
|
{
|
||||||
struct event *ev = dect_fd_priv(dfd);
|
struct io_event *ioe = dect_fd_priv(dfd);
|
||||||
unsigned short mask;
|
unsigned short mask;
|
||||||
|
|
||||||
mask = EV_PERSIST;
|
mask = EV_PERSIST;
|
||||||
|
@ -32,45 +46,50 @@ static int register_fd(const struct dect_handle *dh, struct dect_fd *dfd,
|
||||||
if (events & DECT_FD_WRITE)
|
if (events & DECT_FD_WRITE)
|
||||||
mask |= EV_WRITE;
|
mask |= EV_WRITE;
|
||||||
|
|
||||||
event_set(ev, dect_fd_num(dfd), mask, event_io_callback, dfd);
|
ioe->dh = dh;
|
||||||
event_add(ev, NULL);
|
event_set(&ioe->ev, dect_fd_num(dfd), mask, event_io_callback, dfd);
|
||||||
|
event_add(&ioe->ev, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unregister_fd(const struct dect_handle *dh, struct dect_fd *dfd)
|
static void unregister_fd(const struct dect_handle *dh, struct dect_fd *dfd)
|
||||||
{
|
{
|
||||||
struct event *ev = dect_fd_priv(dfd);
|
struct io_event *ioe = dect_fd_priv(dfd);
|
||||||
|
|
||||||
event_del(ev);
|
event_del(&ioe->ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void event_timer_callback(int fd, short mask, void *data)
|
static void event_timer_callback(int fd, short mask, void *data)
|
||||||
{
|
{
|
||||||
dect_timer_run(dh, data);
|
struct dect_timer *timer = data;
|
||||||
|
struct io_event *ioe = dect_timer_priv(timer);
|
||||||
|
|
||||||
|
dect_timer_run((struct dect_handle *)ioe->dh, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_timer(const struct dect_handle *dh,
|
static void start_timer(const struct dect_handle *dh,
|
||||||
struct dect_timer *timer,
|
struct dect_timer *timer,
|
||||||
const struct timeval *tv)
|
const struct timeval *tv)
|
||||||
{
|
{
|
||||||
struct event *ev = dect_timer_priv(timer);
|
struct io_event *ioe = dect_timer_priv(timer);
|
||||||
|
|
||||||
evtimer_set(ev, event_timer_callback, timer);
|
ioe->dh = dh;
|
||||||
evtimer_add(ev, (struct timeval *)tv);
|
evtimer_set(&ioe->ev, event_timer_callback, timer);
|
||||||
|
evtimer_add(&ioe->ev, (struct timeval *)tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stop_timer(const struct dect_handle *dh, struct dect_timer *timer)
|
static void stop_timer(const struct dect_handle *dh, struct dect_timer *timer)
|
||||||
{
|
{
|
||||||
struct event *ev = dect_timer_priv(timer);
|
struct io_event *ioe = dect_timer_priv(timer);
|
||||||
|
|
||||||
evtimer_del(ev);
|
evtimer_del(&ioe->ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct dect_event_ops dect_event_ops = {
|
static const struct dect_event_ops dect_event_ops = {
|
||||||
.fd_priv_size = sizeof(struct event),
|
.fd_priv_size = sizeof(struct io_event),
|
||||||
.register_fd = register_fd,
|
.register_fd = register_fd,
|
||||||
.unregister_fd = unregister_fd,
|
.unregister_fd = unregister_fd,
|
||||||
.timer_priv_size = sizeof(struct event),
|
.timer_priv_size = sizeof(struct io_event),
|
||||||
.start_timer = start_timer,
|
.start_timer = start_timer,
|
||||||
.stop_timer = stop_timer
|
.stop_timer = stop_timer
|
||||||
};
|
};
|
||||||
|
|
141
src/mac.c
141
src/mac.c
|
@ -493,7 +493,7 @@ static int dect_parse_ct_data(struct dect_tail_msg *tm, uint64_t t, uint8_t seq)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dect_parse_tail_msg(struct dect_tail_msg *tm, uint8_t slot,
|
static int dect_parse_tail_msg(struct dect_tail_msg *tm,
|
||||||
const struct dect_msg_buf *mb)
|
const struct dect_msg_buf *mb)
|
||||||
{
|
{
|
||||||
uint64_t t;
|
uint64_t t;
|
||||||
|
@ -514,7 +514,7 @@ static int dect_parse_tail_msg(struct dect_tail_msg *tm, uint8_t slot,
|
||||||
return dect_parse_system_information(tm, t);
|
return dect_parse_system_information(tm, t);
|
||||||
case DECT_TI_PT:
|
case DECT_TI_PT:
|
||||||
/* Paging tail in direction FP->PP, MAC control otherwise */
|
/* Paging tail in direction FP->PP, MAC control otherwise */
|
||||||
if (slot < 12)
|
if (mb->slot < 12)
|
||||||
return dect_parse_paging_msg(tm, t);
|
return dect_parse_paging_msg(tm, t);
|
||||||
case DECT_TI_MT:
|
case DECT_TI_MT:
|
||||||
return dect_parse_mac_ctrl(tm, t);
|
return dect_parse_mac_ctrl(tm, t);
|
||||||
|
@ -524,32 +524,77 @@ static int dect_parse_tail_msg(struct dect_tail_msg *tm, uint8_t slot,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dect_trx_slot {
|
/*
|
||||||
struct dect_tbc *tbc;
|
* TBC
|
||||||
} slots[DECT_FRAME_SIZE];
|
*/
|
||||||
|
|
||||||
static struct dect_tbc *dect_tbc_init(uint32_t pmid)
|
#define tbc_log(tbc, fmt, args...) \
|
||||||
|
printf("TBC: PMID: %.5x FMID: %.3x: " fmt, \
|
||||||
|
(tbc)->pmid, (tbc)->fmid, ## args)
|
||||||
|
|
||||||
|
static void dect_tbc_release(struct dect_handle *dh, struct dect_tbc *tbc)
|
||||||
{
|
{
|
||||||
|
struct dect_handle_priv *priv = dect_handle_priv(dh);
|
||||||
|
|
||||||
|
tbc_log(tbc, "release\n");
|
||||||
|
if (dect_timer_running(tbc->timer))
|
||||||
|
dect_timer_stop(dh, tbc->timer);
|
||||||
|
priv->slots[tbc->slot1] = NULL;
|
||||||
|
priv->slots[tbc->slot2] = NULL;
|
||||||
|
free(tbc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dect_tbc_timeout(struct dect_handle *dh, struct dect_timer *timer)
|
||||||
|
{
|
||||||
|
struct dect_tbc *tbc = dect_timer_data(timer);
|
||||||
|
|
||||||
|
tbc_log(tbc, "timeout\n");
|
||||||
|
dect_tbc_release(dh, tbc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct dect_tbc *dect_tbc_init(struct dect_handle *dh,
|
||||||
|
const struct dect_tail_msg *tm,
|
||||||
|
uint8_t slot)
|
||||||
|
{
|
||||||
|
struct dect_handle_priv *priv = dect_handle_priv(dh);
|
||||||
|
uint8_t slot2 = dect_tdd_slot(slot);
|
||||||
struct dect_tbc *tbc;
|
struct dect_tbc *tbc;
|
||||||
|
|
||||||
tbc = calloc(1, sizeof(*tbc));
|
tbc = calloc(1, sizeof(*tbc));
|
||||||
if (tbc == NULL)
|
if (tbc == NULL)
|
||||||
return NULL;
|
goto err1;
|
||||||
|
|
||||||
tbc->dl.tbc = tbc;
|
tbc->slot1 = slot;
|
||||||
|
tbc->slot2 = slot2;
|
||||||
|
tbc->fmid = tm->cctl.fmid;
|
||||||
|
tbc->pmid = tm->cctl.pmid;
|
||||||
|
|
||||||
|
tbc->timer = dect_timer_alloc(dh);
|
||||||
|
if (tbc->timer == NULL)
|
||||||
|
goto err2;
|
||||||
|
dect_timer_setup(tbc->timer, dect_tbc_timeout, tbc);
|
||||||
|
dect_timer_start(dh, tbc->timer, 5);
|
||||||
|
|
||||||
tbc->mbc[DECT_MODE_FP].cs_seq = 1;
|
tbc->mbc[DECT_MODE_FP].cs_seq = 1;
|
||||||
tbc->mbc[DECT_MODE_FP].cf_seq = 1;
|
tbc->mbc[DECT_MODE_FP].cf_seq = 1;
|
||||||
tbc->mbc[DECT_MODE_FP].mc.pmid = pmid;
|
|
||||||
tbc->mbc[DECT_MODE_FP].mc.tbc = tbc;
|
tbc->mbc[DECT_MODE_FP].mc.tbc = tbc;
|
||||||
|
|
||||||
|
|
||||||
tbc->mbc[DECT_MODE_PP].cs_seq = 1;
|
tbc->mbc[DECT_MODE_PP].cs_seq = 1;
|
||||||
tbc->mbc[DECT_MODE_PP].cf_seq = 1;
|
tbc->mbc[DECT_MODE_PP].cf_seq = 1;
|
||||||
tbc->mbc[DECT_MODE_PP].mc.pmid = pmid;
|
|
||||||
tbc->mbc[DECT_MODE_PP].mc.tbc = tbc;
|
tbc->mbc[DECT_MODE_PP].mc.tbc = tbc;
|
||||||
|
|
||||||
|
tbc->dl.tbc = tbc;
|
||||||
|
|
||||||
|
priv->slots[slot] = tbc;
|
||||||
|
priv->slots[slot2] = tbc;
|
||||||
|
tbc_log(tbc, "establish: slot %u/%u\n", slot, slot2);
|
||||||
|
|
||||||
return tbc;
|
return tbc;
|
||||||
|
|
||||||
|
err2:
|
||||||
|
free(tbc);
|
||||||
|
err1:
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dect_dsc_cipher(struct dect_tbc *tbc, struct dect_msg_buf *mb)
|
static void dect_dsc_cipher(struct dect_tbc *tbc, struct dect_msg_buf *mb)
|
||||||
|
@ -557,7 +602,7 @@ static void dect_dsc_cipher(struct dect_tbc *tbc, struct dect_msg_buf *mb)
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
uint8_t *ks;
|
uint8_t *ks;
|
||||||
|
|
||||||
if (mb->slot < 12)
|
if (mb->slot < DECT_HALF_FRAME_SIZE)
|
||||||
ks = tbc->ks;
|
ks = tbc->ks;
|
||||||
else
|
else
|
||||||
ks = tbc->ks + 45;
|
ks = tbc->ks + 45;
|
||||||
|
@ -575,34 +620,40 @@ static void dect_dsc_cipher(struct dect_tbc *tbc, struct dect_msg_buf *mb)
|
||||||
mb->data[i + 8] ^= ks[i + 5];
|
mb->data[i + 8] ^= ks[i + 5];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dect_tbc_rcv(struct dect_tbc *tbc, uint8_t slot,
|
static void dect_tbc_rcv(struct dect_handle *dh, struct dect_tbc *tbc,
|
||||||
struct dect_msg_buf *mb, struct dect_tail_msg *tm)
|
struct dect_msg_buf *mb, struct dect_tail_msg *tm)
|
||||||
{
|
{
|
||||||
enum dect_b_identifications b_id;
|
enum dect_b_identifications b_id;
|
||||||
struct dect_mbc *mbc;
|
struct dect_mbc *mbc;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
uint8_t slot = mb->slot;
|
||||||
bool cf;
|
bool cf;
|
||||||
|
|
||||||
if (tbc->ciphered) {
|
if (tbc->ciphered) {
|
||||||
if (slot < 12)
|
if (slot < DECT_HALF_FRAME_SIZE)
|
||||||
dect_dsc_keystream(dect_dsc_iv(mb->mfn, mb->frame),
|
dect_dsc_keystream(dect_dsc_iv(mb->mfn, mb->frame),
|
||||||
tbc->dl.pt->dck,
|
tbc->dl.pt->dck,
|
||||||
tbc->ks, sizeof(tbc->ks));
|
tbc->ks, sizeof(tbc->ks));
|
||||||
dect_dsc_cipher(tbc, mb);
|
dect_dsc_cipher(tbc, mb);
|
||||||
}
|
}
|
||||||
|
|
||||||
mbc = &tbc->mbc[slot < 12 ? DECT_MODE_FP : DECT_MODE_PP];
|
if (tm->type == DECT_TM_TYPE_ID) {
|
||||||
|
dect_timer_stop(dh, tbc->timer);
|
||||||
|
dect_timer_start(dh, tbc->timer, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
mbc = &tbc->mbc[slot < DECT_HALF_FRAME_SIZE ? DECT_MODE_FP : DECT_MODE_PP];
|
||||||
b_id = (mb->data[0] & DECT_HDR_BA_MASK);
|
b_id = (mb->data[0] & DECT_HDR_BA_MASK);
|
||||||
|
|
||||||
if (tm->type == DECT_TM_TYPE_CT) {
|
if (tm->type == DECT_TM_TYPE_CT) {
|
||||||
if (tm->ctd.seq != mbc->cs_seq) {
|
if (tm->ctd.seq != mbc->cs_seq) {
|
||||||
printf("CS: incorrect seq: %u\n", tm->ctd.seq);
|
tbc_log(tbc, "CS: incorrect seq: %u\n", tm->ctd.seq);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mbc->cs_seq = !mbc->cs_seq;
|
mbc->cs_seq = !mbc->cs_seq;
|
||||||
|
|
||||||
dect_mbuf_pull(mb, 1);
|
dect_mbuf_pull(mb, 1);
|
||||||
dect_mac_co_data_ind(&mbc->mc, DECT_MC_C_S, mb);
|
dect_mac_co_data_ind(dh, &mbc->mc, DECT_MC_C_S, mb);
|
||||||
dect_mbuf_pull(mb, 7);
|
dect_mbuf_pull(mb, 7);
|
||||||
} else
|
} else
|
||||||
dect_mbuf_pull(mb, 8);
|
dect_mbuf_pull(mb, 8);
|
||||||
|
@ -616,21 +667,18 @@ static void dect_tbc_rcv(struct dect_tbc *tbc, uint8_t slot,
|
||||||
case DECT_BI_ETYPE_CF_0:
|
case DECT_BI_ETYPE_CF_0:
|
||||||
case DECT_BI_ETYPE_CF_1:
|
case DECT_BI_ETYPE_CF_1:
|
||||||
if (((b_id >> DECT_HDR_BA_SHIFT) & 0x1) != mbc->cf_seq) {
|
if (((b_id >> DECT_HDR_BA_SHIFT) & 0x1) != mbc->cf_seq) {
|
||||||
printf("CF: incorrect seq: %u\n", b_id & 0x1);
|
tbc_log(tbc, "CF: incorrect seq: %u\n", b_id & 0x1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mbc->cf_seq = !mbc->cf_seq;
|
mbc->cf_seq = !mbc->cf_seq;
|
||||||
|
|
||||||
for (i = 0; i < mb->len / 10; i++) {
|
for (i = 0; i < mb->len / 10; i++) {
|
||||||
if (cf) {
|
if (cf) {
|
||||||
mac_print("CF: seq: %u\n", i);
|
tbc_log(tbc, "CF: seq: %u\n", i);
|
||||||
dect_mac_co_data_ind(&mbc->mc, DECT_MC_C_F, mb);
|
dect_mac_co_data_ind(dh, &mbc->mc, DECT_MC_C_F, mb);
|
||||||
dect_mbuf_pull(mb, 10);
|
} else if (!(mb->data[0] & 0x80))
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(mb->data[0] & 0x80))
|
|
||||||
cf = true;
|
cf = true;
|
||||||
|
|
||||||
dect_mbuf_pull(mb, 10);
|
dect_mbuf_pull(mb, 10);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -641,11 +689,8 @@ static void dect_tbc_rcv(struct dect_tbc *tbc, uint8_t slot,
|
||||||
switch (tm->type) {
|
switch (tm->type) {
|
||||||
case DECT_TM_TYPE_BCCTRL:
|
case DECT_TM_TYPE_BCCTRL:
|
||||||
case DECT_TM_TYPE_ACCTRL:
|
case DECT_TM_TYPE_ACCTRL:
|
||||||
if (tm->cctl.cmd == DECT_CCTRL_RELEASE) {
|
if (tm->cctl.cmd == DECT_CCTRL_RELEASE)
|
||||||
slots[slot].tbc = NULL;
|
dect_tbc_release(dh, tbc);
|
||||||
slots[dect_tdd_slot(slot)].tbc = NULL;
|
|
||||||
free(tbc);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case DECT_TM_TYPE_ENCCTRL:
|
case DECT_TM_TYPE_ENCCTRL:
|
||||||
switch (tm->encctl.cmd) {
|
switch (tm->encctl.cmd) {
|
||||||
|
@ -653,10 +698,9 @@ static void dect_tbc_rcv(struct dect_tbc *tbc, uint8_t slot,
|
||||||
printf("\n");
|
printf("\n");
|
||||||
break;
|
break;
|
||||||
case DECT_ENCCTRL_START_CONFIRM:
|
case DECT_ENCCTRL_START_CONFIRM:
|
||||||
printf("ciphering enabled: %s\n", slot < 12 ? "FP->PP" : "PP->FP");
|
|
||||||
break;
|
|
||||||
case DECT_ENCCTRL_START_GRANT:
|
case DECT_ENCCTRL_START_GRANT:
|
||||||
printf("ciphering enabled: %s\n", slot < 12 ? "FP->PP" : "PP->FP");
|
tbc_log(tbc, "ciphering enabled: %s\n",
|
||||||
|
slot < 12 ? "FP->PP" : "PP->FP");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -667,41 +711,38 @@ static void dect_tbc_rcv(struct dect_tbc *tbc, uint8_t slot,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dect_mac_rcv(struct dect_msg_buf *mb, uint8_t slot)
|
void dect_mac_rcv(struct dect_handle *dh, struct dect_msg_buf *mb)
|
||||||
{
|
{
|
||||||
struct dect_trx_slot *ts = &slots[slot];
|
struct dect_handle_priv *priv = dect_handle_priv(dh);
|
||||||
|
struct dect_tbc *tbc = priv->slots[mb->slot];
|
||||||
enum dect_tail_identifications a_id;
|
enum dect_tail_identifications a_id;
|
||||||
enum dect_b_identifications b_id;
|
enum dect_b_identifications b_id;
|
||||||
struct dect_tail_msg tm;
|
struct dect_tail_msg tm;
|
||||||
struct dect_tbc *tbc;
|
|
||||||
|
|
||||||
a_id = (mb->data[0] & DECT_HDR_TA_MASK) >> DECT_HDR_TA_SHIFT;
|
a_id = (mb->data[0] & DECT_HDR_TA_MASK) >> DECT_HDR_TA_SHIFT;
|
||||||
b_id = (mb->data[0] & DECT_HDR_BA_MASK) >> DECT_HDR_BA_SHIFT;
|
b_id = (mb->data[0] & DECT_HDR_BA_MASK) >> DECT_HDR_BA_SHIFT;
|
||||||
mac_print("slot: %02u A: %x B: %x ", slot, a_id, b_id);
|
mac_print("slot: %02u A: %x B: %x ", mb->slot, a_id, b_id);
|
||||||
|
|
||||||
dect_parse_tail_msg(&tm, slot, mb);
|
dect_parse_tail_msg(&tm, mb);
|
||||||
//dect_hexdump("MAC RCV", mb->data, mb->len);
|
//dect_hexdump("MAC RCV", mb->data, mb->len);
|
||||||
|
|
||||||
if (ts->tbc != NULL)
|
if (tbc != NULL)
|
||||||
return dect_tbc_rcv(ts->tbc, slot, mb, &tm);
|
return dect_tbc_rcv(dh, tbc, mb, &tm);
|
||||||
|
|
||||||
if (tm.type == DECT_TM_TYPE_BCCTRL ||
|
switch (tm.type) {
|
||||||
tm.type == DECT_TM_TYPE_ACCTRL) {
|
case DECT_TM_TYPE_BCCTRL:
|
||||||
|
case DECT_TM_TYPE_ACCTRL:
|
||||||
switch (tm.cctl.cmd) {
|
switch (tm.cctl.cmd) {
|
||||||
case DECT_CCTRL_ACCESS_REQ:
|
case DECT_CCTRL_ACCESS_REQ:
|
||||||
case DECT_CCTRL_BEARER_HANDOVER_REQ:
|
case DECT_CCTRL_BEARER_HANDOVER_REQ:
|
||||||
case DECT_CCTRL_CONNECTION_HANDOVER_REQ:
|
case DECT_CCTRL_CONNECTION_HANDOVER_REQ:
|
||||||
tbc = dect_tbc_init(tm.cctl.pmid);
|
dect_tbc_init(dh, &tm, mb->slot);
|
||||||
if (tbc == NULL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ts->tbc = tbc;
|
|
||||||
slots[slot - 12].tbc = tbc;
|
|
||||||
printf("TBC slot %u\n", slot);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("unknown\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
173
src/main.c
173
src/main.c
|
@ -1,3 +1,11 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010 Patrick McHardy <kaber@trash.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -7,32 +15,94 @@
|
||||||
#include <dect/raw.h>
|
#include <dect/raw.h>
|
||||||
#include <dectmon.h>
|
#include <dectmon.h>
|
||||||
|
|
||||||
struct dect_handle *dh;
|
#define DECT_MAX_CLUSTERS 16
|
||||||
|
#define DECT_LOCK_TIMEOUT 15
|
||||||
|
|
||||||
static void pexit(const char *str)
|
#define cluster_log(priv, fmt, args...) \
|
||||||
|
printf("%s: " fmt, \
|
||||||
|
((struct dect_handle_priv *)dect_handle_priv(dh))->cluster, \
|
||||||
|
## args)
|
||||||
|
|
||||||
|
static LIST_HEAD(dect_handles);
|
||||||
|
static unsigned int locked;
|
||||||
|
|
||||||
|
static struct dect_handle_priv *dect_handle_lookup(const struct dect_ari *pari)
|
||||||
{
|
{
|
||||||
perror(str);
|
struct dect_handle_priv *priv;
|
||||||
exit(1);
|
|
||||||
|
list_for_each_entry(priv, &dect_handles, list)
|
||||||
|
if (!dect_ari_cmp(pari, &priv->pari))
|
||||||
|
return priv;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dect_lock_timer(struct dect_handle *dh, struct dect_timer *timer)
|
||||||
|
{
|
||||||
|
struct dect_handle_priv *priv = dect_handle_priv(dh);
|
||||||
|
|
||||||
|
cluster_log(dh, "timeout, lock failed\n");
|
||||||
|
memset(&priv->pari, 0, sizeof(priv->pari));
|
||||||
|
dect_llme_scan_req(dh);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dect_mac_me_info_ind(struct dect_handle *dh,
|
||||||
|
const struct dect_ari *pari,
|
||||||
|
const struct dect_fp_capabilities *fpc)
|
||||||
|
{
|
||||||
|
struct dect_handle_priv *priv = dect_handle_priv(dh);
|
||||||
|
|
||||||
|
if (pari != NULL) {
|
||||||
|
if (dect_handle_lookup(pari) == NULL) {
|
||||||
|
cluster_log(dh, "MAC_ME_INFO-ind: EMC: %.4x FPN: %.5x\n",
|
||||||
|
pari->emc, pari->fpn);
|
||||||
|
|
||||||
|
dect_llme_mac_me_info_res(dh, pari);
|
||||||
|
priv->pari = *pari;
|
||||||
|
dect_timer_start(dh, priv->lock_timer, DECT_LOCK_TIMEOUT);
|
||||||
|
}
|
||||||
|
} else if (fpc->fpc != 0) {
|
||||||
|
if (dect_timer_running(priv->lock_timer)) {
|
||||||
|
locked++;
|
||||||
|
cluster_log(dh, "locked (%u): EMC: %.4x FPN: %.5x\n",
|
||||||
|
locked, priv->pari.emc, priv->pari.fpn);
|
||||||
|
|
||||||
|
dect_timer_stop(dh, priv->lock_timer);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
locked--;
|
||||||
|
cluster_log(dh, "unlocked (%u): EMC: %.4x FPN: %.5x\n",
|
||||||
|
locked, priv->pari.emc, priv->pari.fpn);
|
||||||
|
|
||||||
|
memset(&priv->pari, 0, sizeof(priv->pari));
|
||||||
|
dect_llme_scan_req(dh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct dect_llme_ops_ llme_ops = {
|
||||||
|
.mac_me_info_ind = dect_mac_me_info_ind,
|
||||||
|
};
|
||||||
|
|
||||||
static void dect_raw_rcv(struct dect_handle *dh, struct dect_fd *dfd,
|
static void dect_raw_rcv(struct dect_handle *dh, struct dect_fd *dfd,
|
||||||
struct dect_msg_buf *mb)
|
struct dect_msg_buf *mb)
|
||||||
{
|
{
|
||||||
dect_mac_rcv(mb, mb->slot);
|
dect_mac_rcv(dh, mb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dect_raw_ops raw_ops = {
|
static struct dect_raw_ops raw_ops = {
|
||||||
.raw_rcv = dect_raw_rcv,
|
.raw_rcv = dect_raw_rcv,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct dect_ops ops = {
|
static struct dect_ops ops = {
|
||||||
.raw_ops = &raw_ops,
|
.priv_size = sizeof(struct dect_handle_priv),
|
||||||
|
.llme_ops = &llme_ops,
|
||||||
|
.raw_ops = &raw_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define OPTSTRING "c:m:d:n:p:h"
|
#define OPTSTRING "c:sm:d:n:p:h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
OPT_CLUSTER = 'c',
|
OPT_CLUSTER = 'c',
|
||||||
|
OPT_SCAN = 's',
|
||||||
OPT_DUMP_MAC = 'm',
|
OPT_DUMP_MAC = 'm',
|
||||||
OPT_DUMP_DLC = 'd',
|
OPT_DUMP_DLC = 'd',
|
||||||
OPT_DUMP_NWK = 'n',
|
OPT_DUMP_NWK = 'n',
|
||||||
|
@ -42,6 +112,7 @@ enum {
|
||||||
|
|
||||||
static const struct option dectmon_opts[] = {
|
static const struct option dectmon_opts[] = {
|
||||||
{ .name = "cluster", .has_arg = true, .flag = 0, .val = OPT_CLUSTER, },
|
{ .name = "cluster", .has_arg = true, .flag = 0, .val = OPT_CLUSTER, },
|
||||||
|
{ .name = "scan", .has_arg = false, .flag = 0, .val = OPT_SCAN, },
|
||||||
{ .name = "dump-mac", .has_arg = true, .flag = 0, .val = OPT_DUMP_MAC, },
|
{ .name = "dump-mac", .has_arg = true, .flag = 0, .val = OPT_DUMP_MAC, },
|
||||||
{ .name = "dump-dlc", .has_arg = true, .flag = 0, .val = OPT_DUMP_DLC, },
|
{ .name = "dump-dlc", .has_arg = true, .flag = 0, .val = OPT_DUMP_DLC, },
|
||||||
{ .name = "dump-nwk", .has_arg = true, .flag = 0, .val = OPT_DUMP_NWK, },
|
{ .name = "dump-nwk", .has_arg = true, .flag = 0, .val = OPT_DUMP_NWK, },
|
||||||
|
@ -50,6 +121,28 @@ static const struct option dectmon_opts[] = {
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void pexit(const char *str)
|
||||||
|
{
|
||||||
|
perror(str);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dectmon_help(const char *progname)
|
||||||
|
{
|
||||||
|
printf("%s [ options ]\n"
|
||||||
|
"\n"
|
||||||
|
"Options:\n"
|
||||||
|
" -c/--cluster=NAME Bind to cluster NAME. May be specified more than once.\n"
|
||||||
|
" -s/--scan Scan for FPs and lock dynamically\n"
|
||||||
|
" -m/--dump-mac=yes/no Dump MAC layer messages (default: no)\n"
|
||||||
|
" -d/--dump-dlc=yes/no Dump DLC layer messages (default: no)\n"
|
||||||
|
" -n/--dump-nwk=yes/no Dump NWK layer messages (default: yes)\n"
|
||||||
|
" -p/--auth-pin=PIN Authentication PIN for Key Allocation\n"
|
||||||
|
" -h/--help Show this help text\n"
|
||||||
|
"\n",
|
||||||
|
progname);
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t opt_yesno(const char *arg, uint32_t opts, uint32_t flag)
|
static uint32_t opt_yesno(const char *arg, uint32_t opts, uint32_t flag)
|
||||||
{
|
{
|
||||||
if (!strcmp(arg, "yes"))
|
if (!strcmp(arg, "yes"))
|
||||||
|
@ -65,10 +158,37 @@ static uint32_t opt_yesno(const char *arg, uint32_t opts, uint32_t flag)
|
||||||
const char *auth_pin = "0000";
|
const char *auth_pin = "0000";
|
||||||
uint32_t dumpopts = DECTMON_DUMP_NWK;
|
uint32_t dumpopts = DECTMON_DUMP_NWK;
|
||||||
|
|
||||||
|
static struct dect_handle *dectmon_open_handle(struct dect_ops *ops,
|
||||||
|
const char *cluster)
|
||||||
|
{
|
||||||
|
struct dect_handle_priv *priv;
|
||||||
|
struct dect_handle *dh;
|
||||||
|
|
||||||
|
dh = dect_open_handle(ops, cluster);
|
||||||
|
if (dh == NULL)
|
||||||
|
pexit("dect_open_handle");
|
||||||
|
|
||||||
|
priv = dect_handle_priv(dh);
|
||||||
|
priv->cluster = cluster;
|
||||||
|
|
||||||
|
priv->lock_timer = dect_timer_alloc(dh);
|
||||||
|
if (priv->lock_timer == NULL)
|
||||||
|
pexit("dect_alloc_timer");
|
||||||
|
dect_timer_setup(priv->lock_timer, dect_lock_timer, priv);
|
||||||
|
|
||||||
|
init_list_head(&priv->pt_list);
|
||||||
|
list_add_tail(&priv->list, &dect_handles);
|
||||||
|
|
||||||
|
return dh;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
const char *cluster = NULL;
|
const char *cluster[DECT_MAX_CLUSTERS] = {};
|
||||||
|
unsigned int ncluster = 0, i;
|
||||||
|
struct dect_handle *dh;
|
||||||
struct dect_fd *dfd;
|
struct dect_fd *dfd;
|
||||||
|
bool scan = false;
|
||||||
int optidx = 0, c;
|
int optidx = 0, c;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -78,7 +198,10 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case OPT_CLUSTER:
|
case OPT_CLUSTER:
|
||||||
cluster = optarg;
|
cluster[ncluster++] = optarg;
|
||||||
|
break;
|
||||||
|
case OPT_SCAN:
|
||||||
|
scan = true;
|
||||||
break;
|
break;
|
||||||
case OPT_DUMP_MAC:
|
case OPT_DUMP_MAC:
|
||||||
dumpopts = opt_yesno(optarg, dumpopts, DECTMON_DUMP_MAC);
|
dumpopts = opt_yesno(optarg, dumpopts, DECTMON_DUMP_MAC);
|
||||||
|
@ -93,18 +216,10 @@ int main(int argc, char **argv)
|
||||||
auth_pin = optarg;
|
auth_pin = optarg;
|
||||||
break;
|
break;
|
||||||
case OPT_HELP:
|
case OPT_HELP:
|
||||||
printf("%s [ options ]\n"
|
dectmon_help(argv[0]);
|
||||||
"\n"
|
|
||||||
"Options:\n"
|
|
||||||
" -m/--dump-mac=yes/no\n"
|
|
||||||
" -d/--dump-dlc=yes/no\n"
|
|
||||||
" -n/--dump-nwk=yes/no\n"
|
|
||||||
" -p/--auth-pin=PIN\n"
|
|
||||||
" -h/--help\n",
|
|
||||||
argv[0]);
|
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
case '?':
|
case '?':
|
||||||
|
dectmon_help(argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,13 +227,19 @@ int main(int argc, char **argv)
|
||||||
dect_event_ops_init(&ops);
|
dect_event_ops_init(&ops);
|
||||||
dect_dummy_ops_init(&ops);
|
dect_dummy_ops_init(&ops);
|
||||||
|
|
||||||
dh = dect_open_handle(&ops, cluster);
|
if (ncluster == 0)
|
||||||
if (dh == NULL)
|
ncluster = 1;
|
||||||
pexit("dect_init_handle");
|
|
||||||
|
|
||||||
dfd = dect_raw_socket(dh);
|
for (i = 0; i < ncluster; i++) {
|
||||||
if (dfd == NULL)
|
dh = dectmon_open_handle(&ops, cluster[i]);
|
||||||
pexit("dect_raw_socket");
|
|
||||||
|
dfd = dect_raw_socket(dh);
|
||||||
|
if (dfd == NULL)
|
||||||
|
pexit("dect_raw_socket");
|
||||||
|
|
||||||
|
if (scan)
|
||||||
|
dect_llme_scan_req(dh);
|
||||||
|
}
|
||||||
|
|
||||||
dect_event_loop();
|
dect_event_loop();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
36
src/nwk.c
36
src/nwk.c
|
@ -17,8 +17,6 @@
|
||||||
#include <dectmon.h>
|
#include <dectmon.h>
|
||||||
#include <nwk.h>
|
#include <nwk.h>
|
||||||
|
|
||||||
static LIST_HEAD(dect_pt_list);
|
|
||||||
|
|
||||||
static const char * const nwk_msg_types[256] = {
|
static const char * const nwk_msg_types[256] = {
|
||||||
[DECT_LCE_PAGE_RESPONSE] = "LCE-PAGE-RESPONSE",
|
[DECT_LCE_PAGE_RESPONSE] = "LCE-PAGE-RESPONSE",
|
||||||
[DECT_LCE_PAGE_REJECT] = "LCE-PAGE-REJECT",
|
[DECT_LCE_PAGE_REJECT] = "LCE-PAGE-REJECT",
|
||||||
|
@ -134,11 +132,13 @@ err:
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dect_pt *dect_pt_lookup(struct dect_ie_portable_identity *portable_identity)
|
static struct dect_pt *dect_pt_lookup(struct dect_handle *dh,
|
||||||
|
struct dect_ie_portable_identity *portable_identity)
|
||||||
{
|
{
|
||||||
|
struct dect_handle_priv *priv = dect_handle_priv(dh);
|
||||||
struct dect_pt *pt;
|
struct dect_pt *pt;
|
||||||
|
|
||||||
list_for_each_entry(pt, &dect_pt_list, list) {
|
list_for_each_entry(pt, &priv->pt_list, list) {
|
||||||
if (!dect_ipui_cmp(&pt->portable_identity->ipui,
|
if (!dect_ipui_cmp(&pt->portable_identity->ipui,
|
||||||
&portable_identity->ipui))
|
&portable_identity->ipui))
|
||||||
return pt;
|
return pt;
|
||||||
|
@ -146,8 +146,10 @@ static struct dect_pt *dect_pt_lookup(struct dect_ie_portable_identity *portable
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dect_pt *dect_pt_init(struct dect_ie_portable_identity *portable_identity)
|
static struct dect_pt *dect_pt_init(struct dect_handle *dh,
|
||||||
|
struct dect_ie_portable_identity *portable_identity)
|
||||||
{
|
{
|
||||||
|
struct dect_handle_priv *priv = dect_handle_priv(dh);
|
||||||
struct dect_pt *pt;
|
struct dect_pt *pt;
|
||||||
|
|
||||||
pt = calloc(1, sizeof(*pt));
|
pt = calloc(1, sizeof(*pt));
|
||||||
|
@ -155,13 +157,14 @@ static struct dect_pt *dect_pt_init(struct dect_ie_portable_identity *portable_i
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
pt->portable_identity = dect_ie_hold(portable_identity);
|
pt->portable_identity = dect_ie_hold(portable_identity);
|
||||||
list_add_tail(&pt->list, &dect_pt_list);
|
list_add_tail(&pt->list, &priv->pt_list);
|
||||||
|
|
||||||
dect_pt_read_uak(pt);
|
dect_pt_read_uak(pt);
|
||||||
return pt;
|
return pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dect_pt_track_key_allocation(struct dect_pt *pt, uint8_t msgtype,
|
static void dect_pt_track_key_allocation(struct dect_handle *dh,
|
||||||
|
struct dect_pt *pt, uint8_t msgtype,
|
||||||
const struct dect_sfmt_ie *ie,
|
const struct dect_sfmt_ie *ie,
|
||||||
struct dect_ie_common *common)
|
struct dect_ie_common *common)
|
||||||
{
|
{
|
||||||
|
@ -235,7 +238,8 @@ release:
|
||||||
pt->procedure = DECT_MM_NONE;
|
pt->procedure = DECT_MM_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dect_pt_track_auth(struct dect_pt *pt, uint8_t msgtype,
|
static void dect_pt_track_auth(struct dect_handle *dh,
|
||||||
|
struct dect_pt *pt, uint8_t msgtype,
|
||||||
const struct dect_sfmt_ie *ie,
|
const struct dect_sfmt_ie *ie,
|
||||||
struct dect_ie_common *common)
|
struct dect_ie_common *common)
|
||||||
{
|
{
|
||||||
|
@ -301,7 +305,8 @@ release:
|
||||||
pt->procedure = DECT_MM_NONE;
|
pt->procedure = DECT_MM_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dect_pt_track_ciphering(struct dect_pt *pt, uint8_t msgtype,
|
static void dect_pt_track_ciphering(struct dect_handle *dh,
|
||||||
|
struct dect_pt *pt, uint8_t msgtype,
|
||||||
const struct dect_sfmt_ie *ie,
|
const struct dect_sfmt_ie *ie,
|
||||||
struct dect_ie_common *common)
|
struct dect_ie_common *common)
|
||||||
{
|
{
|
||||||
|
@ -316,7 +321,8 @@ static void dect_pt_track_ciphering(struct dect_pt *pt, uint8_t msgtype,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dect_dl_data_ind(struct dect_dl *dl, struct dect_msg_buf *mb)
|
void dect_dl_data_ind(struct dect_handle *dh, struct dect_dl *dl,
|
||||||
|
struct dect_msg_buf *mb)
|
||||||
{
|
{
|
||||||
struct dect_pt *pt;
|
struct dect_pt *pt;
|
||||||
struct dect_sfmt_ie ie;
|
struct dect_sfmt_ie ie;
|
||||||
|
@ -340,17 +346,17 @@ void dect_dl_data_ind(struct dect_dl *dl, struct dect_msg_buf *mb)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ie.id == DECT_IE_PORTABLE_IDENTITY) {
|
if (ie.id == DECT_IE_PORTABLE_IDENTITY) {
|
||||||
pt = dect_pt_lookup((void *)common);
|
pt = dect_pt_lookup(dh, (void *)common);
|
||||||
if (pt == NULL)
|
if (pt == NULL)
|
||||||
pt = dect_pt_init((void *)common);
|
pt = dect_pt_init(dh, (void *)common);
|
||||||
dl->pt = pt;
|
dl->pt = pt;
|
||||||
pt->dl = dl;
|
pt->dl = dl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dl->pt != NULL) {
|
if (dl->pt != NULL) {
|
||||||
dect_pt_track_key_allocation(dl->pt, msgtype, &ie, common);
|
dect_pt_track_key_allocation(dh, dl->pt, msgtype, &ie, common);
|
||||||
dect_pt_track_auth(dl->pt, msgtype, &ie, common);
|
dect_pt_track_auth(dh, dl->pt, msgtype, &ie, common);
|
||||||
dect_pt_track_ciphering(dl->pt, msgtype, &ie, common);
|
dect_pt_track_ciphering(dh, dl->pt, msgtype, &ie, common);
|
||||||
}
|
}
|
||||||
|
|
||||||
__dect_ie_put(dh, common);
|
__dect_ie_put(dh, common);
|
||||||
|
|
Reference in New Issue