/* Copyright (C) 2014 CSP Innovazione nelle ICT s.c.a r.l. (http://www.csp.it/) All rights reserved. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . etisnoop.c Parse ETI NI G.703 file Authors: Sergio Sagliocco */ #include #include #include #include #include #include #include #include "lib_crc.h" #define ETINIPACKETSIZE 6144 void printbuf(char* h,int level, unsigned char* b, unsigned short int l, char* d); void decodeFIG(unsigned char* figdata, unsigned char figlen,unsigned short int figtype, unsigned short int indent); int main (int c, char *v[]) { int i,j,etifd,ret,offset; unsigned char p[ETINIPACKETSIZE],ficdata[32*4],streamdata[684*8]; char desc[256]; char prevsync[3]={0x00,0x00,0x00}; unsigned char ficf,nst,fp,mid,ficl; unsigned short int fl,mnsc,crch; unsigned short int crc; unsigned int sstc; unsigned char scid,tpl,l1; unsigned short int sad[64],stl[64]; etifd=open(v[1],O_RDONLY); if (etifd == -1) { printf("Cannot open %s\n",v[1]); return -1; } while (1) { ret=read(etifd,p,ETINIPACKETSIZE); if (ret!=ETINIPACKETSIZE) { printf("End of ETI\n"); break; } // SYNC printbuf("SYNC",0,p,4,""); // SYNC - ERR if (p[0]==0xFF) strcpy(desc,"No error"); else strcpy(desc,"Error"); printbuf("ERR",1,p,1,desc); // SYNC - FSYNC if (memcmp(prevsync,"\x00\x00\x00",3)==0) { if ((memcmp(p+1,"\x07\x3a\xb6",3)==0)||(memcmp(p+1,"\xf8\xc5\x49",3)==0)) { strcpy(desc,"OK"); memcpy(prevsync,p+1,3); } else { strcpy(desc,"Wrong FSYNC"); memcpy(prevsync,"\x00\x00\x00",3); } } else if (memcmp(prevsync,"\x07\x3a\xb6",3)==0) { if (memcmp(p+1,"\xf8\xc5\x49",3)!=0) { strcpy(desc,"Wrong FSYNC"); memcpy(prevsync,"\x00\x00\x00",3); } else { strcpy(desc,"OK"); memcpy(prevsync,p+1,3); } } else if (memcmp(prevsync,"\xf8\xc5\x49",3)==0) { if (memcmp(p+1,"\x07\x3a\xb6",3)!=0) { strcpy(desc,"Wrong FSYNC"); memcpy(prevsync,"\x00\x00\x00",3); } else { strcpy(desc,"OK"); memcpy(prevsync,p+1,3); } } printbuf("Sync FSYNC",1,p+1,3,desc); // LIDATA printbuf("LDATA",0,NULL,0,""); // LIDATA - FC printbuf("FC - Frame Characterization field",1,p+4,4,""); // LIDATA - FC - FCT sprintf(desc,"%d",p[4]); printbuf("FCT - Frame Count",2,p+4,1,desc); // LIDATA - FC - FICF ficf=(p[5] & 0x80) >> 7; if (ficf == 1) { sprintf(desc,"%d - FIC Information are present",ficf); } else { sprintf(desc,"%d - FIC Information are not present",ficf); } printbuf("FICF - Fast Information Channel Flag",2,NULL,0,desc); // LIDATA - FC - NST nst=p[5] & 0x7F; sprintf(desc,"%d",nst); printbuf("NST - Number of streams",2,NULL,0,desc); // LIDATA - FC - FP fp=(p[6] & 0xE0) >> 5; sprintf(desc,"%d",fp); printbuf("FP - Frame Phase",2,&fp,1,desc); // LIDATA - FC - MID mid=(p[6] & 0x18) >> 3; if (mid != 0) sprintf(desc,"Mode %d",mid); else sprintf(desc,"Mode 4"); printbuf("MID - Mode Identity",2,&mid,1,desc); // LIDATA - FC - FL fl = (p[6] & 0x07) * 256 + p[7]; sprintf(desc,"%d words",fl); printbuf("FL - Frame Length",2,NULL,0,desc); if (ficf==0) ficl=0; else if (mid==3) ficl=32; else ficl=24; // STC printbuf("STC - Stream Characterisation",1,NULL,0,""); for (i=0;i> 2; sprintf(desc,"%d",scid); printbuf("SCID - Sub-channel Identifier",3,NULL,0,desc); sad[i] = (p[8+4*i] & 0x03) * 256 + p[9+4*i]; sprintf(desc,"%d",sad[i]); printbuf("SAD - Sub-channel Start Address",3,NULL,0,desc); tpl = (p[10+4*i] & 0xFC) >> 2; if ((tpl & 0x20) >> 5 == 1) { unsigned char opt, plevel; char plevelstr[32]; opt = (tpl & 0x16) >> 2; plevel = (tpl & 0x03); if (opt == 0x00) { if (plevel == 0) strcpy(plevelstr,"1-A, 1/4, 16 CUs"); else if (plevel == 1) strcpy(plevelstr,"2-A, 3/8, 8 CUs"); else if (plevel == 2) strcpy(plevelstr,"3-A, 1/2, 6 CUs"); else if (plevel == 3) strcpy(plevelstr,"4-A, 3/4, 4 CUs"); } else if (opt == 0x01) { if (plevel == 0) strcpy(plevelstr,"1-B, 4/9, 27 CUs"); else if (plevel == 1) strcpy(plevelstr,"2-B, 4/7, 21 CUs"); else if (plevel == 2) strcpy(plevelstr,"3-B, 4/6, 18 CUs"); else if (plevel == 3) strcpy(plevelstr,"4-B, 4/5, 15 CUs"); } else sprintf(plevelstr,"Unknown option %d",opt); sprintf(desc,"0x%02x - Equal Error Protection. %s",tpl,plevelstr); } else { unsigned char tsw,uepidx; tsw = (tpl & 0x08); uepidx = tpl & 0x07; sprintf(desc,"0x%02x - Unequal Error Protection. Table switch %d, UEP index %d",tpl,tsw,uepidx); } printbuf("TPL - Sub-channel Type and Protection Level",3,NULL,0,desc); stl[i] = (p[10+4*i] & 0x03) * 256 + p[11+4*i]; sprintf(desc,"%d => %d kbit/s",stl[i],stl[i]*8/3); printbuf("STL - Sub-channel Stream Length",3,NULL,0,desc); } // EOH printbuf("EOH - End Of Header",1,p+8+4*nst,4,""); mnsc = p[8+4*nst]*256+p[8+4*nst+1]; printbuf("MNSC - Multiplex Network Signalling Channel",2,p+8+4*nst,2,""); crch = p[8+4*nst+2]*256+p[8+4*nst+3]; crc=0xffff; for (i=4;i<8+4*nst+2;i++) crc=update_crc_ccitt(crc,p[i]); crc=~crc; if (crc == crch) sprintf(desc,"CRC OK"); else sprintf(desc,"CRC Mismatch: %02x",crc); printbuf("Header CRC",2,p+8+4*nst+2,2,desc); // MST - FIC if (ficf==1) { int endmarker=0,figcount=0; unsigned char *fib, *fig; unsigned short int figcrc; memcpy(ficdata,p+12+4*nst,ficl*4); sprintf(desc,"FIC Data (%d bytes)",ficl*4); //printbuf(desc,1,ficdata,ficl*4,""); printbuf(desc,1,NULL,0,""); fib=p+12+4*nst; for(i=0;i> 5; if (figtype != 7) { figlen = fig[0] & 0x1F; sprintf(desc,"FIG %d [%d bytes]",figtype,figlen); printbuf(desc,3,fig+1,figlen,""); decodeFIG(fig+1,figlen,figtype,4); fig+=(figlen+1); figcount+=(figlen+1); if (figcount >= 29) endmarker=1; } else endmarker=1; } figcrc=fib[30]*256+fib[31]; crc=0xffff; for (j=0;j<30;j++) crc=update_crc_ccitt(crc,fib[j]); crc=~crc; if (crc == figcrc) sprintf(desc,"FIB CRC OK"); else sprintf(desc,"FIB CRC Mismatch: %02x",crc); printbuf("FIB CRC",3,fib+30,2,desc); fib+=32; } } offset=0; for (i=0;i> 1; sprintf(desc,"%d ms",l1*8); printbuf("TIST - Time Stamp",1,p+12+4*nst+ficf*ficl*4+offset+4,4,desc); printf("-------------------------------------------------------------------------------------------------------------\n"); } } void printbuf(char* h,int level, unsigned char* b, unsigned short int l, char* d) { int i; for (i=0;i> 7; oe = (f[0] & 0x40) >> 6; pd = (f[0] & 0x20) >> 5; ext = f[0] & 0x1F; sprintf(desc,"FIG %d/%d: C/N=%d OE=%d P/D=%d",figtype,ext,cn,oe,pd); printbuf(desc,indent,f+1,figlen-1,""); switch (ext) { case 0: { unsigned char cid,al,ch,hic,lowc,occ; unsigned short int eid,eref; eid = f[1]*256+f[2]; cid = (f[1] & 0xF0) >> 4; eref = (f[1] & 0x0F)*256 + f[2]; ch = (f[3] & 0xC0) >> 6; al = (f[3] & 0x20) >> 5; hic = f[3] & 0x1F; lowc = f[4]; if (ch != 0) { occ = f[5]; sprintf(desc,"Ensamble ID=0x%02x (Country id=%d, Ensamble reference=%d), Change flag=%d, Alarm flag=%d, CIF Count=%d/%d, Occurance change=%d",eid,cid,eref,ch,al,hic,lowc,occ); } else sprintf(desc,"Ensamble ID=0x%02x (Country id=%d, Ensamble reference=%d), Change flag=%d, Alarm flag=%d, CIF Count=%d/%d",eid,cid,eref,ch,al,hic,lowc); printbuf(desc,indent+1,NULL,0,""); } break; case 2: { unsigned short int sref, scid, sid; unsigned char cid, ecc, local, caid, ncomp, timd, ps, ca, subchid, scty; int k=1; char psdesc[16]; char sctydesc[32]; while (k> 4; sref = (f[k] & 0x0F) * 256 + f[k+1]; k=k+2; } else { sid = f[k] * 256 * 256 * 256 + f[k+1] * 256 * 256 + f[k+2] * 256 + f[k+3]; ecc = f[k]; cid = (f[k+1] & 0xF0) >> 4; sref = (f[k+1] & 0x0F) * 256 * 256 + f[k+2] * 256 + f[k+3]; k=k+4; } local = (f[k] & 0x80) >> 7; caid = (f[k] & 0x70) >> 4; ncomp = f[k] & 0x0F; if (pd == 0) sprintf(desc,"Service ID=0x%02X (Country id=%d, Service referemce=%d), Number of components=%d, Local flag=%d, CAID=%d",sid,cid,sref,ncomp,local,caid); else sprintf(desc,"Service ID=0x%02X (ECC=%d, Country id=%d, Service referemce=%d), Number of components=%d, Local flag=%d, CAID=%d",sid,ecc,cid,sref,ncomp,local,caid); printbuf(desc,indent+1,NULL,0,""); k++; for (i=0;i> 6; ps = (scomp[1] & 0x02) >> 1; ca = scomp[1] & 0x01; scty = scomp[0] & 0x3F; subchid = (scomp[1] & 0xFC) >> 2; if (timd == 3) { scid = scty*64 + subchid; } if (ps == 0) strcpy(psdesc,"Secondary service"); else strcpy(psdesc,"Primary service"); if (timd == 0) { //MSC stream audio if (scty == 0) sprintf(sctydesc,"MPEG Foreground sound (%d)",scty); else if (scty == 1) sprintf(sctydesc,"MPEG Background sound (%d)",scty); else if (scty == 2) sprintf(sctydesc,"Multi Chaneel sound (%d)",scty); else if (scty == 63) sprintf(sctydesc,"AAC sound (%d)",scty); else sprintf(sctydesc,"Unknown ASCTy (%d)",scty); sprintf(desc,"Stream audio mode, %s, %s, SubChannel ID=%02X, CA=%d",psdesc,sctydesc,subchid,ca); printbuf(desc,indent+3,NULL,0,""); } else if (timd == 1) { //MSC stream data sprintf(sctydesc,"DSCTy=%d",scty); sprintf(desc,"Stream data mode, %s, %s, SubChannel ID=%02X, CA=%d",psdesc,sctydesc,subchid,ca); printbuf(desc,indent+3,NULL,0,""); } else if (timd == 2) { // FIDC sprintf(sctydesc,"DSCTy=%d",scty); sprintf(desc,"FIDC mode, %s, %s, Fast Information Data Channel ID=%02X, CA=%d",psdesc,sctydesc,subchid,ca); printbuf(desc,indent+3,NULL,0,""); } else if (timd == 3) { // MSC PAcket mode sprintf(desc,"MSC Packet Mode, %s, Service Component ID=%02X, CA=%d",psdesc,subchid,ca); printbuf(desc,indent+3,NULL,0,""); } k+=2; } } } break; } } break; case 1: {// SHORT LABELS unsigned short int ext,oe,charset; unsigned short int flag; char label[17]; charset = (f[0] & 0xF0) >> 4; oe = (f[0] & 0x80) >> 3; ext = f[0] & 0x07; sprintf(desc,"FIG %d/%d: OE=%d, Charset=%d",figtype,ext,oe,charset); printbuf(desc,indent,f+1,figlen-1,""); memcpy(label,f+figlen-18,16); label[16]=0x00; flag = f[figlen-2] * 256 +f[figlen-1]; switch (ext) { case 0: { // ENSAMBLE LABEL unsigned short int eid; eid = f[1] * 256 + f[2]; sprintf(desc,"Ensamble ID 0x%04X label: \"%s\", Short label mask: 0x%04X",eid,label,flag); printbuf(desc,indent+1,NULL,0,""); } break; case 1: { // Programme LABEL unsigned short int sid; sid = f[1] * 256 + f[2]; sprintf(desc,"Service ID 0x%04X label: \"%s\", Short label mask: 0x%04X",sid,label,flag); printbuf(desc,indent+1,NULL,0,""); } break; case 4: { // Service Component LABEL unsigned int sid; unsigned char pd,SCIdS; pd = (f[1] & 0x80) >> 7; SCIdS = f[1] & 0x0F; if (pd==0) sid = f[2] * 256 + f[3]; else sid = f[2] * 256 * 256 * 256 + f[3] * 256 * 256 + f[4] * 256 + f[5]; sprintf(desc,"Service ID 0x%08X , Service Component ID 0x%04X Short, label: \"%s\", label mask: 0x%04X",sid,SCIdS,label,flag); printbuf(desc,indent+1,NULL,0,""); } break; case 5: { // Data Service LABEL unsigned int sid; sid = sid = f[1] * 256 * 256 * 256 + f[2] * 256 * 256 + f[3] * 256 + f[4]; sprintf(desc,"Service ID 0x%08X label: \"%s\", Short label mask: 0x%04X",sid,label,flag); printbuf(desc,indent+1,NULL,0,""); } break; case 6: { // X-PAD User Application label unsigned int sid; unsigned char pd,SCIdS,xpadapp; char xpadappdesc[16]; pd = (f[1] & 0x80) >> 7; SCIdS = f[1] & 0x0F; if (pd==0) { sid = f[2] * 256 + f[3]; xpadapp = f[4] & 0x1F; } else { sid = f[2] * 256 * 256 * 256 + f[3] * 256 * 256 + f[4] * 256 + f[5]; xpadapp = f[6] & 0x1F; } if (xpadapp==2) strcpy(xpadappdesc,"DLS"); else if (xpadapp==12) strcpy(xpadappdesc,"MOT"); sprintf(desc,"Service ID 0x%08X , Service Component ID 0x%04X Short, X-PAD App %02X (%s), label: \"%s\", label mask: 0x%04X",sid,SCIdS,xpadapp,xpadappdesc,label,flag); printbuf(desc,indent+1,NULL,0,""); } break; } } break; } }