aboutsummaryrefslogtreecommitdiffstats
path: root/lib/misc_utils/tmsi_dumper_impl.cc
blob: 043d9355889c7706fa0b654ce54151acf110ab39 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/* -*- c++ -*- */
/* @file
 * @author (C) 2015 by Piotr Krysik <ptrkrysik@gmail.com>
 * @section LICENSE
 *
 * Gr-gsm 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, or (at your option)
 * any later version.
 *
 * Gr-gsm 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 gr-gsm; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street,
 * Boston, MA 02110-1301, USA.
 *
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gnuradio/io_signature.h>
#include "tmsi_dumper_impl.h"
#include "grgsm/gsmtap.h"
#include <iostream>
#include <boost/format.hpp>

namespace gr {
namespace gsm {

void tmsi_dumper_impl::dump_tmsi(pmt::pmt_t msg)
{
    time_t t = time(0);
    tm *now = localtime(&t);

    pmt::pmt_t message_plus_header_blob = pmt::cdr(msg);
    uint8_t * message_plus_header = (uint8_t *)pmt::blob_data(message_plus_header_blob);
    gsmtap_hdr * header = (gsmtap_hdr *)message_plus_header;
    uint8_t * m = (uint8_t *)(message_plus_header+sizeof(gsmtap_hdr)); //message content

    uint8_t msg_len = m[0];
    uint8_t direction_and_protocol = m[1];
    uint8_t msg_type = m[2];

    if( direction_and_protocol == 0x06 &&                    //direction from originating site, transaction id==0, Radio Resouce Management protocol
            (msg_type==0x21 || msg_type==0x22 || msg_type==0x24) //types corresponding to paging requests
      )
    {
        //write timestamp
        switch(msg_type) {
        case 0x21: //Paging Request Type 1
        {
            uint8_t mobile_identity_type = m[5] & 0x07;
            unsigned int next_element_index = 0; //position of the next element
            bool found_id_element = false;

            if(mobile_identity_type == 0x04) //identity type: TMSI
            {
                write_tmsi(m+6);
                dump_file << "-";
                write_timestamp(now);
                dump_file << "-0";
                dump_file << std::endl;

                next_element_index = 10;
                found_id_element = true;
            } else if(mobile_identity_type == 0x01) //identity type: IMSI
            {
                dump_file << "0-";
                write_timestamp(now);
                dump_file << "-";
                write_imsi(m+5);
                dump_file << std::endl;

                next_element_index = 13;
                found_id_element = true;
            }

            if(found_id_element == true)
            {
                //check if there is additional id element
                uint8_t element_id = m[next_element_index];
                if((next_element_index < (msg_len+1)) && (element_id == 0x17)) {
                    //check if there is another element
                    uint8_t element_len = m[next_element_index+1];
                    mobile_identity_type = m[next_element_index+2] & 0x07;

                    if(mobile_identity_type == 0x04) //identity type: TMSI
                    {
                        write_tmsi(m+next_element_index+3); //write starting from position of the TMSI in the message
                        dump_file << "-";
                        write_timestamp(now);
                        dump_file << "-0";
                        dump_file << std::endl;
                    } else if(mobile_identity_type == 0x01) //identity type: IMSI
                    {
                        dump_file << "0-";
                        write_timestamp(now);
                        dump_file << "-";
                        write_imsi(m+next_element_index+2); //write starting from position of the IMSI in the message
                        dump_file << std::endl;
                    }
                }
                int ii;
            }
        }
        break; 
        case 0x22: //Paging Request Type 2
        {
            uint8_t mobile_identity_type = m[14] & 0x07;

            write_tmsi(m+4);//1st tmsi location
            dump_file << "-";
            write_timestamp(now);
            dump_file << "-0";
            dump_file << std::endl;

            write_tmsi(m+8);//2nd tmsi location
            dump_file << "-";
            write_timestamp(now);
            dump_file << "-0";
            dump_file << std::endl;

            if(mobile_identity_type == 0x04) //identity type: TMSI
            {
                write_tmsi(m+15);
                dump_file << "-";
                write_timestamp(now);
                dump_file << "-0";
                dump_file << std::endl;

            } else if(mobile_identity_type == 0x01) //identity type: IMSI
            {
                dump_file << "0-";
                write_timestamp(now);
                dump_file << "-";
                write_imsi(m+14);
                dump_file << std::endl;

            }
        }
        break;
        case 0x24: //Paging Request Type 3
        {
            int TMSI_INDEX[4] = {4,8,12,16}; // indexes of the 4 tmsi's

            for(int x =0; x < 4; x++)
            {
                write_tmsi(m+TMSI_INDEX[x]);
                dump_file << "-";
                write_timestamp(now);
                dump_file << "-0";
                dump_file << std::endl;
            }

        }
        break;
        }
    }
}

inline void tmsi_dumper_impl::write_timestamp(tm * now)
{
    dump_file << boost::format("%d%02d%02d%02d%02d%02d")
              % (now->tm_year + 1900-2000)                   //year -2000 here after the 1900 leaves you with 15 instead of 2015 (delivery reports format is 150112223501)
              % (now->tm_mon + 1)                           //month
              % now->tm_mday                                //day
              % now->tm_hour % now->tm_min % now->tm_sec;  //time of day
    return;
}

inline int swap(uint8_t c)
{
    uint8_t temp1, temp2;
    temp1 = c & 0x0F;
    temp2 = c & 0xF0;
    temp1=temp1 << 4;
    temp2=temp2 >> 4;
    return(temp2|temp1);
}

void tmsi_dumper_impl::write_imsi(uint8_t * imsi)
{
    dump_file << boost::format("%1x%02x%02x%02x%02x%02x%02x%02x")
              % (swap(imsi[0]) & 0x0f)
              % swap(imsi[1]) % swap(imsi[2]) % swap(imsi[3]) % swap(imsi[4]) % swap(imsi[5]) % swap(imsi[6]) % swap(imsi[7]);
    return;
}

void tmsi_dumper_impl::write_tmsi(uint8_t * tmsi)
{
    dump_file << boost::format("%02x%02x%02x%02x")
              % (int)tmsi[0] % (int)tmsi[1] % (int)tmsi[2] % (int)tmsi[3];
    return;
}


tmsi_dumper::sptr
tmsi_dumper::make()
{
    return gnuradio::get_initial_sptr
           (new tmsi_dumper_impl());
}

/*
 * The private constructor
 */
tmsi_dumper_impl::tmsi_dumper_impl()
    : gr::block("tmsi_dumper",
                gr::io_signature::make(0, 0, 0),
                gr::io_signature::make(0, 0, 0))
{
    dump_file.open("tmsicount.txt", std::ios_base::app);
    message_port_register_in(pmt::mp("msgs"));
    set_msg_handler(pmt::mp("msgs"), boost::bind(&tmsi_dumper_impl::dump_tmsi, this, _1));
}

/*
 * Our virtual destructor.
 */
tmsi_dumper_impl::~tmsi_dumper_impl()
{
    dump_file.close();
}
} /* namespace gsm */
} /* namespace gr */