Compare commits

..

100 Commits

Author SHA1 Message Date
Holger Hans Peter Freyther
2727909dba Make a release with the bugfix of the bugfix 2010-03-24 11:25:13 +01:00
Holger Hans Peter Freyther
ad9856ec15 ipa: Fix the previous patch and initialize the fds to -1
The code in 354ef81d80 checked
for fd >= 0 but on startup the struct is memset to 0 so this
test is true. Initialize the fds to -1 to make the code work
and be able to handle all ranges of the fd.
2010-03-24 11:23:39 +01:00
Holger Hans Peter Freyther
9d53a8ad2a Release 0.3.3 with the proposed BFD fix. 2010-03-24 04:14:26 +01:00
Holger Hans Peter Freyther
058956e8ee ipaccess: Handle the case of replacing RSL connections
Fix a infinite loop when establishing a new RSL connection and the
BSC is identifying itself with a unit id of an already established
RSL connection. The infinite loops happens because we are corrupting
the the linuxlist inside the bsc_fd when registering the bfd twice.

Due the lack of proper authentication favor the new RSL connection
as the real one and close the previous one.
2010-03-24 04:02:55 +01:00
Holger Hans Peter Freyther
a34bb9167f Bump version to 0.3.2 with the two memleak fixes. 2010-02-21 13:08:19 +01:00
Holger Hans Peter Freyther
b8ac7ffd7c [msc/nat] It is better to use msgb_free to free the msgb
msgb_free is currently calling talloc_free but this might
change in the future and then this code would break..
2010-02-21 13:08:12 +01:00
Holger Hans Peter Freyther
b13cf829da [nat/bsc] Fix memory leak of IPA messages...
* The read_msg method is allocating the msgb and we will
  need to free it once we are done with it.
2010-02-21 12:56:02 +01:00
Holger Hans Peter Freyther
fdc64f6806 [bsc_msc_ip] Fix the re-queuing of packets...
* The MSC is sending us the next 04.08 packet before we have
  received the answer for the cipher model complete. The code was
  supposed to copy all packets from the current queue, to a new
  queue and then send the packets again.
* This would (re)establish the different SAPIs. Now the requeuing
  code was grabbing the packet from the empty queue (NULL pointer)
  and we were dereferencing it. It appears that we need to use
  "head" until the queue is empty.
2010-02-08 20:14:53 +01:00
Holger Hans Peter Freyther
ab46372e2a Bump the configure.in to 0.3on-wave. 2010-02-08 15:39:07 +01:00
Holger Hans Peter Freyther
ff0a562f9a Revert "[bssap] Open a traffic channel for the paging any reason"
This reverts commit 55a0716da7.

Using a TCH/H, TCH/F for paging purpose any will break the MT-SMS
case because this needs a SDCCH to establish SAPI=3. The On Waves
BSC Master branch has support for early assignment now so this hack
is not needed anymore.
2010-01-28 11:59:52 +01:00
Holger Hans Peter Freyther
556008d724 [bsc] Implement early assignment for CC for the MT case.
In case we need to handle speech but we are currently on a SDCCH
we need to assign a new channel and close the old one. This
implementation should have the correct flow of things but we might
need to fix some error situations properly.

It is implemented by keeping a secondary_lchan pointer that will
be swapped into the lchan pointer after the assignment complete
message from the MS. The old lchan will be deactivated (the SACCH
should stay open). We have to manually remove the subscr from the
lchan structure to properly close things down.
2010-01-28 11:59:51 +01:00
Holger Hans Peter Freyther
0094f84f30 [bssap] Use switch/case for the signal handler
Use switch/case, switch/case for the subsys and signal
to prepare to handle more signals in the future.
2010-01-28 11:59:51 +01:00
Holger Hans Peter Freyther
86069143ff [gsm48] Use optional Chan Mode 1 for the assignment command
Specify how we intend to use the assigned channel. This is
needed to make CC with early assignment work properly.
2010-01-28 11:59:51 +01:00
Holger Hans Peter Freyther
44f0be88a3 [gsm48] Allow to send the assignment command on a different lchan
Change the signature to take the lchan were the message is supposed
to be sent and the lchan which is supposed to be assigned.
2010-01-28 11:59:51 +01:00
Holger Hans Peter Freyther
5d88b372d7 [rsl] Send the MultiRateConfig in the RSL Channel Activate msg
If the lchan has AMR as speech codec we also need to send the
multirate config IE in the channel activation. This is already
done for the RSL Channel Modify message.
2010-01-28 04:46:32 +01:00
Holger Hans Peter Freyther
71c7bf5907 [sccp] Separate connection parsing and policy for connection request
The same concept as with the previous patch, make the reject method
work on the source local reference instead of passing it the header.
2010-01-27 12:31:50 +01:00
Holger Hans Peter Freyther
869033148c [sccp] Move the UDT parsing to a new method
Separate SCCP UDT parsing and handling into two methods. This
way the parsing can be reused by the BSC NAT.
2010-01-27 12:31:50 +01:00
Holger Hans Peter Freyther
bc0f7c0988 [sccp] Invent new API to be used by the BSC NAT
I want to reuse the SCCP code for header parsing in the BSC
NAT to identify data and patch the source local reference. To do
this the current handle_* methods will be changed into two parts
one is strictly parsing the other is handling the parsed data.
2010-01-27 12:31:50 +01:00
Holger Hans Peter Freyther
7d06063cfb [paging] Increase the time used to send paging messages to the BTS
Send a Paging Request to the BTS every two seconds. This way it is
unlikely that a phone will try to respond to two paging requests as
it is currently happening.
2010-01-27 12:31:50 +01:00
Holger Hans Peter Freyther
4e42b637fd [bsc_msc] Start the Inactivity Timer only when the connection is established
Start the SCCP IT timer only after the MSC has confirmed the SCCP
connection. It is safe to call bsc_del_timer even if it was never
started. This could happen on a connection refusal.
2010-01-27 12:31:50 +01:00
Holger Hans Peter Freyther
f44de9942b [msc] Fix compilation by adding blocked_gsm to the struct 2010-01-27 12:31:50 +01:00
Holger Hans Peter Freyther
3a110ae60b [msc] Attempt to fix MT SMS with ciphering enabled.
The MSC is asking us to enable ciphering and then immediately
sends a DTAP msg for SAPI=3. We handle this correctly by attempting
to establish SAPI=3 but we never get an establishment confirm
for this SAPI.

Attempt to fix it by not sending any DTAP message when we receive
the Cipher Mode Request and unblock the queue when the ciphering
is confirmed. The unblocking currently works by taking all messages
out of the queue and then submitting them again. This will attempt
to establish the SAPI=3 and such automaticaly.

And the MSC stopped sending me SMS so this needs to be verified at a
later time.
2010-01-27 07:34:34 +01:00
Holger Hans Peter Freyther
bb84adc465 [rest_octets] Change data_len to the sizes of the spec
Is that right?
2010-01-27 06:10:43 +01:00
Holger Hans Peter Freyther
8d123ea3c0 [system_information] Initialize the buffer before moving it
In the case of ipaccess we are doing a ++output but then still
try to write 23 bytes into it and on my system this is leading
to a stack corruption.
2010-01-27 06:09:36 +01:00
Holger Hans Peter Freyther
88ca894df7 [nat] Handle write errors with a warning to make the compiler happy
Make the compiler happy by checking the write error and printing
a message to the console.
2010-01-25 10:01:30 +01:00
Holger Hans Peter Freyther
42b0d6b494 [nat] Add a bsc_filter.c which will carry out the analysis and filtering
The first part is to analyze the IP Access Header and only forward
SCCP messages for now. In the future we might want to do MGCP
signalling through this protocol and connection as well and need to
update this then.
2010-01-21 08:52:40 +01:00
Holger Hans Peter Freyther
82d8b0457b [mgcp] In forward mode we need to rediscover the BTS more often
In plain forward mode we don't have DLCX which will clean
and reset the configuration. We will need to remember the
last GSM BTS port and send data to it.
2010-01-14 08:35:57 +01:00
Holger Hans Peter Freyther
433d6ee1a2 [mgcp] Handle BTS and NET being on the same host
* Do not only check the IP but also the port to figure out
  where to send the data
* Do not memset the endp->remote inside the bind_rtp but from
  inside the crcx as this will be modified by the MDCX
2010-01-14 00:15:44 +01:00
Holger Hans Peter Freyther
203a6eddf8 [mgcp] Warn about unknown messages... 2010-01-13 23:53:59 +01:00
Holger Hans Peter Freyther
56ef6249e3 [mgcp] Allow to forward to a different port 2010-01-13 23:36:53 +01:00
Holger Hans Peter Freyther
b2a96b1be7 [mgcp] Rename rtp and rtcp variables to net_rtp and net_rtcp
Rename the variables to refer to the fact that they are
the ports of the remote.

So we have:
    rtp_port as the local address we are binding to
    net_rtp  for the network rtp
    bsc_rtp  for the bsc rtp
2010-01-13 22:49:55 +01:00
Holger Hans Peter Freyther
d4c29c1574 [mgcp] Make it possible to not specify a bts ip
This way the mgcp will allow anyone to be the BTS..
in the future we might need to communicate things
properly between BSC and MGCP.
2010-01-13 16:38:18 +01:00
Holger Hans Peter Freyther
3d947e6d67 [nat] Use the right len for the packages.. 2010-01-13 15:22:20 +01:00
Holger Hans Peter Freyther
b62c9a19cf [sccp] Add a utility for the nat..
Add a small helper to determine the type of a message
2010-01-13 09:55:43 +01:00
Holger Hans Peter Freyther
ff5957568f [nat] Really forward the data to the BSC 2010-01-13 09:55:20 +01:00
Holger Hans Peter Freyther
7d2e1ca4be [nat] Make sure the ipaccess_bsc_cb will be called.. 2010-01-13 09:52:29 +01:00
Holger Hans Peter Freyther
7ce2e0c8b0 [nat] Unregister the fd before leaving.. 2010-01-13 09:51:23 +01:00
Holger Hans Peter Freyther
78d442420b [nat] First code to simply forward data from the MSC to the real BSC
First code to simply forward the data, no filtering or patching
is in place. This will need to happen soon.
2010-01-13 09:28:12 +01:00
Holger Hans Peter Freyther
8cd2709ebf [ipaccess] Create a method to send the ID ACK messages 2010-01-13 09:06:46 +01:00
Holger Hans Peter Freyther
41a1780102 [nat] Turn off compiler warning... 2010-01-12 21:36:08 +01:00
Holger Hans Peter Freyther
2f84715984 [nat] Security will become important at some point... 2010-01-12 21:35:32 +01:00
Holger Hans Peter Freyther
7253154fc5 [nat] Start to listen for the incoming BTS 2010-01-12 21:34:54 +01:00
Holger Hans Peter Freyther
6c1c76683f [nat] Connect to the MSC like the real BSC
Use the connect_to_msc method to connect to the MSC and
create structure to handle and forward messages to the
real BSC.
2010-01-12 21:15:08 +01:00
Holger Hans Peter Freyther
a92fe9a4ca [bsc_msc] Move the connect to the MSC routine into a new file 2010-01-12 20:40:39 +01:00
Holger Hans Peter Freyther
e83a3f584e [bsc-nat] Start with a simple NAT/MUX for a BSC
Harald actually pointed out that this feature is just NAT. We want
to connect n-real BSCs to one BSC Mux. We will talk the ip.access
protocol and SCCP over of this link.

The mux will drop certain GSM messages (like the reset), it will
replace source local reference (NAT functionality) and it will handle
some GSM08.08 specially.

Get the thing started...
2010-01-11 23:01:16 +01:00
Holger Hans Peter Freyther
118ddebc36 [on-waves] Use a default rtp_base_port, write it out in the config
Currently "write memory" will not store the rtp_base_port of the
network. Fix that by writing it out in write_net. Also set it to
4000 by default in the MGCP and in the BSC.
2010-01-08 15:24:21 +01:00
Holger Hans Peter Freyther
bb53004d47 Tag on-waves 0.2 release 2010-01-07 15:12:23 +01:00
Holger Hans Peter Freyther
6af20842cb [bssap] Return u_int16_t from the get_*_code methods
The LAI generation wants to have 16bit unsigned, just keep
them like this already. This means the int32_t will be truncated
inside the get_*_code methods which is better than doing it
somewhere else.
2010-01-07 14:53:18 +01:00
Holger Hans Peter Freyther
cc41cb07e7 [bssap] More brown paper... Make variables really signed
-1 is assigned in case the variables are not set. This means
it must be a signed type (as the comment says), now really use
a signed type.
2010-01-07 14:52:35 +01:00
Holger Hans Peter Freyther
d6fb23523a [bssap] Fix brown paper bag... Keep the air id ...*sigh*
We want to use the real number on the Um... Using the core
network code is totally wrong in this scope...
2010-01-07 14:36:20 +01:00
Holger Hans Peter Freyther
2aa0b45cc0 [bssap] Allow to use a different country code too
* Be able to have a country code in the air but use a different
  country code when talking to the core network.
* Now both country and network code can be different on air and
  on the MSC communication.
2010-01-07 03:17:01 +01:00
Holger Hans Peter Freyther
619df61ad2 [rsl] Partial revert of the GSM speech mode for the nanoBTS
This is partially reverting 0603c9d9e5,
it is true that the ip.access Wireshark dissectors differentiate
TCH/H from TCH/F but in my test I'm unable to send RTP on to the
BTS. It might be that the RTP payload provided in the MDCX is not
the one it will accept with the 0x05 mode. More work needs to be
done to understand this, that is the reason it is comitted to the
on-waves's branch instead of master.
2010-01-06 11:44:26 +01:00
Holger Hans Peter Freyther
893ea65f38 [bsc_msc_ip] Turn the MNC hack into a config option
* Make it possible to have a different MNC in the RSL traffic
  than in the core network.
* Introduce the "core network code NUMBER" variable. If it is
  set this network code will be used in traffic with the MSC.
* Use the core_network_code number when sending a packet to
  the MSC
* Regenerate the LAI (this is where I could have a bug) when
  sending packets to the BTS.
* Add size checks.

This is not tested, I might got something wrong.
2010-01-05 13:57:45 +01:00
Holger Hans Peter Freyther
64b811f113 [bsc_mgcp] Set the right remote rtp and rtcp port
* It is the same as local endpoint port
2010-01-05 12:35:16 +01:00
Holger Hans Peter Freyther
91fc9bf862 [bsc_mgcp] Fix writing of the config file...
* Add the new forward audio option
2010-01-05 12:29:36 +01:00
Holger Hans Peter Freyther
111a58dd37 [bsc_mgcp] Print a message which mode is configured 2010-01-05 12:25:25 +01:00
Holger Hans Peter Freyther
d1a2563a74 [bsc_mgcp] Add a new forward only mode to the bsc_mgcp
With forward IP in the config and early bind on we will
simply forward RTP data on the endpoints from BTS to the
forward IP address.

This is implemented by disabling MGCP functionality when
a forward IP address was specified, setting the forward IP
in the endp->remote and assigning a ci != CI_UNUSED.

Early bind will make sure the sockets are created, the BSC FD's
are registered and then the normal dispatch code will
do the forwarding.
2010-01-05 12:21:36 +01:00
Holger Hans Peter Freyther
7d3ef919ce [bssap] Set the right GSM08.08 speech version indicator
* For half rate we also need to set the 3rd bit to one
* See GSM08.08 §3.2.2.51 and then §3.2.2.11
2010-01-05 04:18:16 +01:00
Holger Hans Peter Freyther
cba98d87d6 [misc] Move handover into libmsc.a
Handover is a high level decision, it can span multiple BSCs
and belongs mostly into the MSC domain.
2009-12-22 08:03:55 +01:00
Holger Hans Peter Freyther
5c18ad0829 Merge commit 'origin/master' into on-waves/bsc-master
Conflicts:
	openbsc/include/openbsc/Makefile.am
	openbsc/include/openbsc/gsm_data.h
	openbsc/src/Makefile.am
	openbsc/src/abis_rsl.c
	openbsc/src/chan_alloc.c
	openbsc/src/gsm_04_08.c
	openbsc/src/gsm_data.c
	openbsc/src/vty_interface.c

The biggest problem is the moving of the RTP code into
the RSL layer. This may break quite some things...
2009-12-22 08:02:13 +01:00
Holger Hans Peter Freyther
0d9ed87d5c [bsc_hack] Ignore the sigpipe...
We might read or write on the OML link when the BTS is
reset and will get SIGPIPE interrupt and be gone... Just
ignore the SIGPIPE we will get the "exception" on the next
run of bsc_select and kill the (old) OML link.
2009-12-06 04:32:27 +01:00
Harald Welte
ec7be0c969 move RTP socket information from timeslot to lchan
With ip.access, in case of TCH/H, we have one RTP stream for each half-slot
(lchan), not just one per on-air timeslot.  This is quite different from
a classic BTS where the TRAU frames of the two TCH/H channels would be
part of the same 16k sub-slot in a E1 timeslot.
2009-12-06 04:05:31 +01:00
Harald Welte
9be3347601 RSL: catch inconsistent parameters ofr channel_mode_from_lchan() 2009-12-06 04:03:55 +01:00
Harald Welte
3eef7b7d81 Assign default values for T3101 and T3113
Without those default values, old config files will no longer work
after commit 23975e718f
2009-12-06 04:03:23 +01:00
Holger Hans Peter Freyther
9de4a6daa9 Merge branch 'master' into on-waves/bsc-master
Conflicts:
	openbsc/src/abis_nm.c
	openbsc/src/bsc_init.c
	openbsc/src/vty_interface.c
2009-11-24 19:58:01 +01:00
Holger Hans Peter Freyther
851ace9f33 Merge branch 'master' into on-waves/bsc-master
Conflicts:
	openbsc/include/openbsc/Makefile.am
	openbsc/src/Makefile.am
2009-11-20 18:01:37 +01:00
Holger Hans Peter Freyther
d1dd069b48 [configure] Add onwaves to the version tag 2009-11-20 17:43:40 +01:00
Holger Hans Peter Freyther
401db32ca2 HACK patch the network code..
Report to the MSC with the right code and patch
it on the air...
2009-11-20 17:41:05 +01:00
Holger Hans Peter Freyther
17e03d21d2 [vty] Add option to disable RF on a given TRX.
- Make sure that on runtime the Radio Carrier can be
  locked and unlocked. The vty code calls into the
  Abis NM to lock/unlock the channel and the state is
  stored there.

- Make sure that on start the Radio Carries remains
  offline and we are not starting it. On start the
  radio carrier is either locked or unlocked. This means
  the RSL will not connect until the RF is unlocked. It
  will connect then. To see RSL bringup failures one
  needs to parse the RSL nack message.
2009-11-20 17:40:50 +01:00
Holger Hans Peter Freyther
26a9bff201 [bsc_init] Activate the RC and the RSL link from the Software Activated Callback
On cold start the RSL link will not be brought up. Wait for the
Software to be Activated before starting the RSL link. This is
working reliable on the BTS I have tested with.
2009-11-20 17:40:39 +01:00
Holger Hans Peter Freyther
80fb260a60 [lchan] Release the channel ones its' usecount drops to zero
Remove the timer handling from the LCHAN and release the
channel ones the use count is dropping to zero.

Change code that was sending/using the lchan after the
release and change the send data method to warn in case
the lchan is used after it has been freed.
2009-11-20 17:40:28 +01:00
Holger Hans Peter Freyther
55a0716da7 [bssap] Open a traffic channel for the paging any reason
In the case the MS is requesting a channel with the
paging any channel reason, use a TCH. This allows us
to keep using very early assignment and the SDCCHs are
kept free for location updating requests.
2009-11-20 17:40:00 +01:00
Holger Hans Peter Freyther
c88fb75616 [rsl] Speculative crash fix in the RSL rcv message
The theory is that the BTS is almost dead and sends out
a incomplete message and we crash with that. I have not
been able to completely verify that.
2009-11-20 17:38:47 +01:00
Holger Hans Peter Freyther
d55a4dc326 Merge branch 'on-waves/gsm0808' into on-waves/bsc-master 2009-11-20 17:38:02 +01:00
Holger Hans Peter Freyther
a4e6f2e6e1 [bssap] Support multiple multiplexers in the assignment command
When more than one trunk group is allocated to the BSC the
MSC will start to assign channels from the different multiplexer.

We will map them the following way onto MGCP endpoints

Multiplex 0:
   0	->	1
   1	->      signalling
   2	->	2
   ..	->	..
   16	->	signalling (might be 15)
   30	->	30

Multiplex 1:
   0	->	31
   2	->	32
...

Multiplex 3:
..
2009-11-20 17:35:47 +01:00
Holger Hans Peter Freyther
7f71d99cc3 [bsc] Add a rtp base port to the BSC config too
Stop having a global variable... keep it in the
gsm network or the mgcp
2009-11-20 17:35:47 +01:00
Holger Hans Peter Freyther
b92167cf80 [vty] Write out BSC specific network parameters too 2009-11-20 17:35:47 +01:00
Holger Hans Peter Freyther
4b6a6dbe7e [bssap] Cope with weird channel mapping on the network side
The timeslot of the network maps the following way
	0	->	1
	1	->	n/a
	2	->	2
	...	->      ...
	31	->	31
2009-11-20 17:35:47 +01:00
Holger Hans Peter Freyther
763e8c7766 [ipacc] Add a way to override the rtp payload for MDCX 2009-11-20 17:35:46 +01:00
Holger Hans Peter Freyther
823ff16088 [bsc] Send the SCCP IT message in a given interval
Send the message every 60 seconds on every SCCP
connection. The 60 seconds were taken from a protocol
trace obtained on the network.
2009-11-20 17:35:46 +01:00
Holger Hans Peter Freyther
6f93c6a1e0 [bsc] Unref the lchan when the MSC is closing the SCCP connection
Currently we are not sending the Inactivity Test message so the
MSC will close the specific sccp connection but we would keep the
lchan open and then end up with resource issues.

Change the code to close the lchan before closing the SCCP connection..
2009-11-20 17:35:46 +01:00
Holger Hans Peter Freyther
f97e48b0de [bssap] Send multirate config for HR AMR with 5.9k
Send a hardcoded multirate config when usin the
AMR codec. This should be more configurable in
the future.
2009-11-20 17:35:46 +01:00
Holger Hans Peter Freyther
761600b0fd [bsc] Add a test_mode function that can be used to inject packages
This method can be called from the main method to inject
a test message into a "fake" network with sccp connection.
2009-11-20 17:35:46 +01:00
Holger Hans Peter Freyther
8549462bc6 [bssap] Attempt to allow selecting the speech mode from config
It is possible to specify a list of possible speech codecs
and we will try to match the assignment command with the
one from the config file. This is not tested yet and we have
one problem. We assume we can modify the channel to hold
the speech value... this will require more work.
2009-11-20 17:35:46 +01:00
Holger Hans Peter Freyther
436e5c6308 [vty] Add configuration for the preferred speech version
Add network configuration option to specify which audio
codecs are supported by the BTS. This allows the BSC to
pick the audio codec in the GSM0808 Assignment Request.
2009-11-20 17:35:46 +01:00
Holger Hans Peter Freyther
f8b9d844c1 [bssap] Pick the A5/0 vs A5/1 setting from the gsm_network
Follow the configuration of the gsm network. If the Cipher
Mode Request does not allow our preferred format we will
reject it. Otherwise send the cipher mode command to the
mobile station. This code is mostly untested.
2009-11-20 17:35:46 +01:00
Holger Hans Peter Freyther
58ec07d580 [bsc] Add BSC specific config option... currently and empty show is implemented
In the future this should give a list of SCCP connections
and their allocated radio resources/users...
2009-11-20 17:35:46 +01:00
Holger Hans Peter Freyther
71465c21f4 [bssap] Implement generating a classmark update message
Generate a classmark update message from a given payload
this might need to be changed to get the version2 and
version3 parameters
2009-11-20 17:35:46 +01:00
Holger Hans Peter Freyther
16d0a833f8 [bssmap] Fix the chosen encryption in assignment complete
Send the RSL value... it is the right value
2009-11-20 17:35:46 +01:00
Holger Hans Peter Freyther
ea72b62cac [bssmap] Unconditionally include the chosen encryption in cipher mode complete 2009-11-20 17:35:45 +01:00
Holger Hans Peter Freyther
49a84ec6e9 [bssmap] Assignment handling fixes and improvements
- Fix the generation of the assignment failure message
- Parse the permitted indicator of the assignment request message
2009-11-20 17:35:45 +01:00
Holger Hans Peter Freyther
42c636b6c8 [bssap] Fix generation of the failure message 2009-11-20 17:35:45 +01:00
Holger Hans Peter Freyther
a0a55f555e [bssap] Only start establish when the link is not yet established
This is fixing a bug when we try to submit a SMS from the MS to
the network. We send the RLS ESTABLISH REQUEST but as the MS
already established this SAPI we waited for the timeout and failed..
2009-11-20 17:35:45 +01:00
Holger Hans Peter Freyther
23ed00e410 [bssap] Improve log messages... 2009-11-20 17:35:45 +01:00
Holger Hans Peter Freyther
3fe910b9f1 [bssap] First go at implementing channel assignment... 2009-11-20 17:35:45 +01:00
Holger Hans Peter Freyther
097bdeb77d [bssap] First go at implementing ASSIGNMENT REQUEST 2009-11-20 17:35:45 +01:00
Holger Hans Peter Freyther
1b85de02e0 [bssap] Add a "#warning" that cipher mode is not properly handled 2009-11-20 17:35:45 +01:00
Holger Hans Peter Freyther
2281d1835f [bssap] Start to queue messages to the BTS and to the MSC
For the MSC we need to queue GSM04.08 messages until the
SCCP connection is  confirmed to be open and then can send
the stored messages. The queue is limited to 10 messages
at which point new ones will be dropped. Currently the
only messages we get are measurement indication messages
but it is better to be safe than sorry.

The SCCP messages are sent as soon as the connection
is considered established and then no queueing happens
any more. While replacing sccp_connection_write calls
various memory leaks has been fixed.

For the MS we might have received a DTAP and need to do
an operation that requires a roundtrip and want to send
wait until this has happened. The two scenerios are sending
a SMS to the phone that requires to do something special
for the different SAPI. Currently it is assumed that
only one SAPI=0 -> SAPI=3 change happen during the connection.

For the first SAPI != 0 we will send the rll_ request
and then wait for the timeout or confirmation. In case
of timeout a SAPI "n" reject is sent and in case of
success the queue is getting emptied.
2009-11-20 17:35:45 +01:00
Holger Hans Peter Freyther
fb4433a129 [bssap] Implement SAPI "N" Reject message
This message will be needed when no RLL connection
on a different SAPI can be established or we don't
want to establish it.
2009-11-20 17:35:45 +01:00
Holger Hans Peter Freyther
d954dcf9e1 [bsc_msc_ip] This is a BSC that connects to real MSC via IP
This is a BSC to be used by on-waves.com to connect to a real
MSC using SCCP over IP.

The following messages and features are currently implemented:
    - IPA identity ack's
    - COMPLETE LAYER3 INFORMATION
    - DTAP
    - PAGING COMMAND
    - CLEAR COMPLETE/CLEAR REQUEST
    - CIPHER MODE COMMAND/ REJECT /COMPLETE

It comes with a tool to create the enum's from the spec and
a very simple test server to do the handshaking.
2009-11-20 17:35:45 +01:00
204 changed files with 10008 additions and 23672 deletions

View File

@@ -1,22 +0,0 @@
Makefile
Makefile.in
.deps
.libs
*.o
*.lo
*.la
*.pc
aclocal.m4
autom4te.cache
config.h*
config.sub
config.log
config.status
config.guess
configure
depcomp
missing
ltmain.sh
install-sh
stamp-h1
libtool

View File

@@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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 2 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, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@@ -1,7 +0,0 @@
AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
INCLUDES = $(all_includes) -I$(top_srcdir)/include
SUBDIRS = include src tests
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libosmocore.pc

View File

@@ -1,52 +0,0 @@
AC_INIT
AM_INIT_AUTOMAKE(libosmocore, 0.0alpha1)
dnl kernel style compile messages
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
dnl checks for programs
AC_PROG_MAKE_SET
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_RANLIB
AC_PROG_LIBTOOL
dnl checks for header files
AC_HEADER_STDC
AC_CHECK_HEADERS(execinfo.h sys/select.h)
# The following test is taken from WebKit's webkit.m4
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -fvisibility=hidden "
AC_MSG_CHECKING([if ${CC} supports -fvisibility=hidden])
AC_COMPILE_IFELSE([char foo;],
[ AC_MSG_RESULT([yes])
SYMBOL_VISIBILITY="-fvisibility=hidden"],
AC_MSG_RESULT([no]))
CFLAGS="$saved_CFLAGS"
AC_SUBST(SYMBOL_VISIBILITY)
dnl Generate the output
AM_CONFIG_HEADER(config.h)
AC_ARG_ENABLE(talloc,
[ --disable-talloc Disable building talloc memory allocator ],
[enable_talloc=0], [enable_talloc=1])
AM_CONDITIONAL(ENABLE_TALLOC, test "x$enable_talloc" = "x1")
AC_ARG_ENABLE(tests,
[ --disable-tests Disable building test programs ],
[enable_tests=0], [enable_tests=1])
AM_CONDITIONAL(ENABLE_TESTS, test "x$enable_tests" = "x1")
AC_OUTPUT(
libosmocore.pc
include/osmocore/Makefile
include/osmocore/protocol/Makefile
include/Makefile
src/Makefile
tests/Makefile
tests/timer/Makefile
tests/sms/Makefile
Makefile)

View File

@@ -1 +0,0 @@
SUBDIRS = osmocore

View File

@@ -1,12 +0,0 @@
osmocore_HEADERS = signal.h linuxlist.h timer.h select.h msgb.h \
tlv.h bitvec.h comp128.h statistics.h gsm_utils.h utils.h \
gsmtap.h write_queue.h rsl.h gsm48.h rxlev_stat.h mncc.h \
gsm48_ie.h
if ENABLE_TALLOC
osmocore_HEADERS += talloc.h
endif
osmocoredir = $(includedir)/osmocore
SUBDIRS = protocol

View File

@@ -1,22 +0,0 @@
/*
* COMP128 header
*
* See comp128.c for details
*/
#ifndef __COMP128_H__
#define __COMP128_H__
#include <stdint.h>
/*
* Performs the COMP128 algorithm (used as A3/A8)
* ki : uint8_t [16]
* srand : uint8_t [16]
* sres : uint8_t [4]
* kc : uint8_t [8]
*/
void comp128(uint8_t *ki, uint8_t *srand, uint8_t *sres, uint8_t *kc);
#endif /* __COMP128_H__ */

View File

@@ -1,17 +0,0 @@
#ifndef _OSMOCORE_GSM48_H
#include <osmocore/tlv.h>
#include <osmocore/protocol/gsm_04_08.h>
#include <osmocore/gsm48_ie.h>
extern const struct tlv_definition gsm48_att_tlvdef;
extern const char *cc_state_names[32];
extern const char *gsm48_cc_msg_names[0x40];
const char *rr_cause_name(uint8_t cause);
void gsm48_generate_lai(struct gsm48_loc_area_id *lai48, uint16_t mcc,
uint16_t mnc, uint16_t lac);
int gsm48_generate_mid_from_tmsi(uint8_t *buf, uint32_t tmsi);
int gsm48_generate_mid_from_imsi(uint8_t *buf, const char *imsi);
#endif

View File

@@ -1,107 +0,0 @@
#ifndef _OSMOCORE_GSM48_IE_H
#define _OSMOCORE_GSM48_IE_H
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <osmocore/msgb.h>
#include <osmocore/tlv.h>
#include <osmocore/mncc.h>
#include <osmocore/protocol/gsm_04_08.h>
/* decode a 'called/calling/connect party BCD number' as in 10.5.4.7 */
int gsm48_decode_bcd_number(char *output, int output_len,
const uint8_t *bcd_lv, int h_len);
/* convert a ASCII phone number to 'called/calling/connect party BCD number' */
int gsm48_encode_bcd_number(uint8_t *bcd_lv, uint8_t max_len,
int h_len, const char *input);
/* decode 'bearer capability' */
int gsm48_decode_bearer_cap(struct gsm_mncc_bearer_cap *bcap,
const uint8_t *lv);
/* encode 'bearer capability' */
int gsm48_encode_bearer_cap(struct msgb *msg, int lv_only,
const struct gsm_mncc_bearer_cap *bcap);
/* decode 'call control cap' */
int gsm48_decode_cccap(struct gsm_mncc_cccap *ccap, const uint8_t *lv);
/* encode 'call control cap' */
int gsm48_encode_cccap(struct msgb *msg,
const struct gsm_mncc_cccap *ccap);
/* decode 'called party BCD number' */
int gsm48_decode_called(struct gsm_mncc_number *called,
const uint8_t *lv);
/* encode 'called party BCD number' */
int gsm48_encode_called(struct msgb *msg,
const struct gsm_mncc_number *called);
/* decode callerid of various IEs */
int gsm48_decode_callerid(struct gsm_mncc_number *callerid,
const uint8_t *lv);
/* encode callerid of various IEs */
int gsm48_encode_callerid(struct msgb *msg, int ie, int max_len,
const struct gsm_mncc_number *callerid);
/* decode 'cause' */
int gsm48_decode_cause(struct gsm_mncc_cause *cause,
const uint8_t *lv);
/* encode 'cause' */
int gsm48_encode_cause(struct msgb *msg, int lv_only,
const struct gsm_mncc_cause *cause);
/* decode 'calling number' */
int gsm48_decode_calling(struct gsm_mncc_number *calling,
const uint8_t *lv);
/* encode 'calling number' */
int gsm48_encode_calling(struct msgb *msg,
const struct gsm_mncc_number *calling);
/* decode 'connected number' */
int gsm48_decode_connected(struct gsm_mncc_number *connected,
const uint8_t *lv);
/* encode 'connected number' */
int gsm48_encode_connected(struct msgb *msg,
const struct gsm_mncc_number *connected);
/* decode 'redirecting number' */
int gsm48_decode_redirecting(struct gsm_mncc_number *redirecting,
const uint8_t *lv);
/* encode 'redirecting number' */
int gsm48_encode_redirecting(struct msgb *msg,
const struct gsm_mncc_number *redirecting);
/* decode 'facility' */
int gsm48_decode_facility(struct gsm_mncc_facility *facility,
const uint8_t *lv);
/* encode 'facility' */
int gsm48_encode_facility(struct msgb *msg, int lv_only,
const struct gsm_mncc_facility *facility);
/* decode 'notify' */
int gsm48_decode_notify(int *notify, const uint8_t *v);
/* encode 'notify' */
int gsm48_encode_notify(struct msgb *msg, int notify);
/* decode 'signal' */
int gsm48_decode_signal(int *signal, const uint8_t *v);
/* encode 'signal' */
int gsm48_encode_signal(struct msgb *msg, int signal);
/* decode 'keypad' */
int gsm48_decode_keypad(int *keypad, const uint8_t *lv);
/* encode 'keypad' */
int gsm48_encode_keypad(struct msgb *msg, int keypad);
/* decode 'progress' */
int gsm48_decode_progress(struct gsm_mncc_progress *progress,
const uint8_t *lv);
/* encode 'progress' */
int gsm48_encode_progress(struct msgb *msg, int lv_only,
const struct gsm_mncc_progress *p);
/* decode 'user-user' */
int gsm48_decode_useruser(struct gsm_mncc_useruser *uu,
const uint8_t *lv);
/* encode 'useruser' */
int gsm48_encode_useruser(struct msgb *msg, int lv_only,
const struct gsm_mncc_useruser *uu);
/* decode 'ss version' */
int gsm48_decode_ssversion(struct gsm_mncc_ssversion *ssv,
const uint8_t *lv);
/* encode 'ss version' */
int gsm48_encode_ssversion(struct msgb *msg,
const struct gsm_mncc_ssversion *ssv);
/* decode 'more data' does not require a function, because it has no value */
/* encode 'more data' */
int gsm48_encode_more(struct msgb *msg);
#endif

View File

@@ -1,84 +0,0 @@
/* GSM utility functions, e.g. coding and decoding */
/*
* (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
*
* 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 2 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#ifndef GSM_UTILS_H
#define GSM_UTILS_H
#include <stdint.h>
struct gsm_time {
uint32_t fn; /* FN count */
uint16_t t1; /* FN div (26*51) */
uint8_t t2; /* FN modulo 26 */
uint8_t t3; /* FN modulo 51 */
uint8_t tc;
};
enum gsm_band {
GSM_BAND_850 = 1,
GSM_BAND_900 = 2,
GSM_BAND_1800 = 4,
GSM_BAND_1900 = 8,
GSM_BAND_450 = 0x10,
GSM_BAND_480 = 0x20,
GSM_BAND_750 = 0x40,
GSM_BAND_810 = 0x80,
};
const char *gsm_band_name(enum gsm_band band);
enum gsm_band gsm_band_parse(const char *mhz);
int gsm_7bit_decode(char *decoded, const uint8_t *user_data, uint8_t length);
int gsm_7bit_encode(uint8_t *result, const char *data);
int ms_pwr_ctl_lvl(enum gsm_band band, unsigned int dbm);
int ms_pwr_dbm(enum gsm_band band, uint8_t lvl);
/* According to TS 08.05 Chapter 8.1.4 */
int rxlev2dbm(uint8_t rxlev);
uint8_t dbm2rxlev(int dbm);
/* According to GSM 04.08 Chapter 10.5.2.29 */
static inline int rach_max_trans_val2raw(int val) { return (val >> 1) & 3; }
static inline int rach_max_trans_raw2val(int raw) {
const int tbl[4] = { 1, 2, 4, 7 };
return tbl[raw & 3];
}
#define ARFCN_PCS 0x8000
#define ARFCN_UPLINK 0x4000
enum gsm_band gsm_arfcn2band(uint16_t arfcn);
/* Convert an ARFCN to the frequency in MHz * 10 */
uint16_t gsm_arfcn2freq10(uint16_t arfcn, int uplink);
/* Convert from frame number to GSM time */
void gsm_fn2gsmtime(struct gsm_time *time, uint32_t fn);
/* Convert from GSM time to frame number */
uint32_t gsm_gsmtime2fn(struct gsm_time *time);
void generate_backtrace();
#endif

View File

@@ -1,72 +0,0 @@
#ifndef _GSMTAP_H
#define _GSMTAP_H
/* gsmtap header, pseudo-header in front of the actua GSM payload */
/* GSMTAP is a generic header format for GSM protocol captures,
* it uses the IANA-assigned UDP port number 4729 and carries
* payload in various formats of GSM interfaces such as Um MAC
* blocks or Um bursts.
*
* Example programs generating GSMTAP data are airprobe
* (http://airprobe.org/) or OsmocomBB (http://bb.osmocom.org/)
*/
#include <stdint.h>
#define GSMTAP_VERSION 0x02
#define GSMTAP_TYPE_UM 0x01
#define GSMTAP_TYPE_ABIS 0x02
#define GSMTAP_TYPE_UM_BURST 0x03 /* raw burst bits */
#define GSMTAP_BURST_UNKNOWN 0x00
#define GSMTAP_BURST_FCCH 0x01
#define GSMTAP_BURST_PARTIAL_SCH 0x02
#define GSMTAP_BURST_SCH 0x03
#define GSMTAP_BURST_CTS_SCH 0x04
#define GSMTAP_BURST_COMPACT_SCH 0x05
#define GSMTAP_BURST_NORMAL 0x06
#define GSMTAP_BURST_DUMMY 0x07
#define GSMTAP_BURST_ACCESS 0x08
#define GSMTAP_BURST_NONE 0x09
#define GSMTAP_CHANNEL_UNKNOWN 0x00
#define GSMTAP_CHANNEL_BCCH 0x01
#define GSMTAP_CHANNEL_CCCH 0x02
#define GSMTAP_CHANNEL_RACH 0x03
#define GSMTAP_CHANNEL_AGCH 0x04
#define GSMTAP_CHANNEL_PCH 0x05
#define GSMTAP_CHANNEL_SDCCH 0x06
#define GSMTAP_CHANNEL_SDCCH4 0x07
#define GSMTAP_CHANNEL_SDCCH8 0x08
#define GSMTAP_CHANNEL_TCH_F 0x09
#define GSMTAP_CHANNEL_TCH_H 0x0a
#define GSMTAP_CHANNEL_ACCH 0x80
#define GSMTAP_ARFCN_F_PCS 0x8000
#define GSMTAP_ARFCN_F_UPLINK 0x4000
#define GSMTAP_ARFCN_MASK 0x3fff
#define GSMTAP_UDP_PORT 4729
struct gsmtap_hdr {
uint8_t version; /* version, set to 0x01 currently */
uint8_t hdr_len; /* length in number of 32bit words */
uint8_t type; /* see GSMTAP_TYPE_* */
uint8_t timeslot; /* timeslot (0..7 on Um) */
uint16_t arfcn; /* ARFCN (frequency) */
int8_t signal_dbm; /* signal level in dBm */
int8_t snr_db; /* signal/noise ratio in dB */
uint32_t frame_number; /* GSM Frame Number (FN) */
uint8_t sub_type; /* Type of burst/channel, see above */
uint8_t antenna_nr; /* Antenna Number */
uint8_t sub_slot; /* sub-slot within timeslot */
uint8_t res; /* reserved for future use (RFU) */
} __attribute__((packed));
#endif /* _GSMTAP_H */

View File

@@ -1,71 +0,0 @@
#ifndef _OSMOCORE_MNCC_H
#define _OSMOCORE_MNCC_H
#define GSM_MAX_FACILITY 128
#define GSM_MAX_SSVERSION 128
#define GSM_MAX_USERUSER 128
/* Expanded fields from GSM TS 04.08, Table 10.5.102 */
struct gsm_mncc_bearer_cap {
int transfer; /* Information Transfer Capability */
int mode; /* Transfer Mode */
int coding; /* Coding Standard */
int radio; /* Radio Channel Requirement */
int speech_ctm; /* CTM text telephony indication */
int speech_ver[8]; /* Speech version indication */
};
struct gsm_mncc_number {
int type;
int plan;
int present;
int screen;
char number[33];
};
struct gsm_mncc_cause {
int location;
int coding;
int rec;
int rec_val;
int value;
int diag_len;
char diag[32];
};
struct gsm_mncc_useruser {
int proto;
char info[GSM_MAX_USERUSER + 1]; /* + termination char */
};
struct gsm_mncc_progress {
int coding;
int location;
int descr;
};
struct gsm_mncc_facility {
int len;
char info[GSM_MAX_FACILITY];
};
struct gsm_mncc_ssversion {
int len;
char info[GSM_MAX_SSVERSION];
};
struct gsm_mncc_cccap {
int dtmf;
int pcp;
};
enum {
GSM_MNCC_BCAP_SPEECH = 0,
GSM_MNCC_BCAP_UNR_DIG = 1,
GSM_MNCC_BCAP_AUDIO = 2,
GSM_MNCC_BCAP_FAX_G3 = 3,
GSM_MNCC_BCAP_OTHER_ITC = 5,
GSM_MNCC_BCAP_RESERVED = 7,
};
#endif

View File

@@ -1,3 +0,0 @@
osmocore_proto_HEADERS = gsm_04_08.h gsm_04_11.h gsm_04_80.h gsm_08_58.h gsm_12_21.h
osmocore_protodir = $(includedir)/osmocore/protocol

View File

@@ -1,743 +0,0 @@
#ifndef PROTO_GSM_04_08_H
#define PROTO_GSM_04_08_H
#include <stdint.h>
/* GSM TS 04.08 definitions */
struct gsm_lchan;
struct gsm48_classmark1 {
uint8_t spare:1,
rev_level:2,
es_ind:1,
a5_1:1,
pwr_lev:3;
} __attribute__ ((packed));
/* Chapter 10.5.2.5 */
struct gsm48_chan_desc {
uint8_t chan_nr;
union {
struct {
uint8_t maio_high:4,
h:1,
tsc:3;
uint8_t hsn:6,
maio_low:2;
} h1;
struct {
uint8_t arfcn_high:2,
spare:2,
h:1,
tsc:3;
uint8_t arfcn_low;
} h0;
};
} __attribute__ ((packed));
/* Chapter 10.5.2.21aa */
struct gsm48_multi_rate_conf {
uint8_t smod : 2,
spare: 1,
icmi : 1,
nscb : 1,
ver : 3;
uint8_t m4_75 : 1,
m5_15 : 1,
m5_90 : 1,
m6_70 : 1,
m7_40 : 1,
m7_95 : 1,
m10_2 : 1,
m12_2 : 1;
} __attribute__((packed));
/* Chapter 10.5.2.30 */
struct gsm48_req_ref {
uint8_t ra;
uint8_t t3_high:3,
t1_:5;
uint8_t t2:5,
t3_low:3;
} __attribute__ ((packed));
/*
* Chapter 9.1.5/9.1.6
*
* For 9.1.6 the chan_desc has the meaning of 10.5.2.5a
*/
struct gsm48_chan_mode_modify {
struct gsm48_chan_desc chan_desc;
uint8_t mode;
} __attribute__ ((packed));
enum gsm48_chan_mode {
GSM48_CMODE_SIGN = 0x00,
GSM48_CMODE_SPEECH_V1 = 0x01,
GSM48_CMODE_SPEECH_EFR = 0x21,
GSM48_CMODE_SPEECH_AMR = 0x41,
GSM48_CMODE_DATA_14k5 = 0x0f,
GSM48_CMODE_DATA_12k0 = 0x03,
GSM48_CMODE_DATA_6k0 = 0x0b,
GSM48_CMODE_DATA_3k6 = 0x23,
};
/* Chapter 9.1.2 */
struct gsm48_ass_cmd {
/* Semantic is from 10.5.2.5a */
struct gsm48_chan_desc chan_desc;
uint8_t power_command;
uint8_t data[0];
} __attribute__((packed));
/* Chapter 10.5.2.2 */
struct gsm48_cell_desc {
uint8_t bcc:3,
ncc:3,
arfcn_hi:2;
uint8_t arfcn_lo;
} __attribute__((packed));
/* Chapter 9.1.15 */
struct gsm48_ho_cmd {
struct gsm48_cell_desc cell_desc;
struct gsm48_chan_desc chan_desc;
uint8_t ho_ref;
uint8_t power_command;
uint8_t data[0];
} __attribute__((packed));
/* Chapter 9.1.18 */
struct gsm48_imm_ass {
uint8_t l2_plen;
uint8_t proto_discr;
uint8_t msg_type;
uint8_t page_mode;
struct gsm48_chan_desc chan_desc;
struct gsm48_req_ref req_ref;
uint8_t timing_advance;
uint8_t mob_alloc_len;
uint8_t mob_alloc[0];
} __attribute__ ((packed));
/* Chapter 10.5.1.3 */
struct gsm48_loc_area_id {
uint8_t digits[3]; /* BCD! */
uint16_t lac;
} __attribute__ ((packed));
/* Section 9.2.2 */
struct gsm48_auth_req {
uint8_t key_seq:4,
spare:4;
uint8_t rand[16];
} __attribute__ ((packed));
/* Section 9.2.15 */
struct gsm48_loc_upd_req {
uint8_t type:4,
key_seq:4;
struct gsm48_loc_area_id lai;
struct gsm48_classmark1 classmark1;
uint8_t mi_len;
uint8_t mi[0];
} __attribute__ ((packed));
/* Section 10.1 */
struct gsm48_hdr {
uint8_t proto_discr;
uint8_t msg_type;
uint8_t data[0];
} __attribute__ ((packed));
/* Section 9.1.3x System information Type header */
struct gsm48_system_information_type_header {
uint8_t l2_plen;
uint8_t rr_protocol_discriminator :4,
skip_indicator:4;
uint8_t system_information;
} __attribute__ ((packed));
struct gsm48_rach_control {
uint8_t re :1,
cell_bar :1,
tx_integer :4,
max_trans :2;
uint8_t t2;
uint8_t t3;
} __attribute__ ((packed));
/* Section 10.5.2.4 Cell Selection Parameters */
struct gsm48_cell_sel_par {
uint8_t ms_txpwr_max_ccch:5, /* GSM 05.08 MS-TXPWR-MAX-CCCH */
cell_resel_hyst:3; /* GSM 05.08 CELL-RESELECT-HYSTERESIS */
uint8_t rxlev_acc_min:6, /* GSM 05.08 RXLEV-ACCESS-MIN */
neci:1,
acs:1;
} __attribute__ ((packed));
/* Section 10.5.2.11 Control Channel Description , Figure 10.5.33 */
struct gsm48_control_channel_descr {
uint8_t ccch_conf :3,
bs_ag_blks_res :3,
att :1,
spare1 :1;
uint8_t bs_pa_mfrms : 3,
spare2 :5;
uint8_t t3212;
} __attribute__ ((packed));
struct gsm48_cell_options {
uint8_t radio_link_timeout:4,
dtx:2,
pwrc:1,
spare:1;
} __attribute__ ((packed));
/* Section 9.2.9 CM service request */
struct gsm48_service_request {
uint8_t cm_service_type : 4,
cipher_key_seq : 4;
/* length + 3 bytes */
uint32_t classmark;
uint8_t mi_len;
uint8_t mi[0];
/* optional priority level */
} __attribute__ ((packed));
/* Section 9.1.31 System information Type 1 */
struct gsm48_system_information_type_1 {
struct gsm48_system_information_type_header header;
uint8_t cell_channel_description[16];
struct gsm48_rach_control rach_control;
uint8_t rest_octets[0]; /* NCH position on the CCCH */
} __attribute__ ((packed));
/* Section 9.1.32 System information Type 2 */
struct gsm48_system_information_type_2 {
struct gsm48_system_information_type_header header;
uint8_t bcch_frequency_list[16];
uint8_t ncc_permitted;
struct gsm48_rach_control rach_control;
} __attribute__ ((packed));
/* Section 9.1.35 System information Type 3 */
struct gsm48_system_information_type_3 {
struct gsm48_system_information_type_header header;
uint16_t cell_identity;
struct gsm48_loc_area_id lai;
struct gsm48_control_channel_descr control_channel_desc;
struct gsm48_cell_options cell_options;
struct gsm48_cell_sel_par cell_sel_par;
struct gsm48_rach_control rach_control;
uint8_t rest_octets[0];
} __attribute__ ((packed));
/* Section 9.1.36 System information Type 4 */
struct gsm48_system_information_type_4 {
struct gsm48_system_information_type_header header;
struct gsm48_loc_area_id lai;
struct gsm48_cell_sel_par cell_sel_par;
struct gsm48_rach_control rach_control;
/* optional CBCH conditional CBCH... followed by
mandantory SI 4 Reset Octets
*/
uint8_t data[0];
} __attribute__ ((packed));
/* Section 9.1.37 System information Type 5 */
struct gsm48_system_information_type_5 {
uint8_t rr_protocol_discriminator :4,
skip_indicator:4;
uint8_t system_information;
uint8_t bcch_frequency_list[16];
} __attribute__ ((packed));
/* Section 9.1.40 System information Type 6 */
struct gsm48_system_information_type_6 {
uint8_t rr_protocol_discriminator :4,
skip_indicator:4;
uint8_t system_information;
uint16_t cell_identity;
struct gsm48_loc_area_id lai;
struct gsm48_cell_options cell_options;
uint8_t ncc_permitted;
uint8_t rest_octets[0];
} __attribute__ ((packed));
/* Section 9.1.43a System Information type 13 */
struct gsm48_system_information_type_13 {
struct gsm48_system_information_type_header header;
uint8_t rest_octets[0];
} __attribute__ ((packed));
/* Section 9.2.12 IMSI Detach Indication */
struct gsm48_imsi_detach_ind {
struct gsm48_classmark1 classmark1;
uint8_t mi_len;
uint8_t mi[0];
} __attribute__ ((packed));
/* Section 10.2 + GSM 04.07 12.2.3.1.1 */
#define GSM48_PDISC_GROUP_CC 0x00
#define GSM48_PDISC_BCAST_CC 0x01
#define GSM48_PDISC_PDSS1 0x02
#define GSM48_PDISC_CC 0x03
#define GSM48_PDISC_PDSS2 0x04
#define GSM48_PDISC_MM 0x05
#define GSM48_PDISC_RR 0x06
#define GSM48_PDISC_MM_GPRS 0x08
#define GSM48_PDISC_SMS 0x09
#define GSM48_PDISC_SM_GPRS 0x0a
#define GSM48_PDISC_NC_SS 0x0b
#define GSM48_PDISC_LOC 0x0c
#define GSM48_PDISC_MASK 0x0f
#define GSM48_PDISC_USSD 0x11
/* Section 10.4 */
#define GSM48_MT_RR_INIT_REQ 0x3c
#define GSM48_MT_RR_ADD_ASS 0x3b
#define GSM48_MT_RR_IMM_ASS 0x3f
#define GSM48_MT_RR_IMM_ASS_EXT 0x39
#define GSM48_MT_RR_IMM_ASS_REJ 0x3a
#define GSM48_MT_RR_CIPH_M_CMD 0x35
#define GSM48_MT_RR_CIPH_M_COMPL 0x32
#define GSM48_MT_RR_CFG_CHG_CMD 0x30
#define GSM48_MT_RR_CFG_CHG_ACK 0x31
#define GSM48_MT_RR_CFG_CHG_REJ 0x33
#define GSM48_MT_RR_ASS_CMD 0x2e
#define GSM48_MT_RR_ASS_COMPL 0x29
#define GSM48_MT_RR_ASS_FAIL 0x2f
#define GSM48_MT_RR_HANDO_CMD 0x2b
#define GSM48_MT_RR_HANDO_COMPL 0x2c
#define GSM48_MT_RR_HANDO_FAIL 0x28
#define GSM48_MT_RR_HANDO_INFO 0x2d
#define GSM48_MT_RR_CELL_CHG_ORDER 0x08
#define GSM48_MT_RR_PDCH_ASS_CMD 0x23
#define GSM48_MT_RR_CHAN_REL 0x0d
#define GSM48_MT_RR_PART_REL 0x0a
#define GSM48_MT_RR_PART_REL_COMP 0x0f
#define GSM48_MT_RR_PAG_REQ_1 0x21
#define GSM48_MT_RR_PAG_REQ_2 0x22
#define GSM48_MT_RR_PAG_REQ_3 0x24
#define GSM48_MT_RR_PAG_RESP 0x27
#define GSM48_MT_RR_NOTIF_NCH 0x20
#define GSM48_MT_RR_NOTIF_FACCH 0x25
#define GSM48_MT_RR_NOTIF_RESP 0x26
#define GSM48_MT_RR_SYSINFO_8 0x18
#define GSM48_MT_RR_SYSINFO_1 0x19
#define GSM48_MT_RR_SYSINFO_2 0x1a
#define GSM48_MT_RR_SYSINFO_3 0x1b
#define GSM48_MT_RR_SYSINFO_4 0x1c
#define GSM48_MT_RR_SYSINFO_5 0x1d
#define GSM48_MT_RR_SYSINFO_6 0x1e
#define GSM48_MT_RR_SYSINFO_7 0x1f
#define GSM48_MT_RR_SYSINFO_2bis 0x02
#define GSM48_MT_RR_SYSINFO_2ter 0x03
#define GSM48_MT_RR_SYSINFO_5bis 0x05
#define GSM48_MT_RR_SYSINFO_5ter 0x06
#define GSM48_MT_RR_SYSINFO_9 0x04
#define GSM48_MT_RR_SYSINFO_13 0x00
#define GSM48_MT_RR_SYSINFO_16 0x3d
#define GSM48_MT_RR_SYSINFO_17 0x3e
#define GSM48_MT_RR_CHAN_MODE_MODIF 0x10
#define GSM48_MT_RR_STATUS 0x12
#define GSM48_MT_RR_CHAN_MODE_MODIF_ACK 0x17
#define GSM48_MT_RR_FREQ_REDEF 0x14
#define GSM48_MT_RR_MEAS_REP 0x15
#define GSM48_MT_RR_CLSM_CHG 0x16
#define GSM48_MT_RR_CLSM_ENQ 0x13
#define GSM48_MT_RR_EXT_MEAS_REP 0x36
#define GSM48_MT_RR_EXT_MEAS_REP_ORD 0x37
#define GSM48_MT_RR_GPRS_SUSP_REQ 0x34
#define GSM48_MT_RR_VGCS_UPL_GRANT 0x08
#define GSM48_MT_RR_UPLINK_RELEASE 0x0e
#define GSM48_MT_RR_UPLINK_FREE 0x0c
#define GSM48_MT_RR_UPLINK_BUSY 0x2a
#define GSM48_MT_RR_TALKER_IND 0x11
#define GSM48_MT_RR_APP_INFO 0x38
/* Table 10.2/3GPP TS 04.08 */
#define GSM48_MT_MM_IMSI_DETACH_IND 0x01
#define GSM48_MT_MM_LOC_UPD_ACCEPT 0x02
#define GSM48_MT_MM_LOC_UPD_REJECT 0x04
#define GSM48_MT_MM_LOC_UPD_REQUEST 0x08
#define GSM48_MT_MM_AUTH_REJ 0x11
#define GSM48_MT_MM_AUTH_REQ 0x12
#define GSM48_MT_MM_AUTH_RESP 0x14
#define GSM48_MT_MM_ID_REQ 0x18
#define GSM48_MT_MM_ID_RESP 0x19
#define GSM48_MT_MM_TMSI_REALL_CMD 0x1a
#define GSM48_MT_MM_TMSI_REALL_COMPL 0x1b
#define GSM48_MT_MM_CM_SERV_ACC 0x21
#define GSM48_MT_MM_CM_SERV_REJ 0x22
#define GSM48_MT_MM_CM_SERV_ABORT 0x23
#define GSM48_MT_MM_CM_SERV_REQ 0x24
#define GSM48_MT_MM_CM_SERV_PROMPT 0x25
#define GSM48_MT_MM_CM_REEST_REQ 0x28
#define GSM48_MT_MM_ABORT 0x29
#define GSM48_MT_MM_NULL 0x30
#define GSM48_MT_MM_STATUS 0x31
#define GSM48_MT_MM_INFO 0x32
/* Table 10.3/3GPP TS 04.08 */
#define GSM48_MT_CC_ALERTING 0x01
#define GSM48_MT_CC_CALL_CONF 0x08
#define GSM48_MT_CC_CALL_PROC 0x02
#define GSM48_MT_CC_CONNECT 0x07
#define GSM48_MT_CC_CONNECT_ACK 0x0f
#define GSM48_MT_CC_EMERG_SETUP 0x0e
#define GSM48_MT_CC_PROGRESS 0x03
#define GSM48_MT_CC_ESTAB 0x04
#define GSM48_MT_CC_ESTAB_CONF 0x06
#define GSM48_MT_CC_RECALL 0x0b
#define GSM48_MT_CC_START_CC 0x09
#define GSM48_MT_CC_SETUP 0x05
#define GSM48_MT_CC_MODIFY 0x17
#define GSM48_MT_CC_MODIFY_COMPL 0x1f
#define GSM48_MT_CC_MODIFY_REJECT 0x13
#define GSM48_MT_CC_USER_INFO 0x10
#define GSM48_MT_CC_HOLD 0x18
#define GSM48_MT_CC_HOLD_ACK 0x19
#define GSM48_MT_CC_HOLD_REJ 0x1a
#define GSM48_MT_CC_RETR 0x1c
#define GSM48_MT_CC_RETR_ACK 0x1d
#define GSM48_MT_CC_RETR_REJ 0x1e
#define GSM48_MT_CC_DISCONNECT 0x25
#define GSM48_MT_CC_RELEASE 0x2d
#define GSM48_MT_CC_RELEASE_COMPL 0x2a
#define GSM48_MT_CC_CONG_CTRL 0x39
#define GSM48_MT_CC_NOTIFY 0x3e
#define GSM48_MT_CC_STATUS 0x3d
#define GSM48_MT_CC_STATUS_ENQ 0x34
#define GSM48_MT_CC_START_DTMF 0x35
#define GSM48_MT_CC_STOP_DTMF 0x31
#define GSM48_MT_CC_STOP_DTMF_ACK 0x32
#define GSM48_MT_CC_START_DTMF_ACK 0x36
#define GSM48_MT_CC_START_DTMF_REJ 0x37
#define GSM48_MT_CC_FACILITY 0x3a
/* FIXME: Table 10.4 / 10.4a (GPRS) */
/* Section 10.5.2.26, Table 10.5.64 */
#define GSM48_PM_MASK 0x03
#define GSM48_PM_NORMAL 0x00
#define GSM48_PM_EXTENDED 0x01
#define GSM48_PM_REORG 0x02
#define GSM48_PM_SAME 0x03
/* Chapter 10.5.3.5 / Table 10.5.93 */
#define GSM48_LUPD_NORMAL 0x0
#define GSM48_LUPD_PERIODIC 0x1
#define GSM48_LUPD_IMSI_ATT 0x2
#define GSM48_LUPD_RESERVED 0x3
/* Table 10.5.4 */
#define GSM_MI_TYPE_MASK 0x07
#define GSM_MI_TYPE_NONE 0x00
#define GSM_MI_TYPE_IMSI 0x01
#define GSM_MI_TYPE_IMEI 0x02
#define GSM_MI_TYPE_IMEISV 0x03
#define GSM_MI_TYPE_TMSI 0x04
#define GSM_MI_ODD 0x08
#define GSM48_IE_MUL_RATE_CFG 0x03 /* 10.5.2.21aa */
#define GSM48_IE_MOBILE_ID 0x17
#define GSM48_IE_NAME_LONG 0x43 /* 10.5.3.5a */
#define GSM48_IE_NAME_SHORT 0x45 /* 10.5.3.5a */
#define GSM48_IE_UTC 0x46 /* 10.5.3.8 */
#define GSM48_IE_NET_TIME_TZ 0x47 /* 10.5.3.9 */
#define GSM48_IE_LSA_IDENT 0x48 /* 10.5.3.11 */
#define GSM48_IE_BEARER_CAP 0x04 /* 10.5.4.5 */
#define GSM48_IE_CAUSE 0x08 /* 10.5.4.11 */
#define GSM48_IE_CC_CAP 0x15 /* 10.5.4.5a */
#define GSM48_IE_ALERT 0x19 /* 10.5.4.26 */
#define GSM48_IE_FACILITY 0x1c /* 10.5.4.15 */
#define GSM48_IE_PROGR_IND 0x1e /* 10.5.4.21 */
#define GSM48_IE_AUX_STATUS 0x24 /* 10.5.4.4 */
#define GSM48_IE_NOTIFY 0x27 /* 10.5.4.20 */
#define GSM48_IE_KPD_FACILITY 0x2c /* 10.5.4.17 */
#define GSM48_IE_SIGNAL 0x34 /* 10.5.4.23 */
#define GSM48_IE_CONN_BCD 0x4c /* 10.5.4.13 */
#define GSM48_IE_CONN_SUB 0x4d /* 10.5.4.14 */
#define GSM48_IE_CALLING_BCD 0x5c /* 10.5.4.9 */
#define GSM48_IE_CALLING_SUB 0x5d /* 10.5.4.10 */
#define GSM48_IE_CALLED_BCD 0x5e /* 10.5.4.7 */
#define GSM48_IE_CALLED_SUB 0x6d /* 10.5.4.8 */
#define GSM48_IE_REDIR_BCD 0x74 /* 10.5.4.21a */
#define GSM48_IE_REDIR_SUB 0x75 /* 10.5.4.21b */
#define GSM48_IE_LOWL_COMPAT 0x7c /* 10.5.4.18 */
#define GSM48_IE_HIGHL_COMPAT 0x7d /* 10.5.4.16 */
#define GSM48_IE_USER_USER 0x7e /* 10.5.4.25 */
#define GSM48_IE_SS_VERS 0x7f /* 10.5.4.24 */
#define GSM48_IE_MORE_DATA 0xa0 /* 10.5.4.19 */
#define GSM48_IE_CLIR_SUPP 0xa1 /* 10.5.4.11a */
#define GSM48_IE_CLIR_INVOC 0xa2 /* 10.5.4.11b */
#define GSM48_IE_REV_C_SETUP 0xa3 /* 10.5.4.22a */
#define GSM48_IE_REPEAT_CIR 0xd1 /* 10.5.4.22 */
#define GSM48_IE_REPEAT_SEQ 0xd3 /* 10.5.4.22 */
/* Section 10.5.4.11 / Table 10.5.122 */
#define GSM48_CAUSE_CS_GSM 0x60
/* Section 9.1.2 / Table 9.3 */
#define GSM48_IE_FRQLIST_AFTER 0x05
#define GSM48_IE_CELL_CH_DESC 0x62
#define GSM48_IE_MSLOT_DESC 0x10
#define GSM48_IE_CHANMODE_1 0x63
#define GSM48_IE_CHANMODE_2 0x11
#define GSM48_IE_CHANMODE_3 0x13
#define GSM48_IE_CHANMODE_4 0x14
#define GSM48_IE_CHANMODE_5 0x15
#define GSM48_IE_CHANMODE_6 0x16
#define GSM48_IE_CHANMODE_7 0x17
#define GSM48_IE_CHANMODE_8 0x18
#define GSM48_IE_CHANDESC_2 0x64
/* FIXME */
/* Section 10.5.4.23 / Table 10.5.130 */
enum gsm48_signal_val {
GSM48_SIGNAL_DIALTONE = 0x00,
GSM48_SIGNAL_RINGBACK = 0x01,
GSM48_SIGNAL_INTERCEPT = 0x02,
GSM48_SIGNAL_NET_CONG = 0x03,
GSM48_SIGNAL_BUSY = 0x04,
GSM48_SIGNAL_CONFIRM = 0x05,
GSM48_SIGNAL_ANSWER = 0x06,
GSM48_SIGNAL_CALL_WAIT = 0x07,
GSM48_SIGNAL_OFF_HOOK = 0x08,
GSM48_SIGNAL_OFF = 0x3f,
GSM48_SIGNAL_ALERT_OFF = 0x4f,
};
enum gsm48_cause_loc {
GSM48_CAUSE_LOC_USER = 0x00,
GSM48_CAUSE_LOC_PRN_S_LU = 0x01,
GSM48_CAUSE_LOC_PUN_S_LU = 0x02,
GSM48_CAUSE_LOC_TRANS_NET = 0x03,
GSM48_CAUSE_LOC_PUN_S_RU = 0x04,
GSM48_CAUSE_LOC_PRN_S_RU = 0x05,
/* not defined */
GSM48_CAUSE_LOC_INN_NET = 0x07,
GSM48_CAUSE_LOC_NET_BEYOND = 0x0a,
};
/* Section 10.5.2.31 RR Cause / Table 10.5.70 */
enum gsm48_rr_cause {
GSM48_RR_CAUSE_NORMAL = 0x00,
GSM48_RR_CAUSE_ABNORMAL_UNSPEC = 0x01,
GSM48_RR_CAUSE_ABNORMAL_UNACCT = 0x02,
GSM48_RR_CAUSE_ABNORMAL_TIMER = 0x03,
GSM48_RR_CAUSE_ABNORMAL_NOACT = 0x04,
GSM48_RR_CAUSE_PREMPTIVE_REL = 0x05,
GSM48_RR_CAUSE_HNDOVER_IMP = 0x06,
GSM48_RR_CAUSE_CHAN_MODE_UNACCT = 0x07,
GSM48_RR_CAUSE_FREQ_NOT_IMPL = 0x08,
GSM48_RR_CAUSE_CALL_CLEARED = 0x41,
GSM48_RR_CAUSE_SEMANT_INCORR = 0x5f,
GSM48_RR_CAUSE_INVALID_MAND_INF = 0x60,
GSM48_RR_CAUSE_MSG_TYPE_N = 0x61,
GSM48_RR_CAUSE_MSG_TYPE_N_COMPAT= 0x62,
GSM48_RR_CAUSE_COND_IE_ERROR = 0x64,
GSM48_RR_CAUSE_NO_CELL_ALLOC_A = 0x65,
GSM48_RR_CAUSE_PROT_ERROR_UNSPC = 0x6f,
};
/* Section 10.5.4.11 CC Cause / Table 10.5.123 */
enum gsm48_cc_cause {
GSM48_CC_CAUSE_UNASSIGNED_NR = 1,
GSM48_CC_CAUSE_NO_ROUTE = 3,
GSM48_CC_CAUSE_CHAN_UNACCEPT = 6,
GSM48_CC_CAUSE_OP_DET_BARRING = 8,
GSM48_CC_CAUSE_NORM_CALL_CLEAR = 16,
GSM48_CC_CAUSE_USER_BUSY = 17,
GSM48_CC_CAUSE_USER_NOTRESPOND = 18,
GSM48_CC_CAUSE_USER_ALERTING_NA = 19,
GSM48_CC_CAUSE_CALL_REJECTED = 21,
GSM48_CC_CAUSE_NUMBER_CHANGED = 22,
GSM48_CC_CAUSE_PRE_EMPTION = 25,
GSM48_CC_CAUSE_NONSE_USER_CLR = 26,
GSM48_CC_CAUSE_DEST_OOO = 27,
GSM48_CC_CAUSE_INV_NR_FORMAT = 28,
GSM48_CC_CAUSE_FACILITY_REJ = 29,
GSM48_CC_CAUSE_RESP_STATUS_INQ = 30,
GSM48_CC_CAUSE_NORMAL_UNSPEC = 31,
GSM48_CC_CAUSE_NO_CIRCUIT_CHAN = 34,
GSM48_CC_CAUSE_NETWORK_OOO = 38,
GSM48_CC_CAUSE_TEMP_FAILURE = 41,
GSM48_CC_CAUSE_SWITCH_CONG = 42,
GSM48_CC_CAUSE_ACC_INF_DISCARD = 43,
GSM48_CC_CAUSE_REQ_CHAN_UNAVAIL = 44,
GSM48_CC_CAUSE_RESOURCE_UNAVAIL = 47,
GSM48_CC_CAUSE_QOS_UNAVAIL = 49,
GSM48_CC_CAUSE_REQ_FAC_NOT_SUBSC= 50,
GSM48_CC_CAUSE_INC_BARRED_CUG = 55,
GSM48_CC_CAUSE_BEARER_CAP_UNAUTH= 57,
GSM48_CC_CAUSE_BEARER_CA_UNAVAIL= 58,
GSM48_CC_CAUSE_SERV_OPT_UNAVAIL = 63,
GSM48_CC_CAUSE_BEARERSERV_UNIMPL= 65,
GSM48_CC_CAUSE_ACM_GE_ACM_MAX = 68,
GSM48_CC_CAUSE_REQ_FAC_NOTIMPL = 69,
GSM48_CC_CAUSE_RESTR_BCAP_AVAIL = 70,
GSM48_CC_CAUSE_SERV_OPT_UNIMPL = 79,
GSM48_CC_CAUSE_INVAL_TRANS_ID = 81,
GSM48_CC_CAUSE_USER_NOT_IN_CUG = 87,
GSM48_CC_CAUSE_INCOMPAT_DEST = 88,
GSM48_CC_CAUSE_INVAL_TRANS_NET = 91,
GSM48_CC_CAUSE_SEMANTIC_INCORR = 95,
GSM48_CC_CAUSE_INVAL_MAND_INF = 96,
GSM48_CC_CAUSE_MSGTYPE_NOTEXIST = 97,
GSM48_CC_CAUSE_MSGTYPE_INCOMPAT = 98,
GSM48_CC_CAUSE_IE_NOTEXIST = 99,
GSM48_CC_CAUSE_COND_IE_ERR = 100,
GSM48_CC_CAUSE_MSG_INCOMP_STATE = 101,
GSM48_CC_CAUSE_RECOVERY_TIMER = 102,
GSM48_CC_CAUSE_PROTO_ERR = 111,
GSM48_CC_CAUSE_INTERWORKING = 127,
};
/* Annex G, GSM specific cause values for mobility management */
enum gsm48_reject_value {
GSM48_REJECT_IMSI_UNKNOWN_IN_HLR = 2,
GSM48_REJECT_ILLEGAL_MS = 3,
GSM48_REJECT_IMSI_UNKNOWN_IN_VLR = 4,
GSM48_REJECT_IMEI_NOT_ACCEPTED = 5,
GSM48_REJECT_ILLEGAL_ME = 6,
GSM48_REJECT_PLMN_NOT_ALLOWED = 11,
GSM48_REJECT_LOC_NOT_ALLOWED = 12,
GSM48_REJECT_ROAMING_NOT_ALLOWED = 13,
GSM48_REJECT_NETWORK_FAILURE = 17,
GSM48_REJECT_CONGESTION = 22,
GSM48_REJECT_SRV_OPT_NOT_SUPPORTED = 32,
GSM48_REJECT_RQD_SRV_OPT_NOT_SUPPORTED = 33,
GSM48_REJECT_SRV_OPT_TMP_OUT_OF_ORDER = 34,
GSM48_REJECT_CALL_CAN_NOT_BE_IDENTIFIED = 38,
GSM48_REJECT_INCORRECT_MESSAGE = 95,
GSM48_REJECT_INVALID_MANDANTORY_INF = 96,
GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED = 97,
GSM48_REJECT_MSG_TYPE_NOT_COMPATIBLE = 98,
GSM48_REJECT_INF_ELEME_NOT_IMPLEMENTED = 99,
GSM48_REJECT_CONDTIONAL_IE_ERROR = 100,
GSM48_REJECT_MSG_NOT_COMPATIBLE = 101,
GSM48_REJECT_PROTOCOL_ERROR = 111,
/* according to G.6 Additional cause codes for GMM */
GSM48_REJECT_GPRS_NOT_ALLOWED = 7,
GSM48_REJECT_SERVICES_NOT_ALLOWED = 8,
GSM48_REJECT_MS_IDENTITY_NOT_DERVIVABLE = 9,
GSM48_REJECT_IMPLICITLY_DETACHED = 10,
GSM48_REJECT_GPRS_NOT_ALLOWED_IN_PLMN = 14,
GSM48_REJECT_MSC_TMP_NOT_REACHABLE = 16,
};
enum chreq_type {
CHREQ_T_EMERG_CALL,
CHREQ_T_CALL_REEST_TCH_F,
CHREQ_T_CALL_REEST_TCH_H,
CHREQ_T_CALL_REEST_TCH_H_DBL,
CHREQ_T_SDCCH,
CHREQ_T_TCH_F,
CHREQ_T_VOICE_CALL_TCH_H,
CHREQ_T_DATA_CALL_TCH_H,
CHREQ_T_LOCATION_UPD,
CHREQ_T_PAG_R_ANY_NECI0,
CHREQ_T_PAG_R_ANY_NECI1,
CHREQ_T_PAG_R_TCH_F,
CHREQ_T_PAG_R_TCH_FH,
CHREQ_T_LMU,
CHREQ_T_RESERVED_SDCCH,
CHREQ_T_RESERVED_IGNORE,
};
/* Chapter 11.3 */
#define GSM48_T301 180, 0
#define GSM48_T303 30, 0
#define GSM48_T305 30, 0
#define GSM48_T306 30, 0
#define GSM48_T308 10, 0
#define GSM48_T310 180, 0
#define GSM48_T313 30, 0
#define GSM48_T323 30, 0
#define GSM48_T331 30, 0
#define GSM48_T333 30, 0
#define GSM48_T334 25, 0 /* min 15 */
#define GSM48_T338 30, 0
/* Chapter 5.1.2.2 */
#define GSM_CSTATE_NULL 0
#define GSM_CSTATE_INITIATED 1
#define GSM_CSTATE_MO_CALL_PROC 3
#define GSM_CSTATE_CALL_DELIVERED 4
#define GSM_CSTATE_CALL_PRESENT 6
#define GSM_CSTATE_CALL_RECEIVED 7
#define GSM_CSTATE_CONNECT_REQUEST 8
#define GSM_CSTATE_MO_TERM_CALL_CONF 9
#define GSM_CSTATE_ACTIVE 10
#define GSM_CSTATE_DISCONNECT_REQ 12
#define GSM_CSTATE_DISCONNECT_IND 12
#define GSM_CSTATE_RELEASE_REQ 19
#define GSM_CSTATE_MO_ORIG_MODIFY 26
#define GSM_CSTATE_MO_TERM_MODIFY 27
#define GSM_CSTATE_CONNECT_IND 28
#define SBIT(a) (1 << a)
#define ALL_STATES 0xffffffff
/* Table 10.5.3/3GPP TS 04.08: Location Area Identification information element */
#define GSM_LAC_RESERVED_DETACHED 0x0
#define GSM_LAC_RESERVED_ALL_BTS 0xfffe
/* GSM 04.08 Bearer Capability: Information Transfer Capability */
enum gsm48_bcap_itcap {
GSM48_BCAP_ITCAP_SPEECH = 0,
GSM48_BCAP_ITCAP_UNR_DIG_INF = 1,
GSM48_BCAP_ITCAP_3k1_AUDIO = 2,
GSM48_BCAP_ITCAP_FAX_G3 = 3,
GSM48_BCAP_ITCAP_OTHER = 5,
GSM48_BCAP_ITCAP_RESERVED = 7,
};
/* GSM 04.08 Bearer Capability: Transfer Mode */
enum gsm48_bcap_tmod {
GSM48_BCAP_TMOD_CIRCUIT = 0,
GSM48_BCAP_TMOD_PACKET = 1,
};
/* GSM 04.08 Bearer Capability: Coding Standard */
enum gsm48_bcap_coding {
GSM48_BCAP_CODING_GSM_STD = 0,
};
/* GSM 04.08 Bearer Capability: Radio Channel Requirements */
enum gsm48_bcap_rrq {
GSM48_BCAP_RRQ_FR_ONLY = 1,
GSM48_BCAP_RRQ_DUAL_HR = 2,
GSM48_BCAP_RRQ_DUAL_FR = 3,
};
#define GSM48_TMSI_LEN 5
#define GSM48_MID_TMSI_LEN (GSM48_TMSI_LEN + 2)
#define GSM48_MI_SIZE 32
#endif /* PROTO_GSM_04_08_H */

View File

@@ -1,188 +0,0 @@
#ifndef PROTO_GSM_04_11_H
#define PROTO_GSM_04_11_H
#include <stdint.h>
/* GSM TS 04.11 definitions */
/* Chapter 5.2.3: SMC-CS states at the network side */
enum gsm411_cp_state {
GSM411_CPS_IDLE = 0,
GSM411_CPS_MM_CONN_PENDING = 1, /* only MT ! */
GSM411_CPS_WAIT_CP_ACK = 2,
GSM411_CPS_MM_ESTABLISHED = 3,
};
/* Chapter 6.2.2: SMR states at the network side */
enum gsm411_rp_state {
GSM411_RPS_IDLE = 0,
GSM411_RPS_WAIT_FOR_RP_ACK = 1,
GSM411_RPS_WAIT_TO_TX_RP_ACK = 3,
};
/* Chapter 8.1.2 (refers to GSM 04.07 Chapter 11.2.3.1.1 */
#define GSM411_PDISC_SMS 0x09
/* Chapter 8.1.3 */
#define GSM411_MT_CP_DATA 0x01
#define GSM411_MT_CP_ACK 0x04
#define GSM411_MT_CP_ERROR 0x10
enum gsm411_cp_ie {
GSM411_CP_IE_USER_DATA = 0x01, /* 8.1.4.1 */
GSM411_CP_IE_CAUSE = 0x02, /* 8.1.4.2. */
};
/* Section 8.1.4.2 / Table 8.2 */
enum gsm411_cp_cause {
GSM411_CP_CAUSE_NET_FAIL = 17,
GSM411_CP_CAUSE_CONGESTION = 22,
GSM411_CP_CAUSE_INV_TRANS_ID = 81,
GSM411_CP_CAUSE_SEMANT_INC_MSG = 95,
GSM411_CP_CAUSE_INV_MAND_INF = 96,
GSM411_CP_CAUSE_MSGTYPE_NOTEXIST= 97,
GSM411_CP_CAUSE_MSG_INCOMP_STATE= 98,
GSM411_CP_CAUSE_IE_NOTEXIST = 99,
GSM411_CP_CAUSE_PROTOCOL_ERR = 111,
};
/* Chapter 8.2.2 */
#define GSM411_MT_RP_DATA_MO 0x00
#define GSM411_MT_RP_DATA_MT 0x01
#define GSM411_MT_RP_ACK_MO 0x02
#define GSM411_MT_RP_ACK_MT 0x03
#define GSM411_MT_RP_ERROR_MO 0x04
#define GSM411_MT_RP_ERROR_MT 0x05
#define GSM411_MT_RP_SMMA_MO 0x06
enum gsm411_rp_ie {
GSM411_IE_RP_USER_DATA = 0x41, /* 8.2.5.3 */
GSM411_IE_RP_CAUSE = 0x42, /* 8.2.5.4 */
};
/* Chapter 8.2.5.4 Table 8.4 */
enum gsm411_rp_cause {
/* valid only for MO */
GSM411_RP_CAUSE_MO_NUM_UNASSIGNED = 1,
GSM411_RP_CAUSE_MO_OP_DET_BARR = 8,
GSM411_RP_CAUSE_MO_CALL_BARRED = 10,
GSM411_RP_CAUSE_MO_SMS_REJECTED = 21,
GSM411_RP_CAUSE_MO_DEST_OUT_OF_ORDER = 27,
GSM411_RP_CAUSE_MO_UNIDENTIFIED_SUBSCR = 28,
GSM411_RP_CAUSE_MO_FACILITY_REJ = 29,
GSM411_RP_CAUSE_MO_UNKNOWN_SUBSCR = 30,
GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER = 38,
GSM411_RP_CAUSE_MO_TEMP_FAIL = 41,
GSM411_RP_CAUSE_MO_CONGESTION = 42,
GSM411_RP_CAUSE_MO_RES_UNAVAIL = 47,
GSM411_RP_CAUSE_MO_REQ_FAC_NOTSUBSCR = 50,
GSM411_RP_CAUSE_MO_REQ_FAC_NOTIMPL = 69,
GSM411_RP_CAUSE_MO_INTERWORKING = 127,
/* valid only for MT */
GSM411_RP_CAUSE_MT_MEM_EXCEEDED = 22,
/* valid for both directions */
GSM411_RP_CAUSE_INV_TRANS_REF = 81,
GSM411_RP_CAUSE_SEMANT_INC_MSG = 95,
GSM411_RP_CAUSE_INV_MAND_INF = 96,
GSM411_RP_CAUSE_MSGTYPE_NOTEXIST = 97,
GSM411_RP_CAUSE_MSG_INCOMP_STATE = 98,
GSM411_RP_CAUSE_IE_NOTEXIST = 99,
GSM411_RP_CAUSE_PROTOCOL_ERR = 111,
};
/* Chapter 10: Timers */
#define GSM411_TMR_TR1M 40, 0 /* 35 < x < 45 seconds */
#define GSM411_TMR_TRAM 30, 0 /* 25 < x < 35 seconds */
#define GSM411_TMR_TR2M 15, 0 /* 12 < x < 20 seconds */
#define GSM411_TMR_TC1A 30, 0
/* Chapter 8.2.1 */
struct gsm411_rp_hdr {
uint8_t len;
uint8_t msg_type;
uint8_t msg_ref;
uint8_t data[0];
} __attribute__ ((packed));
/* our own enum, not related to on-air protocol */
enum sms_alphabet {
DCS_NONE,
DCS_7BIT_DEFAULT,
DCS_UCS2,
DCS_8BIT_DATA,
};
/* GSM 03.40 / Chapter 9.2.3.1: TP-Message-Type-Indicator */
#define GSM340_SMS_DELIVER_SC2MS 0x00
#define GSM340_SMS_DELIVER_REP_MS2SC 0x00
#define GSM340_SMS_STATUS_REP_SC2MS 0x02
#define GSM340_SMS_COMMAND_MS2SC 0x02
#define GSM340_SMS_SUBMIT_MS2SC 0x01
#define GSM340_SMS_SUBMIT_REP_SC2MS 0x01
#define GSM340_SMS_RESSERVED 0x03
/* GSM 03.40 / Chapter 9.2.3.2: TP-More-Messages-to-Send */
#define GSM340_TP_MMS_MORE 0
#define GSM340_TP_MMS_NO_MORE 1
/* GSM 03.40 / Chapter 9.2.3.3: TP-Validity-Period-Format */
#define GSM340_TP_VPF_NONE 0
#define GSM340_TP_VPF_RELATIVE 2
#define GSM340_TP_VPF_ENHANCED 1
#define GSM340_TP_VPF_ABSOLUTE 3
/* GSM 03.40 / Chapter 9.2.3.4: TP-Status-Report-Indication */
#define GSM340_TP_SRI_NONE 0
#define GSM340_TP_SRI_PRESENT 1
/* GSM 03.40 / Chapter 9.2.3.5: TP-Status-Report-Request */
#define GSM340_TP_SRR_NONE 0
#define GSM340_TP_SRR_REQUESTED 1
/* GSM 03.40 / Chapter 9.2.3.9: TP-Protocol-Identifier */
/* telematic interworking (001 or 111 in bits 7-5) */
#define GSM340_TP_PID_IMPLICIT 0x00
#define GSM340_TP_PID_TELEX 0x01
#define GSM340_TP_PID_FAX_G3 0x02
#define GSM340_TP_PID_FAX_G4 0x03
#define GSM340_TP_PID_VOICE 0x04
#define GSM430_TP_PID_ERMES 0x05
#define GSM430_TP_PID_NATIONAL_PAGING 0x06
#define GSM430_TP_PID_VIDEOTEX 0x07
#define GSM430_TP_PID_TELETEX_UNSPEC 0x08
#define GSM430_TP_PID_TELETEX_PSPDN 0x09
#define GSM430_TP_PID_TELETEX_CSPDN 0x0a
#define GSM430_TP_PID_TELETEX_PSTN 0x0b
#define GSM430_TP_PID_TELETEX_ISDN 0x0c
#define GSM430_TP_PID_TELETEX_UCI 0x0d
#define GSM430_TP_PID_MSG_HANDLING 0x10
#define GSM430_TP_PID_MSG_X400 0x11
#define GSM430_TP_PID_EMAIL 0x12
#define GSM430_TP_PID_GSM_MS 0x1f
/* if bit 7 = 0 and bit 6 = 1 */
#define GSM430_TP_PID_SMS_TYPE_0 0
#define GSM430_TP_PID_SMS_TYPE_1 1
#define GSM430_TP_PID_SMS_TYPE_2 2
#define GSM430_TP_PID_SMS_TYPE_3 3
#define GSM430_TP_PID_SMS_TYPE_4 4
#define GSM430_TP_PID_SMS_TYPE_5 5
#define GSM430_TP_PID_SMS_TYPE_6 6
#define GSM430_TP_PID_SMS_TYPE_7 7
#define GSM430_TP_PID_RETURN_CALL_MSG 0x1f
#define GSM430_TP_PID_ME_DATA_DNLOAD 0x3d
#define GSM430_TP_PID_ME_DE_PERSONAL 0x3e
#define GSM430_TP_PID_ME_SIM_DNLOAD 0x3f
/* GSM 03.38 Chapter 4: SMS Data Coding Scheme */
#define GSM338_DCS_00_
#define GSM338_DCS_1110_7BIT (0 << 2)
#define GSM338_DCS_1111_7BIT (0 << 2)
#define GSM338_DCS_1111_8BIT_DATA (1 << 2)
#define GSM338_DCS_1111_CLASS0 0
#define GSM338_DCS_1111_CLASS1_ME 1
#define GSM338_DCS_1111_CLASS2_SIM 2
#define GSM338_DCS_1111_CLASS3_TE 3 /* See TS 07.05 */
#endif /* PROTO_GSM_04_11_H */

View File

@@ -1,126 +0,0 @@
#ifndef PROTO_GSM_04_80_H
#define PROTO_GSM_04_80_H
/* GSM TS 04.80 definitions (Supplementary Services Specification, Formats and Coding) */
/* Section 3.4 */
#define GSM0480_MTYPE_RELEASE_COMPLETE 0x2A
#define GSM0480_MTYPE_FACILITY 0x3A
#define GSM0480_MTYPE_REGISTER 0x3B
/* Section 3.5 */
#define GSM0480_IE_FACILITY 0x1C
#define GSM0480_IE_SS_VERSION 0x7F
/* Section 3.6.2 */
#define GSM0480_CTYPE_INVOKE 0xA1
#define GSM0480_CTYPE_RETURN_RESULT 0xA2
#define GSM0480_CTYPE_RETURN_ERROR 0xA3
#define GSM0480_CTYPE_REJECT 0xA4
/* Section 3.6.3 */
#define GSM0480_COMPIDTAG_INVOKE_ID 0x02
#define GSM0480_COMPIDTAG_LINKED_ID 0x80
/* Section 3.6.4 */
#define GSM0480_OPERATION_CODE 0x02
/* Section 3.6.5 */
#define GSM_0480_SEQUENCE_TAG 0x30
#define GSM_0480_SET_TAG 0x31
/* Section 3.6.6 */
#define GSM_0480_ERROR_CODE_TAG 0x02
/* Section 3.6.7 */
/* Table 3.13 */
#define GSM_0480_PROBLEM_CODE_TAG_GENERAL 0x80
#define GSM_0480_PROBLEM_CODE_TAG_INVOKE 0x81
#define GSM_0480_PROBLEM_CODE_TAG_RETURN_RESULT 0x82
#define GSM_0480_PROBLEM_CODE_TAG_RETURN_ERROR 0x83
/* Table 3.14 */
#define GSM_0480_GEN_PROB_CODE_UNRECOGNISED 0x00
#define GSM_0480_GEN_PROB_CODE_MISTYPED 0x01
#define GSM_0480_GEN_PROB_CODE_BAD_STRUCTURE 0x02
/* Table 3.15 */
#define GSM_0480_INVOKE_PROB_CODE_DUPLICATE_INVOKE_ID 0x00
#define GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_OPERATION 0x01
#define GSM_0480_INVOKE_PROB_CODE_MISTYPED_PARAMETER 0x02
#define GSM_0480_INVOKE_PROB_CODE_RESOURCE_LIMITATION 0x03
#define GSM_0480_INVOKE_PROB_CODE_INITIATING_RELEASE 0x04
#define GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_LINKED_ID 0x05
#define GSM_0480_INVOKE_PROB_CODE_UNEXPECTED_LINKED_RESPONSE 0x06
#define GSM_0480_INVOKE_PROB_CODE_UNEXPECTED_LINKED_OPERATION 0x07
/* Table 3.16 */
#define GSM_0480_RESULT_PROB_CODE_UNRECOGNISED_INVOKE_ID 0x00
#define GSM_0480_RESULT_PROB_CODE_RETURN_RESULT_UNEXPECTED 0x01
#define GSM_0480_RESULT_PROB_CODE_MISTYPED_PARAMETER 0x02
/* Table 3.17 */
#define GSM_0480_ERROR_PROB_CODE_UNRECOGNISED_INVOKE_ID 0x00
#define GSM_0480_ERROR_PROB_CODE_RETURN_ERROR_UNEXPECTED 0x01
#define GSM_0480_ERROR_PROB_CODE_UNRECOGNISED_ERROR 0x02
#define GSM_0480_ERROR_PROB_CODE_UNEXPECTED_ERROR 0x03
#define GSM_0480_ERROR_PROB_CODE_MISTYPED_PARAMETER 0x04
/* Section 4.5 */
#define GSM0480_OP_CODE_REGISTER_SS 0x0A
#define GSM0480_OP_CODE_ERASE_SS 0x0B
#define GSM0480_OP_CODE_ACTIVATE_SS 0x0C
#define GSM0480_OP_CODE_DEACTIVATE_SS 0x0D
#define GSM0480_OP_CODE_INTERROGATE_SS 0x0E
#define GSM0480_OP_CODE_NOTIFY_SS 0x10
#define GSM0480_OP_CODE_REGISTER_PASSWORD 0x11
#define GSM0480_OP_CODE_GET_PASSWORD 0x12
#define GSM0480_OP_CODE_PROCESS_USS_DATA 0x13
#define GSM0480_OP_CODE_FORWARD_CHECK_SS_IND 0x26
#define GSM0480_OP_CODE_PROCESS_USS_REQ 0x3B
#define GSM0480_OP_CODE_USS_REQUEST 0x3C
#define GSM0480_OP_CODE_USS_NOTIFY 0x3D
#define GSM0480_OP_CODE_FORWARD_CUG_INFO 0x78
#define GSM0480_OP_CODE_SPLIT_MPTY 0x79
#define GSM0480_OP_CODE_RETRIEVE_MPTY 0x7A
#define GSM0480_OP_CODE_HOLD_MPTY 0x7B
#define GSM0480_OP_CODE_BUILD_MPTY 0x7C
#define GSM0480_OP_CODE_FORWARD_CHARGE_ADVICE 0x7D
#define GSM0480_ERR_CODE_UNKNOWN_SUBSCRIBER 0x01
#define GSM0480_ERR_CODE_ILLEGAL_SUBSCRIBER 0x09
#define GSM0480_ERR_CODE_BEARER_SERVICE_NOT_PROVISIONED 0x0A
#define GSM0480_ERR_CODE_TELESERVICE_NOT_PROVISIONED 0x0B
#define GSM0480_ERR_CODE_ILLEGAL_EQUIPMENT 0x0C
#define GSM0480_ERR_CODE_CALL_BARRED 0x0D
#define GSM0480_ERR_CODE_ILLEGAL_SS_OPERATION 0x10
#define GSM0480_ERR_CODE_SS_ERROR_STATUS 0x11
#define GSM0480_ERR_CODE_SS_NOT_AVAILABLE 0x12
#define GSM0480_ERR_CODE_SS_SUBSCRIPTION_VIOLATION 0x13
#define GSM0480_ERR_CODE_SS_INCOMPATIBILITY 0x14
#define GSM0480_ERR_CODE_FACILITY_NOT_SUPPORTED 0x15
#define GSM0480_ERR_CODE_ABSENT_SUBSCRIBER 0x1B
#define GSM0480_ERR_CODE_SYSTEM_FAILURE 0x22
#define GSM0480_ERR_CODE_DATA_MISSING 0x23
#define GSM0480_ERR_CODE_UNEXPECTED_DATA_VALUE 0x24
#define GSM0480_ERR_CODE_PW_REGISTRATION_FAILURE 0x25
#define GSM0480_ERR_CODE_NEGATIVE_PW_CHECK 0x26
#define GSM0480_ERR_CODE_NUM_PW_ATTEMPTS_VIOLATION 0x2B
#define GSM0480_ERR_CODE_UNKNOWN_ALPHABET 0x47
#define GSM0480_ERR_CODE_USSD_BUSY 0x48
#define GSM0480_ERR_CODE_MAX_MPTY_PARTICIPANTS 0x7E
#define GSM0480_ERR_CODE_RESOURCES_NOT_AVAILABLE 0x7F
/* ASN.1 type-tags */
#define ASN1_BOOLEAN_TAG 0x01
#define ASN1_INTEGER_TAG 0x02
#define ASN1_BIT_STRING_TAG 0x03
#define ASN1_OCTET_STRING_TAG 0x04
#define ASN1_NULL_TYPE_TAG 0x05
#define ASN1_OBJECT_ID_TAG 0x06
#define ASN1_UTF8_STRING_TAG 0x0C
#define ASN1_PRINTABLE_STRING_TAG 0x13
#define ASN1_IA5_STRING_TAG 0x16
#define ASN1_UNICODE_STRING_TAG 0x1E
#endif /* PROTO_GSM_04_80_H */

View File

@@ -1,512 +0,0 @@
#ifndef PROTO_GSM_08_58_H
#define PROTO_GSM_08_58_H
/* GSM Radio Signalling Link messages on the A-bis interface
* 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
/* (C) 2008 by Harald Welte <laforge@gnumonks.org>
* 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 2 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include <stdint.h>
struct abis_rsl_common_hdr {
uint8_t msg_discr;
uint8_t msg_type;
uint8_t data[0];
} __attribute__ ((packed));
/* Chapter 8.3 */
struct abis_rsl_rll_hdr {
struct abis_rsl_common_hdr c;
uint8_t ie_chan;
uint8_t chan_nr;
uint8_t ie_link_id;
uint8_t link_id;
uint8_t data[0];
} __attribute__ ((packed));
/* Chapter 8.3 and 8.4 */
struct abis_rsl_dchan_hdr {
struct abis_rsl_common_hdr c;
uint8_t ie_chan;
uint8_t chan_nr;
uint8_t data[0];
} __attribute__ ((packed));
/* Chapter 9.1 */
#define ABIS_RSL_MDISC_RLL 0x02
#define ABIS_RSL_MDISC_DED_CHAN 0x08
#define ABIS_RSL_MDISC_COM_CHAN 0x0c
#define ABIS_RSL_MDISC_TRX 0x10
#define ABIS_RSL_MDISC_LOC 0x20
#define ABIS_RSL_MDISC_IPACCESS 0x7e
#define ABIS_RSL_MDISC_TRANSP 0x01
#define ABIS_RSL_MDISC_IS_TRANSP(x) (x & 0x01)
/* Chapter 9.1 */
enum abis_rsl_msgtype {
/* Radio Link Layer Management */
RSL_MT_DATA_REQ = 0x01,
RSL_MT_DATA_IND,
RSL_MT_ERROR_IND,
RSL_MT_EST_REQ,
RSL_MT_EST_CONF,
RSL_MT_EST_IND,
RSL_MT_REL_REQ,
RSL_MT_REL_CONF,
RSL_MT_REL_IND,
RSL_MT_UNIT_DATA_REQ,
RSL_MT_UNIT_DATA_IND, /* 0x0b */
/* Common Channel Management / TRX Management */
RSL_MT_BCCH_INFO = 0x11,
RSL_MT_CCCH_LOAD_IND,
RSL_MT_CHAN_RQD,
RSL_MT_DELETE_IND,
RSL_MT_PAGING_CMD,
RSL_MT_IMMEDIATE_ASSIGN_CMD,
RSL_MT_SMS_BC_REQ,
/* empty */
RSL_MT_RF_RES_IND = 0x19,
RSL_MT_SACCH_FILL,
RSL_MT_OVERLOAD,
RSL_MT_ERROR_REPORT,
RSL_MT_SMS_BC_CMD,
RSL_MT_CBCH_LOAD_IND,
RSL_MT_NOT_CMD, /* 0x1f */
/* Dedicate Channel Management */
RSL_MT_CHAN_ACTIV = 0x21,
RSL_MT_CHAN_ACTIV_ACK,
RSL_MT_CHAN_ACTIV_NACK,
RSL_MT_CONN_FAIL,
RSL_MT_DEACTIVATE_SACCH,
RSL_MT_ENCR_CMD,
RSL_MT_HANDO_DET,
RSL_MT_MEAS_RES,
RSL_MT_MODE_MODIFY_REQ,
RSL_MT_MODE_MODIFY_ACK,
RSL_MT_MODE_MODIFY_NACK,
RSL_MT_PHY_CONTEXT_REQ,
RSL_MT_PHY_CONTEXT_CONF,
RSL_MT_RF_CHAN_REL,
RSL_MT_MS_POWER_CONTROL,
RSL_MT_BS_POWER_CONTROL, /* 0x30 */
RSL_MT_PREPROC_CONFIG,
RSL_MT_PREPROC_MEAS_RES,
RSL_MT_RF_CHAN_REL_ACK,
RSL_MT_SACCH_INFO_MODIFY,
RSL_MT_TALKER_DET,
RSL_MT_LISTENER_DET,
RSL_MT_REMOTE_CODEC_CONF_REP,
RSL_MT_RTD_REP,
RSL_MT_PRE_HANDO_NOTIF,
RSL_MT_MR_CODEC_MOD_REQ,
RSL_MT_MR_CODEC_MOD_ACK,
RSL_MT_MR_CODEC_MOD_NACK,
RSL_MT_MR_CODEC_MOD_PER,
RSL_MT_TFO_REP,
RSL_MT_TFO_MOD_REQ, /* 0x3f */
RSL_MT_LOCATION_INFO = 0x41,
/* ip.access specific RSL message types */
RSL_MT_IPAC_DIR_RETR_ENQ = 0x40,
RSL_MT_IPAC_PDCH_ACT = 0x48,
RSL_MT_IPAC_PDCH_ACT_ACK,
RSL_MT_IPAC_PDCH_ACT_NACK,
RSL_MT_IPAC_PDCH_DEACT = 0x4b,
RSL_MT_IPAC_PDCH_DEACT_ACK,
RSL_MT_IPAC_PDCH_DEACT_NACK,
RSL_MT_IPAC_CONNECT_MUX = 0x50,
RSL_MT_IPAC_CONNECT_MUX_ACK,
RSL_MT_IPAC_CONNECT_MUX_NACK,
RSL_MT_IPAC_BIND_MUX = 0x53,
RSL_MT_IPAC_BIND_MUX_ACK,
RSL_MT_IPAC_BIND_MUX_NACK,
RSL_MT_IPAC_DISC_MUX = 0x56,
RSL_MT_IPAC_DISC_MUX_ACK,
RSL_MT_IPAC_DISC_MUX_NACK,
RSL_MT_IPAC_CRCX = 0x70, /* Bind to local BTS RTP port */
RSL_MT_IPAC_CRCX_ACK,
RSL_MT_IPAC_CRCX_NACK,
RSL_MT_IPAC_MDCX = 0x73,
RSL_MT_IPAC_MDCX_ACK,
RSL_MT_IPAC_MDCX_NACK,
RSL_MT_IPAC_DLCX_IND = 0x76,
RSL_MT_IPAC_DLCX = 0x77,
RSL_MT_IPAC_DLCX_ACK,
RSL_MT_IPAC_DLCX_NACK,
};
/* Siemens vendor-specific */
enum abis_rsl_msgtype_siemens {
RSL_MT_SIEMENS_MRPCI = 0x41,
RSL_MT_SIEMENS_INTRAC_HO_COND_IND = 0x42,
RSL_MT_SIEMENS_INTERC_HO_COND_IND = 0x43,
RSL_MT_SIEMENS_FORCED_HO_REQ = 0x44,
RSL_MT_SIEMENS_PREF_AREA_REQ = 0x45,
RSL_MT_SIEMENS_PREF_AREA = 0x46,
RSL_MT_SIEMENS_START_TRACE = 0x47,
RSL_MT_SIEMENS_START_TRACE_ACK = 0x48,
RSL_MT_SIEMENS_STOP_TRACE = 0x49,
RSL_MT_SIEMENS_TRMR = 0x4a,
RSL_MT_SIEMENS_HO_FAIL_IND = 0x4b,
RSL_MT_SIEMENS_STOP_TRACE_ACK = 0x4c,
RSL_MT_SIEMENS_UPLF = 0x4d,
RSL_MT_SIEMENS_UPLB = 0x4e,
RSL_MT_SIEMENS_SET_SYS_INFO_10 = 0x4f,
RSL_MT_SIEMENS_MODIF_COND_IND = 0x50,
};
/* Chapter 9.3 */
enum abis_rsl_ie {
RSL_IE_CHAN_NR = 0x01,
RSL_IE_LINK_IDENT,
RSL_IE_ACT_TYPE,
RSL_IE_BS_POWER,
RSL_IE_CHAN_IDENT,
RSL_IE_CHAN_MODE,
RSL_IE_ENCR_INFO,
RSL_IE_FRAME_NUMBER,
RSL_IE_HANDO_REF,
RSL_IE_L1_INFO,
RSL_IE_L3_INFO,
RSL_IE_MS_IDENTITY,
RSL_IE_MS_POWER,
RSL_IE_PAGING_GROUP,
RSL_IE_PAGING_LOAD,
RSL_IE_PYHS_CONTEXT = 0x10,
RSL_IE_ACCESS_DELAY,
RSL_IE_RACH_LOAD,
RSL_IE_REQ_REFERENCE,
RSL_IE_RELEASE_MODE,
RSL_IE_RESOURCE_INFO,
RSL_IE_RLM_CAUSE,
RSL_IE_STARTNG_TIME,
RSL_IE_TIMING_ADVANCE,
RSL_IE_UPLINK_MEAS,
RSL_IE_CAUSE,
RSL_IE_MEAS_RES_NR,
RSL_IE_MSG_ID,
/* reserved */
RSL_IE_SYSINFO_TYPE = 0x1e,
RSL_IE_MS_POWER_PARAM,
RSL_IE_BS_POWER_PARAM,
RSL_IE_PREPROC_PARAM,
RSL_IE_PREPROC_MEAS,
RSL_IE_IMM_ASS_INFO, /* Phase 1 (3.6.0), later Full below */
RSL_IE_SMSCB_INFO = 0x24,
RSL_IE_MS_TIMING_OFFSET,
RSL_IE_ERR_MSG,
RSL_IE_FULL_BCCH_INFO,
RSL_IE_CHAN_NEEDED,
RSL_IE_CB_CMD_TYPE,
RSL_IE_SMSCB_MSG,
RSL_IE_FULL_IMM_ASS_INFO,
RSL_IE_SACCH_INFO,
RSL_IE_CBCH_LOAD_INFO,
RSL_IE_SMSCB_CHAN_INDICATOR,
RSL_IE_GROUP_CALL_REF,
RSL_IE_CHAN_DESC = 0x30,
RSL_IE_NCH_DRX_INFO,
RSL_IE_CMD_INDICATOR,
RSL_IE_EMLPP_PRIO,
RSL_IE_UIC,
RSL_IE_MAIN_CHAN_REF,
RSL_IE_MR_CONFIG,
RSL_IE_MR_CONTROL,
RSL_IE_SUP_CODEC_TYPES,
RSL_IE_CODEC_CONFIG,
RSL_IE_RTD,
RSL_IE_TFO_STATUS,
RSL_IE_LLP_APDU,
/* Siemens vendor-specific */
RSL_IE_SIEMENS_MRPCI = 0x40,
RSL_IE_SIEMENS_PREF_AREA_TYPE = 0x43,
RSL_IE_SIEMENS_ININ_CELL_HO_PAR = 0x45,
RSL_IE_SIEMENS_TRACE_REF_NR = 0x46,
RSL_IE_SIEMENS_INT_TRACE_IDX = 0x47,
RSL_IE_SIEMENS_L2_HDR_INFO = 0x48,
RSL_IE_SIEMENS_HIGHEST_RATE = 0x4e,
RSL_IE_SIEMENS_SUGGESTED_RATE = 0x4f,
/* ip.access */
RSL_IE_IPAC_SRTP_CONFIG = 0xe0,
RSL_IE_IPAC_PROXY_UDP = 0xe1,
RSL_IE_IPAC_BSCMPL_TOUT = 0xe2,
RSL_IE_IPAC_REMOTE_IP = 0xf0,
RSL_IE_IPAC_REMOTE_PORT = 0xf1,
RSL_IE_IPAC_RTP_PAYLOAD = 0xf2,
RSL_IE_IPAC_LOCAL_PORT = 0xf3,
RSL_IE_IPAC_SPEECH_MODE = 0xf4,
RSL_IE_IPAC_LOCAL_IP = 0xf5,
RSL_IE_IPAC_CONN_STAT = 0xf6,
RSL_IE_IPAC_HO_C_PARMS = 0xf7,
RSL_IE_IPAC_CONN_ID = 0xf8,
RSL_IE_IPAC_RTP_CSD_FMT = 0xf9,
RSL_IE_IPAC_RTP_JIT_BUF = 0xfa,
RSL_IE_IPAC_RTP_COMPR = 0xfb,
RSL_IE_IPAC_RTP_PAYLOAD2= 0xfc,
RSL_IE_IPAC_RTP_MPLEX = 0xfd,
RSL_IE_IPAC_RTP_MPLEX_ID= 0xfe,
};
/* Chapter 9.3.1 */
#define RSL_CHAN_NR_MASK 0xf8
#define RSL_CHAN_Bm_ACCHs 0x08
#define RSL_CHAN_Lm_ACCHs 0x10 /* .. 0x18 */
#define RSL_CHAN_SDCCH4_ACCH 0x20 /* .. 0x38 */
#define RSL_CHAN_SDCCH8_ACCH 0x40 /* ...0x78 */
#define RSL_CHAN_BCCH 0x80
#define RSL_CHAN_RACH 0x88
#define RSL_CHAN_PCH_AGCH 0x90
/* Chapter 9.3.3 */
#define RSL_ACT_TYPE_INITIAL 0x00
#define RSL_ACT_TYPE_REACT 0x80
#define RSL_ACT_INTRA_IMM_ASS 0x00
#define RSL_ACT_INTRA_NORM_ASS 0x01
#define RSL_ACT_INTER_ASYNC 0x02
#define RSL_ACT_INTER_SYNC 0x03
#define RSL_ACT_SECOND_ADD 0x04
#define RSL_ACT_SECOND_MULTI 0x05
/* Chapter 9.3.6 */
struct rsl_ie_chan_mode {
uint8_t dtx_dtu;
uint8_t spd_ind;
uint8_t chan_rt;
uint8_t chan_rate;
} __attribute__ ((packed));
#define RSL_CMOD_DTXu 0x01 /* uplink */
#define RSL_CMOD_DTXd 0x02 /* downlink */
enum rsl_cmod_spd {
RSL_CMOD_SPD_SPEECH = 0x01,
RSL_CMOD_SPD_DATA = 0x02,
RSL_CMOD_SPD_SIGN = 0x03,
};
#define RSL_CMOD_CRT_SDCCH 0x01
#define RSL_CMOD_CRT_TCH_Bm 0x08 /* full-rate */
#define RSL_CMOD_CRT_TCH_Lm 0x09 /* half-rate */
/* FIXME: More CRT types */
/* Speech */
#define RSL_CMOD_SP_GSM1 0x01
#define RSL_CMOD_SP_GSM2 0x11
#define RSL_CMOD_SP_GSM3 0x21
/* Data */
#define RSL_CMOD_SP_NT_14k5 0x58
#define RSL_CMOD_SP_NT_12k0 0x50
#define RSL_CMOD_SP_NT_6k0 0x51
/* Chapter 9.3.5 */
struct rsl_ie_chan_ident {
/* GSM 04.08 10.5.2.5 */
struct {
uint8_t iei;
uint8_t chan_nr; /* enc_chan_nr */
uint8_t oct3;
uint8_t oct4;
} chan_desc;
#if 0 /* spec says we need this but Abissim doesn't use it */
struct {
uint8_t tag;
uint8_t len;
} mobile_alloc;
#endif
} __attribute__ ((packed));
/* Chapter 9.3.22 */
#define RLL_CAUSE_T200_EXPIRED 0x01
#define RLL_CAUSE_REEST_REQ 0x02
#define RLL_CAUSE_UNSOL_UA_RESP 0x03
#define RLL_CAUSE_UNSOL_DM_RESP 0x04
#define RLL_CAUSE_UNSOL_DM_RESP_MF 0x05
#define RLL_CAUSE_UNSOL_SPRV_RESP 0x06
#define RLL_CAUSE_SEQ_ERR 0x07
#define RLL_CAUSE_UFRM_INC_PARAM 0x08
#define RLL_CAUSE_SFRM_INC_PARAM 0x09
#define RLL_CAUSE_IFRM_INC_MBITS 0x0a
#define RLL_CAUSE_IFRM_INC_LEN 0x0b
#define RLL_CAUSE_FRM_UNIMPL 0x0c
#define RLL_CAUSE_SABM_MF 0x0d
#define RLL_CAUSE_SABM_INFO_NOTALL 0x0e
/* Chapter 9.3.26 */
#define RSL_ERRCLS_NORMAL 0x00
#define RSL_ERRCLS_RESOURCE_UNAVAIL 0x20
#define RSL_ERRCLS_SERVICE_UNAVAIL 0x30
#define RSL_ERRCLS_SERVICE_UNIMPL 0x40
#define RSL_ERRCLS_INVAL_MSG 0x50
#define RSL_ERRCLS_PROTO_ERROR 0x60
#define RSL_ERRCLS_INTERWORKING 0x70
/* normal event */
#define RSL_ERR_RADIO_IF_FAIL 0x00
#define RSL_ERR_RADIO_LINK_FAIL 0x01
#define RSL_ERR_HANDOVER_ACC_FAIL 0x02
#define RSL_ERR_TALKER_ACC_FAIL 0x03
#define RSL_ERR_OM_INTERVENTION 0x07
#define RSL_ERR_NORMAL_UNSPEC 0x0f
#define RSL_ERR_T_MSRFPCI_EXP 0x18
/* resource unavailable */
#define RSL_ERR_EQUIPMENT_FAIL 0x20
#define RSL_ERR_RR_UNAVAIL 0x21
#define RSL_ERR_TERR_CH_FAIL 0x22
#define RSL_ERR_CCCH_OVERLOAD 0x23
#define RSL_ERR_ACCH_OVERLOAD 0x24
#define RSL_ERR_PROCESSOR_OVERLOAD 0x25
#define RSL_ERR_RES_UNAVAIL 0x2f
/* service or option not available */
#define RSL_ERR_TRANSC_UNAVAIL 0x30
#define RSL_ERR_SERV_OPT_UNAVAIL 0x3f
/* service or option not implemented */
#define RSL_ERR_ENCR_UNIMPL 0x40
#define RSL_ERR_SERV_OPT_UNIMPL 0x4f
/* invalid message */
#define RSL_ERR_RCH_ALR_ACTV_ALLOC 0x50
#define RSL_ERR_INVALID_MESSAGE 0x5f
/* protocol error */
#define RSL_ERR_MSG_DISCR 0x60
#define RSL_ERR_MSG_TYPE 0x61
#define RSL_ERR_MSG_SEQ 0x62
#define RSL_ERR_IE_ERROR 0x63
#define RSL_ERR_MAND_IE_ERROR 0x64
#define RSL_ERR_OPT_IE_ERROR 0x65
#define RSL_ERR_IE_NONEXIST 0x66
#define RSL_ERR_IE_LENGTH 0x67
#define RSL_ERR_IE_CONTENT 0x68
#define RSL_ERR_PROTO 0x6f
/* interworking */
#define RSL_ERR_INTERWORKING 0x7f
/* Chapter 9.3.30 */
#define RSL_SYSTEM_INFO_8 0x00
#define RSL_SYSTEM_INFO_1 0x01
#define RSL_SYSTEM_INFO_2 0x02
#define RSL_SYSTEM_INFO_3 0x03
#define RSL_SYSTEM_INFO_4 0x04
#define RSL_SYSTEM_INFO_5 0x05
#define RSL_SYSTEM_INFO_6 0x06
#define RSL_SYSTEM_INFO_7 0x07
#define RSL_SYSTEM_INFO_16 0x08
#define RSL_SYSTEM_INFO_17 0x09
#define RSL_SYSTEM_INFO_2bis 0x0a
#define RSL_SYSTEM_INFO_2ter 0x0b
#define RSL_SYSTEM_INFO_5bis 0x0d
#define RSL_SYSTEM_INFO_5ter 0x0e
#define RSL_SYSTEM_INFO_10 0x0f
#define REL_EXT_MEAS_ORDER 0x47
#define RSL_MEAS_INFO 0x48
#define RSL_SYSTEM_INFO_13 0x28
#define RSL_SYSTEM_INFO_2quater 0x29
#define RSL_SYSTEM_INFO_9 0x2a
#define RSL_SYSTEM_INFO_18 0x2b
#define RSL_SYSTEM_INFO_19 0x2c
#define RSL_SYSTEM_INFO_20 0x2d
/* Chapter 9.3.40 */
#define RSL_CHANNEED_ANY 0x00
#define RSL_CHANNEED_SDCCH 0x01
#define RSL_CHANNEED_TCH_F 0x02
#define RSL_CHANNEED_TCH_ForH 0x03
/* Chapter 3.3.2.3 Brocast control channel */
/* CCCH-CONF, NC is not combined */
#define RSL_BCCH_CCCH_CONF_1_NC 0x00
#define RSL_BCCH_CCCH_CONF_1_C 0x01
#define RSL_BCCH_CCCH_CONF_2_NC 0x02
#define RSL_BCCH_CCCH_CONF_3_NC 0x04
#define RSL_BCCH_CCCH_CONF_4_NC 0x06
/* BS-PA-MFRMS */
#define RSL_BS_PA_MFRMS_2 0x00
#define RSL_BS_PA_MFRMS_3 0x01
#define RSL_BS_PA_MFRMS_4 0x02
#define RSL_BS_PA_MFRMS_5 0x03
#define RSL_BS_PA_MFRMS_6 0x04
#define RSL_BS_PA_MFRMS_7 0x05
#define RSL_BS_PA_MFRMS_8 0x06
#define RSL_BS_PA_MFRMS_9 0x07
/* RSL_IE_IPAC_RTP_PAYLOAD[2] */
enum rsl_ipac_rtp_payload {
RSL_IPAC_RTP_GSM = 1,
RSL_IPAC_RTP_EFR,
RSL_IPAC_RTP_AMR,
RSL_IPAC_RTP_CSD,
RSL_IPAC_RTP_MUX,
};
/* RSL_IE_IPAC_SPEECH_MODE, lower four bits */
enum rsl_ipac_speech_mode_s {
RSL_IPAC_SPEECH_GSM_FR = 0, /* GSM FR (Type 1, FS) */
RSL_IPAC_SPEECH_GSM_EFR = 1, /* GSM EFR (Type 2, FS) */
RSL_IPAC_SPEECH_GSM_AMR_FR = 2, /* GSM AMR/FR (Type 3, FS) */
RSL_IPAC_SPEECH_GSM_HR = 3, /* GSM HR (Type 1, HS) */
RSL_IPAC_SPEECH_GSM_AMR_HR = 5, /* GSM AMR/hr (Type 3, HS) */
RSL_IPAC_SPEECH_AS_RTP = 0xf, /* As specified by RTP Payload IE */
};
/* RSL_IE_IPAC_SPEECH_MODE, upper four bits */
enum rsl_ipac_speech_mode_m {
RSL_IPAC_SPEECH_M_RXTX = 0, /* Send and Receive */
RSL_IPAC_SPEECH_M_RX = 1, /* Receive only */
RSL_IPAC_SPEECH_M_TX = 2, /* Send only */
};
/* RSL_IE_IPAC_RTP_CSD_FMT, lower four bits */
enum rsl_ipac_rtp_csd_format_d {
RSL_IPAC_RTP_CSD_EXT_TRAU = 0,
RSL_IPAC_RTP_CSD_NON_TRAU = 1,
RSL_IPAC_RTP_CSD_TRAU_BTS = 2,
RSL_IPAC_RTP_CSD_IWF_FREE = 3,
};
/* RSL_IE_IPAC_RTP_CSD_FMT, upper four bits */
enum rsl_ipac_rtp_csd_format_ir {
RSL_IPAC_RTP_CSD_IR_8k = 0,
RSL_IPAC_RTP_CSD_IR_16k = 1,
RSL_IPAC_RTP_CSD_IR_32k = 2,
RSL_IPAC_RTP_CSD_IR_64k = 3,
};
/* Siemens vendor-specific RSL extensions */
struct rsl_mrpci {
uint8_t power_class:3,
vgcs_capable:1,
vbs_capable:1,
gsm_phase:2;
} __attribute__ ((packed));
enum rsl_mrpci_pwrclass {
RSL_MRPCI_PWRC_1 = 0,
RSL_MRPCI_PWRC_2 = 1,
RSL_MRPCI_PWRC_3 = 2,
RSL_MRPCI_PWRC_4 = 3,
RSL_MRPCI_PWRC_5 = 4,
};
enum rsl_mrpci_phase {
RSL_MRPCI_PHASE_1 = 0,
/* reserved */
RSL_MRPCI_PHASE_2 = 2,
RSL_MRPCI_PHASE_2PLUS = 3,
};
#endif /* PROTO_GSM_08_58_H */

View File

@@ -1,713 +0,0 @@
#ifndef PROTO_GSM_12_21_H
#define PROTO_GSM_12_21_H
/* GSM Network Management messages on the A-bis interface
* 3GPP TS 12.21 version 8.0.0 Release 1999 / ETSI TS 100 623 V8.0.0 */
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
* 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 2 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include <stdint.h>
#include <osmocore/tlv.h>
/* generic header in front of every OML message according to TS 08.59 */
struct abis_om_hdr {
uint8_t mdisc;
uint8_t placement;
uint8_t sequence;
uint8_t length;
uint8_t data[0];
} __attribute__ ((packed));
#define ABIS_OM_MDISC_FOM 0x80
#define ABIS_OM_MDISC_MMI 0x40
#define ABIS_OM_MDISC_TRAU 0x20
#define ABIS_OM_MDISC_MANUF 0x10
#define ABIS_OM_PLACEMENT_ONLY 0x80
#define ABIS_OM_PLACEMENT_FIRST 0x40
#define ABIS_OM_PLACEMENT_MIDDLE 0x20
#define ABIS_OM_PLACEMENT_LAST 0x10
struct abis_om_obj_inst {
uint8_t bts_nr;
uint8_t trx_nr;
uint8_t ts_nr;
} __attribute__ ((packed));
struct abis_om_fom_hdr {
uint8_t msg_type;
uint8_t obj_class;
struct abis_om_obj_inst obj_inst;
uint8_t data[0];
} __attribute__ ((packed));
#define ABIS_OM_FOM_HDR_SIZE (sizeof(struct abis_om_hdr) + sizeof(struct abis_om_fom_hdr))
/* Section 9.1: Message Types */
enum abis_nm_msgtype {
/* SW Download Management Messages */
NM_MT_LOAD_INIT = 0x01,
NM_MT_LOAD_INIT_ACK,
NM_MT_LOAD_INIT_NACK,
NM_MT_LOAD_SEG,
NM_MT_LOAD_SEG_ACK,
NM_MT_LOAD_ABORT,
NM_MT_LOAD_END,
NM_MT_LOAD_END_ACK,
NM_MT_LOAD_END_NACK,
NM_MT_SW_ACT_REQ, /* BTS->BSC */
NM_MT_SW_ACT_REQ_ACK,
NM_MT_SW_ACT_REQ_NACK,
NM_MT_ACTIVATE_SW, /* BSC->BTS */
NM_MT_ACTIVATE_SW_ACK,
NM_MT_ACTIVATE_SW_NACK,
NM_MT_SW_ACTIVATED_REP, /* 0x10 */
/* A-bis Interface Management Messages */
NM_MT_ESTABLISH_TEI = 0x21,
NM_MT_ESTABLISH_TEI_ACK,
NM_MT_ESTABLISH_TEI_NACK,
NM_MT_CONN_TERR_SIGN,
NM_MT_CONN_TERR_SIGN_ACK,
NM_MT_CONN_TERR_SIGN_NACK,
NM_MT_DISC_TERR_SIGN,
NM_MT_DISC_TERR_SIGN_ACK,
NM_MT_DISC_TERR_SIGN_NACK,
NM_MT_CONN_TERR_TRAF,
NM_MT_CONN_TERR_TRAF_ACK,
NM_MT_CONN_TERR_TRAF_NACK,
NM_MT_DISC_TERR_TRAF,
NM_MT_DISC_TERR_TRAF_ACK,
NM_MT_DISC_TERR_TRAF_NACK,
/* Transmission Management Messages */
NM_MT_CONN_MDROP_LINK = 0x31,
NM_MT_CONN_MDROP_LINK_ACK,
NM_MT_CONN_MDROP_LINK_NACK,
NM_MT_DISC_MDROP_LINK,
NM_MT_DISC_MDROP_LINK_ACK,
NM_MT_DISC_MDROP_LINK_NACK,
/* Air Interface Management Messages */
NM_MT_SET_BTS_ATTR = 0x41,
NM_MT_SET_BTS_ATTR_ACK,
NM_MT_SET_BTS_ATTR_NACK,
NM_MT_SET_RADIO_ATTR,
NM_MT_SET_RADIO_ATTR_ACK,
NM_MT_SET_RADIO_ATTR_NACK,
NM_MT_SET_CHAN_ATTR,
NM_MT_SET_CHAN_ATTR_ACK,
NM_MT_SET_CHAN_ATTR_NACK,
/* Test Management Messages */
NM_MT_PERF_TEST = 0x51,
NM_MT_PERF_TEST_ACK,
NM_MT_PERF_TEST_NACK,
NM_MT_TEST_REP,
NM_MT_SEND_TEST_REP,
NM_MT_SEND_TEST_REP_ACK,
NM_MT_SEND_TEST_REP_NACK,
NM_MT_STOP_TEST,
NM_MT_STOP_TEST_ACK,
NM_MT_STOP_TEST_NACK,
/* State Management and Event Report Messages */
NM_MT_STATECHG_EVENT_REP = 0x61,
NM_MT_FAILURE_EVENT_REP,
NM_MT_STOP_EVENT_REP,
NM_MT_STOP_EVENT_REP_ACK,
NM_MT_STOP_EVENT_REP_NACK,
NM_MT_REST_EVENT_REP,
NM_MT_REST_EVENT_REP_ACK,
NM_MT_REST_EVENT_REP_NACK,
NM_MT_CHG_ADM_STATE,
NM_MT_CHG_ADM_STATE_ACK,
NM_MT_CHG_ADM_STATE_NACK,
NM_MT_CHG_ADM_STATE_REQ,
NM_MT_CHG_ADM_STATE_REQ_ACK,
NM_MT_CHG_ADM_STATE_REQ_NACK,
NM_MT_REP_OUTST_ALARMS = 0x93,
NM_MT_REP_OUTST_ALARMS_ACK,
NM_MT_REP_OUTST_ALARMS_NACK,
/* Equipment Management Messages */
NM_MT_CHANGEOVER = 0x71,
NM_MT_CHANGEOVER_ACK,
NM_MT_CHANGEOVER_NACK,
NM_MT_OPSTART,
NM_MT_OPSTART_ACK,
NM_MT_OPSTART_NACK,
NM_MT_REINIT,
NM_MT_REINIT_ACK,
NM_MT_REINIT_NACK,
NM_MT_SET_SITE_OUT, /* BS11: get alarm ?!? */
NM_MT_SET_SITE_OUT_ACK,
NM_MT_SET_SITE_OUT_NACK,
NM_MT_CHG_HW_CONF = 0x90,
NM_MT_CHG_HW_CONF_ACK,
NM_MT_CHG_HW_CONF_NACK,
/* Measurement Management Messages */
NM_MT_MEAS_RES_REQ = 0x8a,
NM_MT_MEAS_RES_RESP,
NM_MT_STOP_MEAS,
NM_MT_START_MEAS,
/* Other Messages */
NM_MT_GET_ATTR = 0x81,
NM_MT_GET_ATTR_RESP,
NM_MT_GET_ATTR_NACK,
NM_MT_SET_ALARM_THRES,
NM_MT_SET_ALARM_THRES_ACK,
NM_MT_SET_ALARM_THRES_NACK,
};
enum abis_nm_msgtype_bs11 {
NM_MT_BS11_RESET_RESOURCE = 0x74,
NM_MT_BS11_BEGIN_DB_TX = 0xa3,
NM_MT_BS11_BEGIN_DB_TX_ACK,
NM_MT_BS11_BEGIN_DB_TX_NACK,
NM_MT_BS11_END_DB_TX = 0xa6,
NM_MT_BS11_END_DB_TX_ACK,
NM_MT_BS11_END_DB_TX_NACK,
NM_MT_BS11_CREATE_OBJ = 0xa9,
NM_MT_BS11_CREATE_OBJ_ACK,
NM_MT_BS11_CREATE_OBJ_NACK,
NM_MT_BS11_DELETE_OBJ = 0xac,
NM_MT_BS11_DELETE_OBJ_ACK,
NM_MT_BS11_DELETE_OBJ_NACK,
NM_MT_BS11_SET_ATTR = 0xd0,
NM_MT_BS11_SET_ATTR_ACK,
NM_MT_BS11_SET_ATTR_NACK,
NM_MT_BS11_LMT_SESSION = 0xdc,
NM_MT_BS11_GET_STATE = 0xe3,
NM_MT_BS11_GET_STATE_ACK,
NM_MT_BS11_LMT_LOGON = 0xe5,
NM_MT_BS11_LMT_LOGON_ACK,
NM_MT_BS11_RESTART = 0xe7,
NM_MT_BS11_RESTART_ACK,
NM_MT_BS11_DISCONNECT = 0xe9,
NM_MT_BS11_DISCONNECT_ACK,
NM_MT_BS11_LMT_LOGOFF = 0xec,
NM_MT_BS11_LMT_LOGOFF_ACK,
NM_MT_BS11_RECONNECT = 0xf1,
NM_MT_BS11_RECONNECT_ACK,
};
enum abis_nm_msgtype_ipacc {
NM_MT_IPACC_RESTART = 0x87,
NM_MT_IPACC_RESTART_ACK,
NM_MT_IPACC_RESTART_NACK,
NM_MT_IPACC_RSL_CONNECT = 0xe0,
NM_MT_IPACC_RSL_CONNECT_ACK,
NM_MT_IPACC_RSL_CONNECT_NACK,
NM_MT_IPACC_RSL_DISCONNECT = 0xe3,
NM_MT_IPACC_RSL_DISCONNECT_ACK,
NM_MT_IPACC_RSL_DISCONNECT_NACK,
NM_MT_IPACC_CONN_TRAF = 0xe6,
NM_MT_IPACC_CONN_TRAF_ACK,
NM_MT_IPACC_CONN_TRAF_NACK,
NM_MT_IPACC_DEF_BOOT_SW = 0xec,
NM_MT_IPACC_DEF_BOOT_SW_ACK,
MN_MT_IPACC_DEF_BOOT_SW_NACK,
NM_MT_IPACC_SET_NVATTR = 0xef,
NM_MT_IPACC_SET_NVATTR_ACK,
NM_MT_IPACC_SET_NVATTR_NACK,
NM_MT_IPACC_GET_NVATTR = 0xf2,
NM_MT_IPACC_GET_NVATTR_ACK,
NM_MT_IPACC_GET_NVATTR_NACK,
NM_MT_IPACC_SET_ATTR = 0xf5,
NM_MT_IPACC_SET_ATTR_ACK,
NM_MT_IPACC_SET_ATTR_NACK,
};
enum abis_nm_bs11_cell_alloc {
NM_BS11_CANR_GSM = 0x00,
NM_BS11_CANR_DCS1800 = 0x01,
};
/* Section 9.2: Object Class */
enum abis_nm_obj_class {
NM_OC_SITE_MANAGER = 0x00,
NM_OC_BTS,
NM_OC_RADIO_CARRIER,
NM_OC_CHANNEL,
NM_OC_BASEB_TRANSC,
/* RFU: 05-FE */
NM_OC_IPAC_E1_TRUNK = 0x0e,
NM_OC_IPAC_E1_PORT = 0x0f,
NM_OC_IPAC_E1_CHAN = 0x10,
NM_OC_IPAC_CLK_MODULE = 0x22,
NM_OC_BS11_ADJC = 0xa0,
NM_OC_BS11_HANDOVER = 0xa1,
NM_OC_BS11_PWR_CTRL = 0xa2,
NM_OC_BS11_BTSE = 0xa3, /* LMT? */
NM_OC_BS11_RACK = 0xa4,
NM_OC_BS11 = 0xa5, /* 01: ALCO */
NM_OC_BS11_TEST = 0xa6,
NM_OC_BS11_ENVABTSE = 0xa8,
NM_OC_BS11_BPORT = 0xa9,
NM_OC_GPRS_NSE = 0xf0,
NM_OC_GPRS_CELL = 0xf1,
NM_OC_GPRS_NSVC = 0xf2,
NM_OC_NULL = 0xff,
};
/* Section 9.4: Attributes */
enum abis_nm_attr {
NM_ATT_ABIS_CHANNEL = 0x01,
NM_ATT_ADD_INFO,
NM_ATT_ADD_TEXT,
NM_ATT_ADM_STATE,
NM_ATT_ARFCN_LIST,
NM_ATT_AUTON_REPORT,
NM_ATT_AVAIL_STATUS,
NM_ATT_BCCH_ARFCN,
NM_ATT_BSIC,
NM_ATT_BTS_AIR_TIMER,
NM_ATT_CCCH_L_I_P,
NM_ATT_CCCH_L_T,
NM_ATT_CHAN_COMB,
NM_ATT_CONN_FAIL_CRIT,
NM_ATT_DEST,
/* res */
NM_ATT_EVENT_TYPE = 0x11, /* BS11: file data ?!? */
NM_ATT_FILE_ID,
NM_ATT_FILE_VERSION,
NM_ATT_GSM_TIME,
NM_ATT_HSN,
NM_ATT_HW_CONFIG,
NM_ATT_HW_DESC,
NM_ATT_INTAVE_PARAM,
NM_ATT_INTERF_BOUND,
NM_ATT_LIST_REQ_ATTR,
NM_ATT_MAIO,
NM_ATT_MANUF_STATE,
NM_ATT_MANUF_THRESH,
NM_ATT_MANUF_ID,
NM_ATT_MAX_TA,
NM_ATT_MDROP_LINK, /* 0x20 */
NM_ATT_MDROP_NEXT,
NM_ATT_NACK_CAUSES,
NM_ATT_NY1,
NM_ATT_OPER_STATE,
NM_ATT_OVERL_PERIOD,
NM_ATT_PHYS_CONF,
NM_ATT_POWER_CLASS,
NM_ATT_POWER_THRESH,
NM_ATT_PROB_CAUSE,
NM_ATT_RACH_B_THRESH,
NM_ATT_LDAVG_SLOTS,
NM_ATT_RAD_SUBC,
NM_ATT_RF_MAXPOWR_R,
NM_ATT_SITE_INPUTS,
NM_ATT_SITE_OUTPUTS,
NM_ATT_SOURCE, /* 0x30 */
NM_ATT_SPEC_PROB,
NM_ATT_START_TIME,
NM_ATT_T200,
NM_ATT_TEI,
NM_ATT_TEST_DUR,
NM_ATT_TEST_NO,
NM_ATT_TEST_REPORT,
NM_ATT_VSWR_THRESH,
NM_ATT_WINDOW_SIZE,
/* Res */
NM_ATT_BS11_RSSI_OFFS = 0x3d,
NM_ATT_BS11_TXPWR = 0x3e,
NM_ATT_BS11_DIVERSITY = 0x3f,
/* Res */
NM_ATT_TSC = 0x40,
NM_ATT_SW_CONFIG,
NM_ATT_SW_DESCR,
NM_ATT_SEVERITY,
NM_ATT_GET_ARI,
NM_ATT_HW_CONF_CHG,
NM_ATT_OUTST_ALARM,
NM_ATT_FILE_DATA,
NM_ATT_MEAS_RES,
NM_ATT_MEAS_TYPE,
NM_ATT_BS11_ESN_FW_CODE_NO = 0x4c,
NM_ATT_BS11_ESN_HW_CODE_NO = 0x4f,
NM_ATT_BS11_ESN_PCB_SERIAL = 0x55,
NM_ATT_BS11_EXCESSIVE_DISTANCE = 0x58,
NM_ATT_BS11_ALL_TEST_CATG = 0x60,
NM_ATT_BS11_BTSLS_HOPPING,
NM_ATT_BS11_CELL_ALLOC_NR,
NM_ATT_BS11_CELL_GLOBAL_ID,
NM_ATT_BS11_ENA_INTERF_CLASS = 0x66,
NM_ATT_BS11_ENA_INT_INTEC_HANDO = 0x67,
NM_ATT_BS11_ENA_INT_INTRC_HANDO = 0x68,
NM_ATT_BS11_ENA_MS_PWR_CTRL = 0x69,
NM_ATT_BS11_ENA_PWR_BDGT_HO = 0x6a,
NM_ATT_BS11_ENA_PWR_CTRL_RLFW = 0x6b,
NM_ATT_BS11_ENA_RXLEV_HO = 0x6c,
NM_ATT_BS11_ENA_RXQUAL_HO = 0x6d,
NM_ATT_BS11_FACCH_QUAL = 0x6e,
NM_ATT_IPACC_DST_IP = 0x80,
NM_ATT_IPACC_DST_IP_PORT = 0x81,
NM_ATT_IPACC_SSRC = 0x82,
NM_ATT_IPACC_RTP_PAYLD_TYPE = 0x83,
NM_ATT_IPACC_BASEB_ID = 0x84,
NM_ATT_IPACC_STREAM_ID = 0x85,
NM_ATT_IPACC_NV_FLAGS = 0x86,
NM_ATT_IPACC_FREQ_CTRL = 0x87,
NM_ATT_IPACC_PRIM_OML_CFG = 0x88,
NM_ATT_IPACC_SEC_OML_CFG = 0x89,
NM_ATT_IPACC_IP_IF_CFG = 0x8a, /* IP interface */
NM_ATT_IPACC_IP_GW_CFG = 0x8b, /* IP gateway */
NM_ATT_IPACC_IN_SERV_TIME = 0x8c,
NM_ATT_IPACC_TRX_BTS_ASS = 0x8d,
NM_ATT_IPACC_LOCATION = 0x8e, /* string describing location */
NM_ATT_IPACC_PAGING_CFG = 0x8f,
NM_ATT_IPACC_FILE_DATA = 0x90,
NM_ATT_IPACC_UNIT_ID = 0x91, /* Site/BTS/TRX */
NM_ATT_IPACC_PARENT_UNIT_ID = 0x92,
NM_ATT_IPACC_UNIT_NAME = 0x93, /* default: nbts-<mac-as-string> */
NM_ATT_IPACC_SNMP_CFG = 0x94,
NM_ATT_IPACC_PRIM_OML_CFG_LIST = 0x95,
NM_ATT_IPACC_PRIM_OML_FB_TOUT = 0x96,
NM_ATT_IPACC_CUR_SW_CFG = 0x97,
NM_ATT_IPACC_TIMING_BUS = 0x98,
NM_ATT_IPACC_CGI = 0x99,
NM_ATT_IPACC_RAC = 0x9a,
NM_ATT_IPACC_OBJ_VERSION = 0x9b,
NM_ATT_IPACC_GPRS_PAGING_CFG = 0x9c,
NM_ATT_IPACC_NSEI = 0x9d,
NM_ATT_IPACC_BVCI = 0x9e,
NM_ATT_IPACC_NSVCI = 0x9f,
NM_ATT_IPACC_NS_CFG = 0xa0,
NM_ATT_IPACC_BSSGP_CFG = 0xa1,
NM_ATT_IPACC_NS_LINK_CFG = 0xa2,
NM_ATT_IPACC_RLC_CFG = 0xa3,
NM_ATT_IPACC_ALM_THRESH_LIST = 0xa4,
NM_ATT_IPACC_MONIT_VAL_LIST = 0xa5,
NM_ATT_IPACC_TIB_CONTROL = 0xa6,
NM_ATT_IPACC_SUPP_FEATURES = 0xa7,
NM_ATT_IPACC_CODING_SCHEMES = 0xa8,
NM_ATT_IPACC_RLC_CFG_2 = 0xa9,
NM_ATT_IPACC_HEARTB_TOUT = 0xaa,
NM_ATT_IPACC_UPTIME = 0xab,
NM_ATT_IPACC_RLC_CFG_3 = 0xac,
NM_ATT_IPACC_SSL_CFG = 0xad,
NM_ATT_IPACC_SEC_POSSIBLE = 0xae,
NM_ATT_IPACC_IML_SSL_STATE = 0xaf,
NM_ATT_IPACC_REVOC_DATE = 0xb0,
NM_ATT_BS11_RF_RES_IND_PER = 0x8f,
NM_ATT_BS11_RX_LEV_MIN_CELL = 0x90,
NM_ATT_BS11_ABIS_EXT_TIME = 0x91,
NM_ATT_BS11_TIMER_HO_REQUEST = 0x92,
NM_ATT_BS11_TIMER_NCELL = 0x93,
NM_ATT_BS11_TSYNC = 0x94,
NM_ATT_BS11_TTRAU = 0x95,
NM_ATT_BS11_EMRG_CFG_MEMBER = 0x9b,
NM_ATT_BS11_TRX_AREA = 0x9f,
NM_ATT_BS11_BCCH_RECONF = 0xd7,
NM_ATT_BS11_BIT_ERR_THESH = 0xa0,
NM_ATT_BS11_BOOT_SW_VERS = 0xa1,
NM_ATT_BS11_CCLK_ACCURACY = 0xa3,
NM_ATT_BS11_CCLK_TYPE = 0xa4,
NM_ATT_BS11_INP_IMPEDANCE = 0xaa,
NM_ATT_BS11_L1_PROT_TYPE = 0xab,
NM_ATT_BS11_LINE_CFG = 0xac,
NM_ATT_BS11_LI_PORT_1 = 0xad,
NM_ATT_BS11_LI_PORT_2 = 0xae,
NM_ATT_BS11_L1_REM_ALM_TYPE = 0xb0,
NM_ATT_BS11_SW_LOAD_INTENDED = 0xbb,
NM_ATT_BS11_SW_LOAD_SAFETY = 0xbc,
NM_ATT_BS11_SW_LOAD_STORED = 0xbd,
NM_ATT_BS11_VENDOR_NAME = 0xc1,
NM_ATT_BS11_HOPPING_MODE = 0xc5,
NM_ATT_BS11_LMT_LOGON_SESSION = 0xc6,
NM_ATT_BS11_LMT_LOGIN_TIME = 0xc7,
NM_ATT_BS11_LMT_USER_ACC_LEV = 0xc8,
NM_ATT_BS11_LMT_USER_NAME = 0xc9,
NM_ATT_BS11_L1_CONTROL_TS = 0xd8,
NM_ATT_BS11_RADIO_MEAS_GRAN = 0xdc, /* in SACCH multiframes */
NM_ATT_BS11_RADIO_MEAS_REP = 0xdd,
NM_ATT_BS11_SH_LAPD_INT_TIMER = 0xe8,
NM_ATT_BS11_BTS_STATE = 0xf0,
NM_ATT_BS11_E1_STATE = 0xf1,
NM_ATT_BS11_PLL = 0xf2,
NM_ATT_BS11_RX_OFFSET = 0xf3,
NM_ATT_BS11_ANT_TYPE = 0xf4,
NM_ATT_BS11_PLL_MODE = 0xfc,
NM_ATT_BS11_PASSWORD = 0xfd,
};
#define NM_ATT_BS11_FILE_DATA NM_ATT_EVENT_TYPE
/* Section 9.4.4: Administrative State */
enum abis_nm_adm_state {
NM_STATE_LOCKED = 0x01,
NM_STATE_UNLOCKED = 0x02,
NM_STATE_SHUTDOWN = 0x03,
NM_STATE_NULL = 0xff,
};
/* Section 9.4.7: Administrative State */
enum abis_nm_avail_state {
NM_AVSTATE_IN_TEST = 1,
NM_AVSTATE_POWER_OFF = 2,
NM_AVSTATE_OFF_LINE = 3,
NM_AVSTATE_DEPENDENCY = 5,
NM_AVSTATE_DEGRADED = 6,
NM_AVSTATE_NOT_INSTALLED= 7,
NM_AVSTATE_OK = 0xff,
};
enum abis_nm_op_state {
NM_OPSTATE_DISABLED = 1,
NM_OPSTATE_ENABLED = 2,
NM_OPSTATE_NULL = 0xff,
};
/* Section 9.4.13: Channel Combination */
enum abis_nm_chan_comb {
NM_CHANC_TCHFull = 0x00, /* TCH/F + TCH/H + SACCH/TF */
NM_CHANC_TCHHalf = 0x01, /* TCH/H(0,1) + FACCH/H(0,1) +
SACCH/TH(0,1) */
NM_CHANC_TCHHalf2 = 0x02, /* TCH/H(0) + FACCH/H(0) + SACCH/TH(0) +
TCH/H(1) */
NM_CHANC_SDCCH = 0x03, /* SDCCH/8 + SACCH/8 */
NM_CHANC_mainBCCH = 0x04, /* FCCH + SCH + BCCH + CCCH */
NM_CHANC_BCCHComb = 0x05, /* FCCH + SCH + BCCH + CCCH + SDCCH/4 +
SACCH/C4 */
NM_CHANC_BCCH = 0x06, /* BCCH + CCCH */
NM_CHANC_BCCH_CBCH = 0x07, /* CHANC_BCCHComb + CBCH */
NM_CHANC_SDCCH_CBCH = 0x08, /* CHANC_SDCCH8 + CBCH */
/* ip.access */
NM_CHANC_IPAC_bPDCH = 0x0b, /* PBCCH + PCCCH + PDTCH/F + PACCH/F +
PTCCH/F */
NM_CHANC_IPAC_cPDCH = 0x0c, /* PBCCH + PDTCH/F + PACCH/F + PTCCH/F */
NM_CHANC_IPAC_PDCH = 0x0d, /* PDTCH/F + PACCH/F + PTCCH/F */
NM_CHANC_IPAC_TCHFull_PDCH = 0x80,
NM_CHANC_IPAC_TCHFull_TCHHalf = 0x81,
};
/* Section 9.4.16: Event Type */
enum abis_nm_event_type {
NM_EVT_COMM_FAIL = 0x00,
NM_EVT_QOS_FAIL = 0x01,
NM_EVT_PROC_FAIL = 0x02,
NM_EVT_EQUIP_FAIL = 0x03,
NM_EVT_ENV_FAIL = 0x04,
};
/* Section: 9.4.63: Perceived Severity */
enum abis_nm_severity {
NM_SEVER_CEASED = 0x00,
NM_SEVER_CRITICAL = 0x01,
NM_SEVER_MAJOR = 0x02,
NM_SEVER_MINOR = 0x03,
NM_SEVER_WARNING = 0x04,
NM_SEVER_INDETERMINATE = 0x05,
};
/* Section 9.4.43: Probable Cause Type */
enum abis_nm_pcause_type {
NM_PCAUSE_T_X721 = 0x01,
NM_PCAUSE_T_GSM = 0x02,
NM_PCAUSE_T_MANUF = 0x03,
};
/* Section 9.4.36: NACK Causes */
enum abis_nm_nack_cause {
/* General Nack Causes */
NM_NACK_INCORR_STRUCT = 0x01,
NM_NACK_MSGTYPE_INVAL = 0x02,
NM_NACK_OBJCLASS_INVAL = 0x05,
NM_NACK_OBJCLASS_NOTSUPP = 0x06,
NM_NACK_BTSNR_UNKN = 0x07,
NM_NACK_TRXNR_UNKN = 0x08,
NM_NACK_OBJINST_UNKN = 0x09,
NM_NACK_ATTRID_INVAL = 0x0c,
NM_NACK_ATTRID_NOTSUPP = 0x0d,
NM_NACK_PARAM_RANGE = 0x0e,
NM_NACK_ATTRLIST_INCONSISTENT = 0x0f,
NM_NACK_SPEC_IMPL_NOTSUPP = 0x10,
NM_NACK_CANT_PERFORM = 0x11,
/* Specific Nack Causes */
NM_NACK_RES_NOTIMPL = 0x19,
NM_NACK_RES_NOTAVAIL = 0x1a,
NM_NACK_FREQ_NOTAVAIL = 0x1b,
NM_NACK_TEST_NOTSUPP = 0x1c,
NM_NACK_CAPACITY_RESTR = 0x1d,
NM_NACK_PHYSCFG_NOTPERFORM = 0x1e,
NM_NACK_TEST_NOTINIT = 0x1f,
NM_NACK_PHYSCFG_NOTRESTORE = 0x20,
NM_NACK_TEST_NOSUCH = 0x21,
NM_NACK_TEST_NOSTOP = 0x22,
NM_NACK_MSGINCONSIST_PHYSCFG = 0x23,
NM_NACK_FILE_INCOMPLETE = 0x25,
NM_NACK_FILE_NOTAVAIL = 0x26,
NM_NACK_FILE_NOTACTIVATE = 0x27,
NM_NACK_REQ_NOT_GRANT = 0x28,
NM_NACK_WAIT = 0x29,
NM_NACK_NOTH_REPORT_EXIST = 0x2a,
NM_NACK_MEAS_NOTSUPP = 0x2b,
NM_NACK_MEAS_NOTSTART = 0x2c,
};
/* Section 9.4.1 */
struct abis_nm_channel {
uint8_t attrib;
uint8_t bts_port;
uint8_t timeslot;
uint8_t subslot;
} __attribute__ ((packed));
/* Siemens BS-11 specific objects in the SienemsHW (0xA5) object class */
enum abis_bs11_objtype {
BS11_OBJ_ALCO = 0x01,
BS11_OBJ_BBSIG = 0x02, /* obj_class: 0,1 */
BS11_OBJ_TRX1 = 0x03, /* only DEACTIVATE TRX1 */
BS11_OBJ_CCLK = 0x04,
BS11_OBJ_GPSU = 0x06,
BS11_OBJ_LI = 0x07,
BS11_OBJ_PA = 0x09, /* obj_class: 0, 1*/
};
enum abis_bs11_trx_power {
BS11_TRX_POWER_GSM_2W = 0x06,
BS11_TRX_POWER_GSM_250mW= 0x07,
BS11_TRX_POWER_GSM_80mW = 0x08,
BS11_TRX_POWER_GSM_30mW = 0x09,
BS11_TRX_POWER_DCS_3W = 0x0a,
BS11_TRX_POWER_DCS_1W6 = 0x0b,
BS11_TRX_POWER_DCS_500mW= 0x0c,
BS11_TRX_POWER_DCS_160mW= 0x0d,
};
enum abis_bs11_li_pll_mode {
BS11_LI_PLL_LOCKED = 2,
BS11_LI_PLL_STANDALONE = 3,
};
enum abis_bs11_line_cfg {
BS11_LINE_CFG_STAR = 0x00,
BS11_LINE_CFG_MULTIDROP = 0x01,
BS11_LINE_CFG_LOOP = 0x02,
};
enum abis_bs11_phase {
BS11_STATE_SOFTWARE_RQD = 0x01,
BS11_STATE_LOAD_SMU_INTENDED = 0x11,
BS11_STATE_LOAD_SMU_SAFETY = 0x21,
BS11_STATE_LOAD_FAILED = 0x31,
BS11_STATE_LOAD_DIAGNOSTIC = 0x41,
BS11_STATE_WARM_UP = 0x51,
BS11_STATE_WARM_UP_2 = 0x52,
BS11_STATE_WAIT_MIN_CFG = 0x62,
BS11_STATE_MAINTENANCE = 0x72,
BS11_STATE_LOAD_MBCCU = 0x92,
BS11_STATE_WAIT_MIN_CFG_2 = 0xA2,
BS11_STATE_NORMAL = 0x03,
BS11_STATE_ABIS_LOAD = 0x13,
};
enum abis_nm_ipacc_test_no {
NM_IPACC_TESTNO_RLOOP_ANT = 0x01,
NM_IPACC_TESTNO_RLOOP_XCVR = 0x02,
NM_IPACC_TESTNO_FUNC_OBJ = 0x03,
NM_IPACC_TESTNO_CHAN_USAGE = 0x40,
NM_IPACC_TESTNO_BCCH_CHAN_USAGE = 0x41,
NM_IPACC_TESTNO_FREQ_SYNC = 0x42,
NM_IPACC_TESTNO_BCCH_INFO = 0x43,
NM_IPACC_TESTNO_TX_BEACON = 0x44,
NM_IPACC_TESTNO_SYSINFO_MONITOR = 0x45,
NM_IPACC_TESTNO_BCCCH_MONITOR = 0x46,
};
/* first byte after length inside NM_ATT_TEST_REPORT */
enum abis_nm_ipacc_test_res {
NM_IPACC_TESTRES_SUCCESS = 0,
NM_IPACC_TESTRES_TIMEOUT = 1,
NM_IPACC_TESTRES_NO_CHANS = 2,
NM_IPACC_TESTRES_PARTIAL = 3,
NM_IPACC_TESTRES_STOPPED = 4,
};
/* internal IE inside NM_ATT_TEST_REPORT */
enum abis_nm_ipacc_testres_ie {
NM_IPACC_TR_IE_FREQ_ERR_LIST = 3,
NM_IPACC_TR_IE_CHAN_USAGE = 4,
NM_IPACC_TR_IE_BCCH_INFO = 6,
NM_IPACC_TR_IE_RESULT_DETAILS = 8,
NM_IPACC_TR_IE_FREQ_ERR = 18,
};
enum ipac_eie {
NM_IPAC_EIE_ARFCN_WHITE = 0x01,
NM_IPAC_EIE_ARFCH_BLACK = 0x02,
NM_IPAC_EIE_FREQ_ERR_LIST = 0x03,
NM_IPAC_EIE_CHAN_USE_LIST = 0x04,
NM_IPAC_EIE_BCCH_INFO_TYPE = 0x05,
NM_IPAC_EIE_BCCH_INFO = 0x06,
NM_IPAC_EIE_CONFIG = 0x07,
NM_IPAC_EIE_RES_DETAILS = 0x08,
NM_IPAC_EIE_RXLEV_THRESH = 0x09,
NM_IPAC_EIE_FREQ_SYNC_OPTS = 0x0a,
NM_IPAC_EIE_MAC_ADDR = 0x0b,
NM_IPAC_EIE_HW_SW_COMPAT_NR = 0x0c,
NM_IPAC_EIE_MANUF_SER_NR = 0x0d,
NM_IPAC_EIE_OEM_ID = 0x0e,
NM_IPAC_EIE_DATE_TIME_MANUF = 0x0f,
NM_IPAC_EIE_DATE_TIME_CALIB = 0x10,
NM_IPAC_EIE_BEACON_INFO = 0x11,
NM_IPAC_EIE_FREQ_ERR = 0x12,
/* FIXME */
NM_IPAC_EIE_FREQ_BANDS = 0x1c,
NM_IPAC_EIE_MAX_TA = 0x1d,
NM_IPAC_EIE_CIPH_ALGOS = 0x1e,
NM_IPAC_EIE_CHAN_TYPES = 0x1f,
NM_IPAC_EIE_CHAN_MODES = 0x20,
NM_IPAC_EIE_GPRS_CODING = 0x21,
NM_IPAC_EIE_RTP_FEATURES = 0x22,
NM_IPAC_EIE_RSL_FEATURES = 0x23,
NM_IPAC_EIE_BTS_HW_CLASS = 0x24,
NM_IPAC_EIE_BTS_ID = 0x25,
};
enum ipac_bcch_info_type {
IPAC_BINF_RXLEV = (1 << 8),
IPAC_BINF_RXQUAL = (1 << 9),
IPAC_BINF_FREQ_ERR_QUAL = (1 << 10),
IPAC_BINF_FRAME_OFFSET = (1 << 11),
IPAC_BINF_FRAME_NR_OFFSET = (1 << 12),
IPAC_BINF_BSIC = (1 << 13),
IPAC_BINF_CGI = (1 << 14),
IPAC_BINF_NEIGH_BA_SI2 = (1 << 15),
IPAC_BINF_NEIGH_BA_SI2bis = (1 << 0),
IPAC_BINF_NEIGH_BA_SI2ter = (1 << 1),
IPAC_BINF_CELL_ALLOC = (1 << 2),
};
#endif /* PROTO_GSM_12_21_H */

View File

@@ -1,33 +0,0 @@
#ifndef _OSMOCORE_RSL_H
#define _OSMOCORE_RSL_H
#include <stdint.h>
#include <osmocore/utils.h>
#include <osmocore/protocol/gsm_08_58.h>
void rsl_init_rll_hdr(struct abis_rsl_rll_hdr *dh, uint8_t msg_type);
extern const struct tlv_definition rsl_att_tlvdef;
#define rsl_tlv_parse(dec, buf, len) \
tlv_parse(dec, &rsl_att_tlvdef, buf, len, 0, 0)
/* encode channel number as per Section 9.3.1 */
uint8_t rsl_enc_chan_nr(uint8_t type, uint8_t subch, uint8_t timeslot);
/* decode channel number as per Section 9.3.1 */
int rsl_dec_chan_nr(uint8_t chan_nr, uint8_t *type, uint8_t *subch, uint8_t *timeslot);
extern const struct value_string rsl_rlm_cause_strs[];
const char *rsl_err_name(uint8_t err);
/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf);
/* Push a RSL RLL header with L3_INFO IE */
void rsl_rll_push_l3(struct msgb *msg, uint8_t msg_type, uint8_t chan_nr,
uint8_t link_id, int transparent);
/* Allocate msgb and fill with simple RSL RLL header */
struct msgb *rsl_rll_simple(uint8_t msg_type, uint8_t chan_nr,
uint8_t link_id, int transparent);
#endif /* _OSMOCORE_RSL_H */

View File

@@ -1,22 +0,0 @@
#ifndef _OSMOCORE_RXLEV_STATS_H
#define _OSMOCORE_RXLEV_STATS_H
#define NUM_RXLEVS 32
#define NUM_ARFCNS 1024
struct rxlev_stats {
/* the maximum number of ARFCN's is 1024, and there are 32 RxLevels,
* so in we keep one 1024bit-bitvec for each RxLev */
uint8_t rxlev_buckets[NUM_RXLEVS][NUM_ARFCNS/8];
};
void rxlev_stat_input(struct rxlev_stats *st, uint16_t arfcn, uint8_t rxlev);
/* get the next ARFCN that has the specified Rxlev */
int16_t rxlev_stat_get_next(const struct rxlev_stats *st, uint8_t rxlev, int16_t arfcn);
void rxlev_stat_reset(struct rxlev_stats *st);
void rxlev_stat_dump(const struct rxlev_stats *st);
#endif /* _OSMOCORE_RXLEV_STATS_H */

View File

@@ -1,15 +0,0 @@
#ifndef OSMOCORE_SIGNAL_H
#define OSMOCORE_SIGNAL_H
typedef int signal_cbfn(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data);
/* Management */
int register_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data);
void unregister_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data);
/* Dispatch */
void dispatch_signal(unsigned int subsys, unsigned int signal, void *signal_data);
#endif /* OSMOCORE_SIGNAL_H */

View File

@@ -1,31 +0,0 @@
#ifndef _STATISTICS_H
#define _STATISTICS_H
struct counter {
struct llist_head list;
const char *name;
const char *description;
unsigned long value;
};
static inline void counter_inc(struct counter *ctr)
{
ctr->value++;
}
static inline unsigned long counter_get(struct counter *ctr)
{
return ctr->value;
}
static inline void counter_reset(struct counter *ctr)
{
ctr->value = 0;
}
struct counter *counter_alloc(const char *name);
void counter_free(struct counter *ctr);
int counters_for_each(int (*handle_counter)(struct counter *, void *), void *data);
#endif /* _STATISTICS_H */

View File

@@ -1,244 +0,0 @@
#ifndef _TLV_H
#define _TLV_H
#include <stdint.h>
#include <string.h>
#include <osmocore/msgb.h>
/* Terminology / wording
tag length value (in bits)
V - - 8
LV - 8 N * 8
TLV 8 8 N * 8
TL16V 8 16 N * 8
TLV16 8 8 N * 16
TvLV 8 8/16 N * 8
*/
#define LV_GROSS_LEN(x) (x+1)
#define TLV_GROSS_LEN(x) (x+2)
#define TLV16_GROSS_LEN(x) ((2*x)+2)
#define TL16V_GROSS_LEN(x) (x+3)
#define L16TV_GROSS_LEN(x) (x+3)
#define TVLV_MAX_ONEBYTE 0x7f
static inline uint16_t TVLV_GROSS_LEN(uint16_t len)
{
if (len <= TVLV_MAX_ONEBYTE)
return TLV_GROSS_LEN(len);
else
return TL16V_GROSS_LEN(len);
}
/* TLV generation */
static inline uint8_t *lv_put(uint8_t *buf, uint8_t len,
const uint8_t *val)
{
*buf++ = len;
memcpy(buf, val, len);
return buf + len;
}
static inline uint8_t *tlv_put(uint8_t *buf, uint8_t tag, uint8_t len,
const uint8_t *val)
{
*buf++ = tag;
*buf++ = len;
memcpy(buf, val, len);
return buf + len;
}
static inline uint8_t *tlv16_put(uint8_t *buf, uint8_t tag, uint8_t len,
const uint16_t *val)
{
*buf++ = tag;
*buf++ = len;
memcpy(buf, val, len*2);
return buf + len*2;
}
static inline uint8_t *tl16v_put(uint8_t *buf, uint8_t tag, uint16_t len,
const uint8_t *val)
{
*buf++ = tag;
*buf++ = len >> 8;
*buf++ = len & 0xff;
memcpy(buf, val, len);
return buf + len*2;
}
static inline uint8_t *tvlv_put(uint8_t *buf, uint8_t tag, uint16_t len,
const uint8_t *val)
{
uint8_t *ret;
if (len <= TVLV_MAX_ONEBYTE) {
ret = tlv_put(buf, tag, len, val);
buf[1] |= 0x80;
} else
ret = tl16v_put(buf, tag, len, val);
return ret;
}
static inline uint8_t *msgb_tlv16_put(struct msgb *msg, uint8_t tag, uint8_t len, const uint16_t *val)
{
uint8_t *buf = msgb_put(msg, TLV16_GROSS_LEN(len));
return tlv16_put(buf, tag, len, val);
}
static inline uint8_t *msgb_tl16v_put(struct msgb *msg, uint8_t tag, uint16_t len,
const uint8_t *val)
{
uint8_t *buf = msgb_put(msg, TL16V_GROSS_LEN(len));
return tl16v_put(buf, tag, len, val);
}
static inline uint8_t *msgb_tvlv_put(struct msgb *msg, uint8_t tag, uint16_t len,
const uint8_t *val)
{
uint8_t *buf = msgb_put(msg, TVLV_GROSS_LEN(len));
return tvlv_put(buf, tag, len, val);
}
static inline uint8_t *msgb_l16tv_put(struct msgb *msg, uint16_t len, uint8_t tag,
const uint8_t *val)
{
uint8_t *buf = msgb_put(msg, L16TV_GROSS_LEN(len));
*buf++ = len >> 8;
*buf++ = len & 0xff;
*buf++ = tag;
memcpy(buf, val, len);
return buf + len;
}
static inline uint8_t *v_put(uint8_t *buf, uint8_t val)
{
*buf++ = val;
return buf;
}
static inline uint8_t *tv_put(uint8_t *buf, uint8_t tag,
uint8_t val)
{
*buf++ = tag;
*buf++ = val;
return buf;
}
/* 'val' is still in host byte order! */
static inline uint8_t *tv16_put(uint8_t *buf, uint8_t tag,
uint16_t val)
{
*buf++ = tag;
*buf++ = val >> 8;
*buf++ = val & 0xff;
return buf;
}
static inline uint8_t *msgb_lv_put(struct msgb *msg, uint8_t len, const uint8_t *val)
{
uint8_t *buf = msgb_put(msg, LV_GROSS_LEN(len));
return lv_put(buf, len, val);
}
static inline uint8_t *msgb_tlv_put(struct msgb *msg, uint8_t tag, uint8_t len, const uint8_t *val)
{
uint8_t *buf = msgb_put(msg, TLV_GROSS_LEN(len));
return tlv_put(buf, tag, len, val);
}
static inline uint8_t *msgb_tv_put(struct msgb *msg, uint8_t tag, uint8_t val)
{
uint8_t *buf = msgb_put(msg, 2);
return tv_put(buf, tag, val);
}
static inline uint8_t *msgb_v_put(struct msgb *msg, uint8_t val)
{
uint8_t *buf = msgb_put(msg, 1);
return v_put(buf, val);
}
static inline uint8_t *msgb_tv16_put(struct msgb *msg, uint8_t tag, uint16_t val)
{
uint8_t *buf = msgb_put(msg, 3);
return tv16_put(buf, tag, val);
}
static inline uint8_t *msgb_tlv_push(struct msgb *msg, uint8_t tag, uint8_t len, const uint8_t *val)
{
uint8_t *buf = msgb_push(msg, TLV_GROSS_LEN(len));
return tlv_put(buf, tag, len, val);
}
static inline uint8_t *msgb_tv_push(struct msgb *msg, uint8_t tag, uint8_t val)
{
uint8_t *buf = msgb_push(msg, 2);
return tv_put(buf, tag, val);
}
static inline uint8_t *msgb_tv16_push(struct msgb *msg, uint8_t tag, uint16_t val)
{
uint8_t *buf = msgb_push(msg, 3);
return tv16_put(buf, tag, val);
}
static inline uint8_t *msgb_tvlv_push(struct msgb *msg, uint8_t tag, uint16_t len,
const uint8_t *val)
{
uint8_t *buf = msgb_push(msg, TVLV_GROSS_LEN(len));
return tvlv_put(buf, tag, len, val);
}
/* TLV parsing */
struct tlv_p_entry {
uint16_t len;
const uint8_t *val;
};
enum tlv_type {
TLV_TYPE_NONE,
TLV_TYPE_FIXED,
TLV_TYPE_T,
TLV_TYPE_TV,
TLV_TYPE_TLV,
TLV_TYPE_TL16V,
TLV_TYPE_TvLV,
};
struct tlv_def {
enum tlv_type type;
uint8_t fixed_len;
};
struct tlv_definition {
struct tlv_def def[0xff];
};
struct tlv_parsed {
struct tlv_p_entry lv[0xff];
};
extern struct tlv_definition tvlv_att_def;
int tlv_parse_one(uint8_t *o_tag, uint16_t *o_len, const uint8_t **o_val,
const struct tlv_definition *def,
const uint8_t *buf, int buf_len);
int tlv_parse(struct tlv_parsed *dec, const struct tlv_definition *def,
const uint8_t *buf, int buf_len, uint8_t lv_tag, uint8_t lv_tag2);
/* take a master (src) tlvdev and fill up all empty slots in 'dst' */
void tlv_def_patch(struct tlv_definition *dst, const struct tlv_definition *src);
#define TLVP_PRESENT(x, y) ((x)->lv[y].val)
#define TLVP_LEN(x, y) (x)->lv[y].len
#define TLVP_VAL(x, y) (x)->lv[y].val
#endif /* _TLV_H */

View File

@@ -1,20 +0,0 @@
#ifndef OSMOCORE_UTIL_H
#define OSMOCORE_UTIL_H
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#include <stdint.h>
struct value_string {
unsigned int value;
const char *str;
};
const char *get_value_string(const struct value_string *vs, uint32_t val);
int get_string_value(const struct value_string *vs, const char *str);
char bcd2char(uint8_t bcd);
/* only works for numbers in ascci */
uint8_t char2bcd(char c);
#endif

View File

@@ -1,11 +0,0 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: Osmocom Core Library
Description: C Utility Library
Version: @VERSION@
Libs: -L${libdir} -losmocore
Cflags: -I${includedir}/

View File

@@ -1,16 +0,0 @@
# This is _NOT_ the library release version, it's an API version.
# Please read Chapter 6 "Library interface versions" of the libtool documentation before making any modification
LIBVERSION=0:0:0
INCLUDES = $(all_includes) -I$(top_srcdir)/include
AM_CFLAGS = -fPIC -Wall
lib_LTLIBRARIES = libosmocore.la
libosmocore_la_SOURCES = timer.c select.c signal.c msgb.c rxlev_stat.c \
tlv_parser.c bitvec.c comp128.c gsm_utils.c statistics.c \
write_queue.c utils.c rsl.c gsm48.c gsm48_ie.c
if ENABLE_TALLOC
libosmocore_la_SOURCES += talloc.c
endif

View File

@@ -1,230 +0,0 @@
/*
* COMP128 implementation
*
*
* This code is inspired by original code from :
* Marc Briceno <marc@scard.org>, Ian Goldberg <iang@cs.berkeley.edu>,
* and David Wagner <daw@cs.berkeley.edu>
*
* But it has been fully rewritten from various PDFs found online describing
* the algorithm because the licence of the code referenced above was unclear.
* A comment snippet from the original code is included below, it describes
* where the doc came from and how the algorithm was reverse engineered.
*
*
* (C) 2009 by Sylvain Munaut <tnt@246tNt.com>
*
* 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 2 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
/*
* --- SNIP ---
*
* This code derived from a leaked document from the GSM standards.
* Some missing pieces were filled in by reverse-engineering a working SIM.
* We have verified that this is the correct COMP128 algorithm.
*
* The first page of the document identifies it as
* _Technical Information: GSM System Security Study_.
* 10-1617-01, 10th June 1988.
* The bottom of the title page is marked
* Racal Research Ltd.
* Worton Drive, Worton Grange Industrial Estate,
* Reading, Berks. RG2 0SB, England.
* Telephone: Reading (0734) 868601 Telex: 847152
* The relevant bits are in Part I, Section 20 (pages 66--67). Enjoy!
*
* Note: There are three typos in the spec (discovered by
* reverse-engineering).
* First, "z = (2 * x[n] + x[n]) mod 2^(9-j)" should clearly read
* "z = (2 * x[m] + x[n]) mod 2^(9-j)".
* Second, the "k" loop in the "Form bits from bytes" section is severely
* botched: the k index should run only from 0 to 3, and clearly the range
* on "the (8-k)th bit of byte j" is also off (should be 0..7, not 1..8,
* to be consistent with the subsequent section).
* Third, SRES is taken from the first 8 nibbles of x[], not the last 8 as
* claimed in the document. (And the document doesn't specify how Kc is
* derived, but that was also easily discovered with reverse engineering.)
* All of these typos have been corrected in the following code.
*
* --- /SNIP ---
*/
#include <string.h>
#include <stdint.h>
/* The compression tables (just copied ...) */
static const uint8_t table_0[512] = {
102, 177, 186, 162, 2, 156, 112, 75, 55, 25, 8, 12, 251, 193, 246, 188,
109, 213, 151, 53, 42, 79, 191, 115, 233, 242, 164, 223, 209, 148, 108, 161,
252, 37, 244, 47, 64, 211, 6, 237, 185, 160, 139, 113, 76, 138, 59, 70,
67, 26, 13, 157, 63, 179, 221, 30, 214, 36, 166, 69, 152, 124, 207, 116,
247, 194, 41, 84, 71, 1, 49, 14, 95, 35, 169, 21, 96, 78, 215, 225,
182, 243, 28, 92, 201, 118, 4, 74, 248, 128, 17, 11, 146, 132, 245, 48,
149, 90, 120, 39, 87, 230, 106, 232, 175, 19, 126, 190, 202, 141, 137, 176,
250, 27, 101, 40, 219, 227, 58, 20, 51, 178, 98, 216, 140, 22, 32, 121,
61, 103, 203, 72, 29, 110, 85, 212, 180, 204, 150, 183, 15, 66, 172, 196,
56, 197, 158, 0, 100, 45, 153, 7, 144, 222, 163, 167, 60, 135, 210, 231,
174, 165, 38, 249, 224, 34, 220, 229, 217, 208, 241, 68, 206, 189, 125, 255,
239, 54, 168, 89, 123, 122, 73, 145, 117, 234, 143, 99, 129, 200, 192, 82,
104, 170, 136, 235, 93, 81, 205, 173, 236, 94, 105, 52, 46, 228, 198, 5,
57, 254, 97, 155, 142, 133, 199, 171, 187, 50, 65, 181, 127, 107, 147, 226,
184, 218, 131, 33, 77, 86, 31, 44, 88, 62, 238, 18, 24, 43, 154, 23,
80, 159, 134, 111, 9, 114, 3, 91, 16, 130, 83, 10, 195, 240, 253, 119,
177, 102, 162, 186, 156, 2, 75, 112, 25, 55, 12, 8, 193, 251, 188, 246,
213, 109, 53, 151, 79, 42, 115, 191, 242, 233, 223, 164, 148, 209, 161, 108,
37, 252, 47, 244, 211, 64, 237, 6, 160, 185, 113, 139, 138, 76, 70, 59,
26, 67, 157, 13, 179, 63, 30, 221, 36, 214, 69, 166, 124, 152, 116, 207,
194, 247, 84, 41, 1, 71, 14, 49, 35, 95, 21, 169, 78, 96, 225, 215,
243, 182, 92, 28, 118, 201, 74, 4, 128, 248, 11, 17, 132, 146, 48, 245,
90, 149, 39, 120, 230, 87, 232, 106, 19, 175, 190, 126, 141, 202, 176, 137,
27, 250, 40, 101, 227, 219, 20, 58, 178, 51, 216, 98, 22, 140, 121, 32,
103, 61, 72, 203, 110, 29, 212, 85, 204, 180, 183, 150, 66, 15, 196, 172,
197, 56, 0, 158, 45, 100, 7, 153, 222, 144, 167, 163, 135, 60, 231, 210,
165, 174, 249, 38, 34, 224, 229, 220, 208, 217, 68, 241, 189, 206, 255, 125,
54, 239, 89, 168, 122, 123, 145, 73, 234, 117, 99, 143, 200, 129, 82, 192,
170, 104, 235, 136, 81, 93, 173, 205, 94, 236, 52, 105, 228, 46, 5, 198,
254, 57, 155, 97, 133, 142, 171, 199, 50, 187, 181, 65, 107, 127, 226, 147,
218, 184, 33, 131, 86, 77, 44, 31, 62, 88, 18, 238, 43, 24, 23, 154,
159, 80, 111, 134, 114, 9, 91, 3, 130, 16, 10, 83, 240, 195, 119, 253,
}, table_1[256] = {
19, 11, 80, 114, 43, 1, 69, 94, 39, 18, 127, 117, 97, 3, 85, 43,
27, 124, 70, 83, 47, 71, 63, 10, 47, 89, 79, 4, 14, 59, 11, 5,
35, 107, 103, 68, 21, 86, 36, 91, 85, 126, 32, 50, 109, 94, 120, 6,
53, 79, 28, 45, 99, 95, 41, 34, 88, 68, 93, 55, 110, 125, 105, 20,
90, 80, 76, 96, 23, 60, 89, 64, 121, 56, 14, 74, 101, 8, 19, 78,
76, 66, 104, 46, 111, 50, 32, 3, 39, 0, 58, 25, 92, 22, 18, 51,
57, 65, 119, 116, 22, 109, 7, 86, 59, 93, 62, 110, 78, 99, 77, 67,
12, 113, 87, 98, 102, 5, 88, 33, 38, 56, 23, 8, 75, 45, 13, 75,
95, 63, 28, 49, 123, 120, 20, 112, 44, 30, 15, 98, 106, 2, 103, 29,
82, 107, 42, 124, 24, 30, 41, 16, 108, 100, 117, 40, 73, 40, 7, 114,
82, 115, 36, 112, 12, 102, 100, 84, 92, 48, 72, 97, 9, 54, 55, 74,
113, 123, 17, 26, 53, 58, 4, 9, 69, 122, 21, 118, 42, 60, 27, 73,
118, 125, 34, 15, 65, 115, 84, 64, 62, 81, 70, 1, 24, 111, 121, 83,
104, 81, 49, 127, 48, 105, 31, 10, 6, 91, 87, 37, 16, 54, 116, 126,
31, 38, 13, 0, 72, 106, 77, 61, 26, 67, 46, 29, 96, 37, 61, 52,
101, 17, 44, 108, 71, 52, 66, 57, 33, 51, 25, 90, 2, 119, 122, 35,
}, table_2[128] = {
52, 50, 44, 6, 21, 49, 41, 59, 39, 51, 25, 32, 51, 47, 52, 43,
37, 4, 40, 34, 61, 12, 28, 4, 58, 23, 8, 15, 12, 22, 9, 18,
55, 10, 33, 35, 50, 1, 43, 3, 57, 13, 62, 14, 7, 42, 44, 59,
62, 57, 27, 6, 8, 31, 26, 54, 41, 22, 45, 20, 39, 3, 16, 56,
48, 2, 21, 28, 36, 42, 60, 33, 34, 18, 0, 11, 24, 10, 17, 61,
29, 14, 45, 26, 55, 46, 11, 17, 54, 46, 9, 24, 30, 60, 32, 0,
20, 38, 2, 30, 58, 35, 1, 16, 56, 40, 23, 48, 13, 19, 19, 27,
31, 53, 47, 38, 63, 15, 49, 5, 37, 53, 25, 36, 63, 29, 5, 7,
}, table_3[64] = {
1, 5, 29, 6, 25, 1, 18, 23, 17, 19, 0, 9, 24, 25, 6, 31,
28, 20, 24, 30, 4, 27, 3, 13, 15, 16, 14, 18, 4, 3, 8, 9,
20, 0, 12, 26, 21, 8, 28, 2, 29, 2, 15, 7, 11, 22, 14, 10,
17, 21, 12, 30, 26, 27, 16, 31, 11, 7, 13, 23, 10, 5, 22, 19,
}, table_4[32] = {
15, 12, 10, 4, 1, 14, 11, 7, 5, 0, 14, 7, 1, 2, 13, 8,
10, 3, 4, 9, 6, 0, 3, 2, 5, 6, 8, 9, 11, 13, 15, 12,
};
static const uint8_t *_comp128_table[5] = { table_0, table_1, table_2, table_3, table_4 };
static inline void
_comp128_compression_round(uint8_t *x, int n, const uint8_t *tbl)
{
int i, j, m, a, b, y, z;
m = 4 - n;
for (i=0; i<(1<<n); i++)
for (j=0; j<(1<<m); j++) {
a = j + i * (2<<m);
b = a + (1<<m);
y = (x[a] + (x[b]<<1)) & ((32<<m)-1);
z = ((x[a]<<1) + x[b]) & ((32<<m)-1);
x[a] = tbl[y];
x[b] = tbl[z];
}
}
static inline void
_comp128_compression(uint8_t *x)
{
int n;
for (n=0; n<5; n++)
_comp128_compression_round(x, n, _comp128_table[n]);
}
static inline void
_comp128_bitsfrombytes(uint8_t *x, uint8_t *bits)
{
int i;
memset(bits, 0x00, 128);
for (i=0; i<128; i++)
if (x[i>>2] & (1<<(3-(i&3))))
bits[i] = 1;
}
static inline void
_comp128_permutation(uint8_t *x, uint8_t *bits)
{
int i;
memset(&x[16], 0x00, 16);
for (i=0; i<128; i++)
x[(i>>3)+16] |= bits[(i*17) & 127] << (7-(i&7));
}
void
comp128(uint8_t *ki, uint8_t *rand, uint8_t *sres, uint8_t *kc)
{
int i;
uint8_t x[32], bits[128];
/* x[16-31] = RAND */
memcpy(&x[16], rand, 16);
/* Round 1-7 */
for (i=0; i<7; i++) {
/* x[0-15] = Ki */
memcpy(x, ki, 16);
/* Compression */
_comp128_compression(x);
/* FormBitFromBytes */
_comp128_bitsfrombytes(x, bits);
/* Permutation */
_comp128_permutation(x, bits);
}
/* Round 8 (final) */
/* x[0-15] = Ki */
memcpy(x, ki, 16);
/* Compression */
_comp128_compression(x);
/* Output stage */
for (i=0; i<8; i+=2)
sres[i>>1] = x[i]<<4 | x[i+1];
for (i=0; i<12; i+=2)
kc[i>>1] = (x[i + 18] << 6) |
(x[i + 19] << 2) |
(x[i + 20] >> 2);
kc[6] = (x[30]<<6) | (x[31]<<2);
kc[7] = 0;
}

View File

@@ -1,283 +0,0 @@
/* GSM Mobile Radio Interface Layer 3 messages
* 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
* (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
*
* 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 2 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <osmocore/utils.h>
#include <osmocore/tlv.h>
#include <osmocore/gsm48.h>
#include <osmocore/protocol/gsm_04_08.h>
const struct tlv_definition gsm48_att_tlvdef = {
.def = {
[GSM48_IE_MOBILE_ID] = { TLV_TYPE_TLV },
[GSM48_IE_NAME_LONG] = { TLV_TYPE_TLV },
[GSM48_IE_NAME_SHORT] = { TLV_TYPE_TLV },
[GSM48_IE_UTC] = { TLV_TYPE_TV },
[GSM48_IE_NET_TIME_TZ] = { TLV_TYPE_FIXED, 7 },
[GSM48_IE_LSA_IDENT] = { TLV_TYPE_TLV },
[GSM48_IE_BEARER_CAP] = { TLV_TYPE_TLV },
[GSM48_IE_CAUSE] = { TLV_TYPE_TLV },
[GSM48_IE_CC_CAP] = { TLV_TYPE_TLV },
[GSM48_IE_ALERT] = { TLV_TYPE_TLV },
[GSM48_IE_FACILITY] = { TLV_TYPE_TLV },
[GSM48_IE_PROGR_IND] = { TLV_TYPE_TLV },
[GSM48_IE_AUX_STATUS] = { TLV_TYPE_TLV },
[GSM48_IE_NOTIFY] = { TLV_TYPE_TV },
[GSM48_IE_KPD_FACILITY] = { TLV_TYPE_TV },
[GSM48_IE_SIGNAL] = { TLV_TYPE_TV },
[GSM48_IE_CONN_BCD] = { TLV_TYPE_TLV },
[GSM48_IE_CONN_SUB] = { TLV_TYPE_TLV },
[GSM48_IE_CALLING_BCD] = { TLV_TYPE_TLV },
[GSM48_IE_CALLING_SUB] = { TLV_TYPE_TLV },
[GSM48_IE_CALLED_BCD] = { TLV_TYPE_TLV },
[GSM48_IE_CALLED_SUB] = { TLV_TYPE_TLV },
[GSM48_IE_REDIR_BCD] = { TLV_TYPE_TLV },
[GSM48_IE_REDIR_SUB] = { TLV_TYPE_TLV },
[GSM48_IE_LOWL_COMPAT] = { TLV_TYPE_TLV },
[GSM48_IE_HIGHL_COMPAT] = { TLV_TYPE_TLV },
[GSM48_IE_USER_USER] = { TLV_TYPE_TLV },
[GSM48_IE_SS_VERS] = { TLV_TYPE_TLV },
[GSM48_IE_MORE_DATA] = { TLV_TYPE_T },
[GSM48_IE_CLIR_SUPP] = { TLV_TYPE_T },
[GSM48_IE_CLIR_INVOC] = { TLV_TYPE_T },
[GSM48_IE_REV_C_SETUP] = { TLV_TYPE_T },
[GSM48_IE_REPEAT_CIR] = { TLV_TYPE_T },
[GSM48_IE_REPEAT_SEQ] = { TLV_TYPE_T },
/* FIXME: more elements */
},
};
static const char *rr_cause_names[] = {
[GSM48_RR_CAUSE_NORMAL] = "Normal event",
[GSM48_RR_CAUSE_ABNORMAL_UNSPEC] = "Abnormal release, unspecified",
[GSM48_RR_CAUSE_ABNORMAL_UNACCT] = "Abnormal release, channel unacceptable",
[GSM48_RR_CAUSE_ABNORMAL_TIMER] = "Abnormal release, timer expired",
[GSM48_RR_CAUSE_ABNORMAL_NOACT] = "Abnormal release, no activity on radio path",
[GSM48_RR_CAUSE_PREMPTIVE_REL] = "Preemptive release",
[GSM48_RR_CAUSE_HNDOVER_IMP] = "Handover impossible, timing advance out of range",
[GSM48_RR_CAUSE_CHAN_MODE_UNACCT] = "Channel mode unacceptable",
[GSM48_RR_CAUSE_FREQ_NOT_IMPL] = "Frequency not implemented",
[GSM48_RR_CAUSE_CALL_CLEARED] = "Call already cleared",
[GSM48_RR_CAUSE_SEMANT_INCORR] = "Semantically incorrect message",
[GSM48_RR_CAUSE_INVALID_MAND_INF] = "Invalid mandatory information",
[GSM48_RR_CAUSE_MSG_TYPE_N] = "Message type non-existant or not implemented",
[GSM48_RR_CAUSE_MSG_TYPE_N_COMPAT] = "Message type not compatible with protocol state",
[GSM48_RR_CAUSE_COND_IE_ERROR] = "Conditional IE error",
[GSM48_RR_CAUSE_NO_CELL_ALLOC_A] = "No cell allocation available",
[GSM48_RR_CAUSE_PROT_ERROR_UNSPC] = "Protocol error unspecified",
};
const char *cc_state_names[32] = {
"NULL",
"INITIATED",
"illegal state 2",
"MO_CALL_PROC",
"CALL_DELIVERED",
"illegal state 5",
"CALL_PRESENT",
"CALL_RECEIVED",
"CONNECT_REQUEST",
"MO_TERM_CALL_CONF",
"ACTIVE",
"DISCONNECT_REQ",
"DISCONNECT_IND",
"illegal state 13",
"illegal state 14",
"illegal state 15",
"illegal state 16",
"illegal state 17",
"illegal state 18",
"RELEASE_REQ",
"illegal state 20",
"illegal state 21",
"illegal state 22",
"illegal state 23",
"illegal state 24",
"illegal state 25",
"MO_ORIG_MODIFY",
"MO_TERM_MODIFY",
"CONNECT_IND",
"illegal state 29",
"illegal state 30",
"illegal state 31",
};
const char *gsm48_cc_msg_names[0x40] = {
"unknown 0x00",
"ALERTING",
"CALL_PROC",
"PROGRESS",
"ESTAB",
"SETUP",
"ESTAB_CONF",
"CONNECT",
"CALL_CONF",
"START_CC",
"unknown 0x0a",
"RECALL",
"unknown 0x0c",
"unknown 0x0d",
"EMERG_SETUP",
"CONNECT_ACK",
"USER_INFO",
"unknown 0x11",
"unknown 0x12",
"MODIFY_REJECT",
"unknown 0x14",
"unknown 0x15",
"unknown 0x16",
"MODIFY",
"HOLD",
"HOLD_ACK",
"HOLD_REJ",
"unknown 0x1b",
"RETR",
"RETR_ACK",
"RETR_REJ",
"MODIFY_COMPL",
"unknown 0x20",
"unknown 0x21",
"unknown 0x22",
"unknown 0x23",
"unknown 0x24",
"DISCONNECT",
"unknown 0x26",
"unknown 0x27",
"unknown 0x28",
"unknown 0x29",
"RELEASE_COMPL",
"unknown 0x2b",
"unknown 0x2c",
"RELEASE",
"unknown 0x2e",
"unknown 0x2f",
"unknown 0x30",
"STOP_DTMF",
"STOP_DTMF_ACK",
"unknown 0x33",
"STATUS_ENQ",
"START_DTMF",
"START_DTMF_ACK",
"START_DTMF_REJ",
"unknown 0x38",
"CONG_CTRL",
"FACILITY",
"unknown 0x3b",
"STATUS",
"unknown 0x3d",
"NOTIFY",
"unknown 0x3f",
};
static char strbuf[64];
const char *rr_cause_name(uint8_t cause)
{
if (cause < ARRAY_SIZE(rr_cause_names) &&
rr_cause_names[cause])
return rr_cause_names[cause];
snprintf(strbuf, sizeof(strbuf), "0x%02x", cause);
return strbuf;
}
static void to_bcd(uint8_t *bcd, uint16_t val)
{
bcd[2] = val % 10;
val = val / 10;
bcd[1] = val % 10;
val = val / 10;
bcd[0] = val % 10;
val = val / 10;
}
void gsm48_generate_lai(struct gsm48_loc_area_id *lai48, uint16_t mcc,
uint16_t mnc, uint16_t lac)
{
uint8_t bcd[3];
to_bcd(bcd, mcc);
lai48->digits[0] = bcd[0] | (bcd[1] << 4);
lai48->digits[1] = bcd[2];
to_bcd(bcd, mnc);
/* FIXME: do we need three-digit MNC? See Table 10.5.3 */
#if 0
lai48->digits[1] |= bcd[2] << 4;
lai48->digits[2] = bcd[0] | (bcd[1] << 4);
#else
lai48->digits[1] |= 0xf << 4;
lai48->digits[2] = bcd[1] | (bcd[2] << 4);
#endif
lai48->lac = htons(lac);
}
int gsm48_generate_mid_from_tmsi(uint8_t *buf, uint32_t tmsi)
{
uint32_t *tptr = (uint32_t *) &buf[3];
buf[0] = GSM48_IE_MOBILE_ID;
buf[1] = GSM48_TMSI_LEN;
buf[2] = 0xf0 | GSM_MI_TYPE_TMSI;
*tptr = htonl(tmsi);
return 7;
}
int gsm48_generate_mid_from_imsi(uint8_t *buf, const char *imsi)
{
unsigned int length = strlen(imsi), i, off = 0;
uint8_t odd = (length & 0x1) == 1;
buf[0] = GSM48_IE_MOBILE_ID;
buf[2] = char2bcd(imsi[0]) << 4 | GSM_MI_TYPE_IMSI | (odd << 3);
/* if the length is even we will fill half of the last octet */
if (odd)
buf[1] = (length + 1) >> 1;
else
buf[1] = (length + 2) >> 1;
for (i = 1; i < buf[1]; ++i) {
uint8_t lower, upper;
lower = char2bcd(imsi[++off]);
if (!odd && off + 1 == length)
upper = 0x0f;
else
upper = char2bcd(imsi[++off]) & 0x0f;
buf[2 + i] = (upper << 4) | lower;
}
return 2 + buf[1];
}

View File

@@ -1,659 +0,0 @@
/* GSM Mobile Radio Interface Layer 3 messages
* 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
/* (C) 2008 by Harald Welte <laforge@gnumonks.org>
* (C) 2008-2010 by Andreas Eversberg
*
* 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 2 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <osmocore/utils.h>
#include <osmocore/msgb.h>
#include <osmocore/tlv.h>
#include <osmocore/mncc.h>
#include <osmocore/protocol/gsm_04_08.h>
static const char bcd_num_digits[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '*', '#', 'a', 'b', 'c', '\0'
};
/* decode a 'called/calling/connect party BCD number' as in 10.5.4.7 */
int gsm48_decode_bcd_number(char *output, int output_len,
const uint8_t *bcd_lv, int h_len)
{
uint8_t in_len = bcd_lv[0];
int i;
for (i = 1 + h_len; i <= in_len; i++) {
/* lower nibble */
output_len--;
if (output_len <= 1)
break;
*output++ = bcd_num_digits[bcd_lv[i] & 0xf];
/* higher nibble */
output_len--;
if (output_len <= 1)
break;
*output++ = bcd_num_digits[bcd_lv[i] >> 4];
}
if (output_len >= 1)
*output++ = '\0';
return 0;
}
/* convert a single ASCII character to call-control BCD */
static int asc_to_bcd(const char asc)
{
int i;
for (i = 0; i < ARRAY_SIZE(bcd_num_digits); i++) {
if (bcd_num_digits[i] == asc)
return i;
}
return -EINVAL;
}
/* convert a ASCII phone number to 'called/calling/connect party BCD number' */
int gsm48_encode_bcd_number(uint8_t *bcd_lv, uint8_t max_len,
int h_len, const char *input)
{
int in_len = strlen(input);
int i;
uint8_t *bcd_cur = bcd_lv + 1 + h_len;
/* two digits per byte, plus type byte */
bcd_lv[0] = in_len/2 + h_len;
if (in_len % 2)
bcd_lv[0]++;
if (bcd_lv[0] > max_len)
return -EIO;
for (i = 0; i < in_len; i++) {
int rc = asc_to_bcd(input[i]);
if (rc < 0)
return rc;
if (i % 2 == 0)
*bcd_cur = rc;
else
*bcd_cur++ |= (rc << 4);
}
/* append padding nibble in case of odd length */
if (i % 2)
*bcd_cur++ |= 0xf0;
/* return how many bytes we used */
return (bcd_cur - bcd_lv);
}
/* decode 'bearer capability' */
int gsm48_decode_bearer_cap(struct gsm_mncc_bearer_cap *bcap,
const uint8_t *lv)
{
uint8_t in_len = lv[0];
int i, s;
if (in_len < 1)
return -EINVAL;
bcap->speech_ver[0] = -1; /* end of list, of maximum 7 values */
/* octet 3 */
bcap->transfer = lv[1] & 0x07;
bcap->mode = (lv[1] & 0x08) >> 3;
bcap->coding = (lv[1] & 0x10) >> 4;
bcap->radio = (lv[1] & 0x60) >> 5;
if (bcap->transfer == GSM_MNCC_BCAP_SPEECH) {
i = 1;
s = 0;
while(!(lv[i] & 0x80)) {
i++; /* octet 3a etc */
if (in_len < i)
return 0;
bcap->speech_ver[s++] = lv[i] & 0x0f;
bcap->speech_ver[s] = -1; /* end of list */
if (i == 2) /* octet 3a */
bcap->speech_ctm = (lv[i] & 0x20) >> 5;
if (s == 7) /* maximum speech versions + end of list */
return 0;
}
} else {
i = 1;
while (!(lv[i] & 0x80)) {
i++; /* octet 3a etc */
if (in_len < i)
return 0;
/* ignore them */
}
/* FIXME: implement OCTET 4+ parsing */
}
return 0;
}
/* encode 'bearer capability' */
int gsm48_encode_bearer_cap(struct msgb *msg, int lv_only,
const struct gsm_mncc_bearer_cap *bcap)
{
uint8_t lv[32 + 1];
int i = 1, s;
lv[1] = bcap->transfer;
lv[1] |= bcap->mode << 3;
lv[1] |= bcap->coding << 4;
lv[1] |= bcap->radio << 5;
if (bcap->transfer == GSM_MNCC_BCAP_SPEECH) {
for (s = 0; bcap->speech_ver[s] >= 0; s++) {
i++; /* octet 3a etc */
lv[i] = bcap->speech_ver[s];
if (i == 2) /* octet 3a */
lv[i] |= bcap->speech_ctm << 5;
}
lv[i] |= 0x80; /* last IE of octet 3 etc */
} else {
/* FIXME: implement OCTET 4+ encoding */
}
lv[0] = i;
if (lv_only)
msgb_lv_put(msg, lv[0], lv+1);
else
msgb_tlv_put(msg, GSM48_IE_BEARER_CAP, lv[0], lv+1);
return 0;
}
/* decode 'call control cap' */
int gsm48_decode_cccap(struct gsm_mncc_cccap *ccap, const uint8_t *lv)
{
uint8_t in_len = lv[0];
if (in_len < 1)
return -EINVAL;
/* octet 3 */
ccap->dtmf = lv[1] & 0x01;
ccap->pcp = (lv[1] & 0x02) >> 1;
return 0;
}
/* encode 'call control cap' */
int gsm48_encode_cccap(struct msgb *msg,
const struct gsm_mncc_cccap *ccap)
{
uint8_t lv[2];
lv[0] = 1;
lv[1] = 0;
if (ccap->dtmf)
lv [1] |= 0x01;
if (ccap->pcp)
lv [1] |= 0x02;
msgb_tlv_put(msg, GSM48_IE_CC_CAP, lv[0], lv+1);
return 0;
}
/* decode 'called party BCD number' */
int gsm48_decode_called(struct gsm_mncc_number *called,
const uint8_t *lv)
{
uint8_t in_len = lv[0];
if (in_len < 1)
return -EINVAL;
/* octet 3 */
called->plan = lv[1] & 0x0f;
called->type = (lv[1] & 0x70) >> 4;
/* octet 4..N */
gsm48_decode_bcd_number(called->number, sizeof(called->number), lv, 1);
return 0;
}
/* encode 'called party BCD number' */
int gsm48_encode_called(struct msgb *msg,
const struct gsm_mncc_number *called)
{
uint8_t lv[18];
int ret;
/* octet 3 */
lv[1] = called->plan;
lv[1] |= called->type << 4;
/* octet 4..N, octet 2 */
ret = gsm48_encode_bcd_number(lv, sizeof(lv), 1, called->number);
if (ret < 0)
return ret;
msgb_tlv_put(msg, GSM48_IE_CALLED_BCD, lv[0], lv+1);
return 0;
}
/* decode callerid of various IEs */
int gsm48_decode_callerid(struct gsm_mncc_number *callerid,
const uint8_t *lv)
{
uint8_t in_len = lv[0];
int i = 1;
if (in_len < 1)
return -EINVAL;
/* octet 3 */
callerid->plan = lv[1] & 0x0f;
callerid->type = (lv[1] & 0x70) >> 4;
/* octet 3a */
if (!(lv[1] & 0x80)) {
callerid->screen = lv[2] & 0x03;
callerid->present = (lv[2] & 0x60) >> 5;
i = 2;
}
/* octet 4..N */
gsm48_decode_bcd_number(callerid->number, sizeof(callerid->number), lv, i);
return 0;
}
/* encode callerid of various IEs */
int gsm48_encode_callerid(struct msgb *msg, int ie, int max_len,
const struct gsm_mncc_number *callerid)
{
uint8_t lv[max_len - 1];
int h_len = 1;
int ret;
/* octet 3 */
lv[1] = callerid->plan;
lv[1] |= callerid->type << 4;
if (callerid->present || callerid->screen) {
/* octet 3a */
lv[2] = callerid->screen;
lv[2] |= callerid->present << 5;
lv[2] |= 0x80;
h_len++;
} else
lv[1] |= 0x80;
/* octet 4..N, octet 2 */
ret = gsm48_encode_bcd_number(lv, sizeof(lv), h_len, callerid->number);
if (ret < 0)
return ret;
msgb_tlv_put(msg, ie, lv[0], lv+1);
return 0;
}
/* decode 'cause' */
int gsm48_decode_cause(struct gsm_mncc_cause *cause,
const uint8_t *lv)
{
uint8_t in_len = lv[0];
int i;
if (in_len < 2)
return -EINVAL;
cause->diag_len = 0;
/* octet 3 */
cause->location = lv[1] & 0x0f;
cause->coding = (lv[1] & 0x60) >> 5;
i = 1;
if (!(lv[i] & 0x80)) {
i++; /* octet 3a */
if (in_len < i+1)
return 0;
cause->rec = 1;
cause->rec_val = lv[i] & 0x7f;
}
i++;
/* octet 4 */
cause->value = lv[i] & 0x7f;
i++;
if (in_len < i) /* no diag */
return 0;
if (in_len - (i-1) > 32) /* maximum 32 octets */
return 0;
/* octet 5-N */
memcpy(cause->diag, lv + i, in_len - (i-1));
cause->diag_len = in_len - (i-1);
return 0;
}
/* encode 'cause' */
int gsm48_encode_cause(struct msgb *msg, int lv_only,
const struct gsm_mncc_cause *cause)
{
uint8_t lv[32+4];
int i;
if (cause->diag_len > 32)
return -EINVAL;
/* octet 3 */
lv[1] = cause->location;
lv[1] |= cause->coding << 5;
i = 1;
if (cause->rec) {
i++; /* octet 3a */
lv[i] = cause->rec_val;
}
lv[i] |= 0x80; /* end of octet 3 */
/* octet 4 */
i++;
lv[i] = 0x80 | cause->value;
/* octet 5-N */
if (cause->diag_len) {
memcpy(lv + i, cause->diag, cause->diag_len);
i += cause->diag_len;
}
lv[0] = i;
if (lv_only)
msgb_lv_put(msg, lv[0], lv+1);
else
msgb_tlv_put(msg, GSM48_IE_CAUSE, lv[0], lv+1);
return 0;
}
/* decode 'calling number' */
int gsm48_decode_calling(struct gsm_mncc_number *calling,
const uint8_t *lv)
{
return gsm48_decode_callerid(calling, lv);
}
/* encode 'calling number' */
int gsm48_encode_calling(struct msgb *msg,
const struct gsm_mncc_number *calling)
{
return gsm48_encode_callerid(msg, GSM48_IE_CALLING_BCD, 14, calling);
}
/* decode 'connected number' */
int gsm48_decode_connected(struct gsm_mncc_number *connected,
const uint8_t *lv)
{
return gsm48_decode_callerid(connected, lv);
}
/* encode 'connected number' */
int gsm48_encode_connected(struct msgb *msg,
const struct gsm_mncc_number *connected)
{
return gsm48_encode_callerid(msg, GSM48_IE_CONN_BCD, 14, connected);
}
/* decode 'redirecting number' */
int gsm48_decode_redirecting(struct gsm_mncc_number *redirecting,
const uint8_t *lv)
{
return gsm48_decode_callerid(redirecting, lv);
}
/* encode 'redirecting number' */
int gsm48_encode_redirecting(struct msgb *msg,
const struct gsm_mncc_number *redirecting)
{
return gsm48_encode_callerid(msg, GSM48_IE_REDIR_BCD, 19, redirecting);
}
/* decode 'facility' */
int gsm48_decode_facility(struct gsm_mncc_facility *facility,
const uint8_t *lv)
{
uint8_t in_len = lv[0];
if (in_len < 1)
return -EINVAL;
if (in_len > sizeof(facility->info))
return -EINVAL;
memcpy(facility->info, lv+1, in_len);
facility->len = in_len;
return 0;
}
/* encode 'facility' */
int gsm48_encode_facility(struct msgb *msg, int lv_only,
const struct gsm_mncc_facility *facility)
{
uint8_t lv[GSM_MAX_FACILITY + 1];
if (facility->len < 1 || facility->len > GSM_MAX_FACILITY)
return -EINVAL;
memcpy(lv+1, facility->info, facility->len);
lv[0] = facility->len;
if (lv_only)
msgb_lv_put(msg, lv[0], lv+1);
else
msgb_tlv_put(msg, GSM48_IE_FACILITY, lv[0], lv+1);
return 0;
}
/* decode 'notify' */
int gsm48_decode_notify(int *notify, const uint8_t *v)
{
*notify = v[0] & 0x7f;
return 0;
}
/* encode 'notify' */
int gsm48_encode_notify(struct msgb *msg, int notify)
{
msgb_v_put(msg, notify | 0x80);
return 0;
}
/* decode 'signal' */
int gsm48_decode_signal(int *signal, const uint8_t *v)
{
*signal = v[0];
return 0;
}
/* encode 'signal' */
int gsm48_encode_signal(struct msgb *msg, int signal)
{
msgb_tv_put(msg, GSM48_IE_SIGNAL, signal);
return 0;
}
/* decode 'keypad' */
int gsm48_decode_keypad(int *keypad, const uint8_t *lv)
{
uint8_t in_len = lv[0];
if (in_len < 1)
return -EINVAL;
*keypad = lv[1] & 0x7f;
return 0;
}
/* encode 'keypad' */
int gsm48_encode_keypad(struct msgb *msg, int keypad)
{
msgb_tv_put(msg, GSM48_IE_KPD_FACILITY, keypad);
return 0;
}
/* decode 'progress' */
int gsm48_decode_progress(struct gsm_mncc_progress *progress,
const uint8_t *lv)
{
uint8_t in_len = lv[0];
if (in_len < 2)
return -EINVAL;
progress->coding = (lv[1] & 0x60) >> 5;
progress->location = lv[1] & 0x0f;
progress->descr = lv[2] & 0x7f;
return 0;
}
/* encode 'progress' */
int gsm48_encode_progress(struct msgb *msg, int lv_only,
const struct gsm_mncc_progress *p)
{
uint8_t lv[3];
lv[0] = 2;
lv[1] = 0x80 | ((p->coding & 0x3) << 5) | (p->location & 0xf);
lv[2] = 0x80 | (p->descr & 0x7f);
if (lv_only)
msgb_lv_put(msg, lv[0], lv+1);
else
msgb_tlv_put(msg, GSM48_IE_PROGR_IND, lv[0], lv+1);
return 0;
}
/* decode 'user-user' */
int gsm48_decode_useruser(struct gsm_mncc_useruser *uu,
const uint8_t *lv)
{
uint8_t in_len = lv[0];
char *info = uu->info;
int info_len = sizeof(uu->info);
int i;
if (in_len < 1)
return -EINVAL;
uu->proto = lv[1];
for (i = 2; i <= in_len; i++) {
info_len--;
if (info_len <= 1)
break;
*info++ = lv[i];
}
if (info_len >= 1)
*info++ = '\0';
return 0;
}
/* encode 'useruser' */
int gsm48_encode_useruser(struct msgb *msg, int lv_only,
const struct gsm_mncc_useruser *uu)
{
uint8_t lv[GSM_MAX_USERUSER + 2];
if (strlen(uu->info) > GSM_MAX_USERUSER)
return -EINVAL;
lv[0] = 1 + strlen(uu->info);
lv[1] = uu->proto;
memcpy(lv + 2, uu->info, strlen(uu->info));
if (lv_only)
msgb_lv_put(msg, lv[0], lv+1);
else
msgb_tlv_put(msg, GSM48_IE_USER_USER, lv[0], lv+1);
return 0;
}
/* decode 'ss version' */
int gsm48_decode_ssversion(struct gsm_mncc_ssversion *ssv,
const uint8_t *lv)
{
uint8_t in_len = lv[0];
if (in_len < 1 || in_len < sizeof(ssv->info))
return -EINVAL;
memcpy(ssv->info, lv + 1, in_len);
ssv->len = in_len;
return 0;
}
/* encode 'ss version' */
int gsm48_encode_ssversion(struct msgb *msg,
const struct gsm_mncc_ssversion *ssv)
{
uint8_t lv[GSM_MAX_SSVERSION + 1];
if (ssv->len > GSM_MAX_SSVERSION)
return -EINVAL;
lv[0] = ssv->len;
memcpy(lv + 1, ssv->info, ssv->len);
msgb_tlv_put(msg, GSM48_IE_SS_VERS, lv[0], lv+1);
return 0;
}
/* decode 'more data' does not require a function, because it has no value */
/* encode 'more data' */
int gsm48_encode_more(struct msgb *msg)
{
uint8_t *ie;
ie = msgb_put(msg, 1);
ie[0] = GSM48_IE_MORE_DATA;
return 0;
}

View File

@@ -1,361 +0,0 @@
/*
* (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
*
* 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 2 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
//#include <openbsc/gsm_data.h>
#include <osmocore/utils.h>
#include <osmocore/gsm_utils.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include "../config.h"
/* GSM 03.38 6.2.1 Charachter packing */
int gsm_7bit_decode(char *text, const uint8_t *user_data, uint8_t length)
{
int i = 0;
int l = 0;
/* FIXME: We need to account for user data headers here */
i += l;
for (; i < length; i ++)
*(text ++) =
((user_data[(i * 7 + 7) >> 3] <<
(7 - ((i * 7 + 7) & 7))) |
(user_data[(i * 7) >> 3] >>
((i * 7) & 7))) & 0x7f;
*text = '\0';
return i - l;
}
/* GSM 03.38 6.2.1 Charachter packing */
int gsm_7bit_encode(uint8_t *result, const char *data)
{
int i,j = 0;
unsigned char ch1, ch2;
int shift = 0;
for ( i=0; i<strlen(data); i++ ) {
ch1 = data[i] & 0x7F;
ch1 = ch1 >> shift;
ch2 = data[(i+1)] & 0x7F;
ch2 = ch2 << (7-shift);
ch1 = ch1 | ch2;
result[j++] = ch1;
shift++;
if ((shift == 7) && (i+1<strlen(data))) {
shift = 0;
i++;
}
}
return i;
}
/* determine power control level for given dBm value, as indicated
* by the tables in chapter 4.1.1 of GSM TS 05.05 */
int ms_pwr_ctl_lvl(enum gsm_band band, unsigned int dbm)
{
switch (band) {
case GSM_BAND_450:
case GSM_BAND_480:
case GSM_BAND_750:
case GSM_BAND_900:
case GSM_BAND_810:
case GSM_BAND_850:
if (dbm >= 39)
return 0;
else if (dbm < 5)
return 19;
else {
/* we are guaranteed to have (5 <= dbm < 39) */
return 2 + ((39 - dbm) / 2);
}
break;
case GSM_BAND_1800:
if (dbm >= 36)
return 29;
else if (dbm >= 34)
return 30;
else if (dbm >= 32)
return 31;
else if (dbm == 31)
return 0;
else {
/* we are guaranteed to have (0 <= dbm < 31) */
return (30 - dbm) / 2;
}
break;
case GSM_BAND_1900:
if (dbm >= 33)
return 30;
else if (dbm >= 32)
return 31;
else if (dbm == 31)
return 0;
else {
/* we are guaranteed to have (0 <= dbm < 31) */
return (30 - dbm) / 2;
}
break;
}
return -EINVAL;
}
int ms_pwr_dbm(enum gsm_band band, uint8_t lvl)
{
lvl &= 0x1f;
switch (band) {
case GSM_BAND_450:
case GSM_BAND_480:
case GSM_BAND_750:
case GSM_BAND_900:
case GSM_BAND_810:
case GSM_BAND_850:
if (lvl < 2)
return 39;
else if (lvl < 20)
return 39 - ((lvl - 2) * 2) ;
else
return 5;
break;
case GSM_BAND_1800:
if (lvl < 16)
return 30 - (lvl * 2);
else if (lvl < 29)
return 0;
else
return 36 - ((lvl - 29) * 2);
break;
case GSM_BAND_1900:
if (lvl < 16)
return 30 - (lvl * 2);
else if (lvl < 30)
return -EINVAL;
else
return 33 - (lvl - 30);
break;
}
return -EINVAL;
}
/* According to TS 08.05 Chapter 8.1.4 */
int rxlev2dbm(uint8_t rxlev)
{
if (rxlev > 63)
rxlev = 63;
return -110 + rxlev;
}
/* According to TS 08.05 Chapter 8.1.4 */
uint8_t dbm2rxlev(int dbm)
{
int rxlev = dbm + 110;
if (rxlev > 63)
rxlev = 63;
else if (rxlev < 0)
rxlev = 0;
return rxlev;
}
const char *gsm_band_name(enum gsm_band band)
{
switch (band) {
case GSM_BAND_450:
return "GSM450";
case GSM_BAND_480:
return "GSM450";
case GSM_BAND_750:
return "GSM750";
case GSM_BAND_810:
return "GSM810";
case GSM_BAND_850:
return "GSM850";
case GSM_BAND_900:
return "GSM900";
case GSM_BAND_1800:
return "DCS1800";
case GSM_BAND_1900:
return "PCS1900";
}
return "invalid";
}
enum gsm_band gsm_band_parse(const char* mhz)
{
while (*mhz && !isdigit(*mhz))
mhz++;
if (*mhz == '\0')
return -EINVAL;
switch (strtol(mhz, NULL, 10)) {
case 450:
return GSM_BAND_450;
case 480:
return GSM_BAND_480;
case 750:
return GSM_BAND_750;
case 810:
return GSM_BAND_810;
case 850:
return GSM_BAND_850;
case 900:
return GSM_BAND_900;
case 1800:
return GSM_BAND_1800;
case 1900:
return GSM_BAND_1900;
default:
return -EINVAL;
}
}
#ifdef HAVE_EXECINFO_H
#include <execinfo.h>
void generate_backtrace()
{
int i, nptrs;
void *buffer[100];
char **strings;
nptrs = backtrace(buffer, ARRAY_SIZE(buffer));
printf("backtrace() returned %d addresses\n", nptrs);
strings = backtrace_symbols(buffer, nptrs);
if (!strings)
return;
for (i = 1; i < nptrs; i++)
printf("%s\n", strings[i]);
free(strings);
}
#endif
enum gsm_band gsm_arfcn2band(uint16_t arfcn)
{
if (arfcn & ARFCN_PCS)
return GSM_BAND_1900;
else if (arfcn <= 124)
return GSM_BAND_900;
else if (arfcn >= 955 && arfcn <= 1023)
return GSM_BAND_900;
else if (arfcn >= 128 && arfcn <= 251)
return GSM_BAND_850;
else if (arfcn >= 512 && arfcn <= 885)
return GSM_BAND_1800;
else if (arfcn >= 259 && arfcn <= 293)
return GSM_BAND_450;
else if (arfcn >= 306 && arfcn <= 340)
return GSM_BAND_480;
else if (arfcn >= 350 && arfcn <= 425)
return GSM_BAND_810;
else if (arfcn >= 438 && arfcn <= 511)
return GSM_BAND_750;
else
return GSM_BAND_1800;
}
/* Convert an ARFCN to the frequency in MHz * 10 */
uint16_t gsm_arfcn2freq10(uint16_t arfcn, int uplink)
{
uint16_t freq10_ul;
uint16_t freq10_dl;
if (arfcn & ARFCN_PCS) {
/* DCS 1900 */
arfcn &= ~ARFCN_PCS;
freq10_ul = 18502 + 2 * (arfcn-512);
freq10_dl = freq10_ul + 800;
} else if (arfcn <= 124) {
/* Primary GSM + ARFCN 0 of E-GSM */
freq10_ul = 8900 + 2 * arfcn;
freq10_dl = freq10_ul + 450;
} else if (arfcn >= 955 && arfcn <= 1023) {
/* E-GSM and R-GSM */
freq10_ul = 8900 + 2 * (arfcn - 1024);
freq10_dl = freq10_ul + 450;
} else if (arfcn >= 128 && arfcn <= 251) {
/* GSM 850 */
freq10_ul = 8242 + 2 * (arfcn - 128);
freq10_dl = freq10_ul + 450;
} else if (arfcn >= 512 && arfcn <= 885) {
/* DCS 1800 */
freq10_ul = 17102 + 2 * (arfcn - 512);
freq10_dl = freq10_ul + 950;
} else if (arfcn >= 259 && arfcn <= 293) {
/* GSM 450 */
freq10_ul = 4506 + 2 * (arfcn - 259);
freq10_dl = freq10_ul + 100;
} else if (arfcn >= 306 && arfcn <= 340) {
/* GSM 480 */
freq10_ul = 4790 + 2 * (arfcn - 306);
freq10_dl = freq10_ul + 100;
} else if (arfcn >= 350 && arfcn <= 425) {
/* GSM 810 */
freq10_ul = 8060 + 2 * (arfcn - 350);
freq10_dl = freq10_ul + 450;
} else if (arfcn >= 438 && arfcn <= 511) {
/* GSM 750 */
freq10_ul = 7472 + 2 * (arfcn - 438);
freq10_dl = freq10_ul + 300;
} else
return 0xffff;
if (uplink)
return freq10_ul;
else
return freq10_dl;
}
void gsm_fn2gsmtime(struct gsm_time *time, uint32_t fn)
{
time->fn = fn;
time->t1 = time->fn / (26*51);
time->t2 = time->fn % 26;
time->t3 = time->fn % 51;
time->tc = (time->fn / 51) % 8;
}
uint32_t gsm_gsmtime2fn(struct gsm_time *time)
{
/* TS 05.02 Chapter 4.3.3 TDMA frame number */
return (51 * ((time->t3 - time->t2 + 26) % 26) + time->t3 + (26 * 51 * time->t1));
}

View File

@@ -1,327 +0,0 @@
/* GSM Radio Signalling Link messages on the A-bis interface
* 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
*
* 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 2 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include <stdint.h>
#include <errno.h>
#include <osmocore/tlv.h>
#include <osmocore/rsl.h>
#define RSL_ALLOC_SIZE 200
#define RSL_ALLOC_HEADROOM 56
void rsl_init_rll_hdr(struct abis_rsl_rll_hdr *dh, uint8_t msg_type)
{
dh->c.msg_discr = ABIS_RSL_MDISC_RLL;
dh->c.msg_type = msg_type;
dh->ie_chan = RSL_IE_CHAN_NR;
dh->ie_link_id = RSL_IE_LINK_IDENT;
}
const struct tlv_definition rsl_att_tlvdef = {
.def = {
[RSL_IE_CHAN_NR] = { TLV_TYPE_TV },
[RSL_IE_LINK_IDENT] = { TLV_TYPE_TV },
[RSL_IE_ACT_TYPE] = { TLV_TYPE_TV },
[RSL_IE_BS_POWER] = { TLV_TYPE_TV },
[RSL_IE_CHAN_IDENT] = { TLV_TYPE_TLV },
[RSL_IE_CHAN_MODE] = { TLV_TYPE_TLV },
[RSL_IE_ENCR_INFO] = { TLV_TYPE_TLV },
[RSL_IE_FRAME_NUMBER] = { TLV_TYPE_FIXED, 2 },
[RSL_IE_HANDO_REF] = { TLV_TYPE_TV },
[RSL_IE_L1_INFO] = { TLV_TYPE_FIXED, 2 },
[RSL_IE_L3_INFO] = { TLV_TYPE_TL16V },
[RSL_IE_MS_IDENTITY] = { TLV_TYPE_TLV },
[RSL_IE_MS_POWER] = { TLV_TYPE_TV },
[RSL_IE_PAGING_GROUP] = { TLV_TYPE_TV },
[RSL_IE_PAGING_LOAD] = { TLV_TYPE_FIXED, 2 },
[RSL_IE_PYHS_CONTEXT] = { TLV_TYPE_TLV },
[RSL_IE_ACCESS_DELAY] = { TLV_TYPE_TV },
[RSL_IE_RACH_LOAD] = { TLV_TYPE_TLV },
[RSL_IE_REQ_REFERENCE] = { TLV_TYPE_FIXED, 3 },
[RSL_IE_RELEASE_MODE] = { TLV_TYPE_TV },
[RSL_IE_RESOURCE_INFO] = { TLV_TYPE_TLV },
[RSL_IE_RLM_CAUSE] = { TLV_TYPE_TLV },
[RSL_IE_STARTNG_TIME] = { TLV_TYPE_FIXED, 2 },
[RSL_IE_TIMING_ADVANCE] = { TLV_TYPE_TV },
[RSL_IE_UPLINK_MEAS] = { TLV_TYPE_TLV },
[RSL_IE_CAUSE] = { TLV_TYPE_TLV },
[RSL_IE_MEAS_RES_NR] = { TLV_TYPE_TV },
[RSL_IE_MSG_ID] = { TLV_TYPE_TV },
[RSL_IE_SYSINFO_TYPE] = { TLV_TYPE_TV },
[RSL_IE_MS_POWER_PARAM] = { TLV_TYPE_TLV },
[RSL_IE_BS_POWER_PARAM] = { TLV_TYPE_TLV },
[RSL_IE_PREPROC_PARAM] = { TLV_TYPE_TLV },
[RSL_IE_PREPROC_MEAS] = { TLV_TYPE_TLV },
[RSL_IE_IMM_ASS_INFO] = { TLV_TYPE_TLV },
[RSL_IE_SMSCB_INFO] = { TLV_TYPE_FIXED, 23 },
[RSL_IE_MS_TIMING_OFFSET] = { TLV_TYPE_TV },
[RSL_IE_ERR_MSG] = { TLV_TYPE_TLV },
[RSL_IE_FULL_BCCH_INFO] = { TLV_TYPE_TLV },
[RSL_IE_CHAN_NEEDED] = { TLV_TYPE_TV },
[RSL_IE_CB_CMD_TYPE] = { TLV_TYPE_TV },
[RSL_IE_SMSCB_MSG] = { TLV_TYPE_TLV },
[RSL_IE_FULL_IMM_ASS_INFO] = { TLV_TYPE_TLV },
[RSL_IE_SACCH_INFO] = { TLV_TYPE_TLV },
[RSL_IE_CBCH_LOAD_INFO] = { TLV_TYPE_TV },
[RSL_IE_SMSCB_CHAN_INDICATOR] = { TLV_TYPE_TV },
[RSL_IE_GROUP_CALL_REF] = { TLV_TYPE_TLV },
[RSL_IE_CHAN_DESC] = { TLV_TYPE_TLV },
[RSL_IE_NCH_DRX_INFO] = { TLV_TYPE_TLV },
[RSL_IE_CMD_INDICATOR] = { TLV_TYPE_TLV },
[RSL_IE_EMLPP_PRIO] = { TLV_TYPE_TV },
[RSL_IE_UIC] = { TLV_TYPE_TLV },
[RSL_IE_MAIN_CHAN_REF] = { TLV_TYPE_TV },
[RSL_IE_MR_CONFIG] = { TLV_TYPE_TLV },
[RSL_IE_MR_CONTROL] = { TLV_TYPE_TV },
[RSL_IE_SUP_CODEC_TYPES] = { TLV_TYPE_TLV },
[RSL_IE_CODEC_CONFIG] = { TLV_TYPE_TLV },
[RSL_IE_RTD] = { TLV_TYPE_TV },
[RSL_IE_TFO_STATUS] = { TLV_TYPE_TV },
[RSL_IE_LLP_APDU] = { TLV_TYPE_TLV },
[RSL_IE_SIEMENS_MRPCI] = { TLV_TYPE_TV },
[RSL_IE_IPAC_PROXY_UDP] = { TLV_TYPE_FIXED, 2 },
[RSL_IE_IPAC_BSCMPL_TOUT] = { TLV_TYPE_TV },
[RSL_IE_IPAC_REMOTE_IP] = { TLV_TYPE_FIXED, 4 },
[RSL_IE_IPAC_REMOTE_PORT] = { TLV_TYPE_FIXED, 2 },
[RSL_IE_IPAC_RTP_PAYLOAD] = { TLV_TYPE_TV },
[RSL_IE_IPAC_LOCAL_PORT] = { TLV_TYPE_FIXED, 2 },
[RSL_IE_IPAC_SPEECH_MODE] = { TLV_TYPE_TV },
[RSL_IE_IPAC_LOCAL_IP] = { TLV_TYPE_FIXED, 4 },
[RSL_IE_IPAC_CONN_ID] = { TLV_TYPE_FIXED, 2 },
[RSL_IE_IPAC_RTP_CSD_FMT] = { TLV_TYPE_TV },
[RSL_IE_IPAC_RTP_JIT_BUF] = { TLV_TYPE_FIXED, 2 },
[RSL_IE_IPAC_RTP_COMPR] = { TLV_TYPE_TV },
[RSL_IE_IPAC_RTP_PAYLOAD2] = { TLV_TYPE_TV },
[RSL_IE_IPAC_RTP_MPLEX] = { TLV_TYPE_FIXED, 8 },
[RSL_IE_IPAC_RTP_MPLEX_ID] = { TLV_TYPE_TV },
},
};
/* encode channel number as per Section 9.3.1 */
uint8_t rsl_enc_chan_nr(uint8_t type, uint8_t subch, uint8_t timeslot)
{
uint8_t ret;
ret = (timeslot & 0x07) | type;
switch (type) {
case RSL_CHAN_Lm_ACCHs:
subch &= 0x01;
break;
case RSL_CHAN_SDCCH4_ACCH:
subch &= 0x03;
break;
case RSL_CHAN_SDCCH8_ACCH:
subch &= 0x07;
break;
default:
/* no subchannels allowed */
subch = 0x00;
break;
}
ret |= (subch << 3);
return ret;
}
int rsl_dec_chan_nr(uint8_t chan_nr, uint8_t *type, uint8_t *subch, uint8_t *timeslot)
{
*timeslot = chan_nr & 0x7;
if ((chan_nr & 0xf8) == RSL_CHAN_Bm_ACCHs) {
*type = RSL_CHAN_Bm_ACCHs;
*subch = 0;
} else if ((chan_nr & 0xf0) == RSL_CHAN_Lm_ACCHs) {
*type = RSL_CHAN_Lm_ACCHs;
*subch = (chan_nr >> 3) & 0x1;
} else if ((chan_nr & 0xe0) == RSL_CHAN_SDCCH4_ACCH) {
*type = RSL_CHAN_SDCCH4_ACCH;
*subch = (chan_nr >> 3) & 0x3;
} else if ((chan_nr & 0xc0) == RSL_CHAN_SDCCH8_ACCH) {
*type = RSL_CHAN_SDCCH8_ACCH;
*subch = (chan_nr >> 3) & 0x7;
} else if ((chan_nr & 0xf8) == RSL_CHAN_BCCH) {
*type = RSL_CHAN_BCCH;
*subch = 0;
} else if ((chan_nr & 0xf8) == RSL_CHAN_RACH) {
*type = RSL_CHAN_RACH;
*subch = 0;
} else if ((chan_nr & 0xf8) == RSL_CHAN_PCH_AGCH) {
*type = RSL_CHAN_PCH_AGCH;
*subch = 0;
} else
return -EINVAL;
return 0;
}
/* FIXME: convert to value_string */
static const char *rsl_err_vals[0xff] = {
[RSL_ERR_RADIO_IF_FAIL] = "Radio Interface Failure",
[RSL_ERR_RADIO_LINK_FAIL] = "Radio Link Failure",
[RSL_ERR_HANDOVER_ACC_FAIL] = "Handover Access Failure",
[RSL_ERR_TALKER_ACC_FAIL] = "Talker Access Failure",
[RSL_ERR_OM_INTERVENTION] = "O&M Intervention",
[RSL_ERR_NORMAL_UNSPEC] = "Normal event, unspecified",
[RSL_ERR_T_MSRFPCI_EXP] = "Siemens: T_MSRFPCI Expired",
[RSL_ERR_EQUIPMENT_FAIL] = "Equipment Failure",
[RSL_ERR_RR_UNAVAIL] = "Radio Resource not available",
[RSL_ERR_TERR_CH_FAIL] = "Terrestrial Channel Failure",
[RSL_ERR_CCCH_OVERLOAD] = "CCCH Overload",
[RSL_ERR_ACCH_OVERLOAD] = "ACCH Overload",
[RSL_ERR_PROCESSOR_OVERLOAD] = "Processor Overload",
[RSL_ERR_RES_UNAVAIL] = "Resource not available, unspecified",
[RSL_ERR_TRANSC_UNAVAIL] = "Transcoding not available",
[RSL_ERR_SERV_OPT_UNAVAIL] = "Service or Option not available",
[RSL_ERR_ENCR_UNIMPL] = "Encryption algorithm not implemented",
[RSL_ERR_SERV_OPT_UNIMPL] = "Service or Option not implemented",
[RSL_ERR_RCH_ALR_ACTV_ALLOC] = "Radio channel already activated",
[RSL_ERR_INVALID_MESSAGE] = "Invalid Message, unspecified",
[RSL_ERR_MSG_DISCR] = "Message Discriminator Error",
[RSL_ERR_MSG_TYPE] = "Message Type Error",
[RSL_ERR_MSG_SEQ] = "Message Sequence Error",
[RSL_ERR_IE_ERROR] = "General IE error",
[RSL_ERR_MAND_IE_ERROR] = "Mandatory IE error",
[RSL_ERR_OPT_IE_ERROR] = "Optional IE error",
[RSL_ERR_IE_NONEXIST] = "IE non-existent",
[RSL_ERR_IE_LENGTH] = "IE length error",
[RSL_ERR_IE_CONTENT] = "IE content error",
[RSL_ERR_PROTO] = "Protocol error, unspecified",
[RSL_ERR_INTERWORKING] = "Interworking error, unspecified",
};
const struct value_string rsl_rlm_cause_strs[] = {
{ RLL_CAUSE_T200_EXPIRED, "Timer T200 expired (N200+1) times" },
{ RLL_CAUSE_REEST_REQ, "Re-establishment request" },
{ RLL_CAUSE_UNSOL_UA_RESP, "Unsolicited UA response" },
{ RLL_CAUSE_UNSOL_DM_RESP, "Unsolicited DM response" },
{ RLL_CAUSE_UNSOL_DM_RESP_MF, "Unsolicited DM response, multiple frame" },
{ RLL_CAUSE_UNSOL_SPRV_RESP, "Unsolicited supervisory response" },
{ RLL_CAUSE_SEQ_ERR, "Sequence Error" },
{ RLL_CAUSE_UFRM_INC_PARAM, "U-Frame with incorrect parameters" },
{ RLL_CAUSE_SFRM_INC_PARAM, "S-Frame with incorrect parameters" },
{ RLL_CAUSE_IFRM_INC_MBITS, "I-Frame with incorrect use of M bit" },
{ RLL_CAUSE_IFRM_INC_LEN, "I-Frame with incorrect length" },
{ RLL_CAUSE_FRM_UNIMPL, "Fraeme not implemented" },
{ RLL_CAUSE_SABM_MF, "SABM command, multiple frame established state" },
{ RLL_CAUSE_SABM_INFO_NOTALL, "SABM frame with information not allowed in this state" },
{ 0, NULL },
};
const char *rsl_err_name(uint8_t err)
{
if (rsl_err_vals[err])
return rsl_err_vals[err];
else
return "unknown";
}
/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf)
{
switch (ccch_conf) {
case RSL_BCCH_CCCH_CONF_1_NC:
return 1;
case RSL_BCCH_CCCH_CONF_1_C:
return 1;
case RSL_BCCH_CCCH_CONF_2_NC:
return 2;
case RSL_BCCH_CCCH_CONF_3_NC:
return 3;
case RSL_BCCH_CCCH_CONF_4_NC:
return 4;
default:
return -1;
}
}
/* Section 3.3.2.3 TS 05.02 */
int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf)
{
switch (ccch_conf) {
case RSL_BCCH_CCCH_CONF_1_NC:
return 0;
case RSL_BCCH_CCCH_CONF_1_C:
return 1;
case RSL_BCCH_CCCH_CONF_2_NC:
return 0;
case RSL_BCCH_CCCH_CONF_3_NC:
return 0;
case RSL_BCCH_CCCH_CONF_4_NC:
return 0;
default:
return -1;
}
}
/* Push a RSL RLL header with L3_INFO IE */
void rsl_rll_push_l3(struct msgb *msg, uint8_t msg_type, uint8_t chan_nr,
uint8_t link_id, int transparent)
{
uint8_t l3_len = msg->tail - (uint8_t *)msgb_l3(msg);
struct abis_rsl_rll_hdr *rh;
/* construct a RSLms RLL message (DATA INDICATION, UNIT DATA
* INDICATION) and send it off via RSLms */
/* Push the L3 IE tag and lengh */
msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
/* Then push the RSL header */
rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh));
rsl_init_rll_hdr(rh, msg_type);
if (transparent)
rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
rh->chan_nr = chan_nr;
rh->link_id = link_id;
/* set the l2 header pointer */
msg->l2h = (uint8_t *)rh;
}
struct msgb *rsl_rll_simple(uint8_t msg_type, uint8_t chan_nr,
uint8_t link_id, int transparent)
{
struct abis_rsl_rll_hdr *rh;
struct msgb *msg;
msg = msgb_alloc_headroom(RSL_ALLOC_SIZE+RSL_ALLOC_HEADROOM,
RSL_ALLOC_HEADROOM, "rsl_rll_simple");
if (!msg)
return NULL;
/* put the RSL header */
rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
rsl_init_rll_hdr(rh, msg_type);
if (transparent)
rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
rh->chan_nr = chan_nr;
rh->link_id = link_id;
/* set the l2 header pointer */
msg->l2h = (uint8_t *)rh;
return msg;
}

View File

@@ -1,94 +0,0 @@
/* Rx Level statistics */
/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
*
* 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 2 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdint.h>
#include <osmocore/bitvec.h>
#include <osmocore/rxlev_stat.h>
int bitvec_find_bit_pos(const struct bitvec *bv, unsigned int n, enum bit_value val)
{
unsigned int i;
for (i = n; i < bv->data_len*8; i++) {
if (bitvec_get_bit_pos(bv, i) == val)
return i;
}
return -1;
}
void rxlev_stat_input(struct rxlev_stats *st, uint16_t arfcn, uint8_t rxlev)
{
struct bitvec bv;
if (rxlev >= NUM_RXLEVS)
rxlev = NUM_RXLEVS-1;
bv.data_len = NUM_ARFCNS/8;
bv.data = st->rxlev_buckets[rxlev];
bitvec_set_bit_pos(&bv, arfcn, ONE);
}
/* get the next ARFCN that has the specified Rxlev */
int16_t rxlev_stat_get_next(const struct rxlev_stats *st, uint8_t rxlev, int16_t arfcn)
{
struct bitvec bv;
if (rxlev >= NUM_RXLEVS)
rxlev = NUM_RXLEVS-1;
bv.data_len = NUM_ARFCNS/8;
if (arfcn < 0)
arfcn = -1;
bv.data = st->rxlev_buckets[rxlev];
return bitvec_find_bit_pos(&bv, arfcn+1, ONE);
}
void rxlev_stat_reset(struct rxlev_stats *st)
{
memset(st, 0, sizeof(*st));
}
void rxlev_stat_dump(const struct rxlev_stats *st)
{
int i;
for (i = NUM_RXLEVS-1; i >= 0; i--) {
int16_t arfcn = -1;
printf("ARFCN with RxLev %u: ", i);
while ((arfcn = rxlev_stat_get_next(st, i, arfcn)) >= 0) {
printf("%u ", arfcn);
}
printf("\n");
}
}

View File

@@ -1,46 +0,0 @@
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <osmocore/utils.h>
const char *get_value_string(const struct value_string *vs, uint32_t val)
{
int i;
for (i = 0;; i++) {
if (vs[i].value == 0 && vs[i].str == NULL)
break;
if (vs[i].value == val)
return vs[i].str;
}
return "unknown";
}
int get_string_value(const struct value_string *vs, const char *str)
{
int i;
for (i = 0;; i++) {
if (vs[i].value == 0 && vs[i].str == NULL)
break;
if (!strcasecmp(vs[i].str, str))
return vs[i].value;
}
return -EINVAL;
}
char bcd2char(uint8_t bcd)
{
if (bcd < 0xa)
return '0' + bcd;
else
return 'A' + (bcd - 0xa);
}
/* only works for numbers in ascci */
uint8_t char2bcd(char c)
{
return c - 0x30;
}

View File

@@ -1,74 +0,0 @@
/* Generic write queue implementation */
/*
* (C) 2010 by Holger Hans Peter Freyther
* (C) 2010 by On-Waves
*
* 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 2 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include <osmocore/write_queue.h>
int write_queue_bfd_cb(struct bsc_fd *fd, unsigned int what)
{
struct write_queue *queue;
queue = container_of(fd, struct write_queue, bfd);
if (what & BSC_FD_READ)
queue->read_cb(fd);
if (what & BSC_FD_WRITE) {
struct msgb *msg;
fd->when &= ~BSC_FD_WRITE;
msg = msgb_dequeue(&queue->msg_queue);
if (!msg)
return -1;
--queue->current_length;
queue->write_cb(fd, msg);
msgb_free(msg);
if (!llist_empty(&queue->msg_queue))
fd->when |= BSC_FD_WRITE;
}
return 0;
}
void write_queue_init(struct write_queue *queue, int max_length)
{
queue->max_length = max_length;
queue->current_length = 0;
queue->read_cb = NULL;
queue->write_cb = NULL;
queue->bfd.cb = write_queue_bfd_cb;
INIT_LLIST_HEAD(&queue->msg_queue);
}
int write_queue_enqueue(struct write_queue *queue, struct msgb *data)
{
// if (queue->current_length + 1 >= queue->max_length)
// LOGP(DMSC, LOGL_ERROR, "The queue is full. Dropping not yet implemented.\n");
++queue->current_length;
msgb_enqueue(&queue->msg_queue, data);
queue->bfd.when |= BSC_FD_WRITE;
return 0;
}

View File

@@ -1,3 +0,0 @@
if ENABLE_TESTS
SUBDIRS = timer sms
endif

View File

@@ -1,6 +0,0 @@
INCLUDES = $(all_includes) -I$(top_srcdir)/include
noinst_PROGRAMS = timer_test
timer_test_SOURCES = timer_test.c
timer_test_LDADD = $(top_builddir)/src/libosmocore.la

6
openbsc/.gitignore vendored
View File

@@ -3,12 +3,8 @@
.deps
Makefile
Makefile.in
bscconfig.h
bscconfig.h.in
openbsc.pc
bsc_hack
bsc_msc_ip
bsc_mgcp
*.*~
*.sw?
@@ -30,8 +26,6 @@ hlr.sqlite3
bs11_config
ipaccess-config
ipaccess-find
ipaccess-firmware
ipaccess-proxy
isdnsync
#tests

View File

@@ -3,5 +3,3 @@ Holger Freyther <zecke@selfish.org>
Jan Luebbe <jluebbe@debian.org>
Stefan Schmidt <stefan@datenfreihafen.org>
Daniel Willmann <daniel@totalueberwachung.de>
Andreas Eversberg <Andreas.Eversberg@versatel.de>
Sylvain Munaut <246tnt@gmail.com>

View File

@@ -4,7 +4,7 @@ INCLUDES = $(all_includes) -I$(top_srcdir)/include
SUBDIRS = include src tests
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = openbsc.pc libsccp.pc
pkgconfig_DATA = openbsc.pc
#dist-hook:
# rm -rf `find $(distdir) -name .svn`

View File

@@ -1,30 +1,18 @@
About OpenBSC
=============
OpenBSC is a minimalistic implementation of the GSM Network, with
particular emphasis on the functionality typically provided by the BSC,
MSC, HLR, VLR and SMSC.
OpenBSC is a minimalistic implementation of the GSM Network, with particular
emphasis on the functionality typically provided by the BSC, MSC, HLR, VLR.
Its currently supported interfaces towards the BTS are:
Its only current interface is a mISDN based E1 interface utilizing the A-bis
protocol between BSC and BTS. In other words, you can connect an existing
GSM Base Transceiver Station (BTS) through E1 to OpenBSC.
* Classic A-bis over E1 using a mISDN based E1 interface. In other
words, you can connect existing GSM Base Transceiver Station (BTS)
through E1 to OpenBSC. So far, we have only tested the Siemens BS-11
Test reports with other BTS are much appreciated!
* A-bis over IP as used by the ip.access nanoBTS product family
So far, it has only been tested with the Siemens microBTS BS-11. Test reports
with other BTS are appreciated!
This project is still in its early days, and there are lots of areas where it
doesn't behave as per GSM spec.
December 29, 2008
Harald Welte <laforge@gnumonks.org>
libosmocore
===========
Please note that as of March 2010, OpenBSC has a dependency to a library
called "libosmocore". You can obtain that library from
git://git.osmocom.org/libosmocore.git

View File

@@ -1,7 +1,7 @@
dnl Process this file with autoconf to produce a configure script
AC_INIT
AM_INIT_AUTOMAKE(openbsc, 0.0alpha1)
AM_INIT_AUTOMAKE(openbsc, 0.3.4onwaves)
dnl kernel style compile messages
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
@@ -16,8 +16,6 @@ dnl checks for libraries
AC_SEARCH_LIBS(crypt, crypt,
[LIBCRYPT="-lcrypt"; AC_DEFINE([VTY_CRYPT_PW], [], [Use crypt functionality of vty.])])
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore)
dnl checks for header files
AC_HEADER_STDC
@@ -40,7 +38,6 @@ AM_CONFIG_HEADER(bscconfig.h)
AC_OUTPUT(
openbsc.pc
libsccp.pc
include/openbsc/Makefile
include/vty/Makefile
include/sccp/Makefile
@@ -48,6 +45,8 @@ AC_OUTPUT(
src/Makefile
tests/Makefile
tests/debug/Makefile
tests/timer/Makefile
tests/sms/Makefile
tests/gsm0408/Makefile
tests/db/Makefile
tests/channel/Makefile

2
openbsc/contrib/README Normal file
View File

@@ -0,0 +1,2 @@
This contains a set of scripts used for the development of the
MSC functionality.

View File

@@ -0,0 +1,30 @@
#!/usr/bin/env python
import sys
# packages
ACK ="\x00\x01\xfe\x06"
RESET_ACK = "\x00\x13\xfd\x09\x00\x03\x07\x0b\x04\x43\x01\x00\xfe\x04\x43\x5c\x00\xfe\x03\x00\x01\x31"
PAGE = "\x00\x20\xfd\x09\x00\x03\x07\x0b\x04\x43\x01\x00\xfe\x04\x43\x5c\x00\xfe\x10\x00\x0e\x52\x08\x08\x29\x42\x08\x05\x03\x12\x23\x42\x1a\x01\x06"
# simple handshake...
sys.stdout.write(ACK)
sys.stdout.flush()
sys.stdin.read(4)
# wait for some data and send reset ack
sys.stdin.read(21)
sys.stdout.write(RESET_ACK)
sys.stdout.flush()
sys.stdout.write(RESET_ACK)
sys.stdout.flush()
# page a subscriber
sys.stdout.write(PAGE)
sys.stdout.flush()
while True:
sys.stdin.read(1)

View File

@@ -1,11 +1,8 @@
noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \
gsm_subscriber.h gsm_04_11.h debug.h signal.h \
misdn.h chan_alloc.h telnet_interface.h paging.h \
subchan_demux.h trau_frame.h e1_input.h trau_mux.h \
ipaccess.h rs232.h openbscdefines.h rtp_proxy.h \
bsc_rll.h mncc.h transaction.h ussd.h gsm_04_80.h \
silent_call.h mgcp.h meas_rep.h rest_octets.h \
system_information.h handover.h mgcp_internal.h
openbsc_HEADERS = gsm_04_08.h meas_rep.h
openbscdir = $(includedir)/openbsc
noinst_HEADERS = abis_nm.h abis_rsl.h debug.h db.h gsm_04_08.h gsm_data.h \
gsm_subscriber.h linuxlist.h msgb.h select.h tlv.h gsm_04_11.h \
timer.h misdn.h chan_alloc.h telnet_interface.h paging.h \
subchan_demux.h trau_frame.h e1_input.h trau_mux.h signal.h \
gsm_utils.h ipaccess.h rs232.h openbscdefines.h rtp_proxy.h \
bsc_rll.h mncc.h talloc.h transaction.h ussd.h gsm_04_80.h \
silent_call.h mgcp.h meas_rep.h bitvec.h rest_octets.h \
system_information.h handover.h bssap.h bsc_msc.h bsc_nat.h

View File

@@ -24,8 +24,665 @@
#define _NM_H
#include <sys/types.h>
#include <osmocore/tlv.h>
#include <osmocore/protocol/gsm_12_21.h>
#include <openbsc/tlv.h>
/* PRIVATE */
/* generic header in front of every OML message according to TS 08.59 */
struct abis_om_hdr {
u_int8_t mdisc;
u_int8_t placement;
u_int8_t sequence;
u_int8_t length;
u_int8_t data[0];
} __attribute__ ((packed));
#define ABIS_OM_MDISC_FOM 0x80
#define ABIS_OM_MDISC_MMI 0x40
#define ABIS_OM_MDISC_TRAU 0x20
#define ABIS_OM_MDISC_MANUF 0x10
#define ABIS_OM_PLACEMENT_ONLY 0x80
#define ABIS_OM_PLACEMENT_FIRST 0x40
#define ABIS_OM_PLACEMENT_MIDDLE 0x20
#define ABIS_OM_PLACEMENT_LAST 0x10
struct abis_om_obj_inst {
u_int8_t bts_nr;
u_int8_t trx_nr;
u_int8_t ts_nr;
} __attribute__ ((packed));
struct abis_om_fom_hdr {
u_int8_t msg_type;
u_int8_t obj_class;
struct abis_om_obj_inst obj_inst;
u_int8_t data[0];
} __attribute__ ((packed));
#define ABIS_OM_FOM_HDR_SIZE (sizeof(struct abis_om_hdr) + sizeof(struct abis_om_fom_hdr))
/* Section 9.1: Message Types */
enum abis_nm_msgtype {
/* SW Download Management Messages */
NM_MT_LOAD_INIT = 0x01,
NM_MT_LOAD_INIT_ACK,
NM_MT_LOAD_INIT_NACK,
NM_MT_LOAD_SEG,
NM_MT_LOAD_SEG_ACK,
NM_MT_LOAD_ABORT,
NM_MT_LOAD_END,
NM_MT_LOAD_END_ACK,
NM_MT_LOAD_END_NACK,
NM_MT_SW_ACT_REQ, /* BTS->BSC */
NM_MT_SW_ACT_REQ_ACK,
NM_MT_SW_ACT_REQ_NACK,
NM_MT_ACTIVATE_SW, /* BSC->BTS */
NM_MT_ACTIVATE_SW_ACK,
NM_MT_ACTIVATE_SW_NACK,
NM_MT_SW_ACTIVATED_REP, /* 0x10 */
/* A-bis Interface Management Messages */
NM_MT_ESTABLISH_TEI = 0x21,
NM_MT_ESTABLISH_TEI_ACK,
NM_MT_ESTABLISH_TEI_NACK,
NM_MT_CONN_TERR_SIGN,
NM_MT_CONN_TERR_SIGN_ACK,
NM_MT_CONN_TERR_SIGN_NACK,
NM_MT_DISC_TERR_SIGN,
NM_MT_DISC_TERR_SIGN_ACK,
NM_MT_DISC_TERR_SIGN_NACK,
NM_MT_CONN_TERR_TRAF,
NM_MT_CONN_TERR_TRAF_ACK,
NM_MT_CONN_TERR_TRAF_NACK,
NM_MT_DISC_TERR_TRAF,
NM_MT_DISC_TERR_TRAF_ACK,
NM_MT_DISC_TERR_TRAF_NACK,
/* Transmission Management Messages */
NM_MT_CONN_MDROP_LINK = 0x31,
NM_MT_CONN_MDROP_LINK_ACK,
NM_MT_CONN_MDROP_LINK_NACK,
NM_MT_DISC_MDROP_LINK,
NM_MT_DISC_MDROP_LINK_ACK,
NM_MT_DISC_MDROP_LINK_NACK,
/* Air Interface Management Messages */
NM_MT_SET_BTS_ATTR = 0x41,
NM_MT_SET_BTS_ATTR_ACK,
NM_MT_SET_BTS_ATTR_NACK,
NM_MT_SET_RADIO_ATTR,
NM_MT_SET_RADIO_ATTR_ACK,
NM_MT_SET_RADIO_ATTR_NACK,
NM_MT_SET_CHAN_ATTR,
NM_MT_SET_CHAN_ATTR_ACK,
NM_MT_SET_CHAN_ATTR_NACK,
/* Test Management Messages */
NM_MT_PERF_TEST = 0x51,
NM_MT_PERF_TEST_ACK,
NM_MT_PERF_TEST_NACK,
NM_MT_TEST_REP,
NM_MT_SEND_TEST_REP,
NM_MT_SEND_TEST_REP_ACK,
NM_MT_SEND_TEST_REP_NACK,
NM_MT_STOP_TEST,
NM_MT_STOP_TEST_ACK,
NM_MT_STOP_TEST_NACK,
/* State Management and Event Report Messages */
NM_MT_STATECHG_EVENT_REP = 0x61,
NM_MT_FAILURE_EVENT_REP,
NM_MT_STOP_EVENT_REP,
NM_MT_STOP_EVENT_REP_ACK,
NM_MT_STOP_EVENT_REP_NACK,
NM_MT_REST_EVENT_REP,
NM_MT_REST_EVENT_REP_ACK,
NM_MT_REST_EVENT_REP_NACK,
NM_MT_CHG_ADM_STATE,
NM_MT_CHG_ADM_STATE_ACK,
NM_MT_CHG_ADM_STATE_NACK,
NM_MT_CHG_ADM_STATE_REQ,
NM_MT_CHG_ADM_STATE_REQ_ACK,
NM_MT_CHG_ADM_STATE_REQ_NACK,
NM_MT_REP_OUTST_ALARMS = 0x93,
NM_MT_REP_OUTST_ALARMS_ACK,
NM_MT_REP_OUTST_ALARMS_NACK,
/* Equipment Management Messages */
NM_MT_CHANGEOVER = 0x71,
NM_MT_CHANGEOVER_ACK,
NM_MT_CHANGEOVER_NACK,
NM_MT_OPSTART,
NM_MT_OPSTART_ACK,
NM_MT_OPSTART_NACK,
NM_MT_REINIT,
NM_MT_REINIT_ACK,
NM_MT_REINIT_NACK,
NM_MT_SET_SITE_OUT, /* BS11: get alarm ?!? */
NM_MT_SET_SITE_OUT_ACK,
NM_MT_SET_SITE_OUT_NACK,
NM_MT_CHG_HW_CONF = 0x90,
NM_MT_CHG_HW_CONF_ACK,
NM_MT_CHG_HW_CONF_NACK,
/* Measurement Management Messages */
NM_MT_MEAS_RES_REQ = 0x8a,
NM_MT_MEAS_RES_RESP,
NM_MT_STOP_MEAS,
NM_MT_START_MEAS,
/* Other Messages */
NM_MT_GET_ATTR = 0x81,
NM_MT_GET_ATTR_RESP,
NM_MT_GET_ATTR_NACK,
NM_MT_SET_ALARM_THRES,
NM_MT_SET_ALARM_THRES_ACK,
NM_MT_SET_ALARM_THRES_NACK,
};
enum abis_nm_msgtype_bs11 {
NM_MT_BS11_RESET_RESOURCE = 0x74,
NM_MT_BS11_BEGIN_DB_TX = 0xa3,
NM_MT_BS11_BEGIN_DB_TX_ACK,
NM_MT_BS11_BEGIN_DB_TX_NACK,
NM_MT_BS11_END_DB_TX = 0xa6,
NM_MT_BS11_END_DB_TX_ACK,
NM_MT_BS11_END_DB_TX_NACK,
NM_MT_BS11_CREATE_OBJ = 0xa9,
NM_MT_BS11_CREATE_OBJ_ACK,
NM_MT_BS11_CREATE_OBJ_NACK,
NM_MT_BS11_DELETE_OBJ = 0xac,
NM_MT_BS11_DELETE_OBJ_ACK,
NM_MT_BS11_DELETE_OBJ_NACK,
NM_MT_BS11_SET_ATTR = 0xd0,
NM_MT_BS11_SET_ATTR_ACK,
NM_MT_BS11_SET_ATTR_NACK,
NM_MT_BS11_LMT_SESSION = 0xdc,
NM_MT_BS11_GET_STATE = 0xe3,
NM_MT_BS11_GET_STATE_ACK,
NM_MT_BS11_LMT_LOGON = 0xe5,
NM_MT_BS11_LMT_LOGON_ACK,
NM_MT_BS11_RESTART = 0xe7,
NM_MT_BS11_RESTART_ACK,
NM_MT_BS11_DISCONNECT = 0xe9,
NM_MT_BS11_DISCONNECT_ACK,
NM_MT_BS11_LMT_LOGOFF = 0xec,
NM_MT_BS11_LMT_LOGOFF_ACK,
NM_MT_BS11_RECONNECT = 0xf1,
NM_MT_BS11_RECONNECT_ACK,
};
enum abis_nm_msgtype_ipacc {
NM_MT_IPACC_RESTART = 0x87,
NM_MT_IPACC_RESTART_ACK,
NM_MT_IPACC_RSL_CONNECT = 0xe0,
NM_MT_IPACC_RSL_CONNECT_ACK,
NM_MT_IPACC_RSL_CONNECT_NACK,
NM_MT_IPACC_RSL_DISCONNECT = 0xe3,
NM_MT_IPACC_RSL_DISCONNECT_ACK,
NM_MT_IPACC_RSL_DISCONNECT_NACK,
NM_MT_IPACC_CONN_TRAF = 0xe6,
NM_MT_IPACC_CONN_TRAF_ACK,
NM_MT_IPACC_CONN_TRAF_NACK,
NM_MT_IPACC_DEF_BOOT_SW = 0xec,
NM_MT_IPACC_DEF_BOOT_SW_ACK,
MN_MT_IPACC_DEF_BOOT_SW_NACK,
NM_MT_IPACC_SET_NVATTR = 0xef,
NM_MT_IPACC_SET_NVATTR_ACK,
NM_MT_IPACC_SET_NVATTR_NACK,
NM_MT_IPACC_GET_NVATTR = 0xf2,
NM_MT_IPACC_GET_NVATTR_ACK,
NM_MT_IPACC_GET_NVATTR_NACK,
NM_MT_IPACC_SET_ATTR = 0xf5,
NM_MT_IPACC_SET_ATTR_ACK,
NM_MT_IPACC_SET_ATTR_NACK,
};
enum abis_nm_bs11_cell_alloc {
NM_BS11_CANR_GSM = 0x00,
NM_BS11_CANR_DCS1800 = 0x01,
};
/* Section 9.2: Object Class */
enum abis_nm_obj_class {
NM_OC_SITE_MANAGER = 0x00,
NM_OC_BTS,
NM_OC_RADIO_CARRIER,
NM_OC_CHANNEL,
NM_OC_BASEB_TRANSC,
/* RFU: 05-FE */
NM_OC_IPAC_E1_TRUNK = 0x0e,
NM_OC_IPAC_E1_PORT = 0x0f,
NM_OC_IPAC_E1_CHAN = 0x10,
NM_OC_IPAC_CLK_MODULE = 0x22,
NM_OC_BS11_ADJC = 0xa0,
NM_OC_BS11_HANDOVER = 0xa1,
NM_OC_BS11_PWR_CTRL = 0xa2,
NM_OC_BS11_BTSE = 0xa3, /* LMT? */
NM_OC_BS11_RACK = 0xa4,
NM_OC_BS11 = 0xa5, /* 01: ALCO */
NM_OC_BS11_TEST = 0xa6,
NM_OC_BS11_ENVABTSE = 0xa8,
NM_OC_BS11_BPORT = 0xa9,
NM_OC_GPRS_NSE = 0xf0,
NM_OC_GPRS_CELL = 0xf1,
NM_OC_GPRS_NSVC = 0xf2,
NM_OC_NULL = 0xff,
};
/* Section 9.4: Attributes */
enum abis_nm_attr {
NM_ATT_ABIS_CHANNEL = 0x01,
NM_ATT_ADD_INFO,
NM_ATT_ADD_TEXT,
NM_ATT_ADM_STATE,
NM_ATT_ARFCN_LIST,
NM_ATT_AUTON_REPORT,
NM_ATT_AVAIL_STATUS,
NM_ATT_BCCH_ARFCN,
NM_ATT_BSIC,
NM_ATT_BTS_AIR_TIMER,
NM_ATT_CCCH_L_I_P,
NM_ATT_CCCH_L_T,
NM_ATT_CHAN_COMB,
NM_ATT_CONN_FAIL_CRIT,
NM_ATT_DEST,
/* res */
NM_ATT_EVENT_TYPE = 0x11, /* BS11: file data ?!? */
NM_ATT_FILE_ID,
NM_ATT_FILE_VERSION,
NM_ATT_GSM_TIME,
NM_ATT_HSN,
NM_ATT_HW_CONFIG,
NM_ATT_HW_DESC,
NM_ATT_INTAVE_PARAM,
NM_ATT_INTERF_BOUND,
NM_ATT_LIST_REQ_ATTR,
NM_ATT_MAIO,
NM_ATT_MANUF_STATE,
NM_ATT_MANUF_THRESH,
NM_ATT_MANUF_ID,
NM_ATT_MAX_TA,
NM_ATT_MDROP_LINK, /* 0x20 */
NM_ATT_MDROP_NEXT,
NM_ATT_NACK_CAUSES,
NM_ATT_NY1,
NM_ATT_OPER_STATE,
NM_ATT_OVERL_PERIOD,
NM_ATT_PHYS_CONF,
NM_ATT_POWER_CLASS,
NM_ATT_POWER_THRESH,
NM_ATT_PROB_CAUSE,
NM_ATT_RACH_B_THRESH,
NM_ATT_LDAVG_SLOTS,
NM_ATT_RAD_SUBC,
NM_ATT_RF_MAXPOWR_R,
NM_ATT_SITE_INPUTS,
NM_ATT_SITE_OUTPUTS,
NM_ATT_SOURCE, /* 0x30 */
NM_ATT_SPEC_PROB,
NM_ATT_START_TIME,
NM_ATT_T200,
NM_ATT_TEI,
NM_ATT_TEST_DUR,
NM_ATT_TEST_NO,
NM_ATT_TEST_REPORT,
NM_ATT_VSWR_THRESH,
NM_ATT_WINDOW_SIZE,
/* Res */
NM_ATT_BS11_RSSI_OFFS = 0x3d,
NM_ATT_BS11_TXPWR = 0x3e,
NM_ATT_BS11_DIVERSITY = 0x3f,
/* Res */
NM_ATT_TSC = 0x40,
NM_ATT_SW_CONFIG,
NM_ATT_SW_DESCR,
NM_ATT_SEVERITY,
NM_ATT_GET_ARI,
NM_ATT_HW_CONF_CHG,
NM_ATT_OUTST_ALARM,
NM_ATT_FILE_DATA,
NM_ATT_MEAS_RES,
NM_ATT_MEAS_TYPE,
NM_ATT_BS11_ESN_FW_CODE_NO = 0x4c,
NM_ATT_BS11_ESN_HW_CODE_NO = 0x4f,
NM_ATT_BS11_ESN_PCB_SERIAL = 0x55,
NM_ATT_BS11_EXCESSIVE_DISTANCE = 0x58,
NM_ATT_BS11_ALL_TEST_CATG = 0x60,
NM_ATT_BS11_BTSLS_HOPPING,
NM_ATT_BS11_CELL_ALLOC_NR,
NM_ATT_BS11_CELL_GLOBAL_ID,
NM_ATT_BS11_ENA_INTERF_CLASS = 0x66,
NM_ATT_BS11_ENA_INT_INTEC_HANDO = 0x67,
NM_ATT_BS11_ENA_INT_INTRC_HANDO = 0x68,
NM_ATT_BS11_ENA_MS_PWR_CTRL = 0x69,
NM_ATT_BS11_ENA_PWR_BDGT_HO = 0x6a,
NM_ATT_BS11_ENA_PWR_CTRL_RLFW = 0x6b,
NM_ATT_BS11_ENA_RXLEV_HO = 0x6c,
NM_ATT_BS11_ENA_RXQUAL_HO = 0x6d,
NM_ATT_BS11_FACCH_QUAL = 0x6e,
NM_ATT_IPACC_DST_IP = 0x80,
NM_ATT_IPACC_DST_IP_PORT = 0x81,
NM_ATT_IPACC_SSRC = 0x82,
NM_ATT_IPACC_RTP_PAYLD_TYPE = 0x83,
NM_ATT_IPACC_BASEB_ID = 0x84,
NM_ATT_IPACC_STREAM_ID = 0x85,
NM_ATT_IPACC_NV_FLAGS = 0x86,
NM_ATT_IPACC_FREQ_CTRL = 0x87,
NM_ATT_IPACC_PRIM_OML_CFG = 0x88,
NM_ATT_IPACC_SEC_OML_CFG = 0x89,
NM_ATT_IPACC_IP_IF_CFG = 0x8a, /* IP interface */
NM_ATT_IPACC_IP_GW_CFG = 0x8b, /* IP gateway */
NM_ATT_IPACC_IN_SERV_TIME = 0x8c,
NM_ATT_IPACC_TRX_BTS_ASS = 0x8d,
NM_ATT_IPACC_LOCATION = 0x8e, /* string describing location */
NM_ATT_IPACC_PAGING_CFG = 0x8f,
NM_ATT_IPACC_FILE_DATA = 0x90,
NM_ATT_IPACC_UNIT_ID = 0x91, /* Site/BTS/TRX */
NM_ATT_IPACC_PARENT_UNIT_ID = 0x92,
NM_ATT_IPACC_UNIT_NAME = 0x93, /* default: nbts-<mac-as-string> */
NM_ATT_IPACC_SNMP_CFG = 0x94,
NM_ATT_IPACC_PRIM_OML_CFG_LIST = 0x95,
NM_ATT_IPACC_PRIM_OML_FB_TOUT = 0x96,
NM_ATT_IPACC_CUR_SW_CFG = 0x97,
NM_ATT_IPACC_TIMING_BUS = 0x98,
NM_ATT_IPACC_CGI = 0x99,
NM_ATT_IPACC_RAC = 0x9a,
NM_ATT_IPACC_OBJ_VERSION = 0x9b,
NM_ATT_IPACC_GPRS_PAGING_CFG = 0x9c,
NM_ATT_IPACC_NSEI = 0x9d,
NM_ATT_IPACC_BVCI = 0x9e,
NM_ATT_IPACC_NSVCI = 0x9f,
NM_ATT_IPACC_NS_CFG = 0xa0,
NM_ATT_IPACC_BSSGP_CFG = 0xa1,
NM_ATT_IPACC_NS_LINK_CFG = 0xa2,
NM_ATT_IPACC_RLC_CFG = 0xa3,
NM_ATT_IPACC_ALM_THRESH_LIST = 0xa4,
NM_ATT_IPACC_MONIT_VAL_LIST = 0xa5,
NM_ATT_IPACC_TIB_CONTROL = 0xa6,
NM_ATT_IPACC_SUPP_FEATURES = 0xa7,
NM_ATT_IPACC_CODING_SCHEMES = 0xa8,
NM_ATT_IPACC_RLC_CFG_2 = 0xa9,
NM_ATT_IPACC_HEARTB_TOUT = 0xaa,
NM_ATT_IPACC_UPTIME = 0xab,
NM_ATT_IPACC_RLC_CFG_3 = 0xac,
NM_ATT_IPACC_SSL_CFG = 0xad,
NM_ATT_IPACC_SEC_POSSIBLE = 0xae,
NM_ATT_IPACC_IML_SSL_STATE = 0xaf,
NM_ATT_IPACC_REVOC_DATE = 0xb0,
NM_ATT_BS11_RF_RES_IND_PER = 0x8f,
NM_ATT_BS11_RX_LEV_MIN_CELL = 0x90,
NM_ATT_BS11_ABIS_EXT_TIME = 0x91,
NM_ATT_BS11_TIMER_HO_REQUEST = 0x92,
NM_ATT_BS11_TIMER_NCELL = 0x93,
NM_ATT_BS11_TSYNC = 0x94,
NM_ATT_BS11_TTRAU = 0x95,
NM_ATT_BS11_EMRG_CFG_MEMBER = 0x9b,
NM_ATT_BS11_TRX_AREA = 0x9f,
NM_ATT_BS11_BCCH_RECONF = 0xd7,
NM_ATT_BS11_BIT_ERR_THESH = 0xa0,
NM_ATT_BS11_BOOT_SW_VERS = 0xa1,
NM_ATT_BS11_CCLK_ACCURACY = 0xa3,
NM_ATT_BS11_CCLK_TYPE = 0xa4,
NM_ATT_BS11_INP_IMPEDANCE = 0xaa,
NM_ATT_BS11_L1_PROT_TYPE = 0xab,
NM_ATT_BS11_LINE_CFG = 0xac,
NM_ATT_BS11_LI_PORT_1 = 0xad,
NM_ATT_BS11_LI_PORT_2 = 0xae,
NM_ATT_BS11_L1_REM_ALM_TYPE = 0xb0,
NM_ATT_BS11_SW_LOAD_INTENDED = 0xbb,
NM_ATT_BS11_SW_LOAD_SAFETY = 0xbc,
NM_ATT_BS11_SW_LOAD_STORED = 0xbd,
NM_ATT_BS11_VENDOR_NAME = 0xc1,
NM_ATT_BS11_HOPPING_MODE = 0xc5,
NM_ATT_BS11_LMT_LOGON_SESSION = 0xc6,
NM_ATT_BS11_LMT_LOGIN_TIME = 0xc7,
NM_ATT_BS11_LMT_USER_ACC_LEV = 0xc8,
NM_ATT_BS11_LMT_USER_NAME = 0xc9,
NM_ATT_BS11_L1_CONTROL_TS = 0xd8,
NM_ATT_BS11_RADIO_MEAS_GRAN = 0xdc, /* in SACCH multiframes */
NM_ATT_BS11_RADIO_MEAS_REP = 0xdd,
NM_ATT_BS11_SH_LAPD_INT_TIMER = 0xe8,
NM_ATT_BS11_BTS_STATE = 0xf0,
NM_ATT_BS11_E1_STATE = 0xf1,
NM_ATT_BS11_PLL = 0xf2,
NM_ATT_BS11_RX_OFFSET = 0xf3,
NM_ATT_BS11_ANT_TYPE = 0xf4,
NM_ATT_BS11_PLL_MODE = 0xfc,
NM_ATT_BS11_PASSWORD = 0xfd,
};
#define NM_ATT_BS11_FILE_DATA NM_ATT_EVENT_TYPE
/* Section 9.4.4: Administrative State */
enum abis_nm_adm_state {
NM_STATE_LOCKED = 0x01,
NM_STATE_UNLOCKED = 0x02,
NM_STATE_SHUTDOWN = 0x03,
NM_STATE_NULL = 0xff,
};
/* Section 9.4.7: Administrative State */
enum abis_nm_avail_state {
NM_AVSTATE_IN_TEST = 1,
NM_AVSTATE_POWER_OFF = 2,
NM_AVSTATE_OFF_LINE = 3,
NM_AVSTATE_DEPENDENCY = 5,
NM_AVSTATE_DEGRADED = 6,
NM_AVSTATE_NOT_INSTALLED= 7,
NM_AVSTATE_OK = 0xff,
};
/* Section 9.4.13: Channel Combination */
enum abis_nm_chan_comb {
NM_CHANC_TCHFull = 0x00, /* TCH/F + TCH/H + SACCH/TF */
NM_CHANC_TCHHalf = 0x01, /* TCH/H(0,1) + FACCH/H(0,1) +
SACCH/TH(0,1) */
NM_CHANC_TCHHalf2 = 0x02, /* TCH/H(0) + FACCH/H(0) + SACCH/TH(0) +
TCH/H(1) */
NM_CHANC_SDCCH = 0x03, /* SDCCH/8 + SACCH/8 */
NM_CHANC_mainBCCH = 0x04, /* FCCH + SCH + BCCH + CCCH */
NM_CHANC_BCCHComb = 0x05, /* FCCH + SCH + BCCH + CCCH + SDCCH/4 +
SACCH/C4 */
NM_CHANC_BCCH = 0x06, /* BCCH + CCCH */
NM_CHANC_BCCH_CBCH = 0x07, /* CHANC_BCCHComb + CBCH */
NM_CHANC_SDCCH_CBCH = 0x08, /* CHANC_SDCCH8 + CBCH */
/* ip.access */
NM_CHANC_IPAC_bPDCH = 0x0b, /* PBCCH + PCCCH + PDTCH/F + PACCH/F +
PTCCH/F */
NM_CHANC_IPAC_cPDCH = 0x0c, /* PBCCH + PDTCH/F + PACCH/F + PTCCH/F */
NM_CHANC_IPAC_PDCH = 0x0d, /* PDTCH/F + PACCH/F + PTCCH/F */
NM_CHANC_IPAC_TCHFull_PDCH = 0x80,
NM_CHANC_IPAC_TCHFull_TCHHalf = 0x81,
};
/* Section 9.4.16: Event Type */
enum abis_nm_event_type {
NM_EVT_COMM_FAIL = 0x00,
NM_EVT_QOS_FAIL = 0x01,
NM_EVT_PROC_FAIL = 0x02,
NM_EVT_EQUIP_FAIL = 0x03,
NM_EVT_ENV_FAIL = 0x04,
};
/* Section: 9.4.63: Perceived Severity */
enum abis_nm_severity {
NM_SEVER_CEASED = 0x00,
NM_SEVER_CRITICAL = 0x01,
NM_SEVER_MAJOR = 0x02,
NM_SEVER_MINOR = 0x03,
NM_SEVER_WARNING = 0x04,
NM_SEVER_INDETERMINATE = 0x05,
};
/* Section 9.4.43: Probable Cause Type */
enum abis_nm_pcause_type {
NM_PCAUSE_T_X721 = 0x01,
NM_PCAUSE_T_GSM = 0x02,
NM_PCAUSE_T_MANUF = 0x03,
};
/* Section 9.4.36: NACK Causes */
enum abis_nm_nack_cause {
/* General Nack Causes */
NM_NACK_INCORR_STRUCT = 0x01,
NM_NACK_MSGTYPE_INVAL = 0x02,
NM_NACK_OBJCLASS_INVAL = 0x05,
NM_NACK_OBJCLASS_NOTSUPP = 0x06,
NM_NACK_BTSNR_UNKN = 0x07,
NM_NACK_TRXNR_UNKN = 0x08,
NM_NACK_OBJINST_UNKN = 0x09,
NM_NACK_ATTRID_INVAL = 0x0c,
NM_NACK_ATTRID_NOTSUPP = 0x0d,
NM_NACK_PARAM_RANGE = 0x0e,
NM_NACK_ATTRLIST_INCONSISTENT = 0x0f,
NM_NACK_SPEC_IMPL_NOTSUPP = 0x10,
NM_NACK_CANT_PERFORM = 0x11,
/* Specific Nack Causes */
NM_NACK_RES_NOTIMPL = 0x19,
NM_NACK_RES_NOTAVAIL = 0x1a,
NM_NACK_FREQ_NOTAVAIL = 0x1b,
NM_NACK_TEST_NOTSUPP = 0x1c,
NM_NACK_CAPACITY_RESTR = 0x1d,
NM_NACK_PHYSCFG_NOTPERFORM = 0x1e,
NM_NACK_TEST_NOTINIT = 0x1f,
NM_NACK_PHYSCFG_NOTRESTORE = 0x20,
NM_NACK_TEST_NOSUCH = 0x21,
NM_NACK_TEST_NOSTOP = 0x22,
NM_NACK_MSGINCONSIST_PHYSCFG = 0x23,
NM_NACK_FILE_INCOMPLETE = 0x25,
NM_NACK_FILE_NOTAVAIL = 0x26,
NM_NACK_FILE_NOTACTIVATE = 0x27,
NM_NACK_REQ_NOT_GRANT = 0x28,
NM_NACK_WAIT = 0x29,
NM_NACK_NOTH_REPORT_EXIST = 0x2a,
NM_NACK_MEAS_NOTSUPP = 0x2b,
NM_NACK_MEAS_NOTSTART = 0x2c,
};
/* Section 9.4.1 */
struct abis_nm_channel {
u_int8_t attrib;
u_int8_t bts_port;
u_int8_t timeslot;
u_int8_t subslot;
} __attribute__ ((packed));
/* Siemens BS-11 specific objects in the SienemsHW (0xA5) object class */
enum abis_bs11_objtype {
BS11_OBJ_ALCO = 0x01,
BS11_OBJ_BBSIG = 0x02, /* obj_class: 0,1 */
BS11_OBJ_TRX1 = 0x03, /* only DEACTIVATE TRX1 */
BS11_OBJ_CCLK = 0x04,
BS11_OBJ_GPSU = 0x06,
BS11_OBJ_LI = 0x07,
BS11_OBJ_PA = 0x09, /* obj_class: 0, 1*/
};
enum abis_bs11_trx_power {
BS11_TRX_POWER_GSM_2W = 0x06,
BS11_TRX_POWER_GSM_250mW= 0x07,
BS11_TRX_POWER_GSM_80mW = 0x08,
BS11_TRX_POWER_GSM_30mW = 0x09,
BS11_TRX_POWER_DCS_3W = 0x0a,
BS11_TRX_POWER_DCS_1W6 = 0x0b,
BS11_TRX_POWER_DCS_500mW= 0x0c,
BS11_TRX_POWER_DCS_160mW= 0x0d,
};
enum abis_bs11_li_pll_mode {
BS11_LI_PLL_LOCKED = 2,
BS11_LI_PLL_STANDALONE = 3,
};
enum abis_bs11_line_cfg {
BS11_LINE_CFG_STAR = 0x00,
BS11_LINE_CFG_MULTIDROP = 0x01,
BS11_LINE_CFG_LOOP = 0x02,
};
enum abis_bs11_phase {
BS11_STATE_SOFTWARE_RQD = 0x01,
BS11_STATE_LOAD_SMU_INTENDED = 0x11,
BS11_STATE_LOAD_SMU_SAFETY = 0x21,
BS11_STATE_LOAD_FAILED = 0x31,
BS11_STATE_LOAD_DIAGNOSTIC = 0x41,
BS11_STATE_WARM_UP = 0x51,
BS11_STATE_WARM_UP_2 = 0x52,
BS11_STATE_WAIT_MIN_CFG = 0x62,
BS11_STATE_MAINTENANCE = 0x72,
BS11_STATE_LOAD_MBCCU = 0x92,
BS11_STATE_WAIT_MIN_CFG_2 = 0xA2,
BS11_STATE_NORMAL = 0x03,
BS11_STATE_ABIS_LOAD = 0x13,
};
enum abis_nm_ipacc_test_no {
NM_IPACC_TESTNO_RLOOP_ANT = 0x01,
NM_IPACC_TESTNO_RLOOP_XCVR = 0x02,
NM_IPACC_TESTNO_FUNC_OBJ = 0x03,
NM_IPACC_TESTNO_CHAN_USAGE = 0x40,
NM_IPACC_TESTNO_BCCH_CHAN_USAGE = 0x41,
NM_IPACC_TESTNO_FREQ_SYNC = 0x42,
NM_IPACC_TESTNO_BCCH_INFO = 0x43,
NM_IPACC_TESTNO_TX_BEACON = 0x44,
NM_IPACC_TESTNO_SYSINFO_MONITOR = 0x45,
NM_IPACC_TESTNO_BCCCH_MONITOR = 0x46,
};
/* first byte after length inside NM_ATT_TEST_REPORT */
enum abis_nm_ipacc_test_res {
NM_IPACC_TESTRES_SUCCESS = 0,
NM_IPACC_TESTRES_TIMEOUT = 1,
NM_IPACC_TESTRES_NO_CHANS = 2,
NM_IPACC_TESTRES_PARTIAL = 3,
NM_IPACC_TESTRES_STOPPED = 4,
};
/* internal IE inside NM_ATT_TEST_REPORT */
enum abis_nm_ipacc_testres_ie {
NM_IPACC_TR_IE_FREQ_ERR_LIST = 3,
NM_IPACC_TR_IE_CHAN_USAGE = 4,
NM_IPACC_TR_IE_BCCH_INFO = 6,
NM_IPACC_TR_IE_RESULT_DETAILS = 8,
NM_IPACC_TR_IE_FREQ_ERR = 18,
};
enum ipac_eie {
NM_IPAC_EIE_ARFCN_WHITE = 0x01,
NM_IPAC_EIE_ARFCH_BLACK = 0x02,
NM_IPAC_EIE_FREQ_ERR_LIST = 0x03,
NM_IPAC_EIE_CHAN_USE_LIST = 0x04,
NM_IPAC_EIE_BCCH_INFO_TYPE = 0x05,
NM_IPAC_EIE_BCCH_INFO = 0x06,
/* FIXME */
};
enum ipac_bcch_info_type {
IPAC_BINF_RXLEV = (1 << 8),
IPAC_BINF_RXQUAL = (1 << 9),
IPAC_BINF_FREQ_ERR_QUAL = (1 << 10),
IPAC_BINF_FRAME_OFFSET = (1 << 11),
IPAC_BINF_FRAME_NR_OFFSET = (1 << 12),
IPAC_BINF_BSIC = (1 << 13),
IPAC_BINF_CGI = (1 << 14),
IPAC_BINF_NEIGH_BA_SI2 = (1 << 15),
IPAC_BINF_NEIGH_BA_SI2bis = (1 << 0),
IPAC_BINF_NEIGH_BA_SI2ter = (1 << 1),
IPAC_BINF_CELL_ALLOC = (1 << 2),
};
struct cell_global_id {
u_int16_t mcc;
@@ -55,8 +712,6 @@ struct ipac_bcch_info {
u_int8_t ca_list_si1[16];
};
extern const struct tlv_definition nm_att_tlvdef;
/* PUBLIC */
struct msgb;
@@ -71,7 +726,7 @@ struct abis_nm_cfg {
extern int abis_nm_rcvmsg(struct msgb *msg);
int abis_nm_tlv_parse(struct tlv_parsed *tp, struct gsm_bts *bts, const u_int8_t *buf, int len);
int abis_nm_tlv_parse(struct tlv_parsed *tp, const u_int8_t *buf, int len);
int abis_nm_rx(struct msgb *msg);
int abis_nm_opstart(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i0, u_int8_t i1, u_int8_t i2);
int abis_nm_chg_adm_state(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i0,
@@ -125,13 +780,10 @@ int abis_nm_bs11_get_oml_tei_ts(struct gsm_bts *bts);
int abis_nm_bs11_get_serno(struct gsm_bts *bts);
int abis_nm_bs11_set_trx_power(struct gsm_bts_trx *trx, u_int8_t level);
int abis_nm_bs11_get_trx_power(struct gsm_bts_trx *trx);
int abis_nm_bs11_logon(struct gsm_bts *bts, u_int8_t level, const char *name, int on);
int abis_nm_bs11_factory_logon(struct gsm_bts *bts, int on);
int abis_nm_bs11_infield_logon(struct gsm_bts *bts, int on);
int abis_nm_bs11_set_trx1_pw(struct gsm_bts *bts, const char *password);
int abis_nm_bs11_set_pll_locked(struct gsm_bts *bts, int locked);
int abis_nm_bs11_get_pll_mode(struct gsm_bts *bts);
int abis_nm_bs11_set_pll(struct gsm_bts *bts, int value);
int abis_nm_bs11_get_cclk(struct gsm_bts *bts);
int abis_nm_bs11_get_state(struct gsm_bts *bts);
int abis_nm_bs11_load_swl(struct gsm_bts *bts, const char *fname,
@@ -146,7 +798,7 @@ int abis_nm_ipaccess_msg(struct gsm_bts *bts, u_int8_t msg_type,
u_int8_t obj_class, u_int8_t bts_nr,
u_int8_t trx_nr, u_int8_t ts_nr,
u_int8_t *attr, int attr_len);
int abis_nm_ipaccess_set_nvattr(struct gsm_bts_trx *trx, u_int8_t *attr,
int abis_nm_ipaccess_set_nvattr(struct gsm_bts *bts, u_int8_t *attr,
int attr_len);
int abis_nm_ipaccess_restart(struct gsm_bts *bts);
int abis_nm_ipaccess_set_attr(struct gsm_bts *bts, u_int8_t obj_class,
@@ -154,7 +806,6 @@ int abis_nm_ipaccess_set_attr(struct gsm_bts *bts, u_int8_t obj_class,
u_int8_t *attr, u_int8_t attr_len);
int abis_nm_ipaccess_rsl_connect(struct gsm_bts_trx *trx,
u_int32_t ip, u_int16_t port, u_int8_t stream);
void abis_nm_ipaccess_cgi(u_int8_t *buf, struct gsm_bts *bts);
int ipac_parse_bcch_info(struct ipac_bcch_info *binf, u_int8_t *buf);
const char *ipacc_testres_name(u_int8_t res);
@@ -168,5 +819,4 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
const char *nm_opstate_name(u_int8_t os);
const char *nm_avail_name(u_int8_t avail);
int nm_is_running(struct gsm_nm_state *s);
#endif /* _NM_H */

View File

@@ -23,9 +23,468 @@
#ifndef _RSL_H
#define _RSL_H
#include <osmocore/protocol/gsm_08_58.h>
struct abis_rsl_common_hdr {
u_int8_t msg_discr;
u_int8_t msg_type;
u_int8_t data[0];
} __attribute__ ((packed));
#include <osmocore/msgb.h>
/* Chapter 8.3 */
struct abis_rsl_rll_hdr {
struct abis_rsl_common_hdr c;
u_int8_t ie_chan;
u_int8_t chan_nr;
u_int8_t ie_link_id;
u_int8_t link_id;
u_int8_t data[0];
} __attribute__ ((packed));
/* Chapter 8.3 and 8.4 */
struct abis_rsl_dchan_hdr {
struct abis_rsl_common_hdr c;
u_int8_t ie_chan;
u_int8_t chan_nr;
u_int8_t data[0];
} __attribute__ ((packed));
/* Chapter 9.1 */
#define ABIS_RSL_MDISC_RLL 0x02
#define ABIS_RSL_MDISC_DED_CHAN 0x08
#define ABIS_RSL_MDISC_COM_CHAN 0x0c
#define ABIS_RSL_MDISC_TRX 0x10
#define ABIS_RSL_MDISC_LOC 0x20
#define ABIS_RSL_MDISC_IPACCESS 0x7e
#define ABIS_RSL_MDISC_TRANSP 0x01
#define ABIS_RSL_MDISC_IS_TRANSP(x) (x & 0x01)
/* Chapter 9.1 */
enum abis_rsl_msgtype {
/* Radio Link Layer Management */
RSL_MT_DATA_REQ = 0x01,
RSL_MT_DATA_IND,
RSL_MT_ERROR_IND,
RSL_MT_EST_REQ,
RSL_MT_EST_CONF,
RSL_MT_EST_IND,
RSL_MT_REL_REQ,
RSL_MT_REL_CONF,
RSL_MT_REL_IND,
RSL_MT_UNIT_DATA_REQ,
RSL_MT_UNIT_DATA_IND, /* 0x0b */
/* Common Channel Management / TRX Management */
RSL_MT_BCCH_INFO = 0x11,
RSL_MT_CCCH_LOAD_IND,
RSL_MT_CHAN_RQD,
RSL_MT_DELETE_IND,
RSL_MT_PAGING_CMD,
RSL_MT_IMMEDIATE_ASSIGN_CMD,
RSL_MT_SMS_BC_REQ,
/* empty */
RSL_MT_RF_RES_IND = 0x19,
RSL_MT_SACCH_FILL,
RSL_MT_OVERLOAD,
RSL_MT_ERROR_REPORT,
RSL_MT_SMS_BC_CMD,
RSL_MT_CBCH_LOAD_IND,
RSL_MT_NOT_CMD, /* 0x1f */
/* Dedicate Channel Management */
RSL_MT_CHAN_ACTIV = 0x21,
RSL_MT_CHAN_ACTIV_ACK,
RSL_MT_CHAN_ACTIV_NACK,
RSL_MT_CONN_FAIL,
RSL_MT_DEACTIVATE_SACCH,
RSL_MT_ENCR_CMD,
RSL_MT_HANDO_DET,
RSL_MT_MEAS_RES,
RSL_MT_MODE_MODIFY_REQ,
RSL_MT_MODE_MODIFY_ACK,
RSL_MT_MODE_MODIFY_NACK,
RSL_MT_PHY_CONTEXT_REQ,
RSL_MT_PHY_CONTEXT_CONF,
RSL_MT_RF_CHAN_REL,
RSL_MT_MS_POWER_CONTROL,
RSL_MT_BS_POWER_CONTROL, /* 0x30 */
RSL_MT_PREPROC_CONFIG,
RSL_MT_PREPROC_MEAS_RES,
RSL_MT_RF_CHAN_REL_ACK,
RSL_MT_SACCH_INFO_MODIFY,
RSL_MT_TALKER_DET,
RSL_MT_LISTENER_DET,
RSL_MT_REMOTE_CODEC_CONF_REP,
RSL_MT_RTD_REP,
RSL_MT_PRE_HANDO_NOTIF,
RSL_MT_MR_CODEC_MOD_REQ,
RSL_MT_MR_CODEC_MOD_ACK,
RSL_MT_MR_CODEC_MOD_NACK,
RSL_MT_MR_CODEC_MOD_PER,
RSL_MT_TFO_REP,
RSL_MT_TFO_MOD_REQ, /* 0x3f */
RSL_MT_LOCATION_INFO = 0x41,
/* ip.access specific RSL message types */
RSL_MT_IPAC_DIR_RETR_ENQ = 0x40,
RSL_MT_IPAC_PDCH_ACT = 0x48,
RSL_MT_IPAC_PDCH_ACT_ACK,
RSL_MT_IPAC_PDCH_ACT_NACK,
RSL_MT_IPAC_PDCH_DEACT = 0x4b,
RSL_MT_IPAC_PDCH_DEACT_ACK,
RSL_MT_IPAC_PDCH_DEACT_NACK,
RSL_MT_IPAC_CONNECT_MUX = 0x50,
RSL_MT_IPAC_CONNECT_MUX_ACK,
RSL_MT_IPAC_CONNECT_MUX_NACK,
RSL_MT_IPAC_BIND_MUX = 0x53,
RSL_MT_IPAC_BIND_MUX_ACK,
RSL_MT_IPAC_BIND_MUX_NACK,
RSL_MT_IPAC_DISC_MUX = 0x56,
RSL_MT_IPAC_DISC_MUX_ACK,
RSL_MT_IPAC_DISC_MUX_NACK,
RSL_MT_IPAC_CRCX = 0x70, /* Bind to local BTS RTP port */
RSL_MT_IPAC_CRCX_ACK,
RSL_MT_IPAC_CRCX_NACK,
RSL_MT_IPAC_MDCX = 0x73,
RSL_MT_IPAC_MDCX_ACK,
RSL_MT_IPAC_MDCX_NACK,
RSL_MT_IPAC_DLCX_IND = 0x76,
RSL_MT_IPAC_DLCX = 0x77,
RSL_MT_IPAC_DLCX_ACK,
RSL_MT_IPAC_DLCX_NACK,
};
/* Siemens vendor-specific */
enum abis_rsl_msgtype_siemens {
RSL_MT_SIEMENS_MRPCI = 0x41,
RSL_MT_SIEMENS_INTRAC_HO_COND_IND = 0x42,
RSL_MT_SIEMENS_INTERC_HO_COND_IND = 0x43,
RSL_MT_SIEMENS_FORCED_HO_REQ = 0x44,
RSL_MT_SIEMENS_PREF_AREA_REQ = 0x45,
RSL_MT_SIEMENS_PREF_AREA = 0x46,
RSL_MT_SIEMENS_START_TRACE = 0x47,
RSL_MT_SIEMENS_START_TRACE_ACK = 0x48,
RSL_MT_SIEMENS_STOP_TRACE = 0x49,
RSL_MT_SIEMENS_TRMR = 0x4a,
RSL_MT_SIEMENS_HO_FAIL_IND = 0x4b,
RSL_MT_SIEMENS_STOP_TRACE_ACK = 0x4c,
RSL_MT_SIEMENS_UPLF = 0x4d,
RSL_MT_SIEMENS_UPLB = 0x4e,
RSL_MT_SIEMENS_SET_SYS_INFO_10 = 0x4f,
RSL_MT_SIEMENS_MODIF_COND_IND = 0x50,
};
/* Chapter 9.3 */
enum abis_rsl_ie {
RSL_IE_CHAN_NR = 0x01,
RSL_IE_LINK_IDENT,
RSL_IE_ACT_TYPE,
RSL_IE_BS_POWER,
RSL_IE_CHAN_IDENT,
RSL_IE_CHAN_MODE,
RSL_IE_ENCR_INFO,
RSL_IE_FRAME_NUMBER,
RSL_IE_HANDO_REF,
RSL_IE_L1_INFO,
RSL_IE_L3_INFO,
RSL_IE_MS_IDENTITY,
RSL_IE_MS_POWER,
RSL_IE_PAGING_GROUP,
RSL_IE_PAGING_LOAD,
RSL_IE_PYHS_CONTEXT = 0x10,
RSL_IE_ACCESS_DELAY,
RSL_IE_RACH_LOAD,
RSL_IE_REQ_REFERENCE,
RSL_IE_RELEASE_MODE,
RSL_IE_RESOURCE_INFO,
RSL_IE_RLM_CAUSE,
RSL_IE_STARTNG_TIME,
RSL_IE_TIMING_ADVANCE,
RSL_IE_UPLINK_MEAS,
RSL_IE_CAUSE,
RSL_IE_MEAS_RES_NR,
RSL_IE_MSG_ID,
/* reserved */
RSL_IE_SYSINFO_TYPE = 0x1e,
RSL_IE_MS_POWER_PARAM,
RSL_IE_BS_POWER_PARAM,
RSL_IE_PREPROC_PARAM,
RSL_IE_PREPROC_MEAS,
RSL_IE_IMM_ASS_INFO, /* Phase 1 (3.6.0), later Full below */
RSL_IE_SMSCB_INFO = 0x24,
RSL_IE_MS_TIMING_OFFSET,
RSL_IE_ERR_MSG,
RSL_IE_FULL_BCCH_INFO,
RSL_IE_CHAN_NEEDED,
RSL_IE_CB_CMD_TYPE,
RSL_IE_SMSCB_MSG,
RSL_IE_FULL_IMM_ASS_INFO,
RSL_IE_SACCH_INFO,
RSL_IE_CBCH_LOAD_INFO,
RSL_IE_SMSCB_CHAN_INDICATOR,
RSL_IE_GROUP_CALL_REF,
RSL_IE_CHAN_DESC = 0x30,
RSL_IE_NCH_DRX_INFO,
RSL_IE_CMD_INDICATOR,
RSL_IE_EMLPP_PRIO,
RSL_IE_UIC,
RSL_IE_MAIN_CHAN_REF,
RSL_IE_MR_CONFIG,
RSL_IE_MR_CONTROL,
RSL_IE_SUP_CODEC_TYPES,
RSL_IE_CODEC_CONFIG,
RSL_IE_RTD,
RSL_IE_TFO_STATUS,
RSL_IE_LLP_APDU,
/* Siemens vendor-specific */
RSL_IE_SIEMENS_MRPCI = 0x40,
RSL_IE_SIEMENS_PREF_AREA_TYPE = 0x43,
RSL_IE_SIEMENS_ININ_CELL_HO_PAR = 0x45,
RSL_IE_SIEMENS_TRACE_REF_NR = 0x46,
RSL_IE_SIEMENS_INT_TRACE_IDX = 0x47,
RSL_IE_SIEMENS_L2_HDR_INFO = 0x48,
RSL_IE_SIEMENS_HIGHEST_RATE = 0x4e,
RSL_IE_SIEMENS_SUGGESTED_RATE = 0x4f,
/* ip.access */
RSL_IE_IPAC_SRTP_CONFIG = 0xe0,
RSL_IE_IPAC_PROXY_UDP = 0xe1,
RSL_IE_IPAC_BSCMPL_TOUT = 0xe2,
RSL_IE_IPAC_REMOTE_IP = 0xf0,
RSL_IE_IPAC_REMOTE_PORT = 0xf1,
RSL_IE_IPAC_RTP_PAYLOAD = 0xf2,
RSL_IE_IPAC_LOCAL_PORT = 0xf3,
RSL_IE_IPAC_SPEECH_MODE = 0xf4,
RSL_IE_IPAC_LOCAL_IP = 0xf5,
RSL_IE_IPAC_CONN_STAT = 0xf6,
RSL_IE_IPAC_HO_C_PARMS = 0xf7,
RSL_IE_IPAC_CONN_ID = 0xf8,
RSL_IE_IPAC_RTP_CSD_FMT = 0xf9,
RSL_IE_IPAC_RTP_JIT_BUF = 0xfa,
RSL_IE_IPAC_RTP_COMPR = 0xfb,
RSL_IE_IPAC_RTP_PAYLOAD2= 0xfc,
RSL_IE_IPAC_RTP_MPLEX = 0xfd,
RSL_IE_IPAC_RTP_MPLEX_ID= 0xfe,
};
/* Chapter 9.3.1 */
#define RSL_CHAN_NR_MASK 0xf8
#define RSL_CHAN_Bm_ACCHs 0x08
#define RSL_CHAN_Lm_ACCHs 0x10 /* .. 0x18 */
#define RSL_CHAN_SDCCH4_ACCH 0x20 /* .. 0x38 */
#define RSL_CHAN_SDCCH8_ACCH 0x40 /* ...0x78 */
#define RSL_CHAN_BCCH 0x80
#define RSL_CHAN_RACH 0x88
#define RSL_CHAN_PCH_AGCH 0x90
/* Chapter 9.3.3 */
#define RSL_ACT_TYPE_INITIAL 0x00
#define RSL_ACT_TYPE_REACT 0x80
#define RSL_ACT_INTRA_IMM_ASS 0x00
#define RSL_ACT_INTRA_NORM_ASS 0x01
#define RSL_ACT_INTER_ASYNC 0x02
#define RSL_ACT_INTER_SYNC 0x03
#define RSL_ACT_SECOND_ADD 0x04
#define RSL_ACT_SECOND_MULTI 0x05
/* Chapter 9.3.6 */
struct rsl_ie_chan_mode {
u_int8_t dtx_dtu;
u_int8_t spd_ind;
u_int8_t chan_rt;
u_int8_t chan_rate;
} __attribute__ ((packed));
#define RSL_CMOD_DTXu 0x01 /* uplink */
#define RSL_CMOD_DTXd 0x02 /* downlink */
enum rsl_cmod_spd {
RSL_CMOD_SPD_SPEECH = 0x01,
RSL_CMOD_SPD_DATA = 0x02,
RSL_CMOD_SPD_SIGN = 0x03,
};
#define RSL_CMOD_CRT_SDCCH 0x01
#define RSL_CMOD_CRT_TCH_Bm 0x08 /* full-rate */
#define RSL_CMOD_CRT_TCH_Lm 0x09 /* half-rate */
/* FIXME: More CRT types */
/* Speech */
#define RSL_CMOD_SP_GSM1 0x01
#define RSL_CMOD_SP_GSM2 0x11
#define RSL_CMOD_SP_GSM3 0x21
/* Data */
#define RSL_CMOD_SP_NT_14k5 0x58
#define RSL_CMOD_SP_NT_12k0 0x50
#define RSL_CMOD_SP_NT_6k0 0x51
/* Chapter 9.3.5 */
struct rsl_ie_chan_ident {
/* GSM 04.08 10.5.2.5 */
struct {
u_int8_t iei;
u_int8_t chan_nr; /* enc_chan_nr */
u_int8_t oct3;
u_int8_t oct4;
} chan_desc;
#if 0 /* spec says we need this but Abissim doesn't use it */
struct {
u_int8_t tag;
u_int8_t len;
} mobile_alloc;
#endif
} __attribute__ ((packed));
/* Chapter 9.3.22 */
#define RLL_CAUSE_T200_EXPIRED 0x01
#define RLL_CAUSE_REEST_REQ 0x02
#define RLL_CAUSE_UNSOL_UA_RESP 0x03
#define RLL_CAUSE_UNSOL_DM_RESP 0x04
#define RLL_CAUSE_UNSOL_DM_RESP_MF 0x05
#define RLL_CAUSE_UNSOL_SPRV_RESP 0x06
#define RLL_CAUSE_SEQ_ERR 0x07
#define RLL_CAUSE_UFRM_INC_PARAM 0x08
#define RLL_CAUSE_SFRM_INC_PARAM 0x09
#define RLL_CAUSE_IFRM_INC_MBITS 0x0a
#define RLL_CAUSE_IFRM_INC_LEN 0x0b
#define RLL_CAUSE_FRM_UNIMPL 0x0c
#define RLL_CAUSE_SABM_MF 0x0d
#define RLL_CAUSE_SABM_INFO_NOTALL 0x0e
/* Chapter 9.3.26 */
#define RSL_ERRCLS_NORMAL 0x00
#define RSL_ERRCLS_RESOURCE_UNAVAIL 0x20
#define RSL_ERRCLS_SERVICE_UNAVAIL 0x30
#define RSL_ERRCLS_SERVICE_UNIMPL 0x40
#define RSL_ERRCLS_INVAL_MSG 0x50
#define RSL_ERRCLS_PROTO_ERROR 0x60
#define RSL_ERRCLS_INTERWORKING 0x70
/* normal event */
#define RSL_ERR_RADIO_IF_FAIL 0x00
#define RSL_ERR_RADIO_LINK_FAIL 0x01
#define RSL_ERR_HANDOVER_ACC_FAIL 0x02
#define RSL_ERR_TALKER_ACC_FAIL 0x03
#define RSL_ERR_OM_INTERVENTION 0x07
#define RSL_ERR_NORMAL_UNSPEC 0x0f
#define RSL_ERR_T_MSRFPCI_EXP 0x18
/* resource unavailable */
#define RSL_ERR_EQUIPMENT_FAIL 0x20
#define RSL_ERR_RR_UNAVAIL 0x21
#define RSL_ERR_TERR_CH_FAIL 0x22
#define RSL_ERR_CCCH_OVERLOAD 0x23
#define RSL_ERR_ACCH_OVERLOAD 0x24
#define RSL_ERR_PROCESSOR_OVERLOAD 0x25
#define RSL_ERR_RES_UNAVAIL 0x2f
/* service or option not available */
#define RSL_ERR_TRANSC_UNAVAIL 0x30
#define RSL_ERR_SERV_OPT_UNAVAIL 0x3f
/* service or option not implemented */
#define RSL_ERR_ENCR_UNIMPL 0x40
#define RSL_ERR_SERV_OPT_UNIMPL 0x4f
/* invalid message */
#define RSL_ERR_RCH_ALR_ACTV_ALLOC 0x50
#define RSL_ERR_INVALID_MESSAGE 0x5f
/* protocol error */
#define RSL_ERR_MSG_DISCR 0x60
#define RSL_ERR_MSG_TYPE 0x61
#define RSL_ERR_MSG_SEQ 0x62
#define RSL_ERR_IE_ERROR 0x63
#define RSL_ERR_MAND_IE_ERROR 0x64
#define RSL_ERR_OPT_IE_ERROR 0x65
#define RSL_ERR_IE_NONEXIST 0x66
#define RSL_ERR_IE_LENGTH 0x67
#define RSL_ERR_IE_CONTENT 0x68
#define RSL_ERR_PROTO 0x6f
/* interworking */
#define RSL_ERR_INTERWORKING 0x7f
/* Chapter 9.3.30 */
#define RSL_SYSTEM_INFO_8 0x00
#define RSL_SYSTEM_INFO_1 0x01
#define RSL_SYSTEM_INFO_2 0x02
#define RSL_SYSTEM_INFO_3 0x03
#define RSL_SYSTEM_INFO_4 0x04
#define RSL_SYSTEM_INFO_5 0x05
#define RSL_SYSTEM_INFO_6 0x06
#define RSL_SYSTEM_INFO_7 0x07
#define RSL_SYSTEM_INFO_16 0x08
#define RSL_SYSTEM_INFO_17 0x09
#define RSL_SYSTEM_INFO_2bis 0x0a
#define RSL_SYSTEM_INFO_2ter 0x0b
#define RSL_SYSTEM_INFO_5bis 0x0d
#define RSL_SYSTEM_INFO_5ter 0x0e
#define RSL_SYSTEM_INFO_10 0x0f
#define REL_EXT_MEAS_ORDER 0x47
#define RSL_MEAS_INFO 0x48
#define RSL_SYSTEM_INFO_13 0x28
#define RSL_SYSTEM_INFO_2quater 0x29
#define RSL_SYSTEM_INFO_9 0x2a
#define RSL_SYSTEM_INFO_18 0x2b
#define RSL_SYSTEM_INFO_19 0x2c
#define RSL_SYSTEM_INFO_20 0x2d
/* Chapter 9.3.40 */
#define RSL_CHANNEED_ANY 0x00
#define RSL_CHANNEED_SDCCH 0x01
#define RSL_CHANNEED_TCH_F 0x02
#define RSL_CHANNEED_TCH_ForH 0x03
/* Chapter 3.3.2.3 Brocast control channel */
/* CCCH-CONF, NC is not combined */
#define RSL_BCCH_CCCH_CONF_1_NC 0x00
#define RSL_BCCH_CCCH_CONF_1_C 0x01
#define RSL_BCCH_CCCH_CONF_2_NC 0x02
#define RSL_BCCH_CCCH_CONF_3_NC 0x04
#define RSL_BCCH_CCCH_CONF_4_NC 0x06
/* BS-PA-MFRMS */
#define RSL_BS_PA_MFRMS_2 0x00
#define RSL_BS_PA_MFRMS_3 0x01
#define RSL_BS_PA_MFRMS_4 0x02
#define RSL_BS_PA_MFRMS_5 0x03
#define RSL_BS_PA_MFRMS_6 0x04
#define RSL_BS_PA_MFRMS_7 0x05
#define RSL_BS_PA_MFRMS_8 0x06
#define RSL_BS_PA_MFRMS_9 0x07
/* RSL_IE_IPAC_RTP_PAYLOAD[2] */
enum rsl_ipac_rtp_payload {
RSL_IPAC_RTP_GSM = 1,
RSL_IPAC_RTP_EFR,
RSL_IPAC_RTP_AMR,
RSL_IPAC_RTP_CSD,
RSL_IPAC_RTP_MUX,
};
/* RSL_IE_IPAC_SPEECH_MODE, lower four bits */
enum rsl_ipac_speech_mode_s {
RSL_IPAC_SPEECH_GSM_FR = 0, /* GSM FR (Type 1, FS) */
RSL_IPAC_SPEECH_GSM_EFR = 1, /* GSM EFR (Type 2, FS) */
RSL_IPAC_SPEECH_GSM_AMR_FR = 2, /* GSM AMR/FR (Type 3, FS) */
RSL_IPAC_SPEECH_GSM_HR = 3, /* GSM HR (Type 1, HS) */
RSL_IPAC_SPEECH_GSM_AMR_HR = 5, /* GSM AMR/hr (Type 3, HS) */
RSL_IPAC_SPEECH_AS_RTP = 0xf, /* As specified by RTP Payload IE */
};
/* RSL_IE_IPAC_SPEECH_MODE, upper four bits */
enum rsl_ipac_speech_mode_m {
RSL_IPAC_SPEECH_M_RXTX = 0, /* Send and Receive */
RSL_IPAC_SPEECH_M_RX = 1, /* Receive only */
RSL_IPAC_SPEECH_M_TX = 2, /* Send only */
};
/* RSL_IE_IPAC_RTP_CSD_FMT, lower four bits */
enum rsl_ipac_rtp_csd_format_d {
RSL_IPAC_RTP_CSD_EXT_TRAU = 0,
RSL_IPAC_RTP_CSD_NON_TRAU = 1,
RSL_IPAC_RTP_CSD_TRAU_BTS = 2,
RSL_IPAC_RTP_CSD_IWF_FREE = 3,
};
/* RSL_IE_IPAC_RTP_CSD_FMT, upper four bits */
enum rsl_ipac_rtp_csd_format_ir {
RSL_IPAC_RTP_CSD_IR_8k = 0,
RSL_IPAC_RTP_CSD_IR_16k = 1,
RSL_IPAC_RTP_CSD_IR_32k = 2,
RSL_IPAC_RTP_CSD_IR_64k = 3,
};
#include "msgb.h"
int rsl_bcch_info(struct gsm_bts_trx *trx, u_int8_t type,
const u_int8_t *data, int len);
@@ -52,6 +511,27 @@ int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id);
int rsl_relase_request(struct gsm_lchan *lchan, u_int8_t link_id);
/* Siemens vendor-specific RSL extensions */
struct rsl_mrpci {
u_int8_t power_class:3,
vgcs_capable:1,
vbs_capable:1,
gsm_phase:2;
} __attribute__ ((packed));
enum rsl_mrpci_pwrclass {
RSL_MRPCI_PWRC_1 = 0,
RSL_MRPCI_PWRC_2 = 1,
RSL_MRPCI_PWRC_3 = 2,
RSL_MRPCI_PWRC_4 = 3,
RSL_MRPCI_PWRC_5 = 4,
};
enum rsl_mrpci_phase {
RSL_MRPCI_PHASE_1 = 0,
/* reserved */
RSL_MRPCI_PHASE_2 = 2,
RSL_MRPCI_PHASE_2PLUS = 3,
};
int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci);
/* ip.access specfic RSL extensions */

View File

@@ -36,14 +36,14 @@ enum bit_value {
struct bitvec {
unsigned int cur_bit; /* curser to the next unused bit */
unsigned int data_len; /* length of data array in bytes */
uint8_t *data; /* pointer to data array */
u_int8_t *data; /* pointer to data array */
};
/* check if the bit is 0 or 1 for a given position inside a bitvec */
enum bit_value bitvec_get_bit_pos(const struct bitvec *bv, unsigned int bitnr);
enum bit_value bitvec_get_bit_pos(struct bitvec *bv, unsigned int bitnr);
/* get the Nth set bit inside the bit vector */
unsigned int bitvec_get_nth_set_bit(const struct bitvec *bv, unsigned int n);
unsigned int bitvec_get_nth_set_bit(struct bitvec *bv, unsigned int n);
/* Set a bit at given position */
int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnum,

View File

@@ -1,8 +1,7 @@
/* Generic write queue implementation */
/* Routines to talk to the MSC using the IPA Protocol */
/*
* (C) 2010 by Holger Hans Peter Freyther
* (C) 2010 by On-Waves
*
* (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2010 by on-waves.com
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -20,25 +19,12 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#ifndef write_queue_h
#define write_queue_h
#ifndef BSC_MSC_H
#define BSC_MSC_H
#include "select.h"
#include "msgb.h"
struct write_queue {
struct bsc_fd bfd;
unsigned int max_length;
unsigned int current_length;
struct llist_head msg_queue;
int (*read_cb)(struct bsc_fd *fd);
int (*write_cb)(struct bsc_fd *fd, struct msgb *msg);
};
void write_queue_init(struct write_queue *queue, int max_length);
int write_queue_enqueue(struct write_queue *queue, struct msgb *data);
int write_queue_bfd_cb(struct bsc_fd *fd, unsigned int what);
int connect_to_msc(struct bsc_fd *fd, const char *ip, int port);
#endif

View File

@@ -1,7 +1,6 @@
/* Generic BTS - VTY code tries to allocate this BTS before type is known */
/* (C) 2010 by Daniel Willmann <daniel@totalueberwachung.de>
*
/*
* (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2010 by on-waves.com
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -20,21 +19,15 @@
*
*/
#ifndef BSC_NAT_H
#define BSC_NAT_H
#include <sys/types.h>
#include "msgb.h"
#include <openbsc/gsm_data.h>
#include <osmocore/tlv.h>
#include <openbsc/abis_nm.h>
/**
* filter based on IP Access header in both directions
*/
int bsc_nat_filter_ipa(struct msgb *msg);
static struct gsm_bts_model model_unknown = {
.type = GSM_BTS_TYPE_UNKNOWN,
.nm_att_tlvdef = {
.def = {
},
},
};
int bts_model_unknown_init(void)
{
return gsm_bts_model_register(&model_unknown);
}
#endif

View File

@@ -0,0 +1,334 @@
/* From GSM08.08 */
#ifndef BSSAP_H
#define BSSAP_H
#include <stdlib.h>
#include <openbsc/msgb.h>
#include <openbsc/gsm_data.h>
/*
* this is from GSM 03.03 CGI but is copied in GSM 08.08
* in § 3.2.2.27 for Cell Identifier List
*/
enum CELL_IDENT {
CELL_IDENT_WHOLE_GLOBAL = 0,
CELL_IDENT_LAC_AND_CI = 1,
CELL_IDENT_CI = 2,
CELL_IDENT_NO_CELL = 3,
CELL_IDENT_LAI_AND_LAC = 4,
CELL_IDENT_LAC = 5,
CELL_IDENT_BSS = 6,
CELL_IDENT_UTRAN_PLMN_LAC_RNC = 8,
CELL_IDENT_UTRAN_RNC = 9,
CELL_IDENT_UTRAN_LAC_RNC = 10,
};
/* GSM 08.06 § 6.3 */
enum BSSAP_MSG_TYPE {
BSSAP_MSG_BSS_MANAGEMENT = 0x0,
BSSAP_MSG_DTAP = 0x1,
};
struct bssmap_header {
u_int8_t type;
u_int8_t length;
} __attribute__((packed));
struct dtap_header {
u_int8_t type;
u_int8_t link_id;
u_int8_t length;
} __attribute__((packed));
enum BSS_MAP_MSG_TYPE {
BSS_MAP_MSG_RESERVED_0 = 0,
/* ASSIGNMENT MESSAGES */
BSS_MAP_MSG_ASSIGMENT_RQST = 1,
BSS_MAP_MSG_ASSIGMENT_COMPLETE = 2,
BSS_MAP_MSG_ASSIGMENT_FAILURE = 3,
/* HANDOVER MESSAGES */
BSS_MAP_MSG_HANDOVER_RQST = 16,
BSS_MAP_MSG_HANDOVER_REQUIRED = 17,
BSS_MAP_MSG_HANDOVER_RQST_ACKNOWLEDGE= 18,
BSS_MAP_MSG_HANDOVER_CMD = 19,
BSS_MAP_MSG_HANDOVER_COMPLETE = 20,
BSS_MAP_MSG_HANDOVER_SUCCEEDED = 21,
BSS_MAP_MSG_HANDOVER_FAILURE = 22,
BSS_MAP_MSG_HANDOVER_PERFORMED = 23,
BSS_MAP_MSG_HANDOVER_CANDIDATE_ENQUIRE = 24,
BSS_MAP_MSG_HANDOVER_CANDIDATE_RESPONSE = 25,
BSS_MAP_MSG_HANDOVER_REQUIRED_REJECT = 26,
BSS_MAP_MSG_HANDOVER_DETECT = 27,
/* RELEASE MESSAGES */
BSS_MAP_MSG_CLEAR_CMD = 32,
BSS_MAP_MSG_CLEAR_COMPLETE = 33,
BSS_MAP_MSG_CLEAR_RQST = 34,
BSS_MAP_MSG_RESERVED_1 = 35,
BSS_MAP_MSG_RESERVED_2 = 36,
BSS_MAP_MSG_SAPI_N_REJECT = 37,
BSS_MAP_MSG_CONFUSION = 38,
/* OTHER CONNECTION RELATED MESSAGES */
BSS_MAP_MSG_SUSPEND = 40,
BSS_MAP_MSG_RESUME = 41,
BSS_MAP_MSG_CONNECTION_ORIENTED_INFORMATION = 42,
BSS_MAP_MSG_PERFORM_LOCATION_RQST = 43,
BSS_MAP_MSG_LSA_INFORMATION = 44,
BSS_MAP_MSG_PERFORM_LOCATION_RESPONSE = 45,
BSS_MAP_MSG_PERFORM_LOCATION_ABORT = 46,
BSS_MAP_MSG_COMMON_ID = 47,
/* GENERAL MESSAGES */
BSS_MAP_MSG_RESET = 48,
BSS_MAP_MSG_RESET_ACKNOWLEDGE = 49,
BSS_MAP_MSG_OVERLOAD = 50,
BSS_MAP_MSG_RESERVED_3 = 51,
BSS_MAP_MSG_RESET_CIRCUIT = 52,
BSS_MAP_MSG_RESET_CIRCUIT_ACKNOWLEDGE = 53,
BSS_MAP_MSG_MSC_INVOKE_TRACE = 54,
BSS_MAP_MSG_BSS_INVOKE_TRACE = 55,
BSS_MAP_MSG_CONNECTIONLESS_INFORMATION = 58,
/* TERRESTRIAL RESOURCE MESSAGES */
BSS_MAP_MSG_BLOCK = 64,
BSS_MAP_MSG_BLOCKING_ACKNOWLEDGE = 65,
BSS_MAP_MSG_UNBLOCK = 66,
BSS_MAP_MSG_UNBLOCKING_ACKNOWLEDGE = 67,
BSS_MAP_MSG_CIRCUIT_GROUP_BLOCK = 68,
BSS_MAP_MSG_CIRCUIT_GROUP_BLOCKING_ACKNOWLEDGE = 69,
BSS_MAP_MSG_CIRCUIT_GROUP_UNBLOCK = 70,
BSS_MAP_MSG_CIRCUIT_GROUP_UNBLOCKING_ACKNOWLEDGE = 71,
BSS_MAP_MSG_UNEQUIPPED_CIRCUIT = 72,
BSS_MAP_MSG_CHANGE_CIRCUIT = 78,
BSS_MAP_MSG_CHANGE_CIRCUIT_ACKNOWLEDGE = 79,
/* RADIO RESOURCE MESSAGES */
BSS_MAP_MSG_RESOURCE_RQST = 80,
BSS_MAP_MSG_RESOURCE_INDICATION = 81,
BSS_MAP_MSG_PAGING = 82,
BSS_MAP_MSG_CIPHER_MODE_CMD = 83,
BSS_MAP_MSG_CLASSMARK_UPDATE = 84,
BSS_MAP_MSG_CIPHER_MODE_COMPLETE = 85,
BSS_MAP_MSG_QUEUING_INDICATION = 86,
BSS_MAP_MSG_COMPLETE_LAYER_3 = 87,
BSS_MAP_MSG_CLASSMARK_RQST = 88,
BSS_MAP_MSG_CIPHER_MODE_REJECT = 89,
BSS_MAP_MSG_LOAD_INDICATION = 90,
/* VGCS/VBS */
BSS_MAP_MSG_VGCS_VBS_SETUP = 4,
BSS_MAP_MSG_VGCS_VBS_SETUP_ACK = 5,
BSS_MAP_MSG_VGCS_VBS_SETUP_REFUSE = 6,
BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RQST = 7,
BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RESULT = 28,
BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_FAILURE = 29,
BSS_MAP_MSG_VGCS_VBS_QUEUING_INDICATION = 30,
BSS_MAP_MSG_UPLINK_RQST = 31,
BSS_MAP_MSG_UPLINK_RQST_ACKNOWLEDGE = 39,
BSS_MAP_MSG_UPLINK_RQST_CONFIRMATION = 73,
BSS_MAP_MSG_UPLINK_RELEASE_INDICATION = 74,
BSS_MAP_MSG_UPLINK_REJECT_CMD = 75,
BSS_MAP_MSG_UPLINK_RELEASE_CMD = 76,
BSS_MAP_MSG_UPLINK_SEIZED_CMD = 77,
};
enum GSM0808_IE_CODING {
GSM0808_IE_CIRCUIT_IDENTITY_CODE = 1,
GSM0808_IE_RESERVED_0 = 2,
GSM0808_IE_RESOURCE_AVAILABLE = 3,
GSM0808_IE_CAUSE = 4,
GSM0808_IE_CELL_IDENTIFIER = 5,
GSM0808_IE_PRIORITY = 6,
GSM0808_IE_LAYER_3_HEADER_INFORMATION = 7,
GSM0808_IE_IMSI = 8,
GSM0808_IE_TMSI = 9,
GSM0808_IE_ENCRYPTION_INFORMATION = 10,
GSM0808_IE_CHANNEL_TYPE = 11,
GSM0808_IE_PERIODICITY = 12,
GSM0808_IE_EXTENDED_RESOURCE_INDICATOR = 13,
GSM0808_IE_NUMBER_OF_MSS = 14,
GSM0808_IE_RESERVED_1 = 15,
GSM0808_IE_RESERVED_2 = 16,
GSM0808_IE_RESERVED_3 = 17,
GSM0808_IE_CLASSMARK_INFORMATION_T2 = 18,
GSM0808_IE_CLASSMARK_INFORMATION_T3 = 19,
GSM0808_IE_INTERFERENCE_BAND_TO_USE = 20,
GSM0808_IE_RR_CAUSE = 21,
GSM0808_IE_RESERVED_4 = 22,
GSM0808_IE_LAYER_3_INFORMATION = 23,
GSM0808_IE_DLCI = 24,
GSM0808_IE_DOWNLINK_DTX_FLAG = 25,
GSM0808_IE_CELL_IDENTIFIER_LIST = 26,
GSM0808_IE_RESPONSE_RQST = 27,
GSM0808_IE_RESOURCE_INDICATION_METHOD = 28,
GSM0808_IE_CLASSMARK_INFORMATION_TYPE_1 = 29,
GSM0808_IE_CIRCUIT_IDENTITY_CODE_LIST = 30,
GSM0808_IE_DIAGNOSTIC = 31,
GSM0808_IE_LAYER_3_MESSAGE_CONTENTS = 32,
GSM0808_IE_CHOSEN_CHANNEL = 33,
GSM0808_IE_TOTAL_RESOURCE_ACCESSIBLE = 34,
GSM0808_IE_CIPHER_RESPONSE_MODE = 35,
GSM0808_IE_CHANNEL_NEEDED = 36,
GSM0808_IE_TRACE_TYPE = 37,
GSM0808_IE_TRIGGERID = 38,
GSM0808_IE_TRACE_REFERENCE = 39,
GSM0808_IE_TRANSACTIONID = 40,
GSM0808_IE_MOBILE_IDENTITY = 41,
GSM0808_IE_OMCID = 42,
GSM0808_IE_FORWARD_INDICATOR = 43,
GSM0808_IE_CHOSEN_ENCR_ALG = 44,
GSM0808_IE_CIRCUIT_POOL = 45,
GSM0808_IE_CIRCUIT_POOL_LIST = 46,
GSM0808_IE_TIME_INDICATION = 47,
GSM0808_IE_RESOURCE_SITUATION = 48,
GSM0808_IE_CURRENT_CHANNEL_TYPE_1 = 49,
GSM0808_IE_QUEUEING_INDICATOR = 50,
GSM0808_IE_SPEECH_VERSION = 64,
GSM0808_IE_ASSIGNMENT_REQUIREMENT = 51,
GSM0808_IE_TALKER_FLAG = 53,
GSM0808_IE_CONNECTION_RELEASE_RQSTED = 54,
GSM0808_IE_GROUP_CALL_REFERENCE = 55,
GSM0808_IE_EMLPP_PRIORITY = 56,
GSM0808_IE_CONFIG_EVO_INDI = 57,
GSM0808_IE_OLD_BSS_TO_NEW_BSS_INFORMATION = 58,
GSM0808_IE_LSA_IDENTIFIER = 59,
GSM0808_IE_LSA_IDENTIFIER_LIST = 60,
GSM0808_IE_LSA_INFORMATION = 61,
GSM0808_IE_LCS_QOS = 62,
GSM0808_IE_LSA_ACCESS_CTRL_SUPPR = 63,
GSM0808_IE_LCS_PRIORITY = 67,
GSM0808_IE_LOCATION_TYPE = 68,
GSM0808_IE_LOCATION_ESTIMATE = 69,
GSM0808_IE_POSITIONING_DATA = 70,
GSM0808_IE_LCS_CAUSE = 71,
GSM0808_IE_LCS_CLIENT_TYPE = 72,
GSM0808_IE_APDU = 73,
GSM0808_IE_NETWORK_ELEMENT_IDENTITY = 74,
GSM0808_IE_GPS_ASSISTANCE_DATA = 75,
GSM0808_IE_DECIPHERING_KEYS = 76,
GSM0808_IE_RETURN_ERROR_RQST = 77,
GSM0808_IE_RETURN_ERROR_CAUSE = 78,
GSM0808_IE_SEGMENTATION = 79,
GSM0808_IE_SERVICE_HANDOVER = 80,
GSM0808_IE_SOURCE_RNC_TO_TARGET_RNC_TRANSPARENT_UMTS = 81,
GSM0808_IE_SOURCE_RNC_TO_TARGET_RNC_TRANSPARENT_CDMA2000= 82,
GSM0808_IE_RESERVED_5 = 65,
GSM0808_IE_RESERVED_6 = 66,
};
enum gsm0808_cause {
GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE = 0,
GSM0808_CAUSE_RADIO_INTERFACE_FAILURE = 1,
GSM0808_CAUSE_UPLINK_QUALITY = 2,
GSM0808_CAUSE_UPLINK_STRENGTH = 3,
GSM0808_CAUSE_DOWNLINK_QUALITY = 4,
GSM0808_CAUSE_DOWNLINK_STRENGTH = 5,
GSM0808_CAUSE_DISTANCE = 6,
GSM0808_CAUSE_O_AND_M_INTERVENTION = 7,
GSM0808_CAUSE_RESPONSE_TO_MSC_INVOCATION = 8,
GSM0808_CAUSE_CALL_CONTROL = 9,
GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION = 10,
GSM0808_CAUSE_HANDOVER_SUCCESSFUL = 11,
GSM0808_CAUSE_BETTER_CELL = 12,
GSM0808_CAUSE_DIRECTED_RETRY = 13,
GSM0808_CAUSE_JOINED_GROUP_CALL_CHANNEL = 14,
GSM0808_CAUSE_TRAFFIC = 15,
GSM0808_CAUSE_EQUIPMENT_FAILURE = 32,
GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE = 33,
GSM0808_CAUSE_RQSTED_TERRESTRIAL_RESOURCE_UNAVAILABLE = 34,
GSM0808_CAUSE_CCCH_OVERLOAD = 35,
GSM0808_CAUSE_PROCESSOR_OVERLOAD = 36,
GSM0808_CAUSE_BSS_NOT_EQUIPPED = 37,
GSM0808_CAUSE_MS_NOT_EQUIPPED = 38,
GSM0808_CAUSE_INVALID_CELL = 39,
GSM0808_CAUSE_TRAFFIC_LOAD = 40,
GSM0808_CAUSE_PREEMPTION = 41,
GSM0808_CAUSE_RQSTED_TRANSCODING_RATE_ADAPTION_UNAVAILABLE = 48,
GSM0808_CAUSE_CIRCUIT_POOL_MISMATCH = 49,
GSM0808_CAUSE_SWITCH_CIRCUIT_POOL = 50,
GSM0808_CAUSE_RQSTED_SPEECH_VERSION_UNAVAILABLE = 51,
GSM0808_CAUSE_LSA_NOT_ALLOWED = 52,
GSM0808_CAUSE_CIPHERING_ALGORITHM_NOT_SUPPORTED = 64,
GSM0808_CAUSE_TERRESTRIAL_CIRCUIT_ALREADY_ALLOCATED = 80,
GSM0808_CAUSE_INVALID_MESSAGE_CONTENTS = 81,
GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING = 82,
GSM0808_CAUSE_INCORRECT_VALUE = 83,
GSM0808_CAUSE_UNKNOWN_MESSAGE_TYPE = 84,
GSM0808_CAUSE_UNKNOWN_INFORMATION_ELEMENT = 85,
GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC = 96,
};
/* GSM 08.08 3.2.2.11 Channel Type */
enum gsm0808_chan_indicator {
GSM0808_CHAN_SPEECH = 1,
GSM0808_CHAN_DATA = 2,
GSM0808_CHAN_SIGN = 3,
};
enum gsm0808_chan_rate_type_data {
GSM0808_DATA_FULL_BM = 0x8,
GSM0808_DATA_HALF_LM = 0x9,
GSM0808_DATA_FULL_RPREF = 0xa,
GSM0808_DATA_HALF_PREF = 0xb,
GSM0808_DATA_FULL_PREF_NO_CHANGE = 0x1a,
GSM0808_DATA_HALF_PREF_NO_CHANGE = 0x1b,
GSM0808_DATA_MULTI_MASK = 0x20,
GSM0808_DATA_MULTI_MASK_NO_CHANGE = 0x30,
};
enum gsm0808_chan_rate_type_speech {
GSM0808_SPEECH_FULL_BM = 0x8,
GSM0808_SPEECH_HALF_LM = 0x9,
GSM0808_SPEECH_FULL_PREF= 0xa,
GSM0808_SPEECH_HALF_PREF= 0xb,
GSM0808_SPEECH_FULL_PREF_NO_CHANGE = 0x1a,
GSM0808_SPEECH_HALF_PREF_NO_CHANGE = 0x1b,
GSM0808_SPEECH_PERM = 0xf,
GSM0808_SPEECH_PERM_NO_CHANGE = 0x1f,
};
enum gsm0808_permitted_speech {
GSM0808_PERM_FR1 = 0x01,
GSM0808_PERM_FR2 = 0x11,
GSM0808_PERM_FR3 = 0x21,
GSM0808_PERM_HR1 = GSM0808_PERM_FR1 | 0x4,
GSM0808_PERM_HR2 = GSM0808_PERM_FR2 | 0x4,
GSM0808_PERM_HR3 = GSM0808_PERM_FR3 | 0x4,
};
int bssmap_rcvmsg_dt1(struct sccp_connection *conn, struct msgb *msg, unsigned int length);
int bssmap_rcvmsg_udt(struct gsm_network *net, struct msgb *msg, unsigned int length);
struct msgb *bssmap_create_layer3(struct msgb *msg);
struct msgb *bssmap_create_reset(void);
struct msgb *bssmap_create_clear_complete(void);
struct msgb *bssmap_create_cipher_complete(struct msgb *layer3);
struct msgb *bssmap_create_cipher_reject(u_int8_t cause);
struct msgb *bssmap_create_sapi_reject(u_int8_t link_id);
struct msgb *bssmap_create_assignment_completed(struct gsm_lchan *lchan, u_int8_t rr_cause);
struct msgb *bssmap_create_assignment_failure(u_int8_t cause, u_int8_t *rr_cause);
struct msgb *bssmap_create_classmark_update(const u_int8_t *classmark, u_int8_t length);
void gsm0808_send_assignment_failure(struct gsm_lchan *l, u_int8_t cause, u_int8_t *rr_value);
void gsm0808_send_assignment_compl(struct gsm_lchan *l, u_int8_t rr_value);
int dtap_rcvmsg(struct gsm_lchan *lchan, struct msgb *msg, unsigned int length);
struct msgb *dtap_create_msg(struct msgb *msg_l3, u_int8_t link_id);
void bsc_queue_connection_write(struct sccp_connection *conn, struct msgb *msg);
void bsc_free_queued(struct sccp_connection *conn);
void bsc_send_queued(struct sccp_connection *conn);
void bts_queue_send(struct msgb *msg, int link_id);
void bts_send_queued(struct bss_sccp_connection_data*);
void bts_free_queued(struct bss_sccp_connection_data*);
void bts_unblock_queue(struct bss_sccp_connection_data*);
#endif

View File

@@ -23,6 +23,28 @@
#include "gsm_subscriber.h"
/*
* Refcounting for the lchan. If the refcount drops to zero
* the channel will send a RSL release request.
*/
#define use_lchan(lchan) \
do { lchan->use_count++; \
DEBUGP(DCC, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) increases usage to: %d\n", \
lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \
lchan->nr, lchan->use_count); \
} while(0);
#define put_lchan(lchan) \
do { lchan->use_count--; \
DEBUGP(DCC, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) decreases usage to: %d\n", \
lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \
lchan->nr, lchan->use_count); \
if (lchan->use_count <= 0) \
_lchan_release(lchan); \
} while(0);
/* Special allocator for C0 of BTS */
struct gsm_bts_trx_ts *ts_c0_alloc(struct gsm_bts *bts,
enum gsm_phys_chan_config pchan);
@@ -46,21 +68,7 @@ struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type);
/* Free a logical channel (SDCCH, TCH, ...) */
void lchan_free(struct gsm_lchan *lchan);
/* Consider releasing the channel */
int lchan_auto_release(struct gsm_lchan *lchan);
struct load_counter {
unsigned int total;
unsigned int used;
};
struct pchan_load {
struct load_counter pchan[GSM_PCHAN_UNKNOWN];
};
void bts_chan_load(struct pchan_load *cl, const struct gsm_bts *bts);
void network_chan_load(struct pchan_load *pl, struct gsm_network *net);
int trx_is_usable(struct gsm_bts_trx *trx);
/* internal.. do not use */
int _lchan_release(struct gsm_lchan *lchan);
#endif /* _CHAN_ALLOC_H */

View File

@@ -43,20 +43,9 @@ int db_subscriber_alloc_token(struct gsm_subscriber* subscriber, u_int32_t* toke
int db_subscriber_assoc_imei(struct gsm_subscriber* subscriber, char *imei);
int db_sync_equipment(struct gsm_equipment *equip);
/* auth info */
int get_authinfo_by_subscr(struct gsm_auth_info *ainfo,
struct gsm_subscriber *subscr);
int set_authinfo_for_subscr(struct gsm_auth_info *ainfo,
struct gsm_subscriber *subscr);
int get_authtuple_by_subscr(struct gsm_auth_tuple *atuple,
struct gsm_subscriber *subscr);
int set_authtuple_for_subscr(struct gsm_auth_tuple *atuple,
struct gsm_subscriber *subscr);
/* SMS store-and-forward */
int db_sms_store(struct gsm_sms *sms);
struct gsm_sms *db_sms_get_unsent(struct gsm_network *net, int min_id);
struct gsm_sms *db_sms_get_unsent_by_subscr(struct gsm_network *net, int min_subscr_id);
struct gsm_sms *db_sms_get_unsent_for_subscr(struct gsm_subscriber *subscr);
int db_sms_mark_sent(struct gsm_sms *sms);
@@ -64,8 +53,4 @@ int db_sms_mark_sent(struct gsm_sms *sms);
int db_apdu_blob_store(struct gsm_subscriber *subscr,
u_int8_t apdu_id_flags, u_int8_t len,
u_int8_t *apdu);
/* Statistics counter storage */
int db_store_counter(struct counter *ctr);
#endif /* _DB_H */

View File

@@ -1,53 +1,52 @@
#ifndef _DEBUG_H
#define _DEBUG_H
#include <stdio.h>
#include <osmocore/linuxlist.h>
#define DEBUG
/* Debug Areas of the code */
enum {
DRLL,
DCC,
DMM,
DRR,
DRSL,
DNM,
DMNCC,
DSMS,
DPAG,
DMEAS,
DMI,
DMIB,
DMUX,
DINP,
DSCCP,
DMSC,
DMGCP,
DHO,
DDB,
DREF,
Debug_LastEntry,
};
#define DRLL 0x0001
#define DCC 0x0002
#define DMM 0x0004
#define DRR 0x0008
#define DRSL 0x0010
#define DNM 0x0020
#define DMNCC 0x0080
#define DSMS 0x0100
#define DPAG 0x0200
#define DMEAS 0x0400
#define DMI 0x1000
#define DMIB 0x2000
#define DMUX 0x4000
#define DINP 0x8000
#define DSCCP 0x10000
#define DMSC 0x20000
#define DMGCP 0x40000
#define DHO 0x80000
#ifdef DEBUG
#define DEBUGP(ss, fmt, args...) debugp(ss, __FILE__, __LINE__, 0, fmt, ## args)
#define DEBUGPC(ss, fmt, args...) debugp(ss, __FILE__, __LINE__, 1, fmt, ## args)
#else
#define DEBUGP(xss, fmt, args...)
#define DEBUGP(xss, fmt, args...)
#define DEBUGPC(ss, fmt, args...)
#endif
#define static_assert(exp, name) typedef int dummy##name [(exp) ? 1 : -1];
char *hexdump(const unsigned char *buf, int len);
void debugp(unsigned int subsys, char *file, int line, int cont, const char *format, ...) __attribute__ ((format (printf, 5, 6)));
void debug_parse_category_mask(const char* mask);
void debug_use_color(int use_color);
void debug_timestamp(int enable);
extern unsigned int debug_mask;
/* new logging interface */
#define LOGP(ss, level, fmt, args...) debugp2(ss, level, __FILE__, __LINE__, 0, fmt, ##args)
#define LOGPC(ss, level, fmt, args...) debugp2(ss, level, __FILE__, __LINE__, 1, fmt, ##args)
#define LOGP(ss, level, fmt, args...) debugp(ss, __FILE__, __LINE__, 0, fmt, ##args)
#define LOGPC(ss, level, fmt, args...) debugp(ss, __FILE__, __LINE__, 1, fmt, ##args)
/* different levels */
#define LOGL_DEBUG 1 /* debugging information */
@@ -56,76 +55,4 @@ void debugp(unsigned int subsys, char *file, int line, int cont, const char *for
#define LOGL_ERROR 7 /* error condition, requires user action */
#define LOGL_FATAL 8 /* fatal, program aborted */
/* context */
#define BSC_CTX_LCHAN 0
#define BSC_CTX_SUBSCR 1
#define BSC_CTX_BTS 2
#define BSC_CTX_SCCP 3
/* target */
enum {
DEBUG_FILTER_IMSI = 1 << 0,
DEBUG_FILTER_ALL = 1 << 1,
};
struct debug_category {
int enabled;
int loglevel;
};
struct debug_target {
int filter_map;
char *imsi_filter;
struct debug_category categories[Debug_LastEntry];
int use_color;
int print_timestamp;
int loglevel;
union {
struct {
FILE *out;
} tgt_stdout;
struct {
int priority;
} tgt_syslog;
struct {
void *vty;
} tgt_vty;
};
void (*output) (struct debug_target *target, const char *string);
struct llist_head entry;
};
/* use the above macros */
void debugp2(unsigned int subsys, unsigned int level, char *file, int line, int cont, const char *format, ...) __attribute__ ((format (printf, 6, 7)));
void debug_init(void);
/* context management */
void debug_reset_context(void);
void debug_set_context(int ctx, void *value);
/* filter on the targets */
void debug_set_imsi_filter(struct debug_target *target, const char *imsi);
void debug_set_all_filter(struct debug_target *target, int);
void debug_set_use_color(struct debug_target *target, int);
void debug_set_print_timestamp(struct debug_target *target, int);
void debug_set_log_level(struct debug_target *target, int log_level);
void debug_parse_category_mask(struct debug_target *target, const char* mask);
int debug_parse_level(const char *lvl);
int debug_parse_category(const char *category);
void debug_set_category_filter(struct debug_target *target, int category, int enable, int level);
/* management of the targets */
struct debug_target *debug_target_create(void);
struct debug_target *debug_target_create_stderr(void);
void debug_add_target(struct debug_target *target);
void debug_del_target(struct debug_target *target);
#endif /* _DEBUG_H */

View File

@@ -4,10 +4,10 @@
#include <stdlib.h>
#include <netinet/in.h>
#include <osmocore/linuxlist.h>
#include <openbsc/linuxlist.h>
#include <openbsc/gsm_data.h>
#include <osmocore/msgb.h>
#include <osmocore/select.h>
#include <openbsc/msgb.h>
#include <openbsc/select.h>
#include <openbsc/subchan_demux.h>
#define NUM_E1_TS 32

View File

@@ -3,8 +3,742 @@
#include <openbsc/meas_rep.h>
#include <osmocore/protocol/gsm_04_08.h>
#include <osmocore/gsm48.h>
/* GSM TS 04.08 definitions */
struct gsm_lchan;
struct gsm48_classmark1 {
u_int8_t spare:1,
rev_level:2,
es_ind:1,
a5_1:1,
pwr_lev:3;
} __attribute__ ((packed));
/* Chapter 10.5.2.5 */
struct gsm48_chan_desc {
u_int8_t chan_nr;
union {
struct {
u_int8_t maio_high:4,
h:1,
tsc:3;
u_int8_t hsn:6,
maio_low:2;
} h1;
struct {
u_int8_t arfcn_high:2,
spare:2,
h:1,
tsc:3;
u_int8_t arfcn_low;
} h0;
};
} __attribute__ ((packed));
/* Chapter 10.5.2.21aa */
struct gsm48_multi_rate_conf {
u_int8_t smod : 2,
spare: 1,
icmi : 1,
nscb : 1,
ver : 3;
u_int8_t m4_75 : 1,
m5_15 : 1,
m5_90 : 1,
m6_70 : 1,
m7_40 : 1,
m7_95 : 1,
m10_2 : 1,
m12_2 : 1;
} __attribute__((packed));
/* Chapter 10.5.2.30 */
struct gsm48_req_ref {
u_int8_t ra;
u_int8_t t3_high:3,
t1_:5;
u_int8_t t2:5,
t3_low:3;
} __attribute__ ((packed));
/*
* Chapter 9.1.5/9.1.6
*
* For 9.1.6 the chan_desc has the meaning of 10.5.2.5a
*/
struct gsm48_chan_mode_modify {
struct gsm48_chan_desc chan_desc;
u_int8_t mode;
} __attribute__ ((packed));
enum gsm48_chan_mode {
GSM48_CMODE_SIGN = 0x00,
GSM48_CMODE_SPEECH_V1 = 0x01,
GSM48_CMODE_SPEECH_EFR = 0x21,
GSM48_CMODE_SPEECH_AMR = 0x41,
GSM48_CMODE_DATA_14k5 = 0x0f,
GSM48_CMODE_DATA_12k0 = 0x03,
GSM48_CMODE_DATA_6k0 = 0x0b,
GSM48_CMODE_DATA_3k6 = 0x23,
};
/* Chapter 9.1.2 */
struct gsm48_ass_cmd {
/* Semantic is from 10.5.2.5a */
struct gsm48_chan_desc chan_desc;
u_int8_t power_command;
u_int8_t data[0];
} __attribute__((packed));
/* Chapter 10.5.2.2 */
struct gsm48_cell_desc {
u_int8_t bcc:3,
ncc:3,
arfcn_hi:2;
u_int8_t arfcn_lo;
} __attribute__((packed));
/* Chapter 9.1.15 */
struct gsm48_ho_cmd {
struct gsm48_cell_desc cell_desc;
struct gsm48_chan_desc chan_desc;
u_int8_t ho_ref;
u_int8_t power_command;
u_int8_t data[0];
} __attribute__((packed));
/* Chapter 9.1.18 */
struct gsm48_imm_ass {
u_int8_t l2_plen;
u_int8_t proto_discr;
u_int8_t msg_type;
u_int8_t page_mode;
struct gsm48_chan_desc chan_desc;
struct gsm48_req_ref req_ref;
u_int8_t timing_advance;
u_int8_t mob_alloc_len;
u_int8_t mob_alloc[0];
} __attribute__ ((packed));
/* Chapter 10.5.1.3 */
struct gsm48_loc_area_id {
u_int8_t digits[3]; /* BCD! */
u_int16_t lac;
} __attribute__ ((packed));
/* Section 9.2.2 */
struct gsm48_auth_req {
u_int8_t key_seq:4,
spare:4;
u_int8_t rand[16];
} __attribute__ ((packed));
/* Section 9.2.15 */
struct gsm48_loc_upd_req {
u_int8_t type:4,
key_seq:4;
struct gsm48_loc_area_id lai;
struct gsm48_classmark1 classmark1;
u_int8_t mi_len;
u_int8_t mi[0];
} __attribute__ ((packed));
/* Section 10.1 */
struct gsm48_hdr {
u_int8_t proto_discr;
u_int8_t msg_type;
u_int8_t data[0];
} __attribute__ ((packed));
/* Section 9.1.3x System information Type header */
struct gsm48_system_information_type_header {
u_int8_t l2_plen;
u_int8_t rr_protocol_discriminator :4,
skip_indicator:4;
u_int8_t system_information;
} __attribute__ ((packed));
struct gsm48_rach_control {
u_int8_t re :1,
cell_bar :1,
tx_integer :4,
max_trans :2;
u_int8_t t2;
u_int8_t t3;
} __attribute__ ((packed));
/* Section 10.5.2.4 Cell Selection Parameters */
struct gsm48_cell_sel_par {
u_int8_t ms_txpwr_max_ccch:5, /* GSM 05.08 MS-TXPWR-MAX-CCCH */
cell_resel_hyst:3; /* GSM 05.08 CELL-RESELECT-HYSTERESIS */
u_int8_t rxlev_acc_min:6, /* GSM 05.08 RXLEV-ACCESS-MIN */
neci:1,
acs:1;
} __attribute__ ((packed));
/* Section 10.5.2.11 Control Channel Description , Figure 10.5.33 */
struct gsm48_control_channel_descr {
u_int8_t ccch_conf :3,
bs_ag_blks_res :3,
att :1,
spare1 :1;
u_int8_t bs_pa_mfrms : 3,
spare2 :5;
u_int8_t t3212;
} __attribute__ ((packed));
struct gsm48_cell_options {
u_int8_t radio_link_timeout:4,
dtx:2,
pwrc:1,
spare:1;
} __attribute__ ((packed));
/* Section 9.2.9 CM service request */
struct gsm48_service_request {
u_int8_t cm_service_type : 4,
cipher_key_seq : 4;
/* length + 3 bytes */
u_int32_t classmark;
u_int8_t mi_len;
u_int8_t mi[0];
/* optional priority level */
} __attribute__ ((packed));
/* Section 9.1.31 System information Type 1 */
struct gsm48_system_information_type_1 {
struct gsm48_system_information_type_header header;
u_int8_t cell_channel_description[16];
struct gsm48_rach_control rach_control;
u_int8_t rest_octets[0]; /* NCH position on the CCCH */
} __attribute__ ((packed));
/* Section 9.1.32 System information Type 2 */
struct gsm48_system_information_type_2 {
struct gsm48_system_information_type_header header;
u_int8_t bcch_frequency_list[16];
u_int8_t ncc_permitted;
struct gsm48_rach_control rach_control;
} __attribute__ ((packed));
/* Section 9.1.35 System information Type 3 */
struct gsm48_system_information_type_3 {
struct gsm48_system_information_type_header header;
u_int16_t cell_identity;
struct gsm48_loc_area_id lai;
struct gsm48_control_channel_descr control_channel_desc;
struct gsm48_cell_options cell_options;
struct gsm48_cell_sel_par cell_sel_par;
struct gsm48_rach_control rach_control;
u_int8_t rest_octets[0];
} __attribute__ ((packed));
/* Section 9.1.36 System information Type 4 */
struct gsm48_system_information_type_4 {
struct gsm48_system_information_type_header header;
struct gsm48_loc_area_id lai;
struct gsm48_cell_sel_par cell_sel_par;
struct gsm48_rach_control rach_control;
/* optional CBCH conditional CBCH... followed by
mandantory SI 4 Reset Octets
*/
u_int8_t data[0];
} __attribute__ ((packed));
/* Section 9.1.37 System information Type 5 */
struct gsm48_system_information_type_5 {
u_int8_t rr_protocol_discriminator :4,
skip_indicator:4;
u_int8_t system_information;
u_int8_t bcch_frequency_list[16];
} __attribute__ ((packed));
/* Section 9.1.40 System information Type 6 */
struct gsm48_system_information_type_6 {
u_int8_t rr_protocol_discriminator :4,
skip_indicator:4;
u_int8_t system_information;
u_int16_t cell_identity;
struct gsm48_loc_area_id lai;
struct gsm48_cell_options cell_options;
u_int8_t ncc_permitted;
u_int8_t rest_octets[0];
} __attribute__ ((packed));
/* Section 9.1.43a System Information type 13 */
struct gsm48_system_information_type_13 {
struct gsm48_system_information_type_header header;
u_int8_t rest_octets[0];
} __attribute__ ((packed));
/* Section 9.2.12 IMSI Detach Indication */
struct gsm48_imsi_detach_ind {
struct gsm48_classmark1 classmark1;
u_int8_t mi_len;
u_int8_t mi[0];
} __attribute__ ((packed));
/* Section 10.2 + GSM 04.07 12.2.3.1.1 */
#define GSM48_PDISC_GROUP_CC 0x00
#define GSM48_PDISC_BCAST_CC 0x01
#define GSM48_PDISC_PDSS1 0x02
#define GSM48_PDISC_CC 0x03
#define GSM48_PDISC_PDSS2 0x04
#define GSM48_PDISC_MM 0x05
#define GSM48_PDISC_RR 0x06
#define GSM48_PDISC_MM_GPRS 0x08
#define GSM48_PDISC_SMS 0x09
#define GSM48_PDISC_SM_GPRS 0x0a
#define GSM48_PDISC_NC_SS 0x0b
#define GSM48_PDISC_LOC 0x0c
#define GSM48_PDISC_MASK 0x0f
#define GSM48_PDISC_USSD 0x11
/* Section 10.4 */
#define GSM48_MT_RR_INIT_REQ 0x3c
#define GSM48_MT_RR_ADD_ASS 0x3b
#define GSM48_MT_RR_IMM_ASS 0x3f
#define GSM48_MT_RR_IMM_ASS_EXT 0x39
#define GSM48_MT_RR_IMM_ASS_REJ 0x3a
#define GSM48_MT_RR_CIPH_M_CMD 0x35
#define GSM48_MT_RR_CIPH_M_COMPL 0x32
#define GSM48_MT_RR_CFG_CHG_CMD 0x30
#define GSM48_MT_RR_CFG_CHG_ACK 0x31
#define GSM48_MT_RR_CFG_CHG_REJ 0x33
#define GSM48_MT_RR_ASS_CMD 0x2e
#define GSM48_MT_RR_ASS_COMPL 0x29
#define GSM48_MT_RR_ASS_FAIL 0x2f
#define GSM48_MT_RR_HANDO_CMD 0x2b
#define GSM48_MT_RR_HANDO_COMPL 0x2c
#define GSM48_MT_RR_HANDO_FAIL 0x28
#define GSM48_MT_RR_HANDO_INFO 0x2d
#define GSM48_MT_RR_CELL_CHG_ORDER 0x08
#define GSM48_MT_RR_PDCH_ASS_CMD 0x23
#define GSM48_MT_RR_CHAN_REL 0x0d
#define GSM48_MT_RR_PART_REL 0x0a
#define GSM48_MT_RR_PART_REL_COMP 0x0f
#define GSM48_MT_RR_PAG_REQ_1 0x21
#define GSM48_MT_RR_PAG_REQ_2 0x22
#define GSM48_MT_RR_PAG_REQ_3 0x24
#define GSM48_MT_RR_PAG_RESP 0x27
#define GSM48_MT_RR_NOTIF_NCH 0x20
#define GSM48_MT_RR_NOTIF_FACCH 0x25
#define GSM48_MT_RR_NOTIF_RESP 0x26
#define GSM48_MT_RR_SYSINFO_8 0x18
#define GSM48_MT_RR_SYSINFO_1 0x19
#define GSM48_MT_RR_SYSINFO_2 0x1a
#define GSM48_MT_RR_SYSINFO_3 0x1b
#define GSM48_MT_RR_SYSINFO_4 0x1c
#define GSM48_MT_RR_SYSINFO_5 0x1d
#define GSM48_MT_RR_SYSINFO_6 0x1e
#define GSM48_MT_RR_SYSINFO_7 0x1f
#define GSM48_MT_RR_SYSINFO_2bis 0x02
#define GSM48_MT_RR_SYSINFO_2ter 0x03
#define GSM48_MT_RR_SYSINFO_5bis 0x05
#define GSM48_MT_RR_SYSINFO_5ter 0x06
#define GSM48_MT_RR_SYSINFO_9 0x04
#define GSM48_MT_RR_SYSINFO_13 0x00
#define GSM48_MT_RR_SYSINFO_16 0x3d
#define GSM48_MT_RR_SYSINFO_17 0x3e
#define GSM48_MT_RR_CHAN_MODE_MODIF 0x10
#define GSM48_MT_RR_STATUS 0x12
#define GSM48_MT_RR_CHAN_MODE_MODIF_ACK 0x17
#define GSM48_MT_RR_FREQ_REDEF 0x14
#define GSM48_MT_RR_MEAS_REP 0x15
#define GSM48_MT_RR_CLSM_CHG 0x16
#define GSM48_MT_RR_CLSM_ENQ 0x13
#define GSM48_MT_RR_EXT_MEAS_REP 0x36
#define GSM48_MT_RR_EXT_MEAS_REP_ORD 0x37
#define GSM48_MT_RR_GPRS_SUSP_REQ 0x34
#define GSM48_MT_RR_VGCS_UPL_GRANT 0x08
#define GSM48_MT_RR_UPLINK_RELEASE 0x0e
#define GSM48_MT_RR_UPLINK_FREE 0x0c
#define GSM48_MT_RR_UPLINK_BUSY 0x2a
#define GSM48_MT_RR_TALKER_IND 0x11
#define GSM48_MT_RR_APP_INFO 0x38
/* Table 10.2/3GPP TS 04.08 */
#define GSM48_MT_MM_IMSI_DETACH_IND 0x01
#define GSM48_MT_MM_LOC_UPD_ACCEPT 0x02
#define GSM48_MT_MM_LOC_UPD_REJECT 0x04
#define GSM48_MT_MM_LOC_UPD_REQUEST 0x08
#define GSM48_MT_MM_AUTH_REJ 0x11
#define GSM48_MT_MM_AUTH_REQ 0x12
#define GSM48_MT_MM_AUTH_RESP 0x14
#define GSM48_MT_MM_ID_REQ 0x18
#define GSM48_MT_MM_ID_RESP 0x19
#define GSM48_MT_MM_TMSI_REALL_CMD 0x1a
#define GSM48_MT_MM_TMSI_REALL_COMPL 0x1b
#define GSM48_MT_MM_CM_SERV_ACC 0x21
#define GSM48_MT_MM_CM_SERV_REJ 0x22
#define GSM48_MT_MM_CM_SERV_ABORT 0x23
#define GSM48_MT_MM_CM_SERV_REQ 0x24
#define GSM48_MT_MM_CM_SERV_PROMPT 0x25
#define GSM48_MT_MM_CM_REEST_REQ 0x28
#define GSM48_MT_MM_ABORT 0x29
#define GSM48_MT_MM_NULL 0x30
#define GSM48_MT_MM_STATUS 0x31
#define GSM48_MT_MM_INFO 0x32
/* Table 10.3/3GPP TS 04.08 */
#define GSM48_MT_CC_ALERTING 0x01
#define GSM48_MT_CC_CALL_CONF 0x08
#define GSM48_MT_CC_CALL_PROC 0x02
#define GSM48_MT_CC_CONNECT 0x07
#define GSM48_MT_CC_CONNECT_ACK 0x0f
#define GSM48_MT_CC_EMERG_SETUP 0x0e
#define GSM48_MT_CC_PROGRESS 0x03
#define GSM48_MT_CC_ESTAB 0x04
#define GSM48_MT_CC_ESTAB_CONF 0x06
#define GSM48_MT_CC_RECALL 0x0b
#define GSM48_MT_CC_START_CC 0x09
#define GSM48_MT_CC_SETUP 0x05
#define GSM48_MT_CC_MODIFY 0x17
#define GSM48_MT_CC_MODIFY_COMPL 0x1f
#define GSM48_MT_CC_MODIFY_REJECT 0x13
#define GSM48_MT_CC_USER_INFO 0x10
#define GSM48_MT_CC_HOLD 0x18
#define GSM48_MT_CC_HOLD_ACK 0x19
#define GSM48_MT_CC_HOLD_REJ 0x1a
#define GSM48_MT_CC_RETR 0x1c
#define GSM48_MT_CC_RETR_ACK 0x1d
#define GSM48_MT_CC_RETR_REJ 0x1e
#define GSM48_MT_CC_DISCONNECT 0x25
#define GSM48_MT_CC_RELEASE 0x2d
#define GSM48_MT_CC_RELEASE_COMPL 0x2a
#define GSM48_MT_CC_CONG_CTRL 0x39
#define GSM48_MT_CC_NOTIFY 0x3e
#define GSM48_MT_CC_STATUS 0x3d
#define GSM48_MT_CC_STATUS_ENQ 0x34
#define GSM48_MT_CC_START_DTMF 0x35
#define GSM48_MT_CC_STOP_DTMF 0x31
#define GSM48_MT_CC_STOP_DTMF_ACK 0x32
#define GSM48_MT_CC_START_DTMF_ACK 0x36
#define GSM48_MT_CC_START_DTMF_REJ 0x37
#define GSM48_MT_CC_FACILITY 0x3a
/* FIXME: Table 10.4 / 10.4a (GPRS) */
/* Section 10.5.2.26, Table 10.5.64 */
#define GSM48_PM_MASK 0x03
#define GSM48_PM_NORMAL 0x00
#define GSM48_PM_EXTENDED 0x01
#define GSM48_PM_REORG 0x02
#define GSM48_PM_SAME 0x03
/* Chapter 10.5.3.5 / Table 10.5.93 */
#define GSM48_LUPD_NORMAL 0x0
#define GSM48_LUPD_PERIODIC 0x1
#define GSM48_LUPD_IMSI_ATT 0x2
#define GSM48_LUPD_RESERVED 0x3
/* Table 10.5.4 */
#define GSM_MI_TYPE_MASK 0x07
#define GSM_MI_TYPE_NONE 0x00
#define GSM_MI_TYPE_IMSI 0x01
#define GSM_MI_TYPE_IMEI 0x02
#define GSM_MI_TYPE_IMEISV 0x03
#define GSM_MI_TYPE_TMSI 0x04
#define GSM_MI_ODD 0x08
#define GSM48_IE_MUL_RATE_CFG 0x03 /* 10.5.2.21aa */
#define GSM48_IE_MOBILE_ID 0x17
#define GSM48_IE_NAME_LONG 0x43 /* 10.5.3.5a */
#define GSM48_IE_NAME_SHORT 0x45 /* 10.5.3.5a */
#define GSM48_IE_UTC 0x46 /* 10.5.3.8 */
#define GSM48_IE_NET_TIME_TZ 0x47 /* 10.5.3.9 */
#define GSM48_IE_LSA_IDENT 0x48 /* 10.5.3.11 */
#define GSM48_IE_BEARER_CAP 0x04 /* 10.5.4.5 */
#define GSM48_IE_CAUSE 0x08 /* 10.5.4.11 */
#define GSM48_IE_CC_CAP 0x15 /* 10.5.4.5a */
#define GSM48_IE_ALERT 0x19 /* 10.5.4.26 */
#define GSM48_IE_FACILITY 0x1c /* 10.5.4.15 */
#define GSM48_IE_PROGR_IND 0x1e /* 10.5.4.21 */
#define GSM48_IE_AUX_STATUS 0x24 /* 10.5.4.4 */
#define GSM48_IE_NOTIFY 0x27 /* 10.5.4.20 */
#define GSM48_IE_KPD_FACILITY 0x2c /* 10.5.4.17 */
#define GSM48_IE_SIGNAL 0x34 /* 10.5.4.23 */
#define GSM48_IE_CONN_BCD 0x4c /* 10.5.4.13 */
#define GSM48_IE_CONN_SUB 0x4d /* 10.5.4.14 */
#define GSM48_IE_CALLING_BCD 0x5c /* 10.5.4.9 */
#define GSM48_IE_CALLING_SUB 0x5d /* 10.5.4.10 */
#define GSM48_IE_CALLED_BCD 0x5e /* 10.5.4.7 */
#define GSM48_IE_CALLED_SUB 0x6d /* 10.5.4.8 */
#define GSM48_IE_REDIR_BCD 0x74 /* 10.5.4.21a */
#define GSM48_IE_REDIR_SUB 0x75 /* 10.5.4.21b */
#define GSM48_IE_LOWL_COMPAT 0x7c /* 10.5.4.18 */
#define GSM48_IE_HIGHL_COMPAT 0x7d /* 10.5.4.16 */
#define GSM48_IE_USER_USER 0x7e /* 10.5.4.25 */
#define GSM48_IE_SS_VERS 0x7f /* 10.5.4.24 */
#define GSM48_IE_MORE_DATA 0xa0 /* 10.5.4.19 */
#define GSM48_IE_CLIR_SUPP 0xa1 /* 10.5.4.11a */
#define GSM48_IE_CLIR_INVOC 0xa2 /* 10.5.4.11b */
#define GSM48_IE_REV_C_SETUP 0xa3 /* 10.5.4.22a */
#define GSM48_IE_REPEAT_CIR 0xd1 /* 10.5.4.22 */
#define GSM48_IE_REPEAT_SEQ 0xd3 /* 10.5.4.22 */
/* Section 10.5.4.11 / Table 10.5.122 */
#define GSM48_CAUSE_CS_GSM 0x60
/* Section 9.1.2 / Table 9.3 */
#define GSM48_IE_FRQLIST_AFTER 0x05
#define GSM48_IE_CELL_CH_DESC 0x62
#define GSM48_IE_MSLOT_DESC 0x10
#define GSM48_IE_CHANMODE_1 0x63
#define GSM48_IE_CHANMODE_2 0x11
#define GSM48_IE_CHANMODE_3 0x13
#define GSM48_IE_CHANMODE_4 0x14
#define GSM48_IE_CHANMODE_5 0x15
#define GSM48_IE_CHANMODE_6 0x16
#define GSM48_IE_CHANMODE_7 0x17
#define GSM48_IE_CHANMODE_8 0x18
#define GSM48_IE_CHANDESC_2 0x64
/* FIXME */
/* Section 10.5.4.23 / Table 10.5.130 */
enum gsm48_signal_val {
GSM48_SIGNAL_DIALTONE = 0x00,
GSM48_SIGNAL_RINGBACK = 0x01,
GSM48_SIGNAL_INTERCEPT = 0x02,
GSM48_SIGNAL_NET_CONG = 0x03,
GSM48_SIGNAL_BUSY = 0x04,
GSM48_SIGNAL_CONFIRM = 0x05,
GSM48_SIGNAL_ANSWER = 0x06,
GSM48_SIGNAL_CALL_WAIT = 0x07,
GSM48_SIGNAL_OFF_HOOK = 0x08,
GSM48_SIGNAL_OFF = 0x3f,
GSM48_SIGNAL_ALERT_OFF = 0x4f,
};
enum gsm48_cause_loc {
GSM48_CAUSE_LOC_USER = 0x00,
GSM48_CAUSE_LOC_PRN_S_LU = 0x01,
GSM48_CAUSE_LOC_PUN_S_LU = 0x02,
GSM48_CAUSE_LOC_TRANS_NET = 0x03,
GSM48_CAUSE_LOC_PUN_S_RU = 0x04,
GSM48_CAUSE_LOC_PRN_S_RU = 0x05,
/* not defined */
GSM48_CAUSE_LOC_INN_NET = 0x07,
GSM48_CAUSE_LOC_NET_BEYOND = 0x0a,
};
/* Section 10.5.2.31 RR Cause / Table 10.5.70 */
enum gsm48_rr_cause {
GSM48_RR_CAUSE_NORMAL = 0x00,
GSM48_RR_CAUSE_ABNORMAL_UNSPEC = 0x01,
GSM48_RR_CAUSE_ABNORMAL_UNACCT = 0x02,
GSM48_RR_CAUSE_ABNORMAL_TIMER = 0x03,
GSM48_RR_CAUSE_ABNORMAL_NOACT = 0x04,
GSM48_RR_CAUSE_PREMPTIVE_REL = 0x05,
GSM48_RR_CAUSE_HNDOVER_IMP = 0x06,
GSM48_RR_CAUSE_CHAN_MODE_UNACCT = 0x07,
GSM48_RR_CAUSE_FREQ_NOT_IMPL = 0x08,
GSM48_RR_CAUSE_CALL_CLEARED = 0x41,
GSM48_RR_CAUSE_SEMANT_INCORR = 0x5f,
GSM48_RR_CAUSE_INVALID_MAND_INF = 0x60,
GSM48_RR_CAUSE_MSG_TYPE_N = 0x61,
GSM48_RR_CAUSE_MSG_TYPE_N_COMPAT= 0x62,
GSM48_RR_CAUSE_COND_IE_ERROR = 0x64,
GSM48_RR_CAUSE_NO_CELL_ALLOC_A = 0x65,
GSM48_RR_CAUSE_PROT_ERROR_UNSPC = 0x6f,
};
/* Section 10.5.4.11 CC Cause / Table 10.5.123 */
enum gsm48_cc_cause {
GSM48_CC_CAUSE_UNASSIGNED_NR = 1,
GSM48_CC_CAUSE_NO_ROUTE = 3,
GSM48_CC_CAUSE_CHAN_UNACCEPT = 6,
GSM48_CC_CAUSE_OP_DET_BARRING = 8,
GSM48_CC_CAUSE_NORM_CALL_CLEAR = 16,
GSM48_CC_CAUSE_USER_BUSY = 17,
GSM48_CC_CAUSE_USER_NOTRESPOND = 18,
GSM48_CC_CAUSE_USER_ALERTING_NA = 19,
GSM48_CC_CAUSE_CALL_REJECTED = 21,
GSM48_CC_CAUSE_NUMBER_CHANGED = 22,
GSM48_CC_CAUSE_PRE_EMPTION = 25,
GSM48_CC_CAUSE_NONSE_USER_CLR = 26,
GSM48_CC_CAUSE_DEST_OOO = 27,
GSM48_CC_CAUSE_INV_NR_FORMAT = 28,
GSM48_CC_CAUSE_FACILITY_REJ = 29,
GSM48_CC_CAUSE_RESP_STATUS_INQ = 30,
GSM48_CC_CAUSE_NORMAL_UNSPEC = 31,
GSM48_CC_CAUSE_NO_CIRCUIT_CHAN = 34,
GSM48_CC_CAUSE_NETWORK_OOO = 38,
GSM48_CC_CAUSE_TEMP_FAILURE = 41,
GSM48_CC_CAUSE_SWITCH_CONG = 42,
GSM48_CC_CAUSE_ACC_INF_DISCARD = 43,
GSM48_CC_CAUSE_REQ_CHAN_UNAVAIL = 44,
GSM48_CC_CAUSE_RESOURCE_UNAVAIL = 47,
GSM48_CC_CAUSE_QOS_UNAVAIL = 49,
GSM48_CC_CAUSE_REQ_FAC_NOT_SUBSC= 50,
GSM48_CC_CAUSE_INC_BARRED_CUG = 55,
GSM48_CC_CAUSE_BEARER_CAP_UNAUTH= 57,
GSM48_CC_CAUSE_BEARER_CA_UNAVAIL= 58,
GSM48_CC_CAUSE_SERV_OPT_UNAVAIL = 63,
GSM48_CC_CAUSE_BEARERSERV_UNIMPL= 65,
GSM48_CC_CAUSE_ACM_GE_ACM_MAX = 68,
GSM48_CC_CAUSE_REQ_FAC_NOTIMPL = 69,
GSM48_CC_CAUSE_RESTR_BCAP_AVAIL = 70,
GSM48_CC_CAUSE_SERV_OPT_UNIMPL = 79,
GSM48_CC_CAUSE_INVAL_TRANS_ID = 81,
GSM48_CC_CAUSE_USER_NOT_IN_CUG = 87,
GSM48_CC_CAUSE_INCOMPAT_DEST = 88,
GSM48_CC_CAUSE_INVAL_TRANS_NET = 91,
GSM48_CC_CAUSE_SEMANTIC_INCORR = 95,
GSM48_CC_CAUSE_INVAL_MAND_INF = 96,
GSM48_CC_CAUSE_MSGTYPE_NOTEXIST = 97,
GSM48_CC_CAUSE_MSGTYPE_INCOMPAT = 98,
GSM48_CC_CAUSE_IE_NOTEXIST = 99,
GSM48_CC_CAUSE_COND_IE_ERR = 100,
GSM48_CC_CAUSE_MSG_INCOMP_STATE = 101,
GSM48_CC_CAUSE_RECOVERY_TIMER = 102,
GSM48_CC_CAUSE_PROTO_ERR = 111,
GSM48_CC_CAUSE_INTERWORKING = 127,
};
/* Annex G, GSM specific cause values for mobility management */
enum gsm48_reject_value {
GSM48_REJECT_IMSI_UNKNOWN_IN_HLR = 2,
GSM48_REJECT_ILLEGAL_MS = 3,
GSM48_REJECT_IMSI_UNKNOWN_IN_VLR = 4,
GSM48_REJECT_IMEI_NOT_ACCEPTED = 5,
GSM48_REJECT_ILLEGAL_ME = 6,
GSM48_REJECT_PLMN_NOT_ALLOWED = 11,
GSM48_REJECT_LOC_NOT_ALLOWED = 12,
GSM48_REJECT_ROAMING_NOT_ALLOWED = 13,
GSM48_REJECT_NETWORK_FAILURE = 17,
GSM48_REJECT_CONGESTION = 22,
GSM48_REJECT_SRV_OPT_NOT_SUPPORTED = 32,
GSM48_REJECT_RQD_SRV_OPT_NOT_SUPPORTED = 33,
GSM48_REJECT_SRV_OPT_TMP_OUT_OF_ORDER = 34,
GSM48_REJECT_CALL_CAN_NOT_BE_IDENTIFIED = 38,
GSM48_REJECT_INCORRECT_MESSAGE = 95,
GSM48_REJECT_INVALID_MANDANTORY_INF = 96,
GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED = 97,
GSM48_REJECT_MSG_TYPE_NOT_COMPATIBLE = 98,
GSM48_REJECT_INF_ELEME_NOT_IMPLEMENTED = 99,
GSM48_REJECT_CONDTIONAL_IE_ERROR = 100,
GSM48_REJECT_MSG_NOT_COMPATIBLE = 101,
GSM48_REJECT_PROTOCOL_ERROR = 111,
/* according to G.6 Additional cause codes for GMM */
GSM48_REJECT_GPRS_NOT_ALLOWED = 7,
GSM48_REJECT_SERVICES_NOT_ALLOWED = 8,
GSM48_REJECT_MS_IDENTITY_NOT_DERVIVABLE = 9,
GSM48_REJECT_IMPLICITLY_DETACHED = 10,
GSM48_REJECT_GPRS_NOT_ALLOWED_IN_PLMN = 14,
GSM48_REJECT_MSC_TMP_NOT_REACHABLE = 16,
};
enum chreq_type {
CHREQ_T_EMERG_CALL,
CHREQ_T_CALL_REEST_TCH_F,
CHREQ_T_CALL_REEST_TCH_H,
CHREQ_T_CALL_REEST_TCH_H_DBL,
CHREQ_T_SDCCH,
CHREQ_T_TCH_F,
CHREQ_T_VOICE_CALL_TCH_H,
CHREQ_T_DATA_CALL_TCH_H,
CHREQ_T_LOCATION_UPD,
CHREQ_T_PAG_R_ANY_NECI0,
CHREQ_T_PAG_R_ANY_NECI1,
CHREQ_T_PAG_R_TCH_F,
CHREQ_T_PAG_R_TCH_FH,
CHREQ_T_LMU,
CHREQ_T_RESERVED_SDCCH,
CHREQ_T_RESERVED_IGNORE,
};
/* Chapter 11.3 */
#define GSM48_T301 180, 0
#define GSM48_T303 30, 0
#define GSM48_T305 30, 0
#define GSM48_T306 30, 0
#define GSM48_T308 10, 0
#define GSM48_T310 180, 0
#define GSM48_T313 30, 0
#define GSM48_T323 30, 0
#define GSM48_T331 30, 0
#define GSM48_T333 30, 0
#define GSM48_T334 25, 0 /* min 15 */
#define GSM48_T338 30, 0
/* Chapter 5.1.2.2 */
#define GSM_CSTATE_NULL 0
#define GSM_CSTATE_INITIATED 1
#define GSM_CSTATE_MO_CALL_PROC 3
#define GSM_CSTATE_CALL_DELIVERED 4
#define GSM_CSTATE_CALL_PRESENT 6
#define GSM_CSTATE_CALL_RECEIVED 7
#define GSM_CSTATE_CONNECT_REQUEST 8
#define GSM_CSTATE_MO_TERM_CALL_CONF 9
#define GSM_CSTATE_ACTIVE 10
#define GSM_CSTATE_DISCONNECT_REQ 12
#define GSM_CSTATE_DISCONNECT_IND 12
#define GSM_CSTATE_RELEASE_REQ 19
#define GSM_CSTATE_MO_ORIG_MODIFY 26
#define GSM_CSTATE_MO_TERM_MODIFY 27
#define GSM_CSTATE_CONNECT_IND 28
#define SBIT(a) (1 << a)
#define ALL_STATES 0xffffffff
/* Table 10.5.3/3GPP TS 04.08: Location Area Identification information element */
#define GSM_LAC_RESERVED_DETACHED 0x0
#define GSM_LAC_RESERVED_ALL_BTS 0xfffe
/* GSM 04.08 Bearer Capability: Information Transfer Capability */
enum gsm48_bcap_itcap {
GSM48_BCAP_ITCAP_SPEECH = 0,
GSM48_BCAP_ITCAP_UNR_DIG_INF = 1,
GSM48_BCAP_ITCAP_3k1_AUDIO = 2,
GSM48_BCAP_ITCAP_FAX_G3 = 3,
GSM48_BCAP_ITCAP_OTHER = 5,
GSM48_BCAP_ITCAP_RESERVED = 7,
};
/* GSM 04.08 Bearer Capability: Transfer Mode */
enum gsm48_bcap_tmod {
GSM48_BCAP_TMOD_CIRCUIT = 0,
GSM48_BCAP_TMOD_PACKET = 1,
};
/* GSM 04.08 Bearer Capability: Coding Standard */
enum gsm48_bcap_coding {
GSM48_BCAP_CODING_GSM_STD = 0,
};
/* GSM 04.08 Bearer Capability: Radio Channel Requirements */
enum gsm48_bcap_rrq {
GSM48_BCAP_RRQ_FR_ONLY = 1,
GSM48_BCAP_RRQ_DUAL_HR = 2,
GSM48_BCAP_RRQ_DUAL_FR = 3,
};
#define GSM48_TMSI_LEN 5
#define GSM48_MID_TMSI_LEN (GSM48_TMSI_LEN + 2)
#define GSM48_MI_SIZE 32
struct msgb;
struct gsm_bts;
@@ -16,14 +750,18 @@ struct gsm_trans;
void gsm0408_allow_everyone(int allow);
int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id);
void gsm0408_generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc,
u_int16_t mnc, u_int16_t lac);
enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci);
enum gsm_chreq_reason_t get_reason_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci);
int gsm48_tx_mm_info(struct gsm_lchan *lchan);
int gsm48_tx_mm_auth_req(struct gsm_lchan *lchan, u_int8_t *rand, int key_seq);
int gsm48_tx_mm_auth_req(struct gsm_lchan *lchan, u_int8_t *rand);
int gsm48_tx_mm_auth_rej(struct gsm_lchan *lchan);
struct msgb *gsm48_msgb_alloc(void);
int gsm48_sendmsg(struct msgb *msg, struct gsm_trans *trans);
int gsm48_generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi);
int gsm48_generate_mid_from_imsi(u_int8_t *buf, const char* imsi);
int gsm48_mi_to_string(char *string, const int str_len, const u_int8_t *mi, const int mi_len);
int gsm48_send_rr_release(struct gsm_lchan *lchan);
@@ -44,6 +782,8 @@ int encode_bcd_number(u_int8_t *bcd_lv, u_int8_t max_len,
int decode_bcd_number(char *output, int output_len, const u_int8_t *bcd_lv,
int h_len);
extern const char *gsm0408_cc_msg_names[];
int send_siemens_mrpci(struct gsm_lchan *lchan, u_int8_t *classmark2_lv);
int gsm48_paging_extract_mi(struct msgb *msg, char *mi_string, u_int8_t *mi_type);
int gsm48_handle_paging_resp(struct msgb *msg, struct gsm_subscriber *subscr);

View File

@@ -1,7 +1,187 @@
#ifndef _GSM_04_11_H
#define _GSM_04_11_H
#include <osmocore/protocol/gsm_04_11.h>
/* GSM TS 04.11 definitions */
/* Chapter 5.2.3: SMC-CS states at the network side */
enum gsm411_cp_state {
GSM411_CPS_IDLE = 0,
GSM411_CPS_MM_CONN_PENDING = 1, /* only MT ! */
GSM411_CPS_WAIT_CP_ACK = 2,
GSM411_CPS_MM_ESTABLISHED = 3,
};
/* Chapter 6.2.2: SMR states at the network side */
enum gsm411_rp_state {
GSM411_RPS_IDLE = 0,
GSM411_RPS_WAIT_FOR_RP_ACK = 1,
GSM411_RPS_WAIT_TO_TX_RP_ACK = 3,
};
/* Chapter 8.1.2 (refers to GSM 04.07 Chapter 11.2.3.1.1 */
#define GSM411_PDISC_SMS 0x09
/* Chapter 8.1.3 */
#define GSM411_MT_CP_DATA 0x01
#define GSM411_MT_CP_ACK 0x04
#define GSM411_MT_CP_ERROR 0x10
enum gsm411_cp_ie {
GSM411_CP_IE_USER_DATA = 0x01, /* 8.1.4.1 */
GSM411_CP_IE_CAUSE = 0x02, /* 8.1.4.2. */
};
/* Section 8.1.4.2 / Table 8.2 */
enum gsm411_cp_cause {
GSM411_CP_CAUSE_NET_FAIL = 17,
GSM411_CP_CAUSE_CONGESTION = 22,
GSM411_CP_CAUSE_INV_TRANS_ID = 81,
GSM411_CP_CAUSE_SEMANT_INC_MSG = 95,
GSM411_CP_CAUSE_INV_MAND_INF = 96,
GSM411_CP_CAUSE_MSGTYPE_NOTEXIST= 97,
GSM411_CP_CAUSE_MSG_INCOMP_STATE= 98,
GSM411_CP_CAUSE_IE_NOTEXIST = 99,
GSM411_CP_CAUSE_PROTOCOL_ERR = 111,
};
/* Chapter 8.2.2 */
#define GSM411_MT_RP_DATA_MO 0x00
#define GSM411_MT_RP_DATA_MT 0x01
#define GSM411_MT_RP_ACK_MO 0x02
#define GSM411_MT_RP_ACK_MT 0x03
#define GSM411_MT_RP_ERROR_MO 0x04
#define GSM411_MT_RP_ERROR_MT 0x05
#define GSM411_MT_RP_SMMA_MO 0x06
enum gsm411_rp_ie {
GSM411_IE_RP_USER_DATA = 0x41, /* 8.2.5.3 */
GSM411_IE_RP_CAUSE = 0x42, /* 8.2.5.4 */
};
/* Chapter 8.2.5.4 Table 8.4 */
enum gsm411_rp_cause {
/* valid only for MO */
GSM411_RP_CAUSE_MO_NUM_UNASSIGNED = 1,
GSM411_RP_CAUSE_MO_OP_DET_BARR = 8,
GSM411_RP_CAUSE_MO_CALL_BARRED = 10,
GSM411_RP_CAUSE_MO_SMS_REJECTED = 21,
GSM411_RP_CAUSE_MO_DEST_OUT_OF_ORDER = 27,
GSM411_RP_CAUSE_MO_UNIDENTIFIED_SUBSCR = 28,
GSM411_RP_CAUSE_MO_FACILITY_REJ = 29,
GSM411_RP_CAUSE_MO_UNKNOWN_SUBSCR = 30,
GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER = 38,
GSM411_RP_CAUSE_MO_TEMP_FAIL = 41,
GSM411_RP_CAUSE_MO_CONGESTION = 42,
GSM411_RP_CAUSE_MO_RES_UNAVAIL = 47,
GSM411_RP_CAUSE_MO_REQ_FAC_NOTSUBSCR = 50,
GSM411_RP_CAUSE_MO_REQ_FAC_NOTIMPL = 69,
GSM411_RP_CAUSE_MO_INTERWORKING = 127,
/* valid only for MT */
GSM411_RP_CAUSE_MT_MEM_EXCEEDED = 22,
/* valid for both directions */
GSM411_RP_CAUSE_INV_TRANS_REF = 81,
GSM411_RP_CAUSE_SEMANT_INC_MSG = 95,
GSM411_RP_CAUSE_INV_MAND_INF = 96,
GSM411_RP_CAUSE_MSGTYPE_NOTEXIST = 97,
GSM411_RP_CAUSE_MSG_INCOMP_STATE = 98,
GSM411_RP_CAUSE_IE_NOTEXIST = 99,
GSM411_RP_CAUSE_PROTOCOL_ERR = 111,
};
/* Chapter 10: Timers */
#define GSM411_TMR_TR1M 40, 0 /* 35 < x < 45 seconds */
#define GSM411_TMR_TRAM 30, 0 /* 25 < x < 35 seconds */
#define GSM411_TMR_TR2M 15, 0 /* 12 < x < 20 seconds */
#define GSM411_TMR_TC1A 30, 0
/* Chapter 8.2.1 */
struct gsm411_rp_hdr {
u_int8_t len;
u_int8_t msg_type;
u_int8_t msg_ref;
u_int8_t data[0];
} __attribute__ ((packed));
/* our own enum, not related to on-air protocol */
enum sms_alphabet {
DCS_NONE,
DCS_7BIT_DEFAULT,
DCS_UCS2,
DCS_8BIT_DATA,
};
/* GSM 03.40 / Chapter 9.2.3.1: TP-Message-Type-Indicator */
#define GSM340_SMS_DELIVER_SC2MS 0x00
#define GSM340_SMS_DELIVER_REP_MS2SC 0x00
#define GSM340_SMS_STATUS_REP_SC2MS 0x02
#define GSM340_SMS_COMMAND_MS2SC 0x02
#define GSM340_SMS_SUBMIT_MS2SC 0x01
#define GSM340_SMS_SUBMIT_REP_SC2MS 0x01
#define GSM340_SMS_RESSERVED 0x03
/* GSM 03.40 / Chapter 9.2.3.2: TP-More-Messages-to-Send */
#define GSM340_TP_MMS_MORE 0
#define GSM340_TP_MMS_NO_MORE 1
/* GSM 03.40 / Chapter 9.2.3.3: TP-Validity-Period-Format */
#define GSM340_TP_VPF_NONE 0
#define GSM340_TP_VPF_RELATIVE 2
#define GSM340_TP_VPF_ENHANCED 1
#define GSM340_TP_VPF_ABSOLUTE 3
/* GSM 03.40 / Chapter 9.2.3.4: TP-Status-Report-Indication */
#define GSM340_TP_SRI_NONE 0
#define GSM340_TP_SRI_PRESENT 1
/* GSM 03.40 / Chapter 9.2.3.5: TP-Status-Report-Request */
#define GSM340_TP_SRR_NONE 0
#define GSM340_TP_SRR_REQUESTED 1
/* GSM 03.40 / Chapter 9.2.3.9: TP-Protocol-Identifier */
/* telematic interworking (001 or 111 in bits 7-5) */
#define GSM340_TP_PID_IMPLICIT 0x00
#define GSM340_TP_PID_TELEX 0x01
#define GSM340_TP_PID_FAX_G3 0x02
#define GSM340_TP_PID_FAX_G4 0x03
#define GSM340_TP_PID_VOICE 0x04
#define GSM430_TP_PID_ERMES 0x05
#define GSM430_TP_PID_NATIONAL_PAGING 0x06
#define GSM430_TP_PID_VIDEOTEX 0x07
#define GSM430_TP_PID_TELETEX_UNSPEC 0x08
#define GSM430_TP_PID_TELETEX_PSPDN 0x09
#define GSM430_TP_PID_TELETEX_CSPDN 0x0a
#define GSM430_TP_PID_TELETEX_PSTN 0x0b
#define GSM430_TP_PID_TELETEX_ISDN 0x0c
#define GSM430_TP_PID_TELETEX_UCI 0x0d
#define GSM430_TP_PID_MSG_HANDLING 0x10
#define GSM430_TP_PID_MSG_X400 0x11
#define GSM430_TP_PID_EMAIL 0x12
#define GSM430_TP_PID_GSM_MS 0x1f
/* if bit 7 = 0 and bit 6 = 1 */
#define GSM430_TP_PID_SMS_TYPE_0 0
#define GSM430_TP_PID_SMS_TYPE_1 1
#define GSM430_TP_PID_SMS_TYPE_2 2
#define GSM430_TP_PID_SMS_TYPE_3 3
#define GSM430_TP_PID_SMS_TYPE_4 4
#define GSM430_TP_PID_SMS_TYPE_5 5
#define GSM430_TP_PID_SMS_TYPE_6 6
#define GSM430_TP_PID_SMS_TYPE_7 7
#define GSM430_TP_PID_RETURN_CALL_MSG 0x1f
#define GSM430_TP_PID_ME_DATA_DNLOAD 0x3d
#define GSM430_TP_PID_ME_DE_PERSONAL 0x3e
#define GSM430_TP_PID_ME_SIM_DNLOAD 0x3f
/* GSM 03.38 Chapter 4: SMS Data Coding Scheme */
#define GSM338_DCS_00_
#define GSM338_DCS_1110_7BIT (0 << 2)
#define GSM338_DCS_1111_7BIT (0 << 2)
#define GSM338_DCS_1111_8BIT_DATA (1 << 2)
#define GSM338_DCS_1111_CLASS0 0
#define GSM338_DCS_1111_CLASS1_ME 1
#define GSM338_DCS_1111_CLASS2_SIM 2
#define GSM338_DCS_1111_CLASS3_TE 3 /* See TS 07.05 */
/* SMS deliver PDU */
struct sms_deliver {

View File

@@ -1,8 +1,129 @@
#ifndef _GSM_04_80_H
#define _GSM_04_80_H
#include <osmocore/msgb.h>
#include <osmocore/protocol/gsm_04_80.h>
/* GSM TS 04.80 definitions (Supplementary Services Specification, Formats and Coding) */
/* Section 3.4 */
#define GSM0480_MTYPE_RELEASE_COMPLETE 0x2A
#define GSM0480_MTYPE_FACILITY 0x3A
#define GSM0480_MTYPE_REGISTER 0x3B
/* Section 3.5 */
#define GSM0480_IE_FACILITY 0x1C
#define GSM0480_IE_SS_VERSION 0x7F
/* Section 3.6.2 */
#define GSM0480_CTYPE_INVOKE 0xA1
#define GSM0480_CTYPE_RETURN_RESULT 0xA2
#define GSM0480_CTYPE_RETURN_ERROR 0xA3
#define GSM0480_CTYPE_REJECT 0xA4
/* Section 3.6.3 */
#define GSM0480_COMPIDTAG_INVOKE_ID 0x02
#define GSM0480_COMPIDTAG_LINKED_ID 0x80
/* Section 3.6.4 */
#define GSM0480_OPERATION_CODE 0x02
/* Section 3.6.5 */
#define GSM_0480_SEQUENCE_TAG 0x30
#define GSM_0480_SET_TAG 0x31
/* Section 3.6.6 */
#define GSM_0480_ERROR_CODE_TAG 0x02
/* Section 3.6.7 */
/* Table 3.13 */
#define GSM_0480_PROBLEM_CODE_TAG_GENERAL 0x80
#define GSM_0480_PROBLEM_CODE_TAG_INVOKE 0x81
#define GSM_0480_PROBLEM_CODE_TAG_RETURN_RESULT 0x82
#define GSM_0480_PROBLEM_CODE_TAG_RETURN_ERROR 0x83
/* Table 3.14 */
#define GSM_0480_GEN_PROB_CODE_UNRECOGNISED 0x00
#define GSM_0480_GEN_PROB_CODE_MISTYPED 0x01
#define GSM_0480_GEN_PROB_CODE_BAD_STRUCTURE 0x02
/* Table 3.15 */
#define GSM_0480_INVOKE_PROB_CODE_DUPLICATE_INVOKE_ID 0x00
#define GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_OPERATION 0x01
#define GSM_0480_INVOKE_PROB_CODE_MISTYPED_PARAMETER 0x02
#define GSM_0480_INVOKE_PROB_CODE_RESOURCE_LIMITATION 0x03
#define GSM_0480_INVOKE_PROB_CODE_INITIATING_RELEASE 0x04
#define GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_LINKED_ID 0x05
#define GSM_0480_INVOKE_PROB_CODE_UNEXPECTED_LINKED_RESPONSE 0x06
#define GSM_0480_INVOKE_PROB_CODE_UNEXPECTED_LINKED_OPERATION 0x07
/* Table 3.16 */
#define GSM_0480_RESULT_PROB_CODE_UNRECOGNISED_INVOKE_ID 0x00
#define GSM_0480_RESULT_PROB_CODE_RETURN_RESULT_UNEXPECTED 0x01
#define GSM_0480_RESULT_PROB_CODE_MISTYPED_PARAMETER 0x02
/* Table 3.17 */
#define GSM_0480_ERROR_PROB_CODE_UNRECOGNISED_INVOKE_ID 0x00
#define GSM_0480_ERROR_PROB_CODE_RETURN_ERROR_UNEXPECTED 0x01
#define GSM_0480_ERROR_PROB_CODE_UNRECOGNISED_ERROR 0x02
#define GSM_0480_ERROR_PROB_CODE_UNEXPECTED_ERROR 0x03
#define GSM_0480_ERROR_PROB_CODE_MISTYPED_PARAMETER 0x04
/* Section 4.5 */
#define GSM0480_OP_CODE_REGISTER_SS 0x0A
#define GSM0480_OP_CODE_ERASE_SS 0x0B
#define GSM0480_OP_CODE_ACTIVATE_SS 0x0C
#define GSM0480_OP_CODE_DEACTIVATE_SS 0x0D
#define GSM0480_OP_CODE_INTERROGATE_SS 0x0E
#define GSM0480_OP_CODE_NOTIFY_SS 0x10
#define GSM0480_OP_CODE_REGISTER_PASSWORD 0x11
#define GSM0480_OP_CODE_GET_PASSWORD 0x12
#define GSM0480_OP_CODE_PROCESS_USS_DATA 0x13
#define GSM0480_OP_CODE_FORWARD_CHECK_SS_IND 0x26
#define GSM0480_OP_CODE_PROCESS_USS_REQ 0x3B
#define GSM0480_OP_CODE_USS_REQUEST 0x3C
#define GSM0480_OP_CODE_USS_NOTIFY 0x3D
#define GSM0480_OP_CODE_FORWARD_CUG_INFO 0x78
#define GSM0480_OP_CODE_SPLIT_MPTY 0x79
#define GSM0480_OP_CODE_RETRIEVE_MPTY 0x7A
#define GSM0480_OP_CODE_HOLD_MPTY 0x7B
#define GSM0480_OP_CODE_BUILD_MPTY 0x7C
#define GSM0480_OP_CODE_FORWARD_CHARGE_ADVICE 0x7D
#define GSM0480_ERR_CODE_UNKNOWN_SUBSCRIBER 0x01
#define GSM0480_ERR_CODE_ILLEGAL_SUBSCRIBER 0x09
#define GSM0480_ERR_CODE_BEARER_SERVICE_NOT_PROVISIONED 0x0A
#define GSM0480_ERR_CODE_TELESERVICE_NOT_PROVISIONED 0x0B
#define GSM0480_ERR_CODE_ILLEGAL_EQUIPMENT 0x0C
#define GSM0480_ERR_CODE_CALL_BARRED 0x0D
#define GSM0480_ERR_CODE_ILLEGAL_SS_OPERATION 0x10
#define GSM0480_ERR_CODE_SS_ERROR_STATUS 0x11
#define GSM0480_ERR_CODE_SS_NOT_AVAILABLE 0x12
#define GSM0480_ERR_CODE_SS_SUBSCRIPTION_VIOLATION 0x13
#define GSM0480_ERR_CODE_SS_INCOMPATIBILITY 0x14
#define GSM0480_ERR_CODE_FACILITY_NOT_SUPPORTED 0x15
#define GSM0480_ERR_CODE_ABSENT_SUBSCRIBER 0x1B
#define GSM0480_ERR_CODE_SYSTEM_FAILURE 0x22
#define GSM0480_ERR_CODE_DATA_MISSING 0x23
#define GSM0480_ERR_CODE_UNEXPECTED_DATA_VALUE 0x24
#define GSM0480_ERR_CODE_PW_REGISTRATION_FAILURE 0x25
#define GSM0480_ERR_CODE_NEGATIVE_PW_CHECK 0x26
#define GSM0480_ERR_CODE_NUM_PW_ATTEMPTS_VIOLATION 0x2B
#define GSM0480_ERR_CODE_UNKNOWN_ALPHABET 0x47
#define GSM0480_ERR_CODE_USSD_BUSY 0x48
#define GSM0480_ERR_CODE_MAX_MPTY_PARTICIPANTS 0x7E
#define GSM0480_ERR_CODE_RESOURCES_NOT_AVAILABLE 0x7F
/* ASN.1 type-tags */
#define ASN1_BOOLEAN_TAG 0x01
#define ASN1_INTEGER_TAG 0x02
#define ASN1_BIT_STRING_TAG 0x03
#define ASN1_OCTET_STRING_TAG 0x04
#define ASN1_NULL_TYPE_TAG 0x05
#define ASN1_OBJECT_ID_TAG 0x06
#define ASN1_UTF8_STRING_TAG 0x0C
#define ASN1_PRINTABLE_STRING_TAG 0x13
#define ASN1_IA5_STRING_TAG 0x16
#define ASN1_UNICODE_STRING_TAG 0x1E
#include <openbsc/msgb.h>
#define MAX_LEN_USSD_STRING 31

View File

@@ -3,6 +3,21 @@
#include <sys/types.h>
struct value_string {
unsigned int value;
const char *str;
};
const char *get_value_string(const struct value_string *vs, u_int32_t val);
enum gsm_band {
GSM_BAND_400,
GSM_BAND_850,
GSM_BAND_900,
GSM_BAND_1800,
GSM_BAND_1900,
};
enum gsm_phys_chan_config {
GSM_PCHAN_NONE,
GSM_PCHAN_CCCH,
@@ -40,15 +55,14 @@ enum gsm_chreq_reason_t {
GSM_CHREQ_REASON_OTHER,
};
#include <osmocore/timer.h>
#include <openbsc/timer.h>
#include <openbsc/gsm_04_08.h>
#include <openbsc/abis_rsl.h>
#include <openbsc/mncc.h>
#include <osmocore/tlv.h>
#include <osmocore/bitvec.h>
#include <osmocore/statistics.h>
#include <osmocore/gsm_utils.h>
#include <osmocore/utils.h>
#include <openbsc/tlv.h>
#include <openbsc/bitvec.h>
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define TRX_NR_TS 8
#define TS_MAX_LCHAN 8
@@ -79,58 +93,51 @@ typedef int gsm_cbfn(unsigned int hooknum,
struct msgb *msg,
void *data, void *param);
/*
* Use the channel. As side effect the lchannel recycle timer
* will be started.
*/
#define LCHAN_RELEASE_TIMEOUT 20, 0
#define use_lchan(lchan) \
do { lchan->use_count++; \
DEBUGP(DREF, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) increases usage to: %d\n", \
lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \
lchan->nr, lchan->use_count); \
bsc_schedule_timer(&lchan->release_timer, LCHAN_RELEASE_TIMEOUT); } while(0);
#define put_lchan(lchan) \
do { lchan->use_count--; \
DEBUGP(DREF, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) decreases usage to: %d\n", \
lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \
lchan->nr, lchan->use_count); \
} while(0);
/* communications link with a BTS */
struct gsm_bts_link {
struct gsm_bts *bts;
};
/* Real authentication information containing Ki */
enum gsm_auth_algo {
AUTH_ALGO_NONE,
AUTH_ALGO_XOR,
AUTH_ALGO_COMP128v1,
};
struct gsm_auth_info {
enum gsm_auth_algo auth_algo;
unsigned int a3a8_ki_len;
u_int8_t a3a8_ki[16];
};
struct gsm_auth_tuple {
int use_count;
int key_seq;
u_int8_t rand[16];
u_int8_t sres[4];
u_int8_t kc[8];
};
struct sccp_connection;
struct gsm_lchan;
struct gsm_subscriber;
struct gsm_mncc;
struct rtp_socket;
/* BSC/MSC data holding them together */
struct bss_sccp_connection_data {
struct gsm_lchan *lchan;
struct gsm_lchan *secondary_lchan;
struct sccp_connection *sccp;
int ciphering_handled : 1;
/* Timers... */
/* for assginment command */
struct timer_list T10;
/* for SCCP ... */
struct timer_list sccp_it;
/* audio handling */
int rtp_port;
/* Queue SCCP and GSM0408 messages */
int block_gsm;
struct llist_head gsm_queue;
unsigned int gsm_queue_size;
struct llist_head sccp_queue;
unsigned int sccp_queue_size;
};
#define GSM0808_T10_VALUE 6, 0
#define sccp_get_lchan(data_ctx) ((struct bss_sccp_connection_data *)data_ctx)->lchan
#define lchan_get_sccp(lchan) lchan->msc_data->sccp
struct bss_sccp_connection_data *bss_sccp_create_data();
void bss_sccp_free_data(struct bss_sccp_connection_data *);
/* Network Management State */
struct gsm_nm_state {
u_int8_t operational;
@@ -176,9 +183,7 @@ struct neigh_meas_proc {
/* state of a logical channel */
enum gsm_lchan_state {
LCHAN_S_NONE, /* channel is not active */
LCHAN_S_ACT_REQ, /* channel activatin requested */
LCHAN_S_ACTIVE, /* channel is active and operational */
LCHAN_S_REL_REQ, /* channel release has been requested */
LCHAN_S_INACTIVE, /* channel is set inactive */
};
@@ -204,8 +209,6 @@ struct gsm_lchan {
u_int8_t key_len;
u_int8_t key[MAX_A5_KEY_LEN];
} encr;
/* Are we part of a special "silent" call */
int silent_call;
/* AMR bits */
struct gsm48_multi_rate_conf mr_conf;
@@ -213,9 +216,6 @@ struct gsm_lchan {
/* To whom we are allocated at the moment */
struct gsm_subscriber *subscr;
/* Timer started to release the channel */
struct timer_list release_timer;
struct timer_list T3101;
/* Established data link layer services */
@@ -226,6 +226,12 @@ struct gsm_lchan {
*/
struct gsm_loc_updating_operation *loc_operation;
/*
* MSC handling...
*/
struct bss_sccp_connection_data *msc_data;
/* use count. how many users use this channel */
unsigned int use_count;
@@ -311,6 +317,9 @@ struct gsm_bts_trx {
} bs11;
};
struct gsm_bts_trx_ts ts[TRX_NR_TS];
/* NM state */
int rf_locked;
};
enum gsm_bts_type {
@@ -319,15 +328,6 @@ enum gsm_bts_type {
GSM_BTS_TYPE_NANOBTS,
};
struct gsm_bts_model {
struct llist_head list;
enum gsm_bts_type type;
const char *name;
struct tlv_definition nm_att_tlvdef;
};
/**
* A pending paging request
*/
@@ -374,10 +374,6 @@ struct gsm_envabtse {
struct gsm_bts_gprs_nsvc {
struct gsm_bts *bts;
int id;
u_int16_t nsvci;
u_int16_t local_port;
u_int16_t remote_port;
u_int32_t remote_ip;
struct gsm_nm_state nm_state;
};
@@ -399,7 +395,6 @@ struct gsm_bts {
u_int8_t bsic;
/* type of BTS */
enum gsm_bts_type type;
struct gsm_bts_model *model;
enum gsm_band band;
/* should the channel allocator allocate channels from high TRX to TRX0,
* rather than starting from TRX0 and go upwards? */
@@ -466,17 +461,13 @@ struct gsm_bts {
/* Not entirely sure how ip.access specific this is */
struct {
int enabled;
struct {
struct gsm_nm_state nm_state;
u_int16_t nsei;
} nse;
struct {
struct gsm_nm_state nm_state;
u_int16_t bvci;
} cell;
struct gsm_bts_gprs_nsvc nsvc[2];
u_int8_t rac;
} gprs;
/* transceivers */
@@ -487,43 +478,43 @@ struct gsm_bts {
/* Some statistics of our network */
struct gsmnet_stats {
struct {
struct counter *total;
struct counter *no_channel;
unsigned long total;
unsigned long no_channel;
} chreq;
struct {
struct counter *attempted;
struct counter *no_channel; /* no channel available */
struct counter *timeout; /* T3103 timeout */
struct counter *completed; /* HO COMPL received */
struct counter *failed; /* HO FAIL received */
unsigned long attempted;
unsigned long no_channel; /* no channel available */
unsigned long timeout; /* T3103 timeout */
unsigned long completed; /* HO COMPL received */
unsigned long failed; /* HO FAIL received */
} handover;
struct {
struct counter *attach;
struct counter *normal;
struct counter *periodic;
struct counter *detach;
unsigned long attach;
unsigned long normal;
unsigned long periodic;
unsigned long detach;
} loc_upd_type;
struct {
struct counter *reject;
struct counter *accept;
unsigned long reject;
unsigned long accept;
} loc_upd_resp;
struct {
struct counter *attempted;
struct counter *detached;
struct counter *completed;
struct counter *expired;
unsigned long attempted;
unsigned long detached;
unsigned long completed;
unsigned long expired;
} paging;
struct {
struct counter *submitted; /* MO SMS submissions */
struct counter *no_receiver;
struct counter *delivered; /* MT SMS deliveries */
struct counter *rp_err_mem;
struct counter *rp_err_other;
unsigned long submitted; /* MO SMS submissions */
unsigned long no_receiver;
unsigned long delivered; /* MT SMS deliveries */
unsigned long rp_err_mem;
unsigned long rp_err_other;
} sms;
struct {
struct counter *dialled; /* total number of dialled calls */
struct counter *alerted; /* we alerted the other end */
struct counter *connected;/* how many calls were accepted */
unsigned long dialled; /* total number of dialled calls */
unsigned long alerted; /* we alerted the other end */
unsigned long connected;/* how many calls were accepted */
} call;
};
@@ -536,6 +527,14 @@ enum gsm_auth_policy {
#define GSM_T3101_DEFAULT 10
#define GSM_T3113_DEFAULT 60
/*
* internal data for audio management
*/
struct gsm_audio_support {
u_int8_t hr : 1,
ver : 7;
};
struct gsm_network {
/* global parameters */
u_int16_t country_code;
@@ -566,6 +565,11 @@ struct gsm_network {
struct gsmnet_stats stats;
struct gsm_audio_support **audio_support;
int audio_length;
int rtp_payload;
int rtp_base_port;
/* layer 4 */
int (*mncc_recv) (struct gsm_network *net, int msg_type, void *arg);
struct llist_head upqueue;
@@ -591,6 +595,10 @@ struct gsm_network {
struct {
enum rrlp_mode mode;
} rrlp;
/* a hack for On Waves. It must be signed */
int32_t core_country_code;
int32_t core_network_code;
};
#define SMS_HDR_SIZE 128
@@ -615,13 +623,11 @@ struct gsm_sms {
char text[SMS_TEXT_SIZE];
};
struct gsm_network *gsm_network_init(u_int16_t country_code, u_int16_t network_code,
int (*mncc_recv)(struct gsm_network *, int, void *));
struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, enum gsm_bts_type type,
u_int8_t tsc, u_int8_t bsic);
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts);
int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type);
struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num);
@@ -633,12 +639,9 @@ struct gsm_bts_trx *gsm_bts_trx_num(struct gsm_bts *bts, int num);
const char *gsm_pchan_name(enum gsm_phys_chan_config c);
enum gsm_phys_chan_config gsm_pchan_parse(const char *name);
const char *gsm_lchant_name(enum gsm_chan_t c);
const char *gsm_lchan_name(enum gsm_chan_t c);
const char *gsm_chreq_name(enum gsm_chreq_reason_t c);
char *gsm_trx_name(struct gsm_bts_trx *trx);
char *gsm_ts_name(struct gsm_bts_trx_ts *ts);
char *gsm_lchan_name(struct gsm_lchan *lchan);
const char *gsm_lchans_name(enum gsm_lchan_state s);
enum gsm_e1_event {
EVT_E1_NONE,
@@ -650,10 +653,12 @@ void set_ts_e1link(struct gsm_bts_trx_ts *ts, u_int8_t e1_nr,
u_int8_t e1_ts, u_int8_t e1_ts_ss);
enum gsm_bts_type parse_btstype(const char *arg);
const char *btstype2str(enum gsm_bts_type type);
struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr);
struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac,
struct gsm_bts *start_bts);
char *gsm_band_name(enum gsm_band band);
enum gsm_band gsm_band_parse(const char *mhz);
extern void *tall_bsc_ctx;
extern int ipacc_rtp_direct;
@@ -689,18 +694,6 @@ const char *rrlp_mode_name(enum rrlp_mode mode);
void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked);
/* A parsed GPRS routing area */
struct gprs_ra_id {
u_int16_t mnc;
u_int16_t mcc;
u_int16_t lac;
u_int8_t rac;
};
int gsm48_ra_id_by_bts(u_int8_t *buf, struct gsm_bts *bts);
void gprs_ra_id_by_bts(struct gprs_ra_id *raid, struct gsm_bts *bts);
struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan);
int gsm_bts_model_register(struct gsm_bts_model *model);
#endif

View File

@@ -3,7 +3,7 @@
#include <sys/types.h>
#include "gsm_data.h"
#include <osmocore/linuxlist.h>
#include "linuxlist.h"
#define GSM_IMEI_LENGTH 17
#define GSM_IMSI_LENGTH 17
@@ -81,13 +81,13 @@ struct gsm_subscriber *subscr_get_by_extension(struct gsm_network *net,
const char *ext);
struct gsm_subscriber *subscr_get_by_id(struct gsm_network *net,
unsigned long long id);
struct gsm_subscriber *subscr_get_or_create(struct gsm_network *net,
const char *imsi);
int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason);
void subscr_put_channel(struct gsm_lchan *lchan);
void subscr_get_channel(struct gsm_subscriber *subscr,
int type, gsm_cbfn *cbfn, void *param);
char *subscr_name(struct gsm_subscriber *subscr);
/* internal */
struct gsm_subscriber *subscr_alloc(void);
extern struct llist_head active_subscribers;

View File

@@ -0,0 +1,41 @@
/* GSM utility functions, e.g. coding and decoding */
/*
* (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009 by Harald Welte <laforge@gnumonks.org>
*
* 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 2 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#ifndef GSM_UTILS_H
#define GSM_UTILS_H
#include <sys/types.h>
int gsm_7bit_decode(char *decoded, const u_int8_t *user_data, u_int8_t length);
int gsm_7bit_encode(u_int8_t *result, const char *data);
int ms_pwr_ctl_lvl(enum gsm_band band, unsigned int dbm);
int ms_pwr_dbm(enum gsm_band band, u_int8_t lvl);
/* According to TS 08.05 Chapter 8.1.4 */
int rxlev2dbm(u_int8_t rxlev);
u_int8_t dbm2rxlev(int dbm);
void generate_backtrace();
#endif

View File

@@ -2,10 +2,6 @@
#define _IPACCESS_H
#include "e1_input.h"
#include <osmocore/linuxlist.h>
#define IPA_TCP_PORT_OML 3002
#define IPA_TCP_PORT_RSL 3003
struct ipaccess_head {
u_int16_t len; /* network byte order */
@@ -49,59 +45,5 @@ int ipaccess_rcvmsg_base(struct msgb *msg, struct bsc_fd *bfd);
struct msgb *ipaccess_read_msg(struct bsc_fd *bfd, int *error);
void ipaccess_prepend_header(struct msgb *msg, int proto);
int ipaccess_send_id_ack(int fd);
int ipaccess_send_id_req(int fd);
int ipaccess_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len);
/*
* Firmware specific header
*/
struct sdp_firmware {
char magic[4];
char more_magic[2];
u_int16_t more_more_magic;
u_int32_t header_length;
u_int32_t file_length;
char sw_part[20];
char text1[64];
char time[12];
char date[14];
char text2[10];
char version[20];
u_int16_t table_offset;
/* stuff i don't know */
} __attribute__((packed));
struct sdp_header_entry {
u_int16_t something1;
char text1[64];
char time[12];
char date[14];
char text2[10];
char version[20];
u_int32_t length;
u_int32_t addr1;
u_int32_t addr2;
u_int32_t start;
} __attribute__((packed));
struct sdp_header_item {
struct sdp_header_entry header_entry;
struct llist_head entry;
off_t absolute_offset;
};
struct sdp_header {
struct sdp_firmware firmware_info;
/* for more_magic a list of sdp_header_entry_list */
struct llist_head header_list;
/* the entry of the sdp_header */
struct llist_head entry;
};
int ipaccess_analyze_file(int fd, const unsigned int st_size, const unsigned base_offset, struct llist_head *list);
#endif /* _IPACCESS_H */

View File

@@ -7,7 +7,6 @@
struct gsm_meas_rep_cell {
u_int8_t rxlev;
u_int8_t bsic;
u_int8_t neigh_idx;
u_int16_t arfcn;
unsigned int flags;
};

View File

@@ -1,8 +1,8 @@
/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
/*
* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2010 by On-Waves
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009 by on-waves.com
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -21,15 +21,6 @@
*
*/
#ifndef OPENBSC_MGCP_H
#define OPENBSC_MGCP_H
#include <osmocore/msgb.h>
#include <arpa/inet.h>
#define RTP_PORT_DEFAULT 4000
/**
* Calculate the RTP audio port for the given multiplex
* and the direction. This allows a semi static endpoint
@@ -49,74 +40,7 @@
* network and BTS.
*
*/
static inline int rtp_calculate_port(int multiplex, int base)
int rtp_calculate_port(int multiplex, int base)
{
return base + (multiplex * 2);
}
/*
* Handling of MGCP Endpoints and the MGCP Config
*/
struct mgcp_endpoint;
struct mgcp_config;
#define MGCP_ENDP_CRCX 1
#define MGCP_ENDP_DLCX 2
#define MGCP_ENDP_MDCX 3
/*
* what to do with the msg?
* - continue as usual?
* - reject and send a failure code?
* - defer? do not send anything
*/
#define MGCP_POLICY_CONT 4
#define MGCP_POLICY_REJECT 5
#define MGCP_POLICY_DEFER 6
typedef int (*mgcp_change)(struct mgcp_config *cfg, int endpoint, int state, int local_rtp);
typedef int (*mgcp_policy)(struct mgcp_config *cfg, int endpoint, int state, const char *transactio_id);
struct mgcp_config {
int source_port;
char *local_ip;
char *source_addr;
unsigned int number_endpoints;
char *bts_ip;
struct in_addr bts_in;
char *audio_name;
int audio_payload;
int audio_loop;
int early_bind;
int rtp_base_port;
char *forward_ip;
int forward_port;
mgcp_change change_cb;
mgcp_policy policy_cb;
void *data;
struct mgcp_endpoint *endpoints;
unsigned int last_call_id;
};
/* config management */
struct mgcp_config *mgcp_config_alloc(void);
int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg);
int mgcp_vty_init(void);
int mgcp_endpoints_allocate(struct mgcp_config *cfg);
int mgcp_bind_rtp_port(struct mgcp_endpoint *endp, int rtp_port);
void mgcp_free_endp(struct mgcp_endpoint *endp);
/*
* format helper functions
*/
struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg);
struct msgb *mgcp_create_rsip(void);
struct msgb *mgcp_create_response_with_data(int code, const char *msg, const char *trans, const char *data);
#endif

View File

@@ -1,64 +0,0 @@
/* MGCP Private Data */
/*
* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2010 by On-Waves
* 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 2 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#ifndef OPENBSC_MGCP_DATA_H
#define OPENBSC_MGCP_DATA_H
#include <osmocore/select.h>
#define CI_UNUSED 0
struct mgcp_endpoint {
int ci;
char *callid;
char *local_options;
int conn_mode;
int bts_payload_type;
int net_payload_type;
/* the local rtp port we are binding to */
int rtp_port;
/*
* RTP mangling:
* - we get RTP and RTCP to us and need to forward to the BTS
* - we get RTP and RTCP from the BTS and forward to the network
*/
struct bsc_fd local_rtp;
struct bsc_fd local_rtcp;
struct in_addr remote;
struct in_addr bts;
/* in network byte order */
int net_rtp, net_rtcp;
int bts_rtp, bts_rtcp;
/* backpointer */
struct mgcp_config *cfg;
};
#define ENDPOINT_NUMBER(endp) abs(endp - endp->cfg->endpoints)
#endif

View File

@@ -25,8 +25,7 @@
#ifndef _MNCC_H
#define _MNCC_H
#include <osmocore/linuxlist.h>
#include <osmocore/mncc.h>
#include <openbsc/linuxlist.h>
/* One end of a call */
struct gsm_call {
@@ -110,6 +109,69 @@ struct gsm_call {
#define MNCC_F_KEYPAD 0x1000
#define MNCC_F_SIGNAL 0x2000
/* Expanded fields from GSM TS 04.08, Table 10.5.102 */
struct gsm_mncc_bearer_cap {
int transfer; /* Information Transfer Capability */
int mode; /* Transfer Mode */
int coding; /* Coding Standard */
int radio; /* Radio Channel Requirement */
int speech_ctm; /* CTM text telephony indication */
int speech_ver[8]; /* Speech version indication */
};
struct gsm_mncc_number {
int type;
int plan;
int present;
int screen;
char number[33];
};
struct gsm_mncc_cause {
int location;
int coding;
int rec;
int rec_val;
int value;
int diag_len;
char diag[32];
};
struct gsm_mncc_useruser {
int proto;
char info[GSM_MAX_USERUSER + 1]; /* + termination char */
};
struct gsm_mncc_progress {
int coding;
int location;
int descr;
};
struct gsm_mncc_facility {
int len;
char info[GSM_MAX_FACILITY];
};
struct gsm_mncc_ssversion {
int len;
char info[GSM_MAX_SSVERSION];
};
struct gsm_mncc_cccap {
int dtmf;
int pcp;
};
enum {
GSM_MNCC_BCAP_SPEECH = 0,
GSM_MNCC_BCAP_UNR_DIG = 1,
GSM_MNCC_BCAP_AUDIO = 2,
GSM_MNCC_BCAP_FAX_G3 = 3,
GSM_MNCC_BCAP_OTHER_ITC = 5,
GSM_MNCC_BCAP_RESERVED = 7,
};
struct gsm_mncc {
/* context based information */
u_int32_t msg_type;

View File

@@ -20,8 +20,7 @@
*
*/
#include <stdint.h>
#include "linuxlist.h"
#include <openbsc/linuxlist.h>
struct bts_link;
@@ -35,26 +34,13 @@ struct msgb {
struct gsm_bts_trx *trx;
struct gsm_lchan *lchan;
/* the Layer1 header (if any) */
unsigned char *l1h;
/* the A-bis layer 2 header: OML, RSL(RLL), NS */
unsigned char *l2h;
/* the layer 3 header. For OML: FOM; RSL: 04.08; GPRS: BSSGP */
unsigned char *l3h;
unsigned char *smsh;
unsigned char *l4h;
/* the layer 4 header */
union {
unsigned char *smsh;
unsigned char *llch;
unsigned char *l4h;
};
/* the layer 5 header, GPRS: GMM header */
unsigned char *gmmh;
uint32_t tlli;
uint16_t data_len;
uint16_t len;
u_int16_t data_len;
u_int16_t len;
unsigned char *head;
unsigned char *tail;
@@ -62,30 +48,25 @@ struct msgb {
unsigned char _data[0];
};
extern struct msgb *msgb_alloc(uint16_t size, const char *name);
extern struct msgb *msgb_alloc(u_int16_t size, const char *name);
extern void msgb_free(struct msgb *m);
extern void msgb_enqueue(struct llist_head *queue, struct msgb *msg);
extern struct msgb *msgb_dequeue(struct llist_head *queue);
extern void msgb_reset(struct msgb *m);
#define msgb_l1(m) ((void *)(m->l1h))
#define msgb_l2(m) ((void *)(m->l2h))
#define msgb_l3(m) ((void *)(m->l3h))
#define msgb_l4(m) ((void *)(m->l4h))
#define msgb_sms(m) ((void *)(m->smsh))
static inline unsigned int msgb_l1len(const struct msgb *msgb)
{
return msgb->tail - (uint8_t *)msgb_l1(msgb);
}
static inline unsigned int msgb_l2len(const struct msgb *msgb)
{
return msgb->tail - (uint8_t *)msgb_l2(msgb);
return msgb->tail - (u_int8_t *)msgb_l2(msgb);
}
static inline unsigned int msgb_l3len(const struct msgb *msgb)
{
return msgb->tail - (uint8_t *)msgb_l3(msgb);
return msgb->tail - (u_int8_t *)msgb_l3(msgb);
}
static inline unsigned int msgb_headlen(const struct msgb *msgb)
@@ -99,47 +80,6 @@ static inline unsigned char *msgb_put(struct msgb *msgb, unsigned int len)
msgb->len += len;
return tmp;
}
static inline void msgb_put_u8(struct msgb *msgb, uint8_t word)
{
uint8_t *space = msgb_put(msgb, 1);
space[0] = word & 0xFF;
}
static inline void msgb_put_u16(struct msgb *msgb, uint16_t word)
{
uint8_t *space = msgb_put(msgb, 2);
space[0] = word >> 8 & 0xFF;
space[1] = word & 0xFF;
}
static inline void msgb_put_u32(struct msgb *msgb, uint32_t word)
{
uint8_t *space = msgb_put(msgb, 4);
space[0] = word >> 24 & 0xFF;
space[1] = word >> 16 & 0xFF;
space[2] = word >> 8 & 0xFF;
space[3] = word & 0xFF;
}
static inline unsigned char *msgb_get(struct msgb *msgb, unsigned int len)
{
unsigned char *tmp = msgb->data;
msgb->data += len;
msgb->len -= len;
return tmp;
}
static inline uint8_t msgb_get_u8(struct msgb *msgb)
{
uint8_t *space = msgb_get(msgb, 1);
return space[0];
}
static inline uint16_t msgb_get_u16(struct msgb *msgb)
{
uint8_t *space = msgb_get(msgb, 2);
return space[0] << 8 | space[1];
}
static inline uint32_t msgb_get_u32(struct msgb *msgb)
{
uint8_t *space = msgb_get(msgb, 4);
return space[0] << 24 | space[1] << 16 | space[2] << 8 | space[3];
}
static inline unsigned char *msgb_push(struct msgb *msgb, unsigned int len)
{
msgb->data -= len;
@@ -153,7 +93,7 @@ static inline unsigned char *msgb_pull(struct msgb *msgb, unsigned int len)
}
static inline int msgb_tailroom(const struct msgb *msgb)
{
return (msgb->head + msgb->data_len) - msgb->tail;
return (msgb->data + msgb->data_len) - msgb->tail;
}
/* increase the headroom of an empty msgb, reducing the tailroom */

View File

@@ -24,10 +24,10 @@
#include <stdlib.h>
#include <string.h>
#include <osmocore/linuxlist.h>
#include "linuxlist.h"
#include "gsm_data.h"
#include "gsm_subscriber.h"
#include <osmocore/timer.h>
#include "timer.h"
/* call once for every gsm_bts... */
void paging_init(struct gsm_bts *bts);

View File

@@ -25,8 +25,8 @@
#include <netinet/in.h>
#include <osmocore/linuxlist.h>
#include <osmocore/select.h>
#include <openbsc/linuxlist.h>
#include <openbsc/select.h>
enum rtp_rx_action {
RTP_NONE,

View File

@@ -1,7 +1,7 @@
#ifndef _BSC_SELECT_H
#define _BSC_SELECT_H
#include "linuxlist.h"
#include <openbsc/linuxlist.h>
#define BSC_FD_READ 0x0001
#define BSC_FD_WRITE 0x0002

View File

@@ -28,7 +28,6 @@
#include <openbsc/gsm_data.h>
#include <openbsc/gsm_subscriber.h>
#include <osmocore/signal.h>
/*
* Signalling subsystems
@@ -46,8 +45,7 @@ enum signal_subsystems {
/* SS_PAGING signals */
enum signal_paging {
S_PAGING_SUCCEEDED,
S_PAGING_EXPIRED,
S_PAGING_COMPLETED,
};
/* SS_SMS signals */
@@ -71,9 +69,6 @@ enum signal_nm {
S_NM_FAIL_REP, /* GSM 12.21 failure event report */
S_NM_NACK, /* GSM 12.21 various NM_MT_*_NACK happened */
S_NM_IPACC_NACK, /* GSM 12.21 nanoBTS extensions NM_MT_IPACC_*_*_NACK happened */
S_NM_IPACC_ACK, /* GSM 12.21 nanoBTS extensions NM_MT_IPACC_*_*_ACK happened */
S_NM_IPACC_RESTART_ACK, /* nanoBTS has send a restart ack */
S_NM_IPACC_RESTART_NACK,/* nanoBTS has send a restart ack */
S_NM_TEST_REP, /* GSM 12.21 Test Report */
};
@@ -111,6 +106,9 @@ enum signal_global {
S_GLOBAL_SHUTDOWN,
};
typedef int signal_cbfn(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data);
struct paging_signal_data {
struct gsm_subscriber *subscr;
struct gsm_bts *bts;
@@ -125,9 +123,12 @@ struct scall_signal_data {
void *data;
};
struct ipacc_ack_signal_data {
struct gsm_bts *bts;
u_int8_t msg_type;
};
/* Management */
int register_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data);
void unregister_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data);
/* Dispatch */
void dispatch_signal(unsigned int subsys, unsigned int signal, void *signal_data);
#endif

View File

@@ -1,10 +1,7 @@
#ifndef _SILENT_CALL_H
#define _SILENT_CALL_H
extern int gsm_silent_call_start(struct gsm_subscriber *subscr,
void *data, int type);
extern int gsm_silent_call_start(struct gsm_subscriber *subscr, void *data);
extern int gsm_silent_call_stop(struct gsm_subscriber *subscr);
extern int silent_call_rx(struct msgb *msg);
extern int silent_call_reroute(struct msgb *msg);
#endif /* _SILENT_CALL_H */

View File

@@ -22,7 +22,7 @@
*/
#include <sys/types.h>
#include <osmocore/linuxlist.h>
#include <openbsc/linuxlist.h>
#define NR_SUBCH 4
#define TRAU_FRAME_SIZE 40

View File

@@ -22,17 +22,19 @@
#define TELNET_INTERFACE_H
#include "gsm_data.h"
#include "debug.h"
#include <osmocore/select.h>
#include "linuxlist.h"
#include "select.h"
#include <vty/vty.h>
#define TELNET_COMMAND_48 1
#define TELNET_COMMAND_11 2
struct telnet_connection {
struct llist_head entry;
struct gsm_network *network;
struct bsc_fd fd;
struct vty *vty;
struct debug_target *dbg;
};

View File

@@ -0,0 +1,221 @@
#ifndef _TLV_H
#define _TLV_H
#include <sys/types.h>
#include <string.h>
#include <openbsc/msgb.h>
/* Terminology / wording
tag length value (in bits)
V - - 8
LV - 8 N * 8
TLV 8 8 N * 8
TL16V 8 16 N * 8
TLV16 8 8 N * 16
TvLV 8 8/16 N * 8
*/
#define LV_GROSS_LEN(x) (x+1)
#define TLV_GROSS_LEN(x) (x+2)
#define TLV16_GROSS_LEN(x) ((2*x)+2)
#define TL16V_GROSS_LEN(x) (x+3)
#define TVLV_MAX_ONEBYTE 0x7f
static inline u_int16_t TVLV_GROSS_LEN(u_int16_t len)
{
if (len <= TVLV_MAX_ONEBYTE)
return TLV_GROSS_LEN(len);
else
return TL16V_GROSS_LEN(len);
}
/* TLV generation */
static inline u_int8_t *lv_put(u_int8_t *buf, u_int8_t len,
const u_int8_t *val)
{
*buf++ = len;
memcpy(buf, val, len);
return buf + len;
}
static inline u_int8_t *tlv_put(u_int8_t *buf, u_int8_t tag, u_int8_t len,
const u_int8_t *val)
{
*buf++ = tag;
*buf++ = len;
memcpy(buf, val, len);
return buf + len;
}
static inline u_int8_t *tlv16_put(u_int8_t *buf, u_int8_t tag, u_int8_t len,
const u_int16_t *val)
{
*buf++ = tag;
*buf++ = len;
memcpy(buf, val, len*2);
return buf + len*2;
}
static inline u_int8_t *tl16v_put(u_int8_t *buf, u_int8_t tag, u_int16_t len,
const u_int8_t *val)
{
*buf++ = tag;
*buf++ = len >> 8;
*buf++ = len & 0xff;
memcpy(buf, val, len);
return buf + len*2;
}
static inline u_int8_t *tvlv_put(u_int8_t *buf, u_int8_t tag, u_int16_t len,
const u_int8_t *val)
{
u_int8_t *ret;
if (len <= TVLV_MAX_ONEBYTE) {
ret = tlv_put(buf, tag, len, val);
buf[1] |= 0x80;
} else
ret = tl16v_put(buf, tag, len, val);
return ret;
}
static inline u_int8_t *msgb_tlv16_put(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int16_t *val)
{
u_int8_t *buf = msgb_put(msg, TLV16_GROSS_LEN(len));
return tlv16_put(buf, tag, len, val);
}
static inline u_int8_t *msgb_tl16v_put(struct msgb *msg, u_int8_t tag, u_int16_t len,
const u_int8_t *val)
{
u_int8_t *buf = msgb_put(msg, TL16V_GROSS_LEN(len));
return tl16v_put(buf, tag, len, val);
}
static inline u_int8_t *msgb_tvlv_put(struct msgb *msg, u_int8_t tag, u_int16_t len,
const u_int8_t *val)
{
u_int8_t *buf = msgb_put(msg, TVLV_GROSS_LEN(len));
return tvlv_put(buf, tag, len, val);
}
static inline u_int8_t *v_put(u_int8_t *buf, u_int8_t val)
{
*buf++ = val;
return buf;
}
static inline u_int8_t *tv_put(u_int8_t *buf, u_int8_t tag,
u_int8_t val)
{
*buf++ = tag;
*buf++ = val;
return buf;
}
/* 'val' is still in host byte order! */
static inline u_int8_t *tv16_put(u_int8_t *buf, u_int8_t tag,
u_int16_t val)
{
*buf++ = tag;
*buf++ = val >> 8;
*buf++ = val & 0xff;
return buf;
}
static inline u_int8_t *msgb_lv_put(struct msgb *msg, u_int8_t len, const u_int8_t *val)
{
u_int8_t *buf = msgb_put(msg, LV_GROSS_LEN(len));
return lv_put(buf, len, val);
}
static inline u_int8_t *msgb_tlv_put(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int8_t *val)
{
u_int8_t *buf = msgb_put(msg, TLV_GROSS_LEN(len));
return tlv_put(buf, tag, len, val);
}
static inline u_int8_t *msgb_tv_put(struct msgb *msg, u_int8_t tag, u_int8_t val)
{
u_int8_t *buf = msgb_put(msg, 2);
return tv_put(buf, tag, val);
}
static inline u_int8_t *msgb_v_put(struct msgb *msg, u_int8_t val)
{
u_int8_t *buf = msgb_put(msg, 1);
return v_put(buf, val);
}
static inline u_int8_t *msgb_tv16_put(struct msgb *msg, u_int8_t tag, u_int16_t val)
{
u_int8_t *buf = msgb_put(msg, 3);
return tv16_put(buf, tag, val);
}
static inline u_int8_t *msgb_tlv_push(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int8_t *val)
{
u_int8_t *buf = msgb_push(msg, TLV_GROSS_LEN(len));
return tlv_put(buf, tag, len, val);
}
static inline u_int8_t *msgb_tv_push(struct msgb *msg, u_int8_t tag, u_int8_t val)
{
u_int8_t *buf = msgb_push(msg, 2);
return tv_put(buf, tag, val);
}
static inline u_int8_t *msgb_tv16_push(struct msgb *msg, u_int8_t tag, u_int16_t val)
{
u_int8_t *buf = msgb_push(msg, 3);
return tv16_put(buf, tag, val);
}
/* TLV parsing */
struct tlv_p_entry {
u_int16_t len;
const u_int8_t *val;
};
enum tlv_type {
TLV_TYPE_FIXED,
TLV_TYPE_T,
TLV_TYPE_TV,
TLV_TYPE_TLV,
TLV_TYPE_TL16V,
TLV_TYPE_TvLV,
};
struct tlv_def {
enum tlv_type type;
u_int8_t fixed_len;
};
struct tlv_definition {
struct tlv_def def[0xff];
};
struct tlv_parsed {
struct tlv_p_entry lv[0xff];
};
extern struct tlv_definition tvlv_att_def;
int tlv_parse_one(u_int8_t *o_tag, u_int16_t *o_len, const u_int8_t **o_val,
const struct tlv_definition *def,
const u_int8_t *buf, int buf_len);
int tlv_parse(struct tlv_parsed *dec, const struct tlv_definition *def,
const u_int8_t *buf, int buf_len, u_int8_t lv_tag, u_int8_t lv_tag2);
#define TLVP_PRESENT(x, y) ((x)->lv[y].val)
#define TLVP_LEN(x, y) (x)->lv[y].len
#define TLVP_VAL(x, y) (x)->lv[y].val
#endif /* _TLV_H */

View File

@@ -3,7 +3,7 @@
#include <openbsc/gsm_data.h>
#include <openbsc/gsm_subscriber.h>
#include <osmocore/linuxlist.h>
#include <openbsc/linuxlist.h>
#include <openbsc/gsm_04_11.h>
/* One transaction */

View File

@@ -3,7 +3,7 @@
/* Handler function for mobile-originated USSD messages */
#include <osmocore/msgb.h>
#include <openbsc/msgb.h>
int handle_rcv_ussd(struct msgb *msg);

View File

@@ -1,2 +1 @@
sccp_HEADERS = sccp_types.h sccp.h
sccpdir = $(includedir)/sccp
noinst_HEADERS = sccp_types.h sccp.h

View File

@@ -27,11 +27,11 @@
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <openbsc/msgb.h>
#include "sccp_types.h"
struct msgb;
struct sccp_system;
enum {

View File

@@ -24,8 +24,6 @@
#ifndef SCCP_TYPES_H
#define SCCP_TYPES_H
#include <endian.h>
/* Table 1/Q.713 - SCCP message types */
enum sccp_message_types {
SCCP_MSG_TYPE_CR = 1,
@@ -89,19 +87,11 @@ enum {
};
struct sccp_called_party_address {
#if __BYTE_ORDER == __LITTLE_ENDIAN
u_int8_t point_code_indicator : 1,
ssn_indicator : 1,
global_title_indicator : 4,
routing_indicator : 1,
reserved : 1;
#elif __BYTE_ORDER == __BIG_ENDIAN
u_int8_t reserved : 1,
routing_indicator : 1,
global_title_indicator : 4,
ssn_indicator : 1,
point_code_indicator : 1;
#endif
u_int8_t data[0];
} __attribute__((packed));
@@ -110,13 +100,8 @@ struct sccp_called_party_address {
/* Figure 6/Q.713 */
struct sccp_signalling_point_code {
u_int8_t lsb;
#if __BYTE_ORDER == __LITTLE_ENDIAN
u_int8_t msb : 6,
reserved : 2;
#elif __BYTE_ORDER == __BIG_ENDIAN
u_int8_t reserved : 2,
msb : 6;
#endif
} __attribute__((packed));
/* SSN == subsystem number */
@@ -152,13 +137,8 @@ enum {
};
struct sccp_global_title {
#if __BYTE_ORDER == __LITTLE_ENDIAN
u_int8_t nature_of_addr_ind : 7,
odd_even : 1;
#elif __BYTE_ORDER == __BIG_ENDIAN
u_int8_t odd_even : 1,
nature_of_addr_ind : 7;
#endif
u_int8_t data[0];
} __attribute__((packed));

View File

@@ -356,6 +356,4 @@ void host_config_set(const char *);
void print_version(const char *);
extern void *tall_vty_cmd_ctx;
#endif /* _ZEBRA_COMMAND_H */

View File

@@ -59,6 +59,4 @@ vector vector_copy(vector v);
void *vector_lookup(vector, unsigned int);
void *vector_lookup_ensure(vector, unsigned int);
extern void *tall_vty_vec_ctx;
#endif /* _ZEBRA_VECTOR_H */

View File

@@ -1,10 +0,0 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: OpenBSC SCCP Lib
Description: OpenBSC SCCP Lib
Version: @VERSION@
Libs: -L${libdir} -lsccp
Cflags: -I${includedir}/

View File

@@ -1,7 +1,7 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@/
includedir=@includedir@/openbsc-1.0
Name: OpenBSC
Description: OpenBSC base station controller

View File

@@ -1,28 +1,23 @@
INCLUDES = $(all_includes) -I$(top_srcdir)/include
AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS)
AM_LDFLAGS = $(LIBOSMOCORE_LIBS)
AM_CFLAGS=-Wall
sbin_PROGRAMS = bsc_hack bs11_config ipaccess-find ipaccess-config \
isdnsync bsc_mgcp ipaccess-proxy
noinst_LIBRARIES = libbsc.a libmsc.a libvty.a
isdnsync bsc_mgcp bsc_msc_ip bsc_nat
noinst_LIBRARIES = libbsc.a libmsc.a libvty.a libsccp.a
noinst_HEADERS = vty/cardshell.h
bscdir = $(libdir)
bsc_LIBRARIES = libsccp.a
libbsc_a_SOURCES = abis_rsl.c abis_nm.c gsm_data.c gsm_04_08_utils.c \
chan_alloc.c debug.c \
msgb.c select.c chan_alloc.c timer.c debug.c \
gsm_subscriber_base.c subchan_demux.c bsc_rll.c transaction.c \
trau_frame.c trau_mux.c paging.c e1_config.c e1_input.c \
input/misdn.c input/ipaccess.c \
talloc_ctx.c system_information.c rest_octets.c \
rtp_proxy.c bts_siemens_bs11.c bts_ipaccess_nanobts.c \
bts_unknown.c
trau_frame.c trau_mux.c paging.c e1_config.c e1_input.c tlv_parser.c \
input/misdn.c input/ipaccess.c signal.c gsm_utils.c talloc.c \
talloc_ctx.c system_information.c bitvec.c rest_octets.c \
rtp_proxy.c telnet_interface.c
libmsc_a_SOURCES = gsm_subscriber.c db.c telnet_interface.c \
libmsc_a_SOURCES = gsm_subscriber.c db.c \
mncc.c gsm_04_08.c gsm_04_11.c transaction.c \
token_auth.c rrlp.c gsm_04_80.c ussd.c silent_call.c \
handover_logic.c handover_decision.c meas_rep.c
handover_logic.c handover_decision.c meas_rep.c
libvty_a_SOURCES = vty/buffer.c vty/command.c vty/vector.c vty/vty.c
@@ -31,18 +26,22 @@ libsccp_a_SOURCES = sccp/sccp.c
bsc_hack_SOURCES = bsc_hack.c bsc_init.c vty_interface.c vty_interface_layer3.c
bsc_hack_LDADD = libmsc.a libbsc.a libmsc.a libvty.a -ldl -ldbi $(LIBCRYPT)
bs11_config_SOURCES = bs11_config.c abis_nm.c gsm_data.c debug.c \
rs232.c bts_siemens_bs11.c
bsc_msc_ip_SOURCES = bssap.c bsc_msc_ip.c bsc_init.c vty_interface.c vty_interface_bsc.c \
bsc_msc.c
bsc_msc_ip_LDADD = libbsc.a libvty.a libsccp.a
ipaccess_find_SOURCES = ipaccess/ipaccess-find.c
bs11_config_SOURCES = bs11_config.c abis_nm.c gsm_data.c msgb.c debug.c \
select.c timer.c rs232.c tlv_parser.c signal.c talloc.c
ipaccess_config_SOURCES = ipaccess/ipaccess-config.c ipaccess/ipaccess-firmware.c
ipaccess_find_SOURCES = ipaccess-find.c select.c timer.c
ipaccess_config_SOURCES = ipaccess-config.c
ipaccess_config_LDADD = libbsc.a libmsc.a libbsc.a libvty.a -ldl -ldbi $(LIBCRYPT)
isdnsync_SOURCES = isdnsync.c
bsc_mgcp_SOURCES = mgcp/mgcp_main.c mgcp/mgcp_protocol.c mgcp/mgcp_network.c mgcp/mgcp_vty.c \
debug.c telnet_interface.c
bsc_mgcp_SOURCES = bsc_mgcp.c msgb.c talloc.c debug.c select.c timer.c telnet_interface.c
bsc_mgcp_LDADD = libvty.a
ipaccess_proxy_SOURCES = ipaccess/ipaccess-proxy.c debug.c
bsc_nat_SOURCES = nat/bsc_nat.c nat/bsc_filter.c bsc_msc.c
bsc_nat_LDADD = libbsc.a libsccp.a

View File

@@ -38,16 +38,15 @@
#include <openbsc/gsm_data.h>
#include <openbsc/debug.h>
#include <osmocore/msgb.h>
#include <osmocore/tlv.h>
#include <osmocore/talloc.h>
#include <openbsc/msgb.h>
#include <openbsc/tlv.h>
#include <openbsc/abis_nm.h>
#include <openbsc/misdn.h>
#include <openbsc/signal.h>
#include <openbsc/talloc.h>
#define OM_ALLOC_SIZE 1024
#define OM_HEADROOM_SIZE 128
#define IPACC_SEGMENT_SIZE 245
/* unidirectional messages from BTS to BSC */
static const enum abis_nm_msgtype reports[] = {
@@ -264,7 +263,7 @@ static const enum abis_nm_attr nm_att_settable[] = {
NM_ATT_MEAS_TYPE,
};
const struct tlv_definition nm_att_tlvdef = {
static const struct tlv_definition nm_att_tlvdef = {
.def = {
[NM_ATT_ABIS_CHANNEL] = { TLV_TYPE_FIXED, 3 },
[NM_ATT_ADD_INFO] = { TLV_TYPE_TL16V },
@@ -330,6 +329,77 @@ const struct tlv_definition nm_att_tlvdef = {
[NM_ATT_HW_CONF_CHG] = { TLV_TYPE_TL16V },
[NM_ATT_OUTST_ALARM] = { TLV_TYPE_TV },
[NM_ATT_MEAS_RES] = { TLV_TYPE_TL16V },
/* BS11 specifics */
[NM_ATT_BS11_ESN_FW_CODE_NO] = { TLV_TYPE_TLV },
[NM_ATT_BS11_ESN_HW_CODE_NO] = { TLV_TYPE_TLV },
[NM_ATT_BS11_ESN_PCB_SERIAL] = { TLV_TYPE_TLV },
[NM_ATT_BS11_BOOT_SW_VERS] = { TLV_TYPE_TLV },
[0xd5] = { TLV_TYPE_TLV },
[0xa8] = { TLV_TYPE_TLV },
[NM_ATT_BS11_PASSWORD] = { TLV_TYPE_TLV },
[NM_ATT_BS11_TXPWR] = { TLV_TYPE_TLV },
[NM_ATT_BS11_RSSI_OFFS] = { TLV_TYPE_TLV },
[NM_ATT_BS11_LINE_CFG] = { TLV_TYPE_TV },
[NM_ATT_BS11_L1_PROT_TYPE] = { TLV_TYPE_TV },
[NM_ATT_BS11_BIT_ERR_THESH] = { TLV_TYPE_FIXED, 2 },
[NM_ATT_BS11_DIVERSITY] = { TLV_TYPE_TLV },
[NM_ATT_BS11_LMT_LOGON_SESSION]={ TLV_TYPE_TLV },
[NM_ATT_BS11_LMT_LOGIN_TIME] = { TLV_TYPE_TLV },
[NM_ATT_BS11_LMT_USER_ACC_LEV] ={ TLV_TYPE_TLV },
[NM_ATT_BS11_LMT_USER_NAME] = { TLV_TYPE_TLV },
[NM_ATT_BS11_BTS_STATE] = { TLV_TYPE_TLV },
[NM_ATT_BS11_E1_STATE] = { TLV_TYPE_TLV },
[NM_ATT_BS11_PLL_MODE] = { TLV_TYPE_TLV },
[NM_ATT_BS11_PLL] = { TLV_TYPE_TLV },
[NM_ATT_BS11_CCLK_ACCURACY] = { TLV_TYPE_TV },
[NM_ATT_BS11_CCLK_TYPE] = { TLV_TYPE_TV },
/* ip.access specifics */
[NM_ATT_IPACC_DST_IP] = { TLV_TYPE_FIXED, 4 },
[NM_ATT_IPACC_DST_IP_PORT] = { TLV_TYPE_FIXED, 2 },
[NM_ATT_IPACC_STREAM_ID] = { TLV_TYPE_TV, },
[NM_ATT_IPACC_FREQ_CTRL] = { TLV_TYPE_TV, },
[NM_ATT_IPACC_SEC_OML_CFG] = { TLV_TYPE_FIXED, 6 },
[NM_ATT_IPACC_IP_IF_CFG] = { TLV_TYPE_FIXED, 8 },
[NM_ATT_IPACC_IP_GW_CFG] = { TLV_TYPE_FIXED, 12 },
[NM_ATT_IPACC_IN_SERV_TIME] = { TLV_TYPE_FIXED, 4 },
[NM_ATT_IPACC_LOCATION] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_PAGING_CFG] = { TLV_TYPE_FIXED, 2 },
[NM_ATT_IPACC_UNIT_ID] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_UNIT_NAME] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_SNMP_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_PRIM_OML_CFG_LIST] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_NV_FLAGS] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_FREQ_CTRL] = { TLV_TYPE_FIXED, 2 },
[NM_ATT_IPACC_PRIM_OML_FB_TOUT] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_CUR_SW_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_TIMING_BUS] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_CGI] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_RAC] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_OBJ_VERSION] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_GPRS_PAGING_CFG]= { TLV_TYPE_TL16V },
[NM_ATT_IPACC_NSEI] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_BVCI] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_NSVCI] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_NS_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_BSSGP_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_NS_LINK_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_RLC_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_ALM_THRESH_LIST]= { TLV_TYPE_TL16V },
[NM_ATT_IPACC_MONIT_VAL_LIST] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_TIB_CONTROL] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_SUPP_FEATURES] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_CODING_SCHEMES] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_RLC_CFG_2] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_HEARTB_TOUT] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_UPTIME] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_RLC_CFG_3] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_SSL_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_SEC_POSSIBLE] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_IML_SSL_STATE] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_REVOC_DATE] = { TLV_TYPE_TL16V },
//[0x95] = { TLV_TYPE_FIXED, 2 },
[0x85] = { TLV_TYPE_TV },
},
};
@@ -352,11 +422,9 @@ int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan)
return -EINVAL;
}
int abis_nm_tlv_parse(struct tlv_parsed *tp, struct gsm_bts *bts, const u_int8_t *buf, int len)
int abis_nm_tlv_parse(struct tlv_parsed *tp, const u_int8_t *buf, int len)
{
if (!bts->model)
return -EIO;
return tlv_parse(tp, &bts->model->nm_att_tlvdef, buf, len, 0, 0);
return tlv_parse(tp, &nm_att_tlvdef, buf, len, 0, 0);
}
static int is_in_arr(enum abis_nm_msgtype mt, const enum abis_nm_msgtype *arr, int size)
@@ -472,11 +540,11 @@ static const char *obj_class_name(u_int8_t oc)
const char *nm_opstate_name(u_int8_t os)
{
switch (os) {
case NM_OPSTATE_DISABLED:
case 1:
return "Disabled";
case NM_OPSTATE_ENABLED:
case 2:
return "Enabled";
case NM_OPSTATE_NULL:
case 0xff:
return "NULL";
default:
return "RFU";
@@ -530,13 +598,6 @@ const char *nm_adm_name(u_int8_t adm)
}
}
int nm_is_running(struct gsm_nm_state *s) {
return (s->operational == NM_OPSTATE_ENABLED) && (
(s->availability == NM_AVSTATE_OK) ||
(s->availability == 0xff)
);
}
static void debugp_foh(struct abis_om_fom_hdr *foh)
{
DEBUGP(DNM, "OC=%s(%02x) INST=(%02x,%02x,%02x) ",
@@ -732,7 +793,7 @@ static int abis_nm_rx_statechg_rep(struct msgb *mb)
new_state = *nm_state;
abis_nm_tlv_parse(&tp, bts, foh->data, oh->length-sizeof(*foh));
abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
if (TLVP_PRESENT(&tp, NM_ATT_OPER_STATE)) {
new_state.operational = *TLVP_VAL(&tp, NM_ATT_OPER_STATE);
DEBUGPC(DNM, "OP_STATE=%s ", nm_opstate_name(new_state.operational));
@@ -744,25 +805,19 @@ static int abis_nm_rx_statechg_rep(struct msgb *mb)
new_state.availability = *TLVP_VAL(&tp, NM_ATT_AVAIL_STATUS);
DEBUGPC(DNM, "AVAIL=%s(%02x) ", nm_avail_name(new_state.availability),
new_state.availability);
} else
new_state.availability = 0xff;
}
if (TLVP_PRESENT(&tp, NM_ATT_ADM_STATE)) {
new_state.administrative = *TLVP_VAL(&tp, NM_ATT_ADM_STATE);
DEBUGPC(DNM, "ADM=%2s ", nm_adm_name(new_state.administrative));
}
DEBUGPC(DNM, "\n");
if ((new_state.administrative != 0 && nm_state->administrative == 0) ||
new_state.operational != nm_state->operational ||
new_state.availability != nm_state->availability) {
if (memcmp(&new_state, nm_state, sizeof(new_state))) {
/* Update the operational state of a given object in our in-memory data
* structures and send an event to the higher layer */
void *obj = objclass2obj(bts, foh->obj_class, &foh->obj_inst);
rc = nm_state_event(EVT_STATECHG_OPER, foh->obj_class, obj, nm_state, &new_state);
nm_state->operational = new_state.operational;
nm_state->availability = new_state.availability;
if (nm_state->administrative == 0)
nm_state->administrative = new_state.administrative;
*nm_state = new_state;
}
#if 0
if (op_state == 1) {
@@ -784,7 +839,7 @@ static int rx_fail_evt_rep(struct msgb *mb)
DEBUGPC(DNM, "Failure Event Report ");
abis_nm_tlv_parse(&tp, mb->trx->bts, foh->data, oh->length-sizeof(*foh));
abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
if (TLVP_PRESENT(&tp, NM_ATT_EVENT_TYPE))
DEBUGPC(DNM, "Type=%s ", event_type_name(*TLVP_VAL(&tp, NM_ATT_EVENT_TYPE)));
@@ -856,21 +911,29 @@ static int abis_nm_rx_sw_act_req(struct msgb *mb)
const u_int8_t *sw_config;
int sw_config_len;
int file_id_len;
int nack = 0;
int ret;
debugp_foh(foh);
DEBUGPC(DNM, "SW Activate Request: ");
DEBUGP(DNM, "Software Activate Request, ACKing and Activating\n");
if (foh->obj_class >= 0xf0 && foh->obj_class <= 0xf3) {
DEBUGPC(DNM, "NACKing for GPRS obj_class 0x%02x\n", foh->obj_class);
nack = 1;
} else
DEBUGPC(DNM, "ACKing and Activating\n");
ret = abis_nm_sw_act_req_ack(mb->trx->bts, foh->obj_class,
foh->obj_inst.bts_nr,
foh->obj_inst.trx_nr,
foh->obj_inst.ts_nr, 0,
foh->obj_inst.ts_nr, nack,
foh->data, oh->length-sizeof(*foh));
abis_nm_tlv_parse(&tp, mb->trx->bts, foh->data, oh->length-sizeof(*foh));
if (nack)
return ret;
abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
sw_config = TLVP_VAL(&tp, NM_ATT_SW_CONFIG);
sw_config_len = TLVP_LEN(&tp, NM_ATT_SW_CONFIG);
if (!TLVP_PRESENT(&tp, NM_ATT_SW_CONFIG)) {
@@ -904,7 +967,7 @@ static int abis_nm_rx_chg_adm_state_ack(struct msgb *mb)
struct tlv_parsed tp;
u_int8_t adm_state;
abis_nm_tlv_parse(&tp, mb->trx->bts, foh->data, oh->length-sizeof(*foh));
abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
if (!TLVP_PRESENT(&tp, NM_ATT_ADM_STATE))
return -EINVAL;
@@ -920,7 +983,7 @@ static int abis_nm_rx_lmt_event(struct msgb *mb)
struct tlv_parsed tp;
DEBUGP(DNM, "LMT Event ");
abis_nm_tlv_parse(&tp, mb->trx->bts, foh->data, oh->length-sizeof(*foh));
abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
if (TLVP_PRESENT(&tp, NM_ATT_BS11_LMT_LOGON_SESSION) &&
TLVP_LEN(&tp, NM_ATT_BS11_LMT_LOGON_SESSION) >= 1) {
u_int8_t onoff = *TLVP_VAL(&tp, NM_ATT_BS11_LMT_LOGON_SESSION);
@@ -966,7 +1029,7 @@ static int abis_nm_rcvmsg_fom(struct msgb *mb)
else
DEBUGPC(DNM, "NACK 0x%02x ", mt);
abis_nm_tlv_parse(&tp, mb->trx->bts, foh->data, oh->length-sizeof(*foh));
abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
if (TLVP_PRESENT(&tp, NM_ATT_NACK_CAUSES))
DEBUGPC(DNM, "CAUSE=%s\n",
nack_cause_name(*TLVP_VAL(&tp, NM_ATT_NACK_CAUSES)));
@@ -980,11 +1043,13 @@ static int abis_nm_rcvmsg_fom(struct msgb *mb)
/* check if last message is to be acked */
if (is_ack_nack(nmh->last_msgtype)) {
if (mt == MT_ACK(nmh->last_msgtype)) {
DEBUGP(DNM, "received ACK (0x%x)\n", foh->msg_type);
fprintf(stderr, "received ACK (0x%x)\n",
foh->msg_type);
/* we got our ACK, continue sending the next msg */
} else if (mt == MT_NACK(nmh->last_msgtype)) {
/* we got a NACK, signal this to the caller */
DEBUGP(DNM, "received NACK (0x%x)\n", foh->msg_type);
fprintf(stderr, "received NACK (0x%x)\n",
foh->msg_type);
/* FIXME: somehow signal this to the caller */
} else {
/* really strange things happen */
@@ -1006,12 +1071,6 @@ static int abis_nm_rcvmsg_fom(struct msgb *mb)
case NM_MT_CONN_MDROP_LINK_ACK:
DEBUGP(DNM, "CONN MDROP LINK ACK\n");
break;
case NM_MT_IPACC_RESTART_ACK:
dispatch_signal(SS_NM, S_NM_IPACC_RESTART_ACK, NULL);
break;
case NM_MT_IPACC_RESTART_NACK:
dispatch_signal(SS_NM, S_NM_IPACC_RESTART_NACK, NULL);
break;
}
return 0;
@@ -1157,22 +1216,6 @@ struct abis_nm_sw {
static struct abis_nm_sw g_sw;
static void sw_add_file_id_and_ver(struct abis_nm_sw *sw, struct msgb *msg)
{
if (sw->bts->type == GSM_BTS_TYPE_NANOBTS) {
msgb_v_put(msg, NM_ATT_SW_DESCR);
msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id);
msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len,
sw->file_version);
} else if (sw->bts->type == GSM_BTS_TYPE_BS11) {
msgb_tlv_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id);
msgb_tlv_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len,
sw->file_version);
} else {
LOGP(DNM, LOGL_ERROR, "Please implement this for the BTS.\n");
}
}
/* 6.2.1 / 8.3.1: Load Data Initiate */
static int sw_load_init(struct abis_nm_sw *sw)
{
@@ -1184,8 +1227,11 @@ static int sw_load_init(struct abis_nm_sw *sw)
fill_om_fom_hdr(oh, len, NM_MT_LOAD_INIT, sw->obj_class,
sw->obj_instance[0], sw->obj_instance[1],
sw->obj_instance[2]);
sw_add_file_id_and_ver(sw, msg);
/* FIXME: this is BS11 specific format */
msgb_tlv_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id);
msgb_tlv_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len,
sw->file_version);
msgb_tv_put(msg, NM_ATT_WINDOW_SIZE, sw->window_size);
return abis_nm_sendmsg(sw->bts, msg);
@@ -1243,24 +1289,7 @@ static int sw_load_segment(struct abis_nm_sw *sw)
/* we only now know the exact length for the OM hdr */
len = strlen(line_buf)+2;
break;
case GSM_BTS_TYPE_NANOBTS: {
static_assert(sizeof(seg_buf) >= IPACC_SEGMENT_SIZE, buffer_big_enough);
len = read(sw->fd, &seg_buf, IPACC_SEGMENT_SIZE);
if (len < 0) {
perror("read failed");
return -EINVAL;
}
if (len != IPACC_SEGMENT_SIZE)
sw->last_seg = 1;
++sw->seg_in_window;
msgb_tl16v_put(msg, NM_ATT_IPACC_FILE_DATA, len, (const u_int8_t *) seg_buf);
len += 3;
break;
}
default:
LOGP(DNM, LOGL_ERROR, "sw_load_segment needs implementation for the BTS.\n");
/* FIXME: Other BTS types */
return -1;
}
@@ -1284,7 +1313,11 @@ static int sw_load_end(struct abis_nm_sw *sw)
sw->obj_instance[0], sw->obj_instance[1],
sw->obj_instance[2]);
sw_add_file_id_and_ver(sw, msg);
/* FIXME: this is BS11 specific format */
msgb_tlv_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id);
msgb_tlv_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len,
sw->file_version);
return abis_nm_sendmsg(sw->bts, msg);
}
@@ -1308,59 +1341,6 @@ static int sw_activate(struct abis_nm_sw *sw)
return abis_nm_sendmsg(sw->bts, msg);
}
struct sdp_firmware {
char magic[4];
char more_magic[4];
unsigned int header_length;
unsigned int file_length;
} __attribute__ ((packed));
static int parse_sdp_header(struct abis_nm_sw *sw)
{
struct sdp_firmware firmware_header;
int rc;
struct stat stat;
rc = read(sw->fd, &firmware_header, sizeof(firmware_header));
if (rc != sizeof(firmware_header)) {
LOGP(DNM, LOGL_ERROR, "Could not read SDP file header.\n");
return -1;
}
if (strncmp(firmware_header.magic, " SDP", 4) != 0) {
LOGP(DNM, LOGL_ERROR, "The magic number1 is wrong.\n");
return -1;
}
if (firmware_header.more_magic[0] != 0x10 ||
firmware_header.more_magic[1] != 0x02 ||
firmware_header.more_magic[2] != 0x00 ||
firmware_header.more_magic[3] != 0x00) {
LOGP(DNM, LOGL_ERROR, "The more magic number is wrong.\n");
return -1;
}
if (fstat(sw->fd, &stat) == -1) {
LOGP(DNM, LOGL_ERROR, "Could not stat the file.\n");
return -1;
}
if (ntohl(firmware_header.file_length) != stat.st_size) {
LOGP(DNM, LOGL_ERROR, "The filesizes do not match.\n");
return -1;
}
/* go back to the start as we checked the whole filesize.. */
lseek(sw->fd, 0l, SEEK_SET);
LOGP(DNM, LOGL_NOTICE, "The ipaccess SDP header is not fully understood.\n"
"There might be checksums in the file that are not\n"
"verified and incomplete firmware might be flashed.\n"
"There is absolutely no WARRANTY that flashing will\n"
"work.\n");
return 0;
}
static int sw_open_file(struct abis_nm_sw *sw, const char *fname)
{
char file_id[12+1];
@@ -1392,19 +1372,6 @@ static int sw_open_file(struct abis_nm_sw *sw, const char *fname)
/* rewind to start of file */
rewind(sw->stream);
break;
case GSM_BTS_TYPE_NANOBTS:
/* TODO: extract that from the filename or content */
rc = parse_sdp_header(sw);
if (rc < 0) {
fprintf(stderr, "Could not parse the ipaccess SDP header\n");
return -1;
}
strcpy((char *)sw->file_id, "id");
sw->file_id_len = 3;
strcpy((char *)sw->file_version, "version");
sw->file_version_len = 8;
break;
default:
/* We don't know how to treat them yet */
close(sw->fd);
@@ -1503,12 +1470,6 @@ static int abis_nm_rcvmsg_sw(struct msgb *mb)
rc = sw_load_end(sw);
}
break;
case NM_MT_LOAD_ABORT:
if (sw->cbfn)
sw->cbfn(GSM_HOOK_NM_SWLOAD,
NM_MT_LOAD_ABORT, mb,
sw->cb_data, NULL);
break;
}
break;
case SW_STATE_WAIT_ENDACK:
@@ -1522,7 +1483,6 @@ static int abis_nm_rcvmsg_sw(struct msgb *mb)
sw->cbfn(GSM_HOOK_NM_SWLOAD,
NM_MT_LOAD_END_ACK, mb,
sw->cb_data, NULL);
rc = 0;
break;
case NM_MT_LOAD_END_NACK:
if (sw->forced) {
@@ -1599,26 +1559,10 @@ int abis_nm_software_load(struct gsm_bts *bts, const char *fname,
return -EBUSY;
sw->bts = bts;
switch (bts->type) {
case GSM_BTS_TYPE_BS11:
sw->obj_class = NM_OC_SITE_MANAGER;
sw->obj_instance[0] = 0xff;
sw->obj_instance[1] = 0xff;
sw->obj_instance[2] = 0xff;
break;
case GSM_BTS_TYPE_NANOBTS:
sw->obj_class = NM_OC_BASEB_TRANSC;
sw->obj_instance[0] = 0x00;
sw->obj_instance[1] = 0x00;
sw->obj_instance[2] = 0xff;
break;
case GSM_BTS_TYPE_UNKNOWN:
default:
LOGPC(DNM, LOGL_ERROR, "Software Load not properly implemented.\n");
return -1;
break;
}
sw->obj_class = NM_OC_SITE_MANAGER;
sw->obj_instance[0] = 0xff;
sw->obj_instance[1] = 0xff;
sw->obj_instance[2] = 0xff;
sw->window_size = win_size;
sw->state = SW_STATE_WAIT_INITACK;
sw->cbfn = cbfn;
@@ -1646,10 +1590,7 @@ int abis_nm_software_load_status(struct gsm_bts *bts)
return rc;
}
if (sw->stream)
percent = (ftell(sw->stream) * 100) / st.st_size;
else
percent = (lseek(sw->fd, 0, SEEK_CUR) * 100) / st.st_size;
percent = (ftell(sw->stream) * 100) / st.st_size;
return percent;
}
@@ -2340,18 +2281,10 @@ int abis_nm_bs11_get_cclk(struct gsm_bts *bts)
}
//static const u_int8_t bs11_logon_c7[] = { 0x07, 0xd9, 0x01, 0x11, 0x0d, 0x10, 0x20 };
static const u_int8_t bs11_logon_c8[] = { 0x02 };
static const u_int8_t bs11_logon_c9[] = "FACTORY";
int abis_nm_bs11_factory_logon(struct gsm_bts *bts, int on)
{
return abis_nm_bs11_logon(bts, 0x02, "FACTORY", on);
}
int abis_nm_bs11_infield_logon(struct gsm_bts *bts, int on)
{
return abis_nm_bs11_logon(bts, 0x03, "FIELD ", on);
}
int abis_nm_bs11_logon(struct gsm_bts *bts, u_int8_t level, const char *name, int on)
{
struct abis_om_hdr *oh;
struct msgb *msg = nm_msgb_alloc();
@@ -2362,15 +2295,15 @@ int abis_nm_bs11_logon(struct gsm_bts *bts, u_int8_t level, const char *name, in
oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
if (on) {
u_int8_t len = 3*2 + sizeof(bdt)
+ 1 + strlen(name);
+ sizeof(bs11_logon_c8) + sizeof(bs11_logon_c9);
fill_om_fom_hdr(oh, len, NM_MT_BS11_LMT_LOGON,
NM_OC_BS11_BTSE, 0xff, 0xff, 0xff);
msgb_tlv_put(msg, NM_ATT_BS11_LMT_LOGIN_TIME,
sizeof(bdt), (u_int8_t *) &bdt);
msgb_tlv_put(msg, NM_ATT_BS11_LMT_USER_ACC_LEV,
1, &level);
sizeof(bs11_logon_c8), bs11_logon_c8);
msgb_tlv_put(msg, NM_ATT_BS11_LMT_USER_NAME,
strlen(name), (u_int8_t *)name);
sizeof(bs11_logon_c9), bs11_logon_c9);
} else {
fill_om_fom_hdr(oh, 0, NM_MT_BS11_LMT_LOGOFF,
NM_OC_BS11_BTSE, 0xff, 0xff, 0xff);
@@ -2418,27 +2351,6 @@ int abis_nm_bs11_set_pll_locked(struct gsm_bts *bts, int locked)
return abis_nm_sendmsg(bts, msg);
}
/* Set the calibration value of the PLL (work value/set value)
* It depends on the login which one is changed */
int abis_nm_bs11_set_pll(struct gsm_bts *bts, int value)
{
struct abis_om_hdr *oh;
struct msgb *msg;
u_int8_t tlv_value[2];
msg = nm_msgb_alloc();
oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
fill_om_fom_hdr(oh, 3, NM_MT_BS11_SET_ATTR, NM_OC_BS11,
BS11_OBJ_TRX1, 0x00, 0x00);
tlv_value[0] = value>>8;
tlv_value[1] = value&0xff;
msgb_tlv_put(msg, NM_ATT_BS11_PLL, 2, tlv_value);
return abis_nm_sendmsg(bts, msg);
}
int abis_nm_bs11_get_state(struct gsm_bts *bts)
{
return __simple_cmd(bts, NM_MT_BS11_GET_STATE);
@@ -2685,15 +2597,14 @@ static int abis_nm_rx_ipacc(struct msgb *msg)
struct abis_om_fom_hdr *foh;
u_int8_t idstrlen = oh->data[0];
struct tlv_parsed tp;
struct ipacc_ack_signal_data signal;
if (strncmp((char *)&oh->data[1], ipaccess_magic, idstrlen)) {
LOGP(DNM, LOGL_ERROR, "id string is not com.ipaccess !?!\n");
DEBUGP(DNM, "id string is not com.ipaccess !?!\n");
return -EINVAL;
}
foh = (struct abis_om_fom_hdr *) (oh->data + 1 + idstrlen);
abis_nm_tlv_parse(&tp, msg->trx->bts, foh->data, oh->length-sizeof(*foh));
abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
debugp_foh(foh);
@@ -2716,7 +2627,7 @@ static int abis_nm_rx_ipacc(struct msgb *msg)
DEBUGPC(DNM, "\n");
break;
case NM_MT_IPACC_RSL_CONNECT_NACK:
LOGP(DNM, LOGL_ERROR, "RSL CONNECT NACK ");
DEBUGPC(DNM, "RSL CONNECT NACK ");
if (TLVP_PRESENT(&tp, NM_ATT_NACK_CAUSES))
DEBUGPC(DNM, " CAUSE=%s\n",
nack_cause_name(*TLVP_VAL(&tp, NM_ATT_NACK_CAUSES)));
@@ -2728,35 +2639,35 @@ static int abis_nm_rx_ipacc(struct msgb *msg)
/* FIXME: decode and show the actual attributes */
break;
case NM_MT_IPACC_SET_NVATTR_NACK:
LOGP(DNM, LOGL_ERROR, "SET NVATTR NACK ");
DEBUGPC(DNM, "SET NVATTR NACK ");
if (TLVP_PRESENT(&tp, NM_ATT_NACK_CAUSES))
LOGPC(DNM, LOGL_ERROR, " CAUSE=%s\n",
DEBUGPC(DNM, " CAUSE=%s\n",
nack_cause_name(*TLVP_VAL(&tp, NM_ATT_NACK_CAUSES)));
else
LOGPC(DNM, LOGL_ERROR, "\n");
DEBUGPC(DNM, "\n");
break;
case NM_MT_IPACC_GET_NVATTR_ACK:
DEBUGPC(DNM, "GET NVATTR ACK\n");
/* FIXME: decode and show the actual attributes */
break;
case NM_MT_IPACC_GET_NVATTR_NACK:
LOGPC(DNM, LOGL_ERROR, "GET NVATTR NACK ");
DEBUGPC(DNM, "GET NVATTR NACK ");
if (TLVP_PRESENT(&tp, NM_ATT_NACK_CAUSES))
LOGPC(DNM, LOGL_ERROR, " CAUSE=%s\n",
DEBUGPC(DNM, " CAUSE=%s\n",
nack_cause_name(*TLVP_VAL(&tp, NM_ATT_NACK_CAUSES)));
else
LOGPC(DNM, LOGL_ERROR, "\n");
DEBUGPC(DNM, "\n");
break;
case NM_MT_IPACC_SET_ATTR_ACK:
DEBUGPC(DNM, "SET ATTR ACK\n");
break;
case NM_MT_IPACC_SET_ATTR_NACK:
LOGPC(DNM, LOGL_ERROR, "SET ATTR NACK ");
DEBUGPC(DNM, "SET ATTR NACK ");
if (TLVP_PRESENT(&tp, NM_ATT_NACK_CAUSES))
LOGPC(DNM, LOGL_ERROR, " CAUSE=%s\n",
DEBUGPC(DNM, " CAUSE=%s\n",
nack_cause_name(*TLVP_VAL(&tp, NM_ATT_NACK_CAUSES)));
else
LOGPC(DNM, LOGL_ERROR, "\n");
DEBUGPC(DNM, "\n");
break;
default:
DEBUGPC(DNM, "unknown\n");
@@ -2768,14 +2679,7 @@ static int abis_nm_rx_ipacc(struct msgb *msg)
case NM_MT_IPACC_RSL_CONNECT_NACK:
case NM_MT_IPACC_SET_NVATTR_NACK:
case NM_MT_IPACC_GET_NVATTR_NACK:
signal.bts = msg->trx->bts;
signal.msg_type = foh->msg_type;
dispatch_signal(SS_NM, S_NM_IPACC_NACK, &signal);
break;
case NM_MT_IPACC_SET_NVATTR_ACK:
signal.bts = msg->trx->bts;
signal.msg_type = foh->msg_type;
dispatch_signal(SS_NM, S_NM_IPACC_ACK, &signal);
dispatch_signal(SS_NM, S_NM_IPACC_NACK, &foh->msg_type);
break;
default:
break;
@@ -2822,11 +2726,11 @@ int abis_nm_ipaccess_msg(struct gsm_bts *bts, u_int8_t msg_type,
}
/* set some attributes in NVRAM */
int abis_nm_ipaccess_set_nvattr(struct gsm_bts_trx *trx, u_int8_t *attr,
int abis_nm_ipaccess_set_nvattr(struct gsm_bts *bts, u_int8_t *attr,
int attr_len)
{
return abis_nm_ipaccess_msg(trx->bts, NM_MT_IPACC_SET_NVATTR,
NM_OC_BASEB_TRANSC, 0, trx->nr, 0xff, attr,
return abis_nm_ipaccess_msg(bts, NM_MT_IPACC_SET_NVATTR,
NM_OC_BASEB_TRANSC, 0, 0, 0xff, attr,
attr_len);
}
@@ -2873,19 +2777,11 @@ int abis_nm_ipaccess_set_attr(struct gsm_bts *bts, u_int8_t obj_class,
attr, attr_len);
}
void abis_nm_ipaccess_cgi(u_int8_t *buf, struct gsm_bts *bts)
{
/* we simply reuse the GSM48 function and overwrite the RAC
* with the Cell ID */
gsm48_ra_id_by_bts(buf, bts);
*((u_int16_t *)(buf + 5)) = htons(bts->cell_identity);
}
void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked)
{
int new_state = locked ? NM_STATE_LOCKED : NM_STATE_UNLOCKED;
trx->nm_state.administrative = new_state;
trx->rf_locked = locked;
if (!trx->bts || !trx->bts->oml_link)
return;
@@ -3000,3 +2896,5 @@ int ipac_parse_bcch_info(struct ipac_bcch_info *binf, u_int8_t *buf)
return 0;
}

View File

@@ -1,7 +1,7 @@
/* GSM Radio Signalling Link messages on the A-bis interface
* 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
*
* All Rights Reserved
*
@@ -30,23 +30,104 @@
#include <openbsc/gsm_data.h>
#include <openbsc/gsm_04_08.h>
#include <osmocore/gsm_utils.h>
#include <openbsc/gsm_utils.h>
#include <openbsc/abis_rsl.h>
#include <openbsc/chan_alloc.h>
#include <openbsc/bsc_rll.h>
#include <openbsc/debug.h>
#include <osmocore/tlv.h>
#include <openbsc/tlv.h>
#include <openbsc/paging.h>
#include <openbsc/signal.h>
#include <openbsc/meas_rep.h>
#include <openbsc/rtp_proxy.h>
#include <osmocore/rsl.h>
#define RSL_ALLOC_SIZE 1024
#define RSL_ALLOC_HEADROOM 128
#define MAX(a, b) (a) >= (b) ? (a) : (b)
static const struct tlv_definition rsl_att_tlvdef = {
.def = {
[RSL_IE_CHAN_NR] = { TLV_TYPE_TV },
[RSL_IE_LINK_IDENT] = { TLV_TYPE_TV },
[RSL_IE_ACT_TYPE] = { TLV_TYPE_TV },
[RSL_IE_BS_POWER] = { TLV_TYPE_TV },
[RSL_IE_CHAN_IDENT] = { TLV_TYPE_TLV },
[RSL_IE_CHAN_MODE] = { TLV_TYPE_TLV },
[RSL_IE_ENCR_INFO] = { TLV_TYPE_TLV },
[RSL_IE_FRAME_NUMBER] = { TLV_TYPE_FIXED, 2 },
[RSL_IE_HANDO_REF] = { TLV_TYPE_TV },
[RSL_IE_L1_INFO] = { TLV_TYPE_FIXED, 2 },
[RSL_IE_L3_INFO] = { TLV_TYPE_TL16V },
[RSL_IE_MS_IDENTITY] = { TLV_TYPE_TLV },
[RSL_IE_MS_POWER] = { TLV_TYPE_TV },
[RSL_IE_PAGING_GROUP] = { TLV_TYPE_TV },
[RSL_IE_PAGING_LOAD] = { TLV_TYPE_FIXED, 2 },
[RSL_IE_PYHS_CONTEXT] = { TLV_TYPE_TLV },
[RSL_IE_ACCESS_DELAY] = { TLV_TYPE_TV },
[RSL_IE_RACH_LOAD] = { TLV_TYPE_TLV },
[RSL_IE_REQ_REFERENCE] = { TLV_TYPE_FIXED, 3 },
[RSL_IE_RELEASE_MODE] = { TLV_TYPE_TV },
[RSL_IE_RESOURCE_INFO] = { TLV_TYPE_TLV },
[RSL_IE_RLM_CAUSE] = { TLV_TYPE_TLV },
[RSL_IE_STARTNG_TIME] = { TLV_TYPE_FIXED, 2 },
[RSL_IE_TIMING_ADVANCE] = { TLV_TYPE_TV },
[RSL_IE_UPLINK_MEAS] = { TLV_TYPE_TLV },
[RSL_IE_CAUSE] = { TLV_TYPE_TLV },
[RSL_IE_MEAS_RES_NR] = { TLV_TYPE_TV },
[RSL_IE_MSG_ID] = { TLV_TYPE_TV },
[RSL_IE_SYSINFO_TYPE] = { TLV_TYPE_TV },
[RSL_IE_MS_POWER_PARAM] = { TLV_TYPE_TLV },
[RSL_IE_BS_POWER_PARAM] = { TLV_TYPE_TLV },
[RSL_IE_PREPROC_PARAM] = { TLV_TYPE_TLV },
[RSL_IE_PREPROC_MEAS] = { TLV_TYPE_TLV },
[RSL_IE_IMM_ASS_INFO] = { TLV_TYPE_TLV },
[RSL_IE_SMSCB_INFO] = { TLV_TYPE_FIXED, 23 },
[RSL_IE_MS_TIMING_OFFSET] = { TLV_TYPE_TV },
[RSL_IE_ERR_MSG] = { TLV_TYPE_TLV },
[RSL_IE_FULL_BCCH_INFO] = { TLV_TYPE_TLV },
[RSL_IE_CHAN_NEEDED] = { TLV_TYPE_TV },
[RSL_IE_CB_CMD_TYPE] = { TLV_TYPE_TV },
[RSL_IE_SMSCB_MSG] = { TLV_TYPE_TLV },
[RSL_IE_FULL_IMM_ASS_INFO] = { TLV_TYPE_TLV },
[RSL_IE_SACCH_INFO] = { TLV_TYPE_TLV },
[RSL_IE_CBCH_LOAD_INFO] = { TLV_TYPE_TV },
[RSL_IE_SMSCB_CHAN_INDICATOR] = { TLV_TYPE_TV },
[RSL_IE_GROUP_CALL_REF] = { TLV_TYPE_TLV },
[RSL_IE_CHAN_DESC] = { TLV_TYPE_TLV },
[RSL_IE_NCH_DRX_INFO] = { TLV_TYPE_TLV },
[RSL_IE_CMD_INDICATOR] = { TLV_TYPE_TLV },
[RSL_IE_EMLPP_PRIO] = { TLV_TYPE_TV },
[RSL_IE_UIC] = { TLV_TYPE_TLV },
[RSL_IE_MAIN_CHAN_REF] = { TLV_TYPE_TV },
[RSL_IE_MR_CONFIG] = { TLV_TYPE_TLV },
[RSL_IE_MR_CONTROL] = { TLV_TYPE_TV },
[RSL_IE_SUP_CODEC_TYPES] = { TLV_TYPE_TLV },
[RSL_IE_CODEC_CONFIG] = { TLV_TYPE_TLV },
[RSL_IE_RTD] = { TLV_TYPE_TV },
[RSL_IE_TFO_STATUS] = { TLV_TYPE_TV },
[RSL_IE_LLP_APDU] = { TLV_TYPE_TLV },
[RSL_IE_SIEMENS_MRPCI] = { TLV_TYPE_TV },
[RSL_IE_IPAC_PROXY_UDP] = { TLV_TYPE_FIXED, 2 },
[RSL_IE_IPAC_BSCMPL_TOUT] = { TLV_TYPE_TV },
[RSL_IE_IPAC_REMOTE_IP] = { TLV_TYPE_FIXED, 4 },
[RSL_IE_IPAC_REMOTE_PORT] = { TLV_TYPE_FIXED, 2 },
[RSL_IE_IPAC_RTP_PAYLOAD] = { TLV_TYPE_TV },
[RSL_IE_IPAC_LOCAL_PORT] = { TLV_TYPE_FIXED, 2 },
[RSL_IE_IPAC_SPEECH_MODE] = { TLV_TYPE_TV },
[RSL_IE_IPAC_LOCAL_IP] = { TLV_TYPE_FIXED, 4 },
[RSL_IE_IPAC_CONN_ID] = { TLV_TYPE_FIXED, 2 },
[RSL_IE_IPAC_RTP_CSD_FMT] = { TLV_TYPE_TV },
[RSL_IE_IPAC_RTP_JIT_BUF] = { TLV_TYPE_FIXED, 2 },
[RSL_IE_IPAC_RTP_COMPR] = { TLV_TYPE_TV },
[RSL_IE_IPAC_RTP_PAYLOAD2] = { TLV_TYPE_TV },
[RSL_IE_IPAC_RTP_MPLEX] = { TLV_TYPE_FIXED, 8 },
[RSL_IE_IPAC_RTP_MPLEX_ID] = { TLV_TYPE_TV },
},
};
#define rsl_tlv_parse(dec, buf, len) \
tlv_parse(dec, &rsl_att_tlvdef, buf, len, 0, 0)
static u_int8_t mdisc_by_msgtype(u_int8_t msg_type)
{
/* mask off the transparent bit ? */
@@ -74,6 +155,44 @@ static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
dh->ie_chan = RSL_IE_CHAN_NR;
}
static inline void init_llm_hdr(struct abis_rsl_rll_hdr *dh,
u_int8_t msg_type)
{
/* dh->c.msg_discr = mdisc_by_msgtype(msg_type); */
dh->c.msg_discr = ABIS_RSL_MDISC_RLL;
dh->c.msg_type = msg_type;
dh->ie_chan = RSL_IE_CHAN_NR;
dh->ie_link_id = RSL_IE_LINK_IDENT;
}
/* encode channel number as per Section 9.3.1 */
u_int8_t rsl_enc_chan_nr(u_int8_t type, u_int8_t subch, u_int8_t timeslot)
{
u_int8_t ret;
ret = (timeslot & 0x07) | type;
switch (type) {
case RSL_CHAN_Lm_ACCHs:
subch &= 0x01;
break;
case RSL_CHAN_SDCCH4_ACCH:
subch &= 0x07;
break;
case RSL_CHAN_SDCCH8_ACCH:
subch &= 0x07;
break;
default:
/* no subchannels allowed */
subch = 0x00;
break;
}
ret |= (subch << 3);
return ret;
}
/* determine logical channel based on TRX and channel number IE */
struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, u_int8_t chan_nr)
{
@@ -118,8 +237,6 @@ struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, u_int8_t chan_nr)
}
lchan = &ts->lchan[lch_idx];
debug_set_context(BSC_CTX_LCHAN, lchan);
debug_set_context(BSC_CTX_SUBSCR, lchan->subscr);
return lchan;
}
@@ -216,14 +333,57 @@ static int build_encr_info(u_int8_t *out, struct gsm_lchan *lchan)
return lchan->encr.key_len + 1;
}
static void print_rsl_cause(int lvl, const u_int8_t *cause_v, u_int8_t cause_len)
static const char *rsl_err_vals[0xff] = {
[RSL_ERR_RADIO_IF_FAIL] = "Radio Interface Failure",
[RSL_ERR_RADIO_LINK_FAIL] = "Radio Link Failure",
[RSL_ERR_HANDOVER_ACC_FAIL] = "Handover Access Failure",
[RSL_ERR_TALKER_ACC_FAIL] = "Talker Access Failure",
[RSL_ERR_OM_INTERVENTION] = "O&M Intervention",
[RSL_ERR_NORMAL_UNSPEC] = "Normal event, unspecified",
[RSL_ERR_T_MSRFPCI_EXP] = "Siemens: T_MSRFPCI Expired",
[RSL_ERR_EQUIPMENT_FAIL] = "Equipment Failure",
[RSL_ERR_RR_UNAVAIL] = "Radio Resource not available",
[RSL_ERR_TERR_CH_FAIL] = "Terrestrial Channel Failure",
[RSL_ERR_CCCH_OVERLOAD] = "CCCH Overload",
[RSL_ERR_ACCH_OVERLOAD] = "ACCH Overload",
[RSL_ERR_PROCESSOR_OVERLOAD] = "Processor Overload",
[RSL_ERR_RES_UNAVAIL] = "Resource not available, unspecified",
[RSL_ERR_TRANSC_UNAVAIL] = "Transcoding not available",
[RSL_ERR_SERV_OPT_UNAVAIL] = "Service or Option not available",
[RSL_ERR_ENCR_UNIMPL] = "Encryption algorithm not implemented",
[RSL_ERR_SERV_OPT_UNIMPL] = "Service or Option not implemented",
[RSL_ERR_RCH_ALR_ACTV_ALLOC] = "Radio channel already activated",
[RSL_ERR_INVALID_MESSAGE] = "Invalid Message, unspecified",
[RSL_ERR_MSG_DISCR] = "Message Discriminator Error",
[RSL_ERR_MSG_TYPE] = "Message Type Error",
[RSL_ERR_MSG_SEQ] = "Message Sequence Error",
[RSL_ERR_IE_ERROR] = "General IE error",
[RSL_ERR_MAND_IE_ERROR] = "Mandatory IE error",
[RSL_ERR_OPT_IE_ERROR] = "Optional IE error",
[RSL_ERR_IE_NONEXIST] = "IE non-existent",
[RSL_ERR_IE_LENGTH] = "IE length error",
[RSL_ERR_IE_CONTENT] = "IE content error",
[RSL_ERR_PROTO] = "Protocol error, unspecified",
[RSL_ERR_INTERWORKING] = "Interworking error, unspecified",
};
static const char *rsl_err_name(u_int8_t err)
{
if (rsl_err_vals[err])
return rsl_err_vals[err];
else
return "unknown";
}
static void print_rsl_cause(const u_int8_t *cause_v, u_int8_t cause_len)
{
int i;
LOGPC(DRSL, lvl, "CAUSE=0x%02x(%s) ",
DEBUGPC(DRSL, "CAUSE=0x%02x(%s) ",
cause_v[0], rsl_err_name(cause_v[0]));
for (i = 1; i < cause_len-1; i++)
LOGPC(DRSL, lvl, "%02x ", cause_v[i]);
DEBUGPC(DRSL, "%02x ", cause_v[i]);
}
/* Send a BCCH_INFO message as per Chapter 8.5.1 */
@@ -563,7 +723,8 @@ int rsl_deact_sacch(struct gsm_lchan *lchan)
msg->lchan = lchan;
msg->trx = lchan->ts->trx;
DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
DEBUGP(DRSL, "DEACTivate SACCH CMD channel=%s chan_nr=0x%02x\n",
gsm_ts_name(lchan->ts), dh->chan_nr);
return abis_rsl_sendmsg(msg);
}
@@ -581,7 +742,8 @@ int rsl_rf_chan_release(struct gsm_lchan *lchan)
msg->lchan = lchan;
msg->trx = lchan->ts->trx;
DEBUGP(DRSL, "%s RF Channel Release CMD\n", gsm_lchan_name(lchan));
DEBUGP(DRSL, "RF Channel Release CMD channel=%s chan_nr=0x%02x\n",
gsm_ts_name(lchan->ts), dh->chan_nr);
/* BTS will respond by RF CHAN REL ACK */
return abis_rsl_sendmsg(msg);
@@ -674,8 +836,8 @@ int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
dh->chan_nr = lchan2chan_nr(lchan);
msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(u_int8_t *)mrpci);
DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
gsm_lchan_name(lchan), *(u_int8_t *)mrpci);
DEBUGP(DRSL, "channel=%s chan_nr=0x%02x TX Siemens MRPCI 0x%02x\n",
gsm_ts_name(lchan->ts), dh->chan_nr, *(u_int8_t *)mrpci);
msg->trx = lchan->ts->trx;
@@ -687,13 +849,27 @@ int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
/* Chapter 8.3.1 */
int rsl_data_request(struct msgb *msg, u_int8_t link_id)
{
u_int8_t l3_len = msg->tail - (u_int8_t *)msgb_l3(msg);
struct abis_rsl_rll_hdr *rh;
if (msg->lchan == NULL) {
LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
return -EINVAL;
}
rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, lchan2chan_nr(msg->lchan),
link_id, 1);
if (msg->lchan->use_count <= 0) {
DEBUGP(DRSL, "BUG: Trying to send data on unused lchan\n");
}
/* First push the L3 IE tag and length */
msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
/* Then push the RSL header */
rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh));
init_llm_hdr(rh, RSL_MT_DATA_REQ);
rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
rh->chan_nr = lchan2chan_nr(msg->lchan);
rh->link_id = link_id;
msg->trx = msg->lchan->ts->trx;
@@ -704,10 +880,15 @@ int rsl_data_request(struct msgb *msg, u_int8_t link_id)
/* Chapter 8.3.1 */
int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id)
{
struct msgb *msg;
struct msgb *msg = rsl_msgb_alloc();
struct abis_rsl_rll_hdr *rh;
rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
init_llm_hdr(rh, RSL_MT_EST_REQ);
//rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
rh->chan_nr = lchan2chan_nr(lchan);
rh->link_id = link_id;
msg = rsl_rll_simple(RSL_MT_EST_REQ, lchan2chan_nr(lchan),
link_id, 0);
msg->trx = lchan->ts->trx;
return abis_rsl_sendmsg(msg);
@@ -720,16 +901,16 @@ int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id)
lchan_free() */
int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id)
{
struct msgb *msg = rsl_msgb_alloc();
struct abis_rsl_rll_hdr *rh;
struct msgb *msg;
msg = rsl_rll_simple(RSL_MT_REL_REQ, lchan2chan_nr(lchan),
link_id, 0);
rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
init_llm_hdr(rh, RSL_MT_REL_REQ);
//rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
rh->chan_nr = lchan2chan_nr(lchan);
rh->link_id = link_id;
msgb_tv_put(msg, RSL_IE_RELEASE_MODE, 0); /* normal release */
lchan->state = LCHAN_S_REL_REQ;
/* FIXME: start some timer in case we don't receive a REL ACK ? */
msg->trx = lchan->ts->trx;
return abis_rsl_sendmsg(msg);
@@ -745,10 +926,6 @@ static int rsl_rx_chan_act_ack(struct msgb *msg)
if (rslh->ie_chan != RSL_IE_CHAN_NR)
return -EINVAL;
if (msg->lchan->state != LCHAN_S_ACT_REQ)
LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
gsm_lchan_name(msg->lchan),
gsm_lchans_name(msg->lchan->state));
msg->lchan->state = LCHAN_S_ACTIVE;
dispatch_signal(SS_LCHAN, S_LCHAN_ACTIVATE_ACK, msg->lchan);
@@ -762,24 +939,16 @@ static int rsl_rx_chan_act_nack(struct msgb *msg)
struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
struct tlv_parsed tp;
LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK",
gsm_lchan_name(msg->lchan));
/* BTS has rejected channel activation ?!? */
if (dh->ie_chan != RSL_IE_CHAN_NR)
return -EINVAL;
rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
const u_int8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
print_rsl_cause(LOGL_ERROR, cause,
if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
TLVP_LEN(&tp, RSL_IE_CAUSE));
if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
msg->lchan->state = LCHAN_S_NONE;
} else
msg->lchan->state = LCHAN_S_NONE;
LOGPC(DRSL, LOGL_ERROR, "\n");
msg->lchan->state = LCHAN_S_NONE;
dispatch_signal(SS_LCHAN, S_LCHAN_ACTIVATE_NACK, msg->lchan);
@@ -794,16 +963,14 @@ static int rsl_rx_conn_fail(struct msgb *msg)
struct tlv_parsed tp;
/* FIXME: print which channel */
LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING ",
gsm_lchan_name(msg->lchan));
LOGP(DRSL, LOGL_NOTICE, "CONNECTION FAIL: RELEASING\n");
rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
TLVP_LEN(&tp, RSL_IE_CAUSE));
LOGPC(DRSL, LOGL_NOTICE, "\n");
/* FIXME: only free it after channel release ACK */
return rsl_rf_chan_release(msg->lchan);
}
@@ -853,8 +1020,8 @@ static void print_meas_rep(struct gsm_meas_rep *mr)
return;
for (i = 0; i < mr->num_cell; i++) {
struct gsm_meas_rep_cell *mrc = &mr->cell[i];
DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
DEBUGP(DMEAS, "ARFCN=%u BSIC=%u => %d dBm\n", mrc->arfcn, mrc->bsic,
rxlev2dbm(mrc->rxlev));
}
}
@@ -869,11 +1036,8 @@ static int rsl_rx_meas_res(struct msgb *msg)
/* check if this channel is actually active */
/* FIXME: maybe this check should be way more generic/centralized */
if (msg->lchan->state != LCHAN_S_ACTIVE) {
LOGP(DRSL, LOGL_NOTICE, "%s: MEAS RES for inactive channel\n",
gsm_lchan_name(msg->lchan));
if (msg->lchan->state != LCHAN_S_ACTIVE)
return 0;
}
memset(mr, 0, sizeof(*mr));
mr->lchan = msg->lchan;
@@ -934,7 +1098,7 @@ static int rsl_rx_hando_det(struct msgb *msg)
struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
struct tlv_parsed tp;
DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
DEBUGP(DRSL, "HANDOVER DETECT ");
rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
@@ -956,14 +1120,18 @@ static int abis_rsl_rx_dchan(struct msgb *msg)
char *ts_name;
msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
ts_name = gsm_lchan_name(msg->lchan);
ts_name = gsm_ts_name(msg->lchan->ts);
if (rslh->c.msg_type != RSL_MT_MEAS_RES)
DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ", ts_name, rslh->chan_nr);
switch (rslh->c.msg_type) {
case RSL_MT_CHAN_ACTIV_ACK:
DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
DEBUGPC(DRSL, "CHANNEL ACTIVATE ACK\n");
rc = rsl_rx_chan_act_ack(msg);
break;
case RSL_MT_CHAN_ACTIV_NACK:
DEBUGPC(DRSL, "CHANNEL ACTIVATE NACK\n");
rc = rsl_rx_chan_act_nack(msg);
break;
case RSL_MT_CONN_FAIL:
@@ -976,31 +1144,27 @@ static int abis_rsl_rx_dchan(struct msgb *msg)
rc = rsl_rx_hando_det(msg);
break;
case RSL_MT_RF_CHAN_REL_ACK:
DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", ts_name);
if (msg->lchan->state != LCHAN_S_REL_REQ)
LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
gsm_lchan_name(msg->lchan),
gsm_lchans_name(msg->lchan->state));
DEBUGPC(DRSL, "RF CHANNEL RELEASE ACK\n");
msg->lchan->state = LCHAN_S_NONE;
lchan_free(msg->lchan);
break;
case RSL_MT_MODE_MODIFY_ACK:
DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
DEBUGPC(DRSL, "CHANNEL MODE MODIFY ACK\n");
break;
case RSL_MT_MODE_MODIFY_NACK:
LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
DEBUGPC(DRSL, "CHANNEL MODE MODIFY NACK\n");
break;
case RSL_MT_IPAC_PDCH_ACT_ACK:
DEBUGPC(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
DEBUGPC(DRSL, "IPAC PDCH ACT ACK\n");
break;
case RSL_MT_IPAC_PDCH_ACT_NACK:
LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
DEBUGPC(DRSL, "IPAC PDCH ACT NACK\n");
break;
case RSL_MT_IPAC_PDCH_DEACT_ACK:
DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
DEBUGPC(DRSL, "IPAC PDCH DEACT ACK\n");
break;
case RSL_MT_IPAC_PDCH_DEACT_NACK:
LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
DEBUGPC(DRSL, "IPAC PDCH DEACT NACK\n");
break;
case RSL_MT_PHY_CONTEXT_CONF:
case RSL_MT_PREPROC_MEAS_RES:
@@ -1010,12 +1174,12 @@ static int abis_rsl_rx_dchan(struct msgb *msg)
case RSL_MT_MR_CODEC_MOD_ACK:
case RSL_MT_MR_CODEC_MOD_NACK:
case RSL_MT_MR_CODEC_MOD_PER:
LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
"msg 0x%02x\n", ts_name, rslh->c.msg_type);
DEBUGPC(DRSL, "Unimplemented Abis RSL DChan msg 0x%02x\n",
rslh->c.msg_type);
break;
default:
LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
ts_name, rslh->c.msg_type);
DEBUGPC(DRSL, "unknown Abis RSL DChan msg 0x%02x\n",
rslh->c.msg_type);
return -EINVAL;
}
@@ -1027,12 +1191,12 @@ static int rsl_rx_error_rep(struct msgb *msg)
struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
struct tlv_parsed tp;
LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(msg->trx));
LOGP(DRSL, LOGL_ERROR, "ERROR REPORT ");
rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
TLVP_LEN(&tp, RSL_IE_CAUSE));
LOGPC(DRSL, LOGL_ERROR, "\n");
@@ -1051,16 +1215,15 @@ static int abis_rsl_rx_trx(struct msgb *msg)
break;
case RSL_MT_RF_RES_IND:
/* interference on idle channels of TRX */
//DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(msg->trx));
//DEBUGP(DRSL, "TRX: RF Interference Indication\n");
break;
case RSL_MT_OVERLOAD:
/* indicate CCCH / ACCH / processor overload */
LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
gsm_trx_name(msg->trx));
LOGP(DRSL, LOGL_ERROR, "TRX: CCCH/ACCH/CPU Overload\n");
break;
default:
LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
"type 0x%02x\n", gsm_trx_name(msg->trx), rslh->msg_type);
DEBUGP(DRSL, "Unknown Abis RSL TRX message type 0x%02x\n",
rslh->msg_type);
return -EINVAL;
}
return rc;
@@ -1106,24 +1269,18 @@ static int rsl_rx_chan_rqd(struct msgb *msg)
lctype = get_ctype_by_chreq(bts, rqd_ref->ra, bts->network->neci);
chreq_reason = get_reason_by_chreq(bts, rqd_ref->ra, bts->network->neci);
counter_inc(bts->network->stats.chreq.total);
bts->network->stats.chreq.total++;
/* check availability / allocate channel */
lchan = lchan_alloc(bts, lctype);
if (!lchan) {
LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
counter_inc(bts->network->stats.chreq.no_channel);
DEBUGP(DRSL, "CHAN RQD: no resources for %s 0x%x\n",
gsm_lchan_name(lctype), rqd_ref->ra);
bts->network->stats.chreq.no_channel++;
/* FIXME: send some kind of reject ?!? */
return -ENOMEM;
}
if (lchan->state != LCHAN_S_NONE)
LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
"in state %s\n", gsm_lchan_name(lchan),
gsm_lchans_name(lchan->state));
lchan->state = LCHAN_S_ACT_REQ;
ts_number = lchan->ts->nr;
arfcn = lchan->ts->trx->arfcn;
subch = lchan->nr;
@@ -1151,9 +1308,10 @@ static int rsl_rx_chan_rqd(struct msgb *msg)
ia.timing_advance = rqd_ta;
ia.mob_alloc_len = 0;
DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
"r=%s ra=0x%02x\n", gsm_lchan_name(lchan), arfcn, subch,
gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
DEBUGP(DRSL, "Activating ARFCN(%u) TS(%u) SS(%u) lctype %s "
"chan_nr=0x%02x r=%s ra=0x%02x\n",
arfcn, ts_number, subch, gsm_lchan_name(lchan->type),
ia.chan_desc.chan_nr, gsm_chreq_name(chreq_reason),
rqd_ref->ra);
/* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
@@ -1232,12 +1390,10 @@ static int rsl_rx_rll_err_ind(struct msgb *msg)
struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
u_int8_t *rlm_cause = rllh->data;
LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s\n",
gsm_lchan_name(msg->lchan),
get_value_string(rsl_rlm_cause_strs, rlm_cause[1]));
LOGP(DRLL, LOGL_ERROR, "ERROR INDICATION cause=0x%02x\n", rlm_cause[1]);
rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED)
return rsl_rf_chan_release(msg->lchan);
@@ -1258,8 +1414,9 @@ static int abis_rsl_rx_rll(struct msgb *msg)
u_int8_t sapi = rllh->link_id & 7;
msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
ts_name = gsm_lchan_name(msg->lchan);
DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
ts_name = gsm_ts_name(msg->lchan->ts);
DEBUGP(DRLL, "channel=%s chan_nr=0x%02x sapi=%u ", ts_name,
rllh->chan_nr, sapi);
switch (rllh->c.msg_type) {
case RSL_MT_DATA_IND:
@@ -1328,31 +1485,11 @@ static u_int8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
{
switch (lchan->tch_mode) {
case GSM48_CMODE_SPEECH_V1:
switch (lchan->type) {
case GSM_LCHAN_TCH_F:
return 0x00;
case GSM_LCHAN_TCH_H:
return 0x03;
default:
break;
}
return 0x00;
case GSM48_CMODE_SPEECH_EFR:
switch (lchan->type) {
case GSM_LCHAN_TCH_F:
return 0x01;
/* there's no half-rate EFR */
default:
break;
}
return 0x01;
case GSM48_CMODE_SPEECH_AMR:
switch (lchan->type) {
case GSM_LCHAN_TCH_F:
return 0x02;
case GSM_LCHAN_TCH_H:
return 0x05;
default:
break;
}
return 0x02;
default:
break;
}
@@ -1429,8 +1566,9 @@ int rsl_ipacc_crcx(struct gsm_lchan *lchan)
lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x\n",
gsm_lchan_name(lchan), lchan->abis_ip.speech_mode);
DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_BIND "
"speech_mode=0x%02x\n", gsm_ts_name(lchan->ts),
dh->chan_nr, lchan->abis_ip.speech_mode);
msg->trx = lchan->ts->trx;
@@ -1459,8 +1597,9 @@ int rsl_ipacc_mdcx(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port,
lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
ia.s_addr = htonl(ip);
DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d "
"speech_mode=0x%02x\n", gsm_lchan_name(lchan), inet_ntoa(ia), port,
DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_MDCX "
"IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d speech_mode=0x%02x\n",
gsm_ts_name(lchan->ts), dh->chan_nr, inet_ntoa(ia), port,
rtp_payload2, lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
@@ -1501,7 +1640,8 @@ int rsl_ipacc_pdch_activate(struct gsm_lchan *lchan)
dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
dh->chan_nr = lchan2chan_nr(lchan);
DEBUGP(DRSL, "%s IPAC_PDCH_ACT\n", gsm_lchan_name(lchan));
DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_PDCH_ACT\n",
gsm_ts_name(lchan->ts), dh->chan_nr);
msg->trx = lchan->ts->trx;
@@ -1582,7 +1722,7 @@ static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
print_rsl_cause(TLVP_VAL(&tv, RSL_IE_CAUSE),
TLVP_LEN(&tv, RSL_IE_CAUSE));
/* the BTS tells us a RTP stream has been disconnected */
@@ -1599,38 +1739,38 @@ static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
static int abis_rsl_rx_ipacc(struct msgb *msg)
{
struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
char *ts_name;
int rc = 0;
msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
ts_name = gsm_lchan_name(msg->lchan);
DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ",
gsm_ts_name(msg->lchan->ts), rllh->chan_nr);
switch (rllh->c.msg_type) {
case RSL_MT_IPAC_CRCX_ACK:
DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
DEBUGPC(DRSL, "IPAC_CRCX_ACK ");
rc = abis_rsl_rx_ipacc_crcx_ack(msg);
break;
case RSL_MT_IPAC_CRCX_NACK:
/* somehow the BTS was unable to bind the lchan to its local
* port?!? */
LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
DEBUGPC(DRSL, "IPAC_CRCX_NACK ");
break;
case RSL_MT_IPAC_MDCX_ACK:
/* the BTS tells us that a connect operation was successful */
DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
DEBUGPC(DRSL, "IPAC_MDCX_ACK ");
rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
break;
case RSL_MT_IPAC_MDCX_NACK:
/* somehow the BTS was unable to connect the lchan to a remote
* port */
LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
DEBUGPC(DRSL, "IPAC_MDCX_NACK ");
break;
case RSL_MT_IPAC_DLCX_IND:
DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
DEBUGPC(DRSL, "IPAC_DLCX_IND ");
rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
break;
default:
LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x",
rllh->c.msg_type);
break;
}
@@ -1643,9 +1783,21 @@ static int abis_rsl_rx_ipacc(struct msgb *msg)
/* Entry-point where L2 RSL from BTS enters */
int abis_rsl_rcvmsg(struct msgb *msg)
{
struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ;
struct abis_rsl_common_hdr *rslh;
int rc = 0;
if (!msg) {
DEBUGP(DRSL, "Empty RSL msg?..\n");
return -1;
}
if (msgb_l2len(msg) < sizeof(*rslh)) {
DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
return -1;
}
rslh = msgb_l2(msg);
switch (rslh->msg_discr & 0xfe) {
case ABIS_RSL_MDISC_RLL:
rc = abis_rsl_rx_rll(msg);
@@ -1675,6 +1827,45 @@ int abis_rsl_rcvmsg(struct msgb *msg)
return rc;
}
/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf)
{
switch (ccch_conf) {
case RSL_BCCH_CCCH_CONF_1_NC:
return 1;
case RSL_BCCH_CCCH_CONF_1_C:
return 1;
case RSL_BCCH_CCCH_CONF_2_NC:
return 2;
case RSL_BCCH_CCCH_CONF_3_NC:
return 3;
case RSL_BCCH_CCCH_CONF_4_NC:
return 4;
default:
return -1;
}
}
/* Section 3.3.2.3 TS 05.02 */
int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf)
{
switch (ccch_conf) {
case RSL_BCCH_CCCH_CONF_1_NC:
return 0;
case RSL_BCCH_CCCH_CONF_1_C:
return 1;
case RSL_BCCH_CCCH_CONF_2_NC:
return 0;
case RSL_BCCH_CCCH_CONF_3_NC:
return 0;
case RSL_BCCH_CCCH_CONF_4_NC:
return 0;
default:
return -1;
}
}
/* From Table 10.5.33 of GSM 04.08 */
int rsl_number_of_paging_subchannels(struct gsm_bts *bts)
{

View File

@@ -22,9 +22,9 @@
#include <errno.h>
#include <stdint.h>
#include <sys/types.h>
#include <osmocore/bitvec.h>
#include <openbsc/bitvec.h>
#define BITNUM_FROM_COMP(byte, bit) ((byte*8)+bit)
@@ -36,7 +36,7 @@ static inline unsigned int bytenum_from_bitnum(unsigned int bitnum)
}
/* convert ZERO/ONE/L/H to a bitmask at given pos in a byte */
static uint8_t bitval2mask(enum bit_value bit, uint8_t bitnum)
static u_int8_t bitval2mask(enum bit_value bit, u_int8_t bitnum)
{
int bitval;
@@ -60,11 +60,11 @@ static uint8_t bitval2mask(enum bit_value bit, uint8_t bitnum)
}
/* check if the bit is 0 or 1 for a given position inside a bitvec */
enum bit_value bitvec_get_bit_pos(const struct bitvec *bv, unsigned int bitnr)
enum bit_value bitvec_get_bit_pos(struct bitvec *bv, unsigned int bitnr)
{
unsigned int bytenum = bytenum_from_bitnum(bitnr);
unsigned int bitnum = 7 - (bitnr % 8);
uint8_t bitval;
u_int8_t bitval;
if (bytenum >= bv->data_len)
return -EINVAL;
@@ -78,7 +78,7 @@ enum bit_value bitvec_get_bit_pos(const struct bitvec *bv, unsigned int bitnr)
}
/* get the Nth set bit inside the bit vector */
unsigned int bitvec_get_nth_set_bit(const struct bitvec *bv, unsigned int n)
unsigned int bitvec_get_nth_set_bit(struct bitvec *bv, unsigned int n)
{
unsigned int i, k = 0;
@@ -99,7 +99,7 @@ int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnr,
{
unsigned int bytenum = bytenum_from_bitnum(bitnr);
unsigned int bitnum = 7 - (bitnr % 8);
uint8_t bitval;
u_int8_t bitval;
if (bytenum >= bv->data_len)
return -EINVAL;

View File

@@ -36,10 +36,10 @@
#include <openbsc/gsm_data.h>
#include <openbsc/abis_nm.h>
#include <osmocore/msgb.h>
#include <osmocore/tlv.h>
#include <openbsc/msgb.h>
#include <openbsc/tlv.h>
#include <openbsc/debug.h>
#include <osmocore/select.h>
#include <openbsc/select.h>
#include <openbsc/rs232.h>
/* state of our bs11_config application */
@@ -51,7 +51,7 @@ enum bs11cfg_state {
STATE_QUERY,
};
static enum bs11cfg_state bs11cfg_state = STATE_NONE;
static char *command, *value;
static char *command;
struct timer_list status_timer;
static const u_int8_t obj_li_attr[] = {
@@ -71,13 +71,6 @@ static const char *trx1_password = "1111111111";
static const u_int8_t too_fast[] = { 0x12, 0x80, 0x00, 0x00, 0x02, 0x02 };
static struct debug_target *stderr_target;
/* dummy function to keep gsm_data.c happy */
struct counter *counter_alloc(const char *name)
{
return NULL;
}
int handle_serial_msg(struct msgb *rx_msg);
@@ -540,21 +533,6 @@ static int handle_state_resp(enum abis_bs11_phase state)
sleep(1);
abis_nm_bs11_factory_logon(g_bts, 0);
command = NULL;
} else if (!strcmp(command, "pll-setvalue")) {
abis_nm_bs11_set_pll(g_bts, atoi(value));
sleep(1);
abis_nm_bs11_factory_logon(g_bts, 0);
command = NULL;
} else if (!strcmp(command, "pll-workvalue")) {
/* To set the work value we need to login as FIELD */
abis_nm_bs11_factory_logon(g_bts, 0);
sleep(1);
abis_nm_bs11_infield_logon(g_bts, 1);
sleep(1);
abis_nm_bs11_set_pll(g_bts, atoi(value));
sleep(1);
abis_nm_bs11_infield_logon(g_bts, 0);
command = NULL;
} else if (!strcmp(command, "oml-tei")) {
abis_nm_bs11_conn_oml_tei(g_bts, 0, 1, 0xff, TEI_OML);
command = NULL;
@@ -649,7 +627,7 @@ int handle_serial_msg(struct msgb *rx_msg)
exit(0);
break;
case NM_MT_BS11_GET_STATE_ACK:
rc = abis_nm_tlv_parse(&tp, g_bts, foh->data, oh->length-sizeof(*foh));
rc = abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
print_state(&tp);
if (TLVP_PRESENT(&tp, NM_ATT_BS11_BTS_STATE) &&
TLVP_LEN(&tp, NM_ATT_BS11_BTS_STATE) >= 1)
@@ -657,7 +635,7 @@ int handle_serial_msg(struct msgb *rx_msg)
break;
case NM_MT_GET_ATTR_RESP:
printf("\n%sATTRIBUTES:\n", obj_name(foh));
abis_nm_tlv_parse(&tp, g_bts, foh->data, oh->length-sizeof(*foh));
abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
rc = print_attr(&tp);
//hexdump(foh->data, oh->length-sizeof(*foh));
break;
@@ -721,27 +699,25 @@ static void print_help(void)
printf("\t-p --port </dev/ttyXXX>\t\tSpecify serial port\n");
printf("\t-s --software <file>\t\tSpecify Software file\n");
printf("\t-S --safety <file>\t\tSpecify Safety Load file\n");
printf("\t-d --delay <ms>\t\t\tSpecify delay in milliseconds\n");
printf("\t-d --delay <ms>\t\tSpecify delay in milliseconds\n");
printf("\t-D --disconnect\t\t\tDisconnect BTS from BSC\n");
printf("\t-w --win-size <num>\t\tSpecify Window Size\n");
printf("\t-f --forced\t\t\tForce Software Load\n");
printf("\nSupported commands:\n");
printf("\tquery\t\t\tQuery the BS-11 about serial number and configuration\n");
printf("\tdisconnect\t\tDisconnect A-bis link (go into administrative state)\n");
printf("\tresconnect\t\tReconnect A-bis link (go into normal state)\n");
printf("\trestart\t\t\tRestart the BTS\n");
printf("\tsoftware\t\tDownload Software (only in administrative state)\n");
printf("\tcreate-trx1\t\tCreate objects for TRX1 (Danger: Your BS-11 might overheat)\n");
printf("\tdelete-trx1\t\tDelete objects for TRX1\n");
printf("\tpll-e1-locked\t\tSet the PLL to be locked to E1 clock\n");
printf("\tpll-standalone\t\tSet the PLL to be in standalone mode\n");
printf("\tpll-setvalue <value>\tSet the PLL set value\n");
printf("\tpll-workvalue <value>\tSet the PLL work value\n");
printf("\toml-tei\t\t\tSet OML E1 TS and TEI\n");
printf("\tbport0-star\t\tSet BPORT0 line config to star\n");
printf("\tquery\t\tQuery the BS-11 about serial number and configuration\n");
printf("\tdisconnect\tDisconnect A-bis link (go into administrative state)\n");
printf("\tresconnect\tReconnect A-bis link (go into normal state)\n");
printf("\trestart\t\tRestart the BTS\n");
printf("\tsoftware\tDownload Software (only in administrative state)\n");
printf("\tcreate-trx1\tCreate objects for TRX1 (Danger: Your BS-11 might overheat)\n");
printf("\tdelete-trx1\tDelete objects for TRX1\n");
printf("\tpll-e1-locked\tSet the PLL to be locked to E1 clock\n");
printf("\tpll-standalone\tSet the PLL to be in standalone mode\n");
printf("\toml-tei\tSet OML E1 TS and TEI\n");
printf("\tbport0-star\tSet BPORT0 line config to star\n");
printf("\tbport0-multiport\tSet BPORT0 line config to multiport\n");
printf("\tcreate-bport1\t\tCreate BPORT1 object\n");
printf("\tdelete-bport1\t\tDelete BPORT1 object\n");
printf("\tcreate-bport1\tCreate BPORT1 object\n");
printf("\tdelete-bport1\tDelete BPORT1 object\n");
}
static void handle_options(int argc, char **argv)
@@ -778,7 +754,7 @@ static void handle_options(int argc, char **argv)
serial_port = optarg;
break;
case 'b':
debug_parse_category_mask(stderr_target, optarg);
debug_parse_category_mask(optarg);
break;
case 's':
fname_software = optarg;
@@ -808,9 +784,6 @@ static void handle_options(int argc, char **argv)
}
if (optind < argc)
command = argv[optind];
if (optind+1 < argc)
value = argv[optind+1];
}
static int num_sigint;
@@ -834,12 +807,7 @@ int main(int argc, char **argv)
struct gsm_network *gsmnet;
int rc;
debug_init();
stderr_target = debug_target_create_stderr();
debug_add_target(stderr_target);
debug_set_all_filter(stderr_target, 1);
handle_options(argc, argv);
bts_model_bs11_init();
gsmnet = gsm_network_init(1, 1, NULL);
if (!gsmnet) {

View File

@@ -1,6 +1,6 @@
/* A hackish minimal BSC (+MSC +HLR) implementation */
/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
* All Rights Reserved
*
@@ -31,23 +31,17 @@
#include <getopt.h>
#include <openbsc/db.h>
#include <osmocore/select.h>
#include <openbsc/select.h>
#include <openbsc/debug.h>
#include <openbsc/e1_input.h>
#include <osmocore/talloc.h>
#include <openbsc/talloc.h>
#include <openbsc/signal.h>
/* MCC and MNC for the Location Area Identifier */
static struct debug_target *stderr_target;
struct gsm_network *bsc_gsmnet = 0;
static const char *database_name = "hlr.sqlite3";
static const char *config_file = "openbsc.cfg";
/* timer to store statistics */
#define DB_SYNC_INTERVAL 60, 0
static struct timer_list db_sync_timer;
extern int bsc_bootstrap_network(int (*mmc_rev)(struct gsm_network *, int, void *),
const char *cfg_file);
extern int bsc_shutdown_net(struct gsm_network *net);
@@ -111,10 +105,10 @@ static void handle_options(int argc, char** argv)
print_help();
exit(0);
case 's':
debug_set_use_color(stderr_target, 0);
debug_use_color(0);
break;
case 'd':
debug_parse_category_mask(stderr_target, optarg);
debug_parse_category_mask(optarg);
break;
case 'l':
database_name = strdup(optarg);
@@ -126,7 +120,7 @@ static void handle_options(int argc, char** argv)
create_pcap_file(optarg);
break;
case 'T':
debug_set_print_timestamp(stderr_target, 1);
debug_timestamp(1);
break;
case 'P':
ipacc_rtp_direct = 0;
@@ -138,7 +132,6 @@ static void handle_options(int argc, char** argv)
}
}
extern void *tall_vty_ctx;
static void signal_handler(int signal)
{
fprintf(stdout, "signal %u received\n", signal);
@@ -154,53 +147,22 @@ static void signal_handler(int signal)
/* in case of abort, we want to obtain a talloc report
* and then return to the caller, who will abort the process */
case SIGUSR1:
talloc_report(tall_vty_ctx, stderr);
talloc_report_full(tall_bsc_ctx, stderr);
break;
case SIGUSR2:
talloc_report_full(tall_vty_ctx, stderr);
break;
default:
break;
}
}
/* timer handling */
static int _db_store_counter(struct counter *counter, void *data)
{
return db_store_counter(counter);
}
static void db_sync_timer_cb(void *data)
{
/* store counters to database and re-schedule */
counters_for_each(_db_store_counter, NULL);
bsc_schedule_timer(&db_sync_timer, DB_SYNC_INTERVAL);
}
extern int bts_model_unknown_init(void);
extern int bts_model_bs11_init(void);
extern int bts_model_nanobts_init(void);
int main(int argc, char **argv)
{
int rc;
debug_init();
tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
talloc_ctx_init();
on_dso_load_token();
on_dso_load_rrlp();
on_dso_load_ho_dec();
stderr_target = debug_target_create_stderr();
debug_add_target(stderr_target);
bts_model_unknown_init();
bts_model_bs11_init();
bts_model_nanobts_init();
/* enable filters */
debug_set_all_filter(stderr_target, 1);
/* parse options */
handle_options(argc, argv);
@@ -220,11 +182,6 @@ int main(int argc, char **argv)
}
printf("DB: Database prepared.\n");
/* setup the timer */
db_sync_timer.cb = db_sync_timer_cb;
db_sync_timer.data = NULL;
bsc_schedule_timer(&db_sync_timer, DB_SYNC_INTERVAL);
rc = bsc_bootstrap_network(mncc_recv, config_file);
if (rc < 0)
exit(1);
@@ -232,12 +189,10 @@ int main(int argc, char **argv)
signal(SIGINT, &signal_handler);
signal(SIGABRT, &signal_handler);
signal(SIGUSR1, &signal_handler);
signal(SIGUSR2, &signal_handler);
signal(SIGPIPE, SIG_IGN);
while (1) {
bsc_upqueue(bsc_gsmnet);
debug_reset_context();
bsc_select_main(0);
}
}

View File

@@ -21,7 +21,7 @@
*/
#include <openbsc/gsm_data.h>
#include <osmocore/gsm_utils.h>
#include <openbsc/gsm_utils.h>
#include <openbsc/gsm_04_08.h>
#include <openbsc/abis_rsl.h>
#include <openbsc/abis_nm.h>
@@ -31,7 +31,7 @@
#include <openbsc/system_information.h>
#include <openbsc/paging.h>
#include <openbsc/signal.h>
#include <osmocore/talloc.h>
#include <openbsc/talloc.h>
/* global pointer to the gsm network data structure */
extern struct gsm_network *bsc_gsmnet;
@@ -330,7 +330,6 @@ static unsigned char nanobts_attr_bts[] = {
NM_ATT_NY1, 10, /* 10 retransmissions of physical config */
NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
NM_ATT_BSIC, HARDCODED_BSIC,
NM_ATT_IPACC_CGI, 0, 7, 0x00, 0xf1, 0x10, 0x00, 0x01, 0x00, 0x00,
};
static unsigned char nanobts_attr_radio[] = {
@@ -338,66 +337,6 @@ static unsigned char nanobts_attr_radio[] = {
NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
};
static unsigned char nanobts_attr_nse[] = {
NM_ATT_IPACC_NSEI, 0, 2, 0x03, 0x9d, /* NSEI 925 */
NM_ATT_IPACC_NS_CFG, 0, 7, 3, /* (un)blocking timer (Tns-block) */
3, /* (un)blocking retries */
3, /* reset timer (Tns-reset) */
3, /* reset retries */
30, /* test timer (Tns-test) */
3, /* alive timer (Tns-alive) */
10, /* alive retrires */
NM_ATT_IPACC_BSSGP_CFG, 0, 11,
3, /* blockimg timer (T1) */
3, /* blocking retries */
3, /* unblocking retries */
3, /* reset timer */
3, /* reset retries */
10, /* suspend timer (T3) in 100ms */
3, /* suspend retries */
10, /* resume timer (T4) in 100ms */
3, /* resume retries */
10, /* capability update timer (T5) */
3, /* capability update retries */
};
static unsigned char nanobts_attr_cell[] = {
NM_ATT_IPACC_RAC, 0, 1, 1, /* routing area code */
NM_ATT_IPACC_GPRS_PAGING_CFG, 0, 2,
5, /* repeat time (50ms) */
3, /* repeat count */
NM_ATT_IPACC_BVCI, 0, 2, 0x03, 0x9d, /* BVCI 925 */
NM_ATT_IPACC_RLC_CFG, 0, 9,
20, /* T3142 */
5, /* T3169 */
5, /* T3191 */
200, /* T3193 */
5, /* T3195 */
10, /* N3101 */
4, /* N3103 */
8, /* N3105 */
15, /* RLC CV countdown */
NM_ATT_IPACC_CODING_SCHEMES, 0, 2, 0x0f, 0x00,
NM_ATT_IPACC_RLC_CFG_2, 0, 5,
0x00, 250,
0x00, 250,
2, /* MCS2 */
#if 0
/* EDGE model only, breaks older models.
* Should inquire the BTS capabilities */
NM_ATT_IPACC_RLC_CFG_3, 0, 1,
2, /* MCS2 */
#endif
};
static unsigned char nanobts_attr_nsvc0[] = {
NM_ATT_IPACC_NSVCI, 0, 2, 0x03, 0x9d, /* 925 */
NM_ATT_IPACC_NS_LINK_CFG, 0, 8,
0x59, 0xd8, /* remote udp port (23000) */
192, 168, 100, 11, /* remote ip address */
0x59, 0xd8, /* local udp port (23000) */
};
/* Callback function to be called whenever we get a GSM 12.21 state change event */
int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
@@ -405,7 +344,6 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
struct gsm_bts *bts;
struct gsm_bts_trx *trx;
struct gsm_bts_trx_ts *ts;
struct gsm_bts_gprs_nsvc *nsvc;
/* This event-driven BTS setup is currently only required on nanoBTS */
@@ -417,15 +355,16 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
switch (obj_class) {
case NM_OC_SITE_MANAGER:
bts = container_of(obj, struct gsm_bts, site_mgr);
if ((new_state->operational == 2 &&
new_state->availability == NM_AVSTATE_OK) ||
(new_state->operational == 1 &&
new_state->availability == NM_AVSTATE_OFF_LINE))
if (new_state->operational == 2 &&
new_state->availability == NM_AVSTATE_OK) {
printf("STARTING SITE MANAGER\n");
abis_nm_opstart(bts, obj_class, 0xff, 0xff, 0xff);
}
break;
case NM_OC_BTS:
bts = obj;
if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
printf("STARTING BTS...\n");
patch_nm_tables(bts);
abis_nm_set_bts_attr(bts, nanobts_attr_bts,
sizeof(nanobts_attr_bts));
@@ -441,6 +380,7 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
trx = ts->trx;
if (new_state->operational == 1 &&
new_state->availability == NM_AVSTATE_DEPENDENCY) {
printf("STARTING OC Channel...\n");
patch_nm_tables(trx->bts);
enum abis_nm_chan_comb ccomb =
abis_nm_chcomb4pchan(ts->pchan);
@@ -459,53 +399,6 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
abis_nm_opstart(trx->bts, obj_class, trx->bts->bts_nr,
trx->nr, 0xff);
break;
case NM_OC_GPRS_NSE:
bts = container_of(obj, struct gsm_bts, gprs.nse);
if (!bts->gprs.enabled)
break;
if (new_state->availability == 5) {
abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
0xff, 0xff, nanobts_attr_nse,
sizeof(nanobts_attr_nse));
abis_nm_opstart(bts, obj_class, bts->bts_nr,
0xff, 0xff);
abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
0xff, 0xff, NM_STATE_UNLOCKED);
}
break;
case NM_OC_GPRS_CELL:
bts = container_of(obj, struct gsm_bts, gprs.cell);
if (!bts->gprs.enabled)
break;
if (new_state->availability == 5) {
abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
0, 0xff, nanobts_attr_cell,
sizeof(nanobts_attr_cell));
abis_nm_opstart(bts, obj_class, bts->bts_nr,
0, 0xff);
abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
0, 0xff, NM_STATE_UNLOCKED);
}
break;
case NM_OC_GPRS_NSVC:
nsvc = obj;
bts = nsvc->bts;
if (!bts->gprs.enabled)
break;
/* We skip NSVC1 since we only use NSVC0 */
if (nsvc->id == 1)
break;
if (new_state->availability == NM_AVSTATE_OFF_LINE) {
abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
nsvc->id, 0xff,
nanobts_attr_nsvc0,
sizeof(nanobts_attr_nsvc0));
abis_nm_opstart(bts, obj_class, bts->bts_nr,
nsvc->id, 0xff);
abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
nsvc->id, 0xff,
NM_STATE_UNLOCKED);
}
default:
break;
}
@@ -519,8 +412,6 @@ static int sw_activ_rep(struct msgb *mb)
struct gsm_bts *bts = mb->trx->bts;
struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
if (!trx)
return -EINVAL;
switch (foh->obj_class) {
case NM_OC_BASEB_TRANSC:
@@ -542,7 +433,8 @@ static int sw_activ_rep(struct msgb *mb)
* This code is here to make sure that on start
* a TRX remains locked.
*/
int rc_state = trx->nm_state.administrative;
int rc_state = trx->rf_locked ?
NM_STATE_LOCKED : NM_STATE_UNLOCKED;
/* Patch ARFCN into radio attribute */
nanobts_attr_radio[5] &= 0xf0;
nanobts_attr_radio[5] |= trx->arfcn >> 8;
@@ -798,14 +690,14 @@ static int set_system_infos(struct gsm_bts_trx *trx)
DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
rsl_bcch_info(trx, i, si_tmp, sizeof(si_tmp));
}
if (bts->gprs.enabled) {
i = 13;
rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_13);
if (rc < 0)
goto err_out;
DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
rsl_bcch_info(trx, RSL_SYSTEM_INFO_13, si_tmp, rc);
}
#ifdef GPRS
i = 13
rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_13);
if (rc < 0)
goto err_out;
DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
rsl_bcch_info(trx, RSL_SYSTEM_INFO_13, si_tmp, rc);
#endif
}
i = 5;
@@ -854,46 +746,19 @@ static void patch_nm_tables(struct gsm_bts *bts)
/* patch BSIC */
bs11_attr_bts[1] = bts->bsic;
nanobts_attr_bts[sizeof(nanobts_attr_bts)-11] = bts->bsic;
/* patch CGI */
abis_nm_ipaccess_cgi(nanobts_attr_bts+sizeof(nanobts_attr_bts)-7, bts);
nanobts_attr_bts[sizeof(nanobts_attr_bts)-1] = bts->bsic;
/* patch the power reduction */
bs11_attr_radio[5] = bts->c0->max_power_red / 2;
nanobts_attr_radio[1] = bts->c0->max_power_red / 2;
/* patch NSEI */
nanobts_attr_nse[3] = bts->gprs.nse.nsei >> 8;
nanobts_attr_nse[4] = bts->gprs.nse.nsei & 0xff;
/* patch NSVCI */
nanobts_attr_nsvc0[3] = bts->gprs.nsvc[0].nsvci >> 8;
nanobts_attr_nsvc0[4] = bts->gprs.nsvc[0].nsvci & 0xff;
/* patch IP address as SGSN IP */
*(u_int16_t *)(nanobts_attr_nsvc0+8) =
htons(bts->gprs.nsvc[0].remote_port);
*(u_int32_t *)(nanobts_attr_nsvc0+10) =
htonl(bts->gprs.nsvc[0].remote_ip);
*(u_int16_t *)(nanobts_attr_nsvc0+14) =
htons(bts->gprs.nsvc[0].local_port);
/* patch BVCI */
nanobts_attr_cell[12] = bts->gprs.cell.bvci >> 8;
nanobts_attr_cell[13] = bts->gprs.cell.bvci & 0xff;
/* patch RAC */
nanobts_attr_cell[3] = bts->gprs.rac;
}
static void bootstrap_rsl(struct gsm_bts_trx *trx)
{
LOGP(DRSL, LOGL_NOTICE, "bootstrapping RSL for BTS/TRX (%u/%u) "
"on ARFCN %u using MCC=%u MNC=%u LAC=%u CID=%u BSIC=%u TSC=%u\n",
trx->bts->nr, trx->nr, trx->arfcn, bsc_gsmnet->country_code,
bsc_gsmnet->network_code, trx->bts->location_area_code,
trx->bts->cell_identity, trx->bts->bsic, trx->bts->tsc);
"using MCC=%u MNC=%u BSIC=%u TSC=%u\n",
trx->bts->nr, trx->nr, bsc_gsmnet->country_code,
bsc_gsmnet->network_code, trx->bts->bsic, trx->bts->tsc);
set_system_infos(trx);
}
@@ -937,10 +802,8 @@ static int bootstrap_bts(struct gsm_bts *bts)
}
break;
case GSM_BAND_900:
if (bts->c0->arfcn < 1 ||
(bts->c0->arfcn > 124 && bts->c0->arfcn < 955) ||
bts->c0->arfcn > 1023) {
LOGP(DNM, LOGL_ERROR, "GSM900 channel must be between 1-124, 955-1023.\n");
if (bts->c0->arfcn < 1 || bts->c0->arfcn > 124) {
LOGP(DNM, LOGL_ERROR, "GSM900 channel must be between 1-124.\n");
return -EINVAL;
}
break;
@@ -964,6 +827,11 @@ static int bootstrap_bts(struct gsm_bts *bts)
/* T3212 is set from vty/config */
/* some defaults for our system information */
bts->si_common.rach_control.re = 1; /* no re-establishment */
bts->si_common.rach_control.tx_integer = 5; /* 8 slots spread */
bts->si_common.rach_control.max_trans = 3; /* 7 retransmissions */
bts->si_common.rach_control.t2 = 4; /* no emergency calls */
bts->si_common.cell_options.radio_link_timeout = 2; /* 12 */
bts->si_common.cell_options.dtx = 2; /* MS shall not use upplink DTX */
bts->si_common.cell_options.pwrc = 0; /* PWRC not set */

1237
openbsc/src/bsc_mgcp.c Normal file

File diff suppressed because it is too large Load Diff

72
openbsc/src/bsc_msc.c Normal file
View File

@@ -0,0 +1,72 @@
/* Routines to talk to the MSC using the IPA Protocol */
/*
* (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2010 by on-waves.com
* 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 2 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include <openbsc/bsc_msc.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int connect_to_msc(struct bsc_fd *fd, const char *ip, int port)
{
struct sockaddr_in sin;
int on = 1, ret;
printf("Attempting to connect MSC at %s:%d\n", ip, port);
fd->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
fd->when = BSC_FD_READ;
fd->data = NULL;
fd->priv_nr = 1;
if (fd->fd < 0) {
perror("Creating TCP socket failed");
return fd->fd;
}
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
inet_aton(ip, &sin.sin_addr);
setsockopt(fd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
ret = connect(fd->fd, (struct sockaddr *) &sin, sizeof(sin));
if (ret < 0) {
perror("Connection failed");
return ret;
}
ret = bsc_register_fd(fd);
if (ret < 0) {
perror("Registering the fd failed");
close(fd->fd);
return ret;
}
return ret;
}

809
openbsc/src/bsc_msc_ip.c Normal file
View File

@@ -0,0 +1,809 @@
/* A hackish minimal BSC (+MSC +HLR) implementation */
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009 by on-waves.com
* 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 2 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define _GNU_SOURCE
#include <getopt.h>
#include <openbsc/select.h>
#include <openbsc/debug.h>
#include <openbsc/e1_input.h>
#include <openbsc/talloc.h>
#include <openbsc/select.h>
#include <openbsc/ipaccess.h>
#include <openbsc/bssap.h>
#include <openbsc/paging.h>
#include <openbsc/signal.h>
#include <openbsc/chan_alloc.h>
#include <openbsc/bsc_msc.h>
#include <sccp/sccp.h>
/* SCCP helper */
#define SCCP_IT_TIMER 60
/* MCC and MNC for the Location Area Identifier */
struct gsm_network *bsc_gsmnet = 0;
static const char *config_file = "openbsc.cfg";
static char *msc_address = "127.0.0.1";
static struct bsc_fd msc_connection;
static struct in_addr local_addr;
extern int ipacc_rtp_direct;
extern int bsc_bootstrap_network(int (*layer4)(struct gsm_network *, int, void *), const char *cfg_file);
extern int bsc_shutdown_net(struct gsm_network *net);
struct bss_sccp_connection_data *bss_sccp_create_data()
{
struct bss_sccp_connection_data *data;
data = _talloc_zero(tall_bsc_ctx,
sizeof(struct bss_sccp_connection_data),
"bsc<->msc");
if (!data)
return NULL;
INIT_LLIST_HEAD(&data->sccp_queue);
INIT_LLIST_HEAD(&data->gsm_queue);
return data;
}
void bss_sccp_free_data(struct bss_sccp_connection_data *data)
{
bsc_del_timer(&data->T10);
bsc_del_timer(&data->sccp_it);
bsc_free_queued(data->sccp);
bts_free_queued(data);
talloc_free(data);
}
static void sccp_it_fired(void *_data)
{
struct bss_sccp_connection_data *data =
(struct bss_sccp_connection_data *) _data;
sccp_connection_send_it(data->sccp);
bsc_schedule_timer(&data->sccp_it, SCCP_IT_TIMER, 0);
}
/* GSM subscriber drop-ins */
extern struct llist_head *subscr_bsc_active_subscriber(void);
struct gsm_subscriber *find_subscriber(u_int8_t type, const char *mi_string)
{
struct gsm_subscriber *subscr;
u_int32_t tmsi = GSM_RESERVED_TMSI;
if (type == GSM_MI_TYPE_TMSI) {
tmsi = tmsi_from_string(mi_string);
if (tmsi == GSM_RESERVED_TMSI) {
DEBUGP(DMSC, "The TMSI is the reserved one.\n");
return NULL;
}
}
llist_for_each_entry(subscr, subscr_bsc_active_subscriber(), entry) {
if (type == GSM_MI_TYPE_TMSI && tmsi == subscr->tmsi) {
return subscr_get(subscr);
} else if (type == GSM_MI_TYPE_IMSI && strcmp(mi_string, subscr->imsi) == 0) {
return subscr_get(subscr);
}
}
DEBUGP(DMSC, "No subscriber has been found.\n");
return NULL;
}
/* SCCP handling */
void msc_outgoing_sccp_data(struct sccp_connection *conn, struct msgb *msg, unsigned int len)
{
struct bssmap_header *bs;
if (len < 1) {
DEBUGP(DMSC, "The header is too short.\n");
return;
}
switch (msg->l3h[0]) {
case BSSAP_MSG_BSS_MANAGEMENT:
msg->l4h = &msg->l3h[sizeof(*bs)];
msg->lchan = sccp_get_lchan(conn->data_ctx);
bssmap_rcvmsg_dt1(conn, msg, len - sizeof(*bs));
break;
case BSSAP_MSG_DTAP:
dtap_rcvmsg(sccp_get_lchan(conn->data_ctx), msg, len);
break;
default:
DEBUGPC(DMSC, "Unimplemented msg type: %d\n", msg->l3h[0]);
}
}
void msc_outgoing_sccp_state(struct sccp_connection *conn, int old_state)
{
if (conn->connection_state >= SCCP_CONNECTION_STATE_RELEASE_COMPLETE) {
DEBUGP(DMSC, "Freeing sccp conn: %p state: %d\n", conn, conn->connection_state);
if (sccp_get_lchan(conn->data_ctx) != NULL) {
struct gsm_lchan *lchan = sccp_get_lchan(conn->data_ctx);
DEBUGP(DMSC, "ERROR: The lchan is still associated\n.");
lchan->msc_data = NULL;
put_lchan(lchan);
}
bss_sccp_free_data((struct bss_sccp_connection_data *)conn->data_ctx);
sccp_connection_free(conn);
return;
} else if (conn->connection_state == SCCP_CONNECTION_STATE_ESTABLISHED) {
struct bss_sccp_connection_data *con_data;
DEBUGP(DMSC, "Connection established: %p\n", conn);
/* start the inactivity test timer */
con_data = (struct bss_sccp_connection_data *) conn->data_ctx;
con_data->sccp_it.cb = sccp_it_fired;
con_data->sccp_it.data = con_data;
bsc_schedule_timer(&con_data->sccp_it, SCCP_IT_TIMER, 0);
bsc_send_queued(conn);
}
}
/*
* General COMPLETE LAYER3 INFORMATION handling for
* PAGING RESPONSE, LOCATION UPDATING REQUEST, CM REESTABLISHMENT REQUEST,
* CM SERVICE REQUEST, IMSI DETACH, IMMEDIATE SETUP.
*
* IMMEDIATE SETUP is coming from GROUP CC that is not yet
* supported...
*/
int open_sccp_connection(struct msgb *layer3)
{
struct bss_sccp_connection_data *con_data;
struct sccp_connection *sccp_connection;
struct msgb *data;
DEBUGP(DMSC, "Opening new layer3 connection\n");
sccp_connection = sccp_connection_socket();
if (!sccp_connection) {
DEBUGP(DMSC, "Failed to allocate memory.\n");
return -ENOMEM;
}
data = bssmap_create_layer3(layer3);
if (!data) {
DEBUGP(DMSC, "Failed to allocate complete layer3.\n");
sccp_connection_free(sccp_connection);
return -ENOMEM;
}
con_data = bss_sccp_create_data();
if (!con_data) {
DEBUGP(DMSC, "Failed to allocate bss<->msc data.\n");
sccp_connection_free(sccp_connection);
msgb_free(data);
return -ENOMEM;
}
/* initialize the bridge */
con_data->lchan = layer3->lchan;
con_data->sccp = sccp_connection;
sccp_connection->state_cb = msc_outgoing_sccp_state;
sccp_connection->data_cb = msc_outgoing_sccp_data;
sccp_connection->data_ctx = con_data;
layer3->lchan->msc_data = con_data;
/* FIXME: Use transaction for this */
use_lchan(layer3->lchan);
sccp_connection_connect(sccp_connection, &sccp_ssn_bssap, data);
msgb_free(data);
return 1;
}
/* figure out if this is the inial layer3 message */
static int send_dtap_or_open_connection(struct msgb *msg)
{
if (msg->lchan->msc_data) {
struct msgb *dtap = dtap_create_msg(msg, 0);
if (!dtap) {
DEBUGP(DMSC, "Creating a DTAP message failed.\n");
return -1;
}
bsc_queue_connection_write(lchan_get_sccp(msg->lchan), dtap);
return 1;
} else {
return open_sccp_connection(msg);
}
}
/* Receive a PAGING RESPONSE message from the MS */
static int handle_paging_response(struct msgb *msg)
{
struct gsm_subscriber *subscr;
char mi_string[GSM48_MI_SIZE];
u_int8_t mi_type;
gsm48_paging_extract_mi(msg, mi_string, &mi_type);
DEBUGP(DMSC, "PAGING RESPONSE: mi_type=0x%02x MI(%s)\n",
mi_type, mi_string);
subscr = find_subscriber(mi_type, mi_string);
if (!subscr)
return -EINVAL;
/* force the paging to stop at every bts */
subscr->lac = GSM_LAC_RESERVED_ALL_BTS;
if (gsm48_handle_paging_resp(msg, subscr) != 0) {
DEBUGP(DMSC, "Paging failed.\n");
return -1;
}
/* open a new transaction and SCCP connection */
return send_dtap_or_open_connection(msg);
}
/* Receive a CIPHER MODE COMPLETE from the MS */
static int handle_cipher_m_complete(struct msgb *msg)
{
struct msgb *resp;
DEBUGP(DMSC, "CIPHER MODE COMPLETE from MS, forwarding to MSC\n");
resp = bssmap_create_cipher_complete(msg);
if (!resp) {
DEBUGP(DMSC, "Creating MSC response failed.\n");
return -1;
}
/* handled this message */
bts_unblock_queue(msg->lchan->msc_data);
bsc_queue_connection_write(lchan_get_sccp(msg->lchan), resp);
return 1;
}
/* Receive a ASSIGNMENT COMPLETE */
static int handle_ass_compl(struct msgb *msg)
{
struct gsm_lchan *old_chan;
struct gsm48_hdr *gh = msgb_l3(msg);
DEBUGP(DMSC, "ASSIGNMENT COMPLETE from MS, forwarding to MSC\n");
if (!msg->lchan->msc_data) {
DEBUGP(DMSC, "No MSC data\n");
put_lchan(msg->lchan);
return -1;
}
if (msg->lchan->msc_data->secondary_lchan != msg->lchan) {
LOGP(DMSC, LOGL_NOTICE, "Wrong assignment complete.\n");
put_lchan(msg->lchan);
return -1;
}
if (msgb_l3len(msg) - sizeof(*gh) != 1) {
DEBUGP(DMSC, "assignment failure invalid: %d\n",
msgb_l3len(msg) - sizeof(*gh));
put_lchan(msg->lchan);
return -1;
}
/* swap the channels and release the old */
old_chan = msg->lchan->msc_data->lchan;
msg->lchan->msc_data->lchan = msg->lchan;
msg->lchan->msc_data->secondary_lchan = NULL;
old_chan->msc_data = NULL;
/* give up the old channel to not do a SACCH deactivate */
subscr_put(old_chan->subscr);
old_chan->subscr = NULL;
put_lchan(old_chan);
/* activate audio on it... */
if (is_ipaccess_bts(msg->lchan->ts->trx->bts) && msg->lchan->tch_mode != GSM48_CMODE_SIGN)
rsl_ipacc_crcx(msg->lchan);
gsm0808_send_assignment_compl(msg->lchan, gh->data[0]);
return 1;
}
/*
* Receive a ASSIGNMENT FAILURE. If the message is failed
* to be parsed the T10 timer will send the failure.
*/
static int handle_ass_fail(struct msgb *msg)
{
struct gsm48_hdr *gh = msgb_l3(msg);
DEBUGP(DMSC, "ASSIGNMENT FAILURE from MS, forwarding to MSC\n");
if (!msg->lchan->msc_data) {
DEBUGP(DMSC, "No MSC data\n");
put_lchan(msg->lchan);
return -1;
}
if (msg->lchan->msc_data->secondary_lchan != msg->lchan) {
LOGP(DMSC, LOGL_NOTICE, "Wrong assignment complete.\n");
put_lchan(msg->lchan);
return -1;
}
if (msgb_l3len(msg) - sizeof(*gh) != 1) {
DEBUGP(DMSC, "assignment failure invalid: %d\n",
msgb_l3len(msg) - sizeof(*gh));
put_lchan(msg->lchan);
return -1;
}
gsm0808_send_assignment_failure(msg->lchan,
GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, &gh->data[0]);
return 1;
}
/*
* Receive a GSM04.08 MODIFY ACK. Actually we have to check
* the content to see if this was a success or not.
*/
static int handle_modify_ack(struct msgb *msg)
{
int rc;
/* modify RSL */
rc = gsm48_rx_rr_modif_ack(msg);
if (rc < 0)
gsm0808_send_assignment_failure(msg->lchan,
GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE, NULL);
else
gsm0808_send_assignment_compl(msg->lchan, 0);
return 1;
}
/* Receive a GSM 04.08 Radio Resource (RR) message */
static int gsm0408_rcv_rr(struct msgb *msg)
{
struct gsm48_hdr *gh = msgb_l3(msg);
int rc = 0;
switch (gh->msg_type) {
case GSM48_MT_RR_PAG_RESP:
rc = handle_paging_response(msg);
break;
case GSM48_MT_RR_MEAS_REP:
/* ignore measurement for now */
rc = -1;
break;
case GSM48_MT_RR_CIPH_M_COMPL:
rc = handle_cipher_m_complete(msg);
break;
case GSM48_MT_RR_ASS_COMPL:
rc = handle_ass_compl(msg);
break;
case GSM48_MT_RR_ASS_FAIL:
rc = handle_ass_fail(msg);
break;
case GSM48_MT_RR_CHAN_MODE_MODIF_ACK:
rc = handle_modify_ack(msg);
break;
default:
break;
}
return rc;
}
/* Receive a GSM 04.08 Mobility Management (MM) message */
static int gsm0408_rcv_mm(struct msgb *msg)
{
struct gsm48_hdr *gh = msgb_l3(msg);
int rc = 0;
switch (gh->msg_type & 0xbf) {
case GSM48_MT_MM_LOC_UPD_REQUEST:
case GSM48_MT_MM_CM_REEST_REQ:
case GSM48_MT_MM_CM_SERV_REQ:
case GSM48_MT_MM_IMSI_DETACH_IND:
rc = send_dtap_or_open_connection(msg);
break;
default:
break;
}
return rc;
}
int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id)
{
struct gsm48_hdr *gh = msgb_l3(msg);
u_int8_t pdisc = gh->proto_discr & 0x0f;
int rc = 0;
switch (pdisc) {
case GSM48_PDISC_RR:
rc = gsm0408_rcv_rr(msg);
break;
case GSM48_PDISC_MM:
rc = gsm0408_rcv_mm(msg);
break;
default:
break;
}
/*
* if we have a sccp connection and didn't handle the message
* forward it to the MSC using DTAP
*/
if (rc == 0 && msg->lchan->msc_data && lchan_get_sccp(msg->lchan)) {
struct msgb *dtap = dtap_create_msg(msg, link_id);
if (!dtap) {
DEBUGP(DMSC, "Creating a DTAP message failed.\n");
return -1;
}
bsc_queue_connection_write(lchan_get_sccp(msg->lchan), dtap);
}
return rc;
}
/* handle ipaccess signals */
static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
{
struct gsm_lchan *lchan = signal_data;
struct gsm_bts_trx_ts *ts;
int rc;
if (subsys != SS_ABISIP)
return 0;
ts = lchan->ts;
switch (signal) {
case S_ABISIP_CRCX_ACK:
/* we can ask it to connect now */
if (lchan->msc_data) {
DEBUGP(DMSC, "Connecting BTS to port: %d conn: %d\n",
lchan->msc_data->rtp_port, lchan->abis_ip.conn_id);
int rtp_payload = ts->trx->bts->network->rtp_payload;
if (rtp_payload == 0)
rtp_payload = lchan->abis_ip.rtp_payload2;
rc = rsl_ipacc_mdcx(lchan, ntohl(local_addr.s_addr),
lchan->msc_data->rtp_port,
rtp_payload);
if (rc < 0) {
DEBUGP(DMSC, "Failed to send connect: %d\n", rc);
return rc;
}
}
break;
case S_ABISIP_DLCX_IND:
break;
}
return 0;
}
static void print_usage()
{
printf("Usage: bsc_hack\n");
}
/*
* SCCP handling
*/
static int msc_sccp_write_ipa(struct msgb *msg, void *data)
{
int ret;
DEBUGP(DMSC, "Sending SCCP to MSC: %u\n", msgb_l2len(msg));
ipaccess_prepend_header(msg, IPAC_PROTO_SCCP);
DEBUGP(DMI, "MSC TX %s\n", hexdump(msg->l2h, msgb_l2len(msg)));
ret = write(msc_connection.fd, msg->data, msg->len);
if (ret <= 0) {
perror("MSC: Failed to send SCCP");
return -1;
}
return 0;
}
static int msc_sccp_accept(struct sccp_connection *connection, void *data)
{
DEBUGP(DMSC, "Rejecting incoming SCCP connection.\n");
return -1;
}
static int msc_sccp_read(struct msgb *msgb, unsigned int length, void *data)
{
struct bssmap_header *bs;
DEBUGP(DMSC, "Incoming SCCP message ftom MSC: %s\n", hexdump(msgb->l3h, length));
if (length < sizeof(*bs)) {
DEBUGP(DMSC, "The header is too short.\n");
return -1;
}
bs = (struct bssmap_header *) msgb->l3h;
if (bs->length < length - sizeof(*bs))
return -1;
switch (bs->type) {
case BSSAP_MSG_BSS_MANAGEMENT:
msgb->l4h = &msgb->l3h[sizeof(*bs)];
bssmap_rcvmsg_udt(bsc_gsmnet, msgb, length - sizeof(*bs));
break;
default:
DEBUGPC(DMSC, "Unimplemented msg type: %d\n", bs->type);
}
return 0;
}
/*
* network initialisation
*/
static void initialize_if_needed(void)
{
if (!bsc_gsmnet) {
int rc;
struct msgb *msg;
fprintf(stderr, "Bootstraping the network. Sending GSM08.08 reset.\n");
rc = bsc_bootstrap_network(NULL, config_file);
if (rc < 0) {
fprintf(stderr, "Bootstrapping the network failed. exiting.\n");
exit(1);
}
/* send a gsm 08.08 reset message from here */
msg = bssmap_create_reset();
if (!msg) {
DEBUGP(DMSC, "Failed to create the reset message.\n");
return;
}
sccp_write(msg, &sccp_ssn_bssap, &sccp_ssn_bssap, 0);
msgb_free(msg);
}
}
/*
* callback with IP access data
*/
static int ipaccess_a_fd_cb(struct bsc_fd *bfd, unsigned int what)
{
int error;
struct msgb *msg = ipaccess_read_msg(bfd, &error);
struct ipaccess_head *hh;
if (!msg) {
if (error == 0) {
fprintf(stderr, "The connection to the MSC was lost, exiting\n");
exit(-2);
}
fprintf(stderr, "Failed to parse ip access message: %d\n", error);
return -1;
}
DEBUGP(DMSC, "From MSC: %s proto: %d\n", hexdump(msg->data, msg->len), msg->l2h[0]);
/* handle base message handling */
hh = (struct ipaccess_head *) msg->data;
ipaccess_rcvmsg_base(msg, bfd);
/* initialize the networking. This includes sending a GSM08.08 message */
if (hh->proto == IPAC_PROTO_IPACCESS && msg->l2h[0] == IPAC_MSGT_ID_ACK)
initialize_if_needed();
else if (hh->proto == IPAC_PROTO_SCCP)
sccp_system_incoming(msg);
msgb_free(msg);
return 0;
}
static void print_help()
{
printf(" Some useful help...\n");
printf(" -h --help this text\n");
printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
printf(" -s --disable-color\n");
printf(" -c --config-file filename The config file to use.\n");
printf(" -m --msc=IP. The address of the MSC.\n");
printf(" -l --local=IP. The local address of the MGCP.\n");
}
static void handle_options(int argc, char** argv)
{
while (1) {
int option_index = 0, c;
static struct option long_options[] = {
{"help", 0, 0, 'h'},
{"debug", 1, 0, 'd'},
{"config-file", 1, 0, 'c'},
{"disable-color", 0, 0, 's'},
{"timestamp", 0, 0, 'T'},
{"rtp-proxy", 0, 0, 'P'},
{"msc", 1, 0, 'm'},
{"local", 1, 0, 'l'},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "hd:sTPc:m:l:",
long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 'h':
print_usage();
print_help();
exit(0);
case 's':
debug_use_color(0);
break;
case 'd':
debug_parse_category_mask(optarg);
break;
case 'c':
config_file = strdup(optarg);
break;
case 'T':
debug_timestamp(1);
break;
case 'P':
ipacc_rtp_direct = 0;
break;
case 'm':
msc_address = strdup(optarg);
break;
case 'l':
inet_aton(optarg, &local_addr);
break;
default:
/* ignore */
break;
}
}
}
static void signal_handler(int signal)
{
fprintf(stdout, "signal %u received\n", signal);
switch (signal) {
case SIGINT:
bsc_shutdown_net(bsc_gsmnet);
sleep(3);
exit(0);
break;
case SIGABRT:
/* in case of abort, we want to obtain a talloc report
* and then return to the caller, who will abort the process */
case SIGUSR1:
talloc_report_full(tall_bsc_ctx, stderr);
break;
default:
break;
}
}
static void test_mode()
{
static const u_int8_t assignment_req[] = { 0x01, 0x0b, 0x03, 0x01, 0x0b, 0x25, 0x01, 0x00, 0x01 };
struct gsm_lchan lchan;
struct sccp_connection conn;
struct bss_sccp_connection_data data;
struct gsm_bts_trx_ts trx_ts;
struct gsm_bts_trx trx;
struct gsm_bts bts;
int rc;
/* initialize */
fprintf(stderr, "Bootstraping the network. Sending GSM08.08 reset.\n");
rc = bsc_bootstrap_network(NULL, config_file);
if (rc < 0) {
fprintf(stderr, "Bootstrapping the network failed. exiting.\n");
exit(1);
}
bts.network = bsc_gsmnet;
trx.bts = &bts;
trx_ts.trx = &trx;
lchan.ts = &trx_ts;
/* create fake data connection */
data.lchan = &lchan;
data.sccp = &conn;
lchan.msc_data = &data;
conn.data_ctx = &data;
struct msgb *msg = msgb_alloc(400, "test-msg");
msg->lchan = &lchan;
msg->l4h = msgb_put(msg, ARRAY_SIZE(assignment_req));
memcpy(msg->l4h, assignment_req, ARRAY_SIZE(assignment_req));
bssmap_rcvmsg_dt1(&conn, msg, ARRAY_SIZE(assignment_req));
}
int main(int argc, char **argv)
{
int rc;
tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
/* parse options */
handle_options(argc, argv);
/* seed the PRNG */
srand(time(NULL));
/* initialize sccp */
sccp_system_init(msc_sccp_write_ipa, NULL);
sccp_connection_set_incoming(&sccp_ssn_bssap, msc_sccp_accept, NULL);
sccp_set_read(&sccp_ssn_bssap, msc_sccp_read, NULL);
/* initialize ipaccess handling */
register_signal_handler(SS_ABISIP, handle_abisip_signal, NULL);
msc_connection.cb = ipaccess_a_fd_cb;
rc = connect_to_msc(&msc_connection, msc_address, 5000);
if (rc < 0) {
fprintf(stderr, "Opening the MSC connection failed.\n");
exit(1);
}
signal(SIGINT, &signal_handler);
signal(SIGABRT, &signal_handler);
signal(SIGUSR1, &signal_handler);
signal(SIGPIPE, SIG_IGN);
while (1) {
bsc_select_main(0);
}
}

View File

@@ -24,9 +24,9 @@
#include <errno.h>
#include <openbsc/debug.h>
#include <osmocore/talloc.h>
#include <osmocore/timer.h>
#include <osmocore/linuxlist.h>
#include <openbsc/talloc.h>
#include <openbsc/timer.h>
#include <openbsc/linuxlist.h>
#include <openbsc/bsc_rll.h>
#include <openbsc/gsm_data.h>
#include <openbsc/chan_alloc.h>

1299
openbsc/src/bssap.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,84 +0,0 @@
/* ip.access nanoBTS specific code */
/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
*
* 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 2 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include <sys/types.h>
#include <openbsc/gsm_data.h>
#include <osmocore/tlv.h>
#include <openbsc/abis_nm.h>
static struct gsm_bts_model model_nanobts = {
.type = GSM_BTS_TYPE_NANOBTS,
.nm_att_tlvdef = {
.def = {
/* ip.access specifics */
[NM_ATT_IPACC_DST_IP] = { TLV_TYPE_FIXED, 4 },
[NM_ATT_IPACC_DST_IP_PORT] = { TLV_TYPE_FIXED, 2 },
[NM_ATT_IPACC_STREAM_ID] = { TLV_TYPE_TV, },
[NM_ATT_IPACC_FREQ_CTRL] = { TLV_TYPE_TV, },
[NM_ATT_IPACC_SEC_OML_CFG] = { TLV_TYPE_FIXED, 6 },
[NM_ATT_IPACC_IP_IF_CFG] = { TLV_TYPE_FIXED, 8 },
[NM_ATT_IPACC_IP_GW_CFG] = { TLV_TYPE_FIXED, 12 },
[NM_ATT_IPACC_IN_SERV_TIME] = { TLV_TYPE_FIXED, 4 },
[NM_ATT_IPACC_LOCATION] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_PAGING_CFG] = { TLV_TYPE_FIXED, 2 },
[NM_ATT_IPACC_UNIT_ID] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_UNIT_NAME] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_SNMP_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_PRIM_OML_CFG_LIST] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_NV_FLAGS] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_FREQ_CTRL] = { TLV_TYPE_FIXED, 2 },
[NM_ATT_IPACC_PRIM_OML_FB_TOUT] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_CUR_SW_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_TIMING_BUS] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_CGI] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_RAC] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_OBJ_VERSION] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_GPRS_PAGING_CFG]= { TLV_TYPE_TL16V },
[NM_ATT_IPACC_NSEI] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_BVCI] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_NSVCI] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_NS_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_BSSGP_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_NS_LINK_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_RLC_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_ALM_THRESH_LIST]= { TLV_TYPE_TL16V },
[NM_ATT_IPACC_MONIT_VAL_LIST] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_TIB_CONTROL] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_SUPP_FEATURES] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_CODING_SCHEMES] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_RLC_CFG_2] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_HEARTB_TOUT] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_UPTIME] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_RLC_CFG_3] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_SSL_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_SEC_POSSIBLE] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_IML_SSL_STATE] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_REVOC_DATE] = { TLV_TYPE_TL16V },
},
},
};
int bts_model_nanobts_init(void)
{
return gsm_bts_model_register(&model_nanobts);
}

View File

@@ -1,66 +0,0 @@
/* Siemens BS-11 specific code */
/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
*
* 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 2 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include <sys/types.h>
#include <openbsc/gsm_data.h>
#include <osmocore/tlv.h>
#include <openbsc/abis_nm.h>
static struct gsm_bts_model model_bs11 = {
.type = GSM_BTS_TYPE_BS11,
.nm_att_tlvdef = {
.def = {
[NM_ATT_AVAIL_STATUS] = { TLV_TYPE_TLV },
/* BS11 specifics */
[NM_ATT_BS11_ESN_FW_CODE_NO] = { TLV_TYPE_TLV },
[NM_ATT_BS11_ESN_HW_CODE_NO] = { TLV_TYPE_TLV },
[NM_ATT_BS11_ESN_PCB_SERIAL] = { TLV_TYPE_TLV },
[NM_ATT_BS11_BOOT_SW_VERS] = { TLV_TYPE_TLV },
[0xd5] = { TLV_TYPE_TLV },
[0xa8] = { TLV_TYPE_TLV },
[NM_ATT_BS11_PASSWORD] = { TLV_TYPE_TLV },
[NM_ATT_BS11_TXPWR] = { TLV_TYPE_TLV },
[NM_ATT_BS11_RSSI_OFFS] = { TLV_TYPE_TLV },
[NM_ATT_BS11_LINE_CFG] = { TLV_TYPE_TV },
[NM_ATT_BS11_L1_PROT_TYPE] = { TLV_TYPE_TV },
[NM_ATT_BS11_BIT_ERR_THESH] = { TLV_TYPE_FIXED, 2 },
[NM_ATT_BS11_DIVERSITY] = { TLV_TYPE_TLV },
[NM_ATT_BS11_LMT_LOGON_SESSION]={ TLV_TYPE_TLV },
[NM_ATT_BS11_LMT_LOGIN_TIME] = { TLV_TYPE_TLV },
[NM_ATT_BS11_LMT_USER_ACC_LEV] ={ TLV_TYPE_TLV },
[NM_ATT_BS11_LMT_USER_NAME] = { TLV_TYPE_TLV },
[NM_ATT_BS11_BTS_STATE] = { TLV_TYPE_TLV },
[NM_ATT_BS11_E1_STATE] = { TLV_TYPE_TLV },
[NM_ATT_BS11_PLL_MODE] = { TLV_TYPE_TLV },
[NM_ATT_BS11_PLL] = { TLV_TYPE_TLV },
[NM_ATT_BS11_CCLK_ACCURACY] = { TLV_TYPE_TV },
[NM_ATT_BS11_CCLK_TYPE] = { TLV_TYPE_TV },
[0x95] = { TLV_TYPE_FIXED, 2 },
},
},
};
int bts_model_bs11_init(void)
{
return gsm_bts_model_register(&model_bs11);
}

Some files were not shown because too many files have changed in this diff Show More