mirror of https://gerrit.osmocom.org/osmo-tetra
move add sds parsing to tetra_sds.c
This commit is contained in:
parent
b547d72863
commit
6733e6c6ed
385
src/tetra_sds.c
385
src/tetra_sds.c
|
@ -21,21 +21,29 @@
|
|||
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include "tetra_sds.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
|
||||
#include "tetra_common.h"
|
||||
#include "tetra_prim.h"
|
||||
#include "tetra_upper_mac.h"
|
||||
#include "tetra_mac_pdu.h"
|
||||
#include "tetra_llc_pdu.h"
|
||||
#include "tetra_mm_pdu.h"
|
||||
#include "tetra_cmce_pdu.h"
|
||||
#include "tetra_sndcp_pdu.h"
|
||||
#include "tetra_mle_pdu.h"
|
||||
#include "tetra_gsmtap.h"
|
||||
#include "tetra_sds.h"
|
||||
#include <math.h>
|
||||
|
||||
|
||||
const char oth_reserved[]="Other Reserved";
|
||||
|
||||
int decode_pdu(char *dec,unsigned char *enc,int len)
|
||||
|
@ -77,6 +85,371 @@ char *get_sds_type(uint8_t type) {
|
|||
|
||||
}
|
||||
|
||||
|
||||
/* TODO: move this into tetra_sds.c and break into multiple functions */
|
||||
unsigned int parse_d_sds_data(struct tetra_mac_state *tms, struct msgb *msg, unsigned int len)
|
||||
{
|
||||
/* strona 269, 297, 1072, 1075 */
|
||||
uint8_t *bits = msg->l3h+3;
|
||||
|
||||
int n=0;
|
||||
int l,a;
|
||||
int m=5;
|
||||
|
||||
uint8_t pdu_type;
|
||||
uint8_t cpti;
|
||||
uint32_t calling_ssi;
|
||||
uint32_t calling_ext=0;
|
||||
uint8_t sdti;
|
||||
uint8_t udata[512];
|
||||
uint16_t datalen=0;
|
||||
uint8_t protoid;
|
||||
uint8_t reserved1;
|
||||
uint8_t coding_scheme;
|
||||
char descr[4096];
|
||||
char tmpstr[128];
|
||||
char tmpstr2[1024];
|
||||
int is_sdstl=0;
|
||||
uint8_t message_type;
|
||||
struct tetra_resrc_decoded rsd;
|
||||
int tmpdu_offset;
|
||||
uint8_t sdstl_delivery_report_request;
|
||||
uint8_t sdstl_service_selection;
|
||||
uint8_t sdstl_storage_control;
|
||||
uint8_t sdstl_message_reference;
|
||||
uint8_t sdstl_validity_period;
|
||||
uint8_t sdstl_forw_address_type;
|
||||
uint32_t sdstl_forw_address;
|
||||
uint32_t sdstl_forw_address_ext;
|
||||
uint8_t sdstl_extnum_digits;
|
||||
uint8_t sdstl_extnum_digit;
|
||||
int decode_sds=1;
|
||||
|
||||
|
||||
memset(&rsd, 0, sizeof(rsd));
|
||||
tmpdu_offset = macpdu_decode_resource(&rsd, msg->l1h);
|
||||
|
||||
|
||||
|
||||
m=5; pdu_type=bits_to_uint(bits+n, m); n=n+m;
|
||||
m=2; cpti=bits_to_uint(bits+n, m); n=n+m;
|
||||
switch(cpti) {
|
||||
case 0: /* SNA */
|
||||
m=8; calling_ssi=bits_to_uint(bits+n, m); n=n+m;
|
||||
break;
|
||||
case 1: /* SSI */
|
||||
m=24; calling_ssi=bits_to_uint(bits+n, m); n=n+m;
|
||||
break;
|
||||
case 2: /* TETRA Subscriber Identity (TSI) */
|
||||
m=24; calling_ssi=bits_to_uint(bits+n, m); n=n+m;
|
||||
m=24; calling_ext=bits_to_uint(bits+n, m); n=n+m;
|
||||
break;
|
||||
default:
|
||||
/* hgw co to jest */
|
||||
printf("\nparse_d_sds_data: BAD CPTI %i\n",cpti);
|
||||
return(1);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
sprintf(descr,"CPTI:%i CalledSSI:%i CallingSSI:%i CallingEXT:%i ",cpti,rsd.addr.ssi,calling_ssi,calling_ext);
|
||||
|
||||
m=2; sdti=bits_to_uint(bits+n, m); n=n+m;
|
||||
|
||||
switch(sdti) {
|
||||
case 0: /* user defined data-1 16 bit */
|
||||
datalen=2;
|
||||
m=8;
|
||||
for(l=0;l<datalen;l++) {
|
||||
udata[l]=bits_to_uint(bits+n, m); n=n+m;
|
||||
}
|
||||
sprintf(tmpstr," UserData1: 0x%2.2X 0x%2.2X",udata[0],udata[1]);
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
break;
|
||||
case 1: /* user defined data-2 32 bit */
|
||||
datalen=4;
|
||||
m=8;
|
||||
for(l=0;l<datalen;l++) {
|
||||
udata[l]=bits_to_uint(bits+n, m); n=n+m;
|
||||
}
|
||||
sprintf(tmpstr,"UserData2: 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X",udata[0],udata[1],udata[2],udata[3]);
|
||||
strcat(descr,tmpstr);
|
||||
break;
|
||||
case 2: /* user defined data-3 64 bit */
|
||||
datalen=8;
|
||||
m=8;
|
||||
for(l=0;l<datalen;l++) {
|
||||
udata[l]=bits_to_uint(bits+n, m); n=n+m;
|
||||
|
||||
}
|
||||
sprintf(tmpstr," UserData3: 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X",udata[0],udata[1],udata[2],udata[3],udata[4],udata[5],udata[6],udata[7]);
|
||||
strcat(descr,tmpstr);
|
||||
break;
|
||||
case 3: /* length indicator + user defined data-4 bit */
|
||||
m=11; datalen=bits_to_uint(bits+n, m); n=n+m;
|
||||
m=8; protoid=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
sprintf(tmpstr," UserData4: len:%i protoid:%2.2X(%s) ",datalen,protoid,get_sds_type(protoid));
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
/* SDS-TL header */
|
||||
if (protoid&0x80) {
|
||||
is_sdstl=1;
|
||||
m=4; message_type=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
strcat(descr,"SDS-TL:[ MsgType:");
|
||||
|
||||
switch(message_type) {
|
||||
case 0: /* SDS-TRANSFER page 1182 */
|
||||
strcat(descr,"SDS-TRANSFER");
|
||||
m=2; sdstl_delivery_report_request=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m; /* page 1186 */
|
||||
m=1; sdstl_service_selection=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m; /* page 1189 1:to group*/
|
||||
m=1; sdstl_storage_control=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m; /* page 1189 */
|
||||
m=8; sdstl_message_reference=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
|
||||
sprintf(tmpstr," MSG_REF:%i TO_GROUP:%i",sdstl_message_reference,sdstl_service_selection);
|
||||
strcat(descr,tmpstr);
|
||||
if (sdstl_storage_control) {
|
||||
/* Storage/forward control information is available */
|
||||
m=5; sdstl_validity_period=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
m=3; sdstl_forw_address_type=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
|
||||
sprintf(tmpstr," Validity_period:%i",sdstl_validity_period);
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
switch(sdstl_forw_address_type) {
|
||||
case 0: /* SNA */
|
||||
m=8; sdstl_forw_address=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
sprintf(tmpstr," Forward_addr_SNA:%i",sdstl_forw_address);
|
||||
strcat(descr,tmpstr);
|
||||
break;
|
||||
case 1: /* SSI */
|
||||
m=24; sdstl_forw_address=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
sprintf(tmpstr," Forward_addr_SSI:%i",sdstl_forw_address);
|
||||
strcat(descr,tmpstr);
|
||||
break;
|
||||
case 2: /* TETRA Subscriber Identity (TSI) */
|
||||
m=24; sdstl_forw_address=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
m=24; sdstl_forw_address_ext=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
sprintf(tmpstr," Forward_addr_SSI:%i:EXT:%i",sdstl_forw_address,sdstl_forw_address_ext);
|
||||
strcat(descr,tmpstr);
|
||||
break;
|
||||
case 3: /* External subscriber number */
|
||||
m=8; sdstl_extnum_digits=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
strcat(descr," Forward_addr_EXT:");
|
||||
l=sdstl_extnum_digits;
|
||||
while(l) {
|
||||
m=4; sdstl_extnum_digit=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
sprintf(tmpstr,"%c",'0'+sdstl_extnum_digit);
|
||||
strcat(descr,tmpstr);
|
||||
l--;
|
||||
}
|
||||
if (sdstl_extnum_digits&0x1) {
|
||||
/* odd number, eat dummy digit */
|
||||
n=n+4;
|
||||
}
|
||||
break;
|
||||
case 7: /* no forward address */
|
||||
strcat(descr," Forward_addr_none");
|
||||
break;
|
||||
default:
|
||||
/* hgw co to jest */
|
||||
sprintf(tmpstr," Forward_addr_BAD:%i",sdstl_forw_address_type);
|
||||
strcat(descr,tmpstr);
|
||||
return(1);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
case 1: /* SDS-REPORT */
|
||||
strcat(descr,"SDS-REPORT");
|
||||
n=n+12;
|
||||
decode_sds=0;
|
||||
break;
|
||||
|
||||
case 2: /* SDS-ACK */
|
||||
strcat(descr,"SDS-ACK ");
|
||||
decode_sds=0;
|
||||
|
||||
n=n+12;
|
||||
break;
|
||||
default:
|
||||
decode_sds=0;
|
||||
if (message_type&0x8) {
|
||||
sprintf(tmpstr,"Defined_by_application_%i ",message_type);
|
||||
} else {
|
||||
sprintf(tmpstr,"Reserved_for_add_msg_types_%i ",message_type);
|
||||
}
|
||||
strcat(descr,tmpstr);
|
||||
n=n+12;
|
||||
break;
|
||||
}
|
||||
|
||||
strcat(descr,"] ");
|
||||
}
|
||||
|
||||
if (datalen>2047) {
|
||||
strcat(descr,"ERROR: SDS too short");
|
||||
decode_sds=0;
|
||||
}
|
||||
|
||||
uint8_t c;
|
||||
if (decode_sds) {
|
||||
switch (protoid) {
|
||||
case TETRA_SDS_PROTO_SIMPLE_LOC:
|
||||
sprintf(tmpstr,"SIMPLE_LOCATION_SYSTEM:[");
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
decode_simplelocsystem(tmpstr2, sizeof(tmpstr2),bits+n,datalen);
|
||||
strcat(descr,tmpstr2);
|
||||
sprintf(tmpstr,"]\n");
|
||||
strcat(descr,tmpstr);
|
||||
break;
|
||||
|
||||
case TETRA_SDS_PROTO_LOCSYSTEM:
|
||||
sprintf(tmpstr,"LOCATION_SYSTEM:[");
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
decode_locsystem(tmpstr2, sizeof(tmpstr2),bits+n,datalen);
|
||||
strcat(descr,tmpstr2);
|
||||
sprintf(tmpstr,"]\n");
|
||||
strcat(descr,tmpstr);
|
||||
break;
|
||||
|
||||
case TETRA_SDS_PROTO_LIP:
|
||||
sprintf(tmpstr,"LIP:[");
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
decode_lip(tmpstr2, sizeof(tmpstr2),bits+n,datalen);
|
||||
strcat(descr,tmpstr2);
|
||||
sprintf(tmpstr,"]");
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case TETRA_SDS_PROTO_TXTMSG:
|
||||
case TETRA_SDS_PROTO_SIMPLE_TXTMSG:
|
||||
case TETRA_SDS_PROTO_SIMPLE_ITXTMSG:
|
||||
case TETRA_SDS_PROTO_ITXTMSG:
|
||||
m=1; reserved1=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
m=7; coding_scheme=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
sprintf(tmpstr," coding_scheme:%2.2x ",coding_scheme);
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
sprintf(tmpstr,"DATA:[");
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
/* dump text message */
|
||||
switch(coding_scheme) {
|
||||
case 0: /* 7-bit gsm encoding */
|
||||
sprintf(tmpstr," *7bit* ");
|
||||
strcat(descr,tmpstr);
|
||||
m=8;
|
||||
l=0;
|
||||
while((datalen>=m)&&(n<=len)) {
|
||||
udata[l]=bits_to_uint(bits+n, m); n=n+m;
|
||||
l++;
|
||||
datalen=datalen-m;
|
||||
}
|
||||
/* TODO: maybe skip the first two bytes? i've never seen a 7-bit SDS in the wild --sq5bpf */
|
||||
datalen=decode_pdu(tmpstr2,udata,l);
|
||||
/* dump */
|
||||
for(a=0;a<datalen;a++) {
|
||||
if (isprint(tmpstr2[a])) {
|
||||
sprintf(tmpstr,"%c",tmpstr2[a]);
|
||||
}
|
||||
else {
|
||||
sprintf(tmpstr,"\\x%2.2X",tmpstr2[a]);
|
||||
}
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
|
||||
}
|
||||
strcat(descr,"]");
|
||||
|
||||
|
||||
break;
|
||||
case 0x1A: /* SO/IEC 10646-1 [22] UCS-2/UTF-16BE (16-bit) alphabet */
|
||||
/* TODO: use iconv or whatever else
|
||||
* for now we'll just use the 8-bit decoding function,
|
||||
* every other bit will be written as \x00. ugly but readable --sq5bpf
|
||||
*/
|
||||
|
||||
sprintf(tmpstr," *UTF16* ");
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
default: /* 8-bit */
|
||||
m=8;
|
||||
l=0;
|
||||
while((datalen>=m)&&(n<=len)) {
|
||||
udata[l]=bits_to_uint(bits+n, m); n=n+m;
|
||||
l++;
|
||||
datalen=datalen-m;
|
||||
}
|
||||
/* TODO: the first two bytes are often garbage. either parse it or skip it
|
||||
* i guess i'll have to read the etsi specifications better --sq5bpf */
|
||||
|
||||
for(a=0;a<l;a++) {
|
||||
if (isprint(udata[a])) {
|
||||
sprintf(tmpstr,"%c",udata[a]);
|
||||
}
|
||||
else {
|
||||
sprintf(tmpstr,"\\x%2.2X",udata[a]);
|
||||
}
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
|
||||
}
|
||||
strcat(descr,"]");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
sprintf(tmpstr,"DATA:[");
|
||||
strcat(descr,tmpstr);
|
||||
/* other message */
|
||||
/* hexdump */
|
||||
m=8;
|
||||
l=0;
|
||||
while((datalen>=m)&&(n<=len)) {
|
||||
udata[l]=bits_to_uint(bits+n, m); n=n+m;
|
||||
l++;
|
||||
datalen=datalen-m;
|
||||
|
||||
}
|
||||
/* dump */
|
||||
for(a=0;a<l;a++) {
|
||||
sprintf(tmpstr,"0x%2.2X ",udata[a]);
|
||||
strcat(descr,tmpstr);
|
||||
}
|
||||
strcat(descr,"]");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
printf("%s\n",descr);
|
||||
sprintf(tmpstr2,"TETMON_begin FUNC:SDSDEC [%s] RX:%i TETMON_end",descr,tetra_hack_rxid);
|
||||
sendto(tetra_hack_live_socket, (char *)&tmpstr2, strlen((char *)&tmpstr2)+1, 0, (struct sockaddr *)&tetra_hack_live_sockaddr, tetra_hack_socklen);
|
||||
/* We'll just ignore these for now :)
|
||||
* External subscriber number
|
||||
* DM-MS address
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
char *get_lip_dirtravel_type(uint8_t type) {
|
||||
struct lip_dirtravel_type* a= (struct lip_dirtravel_type *)&lip_dirtravel_types;
|
||||
while (a->description)
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
//#include <osmocom/core/utils.h>
|
||||
//#include <osmocom/core/msgb.h>
|
||||
//#include <osmocom/core/talloc.h>
|
||||
|
||||
|
||||
#ifndef HAVE_TETRA_SDS_H
|
||||
#define HAVE_TETRA_SDS_H
|
||||
|
@ -198,6 +202,10 @@ enum tetra_lip_velocitytypes {
|
|||
TETRA_LIP_VELOCITY_HORIZ_VELOCITY_VERT_DIRTRAVEL_UNC = 7
|
||||
|
||||
};
|
||||
|
||||
unsigned int parse_d_sds_data(struct tetra_mac_state *tms, struct msgb *msg, unsigned int len);
|
||||
|
||||
|
||||
int decode_lip(char *out, int outlen,uint8_t *bits,int datalen);
|
||||
|
||||
/************** Location System **************/
|
||||
|
|
|
@ -200,369 +200,6 @@ uint parse_d_setup(struct tetra_mac_state *tms, struct msgb *msg, unsigned int l
|
|||
|
||||
}
|
||||
|
||||
/* TODO: move this into tetra_sds.c and break into multiple functions */
|
||||
uint parse_d_sds_data(struct tetra_mac_state *tms, struct msgb *msg, unsigned int len)
|
||||
{
|
||||
/* strona 269, 297, 1072, 1075 */
|
||||
uint8_t *bits = msg->l3h+3;
|
||||
|
||||
int n=0;
|
||||
int l,a;
|
||||
int m=5;
|
||||
|
||||
uint8_t pdu_type;
|
||||
uint8_t cpti;
|
||||
uint32_t calling_ssi;
|
||||
uint32_t calling_ext=0;
|
||||
uint8_t sdti;
|
||||
uint8_t udata[512];
|
||||
uint16_t datalen=0;
|
||||
uint8_t protoid;
|
||||
uint8_t reserved1;
|
||||
uint8_t coding_scheme;
|
||||
char descr[4096];
|
||||
char tmpstr[128];
|
||||
char tmpstr2[1024];
|
||||
int is_sdstl=0;
|
||||
uint8_t message_type;
|
||||
struct tetra_resrc_decoded rsd;
|
||||
int tmpdu_offset;
|
||||
uint8_t sdstl_delivery_report_request;
|
||||
uint8_t sdstl_service_selection;
|
||||
uint8_t sdstl_storage_control;
|
||||
uint8_t sdstl_message_reference;
|
||||
uint8_t sdstl_validity_period;
|
||||
uint8_t sdstl_forw_address_type;
|
||||
uint32_t sdstl_forw_address;
|
||||
uint32_t sdstl_forw_address_ext;
|
||||
uint8_t sdstl_extnum_digits;
|
||||
uint8_t sdstl_extnum_digit;
|
||||
int decode_sds=1;
|
||||
|
||||
|
||||
memset(&rsd, 0, sizeof(rsd));
|
||||
tmpdu_offset = macpdu_decode_resource(&rsd, msg->l1h);
|
||||
|
||||
|
||||
|
||||
m=5; pdu_type=bits_to_uint(bits+n, m); n=n+m;
|
||||
m=2; cpti=bits_to_uint(bits+n, m); n=n+m;
|
||||
switch(cpti) {
|
||||
case 0: /* SNA */
|
||||
m=8; calling_ssi=bits_to_uint(bits+n, m); n=n+m;
|
||||
break;
|
||||
case 1: /* SSI */
|
||||
m=24; calling_ssi=bits_to_uint(bits+n, m); n=n+m;
|
||||
break;
|
||||
case 2: /* TETRA Subscriber Identity (TSI) */
|
||||
m=24; calling_ssi=bits_to_uint(bits+n, m); n=n+m;
|
||||
m=24; calling_ext=bits_to_uint(bits+n, m); n=n+m;
|
||||
break;
|
||||
default:
|
||||
/* hgw co to jest */
|
||||
printf("\nparse_d_sds_data: BAD CPTI %i\n",cpti);
|
||||
return(1);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
sprintf(descr,"CPTI:%i CalledSSI:%i CallingSSI:%i CallingEXT:%i ",cpti,rsd.addr.ssi,calling_ssi,calling_ext);
|
||||
|
||||
m=2; sdti=bits_to_uint(bits+n, m); n=n+m;
|
||||
|
||||
switch(sdti) {
|
||||
case 0: /* user defined data-1 16 bit */
|
||||
datalen=2;
|
||||
m=8;
|
||||
for(l=0;l<datalen;l++) {
|
||||
udata[l]=bits_to_uint(bits+n, m); n=n+m;
|
||||
}
|
||||
sprintf(tmpstr," UserData1: 0x%2.2X 0x%2.2X",udata[0],udata[1]);
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
break;
|
||||
case 1: /* user defined data-2 32 bit */
|
||||
datalen=4;
|
||||
m=8;
|
||||
for(l=0;l<datalen;l++) {
|
||||
udata[l]=bits_to_uint(bits+n, m); n=n+m;
|
||||
}
|
||||
sprintf(tmpstr,"UserData2: 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X",udata[0],udata[1],udata[2],udata[3]);
|
||||
strcat(descr,tmpstr);
|
||||
break;
|
||||
case 2: /* user defined data-3 64 bit */
|
||||
datalen=8;
|
||||
m=8;
|
||||
for(l=0;l<datalen;l++) {
|
||||
udata[l]=bits_to_uint(bits+n, m); n=n+m;
|
||||
|
||||
}
|
||||
sprintf(tmpstr," UserData3: 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X",udata[0],udata[1],udata[2],udata[3],udata[4],udata[5],udata[6],udata[7]);
|
||||
strcat(descr,tmpstr);
|
||||
break;
|
||||
case 3: /* length indicator + user defined data-4 bit */
|
||||
m=11; datalen=bits_to_uint(bits+n, m); n=n+m;
|
||||
m=8; protoid=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
sprintf(tmpstr," UserData4: len:%i protoid:%2.2X(%s) ",datalen,protoid,get_sds_type(protoid));
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
/* SDS-TL header */
|
||||
if (protoid&0x80) {
|
||||
is_sdstl=1;
|
||||
m=4; message_type=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
strcat(descr,"SDS-TL:[ MsgType:");
|
||||
|
||||
switch(message_type) {
|
||||
case 0: /* SDS-TRANSFER page 1182 */
|
||||
strcat(descr,"SDS-TRANSFER");
|
||||
m=2; sdstl_delivery_report_request=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m; /* page 1186 */
|
||||
m=1; sdstl_service_selection=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m; /* page 1189 1:to group*/
|
||||
m=1; sdstl_storage_control=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m; /* page 1189 */
|
||||
m=8; sdstl_message_reference=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
|
||||
sprintf(tmpstr," MSG_REF:%i TO_GROUP:%i",sdstl_message_reference,sdstl_service_selection);
|
||||
strcat(descr,tmpstr);
|
||||
if (sdstl_storage_control) {
|
||||
/* Storage/forward control information is available */
|
||||
m=5; sdstl_validity_period=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
m=3; sdstl_forw_address_type=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
|
||||
sprintf(tmpstr," Validity_period:%i",sdstl_validity_period);
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
switch(sdstl_forw_address_type) {
|
||||
case 0: /* SNA */
|
||||
m=8; sdstl_forw_address=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
sprintf(tmpstr," Forward_addr_SNA:%i",sdstl_forw_address);
|
||||
strcat(descr,tmpstr);
|
||||
break;
|
||||
case 1: /* SSI */
|
||||
m=24; sdstl_forw_address=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
sprintf(tmpstr," Forward_addr_SSI:%i",sdstl_forw_address);
|
||||
strcat(descr,tmpstr);
|
||||
break;
|
||||
case 2: /* TETRA Subscriber Identity (TSI) */
|
||||
m=24; sdstl_forw_address=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
m=24; sdstl_forw_address_ext=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
sprintf(tmpstr," Forward_addr_SSI:%i:EXT:%i",sdstl_forw_address,sdstl_forw_address_ext);
|
||||
strcat(descr,tmpstr);
|
||||
break;
|
||||
case 3: /* External subscriber number */
|
||||
m=8; sdstl_extnum_digits=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
strcat(descr," Forward_addr_EXT:");
|
||||
l=sdstl_extnum_digits;
|
||||
while(l) {
|
||||
m=4; sdstl_extnum_digit=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
sprintf(tmpstr,"%c",'0'+sdstl_extnum_digit);
|
||||
strcat(descr,tmpstr);
|
||||
l--;
|
||||
}
|
||||
if (sdstl_extnum_digits&0x1) {
|
||||
/* odd number, eat dummy digit */
|
||||
n=n+4;
|
||||
}
|
||||
break;
|
||||
case 7: /* no forward address */
|
||||
strcat(descr," Forward_addr_none");
|
||||
break;
|
||||
default:
|
||||
/* hgw co to jest */
|
||||
sprintf(tmpstr," Forward_addr_BAD:%i",sdstl_forw_address_type);
|
||||
strcat(descr,tmpstr);
|
||||
return(1);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
case 1: /* SDS-REPORT */
|
||||
strcat(descr,"SDS-REPORT");
|
||||
n=n+12;
|
||||
decode_sds=0;
|
||||
break;
|
||||
|
||||
case 2: /* SDS-ACK */
|
||||
strcat(descr,"SDS-ACK ");
|
||||
decode_sds=0;
|
||||
|
||||
n=n+12;
|
||||
break;
|
||||
default:
|
||||
decode_sds=0;
|
||||
if (message_type&0x8) {
|
||||
sprintf(tmpstr,"Defined_by_application_%i ",message_type);
|
||||
} else {
|
||||
sprintf(tmpstr,"Reserved_for_add_msg_types_%i ",message_type);
|
||||
}
|
||||
strcat(descr,tmpstr);
|
||||
n=n+12;
|
||||
break;
|
||||
}
|
||||
|
||||
strcat(descr,"] ");
|
||||
}
|
||||
|
||||
if (datalen>2047) {
|
||||
strcat(descr,"ERROR: SDS too short");
|
||||
decode_sds=0;
|
||||
}
|
||||
|
||||
uint8_t c;
|
||||
if (decode_sds) {
|
||||
switch (protoid) {
|
||||
case TETRA_SDS_PROTO_SIMPLE_LOC:
|
||||
sprintf(tmpstr,"SIMPLE_LOCATION_SYSTEM:[");
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
decode_simplelocsystem(tmpstr2, sizeof(tmpstr2),bits+n,datalen);
|
||||
strcat(descr,tmpstr2);
|
||||
sprintf(tmpstr,"]\n");
|
||||
strcat(descr,tmpstr);
|
||||
break;
|
||||
|
||||
case TETRA_SDS_PROTO_LOCSYSTEM:
|
||||
sprintf(tmpstr,"LOCATION_SYSTEM:[");
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
decode_locsystem(tmpstr2, sizeof(tmpstr2),bits+n,datalen);
|
||||
strcat(descr,tmpstr2);
|
||||
sprintf(tmpstr,"]\n");
|
||||
strcat(descr,tmpstr);
|
||||
break;
|
||||
|
||||
case TETRA_SDS_PROTO_LIP:
|
||||
sprintf(tmpstr,"LIP:[");
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
decode_lip(tmpstr2, sizeof(tmpstr2),bits+n,datalen);
|
||||
strcat(descr,tmpstr2);
|
||||
sprintf(tmpstr,"]");
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case TETRA_SDS_PROTO_TXTMSG:
|
||||
case TETRA_SDS_PROTO_SIMPLE_TXTMSG:
|
||||
case TETRA_SDS_PROTO_SIMPLE_ITXTMSG:
|
||||
case TETRA_SDS_PROTO_ITXTMSG:
|
||||
m=1; reserved1=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
m=7; coding_scheme=bits_to_uint(bits+n, m); n=n+m; datalen=datalen-m;
|
||||
sprintf(tmpstr," coding_scheme:%2.2x ",coding_scheme);
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
sprintf(tmpstr,"DATA:[");
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
/* dump text message */
|
||||
switch(coding_scheme) {
|
||||
case 0: /* 7-bit gsm encoding */
|
||||
sprintf(tmpstr," *7bit* ");
|
||||
strcat(descr,tmpstr);
|
||||
m=8;
|
||||
l=0;
|
||||
while((datalen>=m)&&(n<=len)) {
|
||||
udata[l]=bits_to_uint(bits+n, m); n=n+m;
|
||||
l++;
|
||||
datalen=datalen-m;
|
||||
}
|
||||
/* TODO: maybe skip the first two bytes? i've never seen a 7-bit SDS in the wild --sq5bpf */
|
||||
datalen=decode_pdu(tmpstr2,udata,l);
|
||||
/* dump */
|
||||
for(a=0;a<datalen;a++) {
|
||||
if (isprint(tmpstr2[a])) {
|
||||
sprintf(tmpstr,"%c",tmpstr2[a]);
|
||||
}
|
||||
else {
|
||||
sprintf(tmpstr,"\\x%2.2X",tmpstr2[a]);
|
||||
}
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
|
||||
}
|
||||
strcat(descr,"]");
|
||||
|
||||
|
||||
break;
|
||||
case 0x1A: /* SO/IEC 10646-1 [22] UCS-2/UTF-16BE (16-bit) alphabet */
|
||||
/* TODO: use iconv or whatever else
|
||||
* for now we'll just use the 8-bit decoding function,
|
||||
* every other bit will be written as \x00. ugly but readable --sq5bpf
|
||||
*/
|
||||
|
||||
sprintf(tmpstr," *UTF16* ");
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
default: /* 8-bit */
|
||||
m=8;
|
||||
l=0;
|
||||
while((datalen>=m)&&(n<=len)) {
|
||||
udata[l]=bits_to_uint(bits+n, m); n=n+m;
|
||||
l++;
|
||||
datalen=datalen-m;
|
||||
}
|
||||
/* TODO: the first two bytes are often garbage. either parse it or skip it
|
||||
* i guess i'll have to read the etsi specifications better --sq5bpf */
|
||||
|
||||
for(a=0;a<l;a++) {
|
||||
if (isprint(udata[a])) {
|
||||
sprintf(tmpstr,"%c",udata[a]);
|
||||
}
|
||||
else {
|
||||
sprintf(tmpstr,"\\x%2.2X",udata[a]);
|
||||
}
|
||||
strcat(descr,tmpstr);
|
||||
|
||||
|
||||
}
|
||||
strcat(descr,"]");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
sprintf(tmpstr,"DATA:[");
|
||||
strcat(descr,tmpstr);
|
||||
/* other message */
|
||||
/* hexdump */
|
||||
m=8;
|
||||
l=0;
|
||||
while((datalen>=m)&&(n<=len)) {
|
||||
udata[l]=bits_to_uint(bits+n, m); n=n+m;
|
||||
l++;
|
||||
datalen=datalen-m;
|
||||
|
||||
}
|
||||
/* dump */
|
||||
for(a=0;a<l;a++) {
|
||||
sprintf(tmpstr,"0x%2.2X ",udata[a]);
|
||||
strcat(descr,tmpstr);
|
||||
}
|
||||
strcat(descr,"]");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
printf("%s\n",descr);
|
||||
sprintf(tmpstr2,"TETMON_begin FUNC:SDSDEC [%s] RX:%i TETMON_end",descr,tetra_hack_rxid);
|
||||
sendto(tetra_hack_live_socket, (char *)&tmpstr2, strlen((char *)&tmpstr2)+1, 0, (struct sockaddr *)&tetra_hack_live_sockaddr, tetra_hack_socklen);
|
||||
/* We'll just ignore these for now :)
|
||||
* External subscriber number
|
||||
* DM-MS address
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
/* decode 18.5.17 Neighbour cell information for CA */
|
||||
/* str 535, przyklad str 1294 */
|
||||
int parse_nci_ca( uint8_t *bits)
|
||||
|
|
Loading…
Reference in New Issue