dect
/
libdect
Archived
13
0
Fork 0
This repository has been archived on 2022-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
libdect/src/identities.c

183 lines
4.5 KiB
C

/*
* DECT Identities
*
* Copyright (c) 2009 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 <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <asm/byteorder.h>
#include <libdect.h>
#include <identities.h>
#include <utils.h>
uint8_t dect_parse_ari(struct dect_ari *ari, uint64_t a)
{
ari->arc = (a & DECT_ARI_ARC_MASK) >> DECT_ARI_ARC_SHIFT;
switch (ari->arc) {
case DECT_ARC_A:
ari->emc = (a & DECT_ARI_A_EMC_MASK) >> DECT_ARI_A_EMC_SHIFT;
ari->fpn = (a & DECT_ARI_A_FPN_MASK) >> DECT_ARI_A_FPN_SHIFT;
dect_debug("ARI class A: EMC: %.4x FPN: %.5x\n",
ari->emc, ari->fpn);
return DECT_ARC_A_LEN;
case DECT_ARC_B:
ari->eic = (a & DECT_ARI_B_EIC_MASK) >> DECT_ARI_B_EIC_SHIFT;
ari->fpn = (a & DECT_ARI_B_FPN_MASK) >> DECT_ARI_B_FPN_SHIFT;
ari->fps = (a & DECT_ARI_B_FPS_MASK) >> DECT_ARI_B_FPS_SHIFT;
return DECT_ARC_B_LEN;
case DECT_ARC_C:
ari->poc = (a & DECT_ARI_C_POC_MASK) >> DECT_ARI_C_POC_SHIFT;
ari->fpn = (a & DECT_ARI_C_FPN_MASK) >> DECT_ARI_C_FPN_SHIFT;
ari->fps = (a & DECT_ARI_C_FPS_MASK) >> DECT_ARI_C_FPS_SHIFT;
return DECT_ARC_C_LEN;
case DECT_ARC_D:
ari->gop = (a & DECT_ARI_D_GOP_MASK) >> DECT_ARI_D_GOP_SHIFT;
ari->fpn = (a & DECT_ARI_D_FPN_MASK) >> DECT_ARI_D_FPN_SHIFT;
return DECT_ARC_D_LEN;
case DECT_ARC_E:
ari->fil = (a & DECT_ARI_E_FIL_MASK) >> DECT_ARI_E_FIL_SHIFT;
ari->fpn = (a & DECT_ARI_E_FPN_MASK) >> DECT_ARI_E_FPN_SHIFT;
return DECT_ARC_E_LEN;
default:
return 0;
}
}
uint64_t dect_build_ari(const struct dect_ari *ari)
{
uint64_t a = 0;
a |= (uint64_t)ari->arc << DECT_ARI_ARC_SHIFT;
switch (ari->arc) {
case DECT_ARC_A:
a |= (uint64_t)ari->emc << DECT_ARI_A_EMC_SHIFT;
a |= (uint64_t)ari->fpn << DECT_ARI_A_FPN_SHIFT;
break;
case DECT_ARC_B:
a |= (uint64_t)ari->eic << DECT_ARI_B_EIC_SHIFT;
a |= (uint64_t)ari->fpn << DECT_ARI_B_FPN_SHIFT;
a |= (uint64_t)ari->fps << DECT_ARI_B_FPS_SHIFT;
break;
case DECT_ARC_C:
a |= (uint64_t)ari->poc << DECT_ARI_C_POC_SHIFT;
a |= (uint64_t)ari->fpn << DECT_ARI_C_FPN_SHIFT;
a |= (uint64_t)ari->fps << DECT_ARI_C_FPS_SHIFT;
break;
case DECT_ARC_D:
a |= (uint64_t)ari->gop << DECT_ARI_D_GOP_SHIFT;
a |= (uint64_t)ari->fpn << DECT_ARI_D_FPN_SHIFT;
break;
case DECT_ARC_E:
a |= (uint64_t)ari->fil << DECT_ARI_E_FIL_SHIFT;
a |= (uint64_t)ari->fpn << DECT_ARI_E_FPN_SHIFT;
break;
}
return a;
}
static bool dect_parse_ipei(struct dect_ipei *ipei, uint64_t i)
{
ipei->emc = (i & DECT_IPEI_EMC_MASK) >> DECT_IPEI_EMC_SHIFT;
ipei->psn = (i & DECT_IPEI_PSN_MASK);
dect_debug("IPEI: EMC: %.4x PSN: %.5x\n", ipei->emc, ipei->psn);
return true;
}
static uint64_t dect_build_ipei(const struct dect_ipei *ipei)
{
uint64_t i = 0;
i |= (uint64_t)ipei->emc << DECT_IPEI_EMC_SHIFT;
i |= (uint64_t)ipei->psn;
return i;
}
bool dect_parse_ipui(struct dect_ipui *ipui, const uint8_t *ptr, uint8_t len)
{
uint64_t tmp;
tmp = __be64_to_cpu(*(__be64 *)&ptr[0]) >> 24;
ipui->put = ptr[0] & DECT_IPUI_PUT_MASK;
switch (ipui->put) {
case DECT_IPUI_N:
if (len != 40)
return false;
return dect_parse_ipei(&ipui->pun.n.ipei, tmp);
case DECT_IPUI_O:
case DECT_IPUI_P:
case DECT_IPUI_Q:
case DECT_IPUI_R:
case DECT_IPUI_S:
case DECT_IPUI_T:
case DECT_IPUI_U:
default:
dect_debug("IPUI: unhandled type %u\n", ipui->put);
return false;
}
}
uint8_t dect_build_ipui(uint8_t *ptr, const struct dect_ipui *ipui)
{
uint64_t tmp;
switch (ipui->put) {
case DECT_IPUI_N:
tmp = dect_build_ipei(&ipui->pun.n.ipei);
break;
case DECT_IPUI_O:
case DECT_IPUI_P:
case DECT_IPUI_Q:
case DECT_IPUI_R:
case DECT_IPUI_S:
case DECT_IPUI_T:
case DECT_IPUI_U:
return 0;
default:
return 0;
}
ptr[0] = ipui->put;
ptr[0] |= (tmp >> 32) & ~DECT_IPUI_PUT_MASK;
ptr[1] = tmp >> 24;
ptr[2] = tmp >> 16;
ptr[3] = tmp >> 8;
ptr[4] = tmp >> 0;
return 40;
}
bool dect_ipui_cmp(const struct dect_ipui *i1, const struct dect_ipui *i2)
{
return memcmp(i1, i2, sizeof(*i1));
}
void dect_default_individual_tpui(struct dect_tpui *tpui,
const struct dect_ipui *ipui)
{
tpui->tpui = DECT_TPUI_DEFAULT_INDIVIDUAL_ID;
switch (ipui->put) {
case DECT_IPUI_N:
tpui->tpui |= ipui->pun.n.ipei.psn &
DECT_TPUI_DEFAULT_INDIVIDUAL_IPUI_MASK;
break;
case DECT_IPUI_O:
case DECT_IPUI_P:
case DECT_IPUI_Q:
case DECT_IPUI_R:
case DECT_IPUI_S:
case DECT_IPUI_T:
case DECT_IPUI_U:
return;
}
}