Compare commits

..

712 Commits

Author SHA1 Message Date
Holger Hans Peter Freyther
8ce50ba2f7 rf: Delay execution of commands
Delay executing RF commands up to a second. If many commands
arrive within a second then just execute the last command.
2011-02-14 23:41:42 +01:00
Holger Hans Peter Freyther
3f9b6a6539 rf: Verify that the requested mode is entered and drop OML in error
Verify that the BTS is following our orders, if we think there was
an error we will drop the OML connection.
2011-02-14 23:27:18 +01:00
Holger Hans Peter Freyther
b5bb75fbfd rf: Remember the last command requested on the RF CMD interface 2011-02-14 22:34:47 +01:00
Holger Hans Peter Freyther
af5b88fb07 welcome: Fix the str concat here as well. Start to count at 0. 2010-11-26 00:13:02 +01:00
Holger Hans Peter Freyther
0366e67f78 vty: For ipaccess we will dump if the OML connection is present 2010-11-25 16:32:32 +01:00
Holger Hans Peter Freyther
c3f0aeee30 mid-call: Do not lose the first word of the message 2010-11-22 22:27:39 +01:00
Holger Hans Peter Freyther
2413efa47b mid-call: Make the mid-call behavior the default for switching things off
When switching the RF off we will always go through the grace
period, add a direct off mode to switch it off directly. Make
the query return a 'g' if we are in the process of switching
things over.
2010-11-22 19:32:13 +01:00
Holger Hans Peter Freyther
e6fd64d000 mid-call: Implement a timer to go from grace to off.
Start the timer... switch it off when we do the final
tranistion by a command.
2010-11-22 19:15:38 +01:00
Holger Hans Peter Freyther
00d34cd8c6 mid-call: Rename ussd-grace to mid-call 2010-11-22 18:31:35 +01:00
Holger Hans Peter Freyther
58c5e587a5 mid-call: Introduce a timeout to switch from grace to rf off. 2010-11-22 18:25:02 +01:00
Holger Hans Peter Freyther
13b24827d7 bsc_msc_ip: Clean the header, the defines can come from bssap.h 2010-11-03 15:52:11 +01:00
Holger Hans Peter Freyther
ba482438a0 ussd: Catch up with libosmocore and pass the gsm48_hdr
Conflicts:

	openbsc/src/ussd.c
2010-10-18 09:54:33 +02:00
Holger Hans Peter Freyther
4cc21eaa42 ussd: Move the code libosmocore, increase the version number.
Move the code to libosmocore, update the header file and the
version required in the configure.in.

Conflicts:

	openbsc/configure.in
	openbsc/include/openbsc/gsm_04_80.h
	openbsc/src/gsm_04_80.c
2010-10-18 09:54:33 +02:00
Holger Hans Peter Freyther
e9f8a258a8 bssap.c: Fix unaligned memory access by using the read_data16 2010-10-08 20:11:47 +08:00
Holger Hans Peter Freyther
5797ca85c1 bssap.c: The lac is only 16bit.. no need to read two bytes of garbage
Recreate a read_data16, use it to parse the LAC from the Cell Identifier..
we check that the length is at least 3 byte and read from byte 1..
which means reading four bytes is totally wrong.
2010-10-08 20:08:36 +08:00
Holger Hans Peter Freyther
2537b2f836 This is 0.3.99.20 with bring-up hacks, possible crash fixes 2010-10-07 05:56:42 +08:00
Holger Hans Peter Freyther
1168d13e0c msc: Only unregister the fd if the fd value is valid.
This makes sure that someone can call bsc_msc_lost multiple times
even if there is no MSC connection. This makes sense as bsc_msc_lost
is public and be called from client code.
2010-10-07 04:55:42 +08:00
Holger Hans Peter Freyther
588c423f12 msc: Stop the connection timeout when we unregister the bfd
When we dropped the connection... stop the timer as we might
call bsc_unregister_fd twice...
2010-10-07 04:42:03 +08:00
Holger Hans Peter Freyther
088601004c gsm_04_80: Require libosmocore for creating USSD messages
Use the libosmocore to create USSD messages, increase the
minimum version of libosmocore, add header files, remove
the code.

Conflicts:

	openbsc/configure.in
	openbsc/include/openbsc/gsm_04_80.h
	openbsc/src/gsm_04_08.c
	openbsc/src/gsm_04_80.c
2010-10-06 23:36:22 +08:00
Holger Hans Peter Freyther
55982ca9a7 oml: In case we get a NACK, drop the OML connection and hope for the best
Assume that a NACK is a onetime failure and that on the next
attempt it will work better. If that is not the case we might
even send a reboot to the BTS.
2010-10-03 01:48:45 +08:00
Holger Hans Peter Freyther
91a035d2fb oml: Another band aid for reliable BTS init...
Sometimes the operative change for the NSE is getting nacked,
this might be due that we send it before we get the OPSTART ACK
for this object class. Send it from the CELL availability as
a workaround. This init code needs to be changed to make these
dependencies work more reliable.
2010-10-02 04:38:04 +08:00
Holger Hans Peter Freyther
5ed2e3004b ipaccess: Re-Enable the delay between commands...
We still need to keep the delay during startup as the
GPRS code tried to initialize too early.
2010-10-02 02:16:13 +08:00
Holger Hans Peter Freyther
00460d3bc5 bsc_msc_ip: Save the welcome text, add an 'e' to the command. 2010-09-29 20:39:09 +08:00
Holger Hans Peter Freyther
dcb7ad3f2c bsc_msc_ip: Save the bsc-welcome-text message 2010-09-29 20:38:26 +08:00
Holger Hans Peter Freyther
74e7cc4c4a Add missing osmo_bsc_grace.h
This file got lost during a rename.
2010-09-29 18:44:43 +08:00
Holger Hans Peter Freyther
667cba9d28 bsc: Send a USSD command after we have a LU Accept and a new_subscriber 2010-09-26 18:49:03 +08:00
Holger Hans Peter Freyther
6f926f0197 bsc: Add a ussd_welcome_text variable and VTY command
Add a command to set the welcome text for the USSD.
2010-09-26 18:49:02 +08:00
Holger Hans Peter Freyther
c98d67d592 bsc: Mark LUs with a different LAC as needing special care
We want to send a welcome USSD to new subscribers, mark subscribers
with a different LAC than this cell as special and hope someone will
follow up with them.
2010-09-26 18:49:02 +08:00
Holger Hans Peter Freyther
43dbcfe2cf bsc: Rename to osmo_bsc_grace to prepare putting it into master 2010-09-16 00:13:01 +08:00
Holger Hans Peter Freyther
98d949b02f bsc: Rename the RF Ctl interface to match master 2010-09-16 00:01:43 +08:00
Holger Hans Peter Freyther
4f5421a482 bsc_msc: Add minimal code to work with the new SCCP version 2010-08-25 12:22:32 +08:00
Holger Hans Peter Freyther
c8fdf0c4b6 bsc_msc_ip: Set the right log area 2010-08-25 00:55:16 +08:00
Holger Hans Peter Freyther
45473477f6 sccp: Use the libosmo-sccp library and remove the internal copy 2010-08-24 22:38:12 +08:00
Holger Hans Peter Freyther
cd7bed5327 bsc: Remember the MSC connection we use for that connection 2010-08-24 22:26:15 +08:00
Holger Hans Peter Freyther
83594c1f2c oml: Workaround for vty misusage...
Move the OML_NODE below the CONFIG_NODE so that the vty->index
will not be restored when we exit the node. If we do restore the
node we will end up with a double free.
2010-08-11 04:27:25 +08:00
Holger Hans Peter Freyther
7e1524644b mgcp: Speculative mgcp fix...
We really have 32 channels per multiplex... so use the right
number... or at least it seems we do have 32.
2010-08-10 20:24:40 +08:00
Holger Hans Peter Freyther
3ec13ed3a8 OML: Introduce minimal VTY command set to interact with OML managed objects
Conflicts:

	openbsc/include/openbsc/abis_nm.h
	openbsc/src/Makefile.am
	openbsc/src/vty_interface.c
2010-08-10 20:13:38 +08:00
Holger Hans Peter Freyther
11557ecd8c mgcp: Reduce the log level to debug for these calls. 2010-08-08 07:28:54 +08:00
Holger Hans Peter Freyther
c737fbd4af mgcp: Remember if the endpoint was allocated...
Do not use the CI_UNUSED to decide if an endpoint is allocated
but introduce a new flag. This way only the CRCX and free_endp
play with the allocated field.
2010-08-08 07:28:45 +08:00
Holger Hans Peter Freyther
24963554a8 mgcp: Add a callback to inform the client that an endpoint got reallocated 2010-08-08 07:28:36 +08:00
Holger Hans Peter Freyther
c7bd29e6d7 mgcp: Make the CI uint32_t all the way to avoid mismatch
Conflicts:

	openbsc/include/openbsc/mgcp.h
	openbsc/src/nat/bsc_mgcp_utils.c
2010-08-08 07:27:23 +08:00
Holger Hans Peter Freyther
137523ef7c mgcp: Fix discovering the RTCP port with the more strict check.
If we have found the BTS and we receive data on the RTCP port
from the IP of the BTS we will set our RTCP port and forward it
to the network and hope it will be useful.
2010-08-08 07:24:22 +08:00
Holger Hans Peter Freyther
0457b4b6da mgcp: Determine the proto properly... 2010-08-08 07:24:13 +08:00
Holger Hans Peter Freyther
c372b1eb75 bsc_msc: Remove the except code as it is wrong...
Remove wrong code that is luckily not called. We would end up
in a reconnect and attempt to bsc_fd_register the same socket
again. I am removing this part of the code as it is not used
and it would need to know if the fd has ever been registered
or not...
2010-08-08 07:24:06 +08:00
Holger Hans Peter Freyther
55228e31be mgcp: Add instrumentation code to find a possible port leak/bsc-fd corruption 2010-08-08 07:23:58 +08:00
Holger Hans Peter Freyther
db544db73a mgcp: Move the mgcp_free_endp into the right path for the CRCX failure 2010-08-08 07:23:51 +08:00
Holger Hans Peter Freyther
f49d616427 mgcp: Fix a filedescriptor leak in case the bind is failing. 2010-08-08 07:23:44 +08:00
Holger Hans Peter Freyther
1eecb1689b mgcp: Enable the tap after configuring it... 2010-08-08 07:23:36 +08:00
Holger Hans Peter Freyther
f55fc02e87 mgcp: Add a call tap feature to forward audio to another forward port
For debugging it is useful to forward (tee) UDP packets to another
system and use gstreamer to inspect the rtp stream. This is untested
code and might contain bugs.... and of course only tap your own calls.
2010-08-08 07:23:29 +08:00
Holger Hans Peter Freyther
6bb3065e6d mgcp: Patch RTP packets again if that is allowed. 2010-08-08 07:23:22 +08:00
Holger Hans Peter Freyther
3c30a4bb1f mgcp: Get the for network/for bts flag right. 2010-08-08 07:23:15 +08:00
Holger Hans Peter Freyther
636c1cadd8 mgcp: Be more strict on the source addr/source port of the bts
Once we have discovered the bts we will not accept data from
anything else. The call will drop if the BTS is changing the
ip address of the nat anyway.
2010-08-08 07:23:08 +08:00
Holger Hans Peter Freyther
20f3d21665 mgcp: Only discover the bts once, the extra check got lost 2010-08-08 07:22:55 +08:00
Holger Hans Peter Freyther
889fd79511 mgcp: Allow to dynamically allocate ports from a range..
Allow to switch to a dynamic port allocator and not reuse
the ports for a long time... This should help with a crazy
network sending two streams at the same time.
2010-08-08 07:22:40 +08:00
Holger Hans Peter Freyther
7e25253b71 mgcp: Allow to have a different port allocation mode 2010-08-08 07:22:28 +08:00
Holger Hans Peter Freyther
f90c8c9d75 mgcp: Prepare to have different port allocation strategies. 2010-08-08 07:22:06 +08:00
Holger Hans Peter Freyther
08a366f11f mgcp: Fix the signature of the change_cb to not carry the port. 2010-08-08 07:21:58 +08:00
Holger Hans Peter Freyther
c12bfa45a5 mgcp: Separate recv from net/bts and remove autodetection
This allows a more strict check on the source of RTP messages
and we can more easily reject those. For the BTS without an ip
address we will also update the ip address.
2010-08-08 07:21:51 +08:00
Holger Hans Peter Freyther
e320fc115a mgcp: Move the loopback code into the common send as well. 2010-08-08 07:21:43 +08:00
Holger Hans Peter Freyther
5bf8f95701 mgcp: Remove the receive code into a new method. 2010-08-08 07:21:22 +08:00
Holger Hans Peter Freyther
6989b57350 mgcp: Move the selection of the right source port to a new method 2010-08-08 07:19:17 +08:00
Holger Hans Peter Freyther
edd980619c mgcp: Allocate a different port for the networking...
Use the right source port when sending the message.

Conflicts:

	openbsc/include/openbsc/mgcp.h
2010-08-08 07:18:37 +08:00
Holger Hans Peter Freyther
2c362abfb4 mgcp: Rename the base port to bts_base as it will be used for the bts 2010-08-08 07:18:16 +08:00
Holger Hans Peter Freyther
f8e0838f7a mgcp: Move the bfd for rtp/rtcp into the port
Stop using the memset in the mgcp_rtp_end_reset as we
will reset the list pointers and then have a mess..
2010-08-08 07:18:08 +08:00
Holger Hans Peter Freyther
ec2886d1bd mgcp: Make the function internal, only used by the init/config code 2010-08-08 07:18:00 +08:00
Holger Hans Peter Freyther
865ba8b572 mgcp: Rename the bind method to show it is only binding for the bts port 2010-08-08 07:17:52 +08:00
Holger Hans Peter Freyther
9be1b5495f mgcp: Only use early bind for the BTS socket.
Simplify the code by onlt allowing one way to allocate
a socket.
2010-08-08 07:17:42 +08:00
Holger Hans Peter Freyther
7cf7d27d10 mgcp: Attempt to separate the RTP/RTCP port for the Network and for the BTS
We plan to have two different ports for the network and for the
BTS to avoid detecting the BTS and to dynamically allocate the
port to have old data not go to a new socket.

Conflicts:

	openbsc/src/nat/bsc_mgcp_utils.c
2010-08-08 07:17:22 +08:00
Holger Hans Peter Freyther
9002169dcd mgcp: Group the state for bts/net into a struct and have two instances
Group the data that each end (network/bts) have into a struct and use
this struct throughout the sourcecode.

Conflicts:

	openbsc/src/nat/bsc_mgcp_utils.c
2010-08-08 07:16:55 +08:00
Holger Hans Peter Freyther
43242f8947 mgcp: Remove the forwarding mode as it was not used.
Conflicts:

	openbsc/include/openbsc/mgcp.h
2010-08-08 07:16:31 +08:00
Holger Hans Peter Freyther
83961de565 mgcp: Fix the payload_type... it broke in 7cdc62c012 2010-08-08 07:14:58 +08:00
Holger Hans Peter Freyther
19776f70a2 mgcp: Fix the reversed net/bts... which has not cause any issue.. 2010-08-08 07:14:46 +08:00
Holger Hans Peter Freyther
6233ab9859 mgcp: Pass the whole endpoint to the patch method. 2010-08-08 07:14:37 +08:00
Holger Hans Peter Freyther
0037badb02 mgcp: Fix the order of the arguments... 2010-08-08 07:14:07 +08:00
Holger Hans Peter Freyther
054efe1ef2 mgcp: Print the conn mode as well 2010-08-08 07:13:58 +08:00
Holger Hans Peter Freyther
68fc12d89b mgcp: Disable the actual patching... this is a temporary hack 2010-08-08 07:13:50 +08:00
Holger Hans Peter Freyther
7eccf5b0a5 mgcp: Print the system for the duplicate SSRC... 2010-08-08 07:13:40 +08:00
Holger Hans Peter Freyther
6d346d8931 bsc_msc: Fix the naming of this function. 2010-08-08 07:13:20 +08:00
Holger Hans Peter Freyther
71e90b8eea on-waves: Increase the version number... 2010-08-04 00:46:59 +08:00
Holger Hans Peter Freyther
72bd2c247c mgcp: Only patch the header if we had a change in SSRC 2010-08-04 00:26:20 +08:00
Holger Hans Peter Freyther
f45ee6371f mgcp: Style issue... add a space. 2010-08-04 00:26:13 +08:00
Holger Hans Peter Freyther
d585586d7b mgcp: Allow switching the audio streams, patch the header
Patch the sequence number, the SSRC and the timestamp to
allow to mix various voice streams, e.g. toggling the loop
during the call.
2010-08-04 00:26:00 +08:00
Holger Hans Peter Freyther
0b3ffb1513 mgcp: Move the rtp state into a struct
Use a struct to group the rtp state for the up and the down
link of the bts.
2010-08-04 00:25:52 +08:00
Holger Hans Peter Freyther
0577dc1372 mgcp: Fix the documentation entry for the parameters 2010-08-04 00:25:39 +08:00
Holger Hans Peter Freyther
dab98fb15a bsc: Fix the vty writing... it is dtx-used... 2010-08-03 23:52:56 +08:00
Holger Hans Peter Freyther
d8ba591c49 grace: Do not crash if there is no rf ctl
Accept the new connection if there is no rf ctl. Fixes a segfault.
2010-08-03 18:11:27 +08:00
Holger Hans Peter Freyther
87c8f182cc mgcp: Allow to change the receive (the loopback part) via the VTY
Conflicts:

	openbsc/src/mgcp/mgcp_vty.c
2010-08-03 17:37:59 +08:00
Holger Hans Peter Freyther
c4fe5ac43a mgcp: Implement the "loopback" mode for a connection endpoint. 2010-08-03 17:37:30 +08:00
Holger Hans Peter Freyther
00d1f0d7a9 osmocore: Build a against the latest version.. 2010-08-03 03:13:06 +08:00
Holger Hans Peter Freyther
caecc9ad80 osmo-grace: Send USSD messages on the TCH to inform the user..
Send a USSD notification to the user to inform him that the
service will go away in a second..
2010-07-29 20:29:28 +08:00
Holger Hans Peter Freyther
c00bf8f930 osmo-grace: Introduce a global trace text to be send to subscribers 2010-07-29 19:32:12 +08:00
Holger Hans Peter Freyther
d657c67c9c osmo-grace: Handle the grace signal to execute a grace action 2010-07-29 19:19:09 +08:00
Holger Hans Peter Freyther
9ad1f2404f osmo_grace: Allow new connections when the network policy is S_RF_ON.
In case of S_RF_OFF and S_RF_GRACE we will allow new connections.
2010-07-29 19:11:51 +08:00
Holger Hans Peter Freyther
0dcacda194 osmo_rf: Keep the current policy inside the RF struct..
Keep a back pointer to the rf struct inside the connection,
resolve the network through the back pointer. Also assume
that the RF is on. In case we start with RF locked, the policy
is on but we will not see any MS talking to us.
2010-07-29 19:11:06 +08:00
Holger Hans Peter Freyther
1a9ffe85eb bsc_rf: Embed the rf status inside the GSM Network.
Right now we have a network-wide RF lock, in the future
one BSC might have multiple BTSs at different positions
and a global state will not make sense anymore and need
to be moved over to the BTS struct..
2010-07-29 18:57:10 +08:00
Holger Hans Peter Freyther
c94b9c4eb4 bsc_grace: Add a new per network check to decide if new connections are allowed
In case of an ordered RF shutdown we can enter a grace period
where no new RF connections are allowed but active connections
will stay alive until the RF is switched off.
2010-07-29 18:44:39 +08:00
Holger Hans Peter Freyther
b5fa05ff41 gsm_04_80: Allow to specify the alert pattern for the notification
Allow to specify the level (not the category) of the notification
this provides an easy way to test it on the phones.

Conflicts:

	openbsc/src/vty_interface_layer3.c
2010-07-29 04:33:42 +08:00
Holger Hans Peter Freyther
83f94497ce gsm_04_80: Embed a ss_Code inside the NotifySS-ARG...
Indicate that this is about the Call Name Presentation (cnap)
but the a1200 still ignores the call completelty...
2010-07-29 04:33:42 +08:00
Holger Hans Peter Freyther
1230b3c02e gsm_04_80: Send a Release Complete otherwise the USSD unit stays BUSY
We need to release the USSD unit, otherwise it is staying blocked
and will stop to function (even across LUs on my a1200). This code
should encode the transaction and the direction depending on the
network state but this is omitted right now.

Conflicts:

	openbsc/src/vty_interface_layer3.c
2010-07-29 04:33:35 +08:00
Holger Hans Peter Freyther
6d2d523e77 gsm_04_80: Add untested code for USSD notification...
One should be able to send a USSD Notification to a given
subscriber if we has an active link...

Conflicts:

	openbsc/src/vty_interface_layer3.c
2010-07-29 04:29:11 +08:00
Holger Hans Peter Freyther
dbd957c872 gsm_04_80: Fix the size calculation of the 04.80 message..
Subtract the two bytes we were adding to the length of the message.
2010-07-29 04:23:25 +08:00
Holger Hans Peter Freyther
bfc3688024 gsm_04_80: Use msgb_push to get the verification code of msgb
msgb started to verify that we do have enough tail/headroom
and this code was not using this check.
2010-07-29 04:23:25 +08:00
Holger Hans Peter Freyther
c50510b67e gsm_04_80: Add code to wrap a facility IE around. 2010-07-29 04:23:25 +08:00
Holger Hans Peter Freyther
980891cdf4 gsm_04_80: Create a unstructuredSS-Notify message
Create a unstructuredSS-Notify for a given type.
2010-07-29 04:23:25 +08:00
Holger Hans Peter Freyther
c43a0ab856 gsm_04_80: Fix the style and move the '*' to the function 2010-07-29 04:23:25 +08:00
Holger Hans Peter Freyther
c882a0560d gsm0480: Implement a generic "invoke" wrapping for messages.
Implement a GSM 04.80 invoke wrapper for a component and an
invoke id.

Conflicts:

	openbsc/src/gsm_04_80.c
2010-07-29 04:23:18 +08:00
Holger Hans Peter Freyther
1c5d12009e gsm0480: Attempt to encode a NotifySS-Arg with a username.. 2010-07-29 04:13:11 +08:00
Holger Hans Peter Freyther
b6dd348df2 bsc_msc_rf: Add a grace command, send a signal 2010-07-29 03:08:47 +08:00
Holger Hans Peter Freyther
b43e2afb3e mgcp: Attempt to count lost packets better... 2010-07-29 03:05:50 +08:00
Holger Hans Peter Freyther
d506107d1c mgcp: Provide the RTP packet loss information in the mgcp overview 2010-07-29 02:55:12 +08:00
Holger Hans Peter Freyther
7947b6be88 mgcp: Attempt to count missing RTP packets with a basic calculation
This code compares the UDP sequence numbers of two RTP messages
and guesses if packets are missing. It is guessing in two ways:

	1.) by default the sequence number is 0, so on the first
	    value we ignore the jump... we might ignore a real issue
	    in case of a wrap around which is easily possible as the
	    sequence should be a random number.
	2.) the UDP stream might have been reordered on the network
	    and we would see the jump...

In any case these two shortcomings are acceptable for the feature
that is meant to provide some basic analysis..
2010-07-29 02:55:05 +08:00
Holger Hans Peter Freyther
175a7b42af bsc_msc_ip: Use ip-dscp and provide the old value as alias. 2010-07-27 21:06:29 +08:00
Holger Hans Peter Freyther
38a2653801 mgcp: Rename TOS to DSCP
DSCP is the more modern information for TOS and the kernel
will set parts of TOS by itself (e.g. for ECN).
2010-07-27 21:01:19 +08:00
Holger Hans Peter Freyther
f1bb05fbef nat: Remove the nat code from the On-Waves branch... new code is in master 2010-07-27 21:01:18 +08:00
Holger Hans Peter Freyther
0c4f7ecabc bssap: Use libosmocore for the assignment complete msg generation 2010-07-23 18:34:38 +08:00
Holger Hans Peter Freyther
5822be4690 bssap: Use gsm0808 method to create complete layer3 message. 2010-07-23 18:23:29 +08:00
Holger Hans Peter Freyther
acda6908ad bssap: Move cipher mode complete to libosmocore 2010-07-23 17:32:52 +08:00
Holger Hans Peter Freyther
83f46278dd bssap: Use libosmocore GSM0808 generation routines. 2010-07-23 17:29:44 +08:00
Holger Hans Peter Freyther
e1c37bc4fe abis_nm: Band aid on OML initialisation by queuing messages
Instead of sending many messages we will queue the OML
messages and wait for the ACK/NACK before sending the
next message from the queue. We tag the msgb to remember
if we need to wait for an ack or not.

We keep the order of all messages, on ACKs and similiar
occassions we will drown the queue until we reach a message
that needs to be acked and then wait for that ack again.

Possible breakage can appear when we send an OML (e.g.
BS11 specific message) msg which does not need to be acked
through the abis_nm_sendmsg call. The fix will be to use
the _direct version of this method.

Re-Enable as it might have fixed something... who knows.

Conflicts:

	openbsc/include/openbsc/abis_nm.h
	openbsc/include/openbsc/gsm_data.h
	openbsc/src/gsm_data.c
	openbsc/src/input/ipaccess.c
2010-07-23 17:24:23 +08:00
Holger Hans Peter Freyther
0f87be341d Revert "abis_nm: Band aid on OML initialisation by queuing messages"
This has not fixed the init issue and we will need to figure out
an alternative to this.

This reverts commit a68f139820.
2010-07-09 17:48:06 +08:00
Holger Hans Peter Freyther
f15e647cba bsc_init: Allow DTXu and enable DTXd on RSL
Allow the MS to use uplink discontinous transmission by
setting the right bit in the SystemInformation and set
DTXd/DTXu on the RSL channel commands.

This is configurable via dtx-used (0|1) on the network
level..
2010-06-28 10:52:22 +08:00
Holger Hans Peter Freyther
e2c1a6a33d abis_nm.c: Use LOGPC with a LOGL_ERROR for the NACK messages
Make NACK messages print as errors.
2010-06-24 22:06:01 +08:00
Holger Hans Peter Freyther
9626783494 Bump the version for init and alignment fixes. 2010-06-23 11:07:59 +08:00
Holger Hans Peter Freyther
a68f139820 abis_nm: Band aid on OML initialisation by queuing messages
Instead of sending many messages we will queue the OML
messages and wait for the ACK/NACK before sending the
next message from the queue. We tag the msgb to remember
if we need to wait for an ack or not.

We keep the order of all messages, on ACKs and similiar
occassions we will drown the queue until we reach a message
that needs to be acked and then wait for that ack again.

Possible breakage can appear when we send an OML (e.g.
BS11 specific message) msg which does not need to be acked
through the abis_nm_sendmsg call. The fix will be to use
the _direct version of this method.

Conflicts:

	openbsc/include/openbsc/abis_nm.h
	openbsc/include/openbsc/gsm_data.h
	openbsc/src/gsm_data.c
	openbsc/src/input/ipaccess.c
2010-06-23 10:53:28 +08:00
Holger Hans Peter Freyther
539b8ed99f bssap.c: handle CHAN Activate NACK...
This was previously handled by the unexpected release
lchan handling for the secondary channel, we will now
just set the secondary_lchan pointer back to NULL and
let the framework free the resources.
2010-06-22 12:55:57 +08:00
Holger Hans Peter Freyther
d7cb8aa275 abis_rsl: Send the IMMEDIATE Assignment after the Channel Ack.
The Channel Activate might be sent to a different TRX than the
Immediate Assignment. So we need to make sure that the channel
is activated before we send the immediate assignment for the RACH.

Another reason for that is according to GSM 08.58 we should take
the frame number from the activate and use it for the starting
time inside the immediate assignment message. We obviously do not
do this yet.

The code assumes that the BTS will either respond with a CHAN ACK
or a CHAN NACK if not the lchan will remain in the request state.

Conflicts:

	openbsc/include/openbsc/gsm_data.h
	openbsc/src/abis_rsl.c
	openbsc/src/chan_alloc.c
2010-06-22 12:40:30 +08:00
Holger Hans Peter Freyther
38454904cb bssap.c: Fix possible unaligned memory access.
Use a memcpy to read and access the data to gurantee that
the data is properly aligned. The performance hit should
be smaller than the abort handled by the kernel.
2010-06-21 16:57:14 +08:00
Holger Hans Peter Freyther
c60465359b abis_nm.c: Reading the in_addr can lead to unaligned memory access
The value of the in_addr might not be 32 bit aligned and reading
it can generate an alignment error on ARM. Fix it by using memcpy
to copy the data into a local variable.

There are many more potential alignment issues that we will fix
when we hit them.
2010-06-21 16:57:14 +08:00
Holger Hans Peter Freyther
e9eb4d1ab8 bsc_init: Avoid unaligned access to nanobts_attr_nsvc0
nanobts_attr_nsvc0 + 10 is unlikely to be 32 bit aligned
and will trigger an alignment error on ARM..
2010-06-21 16:57:14 +08:00
Holger Hans Peter Freyther
c2b9bd202e Tag a release without the DTX change... 2010-06-16 18:30:37 +08:00
Holger Hans Peter Freyther
0d147d47b9 Revert "bsc_init: Enable DTX in Cell Options..."
This is incomplete and needs more thinking... We need to change
RSL chan modify as well..

This reverts commit 5bfb9102af.
2010-06-16 17:17:57 +08:00
Holger Hans Peter Freyther
ce701d7c5f new release with possible fix for the blackberry... 2010-06-16 12:55:14 +08:00
Holger Hans Peter Freyther
f3759a4934 si13: Use the correct pseudo length for the SI13 message
The GSM04.08 Section 10.5.2.19 specifies the L2 Pseudo Length
and the length does not include rest octets, so we will need
to use a zero for the length.

The patch is coming from Dieter Spaar.
2010-06-16 12:05:56 +08:00
Holger Hans Peter Freyther
5bfb9102af bsc_init: Enable DTX in Cell Options...
Allow the MS to use uplink discontinous transmission has
it can save some power for the MS and we can save some
bandwidth on the uplink as well.
2010-06-16 12:02:13 +08:00
Holger Hans Peter Freyther
2300d69df6 bsc: Increase the hand_off variable when we are done with the lchan.
Every time the highlevel code is done with the channel, increase
the value. This way we will be able to see if we are leaking a
channel that was never used or should have returned to the system.
2010-06-14 17:27:49 +08:00
Holger Hans Peter Freyther
c67cd2e11a vty: Dump the state of the SAPIs of a lchan as well. 2010-06-14 17:20:56 +08:00
Holger Hans Peter Freyther
2afb915758 lchan: Introduce a handoff variable...
This variable can be used by higher levels to declare they
were done with lchan...
2010-06-14 17:20:04 +08:00
Holger Hans Peter Freyther
dbac9295e7 chan_alloc: Swicth to LOGP from DEBUGP 2010-06-14 17:15:54 +08:00
Holger Hans Peter Freyther
9f972a5fb0 vty: Add show lchan-status to show the status...
Sometimes we see channels being allocated and never be freed.
This command should help to understand why this is happening
and in which state this channel is.
2010-06-14 17:00:35 +08:00
Holger Hans Peter Freyther
33f3dcbbca vty: Rename show lchan summary to show lchan-summary. 2010-06-14 17:00:19 +08:00
Holger Hans Peter Freyther
2ad760fe5f Versioning... 2010-06-13 14:24:11 +08:00
Holger Hans Peter Freyther
fea0aebd36 bsc_msc_ip: Attempt to plug an lchan leak...
If we end up with a channel that has refcount of zero,
has no msc_data attached and the handler has not returned
1 we will just close it.
2010-06-13 14:15:39 +08:00
Holger Hans Peter Freyther
c9b7d74a08 channel: Keep track on when a channel got allocated.
This can help to detect 'stale' channels in a network.
2010-06-13 12:38:35 +08:00
Holger Hans Peter Freyther
42a4e9a52d abis_rsl: Reduce logging to LOGL_DEBUG as it is quite nosiy
The nanoBTS will send us at least one measurement report
after we have decided to close the channel... degrade that
output to a debug message.
2010-06-13 10:09:45 +08:00
Holger Hans Peter Freyther
d4f7a81992 nat: Fix the access-list-name command...
We have added two commands with the same name to the tree..
the second one should have been the BSC...
2010-06-08 11:18:26 +08:00
Holger Hans Peter Freyther
cd4afce470 nat: Add both entries to the tail to keep the order they are inserted 2010-06-08 11:00:09 +08:00
Holger Hans Peter Freyther
299d5aa2a4 nat: Allow to specify multiple entries in the access-list...
Inside the access-list we have a list of entries that have
either one allow or one deny rule... we do not allow to remove
a single rule but one has to remove the whole list, in that case
talloc will handle cleaning all entries.

Right now the matching is O(n*m) as we traverse the list
(multiple times) and run the regexp multiple times. One
way to make it faster would be to concat all regexps into
one.
2010-06-08 10:53:39 +08:00
Holger Hans Peter Freyther
f85e93cd4d nat: Shorten the access-list struct and method names (still way too long) 2010-06-08 10:14:44 +08:00
Holger Hans Peter Freyther
fdfaf9c519 bsc_msc_ip: Possible crash fix on the early assignment code path
The crash happened when we had released the primary channel
for one reason or another but still got the assignment complete
on the secondary. This null checking is some extra caution, with
the previous commit we should fail the msc_data test early in
this method.
2010-06-07 22:32:10 +08:00
Holger Hans Peter Freyther
4d4e6714cd bsc_msc_ip: When closing the SCCP check primary and secondary lchan
When closing a SCCP connection and any of the two lchan's are open,
then close them down properly.

Move the lchan freeing into a new method and call that one from the
SCCP connection close handling. Move the bss scp data varaible to
the top of the context..
2010-06-07 22:28:56 +08:00
Holger Hans Peter Freyther
3806b070bb Version bump... 2010-06-07 15:02:01 +08:00
Holger Hans Peter Freyther
3dd069cfd7 bssap.c: Claim to always do HR AMR right now.
The bssap.c code is sending a multirate config with
only AMR 5.9kb marked as supported, the MSC does not
like if we assign a FR channel and send the GSM 0808
FR AMR mode back to the MSC. So change the code to
not look at the channel type for AMR...
2010-06-07 14:47:25 +08:00
Harald Welte
e1dcbc7622 [GPRS] Change SI13 to NMO_II, as some phones (like G1) dislike NMO_III
I still believe NMO_III is what we want, but as indiciated some phones
absolutely refuse to even connect to the GPRS network in this mode :(
2010-06-07 12:26:12 +08:00
Holger Hans Peter Freyther
6be75737c4 Revert "bsc_init: Set the paging config like in the trace..."
I added this to have the patch in the history, I don't think
that we need to include this but it is good to have it cherry
pickable in the history.

This reverts commit 290a11d0ad.
2010-06-06 21:32:02 +08:00
Holger Hans Peter Freyther
290a11d0ad bsc_init: Set the paging config like in the trace...
The value of this config is not known.... the paging load
needs to be tested again with these parameters...
2010-06-06 21:29:07 +08:00
Holger Hans Peter Freyther
67505f46b7 bsc_init: Use configuration settings from a trace... as default
Use the values but the paging configuration from a trace...
2010-06-06 21:25:33 +08:00
Holger Hans Peter Freyther
8b4898360a [nat] Implement the removal of an access-list. 2010-06-03 01:44:05 +08:00
Holger Hans Peter Freyther
6e495eee4b [nat] Fix the parsing of the access-list regexp...
We need to start at argv[1] for the regexp of
this access-list, also subtract one from number
of items..
2010-06-03 01:38:53 +08:00
Holger Hans Peter Freyther
e6a8a9359d [nat] Fix VTY bug with access-lists...
vty->index does not hold a BSC Config at this point as we are
on the nat level... use the global _nat pointer for now...
2010-06-03 01:34:20 +08:00
Holger Hans Peter Freyther
1d55fd9e2b Mark a new test release.. 2010-06-02 17:36:43 +08:00
Holger Hans Peter Freyther
df342ea82b [nat] Introduce the concept of access-list
One can set one access-list to one BSC and one
access-list to one NAT. The matching of IMSIs
remains the same for now, also applying the
white/blacklist. Access lists can not be deleted
for now and no perf opt is done (e.g. one could
cache the result of the last lookup in the bsc
struct).
2010-06-01 01:03:13 +08:00
Harald Welte
049eb23b73 [GPRS] Make sure SI13 rest octets look like those of the ip.access BSC 2010-05-31 19:20:11 +08:00
Holger Hans Peter Freyther
95eb9dd339 [gprs] Use the defaults coming from a trace file.
* Enable sending RLC3
* Use values from the trace..

This is not intended to be merged to master as this enables the
RLC3 that the comment claims to only work on EGPRS enabled models
and it is changing timers to hex indicating a change where none
happened... This is mostly for testing.
2010-05-31 19:19:10 +08:00
Holger Hans Peter Freyther
ca660ac9ca [nat] Add ip-tos option to the nat.
This is applied to all incoming BSC connections.
2010-05-31 10:36:35 +08:00
Holger Hans Peter Freyther
96d6ed2552 [mgcp] Set the IP_TOS/DSCP on RTP/RTCP IP packets. 2010-05-31 10:22:00 +08:00
Harald Welte
170619fef6 [gprs] NS/BSSGP: Make all timers configurable from VTY 2010-05-22 22:21:36 +08:00
Holger Hans Peter Freyther
09f28ea6b3 [misc] Remove spaces, fix indention. 2010-05-22 22:13:13 +08:00
Sylvain Munaut
1884f89d9b bsc_init: Fix ccch description in SI messages
The previous code just hardcoded RSL_BCCH_CCCH_CONF_1_C, but
we need to inspect the timeslot config to know what to use.

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2010-05-22 22:12:48 +08:00
Holger Hans Peter Freyther
0777fb2d32 [mgcp] Only patch RTP packets when they arrived on the RTP port
Do not attempt to patch RTCP packets...
2010-05-22 22:06:13 +08:00
Holger Hans Peter Freyther
35e56453d2 msc: Add msc ip-tos NR option for the BSC
Allow to set the TOS field via the VTY interface. The
SO_PRIORITY was not used as it has no effect on the
packets being sent (in contrast to the documentation).
2010-05-18 03:31:16 +08:00
Holger Hans Peter Freyther
4fcf80a59a [nat] Make the refusal more complicated to support more MSCs
We will need to confirm the connection, then we can send the
GSM48 message, then we need to close the connection... the
embedding in the refusal method was way too easy..
2010-05-16 20:45:16 +08:00
Holger Hans Peter Freyther
31e0bafa10 [sccp] Add method to create a dt1 packet. 2010-05-16 20:45:15 +08:00
Holger Hans Peter Freyther
01ffc204f3 [sccp] Create a method to create RLSD messages. 2010-05-16 20:45:15 +08:00
Holger Hans Peter Freyther
466c40bec2 [sccp] Create a SCCP CC creation routine. 2010-05-16 20:45:15 +08:00
Holger Hans Peter Freyther
60a2f4a7e6 [nat] Make create_sccp_src_ref return the SCCP Connection.
Right now it was not possible to just find a connection, by returning
the connection that is created we will have direct access to it. It
will be used by the local connection handling.
2010-05-16 20:45:15 +08:00
Holger Hans Peter Freyther
797b9f0af0 [nat] Remove parameter that is never accessed directly
The msgb needs to be around when we access the parsed structure
but that needs to be guranteed by the caller handing out the parsed
structure.
2010-05-16 20:45:15 +08:00
Holger Hans Peter Freyther
677f0e7f90 [nat] Add the notion of a "local" connection.
A local connection is only between the MUX and the real BSC. We will
not forward anything to the MSC. This will be needed for the IMSI
filtering as sending a CREF is not liked by every BSC...
2010-05-16 20:45:15 +08:00
Holger Hans Peter Freyther
ddbb5a4e1e [nat] Do not access the con after the removal
In case of a RLC message we will destroy the SCCP connection. This means
that accessing the con and con->bsc will access old memory. Keep the status
local and move the con into an inner scope.
2010-05-16 20:45:15 +08:00
Holger Hans Peter Freyther
75042b80be [nat] Send a GSM48 message within the reject message 2010-05-16 08:15:11 +08:00
Holger Hans Peter Freyther
c32589f395 gsm48: Split LU Reject sending and generation into two. 2010-05-16 02:49:12 +08:00
Holger Hans Peter Freyther
abd0719f23 gsm48: Separate CM Service Reject sending and creation.
Split out the msg generation from the sending, this will
be used by the nat to send a refusal message.
2010-05-16 02:49:12 +08:00
Holger Hans Peter Freyther
5bac62216e [nat] Move the SCCP CREF handling into a new method.
We will need to generate messages with a proper reason
and it is easier to do that from a dedicated method.
2010-05-16 02:49:12 +08:00
Holger Hans Peter Freyther
c93c523872 [bsc_msc_ip] Move the command to the right place
Apparently I could not find the vty_interface_bsc.c when I was
searching for it. Move an extra BSC command into that file.
2010-05-16 02:49:12 +08:00
Holger Hans Peter Freyther
ed1c872352 [bsc_msc_ip] Print SCCP src/dst ref as hex 2010-05-16 02:49:12 +08:00
Holger Hans Peter Freyther
e21bdea501 [nat] Use and print the connection type of a SCCP connection. 2010-05-16 02:49:11 +08:00
Holger Hans Peter Freyther
11c17233fe [nat] Set the connection type/reason as out parameter
We are analyzing each CR message and it is nice to know the
reason these connections were created. Change the nat method.
2010-05-16 02:49:11 +08:00
Holger Hans Peter Freyther
fceee8779e Bump the version. 2010-05-16 01:37:49 +08:00
Holger Hans Peter Freyther
e27740a0e2 [nat] Use the new gsm48 method to parse the MI followed by a classmark. 2010-05-16 01:13:28 +08:00
Holger Hans Peter Freyther
95defd542d gsm48: Add a generic MI from classmark+mi extraction.
This is a generic MI extraction for the MI if it is followed
after a classmark. For the Phase1 Phones the classmark2 is not
four bytes but it might be different. This code can be used
by the CM Service Request handling as well.
2010-05-16 01:07:20 +08:00
Holger Hans Peter Freyther
2d2a43f3d6 [nat] Let IMSI DETACH and other messages pass by. 2010-05-16 01:05:47 +08:00
Holger Hans Peter Freyther
a9aab6a9ca [nat] Print on which BSC config this happend. 2010-05-16 00:45:07 +08:00
Holger Hans Peter Freyther
775b3dc566 [nat] Parse the PAGING RESPONSE inside a CR message as well.
Now we are parsing a CM Service Request, Location Updating Request
and the Paging Response. For all other messages we claim to not
support it and force a refuse.
2010-05-15 23:55:28 +08:00
Holger Hans Peter Freyther
45bb8bfc1a gsm48: Add size checks to the paging response mi parsing.
We go from no size checks to some content checking. We should
refactor the whole classmark2 + mi parsing that is used throughout
the code into one place with proper size checking. This is the
start and requires a new libosmocore as well.
2010-05-15 23:55:28 +08:00
Holger Hans Peter Freyther
57900f0008 [nat] Check proto descriptor and the message type 2010-05-15 23:55:28 +08:00
Holger Hans Peter Freyther
66ac860f62 [nat] Add code to filter the CM Service Request by IMSI.
The code should be shared among the GSM0408 implementation
and this one, and like the LU we are not handling a TMSI
properly as we have no idea where it is coming from.
2010-05-15 23:55:28 +08:00
Holger Hans Peter Freyther
ec82426c5e [nat] Mention where the MSG is coming from. 2010-05-15 19:13:52 +08:00
Holger Hans Peter Freyther
60fa0efcc8 [sccp] Make it optional to send data on a SCCP Connection Refuse
This can be used to send a Location Updating Reject down to the
BSC when it is clear that a subscriber is not allowed.
2010-05-15 01:04:42 +08:00
Holger Hans Peter Freyther
3dfcd4636a [nat] Remove the imsi allow option on the nat level.
For now we have:
1.) bsc imsi deny to deny at the BSC level
2.) bsc imsi allow to allow a SIM at the BSC level
3.) nat imsi deny to deny at the global level
2010-05-15 00:36:54 +08:00
Holger Hans Peter Freyther
50818d0c20 [nat] Separate exit2/exit3 as this can not be shared...
We have tried to send a refuse for arbitary things and ended
up with a segfault... separate the exi2 and exit3 label to have
separate exits and cleanups.
2010-05-15 00:29:50 +08:00
Holger Hans Peter Freyther
317934a2ba [nat] Add a token to the nat config and handle ID GET
This allows to chain a nat with a nat by answering to the
id get code and sending the token.
2010-05-15 00:14:58 +08:00
Holger Hans Peter Freyther
565b355c82 [bsc_msc] Move the id get response into the bsc_msc.c
Create the message in a common place and then it can be used
by tools having an a link or such.
2010-05-15 00:12:19 +08:00
Holger Hans Peter Freyther
be9201a272 [nat] Add a regexp test command to the VTY.
This allows to test the regexp to be used for allo/deny of
the imsi filter.
2010-05-14 23:43:12 +08:00
Holger Hans Peter Freyther
a43c56637d [nat] Fix the regexp of the test and the command line. 2010-05-14 23:07:58 +08:00
Holger Hans Peter Freyther
980c84f0a3 [nat] Fix the imsi deny config write. 2010-05-14 23:06:09 +08:00
Holger Hans Peter Freyther
1ae7b7c372 [nat] We do not want to see the actual matches. 2010-05-14 22:24:36 +08:00
Holger Hans Peter Freyther
e265db68b0 [nat] Allow to set the description for the bsc.
This will allow to add description to each BSC.
2010-05-14 22:06:28 +08:00
Holger Hans Peter Freyther
fdc4a9386f [nat] Implement IMSI filtering... 2010-05-14 19:49:35 +08:00
Holger Hans Peter Freyther
023ac93377 [nat] Fix the size check of the LU Request. 2010-05-14 19:24:06 +08:00
Holger Hans Peter Freyther
fa53aba62c [nat] Make the string -> regexp parsing public
This way it can be used from within a test case to test
the regexps..
2010-05-14 18:38:29 +08:00
Holger Hans Peter Freyther
34c0b245fb nat: Add code to parse the SCCP optional data.
First we have the Complete Layer3 Information, then we have
the IE for the Layer3 information, then the GSM48 hdr, then
the actual content with data. Right now we are parsing the
LU but we are not filtering anything yet.
2010-05-14 08:14:09 +08:00
Holger Hans Peter Freyther
4c4d2d48ec nat: Start to add a test case.. with one CR message. 2010-05-14 08:12:57 +08:00
Holger Hans Peter Freyther
13441a1c50 gsm48: Typo fix. 2010-05-14 08:02:08 +08:00
Holger Hans Peter Freyther
8ff74e8c24 nat: Introduce a nat filter that is working on the CR message.
Currently there is no implementation but the refusal code is
in place and will send a refusal back to the BSC.
2010-05-14 03:47:52 +08:00
Holger Hans Peter Freyther
a202342d64 [sccp] Export function to create SCCP Refuse message. 2010-05-14 03:34:35 +08:00
Holger Hans Peter Freyther
d275cf6407 [bsc_msc_ip] Use A.B.C.D for the VTY code. 2010-05-14 02:37:54 +08:00
Holger Hans Peter Freyther
c00e9ce09f [nat] Use A.B.C.D for the IP address
The VTY code will then be able to validate the IP Address.
2010-05-14 02:36:42 +08:00
Holger Hans Peter Freyther
5d645bf984 [nat] Remove range checks inside the VTY command.
The ranges are enforced by the VTY code.
2010-05-14 02:35:51 +08:00
Holger Hans Peter Freyther
723fb87a6c [mgcp] Clean up VTY code, the ranges are checked by the VTY code. 2010-05-14 02:34:35 +08:00
Holger Hans Peter Freyther
9da4492655 [mgcp] Use A.B.C.D for the ip addresses inside the vty config
Make the vty code parse the ip addresses for us and validate
them for us.
2010-05-14 02:27:50 +08:00
Holger Hans Peter Freyther
1927e93ce5 [mgcp] Improve the language of the comments. 2010-05-14 02:18:59 +08:00
Holger Hans Peter Freyther
7bbd416a52 [mgcp] Include stdlib.h for abs. 2010-05-14 02:14:09 +08:00
Holger Hans Peter Freyther
efd38dd015 [vty] Add power measurements to the one line summary. 2010-05-14 01:58:17 +08:00
Holger Hans Peter Freyther
e8d8811b12 [vty] Add a one line show lchan summary command. 2010-05-14 01:45:52 +08:00
Holger Hans Peter Freyther
39cb9f2a3c [vty] Move "show lchan" into a parameterized method
I want to have a shorter lchan summary but with the same
config parameters. Change the current code to be a method
that takes a dump routine as parameter.
2010-05-14 01:45:45 +08:00
Holger Hans Peter Freyther
0558a5a0dd [vty] Remove unfinished code from the VTY... 2010-05-14 00:58:11 +08:00
Holger Hans Peter Freyther
fcb4468de4 A new day, a new tag 2010-05-14 00:49:14 +08:00
Holger Hans Peter Freyther
9e96b2df12 rach: Allow to set the emergency call bit
Add the rach emergency call allowed (0|1) setting and implement
it by directly manipulating the t2 value. It is the third bit which
is set to 0 when emergency calls are enabled and to one if it is
only enabled for access classes 11 to 15.
2010-05-14 00:39:19 +08:00
Holger Hans Peter Freyther
72952d854c [mgcp] Use tabs here.. 2010-05-14 00:20:32 +08:00
Holger Hans Peter Freyther
637dce99ba ipaccess: Move the RSL delay down to 0 milliseconds.
Set the delay to zero milliseconds to send RSL messages as fast
as possible.
2010-05-14 00:09:05 +08:00
Holger Hans Peter Freyther
641b07ab73 ipaccess: Make sure flashing of the secondary BTS is working
Use the TRX throughout the flash process.
2010-05-13 00:17:17 +08:00
Holger Hans Peter Freyther
6eae31e39f sw_load: Specify the trx_nr for the software load
For the multi TRX setup we will need to specify the right trx->nr
to be able to flash the BTS. For the BS11 case we are ignoring the
additional argument.
2010-05-13 00:17:17 +08:00
Holger Hans Peter Freyther
4647015f69 ipaccess: Send the reset to the BASEBAND_TRANSC and supply TRX
Send the IPA Restart to a given BTS/TRX, change the signal callbacks
to carry the trx instead of the BTS so we have an easy access to the
right TRX and change the ipaccess-config to use that TRX. This is
fixing the restart with a multi TRX setup.

Even if we have the msg->trx, use the gsm_bts_trx_by_nr and get
the TRX from the fom header. This is because the OpenBSC and the
BTS numbering might not match for the multi TRX case.
2010-05-13 00:16:15 +08:00
Holger Hans Peter Freyther
239f95467c ipaccess: Refactor... unite some code 2010-05-12 23:39:51 +08:00
Holger Hans Peter Freyther
cd80c73f37 ipaccess: Use the right trx when performing the test 2010-05-12 23:02:23 +08:00
Holger Hans Peter Freyther
d6f1c4afbb ipaccess: Use the current TRX to set the OML address. 2010-05-12 22:48:28 +08:00
Holger Hans Peter Freyther
0c8af75c94 Increase the version number. 2010-05-12 22:25:40 +08:00
Holger Hans Peter Freyther
e4b33be6fc chan: After sending the GSM04.08 RR Release, reset the subscriber and wait
After we send the SACH DEACTIVATE the BTS will get back to us with a
Release Indication which will trigger the RF Channel Release handling. This
is why we can return here, but we need to put the subscriber reference to
make sure to not end in a infinite loop.

This and the previous change fix the USSD issue for me.
2010-05-12 22:09:24 +08:00
Holger Hans Peter Freyther
cc7461cefc bsc_msc_ip: Assign a dummy gsm_subscriber to send a SACH DEACTIVATE
This is part of fixing USSD delivered to the MS. Currently only MT
services would end up with a GSM Subscriber assigned. The LCHAN code
is using the GSM Subscriber to figure out if a SACH DEACTIVATE should
be send to the MS. Add code to always assign a GSM Subscriber.
2010-05-12 22:09:16 +08:00
Holger Hans Peter Freyther
e174061d17 bssap: Use libosmocore for message creation. 2010-05-12 18:34:20 +08:00
Holger Hans Peter Freyther
6e1c3412ae bssap: Use libosmocore to create GSM0808 Reset 2010-05-12 18:33:15 +08:00
Holger Hans Peter Freyther
bff54b3e00 bssap: Start to libosmocore for gsm0808 message creation. 2010-05-12 18:31:13 +08:00
Holger Hans Peter Freyther
e75eb4ca25 ipaccess: Wait for the BASEBAND_TRANSCEIVER and then bootstrap OML
Currently we are connecting to the BTS and once the OML is established
we are bootstrapping the OML. This does not work for a multi TRX setup
as we will need to use a trx_nr != 0 for it.

Change the code to wait for a message (in this case NM OC_BASEBAND_TRANSC)
to detect the trx_nr used by the BTS and then use that TRX to bootstrap
the network.

I have tested setting the unit id on a single and multi trx system for
the first and second trx.
2010-05-12 17:16:18 +08:00
Holger Hans Peter Freyther
566737a4b8 abis: Pass the abis_om_obj_inst in the nm_state_event.. 2010-05-12 17:16:18 +08:00
Holger Hans Peter Freyther
2b7350240d nat: Have a recycle timer that removes unconfirmed SCCP connections.
The MSC does not respond to a SCCP CR with Paging Response as GSM
payload, when the response comes in 'too late'. Prevent the MUX having
stale connections and start removing old connections every 20 minutes.
2010-05-12 00:58:08 +08:00
Holger Hans Peter Freyther
d76b53c00e nat: When we fail to reallocate... also close down the MGCP part
Give the BSC a chanche to close down MGCP ports as well.
2010-05-12 00:35:07 +08:00
Holger Hans Peter Freyther
9c9ef7796a nat: Store the creation time of a sccp connection.
Generate it when creating the connection but also when
reusing an existing connection.
2010-05-12 00:33:38 +08:00
Holger Hans Peter Freyther
49fcc8fc90 bsc_msc_ip: Use constants for ?/0/1. 2010-05-11 22:54:29 +08:00
Holger Hans Peter Freyther
51a4bcc96a Increase the version... as we have new commands 2010-05-11 20:02:36 +08:00
Holger Hans Peter Freyther
d6238120dd bsc_msc_ip: Add an extra command to show the MSC status. 2010-05-11 20:00:22 +08:00
Holger Hans Peter Freyther
7407aec921 bsc_msc_ip: Move the MSC connection into the structure 2010-05-11 20:00:22 +08:00
Holger Hans Peter Freyther
e575ce69ce nat: Print the MSC status with a new vty command. 2010-05-11 20:00:16 +08:00
Holger Hans Peter Freyther
c1ca0ff091 misc: Make sure PACKAGE_VERSION is getting defined with a useful content.
PACKAGE_VERSION is used by the copyright message.
2010-05-11 19:08:10 +08:00
Holger Hans Peter Freyther
661e68b78f bsc_msc_ip: Add a test mode to send messages to the MSC.
Check if the MSC likes paging responses when it has not
recently send out a paging request.
2010-05-11 19:08:10 +08:00
Holger Hans Peter Freyther
376e146cfb gsm0408: Use counter_inc to increment the counter. 2010-05-11 19:08:10 +08:00
Holger Hans Peter Freyther
eb3ab2f85b bsc_msc: Add a connection timeout for the MSC.
When no one is listening our connection would get stuck
in the SYN_SENT state and we would be there forever.
2010-05-05 22:48:56 +08:00
Holger Hans Peter Freyther
ebc38e4f26 Version bump for testing it on the target 2010-05-05 20:43:11 +08:00
Holger Hans Peter Freyther
e2ab44a439 nat: Using the right fd can be a good idea as well 2010-05-05 20:42:14 +08:00
Holger Hans Peter Freyther
8b3cced773 Another version... another try 2010-05-05 20:37:10 +08:00
Holger Hans Peter Freyther
3d1b0770f4 nat: Fix bad bug, make sure the fd is not overwritten..
The adding of the innocent looking code was actually overwrote
the fd and then stupid things happened. Rename variables to avoid
that. rc,ret should be scratch variables...
2010-05-05 20:33:34 +08:00
Holger Hans Peter Freyther
99743fb7ec Bump the version for TCP_NODELAY. 2010-05-05 19:01:23 +08:00
Holger Hans Peter Freyther
a2a42a7561 bsc_msc_ip: Attempt to disable nagle
Use TCP_NODELAY on the connection to the MSC. We want small
messages to be send immediately.
2010-05-05 19:00:38 +08:00
Holger Hans Peter Freyther
ebd57da87d nat: Use TCP_NODELAY for the connection to the BSC.
We do not want to use NAGLE for the BSC connection.
2010-05-05 18:59:54 +08:00
Holger Hans Peter Freyther
b0ee082bb0 Bump version
Configurable timeout.
2010-05-05 17:52:40 +08:00
Holger Hans Peter Freyther
81f6a4c0bf bsc_msc_ip: Add VTY code for ping/pong timeout. 2010-05-05 17:46:08 +08:00
Holger Hans Peter Freyther
3978de52c1 bsc_msc_ip: Do not send a ping when the timeout is negative 2010-05-05 17:42:32 +08:00
Holger Hans Peter Freyther
7faf692cb7 bsc_msc_ip: Make the ping/pong timeouts configurable
Take the timeouts from the struct.
2010-05-05 17:39:22 +08:00
Holger Hans Peter Freyther
0cf25d5154 nat: Improve log messages. Refer to ip and fd. 2010-05-05 17:03:44 +08:00
Holger Hans Peter Freyther
08db178271 nat: Make ping/pong timeout configurable. 2010-05-05 16:57:38 +08:00
Holger Hans Peter Freyther
936d8c1b64 Work with later libosmocore. 2010-05-03 19:38:01 +08:00
Harald Welte
3170305e56 move gsm48_construct_ra() to libosmocore 2010-05-03 19:36:58 +08:00
Harald Welte
0f3490dd03 'struct gprs_ra_id' is now defined in libosmocore 2010-05-03 19:36:41 +08:00
Holger Hans Peter Freyther
61e5e7bd8b Bump version..
* ping pong and possible crash fix.
2010-05-03 17:27:07 +08:00
Holger Hans Peter Freyther
f7b06fbe0c bsc: Speculative crash fix.
Make sure the sccp_cc_timeout is stopped when we delete the
associated data. There is one crash report that indicates that
we have a pending timer that is inside freed memory.

A crash could have occured when the connection to the MSC was
lost while have unconfirmed connections.
2010-05-03 16:13:02 +08:00
Holger Hans Peter Freyther
45403b1804 nat/bsc: Send PONG on PING, send PING from the BSC too
We do want to send PING/PONG in both ways to have a heartbeat
on the TCP connection. When switching over to SCTP we can rely
on the builtin heartbeat functionality.
2010-05-03 11:51:07 +08:00
Holger Hans Peter Freyther
6782cea4bf nat: Send a IPA PING down the stream and wait for the pong.
We will send a ping every 20 seconds and if we have no pong
within 5 seconds we will close down the BSC connection and
wait for a reconnect. We will start this after having
authenticated the BSC and we stop the timer when destructing
the BSC connection.
2010-05-02 19:31:14 +08:00
Holger Hans Peter Freyther
ec7ecab66f nat: Allow to only show statistics for a given BSC Cfg. 2010-05-02 19:31:14 +08:00
Holger Hans Peter Freyther
d1287e379b nat: Do not allow a BSC to send auth messages twice. 2010-05-02 19:31:13 +08:00
Holger Hans Peter Freyther
3fb44f3e61 nat: Fix vty output for connected BSCs 2010-05-02 19:31:13 +08:00
Holger Hans Peter Freyther
d48bfe0e93 bssap: Store the link_id in the new msgb->cb.
Work with a new version of libosmocore that gets rid of
additional pointers.
2010-05-01 15:22:40 +08:00
Holger Hans Peter Freyther
41cdaf520d remove any reference to 'struct gsm_bts_link' 2010-05-01 15:19:14 +08:00
Harald Welte
f94418a129 gsm_04_11.c: Use msgb->l4h instead of sms->smsh, as the latter is gone 2010-05-01 15:18:37 +08:00
Holger Hans Peter Freyther
88b299ca24 configure.in: Bump the version due mem leak fixes.
The nat is stable and in testing..
2010-05-01 15:01:45 +08:00
Holger Hans Peter Freyther
58a2758e78 nat: Improve log message and refer to the BSC that was lost. 2010-05-01 10:37:15 +08:00
Holger Hans Peter Freyther
be3fdc2c6e nat: Fix memory leak... in MGCP forwarding
The code needs to be refactored but this is fixing the leak for
now. We used to forward everything to the BSC but now we handle
the DLCX locally and this means we need to clear the patched
message. We should refactor it to not generate the patched msg
until a lot later.
2010-05-01 10:31:53 +08:00
Holger Hans Peter Freyther
6a8d765334 [vty] Free the matched at the end of the routine.
Remove the return from the case labels and cleanup at
the end matched array at the end of the routine.
2010-04-30 13:24:09 +08:00
Holger Hans Peter Freyther
adebbfdfa7 [vty] Plug memory leak on auto completion.
I assume the original code crashed with a double free as we
have a cleanup at the end of the method. Return from the routine
like the case label below. This is fixing a memory leak I am
experimenting.
2010-04-30 13:18:05 +08:00
Holger Hans Peter Freyther
afccfb9380 [vty] Allow to create a buffer in a given context.
Stop using the global vty context for all allocations
and allow to embed the buffer into a given context, and
allocate sub buffers with the context of its parent.
2010-04-30 12:26:52 +08:00
Holger Hans Peter Freyther
0f7a8258f0 [vty] Move some allocations into the context of the vty. 2010-04-30 12:18:32 +08:00
Holger Hans Peter Freyther
2aa7f10939 [vty] Remove FIXME as it appears to do the right thing. 2010-04-30 11:33:34 +08:00
Holger Hans Peter Freyther
37ba5b3e35 nat: Report some more contexts 2010-04-30 11:08:22 +08:00
Holger Hans Peter Freyther
9f63d2b4ad [mgcp] Remove talloc.h header. 2010-04-29 21:03:43 +08:00
Holger Hans Peter Freyther
d21b5de8c0 nat: Do not use \n in the vty code.
When we really need a newline we need to use VTY_NEWLINE.
2010-04-27 15:35:14 +08:00
Holger Hans Peter Freyther
12b63716e2 nat: Add a command to close a given BSC Connection
This can be used to clear stale connections for a given BSC
or to force a reconnect of the BSC.
2010-04-27 13:21:39 +08:00
Holger Hans Peter Freyther
184961ea3e nat: Print the remote reference as well. 2010-04-27 13:11:18 +08:00
Holger Hans Peter Freyther
a9ec86029f Bump the version of OpenBSC. 2010-04-26 16:08:13 +08:00
Holger Hans Peter Freyther
d1b19f3308 [ts] Make the e1inp_ts delay configurable
Currently the nanoBTS bootstrap code requires a high delay
otherwise we are not bringing the device up properly. Changing
the init code turns out harder than it seems like. So this is
a workaround for that to allow a high speed RSL/OML connection
after the bringup.

The line driver can have a default TS delay. It is set to the
current default for the nanoBTS and the BS11. For the ipaccess
case we will set the delay lower for the RSL connection and
inside the ipaccess-config we can set it low right away to
have fast firmware flashing and such.
2010-04-26 16:02:04 +08:00
Holger Hans Peter Freyther
33f531fd12 ipaccess: Restore the original delay for the nanoBTS delay. 2010-04-26 10:33:56 +08:00
Holger Hans Peter Freyther
b051b3b161 bsc_init: Do not use magic numbers for GSM 12.21 states. 2010-04-26 10:32:34 +08:00
Holger Hans Peter Freyther
479a3aa707 bsc_init: Remove printf that sneaked in. 2010-04-26 10:27:42 +08:00
Holger Hans Peter Freyther
fd2a877e25 nat: Release the transaction id earlier, always reset the BSC
In case we can not find the SCCP connection we still want to
free any pending transaction ids and reset the BSC inside the
endpoint. In most cases this should be already done when the
SCCP connection or the whole BSC is gone.
2010-04-24 21:05:18 +08:00
Holger Hans Peter Freyther
53f797305f [mgcp] Possible memleak fix for the allowed reallocation case
When allowing to reallocate an allocated endpoint we will need
to free it first. When freeing we will free the call id and other
ids that we would have leaked otherwise.
2010-04-24 21:02:48 +08:00
Holger Hans Peter Freyther
691b40e834 nat: Attempt to clarify the text inside the log message. 2010-04-24 21:02:01 +08:00
Holger Hans Peter Freyther
e511d54dd0 nat: Allocate a named context to make dumping allocations possible
This is fixing the SIGUSR1 to really report the allocated
memory on stderr.
2010-04-23 21:56:57 +08:00
Holger Hans Peter Freyther
6edf7b9a51 bsc_msc_ip: Add a timeout for waiting for the CC of the network
Start a timeout to wait for the CC of the network and if it does
not come in time we will abort the connection and take down the
allocated lchans.
2010-04-23 18:22:26 +08:00
Holger Hans Peter Freyther
e4045679a8 nat: Only close connections that were fully connected
Remember that we have seen a CC and have a valid destination
local reference now and only send a fake RLC to the MSC when
we had connections in this state.
2010-04-23 14:13:27 +08:00
Holger Hans Peter Freyther
52ae9a461b nat: When having a proper close down, or a short read close the connection
For now close the connection when having a short read. This might
be due a network issue (loss of segment) or similiar. As we are not
handling these issues well, let us close the connection.
2010-04-23 00:23:03 +08:00
Holger Hans Peter Freyther
5bd9493257 nat: Only send DLCX when we have send a CRCX to the BSC on this endpoint 2010-04-22 20:12:13 +08:00
Holger Hans Peter Freyther
c92fd5d9d3 nat: Handle all queueing to the MSC through the same function. 2010-04-22 19:11:37 +08:00
Holger Hans Peter Freyther
01cf14d679 nat: Use show bsc config for showing the configuration. 2010-04-22 13:36:46 +08:00
Holger Hans Peter Freyther
840447e2bf [mgcp] Add a change callback and send a dummy packet on MDCX.
Send a dummy packet to make sure our Gateway will discover us
and can send the ringtone to us.
2010-04-22 13:23:05 +08:00
Holger Hans Peter Freyther
3f7586d571 nat: Use hex for the endpoint names 2010-04-22 13:06:24 +08:00
Holger Hans Peter Freyther
b74a9f13e5 [mgcp] Ignore every dummy packet...
This routine should operate on different packets and the
dummy load is smaller than a legitimate RTP header so it
is unlikely we will filture out genuine traffic.

The reason is the dummy load might be send more than once.
2010-04-22 12:15:38 +08:00
Holger Hans Peter Freyther
bbc2c6e765 nat: Change MGCP DLCX handling and send dummy MDCX to the BTS.
When setting a new MSC timeslot to a SCCP connection check if
any of the existing connections have this timeslot, if so we will
send a DLCX down the stream to make sure it is closed there, when
we will CRCX this new timeslot we will happily reallocate it.

When the SCCP connection goes away, or we get a DLCX from the
network, or the BSC is gone we will send a DLCX message down the
stream as well.

When we receive a CRCX from the network we will forward the CRCX
as usual and send a dummy MDCX after it.

For the DLCX and the dummy MDCX we send a custom MGCP message
that will not provoke an answer. Even if the downstream MGCP GW
will answer we will ignore it due the dummy transaction id that
is not used anywhere else.

This change should make sure that we close the dowstream endpoint
all the time, even when the DLCX arrives after the SCCP connection
is torndown.
2010-04-22 12:13:44 +08:00
Holger Hans Peter Freyther
7e3724ad18 nat: Move the write queue init to the allocation function
This is required for unit tests that want to queue messages
and see if we can provoke a memleak.
2010-04-22 12:13:44 +08:00
Holger Hans Peter Freyther
569dccf947 nat: Clear the queued messages at the end
It is possible that the calls from the loop would queue
more messages for the BSC and then we would have a nice
memory leak... Move it to the bottom.
2010-04-22 12:13:44 +08:00
Holger Hans Peter Freyther
89a378e9aa [mgcp] Protocol extension to not generate answers.
For the NAT we want to send requests in a send and forget
way and we are not interested in seeing the answers, so tell
the gateway to not answer them.
2010-04-22 12:13:44 +08:00
Holger Hans Peter Freyther
4a78c7b250 [mgcp] Print a Deleted endpoint message again. 2010-04-22 12:13:44 +08:00
Holger Hans Peter Freyther
c71013091a [mgcp] Add a dummy send method...
This can be used by higher level code to send one dummy
message from the audio port to the network. This can be
used to make the remote discover the nated port of this
endpoint.
2010-04-21 21:25:13 +08:00
Holger Hans Peter Freyther
4b1cde10fe [sccp] Move from DEBUGP to LOGP in sccp.c 2010-04-21 21:08:58 +08:00
Holger Hans Peter Freyther
0f5a2345d1 [nat] Degrade the message to a plain debug output. 2010-04-21 20:17:18 +08:00
Holger Hans Peter Freyther
ae81ff95ea [nat] Fix the vty option... use the right argument. 2010-04-21 20:07:07 +08:00
Holger Hans Peter Freyther
e5981edf6a [nat] Add option to forbid the paging to the BSC.
This can be done for testing purposes and to allow making
a BTS crash that can not handle paging requests properly.
2010-04-21 19:05:14 +08:00
Holger Hans Peter Freyther
93cc16ae4f [nat] Lookup by BSC Connection otherwise the point of reassigning the is defeated
When sending a MSG to the MSC try to find the to be used "src" reference
by comparing the reference on the BSC and the BSC connection. Only this
tuple needs to be unique.
Actually only when looking at the SRC REF we need to compare the BSC as the
dest reference should be unique but we are just making the check a bit stronger
to make it look symmetric.
2010-04-21 18:56:12 +08:00
Holger Hans Peter Freyther
119a1976f5 [nat] Slightly improve logging..
If we find the connection of a different BSC at least log the
BSCs that had duplicated references. We should also dump the
src ref and such but i am not doing this right now.
2010-04-21 18:49:55 +08:00
Holger Hans Peter Freyther
c53c2ab524 [nat] Ignore paging that is to page by BSS...
We do not want to handle this identity. If we can not page by
lac there is no need to page anything else.
2010-04-21 18:47:24 +08:00
Holger Hans Peter Freyther
32423500f6 [nat] Add unit test to forward Proto Error messages back both ways. 2010-04-21 15:46:38 +08:00
Holger Hans Peter Freyther
c3a6a1dbe5 [sccp] Parse the error message and add a unit test for it. 2010-04-21 15:46:38 +08:00
Holger Hans Peter Freyther
f4f090ee36 [nat] Reword warning when we had a pending transaction and forget about it. 2010-04-21 15:17:45 +08:00
Holger Hans Peter Freyther
2a554bfcc4 [nat] Cope with a bad BSC reassigning in use SRC REF
Some closed source BSC like to assign the SRC REF from a
small static pool and might reuses one we have not yet given
up on.
2010-04-21 10:47:25 +08:00
Holger Hans Peter Freyther
a12dea66ca [ipaccess] Attempt to fix setting unit ids with a multi trx setup
Add a --trx/-t NR option to set the TRX nr to be used when calling
set unit id and NVRAM. This was not tested and might or might not
work.
2010-04-20 22:22:00 +08:00
Holger Hans Peter Freyther
ec59bb04df Versioning for the bsc_msc_ip 2010-04-20 18:10:27 +08:00
Holger Hans Peter Freyther
4417f7f477 [vty] Allow to set the RACH NM attributes on a per BTS basis
Be able to tune the RACH settings of the BTS via the vty interface,
by default they are initialized to -1 which means we will use the
content of the static array (BTS default) and can be changed via
the VTY interface. I have verified the setting on the nanoBTS with
wireshark and I have tested writing the config file.
2010-04-20 18:02:25 +08:00
Holger Hans Peter Freyther
39563af27c [paging] Implement the counting for TCH/H and TCH/F
Add some code to count TCH/H and TCH/F and also handle
the neci bit of the network. Our channel allocator will
allocate a TCH/F if we request a TCH/H but can not allocate it.
2010-04-20 17:15:21 +08:00
Holger Hans Peter Freyther
242faaafd1 [paging] Only page if we have some free channels right now
Only page if we have a load that is acceptable for paging. This
option is off by default, and can be enabled per bts. The idea
is that when we have no resources right now we will not page as
it will only create more RACHs and increase the load.
2010-04-20 17:10:43 +08:00
Holger Hans Peter Freyther
f77c0cd428 Version bump for On-Waves
* Revert RTP_PAYLOAD change as it does not work on AMR
* Change paging to not send it as a bulk...
2010-04-20 14:36:40 +08:00
Holger Hans Peter Freyther
4103a3e5b9 Revert "ipaccess: Send RTP Payload IE for CRCX & MDCX"
This is causing a regression with AMR audio. The nanoBTS
is sending a MDCX NACK with Cause 0x52. Reverting this
commit makes it work again.

This reverts commit b54dda4cef.
2010-04-20 14:08:20 +08:00
Holger Hans Peter Freyther
4aca7f621f [paging] Continuisly send paging commands.
Instead of throwing a huge pile of paging commands to the BTS
we will submit one paging command every half second. This way
we can have different messages between the paging commands.
2010-04-20 12:27:33 +08:00
Holger Hans Peter Freyther
507d536ce8 [paging] When giving credit try to send out paging requests too.
Make sure the paging timer is restarted after giving some credit
and send out paging requests.
2010-04-20 10:59:33 +08:00
Holger Hans Peter Freyther
cb618c7980 [paging] Revert the paging band aid. 2010-04-20 10:54:43 +08:00
Holger Hans Peter Freyther
3c0702d3c5 Increase the minor version as this is a band-aid.. 2010-04-19 22:30:28 +08:00
Holger Hans Peter Freyther
caf24567d1 BAND AID... Reduce the delay timer, reduce number of paging requests we send
This is a band aid and not a proper fix. Reduce the time between two
IPA commands even if it is breaking rugby sized BTSs, limit the paging
commands we send during one iteration through the event loop. This should
prevent us from killing ourselves in a RACH loop.
2010-04-19 22:30:21 +08:00
Holger Hans Peter Freyther
1d34c6ac5a bsc_msc_ip: Crash fix on MO-Call starting with a SDCCH
We do not assing a GSM Subscriber to Mobile Originated calls, when
requesting a SDCCH and then starting call control we will crash here
due trying to copy a NULL subscriber from the lchan to the other.

We do not need to know the IMSI at the BSC so it is okay to not
copy the subscriber around, we could even kill all subscriber handling
in the future.
2010-04-19 22:15:32 +08:00
Holger Hans Peter Freyther
1506f8e465 [paging] When we ran down to 0 available paging slots start a credit timer
It might be that we run down to zero available slots but the BTS
might not send us a load indication. This can happen if we think
we send paging requests and the BTS disagrees and considers them
as errors and does not count the paging message.
When we drop to zero we will start a credit timer to give us extra
credit after six seconds, if we get a CCCH load indication before
we will stop the timer.
2010-04-19 19:41:26 +08:00
Holger Hans Peter Freyther
f044c585e2 Merge remote branch 'origin/master' into on-waves/bsc-master
Conflicts:
	openbsc/include/openbsc/abis_rsl.h
	openbsc/include/openbsc/mgcp.h
	openbsc/src/abis_rsl.c
	openbsc/src/chan_alloc.c
	openbsc/src/handover_logic.c
	openbsc/src/mgcp/mgcp_network.c
	openbsc/src/vty/command.c
	openbsc/src/vty_interface.c
2010-04-19 17:17:59 +08:00
Holger Hans Peter Freyther
6d17dd1314 Increase the version. 2010-04-19 17:06:17 +08:00
Holger Hans Peter Freyther
7cb6867ea3 [vty] Count pending paging requests for the vty
Implement a method to count the number of pending paging requests
per bts and print it on the VTY. This helps to see how big the
backlog of requests is for a given BTS.
2010-04-19 16:20:28 +08:00
Holger Hans Peter Freyther
d8138c43a1 nat: Make sccp/bsc show connections more Cisco like...
Second attempt to use a syntax more comparable to 'Cisco',
I have never used such a system... let us see how this is
going.
2010-04-19 16:06:43 +08:00
Holger Hans Peter Freyther
46d9b94477 [vty] Allow to allocate TCH/H and TCH/F too for testing purposes. 2010-04-19 16:01:14 +08:00
Holger Hans Peter Freyther
4f705b9f99 [vty] Add a test command to allocate all SDCCH 2010-04-19 16:01:14 +08:00
Holger Hans Peter Freyther
c592e697ce [alloc] Assign a TCH for LU when all SDCCHs are occupied.
When the cell becomes visible we will be bombed with location
updating requests and to reduce the load on the network we should
assign as many channels for it as possible. During load peek it
is even more important than to have a spare voice channel and in
general the LU procedure is pretty fast.
2010-04-19 16:01:07 +08:00
Holger Hans Peter Freyther
ebb6b99c63 nat: Do not use 0/0 for mux/timeslot by default
0 is a valid timeslot and we should not use it... use
a negative value to be save.
2010-04-18 03:07:22 +08:00
Holger Hans Peter Freyther
e08253a3f7 nat: Clear the connection on a DLCX
We can forget about the timeslot/multiplex when getting
the DLCX. This way we make room for the next connection
that might need to reuse this address.
2010-04-18 03:05:27 +08:00
Holger Hans Peter Freyther
5e86095364 nat: Always initialize the out pointer...
Always initialize the pointer to a invalid value in case
we encounter a parsing error or such.
2010-04-18 02:41:20 +08:00
Holger Hans Peter Freyther
a7c144888d nat: Fix the test case by allocating a config.
For the statistics we do need to have an allocated config,
otherwise we will nicely crash.
2010-04-18 02:40:33 +08:00
Holger Hans Peter Freyther
7897c4446b nat: Return the SCCP Connection again...
We will reset the multiplex in a DLCX message and then
we can reset the multiplex as well...even if the MGCP
connection is staying open. or at least this is a theory.

The MSC likes to leave a connection open during CallControl
when hanging up early enough in the process.
2010-04-18 02:40:33 +08:00
Holger Hans Peter Freyther
ff9e09b2bc nat: Return the newest SCCP connection...
In case we have a stale SCCP connection with an Endpoint that
we want to reassign...use the newest (last) occurence of that
as it is most likely the one we want to handle.
2010-04-18 02:40:32 +08:00
Holger Hans Peter Freyther
ecf5cc294d bsc_msc_ip: Print a small status on active connections
This needs to be improved to print TS of the lchan, when
the connection was created, when we received the last IT.
2010-04-18 02:40:32 +08:00
Holger Hans Peter Freyther
82126763a7 nat: Increase the right counter on calls. 2010-04-18 02:40:31 +08:00
Holger Hans Peter Freyther
a380c89a9c nat: Add new connections to the end of the list
By adding them to the end the VTY interface will only append
connections and not change the order on each invocation.
2010-04-18 02:40:31 +08:00
Holger Hans Peter Freyther
bedaf5da64 bssap: Move parsing of paging into the paging section... 2010-04-18 02:40:30 +08:00
Holger Freyther
2b08aa35a6 nat: Remove the SHOW_STR from none show commands. 2010-04-18 02:40:30 +08:00
Holger Hans Peter Freyther
c24632930a bsc_msc_ip: Allow to put the MSC address into the network config 2010-04-17 09:07:24 +02:00
Holger Hans Peter Freyther
f140348eff nat: Print the LAC that was searched for and not found. 2010-04-17 08:07:19 +02:00
Holger Hans Peter Freyther
b5de1b0781 nat: Mention when we do not find a BSC for a given token.
This might help to identify what is wrong with the config
of the BSC. Also using the result of TLVP_VAL as a char
pointer looks suspicious...
2010-04-17 08:07:03 +02:00
Holger Hans Peter Freyther
b022cc3b8e nat: Print the IP address of the BSC that does not respond to the query. 2010-04-17 07:58:17 +02:00
Holger Hans Peter Freyther
e8396c9663 nat: Make the MSC configurable. 2010-04-17 07:48:45 +02:00
Holger Hans Peter Freyther
941839b300 nat: Move MSC ip address into the config..
The address can still be specified on the cli and it will
overwrite the config in the config file.
2010-04-17 07:31:08 +02:00
Holger Hans Peter Freyther
23a0e46f11 Add rf_locked to the configuration writing. 2010-04-17 07:31:08 +02:00
Holger Hans Peter Freyther
cb8fd6e99e Use osmocore tlv definition for GSM0808. 2010-04-17 07:31:03 +02:00
Holger Hans Peter Freyther
e66bea8ad7 [mgcp] Fix vty file generation for the BSC nat and other cases
The current setting was not properly written out, this commit is
fixing it. This includes indention, empty bts ip, wrong command
for endpoints and the wrong number (+1 as zero is allocated but
unused).
2010-04-16 16:59:48 +02:00
Holger Hans Peter Freyther
e8a9f471ef nat: Two fixes for the write memory case...
Add new BSCs to the tail so we keep the sort order when writing
them out to the vty, fix the LAC command.
2010-04-16 16:52:20 +02:00
Holger Hans Peter Freyther
c2d66bdf5a Increase the version 2010-04-14 11:28:55 +02:00
Holger Hans Peter Freyther
80b584bbe7 [bsc_msc_ip] Implement a simple RF lock command interface
Right now this is using unix domain sockets and it only
supports query, on and off as commands. In the future we
want to have a vty<->snmp bridge or at least more status
exposed via snmp.
2010-04-14 11:19:07 +02:00
Holger Hans Peter Freyther
15c21e8eec bsc_msc_ip.c: Create the GSM network earlier, send the reset on each connection
Create the GSM network at the end of the init, send the
GSM reset on each reconnection and close a small window
when we would send a SCCP msg before being authenticated.

For that we have introduced an authenticated into the bsc_msc
struct and will manage it inside the bsc_msc_ip.c
2010-04-14 08:49:15 +02:00
Holger Hans Peter Freyther
c0a1fff064 bsc_msc_ip.c: Set the signal handler earlier..
We should set this before starting any network operation.
2010-04-14 08:46:29 +02:00
Holger Hans Peter Freyther
77fa4d2386 bsc_msc_ip.c: Fix the source comment...
This file is the bsc_msc_ip process to communicate with a MSC
and to implement the GSM 08.08 spec.
2010-04-14 08:34:24 +02:00
Holger Hans Peter Freyther
9be8752541 [bsc_msc_ip] Fix the name of the process. 2010-04-13 11:28:13 +02:00
Holger Hans Peter Freyther
2b57b3cea4 [bsc_msc_ip] Remove the possible dangerous -P option for the BSC
We always want to handle the CRCX the way we want to without
allocating a BSC proxy process. The default value of 1 is fine
for the bsc_msc_ip and we should not allow to set it.
2010-04-13 11:27:17 +02:00
Holger Hans Peter Freyther
00c531709a nat: Add config option to filter/handle certain imsi'es. 2010-04-13 09:50:38 +02:00
Holger Hans Peter Freyther
a094108f84 [statistics] Count the times we lost the connection to the MSC. 2010-04-13 09:47:22 +02:00
Holger Hans Peter Freyther
61e73eec3f [nat] Add show statistics to the nat 2010-04-13 09:47:22 +02:00
Holger Hans Peter Freyther
1aa2798919 [statistics] Provide basic statistics for the NAT
Count number of SCCP connections, number of BSC reconnects,
number of calls. For most of them we have a per BSC and a
global count.

Right now all structs using the counters survive until the
end of the application so we do not need to free them.
2010-04-13 09:47:22 +02:00
Holger Hans Peter Freyther
b829eac9bc [statistics] Keep track of OML/RSL failures of the BTS. 2010-04-13 09:47:22 +02:00
Holger Hans Peter Freyther
7b1719327d [statistics] Keep track of rf failures and rll release failures
Add two new counters to count the RF Failures and the RLL Release
failure and make them available via the vty interface.
2010-04-13 09:47:22 +02:00
Holger Hans Peter Freyther
493645eda9 bsc_msc_ip: Install BSC specific show statistics command. 2010-04-13 09:47:21 +02:00
Holger Hans Peter Freyther
8614cd0be7 [mgcp] Only write audio_name/payload when it is actually set. 2010-04-13 09:47:21 +02:00
Holger Hans Peter Freyther
19bd74d093 [vty] Separate BSC and MSC statistics. Make it easy to print them.
Move the statistics command into the MSC part and move the
BSC statistics printing into a subroutine.
2010-04-13 09:27:13 +02:00
Holger Hans Peter Freyther
4821b5a847 [nat] Change the command strings
Put the Target/Object first... Apparently this is more what people
that know IOS expect to do.
2010-04-12 07:29:22 +02:00
Holger Hans Peter Freyther
84df56d577 Increase version.. 2010-04-11 19:41:32 +02:00
Holger Hans Peter Freyther
4e23d5f87f [bsc_init] When the RSL/OML connection drops, free all lchan
Free all allocated channels on the TRX that failed, go through
lchan_free to signal higher layers and then force a reset of
the channel. Make the TRX and TS unusable by setting the operational
set to 0 (not really defined).
2010-04-11 19:34:43 +02:00
Holger Hans Peter Freyther
4346424987 [ipa] Fix the reporting of link down...
Now bsc_init.c is able to handle the link down messages.
2010-04-11 18:54:58 +02:00
Holger Hans Peter Freyther
520656e004 [ipa] Handle losing the RSL/OML connection..
This is addressing multiple issues regarding the loss of the
OML/RSL link to the BTS.

1.) When we lose the OML link, close down all RSL connections
on all TRXs (only tested with one TRX) and free the e1inp_line
allocated for the OML connection.
2.) When we lose the RSL link on any TRX and we know to which
lines this connection belongs, we will close down the OML connection
as we have a problem to just reactivate the RSL link.
3.) When we lose the RSL link on any TRX and we do not know
where it belongs to we will free the bfd we have allocated in the
rsl listen/accept method and we properly close the socket (i could
not test this one properly).
4.) When we already have a bts->oml_link we will throw it away
and use the new link.
2010-04-11 18:49:03 +02:00
Holger Hans Peter Freyther
9dac231fe4 e1_input: Stop the timer when deleting the signalling link on the TS
Stop the tx_timer when deleting the link on top of that ts. Otherwise
bad things might happen. E.g. when scheduling a write on OML and then
the OML link vanishes...

This is a slight layering violation as there could be more than
one signalling link on the timeslow (at least in theory) so the
queue and the timer should move to the e1inp_sign_link.
2010-04-11 17:18:02 +02:00
Holger Hans Peter Freyther
2bb518a3bd [e1_input] When destroying a link clear all pending messages 2010-04-11 14:13:10 +02:00
Holger Hans Peter Freyther
476940f747 [vty] First set of fixes for the oml/rsl con dropping
The code had wrong documentation in the VTY, it crashed
when OML or RSL was not up yet. These issues are fixed
right now.
2010-04-11 12:46:45 +02:00
Holger Hans Peter Freyther
8deab8cdee Bump the version.. 2010-04-11 11:36:37 +02:00
Holger Hans Peter Freyther
a54f9e81c8 Revert "ipa: Reduce the throttling of the IPA msges"
Reducing the throttling to this value created a regression with
bringing up RSL on the nanoBTS 900. We do seem to have a bug/issue
in the bsc_init code and might send a command too early without this
longer wait period and then the state transition does not happen.

For now it is agreed that reverting is the best thing to do.

Debugged-by: Sylvain Munaut <246tnt@gmail.com>

This reverts commit f5284ae1cf.
2010-04-11 10:14:39 +02:00
Holger Hans Peter Freyther
ed4390747f bsc_msc_ip.c: Do not directly write but use the write queue..
Use the write queue to write data to the MSC instead of
using a direct write.
2010-04-11 10:08:42 +02:00
Holger Hans Peter Freyther
242d098d32 nat: Update the nat configuration 2010-04-11 10:06:23 +02:00
Holger Hans Peter Freyther
f795164f04 [paging] Start with a smaller paging limit...
The value 20 is just a random number and it really depends
on the number of TRX on a bts to be a sane or insane limit.
2010-04-09 23:20:11 +02:00
Holger Hans Peter Freyther
b6c6d43daa [paging] Move code to use LOGP and print some more information 2010-04-09 23:20:11 +02:00
Holger Hans Peter Freyther
82df124c8e [paging] Simplify the last request and treat llist as a queue
The current code was overly complex. It tried to iterate over
the list in a round robin and we had to keep track of the last
element, see if we remove that one, check if the list becomes
empty... This can all replaced by treating the double linked
list as a queue. We take the item at the front, do something
on it and then and then put it back to the list at the end.
2010-04-09 23:20:04 +02:00
Holger Hans Peter Freyther
189587f428 paging: Fix format compiler warning... 2010-04-09 21:31:16 +02:00
Holger Hans Peter Freyther
45ab581f37 [mgcp] Improve the endpoint display on the vty..
Make sure one understands the two values for number of
incoming packets..
2010-04-09 18:53:24 +02:00
Holger Hans Peter Freyther
f48776ea6a [mgcp] Print the IP addr of the BTS we have detected. 2010-04-09 18:53:01 +02:00
Holger Hans Peter Freyther
7fc17cff64 nat: Set a dummy bts_ip to avoid misdetection of the bts...
It was possible that the nat detected the core network
gateway as the bts just due being the first to send data
to the port. Fix it by setting a dummy bts_ip to force
the mgcp_network code to compare the in_addr.
2010-04-09 18:51:01 +02:00
Holger Hans Peter Freyther
a5a7075fe5 paging: Avoid integer underflow on ipaccess
On the nanoBTS we do not receive any load indication for the
paging channel and we just decrement our available slots and
the unsigned int wraps to the maximum value. Together with a
not yet understood bug this makes us go amock.

For the nanoBTS and even the Siemens BS11 resetting the load
to 20 after two seconds should be just fine. For the nanoBTS
we would need to reset the 20 a lot more earlier but we need
to take a look at how often we run low.
2010-04-09 18:38:06 +02:00
Holger Hans Peter Freyther
2b4e366083 Bump the version to 0.3.94... 2010-04-09 17:18:25 +02:00
Holger Hans Peter Freyther
bf1eb64b02 [rsl] Set the right state when asking for the activation.
Set the state to activation to avoid a warning about the
getting a CHAN ACK without waiting for it. We set it in
the code to make sure it is set after all error checking
to avoid inconsistent state as the state is only set back
to NONE/ACT due replies from the BTS.
2010-04-09 15:04:17 +02:00
Holger Hans Peter Freyther
f0fbae94ea [rsl] Rework the lchan channel release procedure
1.) free every SAPI from 1-7 and wait for the confirmation
    and then continue until all of them are freed. If the
    SAPI is not torn down we will receive a timeout and then
    we force the RF Channel Release...
2.) once SAPI is down we send the RR Release, SACCH Deact
3.) the abis_rsl will see that all SAPIs are down and then
    will release channel...
2010-04-09 14:30:52 +02:00
Holger Hans Peter Freyther
8fe4df503c [rsl] Remove method that is not called by anything. 2010-04-09 13:06:56 +02:00
Holger Hans Peter Freyther
8da7103070 [rsl] Set the release state from within the lchan class
Currently our GSM04.11 code is closing the link for SAPI=3
and this would mean that the whole channel would be scheduled
for close... where we only want to close everything when freeing
the lchan or handling an error.
2010-04-09 12:44:21 +02:00
Holger Hans Peter Freyther
f73f6fad8c [rsl] Introduce a method to set the state of the lchan
Setting the state through a dedicated method allows us to
track the state transitions and check if they are done in
a proper way.
2010-04-09 12:42:37 +02:00
Holger Hans Peter Freyther
25cb84be12 [rsl] Introduce an error state for the lchan and set it on release
When we issue a RF Channel Release in case of a failure we receive
RLL release indications after the channel was tearn down and we
issue another RF Channel Release as a result. The channel allocator
might have already allocated this channel and we release the channel
again with another MS on it.

Make rsl_rf_chan_release take an error argument and make it set
a new state in case of an error and change the RF Channel Release
ack to not set the state back to none in case of an error but wait
for a timeout that is a bit higher than T3111.

I tested this with removing the battery during a phonecall and
waiting for the channel failure. With this test we only send the
release once.
2010-04-09 12:26:32 +02:00
Holger Hans Peter Freyther
d9ae25c1bf [rsl] Implement the T3111 timer to delay the RF Channel release 2010-04-09 11:53:35 +02:00
Holger Hans Peter Freyther
5c011366c9 [rsl] Check the assumption that RF Channel Release is sent during release
We assume that the lchan_free will initiate the release and
that when we handle the RLL release indication or the release
request as part of the shutdown sequence.
2010-04-09 11:53:12 +02:00
Holger Hans Peter Freyther
79e2d4230d bsc_msc_ip.c: Fix crash when gsmnet is not yet initialized. 2010-04-09 11:53:12 +02:00
Holger Hans Peter Freyther
8ecd029b12 [rsl] Move rf channel release scheduling to a new method
The current channel release has a couple of issues we will
need to fix in a set of upcoming commits.

The issues include:
    1.) sending release twice
    2.) reassigning the channel inbetween the relase..
2010-04-08 22:39:34 +02:00
Holger Hans Peter Freyther
3c0508e94a [vty] Add ipa specific command to provoke failures to test OML/RSL reconnect
We need to simulate OML/RSL failure in an easy and fast way
and adding a command to do so seems like a good way to achieve
this. The command is a bit misplaced, in one way it is no config
and does not belong into the config node but then again it does
not belong into the VIEW_NODE either as it is manipulating content.
2010-04-08 22:11:29 +02:00
Holger Hans Peter Freyther
f535aad612 bssap: Reset the msc_data on the lchan earlier/just in case
The refcount should drop to zero immediately and then the
msc_data would be reset automatically but it is better to
remove all traces of it right away.
2010-04-08 22:11:29 +02:00
Holger Hans Peter Freyther
d0ac8866f1 bssap: Use the new method to give up the secondary lchan and related resources 2010-04-08 22:11:24 +02:00
Holger Hans Peter Freyther
73f9a65f12 bssap: Forget the secondary lchan in the MSC data and forget the MSC data
We will handle sending the assignment failure inside the T10
timer but it is better to reset the secondary_lchan inside the
msc_data right away before we might accidently use it.
2010-04-08 21:35:00 +02:00
Holger Hans Peter Freyther
b2c55c49a8 bsc_msc_ip: Attempt to handle assignment failures more properly
1.) when we do get a assignment failure from the MS. It is coming
    on the old channel and not the new one. Fix the comparison. Also
    always reset the msc_data to NULL before dropping the reference
2.) the LCHAN signal handler in bssap.c claims that the T10 expire
    cb should free the secondary channel. It currently does not do
    it and we have to do it now...

the whole thing was not tested and even after this commit this
behavior is not heavily excercised... with OsmocoreBB we would be
able to do this in the future.
2010-04-08 21:29:31 +02:00
Holger Hans Peter Freyther
8dc241959c bsc_msc_ip.c: Move from DEBUG to LOG logging
Use the oppurtunity to flag errors as errors in the code
base.
2010-04-08 20:29:36 +02:00
Holger Hans Peter Freyther
f99709430a bsc_msc_ip.c: Mention the timestamp config option. 2010-04-08 20:17:12 +02:00
Holger Hans Peter Freyther
b9bc45b1b0 bssap: Speculative crash fix when queueing messages for the BTS
It appears to be possible that we attempt to submit a DTAP
on a SCCP connection when we have a channel without the msc_data
assigned. This change should fix the crash (which is not well
understood), fix a memleak in the case of the queue being full.
2010-04-08 20:09:48 +02:00
Holger Hans Peter Freyther
65d10c1320 bsc_msc_ip: Specify the size we can read directly...
data_len is wrong as well as we have reserved... specifying
it directly seems to make valgrind happy. This also means that
we might receive more than one UDP message and do not properly
forward things. I will need to investigate.
2010-04-08 17:07:45 +02:00
Holger Hans Peter Freyther
414ba77f75 [paging] Do not use request after it was was destroyed..
Increment the counter before we call the remove request
which is freeing the request...
2010-04-08 16:48:46 +02:00
Holger Hans Peter Freyther
59f2470650 nat: Handle unknown RLSD by send a RLC back to the network. 2010-04-08 11:28:12 +02:00
Holger Hans Peter Freyther
339dfdb624 nat: Attempt to handle exceptions on the fd and trat them as connection loss 2010-04-08 11:16:43 +02:00
Holger Hans Peter Freyther
9e2e2e04d1 nat: Print the IP address of the connected BSCs 2010-04-08 10:35:20 +02:00
Holger Hans Peter Freyther
2ab6db0153 nat: Rename variable to make it use msc in the name 2010-04-08 10:31:07 +02:00
Holger Hans Peter Freyther
6cb97bdebe nat: Attempt to have a single BSC write method
This method currently prepends the IPA header and sends
the data. In the future we might be able to use SCTP for
it.

We have to remove the IPA header from the static messages
for that to work.

This code is untested.
2010-04-08 10:24:57 +02:00
Holger Hans Peter Freyther
8c3694a282 Bump the version for the BSC. 2010-04-08 10:09:49 +02:00
Holger Hans Peter Freyther
191d23a889 nat: Rename bsc_write to bsc_send_data 2010-04-08 09:20:48 +02:00
Holger Hans Peter Freyther
a5963097ac bssap: Comment and code cleanup 2010-04-07 20:35:59 +02:00
Holger Hans Peter Freyther
221fb37518 bssap: Switch to use LOGP and pick some debug categories 2010-04-07 20:35:02 +02:00
Holger Hans Peter Freyther
4ec8a390cc bssap: Another possible null derference on the code.
We do not want to send a msg over the NULL lchan. Let us
return fast from here.
2010-04-07 20:22:21 +02:00
Holger Hans Peter Freyther
cf3f1c8b3d vty: Fix the byteorder... of the bound_ip
We are storing the bound_ip in host byteorder but when
using ntohl we need to convert it back to to network
byte order.
2010-04-07 15:39:16 +02:00
Holger Hans Peter Freyther
984f3b8047 bssap: Speculative crash fix. 2010-04-07 15:37:33 +02:00
Holger Hans Peter Freyther
ec1f15d513 [mgcp] Print the errno/strerror when we can not receive from our socket 2010-04-07 12:55:40 +02:00
Holger Hans Peter Freyther
b76cd5ed7e nat: Send the reset after we have received the init ack
Sending the reset right away will upset the MSC and we
need to wait for the first contact.
2010-04-07 11:20:36 +02:00
Holger Hans Peter Freyther
1592550d98 nat: Fix the reset message and prepend the IPA header 2010-04-07 11:11:11 +02:00
Holger Hans Peter Freyther
5cdf42b1a4 nat: Allow to realloc already allocated endpoints
E.g. when the MGCP on the BSS is not responding we could block
all of our endpoints. As we are mostly in the middle and forward
bits we will happily reallocate the endpoints.
2010-04-07 10:52:48 +02:00
Holger Hans Peter Freyther
3a6b1a41fb [mgcp] Add an option to allow using reallocing an endpoint
For some mode of operation it can be acceptable to reallocate
an already allocated endpoint. This can be the case when we
only deal with one call agent that is keeping track of the
endpoint but slightly confused.
2010-04-07 10:51:27 +02:00
Holger Hans Peter Freyther
1b5b3bbfdb nat: Send a GSM0808 message to the MSC when we are reconnecting
The rest of the code should filter the reset ack msg. This should
make the MSC give up all resources it had allocated for us.
2010-04-07 10:46:30 +02:00
Holger Hans Peter Freyther
3a67035411 nat: Attempt to make MGCP forwarding more robust
When not being able to allocate the msgb for the forwarded data
there is no point in keeping and preparing the transaction. So
we can move the msg creation a bit up and only do the allocations
after having done the msgb allocation.

When receiving a DLCX we will now delete the endpoint right away. This
means when a BSS does not respond to the DLCX our endpoint will not
be blocked. E.g. this could happen when the MGCP is restarting or
in similiar conditions. When the BSS is not responding we move the
burden up the chain to the CallAgent. We have to still keep track
of the transaction id and the bsc pointer to keep the mgcp forward
routine working.
2010-04-07 09:53:54 +02:00
Holger Hans Peter Freyther
cb1937a4c5 [mgcp] Count incoming RTP packets from the BTS and remote 2010-04-07 09:37:17 +02:00
Holger Hans Peter Freyther
3cfd5d6a02 bsc_msc_ip.c: Fix the -e command line option 2010-04-07 08:41:01 +02:00
Holger Hans Peter Freyther
6cc4dbfd46 Tag on-waves 0.3.92 after the merge with master 2010-04-06 21:54:03 +02:00
Holger Hans Peter Freyther
9960d59fff Merge remote branch 'origin/master' into on-waves/bsc-master
* Move to the new log code and update binaries
* Catch up with lchan changes from master

Conflicts:
	openbsc/include/openbsc/Makefile.am
	openbsc/include/openbsc/gsm_data.h
	openbsc/src/Makefile.am
	openbsc/src/bsc_rll.c
	openbsc/src/chan_alloc.c
	openbsc/src/debug.c
	openbsc/src/gsm_04_08.c
	openbsc/src/gsm_04_11.c
	openbsc/src/gsm_subscriber_base.c
	openbsc/src/handover_logic.c
	openbsc/src/silent_call.c
	openbsc/src/transaction.c
	openbsc/src/vty_interface.c
	openbsc/src/vty_interface_cmds.c
2010-04-06 21:51:26 +02:00
Holger Hans Peter Freyther
161bd6d253 Increase version number 2010-04-06 17:56:01 +02:00
Holger Hans Peter Freyther
add3472e9f bsc_msc_ip.c: Do not attempt to disconnect when not connected
This is fixing a segfault due calling bsc_unregsiter_fd twice
without being in the list.
2010-04-06 17:55:33 +02:00
Holger Hans Peter Freyther
33b0bee457 bsc_msc_ip.c: Crash fix when the MSC disconnects
Check if we do have the msc_data before invoking code in
bssap.c. We might have lost the MSC connection and asked
for the channel to be taken down but we might have received
one last message from the BTS.
2010-04-06 17:44:39 +02:00
Holger Hans Peter Freyther
6949db1bd8 nat: Send a RLSD to the network for connections belonging to the BSC
Sending a RLSD with SCCP failure makes the MSC free all the resources
(MGCP, audio channels), right now we are ignoring the RLC we get from
the network and print a unhandled message.
2010-04-06 17:44:39 +02:00
Holger Hans Peter Freyther
8ae0080e21 bsc_msc_ip.c: Register the SIGUSR2 handler... to really handle it. 2010-04-06 17:44:39 +02:00
Holger Hans Peter Freyther
546c296c4a nat: Print a MSG when receiving unknown SCCP messages. 2010-04-06 17:44:39 +02:00
Holger Hans Peter Freyther
86f42eb6a5 nat: Store the config in the connection instead of the lac
This allows that we can print the Nr. next to the lac
and it allows us to change the lac at runtime without
reconnecting the BSC.
2010-04-06 15:12:25 +02:00
Holger Hans Peter Freyther
494c086dca nat: Close the filedescriptor when ignoring the request. 2010-04-06 12:42:35 +02:00
Holger Hans Peter Freyther
6b18c8f3b6 bsc_msc_ip.c: Remove unused variable. 2010-04-06 12:25:19 +02:00
Holger Hans Peter Freyther
87f6d26c2e [vty] Add the nat area to the list of categories. 2010-04-06 12:09:02 +02:00
Holger Hans Peter Freyther
fab2ff34c4 nat: Add logging commands for the nat as well. 2010-04-06 12:03:11 +02:00
Holger Hans Peter Freyther
06d353e02e [mgcp] Add the logging commands for the MGCP command. 2010-04-06 12:03:05 +02:00
Holger Hans Peter Freyther
dfe47549c6 [vty] Move the VTY logging commands to a new file
Currently vty_interface.c is used for the BSC config, in case of
the MGCP Gateway or the BSC Nat process these logging commands are
not available. Move the commands to a new vty_interface_cmds.c file
to allow to share basic commands across different programs.
2010-04-06 11:55:37 +02:00
Holger Hans Peter Freyther
c70e8c2103 nat: Fix thinko... use the right fd to determine the IP of the bts
Use the fd of the BSC Connection to determine the IP address of the
BTS as we are seeing it.
2010-04-06 11:17:56 +02:00
Holger Hans Peter Freyther
b462a03c35 nat: Improve the log message and print the errno/strerror(errno) 2010-04-06 11:17:07 +02:00
Holger Hans Peter Freyther
6e0ec5b6fa [mgcp] Do not patch RTP payload when type is set to -1.
For the nat we might or might not want to patch it, do not
patch if we have no valid rtp payload type.
2010-04-06 11:15:50 +02:00
Holger Hans Peter Freyther
6768387f16 nat: Set the MGCP audio payload to -1.
This value is copied into the bts_audio_payload when allocating
a BTS MGCP endpoint. For the nat we have actually no interest in
patching MGCP messages. We will patch them to the network because
the code will do it anyway, we will not patch things back to the
BTS.
2010-04-06 11:14:03 +02:00
Holger Hans Peter Freyther
5ef1234dd3 [mgcp] Reset the the address when freeing the endp as well 2010-04-06 11:12:22 +02:00
Holger Hans Peter Freyther
581e58d166 Revert "nat: Remember where the BTS is listening for things."
Remove the code to parse port as we need to discover the
BTS behind the nat and most likely it will have a different
port than the one advertised by the BTS.

This reverts commit c6a1fe773d.
2010-04-06 11:06:11 +02:00
Holger Hans Peter Freyther
e308bb466a nat: Print the unknown byte as a integer instead of charachter
The value might be a non printable one.
2010-04-06 10:25:40 +02:00
Holger Hans Peter Freyther
e4be5394ef bsc_msc.c: Print the error message of the connection. 2010-04-06 10:25:00 +02:00
Holger Hans Peter Freyther
81e1edd3e6 nat: Patch IT messages as well..
We need to patch the source/dest reference inside the messages
as well otherwise we will see failures in the SCCP connection
on long calls.
2010-04-06 10:22:34 +02:00
Holger Hans Peter Freyther
cfd1c28604 nat: Test forwarding Inactivity Test messages.
No change needed to the code.
2010-04-06 10:22:01 +02:00
Holger Hans Peter Freyther
3ba8963a1d nat: Close all endpoints used by a BSC when the BSC is gone
Cleanup all endpoints that belonged to a given BSC. This is
one part of the cleanup, the other is to bring down the SCCP
link properly.
2010-04-05 23:09:27 +02:00
Holger Hans Peter Freyther
238d156481 nat: Remember a pending delete on an endpoint and carry it out later 2010-04-05 22:56:49 +02:00
Holger Hans Peter Freyther
516c4f073a [mgcp] Fix navigation in the vty hierachy (make exit work)
Make exit from the MGCP node work properly.
2010-04-05 22:42:18 +02:00
Holger Hans Peter Freyther
fa22aa6bbd nat: Fix navigation inside the config structure (fix exit)
Make sure exit in nat and nat/bsc is working and we go one
level up.
2010-04-05 22:40:49 +02:00
Holger Hans Peter Freyther
4072ceed32 nat: remove is called on already patched connections..
Fix the test to search for the original message instead
of the already patched one that should not find any items
anyway.

The remove is called on already patched connections so we
need to match it with the patch reference count.
2010-04-05 21:44:51 +02:00
Holger Hans Peter Freyther
cf6bf63a0d bsc_msc_ip: Use the force_free method to free the SCCP connection
Before the connection was not properly removed from the list of
connections and our connection list contained a dangling pointer.
2010-04-05 18:15:19 +02:00
Holger Hans Peter Freyther
88b614110f [sccp] Add a force_free method for connections
E.g. when the underlying connection transport medium is gone
one needs to force to close SCCP connections, add this helper.

It will remove the connection from the list of connections and
it will free the data.
2010-04-05 18:15:12 +02:00
Holger Hans Peter Freyther
d9b825a5f5 nat: Print the SCCP ref's as hex numbers
This allows to more easily compare the numbers with traces
seen in wireshark.
2010-04-05 18:03:39 +02:00
Holger Hans Peter Freyther
b91e5f1da4 nat: Avoid crashing when we have no pending transaction 2010-04-05 18:00:05 +02:00
Holger Hans Peter Freyther
07bb509434 nat: Logging improvement for the nat.
Print some more information, e.g. when a BSC is connected
and authenticated, print the SCCP ref number.
2010-04-05 17:58:52 +02:00
Holger Hans Peter Freyther
08db6ca509 [mgcp] Reduce this to a debug message...
This message can get in the way during a re-establishment
of the MSC connection while the MSCs gateway is still sending
data to us.
2010-04-05 17:57:10 +02:00
Holger Hans Peter Freyther
6446ded81c bsc_msc_ip: Verify that the sccp connection is present.
The SCCP might have been freed by the error case already
so we need to check this one for zero.
2010-04-05 17:16:30 +02:00
Holger Hans Peter Freyther
7b8f6064d6 nat: Print the MSC multiplex as well 2010-04-05 10:10:33 +02:00
Holger Hans Peter Freyther
c6a1fe773d nat: Remember where the BTS is listening for things.
Extract the port from the BSS's MGCP Gateway so we know
where to forward the data to.
2010-04-05 09:10:30 +02:00
Holger Hans Peter Freyther
729d468fdf nat: No need to match \r\n when parsing the C: N 2010-04-05 09:07:39 +02:00
Holger Hans Peter Freyther
b37ce4c5a4 [mgcp] Use a different port to more easily differentiate 2010-04-05 09:01:28 +02:00
Holger Hans Peter Freyther
5cd62c0ba5 [mgcp] Print the BTS IP addr of the endpoint. 2010-04-05 09:00:53 +02:00
Holger Hans Peter Freyther
1e1acafafd nat: Remove the broken empty line check, follow \n vs \r\n of input
Instead of checking the token for NULL we need to check if running
was set to null. Look at the data of the token and check if the line
was ending with a \r\n or \n and then when rewriting a line use that
line ending as well. Add a new test for that.
2010-04-04 19:40:25 +02:00
Holger Hans Peter Freyther
fb83b7a86d [mgcp] Start to look into the MGCP messages and extract the CI
we will need the call identifier for the MDCX and DLCX message
for now we were just assuming it would increment, use som python
to extract the CI from a possible response, also switch back to
a blocking read to test the BSC nat.
2010-04-04 18:39:56 +02:00
Holger Hans Peter Freyther
ef0b641f63 [ipa] When including MGCP our messages might be bigger than 300 byte
The length field of the IPA header allows to have 16bit numbers
and I just ran into the 300 byte limit with MGCP messages. Make it
three times the size and see how long this is going to be enough.
2010-04-04 18:12:37 +02:00
Holger Hans Peter Freyther
27e0bfd3c7 nat: Use a ptr that was allocated by talloc
The endp is part of an array allocated by talloc and simple
array members do not qualify as a context start address.
2010-04-04 18:11:49 +02:00
Holger Hans Peter Freyther
bbfff6ec39 nat: Make rewrite work on string, read to a string first, copy to msgb
The MGCP protocol parsing is adding '\0' to make sure we do not
parse beyond where we should parse. This does not mix with strtok
or similiar routines.
For now we will read the msg into a global array first, then copy
it to the msgb for mgcp protocol handling and if we are required
to forward it to the MGCP we have a untouched copy we will modify
into our own msgb.
2010-04-04 18:09:10 +02:00
Holger Hans Peter Freyther
dc0914df09 [mgcp] Set the right variable to NULL otherwise we get a double free 2010-04-04 17:58:26 +02:00
Holger Hans Peter Freyther
0db691dcf6 [mgcp] Fix the transaction id of the AUEP request 2010-04-04 16:37:21 +02:00
Holger Hans Peter Freyther
bb45b73b20 bsc_msc_ip.c: Fix crash for the hexdump during writing..
we need to set the msgb l2h to the right position otherwise
when trying to dump it we will have a nice crash.
2010-04-04 16:30:39 +02:00
Holger Hans Peter Freyther
5f5c1b6bcb bsc_msc_ip.c: Fix the reading of data...
len contains the actual length of the message and data_len
contains the size of the message. We want to read up to
data_len and not up to 0 bytes.
2010-04-04 16:29:44 +02:00
Holger Hans Peter Freyther
e51cf4f946 bsc_msc_ip.c: Use another kernel feature to bind to a random port 2010-04-04 15:53:38 +02:00
Holger Hans Peter Freyther
749ba7f5ad bsc_msc_ip.c: Use strerror to print the errno variable. 2010-04-04 15:44:53 +02:00
Holger Hans Peter Freyther
860c8955c3 Revert "bsc_msc_ip: Use the autobind functionality of the kernel"
The autobind is not working as I wanted it to work. So we will
revert this for now and then try something else.

This reverts commit fd876b7488.
2010-04-04 15:24:11 +02:00
Holger Hans Peter Freyther
c33701c4e5 nat: Check the authentication bit later...
When moving it up here the code started to reject
the identity responses of the bsc and we would
never authenticate. Move it back down.
2010-04-02 03:47:09 +02:00
Holger Hans Peter Freyther
44d92b4728 bsc_msc_ip.c: Return after having freed the msgb
When reading MGCP is failing (e.g. because the udp socket
is not connected yet) we would have freed the msgb but we
didn't return and then executed msgb_put on a dead buffer.
2010-04-02 03:28:30 +02:00
Holger Hans Peter Freyther
8aaec620da nat: Return MGCP messages to the call agent
Attempt to find the message by transaction id, then patch
the response and use the IP/PORT of the local network, update
the ci with the one from the BSC.

This is currently not tracking any state of the MGCP and will
not handle two bsc's... this will need to happen later.

With this in we should be feature complete and now enter the
mode of making all of this work reliable and fixing thinko's
and other bugs.
2010-04-01 10:16:28 +02:00
Holger Hans Peter Freyther
a5a4014d67 nat: Allow to send MGCP messages from the BSC to the network 2010-04-01 08:47:12 +02:00
Holger Hans Peter Freyther
9d519189ae nat: Handle CRCX/MDCX/DLCX at the nat
* Forward a rewritten msg to the BSS. We change the IP and port
  to point to the NAT instead of the core network. We also keep
  track of the BSC and the transacition id.
* Handle the case where we have not found a SCCP connection and
  need to send a response ourselves.
2010-04-01 08:21:33 +02:00
Holger Hans Peter Freyther
f0fc618782 [mgcp] Look at the bts addr set at the endpoint
This will allow to discover the ports of a bts when we only know
the addr and have multiple bts's to handle.
2010-04-01 07:56:04 +02:00
Holger Hans Peter Freyther
c57575bea8 nat: Test rewriting of MGCP messages to patch ip and port
Add code to change the ip and port for audio data inside
MGCP messages. This is needed because the BSS might be
behind the NAT and can not reach the network directly and
might be behind a nat so the announced sourceport is not
the one as we see it.
2010-04-01 07:41:23 +02:00
Holger Hans Peter Freyther
8cdfe9fc37 nat: Add code to find a BSC connection by the given msc multiplex 2010-04-01 07:41:23 +02:00
Holger Hans Peter Freyther
0959f8cbe6 [mgcp] Export header parsing via mgcp internal
This will be used by the NAT code to implement custom protocol
handling on top of that.
2010-04-01 07:41:23 +02:00
Holger Hans Peter Freyther
f21028985e [mgcp] Do not operate on the ->data pointer, use ->l2h instead
This would have been broken once we attempt to parse encapsulated
MGCP messages.
2010-03-31 13:26:46 +02:00
Holger Hans Peter Freyther
483b768ab2 bsc-msc: Flush the write queue when we have lost the connection 2010-03-31 13:15:26 +02:00
Holger Hans Peter Freyther
82cb311c4f nat: First go at handling MGCP inside the nat
Listen on the MGCP gateway port and let our protocol stack
handle everything for now. We will need to have some more
control over things though.
2010-03-31 13:15:19 +02:00
Holger Hans Peter Freyther
2980442e33 [mgcp] Degrade verbosity to debug 2010-03-31 12:31:09 +02:00
Holger Hans Peter Freyther
fa7afb31e9 nat: Add an example configuration for the BSC NAT with MGCP 2010-03-31 11:53:36 +02:00
Holger Hans Peter Freyther
7513b3a1c2 [mgcp] Add a new config option to set the call agent ip addr
In the case of the nat we only want to communicate with one
upstream call agent and this can now be configured.
2010-03-31 11:46:41 +02:00
Holger Hans Peter Freyther
135d99b36e [mgcp] Regroup struct mgcp_cfg members and provide some hints 2010-03-31 11:35:20 +02:00
Holger Hans Peter Freyther
5aaf7c164c [mgcp] Add a helper function to convert from GSM0808 ts/mux to MGCP endpoint
Move the conversion of GSM0808 timeslot and multiplex from
the bssap.c into the mgcp.h so it can be reused by multiple
users. The weird math comes from the mapping of the MSC...
2010-03-31 09:27:04 +02:00
Holger Hans Peter Freyther
790db1e01b nat: In the case of losing the MSC, reset all endpoints
When losing the SCCP connection make sure that we free all
endpoints. The disconnection of the BSC should already make
sure they are closed but this makes sure everything is
properly reset.
2010-03-31 09:16:56 +02:00
Holger Hans Peter Freyther
81a8975662 nat: bsc_mgcp_clear is called from within the remove function
No need to call it twice... All endpoints should be properly
freed as part of the SCCP disconnection.
2010-03-31 09:15:05 +02:00
Holger Hans Peter Freyther
fd876b7488 bsc_msc_ip: Use the autobind functionality of the kernel
We do not care about the source port for the callagent relay
and can use the autobind functionality of the kernel to pick
a port for us...
2010-03-31 08:41:52 +02:00
Holger Hans Peter Freyther
2ffe7aa340 bsc_msc_ip: Create a local UDP socket and relay MGCP messages
Attempt to bind to the local callagent port and send messages
from the MSC TCP connection to the MGCP and do it the otherway
around as well.
2010-03-31 08:39:53 +02:00
Holger Hans Peter Freyther
538ea6d5c6 [nat] Send a RSIP down to the BSC after it connects
Make sure the MGCP attached to the BSC is resetting all
endpoints whenever the BSC is connecting to us as we assume
that all endpoints are available.
2010-03-31 07:30:58 +02:00
Holger Hans Peter Freyther
e14ec0dab4 [mgcp] Handle the RSIP with resetting all endpoints
We could change that the message came from a special ip
address/port to secure this service in general but we don't
do that right now.
2010-03-31 07:01:35 +02:00
Holger Hans Peter Freyther
8252b9b947 [mgcp] Add some parsing for RSIP messages coming in
This will just call a callback and leave all the handling
to the application.
2010-03-31 06:39:35 +02:00
Holger Hans Peter Freyther
9fb88021dd [mgcp] Remove unused method from the mgcp
This was removed when sending the RSIP was
removed from the code.
2010-03-31 06:26:44 +02:00
Holger Hans Peter Freyther
b031d6ecae [mgcp] Switch from DEBUG to LOGP in the mgcp_main.c 2010-03-31 06:16:45 +02:00
Holger Hans Peter Freyther
fcfdde5390 [mgcp] Remove the sending of RSIP
This message is ignored by the call agent and we were
sending this on the first request which we maybe should
not ignore...
2010-03-30 15:41:03 +02:00
Holger Hans Peter Freyther
571ba8e4da nat: Add MGCP code and parsing to the nat code..
For the nat we will have NAT and MGCP in the same process
and this commit starts with that. We are linking in the MGCP
code and one can embed MGCP config snippets...
2010-03-30 13:08:32 +02:00
Holger Hans Peter Freyther
bed6234e26 [mgcp] The networking code needs a source addrs..
Make the source address mandantory and complain about
complain when it is missing. The address is mandantory
as it needs to be put into the MGCP messages...
2010-03-30 13:00:40 +02:00
Holger Hans Peter Freyther
9d24578812 [mgcp] Move mgcp init into the main method... 2010-03-30 12:43:53 +02:00
Holger Hans Peter Freyther
a087c4e75d [mgcp] Fix format string usage 2010-03-30 12:43:33 +02:00
Holger Hans Peter Freyther
6b64b26d8b nat: Look at the assignment command and remember on which timeslot the data is
This information will be needed when we are trying to forward
MGCP connections to and from the BSC through the IPA protocol.
2010-03-30 12:01:24 +02:00
Holger Hans Peter Freyther
22252a98e3 sccp: Move the destruction of the sccp connection to a new place 2010-03-30 10:45:48 +02:00
Holger Hans Peter Freyther
957bc93244 nat: Return the SCCP connection, change order of patching and updating
* Return the SCCP connection. This will be needed to store the
  assigned timeslot in there.
* Update code to work with this change
* This uncovered a bug in the CC handling, at the time the BSC was
  passed it was still a null pointer and the code would have failed.
2010-03-30 09:17:53 +02:00
Holger Hans Peter Freyther
18bbe2e8a0 misc: Do not prepend 0x when using %p in printf. 2010-03-30 08:41:17 +02:00
Holger Hans Peter Freyther
1b17913cbc nat: Fail more early in the case of not being authenticated
This is also fixing a possible memory leak.
2010-03-30 07:45:52 +02:00
Holger Hans Peter Freyther
ce2a36840d nat: Add test case and data for paging by lac test. 2010-03-30 06:51:53 +02:00
Holger Hans Peter Freyther
0e09feccb0 nat: Some more input validation... on the paging command. 2010-03-30 06:51:23 +02:00
Holger Hans Peter Freyther
40a1de699a nat: Documentation fix... use nat for the parameter 2010-03-30 06:39:37 +02:00
Holger Hans Peter Freyther
d906a366c8 nat: Verify that the configured LACs are unique across the nat 2010-03-30 06:08:56 +02:00
Holger Hans Peter Freyther
d44d4c8c8b nat: Move paging by lac handling code into the utils file
Moving it here means we can more easily test this code, there is one
behaviour change with the code that we only support paging messages
with one LAC and will silently ignore the others.
2010-03-30 05:57:42 +02:00
Holger Hans Peter Freyther
af0e1d7a85 nat: Add a test case for the connection tracking
This test case tests connectiont tracking by sending
a CR, getting a CC, sending a DTAP, receiving a DTAP,
receiving a RLSD, sending a RLC. It verifies that the
messages are properly patched specially the references
at the BSC.
2010-03-30 02:43:11 +02:00
Holger Hans Peter Freyther
d21b4d7f98 nat: Fix the lookup of connections to and from the BSC
When sending a message to the MSC in the case of DT1
messages we only have the address of the MSC, so we
need to go with that, otherwise (e.g. in case of a CR, RLC)
we do have the source address and need to patch it.

When forwarding a message to the BSC we do receive
a msg that should contain the patched address, we need
to unpatch it...
2010-03-29 17:43:32 +02:00
Holger Hans Peter Freyther
3bdaa69fb2 nat: Keep track of both sides of the connection
On a CC message we will need to remeber where the source local
reference of the network belonged so we can properly identify
the connection when receiving UDT messages.
2010-03-29 17:43:32 +02:00
Holger Hans Peter Freyther
5c0132882a nat: Assign the connection inside the new helper function. 2010-03-29 15:14:15 +02:00
Holger Hans Peter Freyther
ed443e949e nat: Actually add the connection to the SCCP list of active connections
Add the connection to the list of active connections. Otherwise
we are not able to find the connection.
2010-03-29 15:03:54 +02:00
Holger Hans Peter Freyther
1df69f3c64 filter: Move logging level down to INFO 2010-03-29 14:59:59 +02:00
Holger Hans Peter Freyther
d7cafafeee debug: Fix debugging for the nat category. 2010-03-29 14:59:21 +02:00
Holger Hans Peter Freyther
e09348d366 nat: Compare the IPA size with the actual size of the data...
One sanity check that was needed in my test case..
2010-03-29 14:58:43 +02:00
Holger Hans Peter Freyther
5f1b7c14f5 nat: Move creation of the structs to a separate file
This way one can create the bsc_nat structure in unit tests..
2010-03-29 12:48:36 +02:00
Holger Hans Peter Freyther
5b3e9198f0 nat: Move SCCP patching to a new file, log updates
Move patching and reassigning of messages to a new file which
will making testing this functionality more easy.
2010-03-29 11:04:52 +02:00
Holger Hans Peter Freyther
f0b21dfd25 bsc_msc: Handle the loss of the MSC connection better
Instead of simply exiting the application we will handle it by
giving up all SCCP connections, once we have the MSC back we will
send a GSM 08.08 reset message, and we will free all resources
related to these connections. This includes the primary and secondary
lchan of these connections.

While we are not connected to the MSC we will handle each message
that would open a SCCP connection by giving up the lchan. This has
only been compile tested and will need to be manually tested during
a test session.

This also highlights a DoS that could be used against OpenBSC
by setting up a lchan but never send any GSM L3 message. We will have
to fix that at some point.
2010-03-29 10:09:27 +02:00
Holger Hans Peter Freyther
e165d1aaa4 [misc] Clean some whitespace in files of this branch. 2010-03-29 08:10:48 +02:00
Holger Hans Peter Freyther
649496eb57 nat: Handle MSC disconnect by closing all NAT connections
When we disconnect from the MSC handle it by pushing the problem
to our connected clients. We will simply close all connections,
reject all new BSC connections and attempt to reconnect to the MSC.
2010-03-29 08:09:29 +02:00
Holger Hans Peter Freyther
135a45c833 msc: Create a real interface for BSC MSC and start handling reconnects
Create a BSC<->MSC interface and use it for the BSC MSC IP and the
BSC NAT to reduce code duplication on handling reconnects to the MSC
and cleaning up the local state. The code is only partially tested
and will contain bugs. Currently both the BSC and the NAT will just
exit on connection loss and this way have the current behavior.
2010-03-26 12:14:37 +01:00
Holger Hans Peter Freyther
1a3d9dbabf bsc_msc: Connect in a non blocking way to the MSC
The latency of setting up of the TCP connection can be quite high,
it is better to connect in a non blocking way. This code is working
by setting the socket nonblocking and temporarily replacing the
bfd callback with the connect handling.
Once the OS has connected our socket we switch back to normal operation.
2010-03-26 10:41:20 +01:00
Holger Hans Peter Freyther
a91d15df7e bsc_msc_ip: Keep track of active connections so we could clear them.
Keep track of SCCP connections so we can clear them
when the MSC is going down.
2010-03-26 09:58:40 +01:00
Holger Hans Peter Freyther
3368e2a3d1 nat: Add a warning for an important todo item on connection loss
In case we disconnect with some pending operations we will need to
signal the MSC that something is wrong. This could be by sending a
RLSD directly, or a clear command. Another part of the fix is to
respond with a RLC on unknown RLSD messages.
2010-03-26 09:28:40 +01:00
Holger Hans Peter Freyther
929d788e21 nat: Clear all pending messages in case the BSC disconnected
Throw away all messages we have scheduled but never delivered
to the BSC.
2010-03-26 09:27:08 +01:00
Holger Hans Peter Freyther
6958065f85 nat: Switch downstream over to the write queue 2010-03-26 09:18:02 +01:00
Holger Hans Peter Freyther
097c82b2bc nat: Stop using the input/ipaccess.c method as it will write directly
We want to write everything through the write queue, it seemed the
easiest to copy the bytes here and feed the data into the bsc_write
method.
2010-03-26 07:41:54 +01:00
Holger Hans Peter Freyther
abaeb3f55f nat: Make it clear where we want to send these methods 2010-03-26 07:26:18 +01:00
Holger Hans Peter Freyther
f42e29c79c nat: Move one more area to the bsc_write method 2010-03-26 07:24:34 +01:00
Holger Hans Peter Freyther
3177580cc1 nat: Move BSC msg sending to a new method.
Move all writes into one place so we can switch to the
write queue more easily in the future.
2010-03-26 07:20:59 +01:00
Holger Hans Peter Freyther
cbe77e1657 nat: Start using a write_queue for the BSC connection
We are still writing to the BSC directly and don't make real
use of this feature right now but we will need to do it.
2010-03-26 07:10:22 +01:00
Holger Hans Peter Freyther
3cedc4738f nat: Move MSC write to the write_queue and make it non blocking
Move the MSC code to a non blocking write.
2010-03-26 07:01:28 +01:00
Holger Hans Peter Freyther
0834fd9b85 nat: Rename variable from connection to listen
This is the socket we listen for incoming BSCs.
2010-03-26 06:51:04 +01:00
Holger Hans Peter Freyther
7b65c986eb bsc_msc_ip: Convert the MSC connection to the write queue
The SCCP stack was changed to give the ownership of the msgb
to the system integration, this allows us to use the stock write
queue to queue the write and write the msg to the MSC once we
are connected again.
2010-03-26 06:41:54 +01:00
Holger Hans Peter Freyther
17d751531e Merge branch 'on-waves/sccp' into on-waves/bsc-master 2010-03-26 05:49:34 +01:00
Holger Hans Peter Freyther
facb5cdfc2 channel requests: Add configuration to handle paging any with TCH
It is possible that the MSC is not sending the channel type it
needs for the operations it wants to do. Add a configuration option
to assign a TCH in case of paging any requests. It can be a good
idea to leave SDCCHs free for location updating requests.
2010-03-25 05:15:09 +01:00
Holger Hans Peter Freyther
aebea482f5 channel request: Store the to be assigned channel type in the GSM Network
Store the mapping from request to channel type in the GSM Network
struct as there is some policy involved with handling the request.

E.g. in a half rate network we don't want emergy calls to be getting
a TCH/F, or we want to have a different policy for early/late assignment
of phone calls.

Update the table when creating the network and when the neci is changed.
2010-03-25 04:58:08 +01:00
Holger Hans Peter Freyther
12f20d369c bsc_msc_ip: Add an option for the global log level 2010-03-25 03:01:24 +01:00
Holger Hans Peter Freyther
2008d3f54c Merge remote branch 'origin/master' into on-waves/bsc-master 2010-03-25 02:58:57 +01:00
Holger Hans Peter Freyther
a26ebe40f5 bssap: Allow to submit a SMS on the TCH
Similar to the bsc_rll.c code we need to indicate if we want to
send the data on the SACH or on the normal signalling link. For
CC and any other SAPI=0 usage this bits must be zero, whener we
try to do something with SMS this bit needs to be set to one.
2010-03-24 14:21:03 +01:00
Holger Hans Peter Freyther
a52f1cacb3 Merge remote branch 'origin/master' into on-waves/bsc-master 2010-03-24 14:16:16 +01:00
Holger Hans Peter Freyther
f5e71415a2 Merge remote branch 'origin/master' into on-waves/bsc-master 2010-03-24 11:23:01 +01:00
Holger Hans Peter Freyther
82a8d6e393 Specify a release reason for the lchan
In case the put_lchan is making the refcount drop to zero use the
release reason specified in the put_lchan call. This is used by the
BSC MSC IP implementation for the assignment handling where the old
channel is getting closed with a local end release (1).
2010-03-24 10:45:07 +01:00
Holger Hans Peter Freyther
1226c93937 Fix DNAT debug.h definition and move it to the enum. 2010-03-24 10:30:37 +01:00
Holger Hans Peter Freyther
b9c520f9b3 Merge remote branch 'origin/master' into on-waves/bsc-master
Keep a static version as the shell script is not dealing well
with branch tags/names containing text.

Resolve merge conflict in the Makefile.am by adding both sides
to the list of sources for the libbsc.a

Conflicts:
	openbsc/configure.in
	openbsc/src/Makefile.am
2010-03-24 10:28:43 +01:00
Holger Hans Peter Freyther
8a7ca57d3e bssap.c: Handle an assignment failure correctly
This method should return !0 in case of an failure so
we can send an assignment reject right away.
2010-03-24 10:27:04 +01:00
Holger Hans Peter Freyther
29f9f9fc79 Bump the local version to 0.3.90 in preparation for a 0.4.0 release 2010-03-24 10:13:23 +01:00
Holger Hans Peter Freyther
d512e454b3 Correct the company name. It should be On-Waves (ehf) 2010-03-24 06:16:24 +01:00
Holger Hans Peter Freyther
22481bf76d Merge remote branch 'origin/master' into on-waves/bsc-master
* Move to libosmocore
* Move to new debugging architecture
* Register the BTS types
* Has only been compile tested

Conflicts:
	openbsc/include/openbsc/Makefile.am
	openbsc/include/openbsc/gsm_data.h
	openbsc/include/openbsc/ipaccess.h
	openbsc/include/openbsc/mgcp.h
	openbsc/include/openbsc/msgb.h
	openbsc/include/openbsc/tlv.h
	openbsc/src/Makefile.am
	openbsc/src/abis_rsl.c
	openbsc/src/bsc_init.c
	openbsc/src/bsc_mgcp.c
	openbsc/src/chan_alloc.c
	openbsc/src/debug.c
	openbsc/src/gsm_subscriber_base.c
	openbsc/src/msgb.c
	openbsc/src/rest_octets.c
	openbsc/src/sccp/sccp.c
	openbsc/src/vty/command.c
	openbsc/src/vty_interface.c
	openbsc/tests/Makefile.am
2010-03-24 06:16:04 +01:00
Holger Hans Peter Freyther
b973955295 [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-13 01:37:36 +01:00
Holger Hans Peter Freyther
9d51a36528 [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-13 00:42:21 +01:00
Holger Hans Peter Freyther
ba3bbe55c1 [nat] Add configuration file for the bsc nat. 2010-02-12 22:26:45 +01:00
Holger Hans Peter Freyther
0619478073 [nat] Intercept the PAGING message and then forward it to the BSCs with that LAC
* Provide access to the GSM0808 TLV attributes so we can use it in
  the nat code.
* Read the PAGING message, if it is paged by LAC we go through each
  LAC and then attempt to find the proper BSC connection and then
  send the message to that BSC.
2010-02-09 17:35:09 +01:00
Holger Hans Peter Freyther
f8f184edab [nat] Fix compiler warning.. 2010-02-09 16:30:53 +01:00
Holger Hans Peter Freyther
d838951302 [nat] Implement token based identification.
Based on the token the NAT/MUX is capable of figuring out
which LAC this BSC is supposed to satisfy. This will be
needed for messages like paging that can be done by LAC.
2010-02-09 16:30:38 +01:00
Holger Hans Peter Freyther
f8e1b45a78 [tlv] Implement a variant for the IDTAG list for the IPA
Implement a helper that will allow to easily fill the
tag list with data.
2010-02-09 16:26:49 +01:00
Holger Hans Peter Freyther
dd2c9fdbcf [bsc] Allow to set a EGSM900, RGSM900 ARFCN
For R-GSM900 the channels 955-1023 are within the 900er band. The
System Information Type generation can not cope with these channels yet.
2010-02-09 15:44:14 +01:00
Holger Hans Peter Freyther
9991421cfb [ipaccess] Make the IPA version of LTV public. 2010-02-09 14:37:23 +01:00
Holger Hans Peter Freyther
e30f0e1c75 [nat] Do not forward messages from and to BSC when it is not authenticated
* Start using the authenticated bit in the BSC connection. This means
  that currently no messages are forwarded to the MSC from unauthenticated
  BSCs.
2010-02-08 23:24:32 +01:00
Holger Hans Peter Freyther
18598ff66d [nat] Use default handler for SIGINT to quit the app 2010-02-08 23:23:54 +01:00
Holger Hans Peter Freyther
8882c9e3a8 Merge commit 'on-waves/0.3.1' into on-waves/bsc-master 2010-02-08 20:20:27 +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
16b331d14f Merge commit 'on-waves/0.3' into on-waves/bsc-master 2010-02-08 15:46:17 +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
be807e4250 [nat] Add VTY support to the BSC nat application
* Create struct bsc_nat and move the various lists into this structure
* Create the VTY code
* Call the VTY init and parsing code
* Create functions to create the types..
* Add some stuff into the bsc_connection to be used for the NAT with
  proper config files. E.g. to close the connection if the BSC does not
  respond to a given command.
2010-02-08 13:44:48 +01:00
Holger Hans Peter Freyther
71ddbf5c4f [telnet] Remove ancient #define... 2010-02-07 13:16:03 +01:00
Holger Hans Peter Freyther
63bb29fac0 [nat] Move the structs to the header file
This way the VTY code can use the structures to implement
the show functionality.
2010-02-07 13:08:09 +01:00
Holger Hans Peter Freyther
04b4f915a7 [ipa] Make sending of ID REQ public...
Make sending of the ID Request message public. We are going
to use this in the BSC NAT code to ask for querying the BSC.
2010-02-07 12:04:07 +01:00
Holger Hans Peter Freyther
4d95ab2231 [vty] Add a config for a simple OpenBSC BSC token
We will use this token to identify us at the MSC for
now. This assumes that something like OpenVPN is already
used to secure the networking. In the future we will
explore using TLS for the communication and certificates
for the authentication.
2010-02-07 11:45:55 +01:00
Holger Hans Peter Freyther
17944f7285 [nat] Add missing Makefile.am.. 2010-02-04 19:24:43 +01:00
Holger Hans Peter Freyther
d2964b6cd1 [nat] Make some methods static. 2010-01-31 13:52:32 +01:00
Holger Hans Peter Freyther
1ce5d7c8b7 [nat] Begin to patch SCCP connections
For the one MSC and n BSC case we need to patch the SCCP source
local reference on connection orientated links to avoid a clash.

For simple UDT packages we just let them pass and for SCCP connection
we have to:
    1.) Create an entry on Connection Request
    2.) Patch the entry on Connection Confirm, Connection Refuse,
        Connection Release, DT1, Connect Release Complete
    3.) Remove the entry on Connection Release Complete

The current code is blocking CRs, Release Complete from the MSC, and
creates the connection state only from the BSC side. The code to
assign a source reference is taken from sccp.c and handles wrap
arounds and such properly. We rely on the SCCP parser to fill out the
place to the source reference correctly so we can easily fix it.

The whole code is young and might contain bugs we need to resolve..
2010-01-31 09:46:21 +01:00
Holger Hans Peter Freyther
846457b10a [nat] Send a GSM 08.08 Reset Ack to the BSC...
When the reset was filtered out to the MSC we will respond
with a GSM08.08 reset ack right away. We are using a static
acknowledge here.
2010-01-30 12:45:10 +01:00
Holger Hans Peter Freyther
e7b9771c4d [nat] Specify the direction of the message
Do not run into the situation where we need to filter in one
direction but it should not be filtered..
2010-01-30 11:53:30 +01:00
Holger Hans Peter Freyther
d709900efa [sccp] Slightly improve the log message 2010-01-30 10:34:18 +01:00
Holger Hans Peter Freyther
55b4f5cc2e [nat] Prepare more sophisicated filtering and patching
Introduce a bsc_nat_parse method to parse a IP Access method
into various parts. Write out the IPA Proto, in case SCCP is used,
store the msg type, pointers to the source/dest local reference and
other information.

Use the result of bsc_nat_parse inside the bsc_nat_filter method
to decide if the message should be dropped or not.

In the future the bsc_nat_parse result will be used for patching
SCCP references and other parts of the message.

The filter language should be able to filter the msg type of SCCP
messages and gain the "NOT" word in the filter language.
2010-01-30 10:33:07 +01:00
Holger Hans Peter Freyther
1ac5ac75a9 [nat] Make use of the LOGP macro in the code base. 2010-01-29 05:58:43 +01:00
Holger Hans Peter Freyther
5cf38ed1ab [nat] Add debug area for the NAT code
This is going to give a conflict when merging with master but
it can be easily resolved by adding a new id then.
2010-01-29 05:49:06 +01:00
Holger Hans Peter Freyther
35d1531089 [sccp] Implement sccp_parse_header to be used by the NAT code. 2010-01-29 04:31:51 +01:00
Holger Hans Peter Freyther
47e3777caa [sccp] Split Connection DT1 into two parts
This is the last of supported messages to be split into a parse
and handle routine. Now all parse routines can be used by the NAT.
2010-01-29 04:31:00 +01:00
Holger Hans Peter Freyther
710f3c615c [sccp] Split Connection Release Complete into two parts 2010-01-29 04:19:56 +01:00
Holger Hans Peter Freyther
3111560e8a [sccp] Split Connection Confirm handling into two parts 2010-01-29 04:03:00 +01:00
Holger Hans Peter Freyther
7396afbba4 [sccp] Split Connection Refused into two parts 2010-01-29 03:58:12 +01:00
Holger Hans Peter Freyther
52a72e217e [sccp] Split Connection Released into two parts
Split the Connection Released into header parsing and into
acting on the parsed result. This is part of the NAT work.
2010-01-29 03:49:32 +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
258 changed files with 32659 additions and 20313 deletions

25
libosmocore/.gitignore vendored Normal file
View File

@@ -0,0 +1,25 @@
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
.tarball-version
.version

339
libosmocore/COPYING Normal file
View File

@@ -0,0 +1,339 @@
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.

14
libosmocore/Makefile.am Normal file
View File

@@ -0,0 +1,14 @@
AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
ACLOCAL_AMFLAGS = -I m4
INCLUDES = $(all_includes) -I$(top_srcdir)/include
SUBDIRS = include src tests
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libosmocore.pc
BUILT_SOURCES = $(top_srcdir)/.version
$(top_srcdir)/.version:
echo $(VERSION) > $@-t && mv $@-t $@
dist-hook:
echo $(VERSION) > $(distdir)/.tarball-version

56
libosmocore/configure.in Normal file
View File

@@ -0,0 +1,56 @@
AC_INIT([libosmocore],
m4_esyscmd([./git-version-gen .tarball-version]),
[openbsc-devel@lists.openbsc.org])
AM_INIT_AUTOMAKE([dist-bzip2])
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
LT_INIT
AC_PROG_LIBTOOL
AC_CONFIG_MACRO_DIR([m4])
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)

151
libosmocore/git-version-gen Executable file
View File

@@ -0,0 +1,151 @@
#!/bin/sh
# Print a version string.
scriptversion=2010-01-28.01
# Copyright (C) 2007-2010 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This script is derived from GIT-VERSION-GEN from GIT: http://git.or.cz/.
# It may be run two ways:
# - from a git repository in which the "git describe" command below
# produces useful output (thus requiring at least one signed tag)
# - from a non-git-repo directory containing a .tarball-version file, which
# presumes this script is invoked like "./git-version-gen .tarball-version".
# In order to use intra-version strings in your project, you will need two
# separate generated version string files:
#
# .tarball-version - present only in a distribution tarball, and not in
# a checked-out repository. Created with contents that were learned at
# the last time autoconf was run, and used by git-version-gen. Must not
# be present in either $(srcdir) or $(builddir) for git-version-gen to
# give accurate answers during normal development with a checked out tree,
# but must be present in a tarball when there is no version control system.
# Therefore, it cannot be used in any dependencies. GNUmakefile has
# hooks to force a reconfigure at distribution time to get the value
# correct, without penalizing normal development with extra reconfigures.
#
# .version - present in a checked-out repository and in a distribution
# tarball. Usable in dependencies, particularly for files that don't
# want to depend on config.h but do want to track version changes.
# Delete this file prior to any autoconf run where you want to rebuild
# files to pick up a version string change; and leave it stale to
# minimize rebuild time after unrelated changes to configure sources.
#
# It is probably wise to add these two files to .gitignore, so that you
# don't accidentally commit either generated file.
#
# Use the following line in your configure.ac, so that $(VERSION) will
# automatically be up-to-date each time configure is run (and note that
# since configure.ac no longer includes a version string, Makefile rules
# should not depend on configure.ac for version updates).
#
# AC_INIT([GNU project],
# m4_esyscmd([build-aux/git-version-gen .tarball-version]),
# [bug-project@example])
#
# Then use the following lines in your Makefile.am, so that .version
# will be present for dependencies, and so that .tarball-version will
# exist in distribution tarballs.
#
# BUILT_SOURCES = $(top_srcdir)/.version
# $(top_srcdir)/.version:
# echo $(VERSION) > $@-t && mv $@-t $@
# dist-hook:
# echo $(VERSION) > $(distdir)/.tarball-version
case $# in
1) ;;
*) echo 1>&2 "Usage: $0 \$srcdir/.tarball-version"; exit 1;;
esac
tarball_version_file=$1
nl='
'
# First see if there is a tarball-only version file.
# then try "git describe", then default.
if test -f $tarball_version_file
then
v=`cat $tarball_version_file` || exit 1
case $v in
*$nl*) v= ;; # reject multi-line output
[0-9]*) ;;
*) v= ;;
esac
test -z "$v" \
&& echo "$0: WARNING: $tarball_version_file seems to be damaged" 1>&2
fi
if test -n "$v"
then
: # use $v
elif
v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \
|| git describe --abbrev=4 HEAD 2>/dev/null` \
&& case $v in
[0-9]*) ;;
v[0-9]*) ;;
*) (exit 1) ;;
esac
then
# Is this a new git that lists number of commits since the last
# tag or the previous older version that did not?
# Newer: v6.10-77-g0f8faeb
# Older: v6.10-g0f8faeb
case $v in
*-*-*) : git describe is okay three part flavor ;;
*-*)
: git describe is older two part flavor
# Recreate the number of commits and rewrite such that the
# result is the same as if we were using the newer version
# of git describe.
vtag=`echo "$v" | sed 's/-.*//'`
numcommits=`git rev-list "$vtag"..HEAD | wc -l`
v=`echo "$v" | sed "s/\(.*\)-\(.*\)/\1-$numcommits-\2/"`;
;;
esac
# Change the first '-' to a '.', so version-comparing tools work properly.
# Remove the "g" in git describe's output string, to save a byte.
v=`echo "$v" | sed 's/-/./;s/\(.*\)-g/\1-/'`;
else
v=UNKNOWN
fi
v=`echo "$v" |sed 's/^v//'`
# Don't declare a version "dirty" merely because a time stamp has changed.
git status > /dev/null 2>&1
dirty=`sh -c 'git diff-index --name-only HEAD' 2>/dev/null` || dirty=
case "$dirty" in
'') ;;
*) # Append the suffix only if there isn't one already.
case $v in
*-dirty) ;;
*) v="$v-dirty" ;;
esac ;;
esac
# Omit the trailing newline, so that m4_esyscmd can use the result directly.
echo "$v" | tr -d '\012'
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

View File

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

View File

@@ -0,0 +1,12 @@
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 logging.h
if ENABLE_TALLOC
osmocore_HEADERS += talloc.h
endif
osmocoredir = $(includedir)/osmocore
SUBDIRS = protocol

View File

@@ -0,0 +1,65 @@
#ifndef _BITVEC_H
#define _BITVEC_H
/* bit vector utility routines */
/* (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.
*
*/
/* In GSM mac blocks, every bit can be 0 or 1, or L or H. L/H are
* defined relative to the 0x2b padding pattern */
enum bit_value {
ZERO = 0,
ONE = 1,
L = 2,
H = 3,
};
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 */
};
/* 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);
/* get the Nth set bit inside the bit vector */
unsigned int bitvec_get_nth_set_bit(const struct bitvec *bv, unsigned int n);
/* Set a bit at given position */
int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnum,
enum bit_value bit);
/* Set the next bit in the vector */
int bitvec_set_bit(struct bitvec *bv, enum bit_value bit);
/* Set multiple bits at the current position */
int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count);
/* Add an unsigned integer (of length count bits) to current position */
int bitvec_set_uint(struct bitvec *bv, unsigned int in, int count);
/* Pad the bit vector up to a certain bit position */
int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit);
#endif /* _BITVEC_H */

View File

@@ -0,0 +1,22 @@
/*
* 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

@@ -0,0 +1,17 @@
#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;
const char *gsm48_cc_state_name(uint8_t state);
const char *gsm48_cc_msg_name(uint8_t msgtype);
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

@@ -0,0 +1,107 @@
#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

@@ -0,0 +1,84 @@
/* 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

@@ -0,0 +1,72 @@
#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

@@ -0,0 +1,360 @@
#ifndef _LINUX_LLIST_H
#define _LINUX_LLIST_H
#include <stddef.h>
#ifndef inline
#define inline __inline__
#endif
static inline void prefetch(const void *x) {;}
/**
* container_of - cast a member of a structure out to the containing structure
*
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
*
*/
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (typeof( ((type *)0)->member ) *)(ptr); \
(type *)( (char *)__mptr - offsetof(type, member) );})
/*
* These are non-NULL pointers that will result in page faults
* under normal circumstances, used to verify that nobody uses
* non-initialized llist entries.
*/
#define LLIST_POISON1 ((void *) 0x00100100)
#define LLIST_POISON2 ((void *) 0x00200200)
/*
* Simple doubly linked llist implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole llists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
struct llist_head {
struct llist_head *next, *prev;
};
#define LLIST_HEAD_INIT(name) { &(name), &(name) }
#define LLIST_HEAD(name) \
struct llist_head name = LLIST_HEAD_INIT(name)
#define INIT_LLIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal llist manipulation where we know
* the prev/next entries already!
*/
static inline void __llist_add(struct llist_head *_new,
struct llist_head *prev,
struct llist_head *next)
{
next->prev = _new;
_new->next = next;
_new->prev = prev;
prev->next = _new;
}
/**
* llist_add - add a new entry
* @new: new entry to be added
* @head: llist head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void llist_add(struct llist_head *_new, struct llist_head *head)
{
__llist_add(_new, head, head->next);
}
/**
* llist_add_tail - add a new entry
* @new: new entry to be added
* @head: llist head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void llist_add_tail(struct llist_head *_new, struct llist_head *head)
{
__llist_add(_new, head->prev, head);
}
/*
* Delete a llist entry by making the prev/next entries
* point to each other.
*
* This is only for internal llist manipulation where we know
* the prev/next entries already!
*/
static inline void __llist_del(struct llist_head * prev, struct llist_head * next)
{
next->prev = prev;
prev->next = next;
}
/**
* llist_del - deletes entry from llist.
* @entry: the element to delete from the llist.
* Note: llist_empty on entry does not return true after this, the entry is
* in an undefined state.
*/
static inline void llist_del(struct llist_head *entry)
{
__llist_del(entry->prev, entry->next);
entry->next = (struct llist_head *)LLIST_POISON1;
entry->prev = (struct llist_head *)LLIST_POISON2;
}
/**
* llist_del_init - deletes entry from llist and reinitialize it.
* @entry: the element to delete from the llist.
*/
static inline void llist_del_init(struct llist_head *entry)
{
__llist_del(entry->prev, entry->next);
INIT_LLIST_HEAD(entry);
}
/**
* llist_move - delete from one llist and add as another's head
* @llist: the entry to move
* @head: the head that will precede our entry
*/
static inline void llist_move(struct llist_head *llist, struct llist_head *head)
{
__llist_del(llist->prev, llist->next);
llist_add(llist, head);
}
/**
* llist_move_tail - delete from one llist and add as another's tail
* @llist: the entry to move
* @head: the head that will follow our entry
*/
static inline void llist_move_tail(struct llist_head *llist,
struct llist_head *head)
{
__llist_del(llist->prev, llist->next);
llist_add_tail(llist, head);
}
/**
* llist_empty - tests whether a llist is empty
* @head: the llist to test.
*/
static inline int llist_empty(const struct llist_head *head)
{
return head->next == head;
}
static inline void __llist_splice(struct llist_head *llist,
struct llist_head *head)
{
struct llist_head *first = llist->next;
struct llist_head *last = llist->prev;
struct llist_head *at = head->next;
first->prev = head;
head->next = first;
last->next = at;
at->prev = last;
}
/**
* llist_splice - join two llists
* @llist: the new llist to add.
* @head: the place to add it in the first llist.
*/
static inline void llist_splice(struct llist_head *llist, struct llist_head *head)
{
if (!llist_empty(llist))
__llist_splice(llist, head);
}
/**
* llist_splice_init - join two llists and reinitialise the emptied llist.
* @llist: the new llist to add.
* @head: the place to add it in the first llist.
*
* The llist at @llist is reinitialised
*/
static inline void llist_splice_init(struct llist_head *llist,
struct llist_head *head)
{
if (!llist_empty(llist)) {
__llist_splice(llist, head);
INIT_LLIST_HEAD(llist);
}
}
/**
* llist_entry - get the struct for this entry
* @ptr: the &struct llist_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the llist_struct within the struct.
*/
#define llist_entry(ptr, type, member) \
container_of(ptr, type, member)
/**
* llist_for_each - iterate over a llist
* @pos: the &struct llist_head to use as a loop counter.
* @head: the head for your llist.
*/
#define llist_for_each(pos, head) \
for (pos = (head)->next, prefetch(pos->next); pos != (head); \
pos = pos->next, prefetch(pos->next))
/**
* __llist_for_each - iterate over a llist
* @pos: the &struct llist_head to use as a loop counter.
* @head: the head for your llist.
*
* This variant differs from llist_for_each() in that it's the
* simplest possible llist iteration code, no prefetching is done.
* Use this for code that knows the llist to be very short (empty
* or 1 entry) most of the time.
*/
#define __llist_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
/**
* llist_for_each_prev - iterate over a llist backwards
* @pos: the &struct llist_head to use as a loop counter.
* @head: the head for your llist.
*/
#define llist_for_each_prev(pos, head) \
for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \
pos = pos->prev, prefetch(pos->prev))
/**
* llist_for_each_safe - iterate over a llist safe against removal of llist entry
* @pos: the &struct llist_head to use as a loop counter.
* @n: another &struct llist_head to use as temporary storage
* @head: the head for your llist.
*/
#define llist_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
/**
* llist_for_each_entry - iterate over llist of given type
* @pos: the type * to use as a loop counter.
* @head: the head for your llist.
* @member: the name of the llist_struct within the struct.
*/
#define llist_for_each_entry(pos, head, member) \
for (pos = llist_entry((head)->next, typeof(*pos), member), \
prefetch(pos->member.next); \
&pos->member != (head); \
pos = llist_entry(pos->member.next, typeof(*pos), member), \
prefetch(pos->member.next))
/**
* llist_for_each_entry_reverse - iterate backwards over llist of given type.
* @pos: the type * to use as a loop counter.
* @head: the head for your llist.
* @member: the name of the llist_struct within the struct.
*/
#define llist_for_each_entry_reverse(pos, head, member) \
for (pos = llist_entry((head)->prev, typeof(*pos), member), \
prefetch(pos->member.prev); \
&pos->member != (head); \
pos = llist_entry(pos->member.prev, typeof(*pos), member), \
prefetch(pos->member.prev))
/**
* llist_for_each_entry_continue - iterate over llist of given type
* continuing after existing point
* @pos: the type * to use as a loop counter.
* @head: the head for your llist.
* @member: the name of the llist_struct within the struct.
*/
#define llist_for_each_entry_continue(pos, head, member) \
for (pos = llist_entry(pos->member.next, typeof(*pos), member), \
prefetch(pos->member.next); \
&pos->member != (head); \
pos = llist_entry(pos->member.next, typeof(*pos), member), \
prefetch(pos->member.next))
/**
* llist_for_each_entry_safe - iterate over llist of given type safe against removal of llist entry
* @pos: the type * to use as a loop counter.
* @n: another type * to use as temporary storage
* @head: the head for your llist.
* @member: the name of the llist_struct within the struct.
*/
#define llist_for_each_entry_safe(pos, n, head, member) \
for (pos = llist_entry((head)->next, typeof(*pos), member), \
n = llist_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = llist_entry(n->member.next, typeof(*n), member))
/**
* llist_for_each_rcu - iterate over an rcu-protected llist
* @pos: the &struct llist_head to use as a loop counter.
* @head: the head for your llist.
*/
#define llist_for_each_rcu(pos, head) \
for (pos = (head)->next, prefetch(pos->next); pos != (head); \
pos = pos->next, ({ smp_read_barrier_depends(); 0;}), prefetch(pos->next))
#define __llist_for_each_rcu(pos, head) \
for (pos = (head)->next; pos != (head); \
pos = pos->next, ({ smp_read_barrier_depends(); 0;}))
/**
* llist_for_each_safe_rcu - iterate over an rcu-protected llist safe
* against removal of llist entry
* @pos: the &struct llist_head to use as a loop counter.
* @n: another &struct llist_head to use as temporary storage
* @head: the head for your llist.
*/
#define llist_for_each_safe_rcu(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, ({ smp_read_barrier_depends(); 0;}), n = pos->next)
/**
* llist_for_each_entry_rcu - iterate over rcu llist of given type
* @pos: the type * to use as a loop counter.
* @head: the head for your llist.
* @member: the name of the llist_struct within the struct.
*/
#define llist_for_each_entry_rcu(pos, head, member) \
for (pos = llist_entry((head)->next, typeof(*pos), member), \
prefetch(pos->member.next); \
&pos->member != (head); \
pos = llist_entry(pos->member.next, typeof(*pos), member), \
({ smp_read_barrier_depends(); 0;}), \
prefetch(pos->member.next))
/**
* llist_for_each_continue_rcu - iterate over an rcu-protected llist
* continuing after existing point.
* @pos: the &struct llist_head to use as a loop counter.
* @head: the head for your llist.
*/
#define llist_for_each_continue_rcu(pos, head) \
for ((pos) = (pos)->next, prefetch((pos)->next); (pos) != (head); \
(pos) = (pos)->next, ({ smp_read_barrier_depends(); 0;}), prefetch((pos)->next))
#endif

View File

@@ -0,0 +1,130 @@
#ifndef _OSMOCORE_LOGGING_H
#define _OSMOCORE_LOGGING_H
#include <stdio.h>
#include <stdint.h>
#include <osmocore/linuxlist.h>
#define LOG_MAX_CATEGORY 32
#define LOG_MAX_CTX 8
#define LOG_MAX_FILTERS 8
#define DEBUG
#ifdef DEBUG
#define DEBUGP(ss, fmt, args...) logp(ss, __FILE__, __LINE__, 0, fmt, ## args)
#define DEBUGPC(ss, fmt, args...) logp(ss, __FILE__, __LINE__, 1, fmt, ## args)
#else
#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 logp(unsigned int subsys, char *file, int line, int cont, const char *format, ...) __attribute__ ((format (printf, 5, 6)));
/* new logging interface */
#define LOGP(ss, level, fmt, args...) \
logp2(ss, level, __FILE__, __LINE__, 0, fmt, ##args)
#define LOGPC(ss, level, fmt, args...) \
logp2(ss, level, __FILE__, __LINE__, 1, fmt, ##args)
/* different levels */
#define LOGL_DEBUG 1 /* debugging information */
#define LOGL_INFO 3
#define LOGL_NOTICE 5 /* abnormal/unexpected condition */
#define LOGL_ERROR 7 /* error condition, requires user action */
#define LOGL_FATAL 8 /* fatal, program aborted */
#define LOG_FILTER_ALL 0x0001
struct log_category {
uint8_t loglevel;
uint8_t enabled;
};
struct log_info_cat {
const char *name;
const char *color;
const char *description;
uint8_t loglevel;
uint8_t enabled;
};
/* log context information, passed to filter */
struct log_context {
void *ctx[LOG_MAX_CTX+1];
};
struct log_target;
typedef int log_filter(const struct log_context *ctx,
struct log_target *target);
struct log_info {
/* filter callback function */
log_filter *filter_fn;
/* per-category information */
const struct log_info_cat *cat;
unsigned int num_cat;
};
struct log_target {
struct llist_head entry;
int filter_map;
void *filter_data[LOG_MAX_FILTERS+1];
struct log_category categories[LOG_MAX_CATEGORY+1];
uint8_t loglevel;
int use_color:1;
int print_timestamp:1;
union {
struct {
FILE *out;
} tgt_stdout;
struct {
int priority;
} tgt_syslog;
struct {
void *vty;
} tgt_vty;
};
void (*output) (struct log_target *target, const char *string);
};
/* use the above macros */
void logp2(unsigned int subsys, unsigned int level, char *file,
int line, int cont, const char *format, ...)
__attribute__ ((format (printf, 6, 7)));
void log_init(const struct log_info *cat);
/* context management */
void log_reset_context(void);
int log_set_context(uint8_t ctx, void *value);
/* filter on the targets */
void log_set_all_filter(struct log_target *target, int);
void log_set_use_color(struct log_target *target, int);
void log_set_print_timestamp(struct log_target *target, int);
void log_set_log_level(struct log_target *target, int log_level);
void log_parse_category_mask(struct log_target *target, const char* mask);
int log_parse_level(const char *lvl);
int log_parse_category(const char *category);
void log_set_category_filter(struct log_target *target, int category,
int enable, int level);
/* management of the targets */
struct log_target *log_target_create(void);
struct log_target *log_target_create_stderr(void);
void log_add_target(struct log_target *target);
void log_del_target(struct log_target *target);
#endif /* _OSMOCORE_LOGGING_H */

View File

@@ -0,0 +1,71 @@
#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

@@ -0,0 +1,175 @@
#ifndef _MSGB_H
#define _MSGB_H
/* (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>
#include "linuxlist.h"
struct bts_link;
struct msgb {
struct llist_head list;
/* ptr to the physical E1 link to the BTS(s) */
struct gsm_bts_link *bts_link;
/* Part of which TRX logical channel we were received / transmitted */
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;
/* 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;
unsigned char *head;
unsigned char *tail;
unsigned char *data;
unsigned char _data[0];
};
extern struct msgb *msgb_alloc(uint16_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_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);
}
static inline unsigned int msgb_l3len(const struct msgb *msgb)
{
return msgb->tail - (uint8_t *)msgb_l3(msgb);
}
static inline unsigned int msgb_headlen(const struct msgb *msgb)
{
return msgb->len - msgb->data_len;
}
static inline unsigned char *msgb_put(struct msgb *msgb, unsigned int len)
{
unsigned char *tmp = msgb->tail;
msgb->tail += 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;
msgb->len += len;
return msgb->data;
}
static inline unsigned char *msgb_pull(struct msgb *msgb, unsigned int len)
{
msgb->len -= len;
return msgb->data += len;
}
static inline int msgb_tailroom(const struct msgb *msgb)
{
return (msgb->head + msgb->data_len) - msgb->tail;
}
/* increase the headroom of an empty msgb, reducing the tailroom */
static inline void msgb_reserve(struct msgb *msg, int len)
{
msg->data += len;
msg->tail += len;
}
static inline struct msgb *msgb_alloc_headroom(int size, int headroom,
const char *name)
{
struct msgb *msg = msgb_alloc(size, name);
if (msg)
msgb_reserve(msg, headroom);
return msg;
}
#endif /* _MSGB_H */

View File

@@ -0,0 +1,3 @@
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

@@ -0,0 +1,743 @@
#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

@@ -0,0 +1,188 @@
#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

@@ -0,0 +1,126 @@
#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

@@ -0,0 +1,512 @@
#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

@@ -0,0 +1,713 @@
#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

@@ -0,0 +1,32 @@
#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);
const char *rsl_err_name(uint8_t err);
const char *rsl_rlm_cause_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

@@ -0,0 +1,22 @@
#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

@@ -0,0 +1,22 @@
#ifndef _BSC_SELECT_H
#define _BSC_SELECT_H
#include "linuxlist.h"
#define BSC_FD_READ 0x0001
#define BSC_FD_WRITE 0x0002
#define BSC_FD_EXCEPT 0x0004
struct bsc_fd {
struct llist_head list;
int fd;
unsigned int when;
int (*cb)(struct bsc_fd *fd, unsigned int what);
void *data;
unsigned int priv_nr;
};
int bsc_register_fd(struct bsc_fd *fd);
void bsc_unregister_fd(struct bsc_fd *fd);
int bsc_select_main(int polling);
#endif /* _BSC_SELECT_H */

View File

@@ -0,0 +1,15 @@
#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

@@ -0,0 +1,31 @@
#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

@@ -0,0 +1,192 @@
#ifndef _TALLOC_H_
#define _TALLOC_H_
/*
Unix SMB/CIFS implementation.
Samba temporary memory allocation functions
Copyright (C) Andrew Tridgell 2004-2005
Copyright (C) Stefan Metzmacher 2006
** NOTE! The following LGPL license applies to the talloc
** library. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#define HAVE_VA_COPY
/* this is only needed for compatibility with the old talloc */
typedef void TALLOC_CTX;
/*
this uses a little trick to allow __LINE__ to be stringified
*/
#ifndef __location__
#define __TALLOC_STRING_LINE1__(s) #s
#define __TALLOC_STRING_LINE2__(s) __TALLOC_STRING_LINE1__(s)
#define __TALLOC_STRING_LINE3__ __TALLOC_STRING_LINE2__(__LINE__)
#define __location__ __FILE__ ":" __TALLOC_STRING_LINE3__
#endif
#ifndef TALLOC_DEPRECATED
#define TALLOC_DEPRECATED 0
#endif
#ifndef PRINTF_ATTRIBUTE
#if (__GNUC__ >= 3)
/** Use gcc attribute to check printf fns. a1 is the 1-based index of
* the parameter containing the format, and a2 the index of the first
* argument. Note that some gcc 2.x versions don't handle this
* properly **/
#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
#else
#define PRINTF_ATTRIBUTE(a1, a2)
#endif
#endif
/* try to make talloc_set_destructor() and talloc_steal() type safe,
if we have a recent gcc */
#if (__GNUC__ >= 3)
#define _TALLOC_TYPEOF(ptr) __typeof__(ptr)
#define talloc_set_destructor(ptr, function) \
do { \
int (*_talloc_destructor_fn)(_TALLOC_TYPEOF(ptr)) = (function); \
_talloc_set_destructor((ptr), (int (*)(void *))_talloc_destructor_fn); \
} while(0)
/* this extremely strange macro is to avoid some braindamaged warning
stupidity in gcc 4.1.x */
#define talloc_steal(ctx, ptr) ({ _TALLOC_TYPEOF(ptr) __talloc_steal_ret = (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr)); __talloc_steal_ret; })
#else
#define talloc_set_destructor(ptr, function) \
_talloc_set_destructor((ptr), (int (*)(void *))(function))
#define _TALLOC_TYPEOF(ptr) void *
#define talloc_steal(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr))
#endif
#define talloc_reference(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_reference((ctx),(ptr))
#define talloc_move(ctx, ptr) (_TALLOC_TYPEOF(*(ptr)))_talloc_move((ctx),(void *)(ptr))
/* useful macros for creating type checked pointers */
#define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type)
#define talloc_size(ctx, size) talloc_named_const(ctx, size, __location__)
#define talloc_ptrtype(ctx, ptr) (_TALLOC_TYPEOF(ptr))talloc_size(ctx, sizeof(*(ptr)))
#define talloc_new(ctx) talloc_named_const(ctx, 0, "talloc_new: " __location__)
#define talloc_zero(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type)
#define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__)
#define talloc_zero_array(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type)
#define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type)
#define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__)
#define talloc_array_ptrtype(ctx, ptr, count) (_TALLOC_TYPEOF(ptr))talloc_array_size(ctx, sizeof(*(ptr)), count)
#define talloc_array_length(ctx) (talloc_get_size(ctx)/sizeof(*ctx))
#define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type)
#define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__)
#define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__)
#define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type)
#define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type)
#define talloc_get_type_abort(ptr, type) (type *)_talloc_get_type_abort(ptr, #type, __location__)
#define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type)
#if TALLOC_DEPRECATED
#define talloc_zero_p(ctx, type) talloc_zero(ctx, type)
#define talloc_p(ctx, type) talloc(ctx, type)
#define talloc_array_p(ctx, type, count) talloc_array(ctx, type, count)
#define talloc_realloc_p(ctx, p, type, count) talloc_realloc(ctx, p, type, count)
#define talloc_destroy(ctx) talloc_free(ctx)
#define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a))
#endif
#define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0)
/* The following definitions come from talloc.c */
void *_talloc(const void *context, size_t size);
void *talloc_pool(const void *context, size_t size);
void _talloc_set_destructor(const void *ptr, int (*_destructor)(void *));
int talloc_increase_ref_count(const void *ptr);
size_t talloc_reference_count(const void *ptr);
void *_talloc_reference(const void *context, const void *ptr);
int talloc_unlink(const void *context, void *ptr);
const char *talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
void talloc_set_name_const(const void *ptr, const char *name);
void *talloc_named(const void *context, size_t size,
const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
void *talloc_named_const(const void *context, size_t size, const char *name);
const char *talloc_get_name(const void *ptr);
void *talloc_check_name(const void *ptr, const char *name);
void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location);
void *talloc_parent(const void *ptr);
const char *talloc_parent_name(const void *ptr);
void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
int talloc_free(void *ptr);
void talloc_free_children(void *ptr);
void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name);
void *_talloc_steal(const void *new_ctx, const void *ptr);
void *_talloc_move(const void *new_ctx, const void *pptr);
size_t talloc_total_size(const void *ptr);
size_t talloc_total_blocks(const void *ptr);
void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
void (*callback)(const void *ptr,
int depth, int max_depth,
int is_ref,
void *private_data),
void *private_data);
void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f);
void talloc_report_full(const void *ptr, FILE *f);
void talloc_report(const void *ptr, FILE *f);
void talloc_enable_null_tracking(void);
void talloc_disable_null_tracking(void);
void talloc_enable_leak_report(void);
void talloc_enable_leak_report_full(void);
void *_talloc_zero(const void *ctx, size_t size, const char *name);
void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name);
void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name);
void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name);
void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name);
void *talloc_realloc_fn(const void *context, void *ptr, size_t size);
void *talloc_autofree_context(void);
size_t talloc_get_size(const void *ctx);
void *talloc_find_parent_byname(const void *ctx, const char *name);
void talloc_show_parents(const void *context, FILE *file);
int talloc_is_parent(const void *context, const void *ptr);
char *talloc_strdup(const void *t, const char *p);
char *talloc_strdup_append(char *s, const char *a);
char *talloc_strdup_append_buffer(char *s, const char *a);
char *talloc_strndup(const void *t, const char *p, size_t n);
char *talloc_strndup_append(char *s, const char *a, size_t n);
char *talloc_strndup_append_buffer(char *s, const char *a, size_t n);
char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
void talloc_set_abort_fn(void (*abort_fn)(const char *reason));
#endif

View File

@@ -0,0 +1,72 @@
/*
* (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.
*
*/
#ifndef TIMER_H
#define TIMER_H
#include <sys/time.h>
#include "linuxlist.h"
/**
* Timer management:
* - Create a struct timer_list
* - Fill out timeout and use add_timer or
* use schedule_timer to schedule a timer in
* x seconds and microseconds from now...
* - Use del_timer to remove the timer
*
* Internally:
* - We hook into select.c to give a timeval of the
* nearest timer. On already passed timers we give
* it a 0 to immediately fire after the select
* - update_timers will call the callbacks and remove
* the timers.
*
*/
struct timer_list {
struct llist_head entry;
struct timeval timeout;
unsigned int active : 1;
unsigned int handled : 1;
unsigned int in_list : 1;
void (*cb)(void*);
void *data;
};
/**
* timer management
*/
void bsc_add_timer(struct timer_list *timer);
void bsc_schedule_timer(struct timer_list *timer, int seconds, int microseconds);
void bsc_del_timer(struct timer_list *timer);
int bsc_timer_pending(struct timer_list *timer);
/**
* internal timer list management
*/
struct timeval *bsc_nearest_timer();
void bsc_prepare_timers();
int bsc_update_timers();
int bsc_timer_check(void);
#endif

View File

@@ -0,0 +1,244 @@
#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

@@ -0,0 +1,20 @@
#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

@@ -0,0 +1,45 @@
/* 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.
*
*/
#ifndef write_queue_h
#define write_queue_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);
void write_queue_clear(struct write_queue *queue);
int write_queue_enqueue(struct write_queue *queue, struct msgb *data);
int write_queue_bfd_cb(struct bsc_fd *fd, unsigned int what);
#endif

View File

@@ -0,0 +1,11 @@
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}/

1
libosmocore/m4/DUMMY Normal file
View File

@@ -0,0 +1 @@
Dummply placeholder.

View File

@@ -0,0 +1,17 @@
# 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 \
logging.c
if ENABLE_TALLOC
libosmocore_la_SOURCES += talloc.c
endif

170
libosmocore/src/bitvec.c Normal file
View File

@@ -0,0 +1,170 @@
/* bit vector utility routines */
/* (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.
*
*/
#include <errno.h>
#include <stdint.h>
#include <osmocore/bitvec.h>
#define BITNUM_FROM_COMP(byte, bit) ((byte*8)+bit)
static inline unsigned int bytenum_from_bitnum(unsigned int bitnum)
{
unsigned int bytenum = bitnum / 8;
return bytenum;
}
/* 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)
{
int bitval;
switch (bit) {
case ZERO:
bitval = (0 << bitnum);
break;
case ONE:
bitval = (1 << bitnum);
break;
case L:
bitval = ((0x2b ^ (0 << bitnum)) & (1 << bitnum));
break;
case H:
bitval = ((0x2b ^ (1 << bitnum)) & (1 << bitnum));
break;
default:
return 0;
}
return bitval;
}
/* 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)
{
unsigned int bytenum = bytenum_from_bitnum(bitnr);
unsigned int bitnum = 7 - (bitnr % 8);
uint8_t bitval;
if (bytenum >= bv->data_len)
return -EINVAL;
bitval = bitval2mask(ONE, bitnum);
if (bv->data[bytenum] & bitval)
return ONE;
return ZERO;
}
/* 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 i, k = 0;
for (i = 0; i < bv->data_len*8; i++) {
if (bitvec_get_bit_pos(bv, i) == ONE) {
k++;
if (k == n)
return i;
}
}
return 0;
}
/* set the bit at a given position inside a bitvec */
int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnr,
enum bit_value bit)
{
unsigned int bytenum = bytenum_from_bitnum(bitnr);
unsigned int bitnum = 7 - (bitnr % 8);
uint8_t bitval;
if (bytenum >= bv->data_len)
return -EINVAL;
/* first clear the bit */
bitval = bitval2mask(ONE, bitnum);
bv->data[bytenum] &= ~bitval;
/* then set it to desired value */
bitval = bitval2mask(bit, bitnum);
bv->data[bytenum] |= bitval;
return 0;
}
/* set the next bit inside a bitvec */
int bitvec_set_bit(struct bitvec *bv, enum bit_value bit)
{
int rc;
rc = bitvec_set_bit_pos(bv, bv->cur_bit, bit);
if (!rc)
bv->cur_bit++;
return rc;
}
/* set multiple bits (based on array of bitvals) at current pos */
int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count)
{
int i, rc;
for (i = 0; i < count; i++) {
rc = bitvec_set_bit(bv, bits[i]);
if (rc)
return rc;
}
return 0;
}
/* set multiple bits (based on numeric value) at current pos */
int bitvec_set_uint(struct bitvec *bv, unsigned int ui, int num_bits)
{
int i, rc;
for (i = 0; i < num_bits; i++) {
int bit = 0;
if (ui & (1 << (num_bits - i - 1)))
bit = 1;
rc = bitvec_set_bit(bv, bit);
if (rc)
return rc;
}
return 0;
}
/* pad all remaining bits up to num_bits */
int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit)
{
unsigned int i;
for (i = bv->cur_bit; i <= up_to_bit; i++)
bitvec_set_bit(bv, L);
return 0;
}

230
libosmocore/src/comp128.c Normal file
View File

@@ -0,0 +1,230 @@
/*
* 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;
}

263
libosmocore/src/gsm48.c Normal file
View File

@@ -0,0 +1,263 @@
/* 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-2010 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 struct value_string 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" },
{ 0, NULL },
};
/* FIXME: convert to value_string */
static 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_state_name(uint8_t state)
{
if (state < ARRAY_SIZE(cc_state_names))
return cc_state_names[state];
return "invalid";
}
static const struct value_string cc_msg_names[] = {
{ GSM48_MT_CC_ALERTING, "ALERTING" },
{ GSM48_MT_CC_CALL_PROC, "CALL_PROC" },
{ GSM48_MT_CC_PROGRESS, "PROGRESS" },
{ GSM48_MT_CC_ESTAB, "ESTAB" },
{ GSM48_MT_CC_SETUP, "SETUP" },
{ GSM48_MT_CC_ESTAB_CONF, "ESTAB_CONF" },
{ GSM48_MT_CC_CONNECT, "CONNECT" },
{ GSM48_MT_CC_CALL_CONF, "CALL_CONF" },
{ GSM48_MT_CC_START_CC, "START_CC" },
{ GSM48_MT_CC_RECALL, "RECALL" },
{ GSM48_MT_CC_EMERG_SETUP, "EMERG_SETUP" },
{ GSM48_MT_CC_CONNECT_ACK, "CONNECT_ACK" },
{ GSM48_MT_CC_USER_INFO, "USER_INFO" },
{ GSM48_MT_CC_MODIFY_REJECT, "MODIFY_REJECT" },
{ GSM48_MT_CC_MODIFY, "MODIFY" },
{ GSM48_MT_CC_HOLD, "HOLD" },
{ GSM48_MT_CC_HOLD_ACK, "HOLD_ACK" },
{ GSM48_MT_CC_HOLD_REJ, "HOLD_REJ" },
{ GSM48_MT_CC_RETR, "RETR" },
{ GSM48_MT_CC_RETR_ACK, "RETR_ACK" },
{ GSM48_MT_CC_RETR_REJ, "RETR_REJ" },
{ GSM48_MT_CC_MODIFY_COMPL, "MODIFY_COMPL" },
{ GSM48_MT_CC_DISCONNECT, "DISCONNECT" },
{ GSM48_MT_CC_RELEASE_COMPL, "RELEASE_COMPL" },
{ GSM48_MT_CC_RELEASE, "RELEASE" },
{ GSM48_MT_CC_STOP_DTMF, "STOP_DTMF" },
{ GSM48_MT_CC_STOP_DTMF_ACK, "STOP_DTMF_ACK" },
{ GSM48_MT_CC_STATUS_ENQ, "STATUS_ENQ" },
{ GSM48_MT_CC_START_DTMF, "START_DTMF" },
{ GSM48_MT_CC_START_DTMF_ACK, "START_DTMF_ACK" },
{ GSM48_MT_CC_START_DTMF_REJ, "START_DTMF_REJ" },
{ GSM48_MT_CC_CONG_CTRL, "CONG_CTRL" },
{ GSM48_MT_CC_FACILITY, "FACILITY" },
{ GSM48_MT_CC_STATUS, "STATUS" },
{ GSM48_MT_CC_NOTIFY, "NOTFIY" },
{ 0, NULL }
};
const char *gsm48_cc_msg_name(uint8_t msgtype)
{
return get_value_string(cc_msg_names, msgtype);
}
const char *rr_cause_name(uint8_t cause)
{
return get_value_string(rr_cause_names, cause);
}
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];
}

659
libosmocore/src/gsm48_ie.c Normal file
View File

@@ -0,0 +1,659 @@
/* 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;
}

361
libosmocore/src/gsm_utils.c Normal file
View File

@@ -0,0 +1,361 @@
/*
* (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));
}

345
libosmocore/src/logging.c Normal file
View File

@@ -0,0 +1,345 @@
/* Debugging/Logging support code */
/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
* (C) 2008 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 <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <time.h>
#include <errno.h>
#include <osmocore/talloc.h>
#include <osmocore/utils.h>
#include <osmocore/logging.h>
static const struct log_info *log_info;
static struct log_context log_context;
static void *tall_log_ctx = NULL;
static LLIST_HEAD(target_list);
static const struct value_string loglevel_strs[] = {
{ 0, "EVERYTHING" },
{ LOGL_DEBUG, "DEBUG" },
{ LOGL_INFO, "INFO" },
{ LOGL_NOTICE, "NOTICE" },
{ LOGL_ERROR, "ERROR" },
{ LOGL_FATAL, "FATAL" },
{ 0, NULL },
};
int log_parse_level(const char *lvl)
{
return get_string_value(loglevel_strs, lvl);
}
int log_parse_category(const char *category)
{
int i;
for (i = 0; i < log_info->num_cat; ++i) {
if (!strcasecmp(log_info->cat[i].name+1, category))
return i;
}
return -EINVAL;
}
/*
* Parse the category mask.
* The format can be this: category1:category2:category3
* or category1,2:category2,3:...
*/
void log_parse_category_mask(struct log_target* target, const char *_mask)
{
int i = 0;
char *mask = strdup(_mask);
char *category_token = NULL;
/* Disable everything to enable it afterwards */
for (i = 0; i < ARRAY_SIZE(target->categories); ++i)
target->categories[i].enabled = 0;
category_token = strtok(mask, ":");
do {
for (i = 0; i < log_info->num_cat; ++i) {
char* colon = strstr(category_token, ",");
int length = strlen(category_token);
if (colon)
length = colon - category_token;
if (strncasecmp(log_info->cat[i].name, category_token,
length) == 0) {
int level = 0;
if (colon)
level = atoi(colon+1);
target->categories[i].enabled = 1;
target->categories[i].loglevel = level;
}
}
} while ((category_token = strtok(NULL, ":")));
free(mask);
}
static const char* color(int subsys)
{
if (subsys < log_info->num_cat)
return log_info->cat[subsys].color;
return NULL;
}
static void _output(struct log_target *target, unsigned int subsys,
char *file, int line, int cont, const char *format,
va_list ap)
{
char col[30];
char sub[30];
char tim[30];
char buf[4096];
char final[4096];
/* prepare the data */
col[0] = '\0';
sub[0] = '\0';
tim[0] = '\0';
buf[0] = '\0';
/* are we using color */
if (target->use_color) {
const char *c = color(subsys);
if (c) {
snprintf(col, sizeof(col), "%s", color(subsys));
col[sizeof(col)-1] = '\0';
}
}
vsnprintf(buf, sizeof(buf), format, ap);
buf[sizeof(buf)-1] = '\0';
if (!cont) {
if (target->print_timestamp) {
char *timestr;
time_t tm;
tm = time(NULL);
timestr = ctime(&tm);
timestr[strlen(timestr)-1] = '\0';
snprintf(tim, sizeof(tim), "%s ", timestr);
tim[sizeof(tim)-1] = '\0';
}
snprintf(sub, sizeof(sub), "<%4.4x> %s:%d ", subsys, file, line);
sub[sizeof(sub)-1] = '\0';
}
snprintf(final, sizeof(final), "%s%s%s%s\033[0;m", col, tim, sub, buf);
final[sizeof(final)-1] = '\0';
target->output(target, final);
}
static void _logp(unsigned int subsys, int level, char *file, int line,
int cont, const char *format, va_list ap)
{
struct log_target *tar;
llist_for_each_entry(tar, &target_list, entry) {
struct log_category *category;
int output = 0;
category = &tar->categories[subsys];
/* subsystem is not supposed to be logged */
if (!category->enabled)
continue;
/* Check the global log level */
if (tar->loglevel != 0 && level < tar->loglevel)
continue;
/* Check the category log level */
if (tar->loglevel == 0 && category->loglevel != 0 &&
level < category->loglevel)
continue;
/* Apply filters here... if that becomes messy we will
* need to put filters in a list and each filter will
* say stop, continue, output */
if ((tar->filter_map & LOG_FILTER_ALL) != 0)
output = 1;
else if (log_info->filter_fn)
output = log_info->filter_fn(&log_context,
tar);
if (output) {
/* FIXME: copying the va_list is an ugly
* workaround against a bug hidden somewhere in
* _output. If we do not copy here, the first
* call to _output() will corrupt the va_list
* contents, and any further _output() calls
* with the same va_list will segfault */
va_list bp;
va_copy(bp, ap);
_output(tar, subsys, file, line, cont, format, bp);
va_end(bp);
}
}
}
void logp(unsigned int subsys, char *file, int line, int cont,
const char *format, ...)
{
va_list ap;
va_start(ap, format);
_logp(subsys, LOGL_DEBUG, file, line, cont, format, ap);
va_end(ap);
}
void logp2(unsigned int subsys, unsigned int level, char *file, int line, int cont, const char *format, ...)
{
va_list ap;
va_start(ap, format);
_logp(subsys, level, file, line, cont, format, ap);
va_end(ap);
}
static char hexd_buff[4096];
char *hexdump(const unsigned char *buf, int len)
{
int i;
char *cur = hexd_buff;
hexd_buff[0] = 0;
for (i = 0; i < len; i++) {
int len_remain = sizeof(hexd_buff) - (cur - hexd_buff);
int rc = snprintf(cur, len_remain, "%02x ", buf[i]);
if (rc <= 0)
break;
cur += rc;
}
hexd_buff[sizeof(hexd_buff)-1] = 0;
return hexd_buff;
}
void log_add_target(struct log_target *target)
{
llist_add_tail(&target->entry, &target_list);
}
void log_del_target(struct log_target *target)
{
llist_del(&target->entry);
}
void log_reset_context(void)
{
memset(&log_context, 0, sizeof(log_context));
}
int log_set_context(uint8_t ctx_nr, void *value)
{
if (ctx_nr > LOG_MAX_CTX)
return -EINVAL;
log_context.ctx[ctx_nr] = value;
return 0;
}
void log_set_all_filter(struct log_target *target, int all)
{
if (all)
target->filter_map |= LOG_FILTER_ALL;
else
target->filter_map &= ~LOG_FILTER_ALL;
}
void log_set_use_color(struct log_target *target, int use_color)
{
target->use_color = use_color;
}
void log_set_print_timestamp(struct log_target *target, int print_timestamp)
{
target->print_timestamp = print_timestamp;
}
void log_set_log_level(struct log_target *target, int log_level)
{
target->loglevel = log_level;
}
void log_set_category_filter(struct log_target *target, int category,
int enable, int level)
{
if (category >= log_info->num_cat)
return;
target->categories[category].enabled = !!enable;
target->categories[category].loglevel = level;
}
static void _stderr_output(struct log_target *target, const char *log)
{
fprintf(target->tgt_stdout.out, "%s", log);
fflush(target->tgt_stdout.out);
}
struct log_target *log_target_create(void)
{
struct log_target *target;
target = talloc_zero(tall_log_ctx, struct log_target);
if (!target)
return NULL;
INIT_LLIST_HEAD(&target->entry);
memcpy(target->categories, log_info->cat,
sizeof(struct log_category)*log_info->num_cat);
target->use_color = 1;
target->print_timestamp = 0;
target->loglevel = 0;
return target;
}
struct log_target *log_target_create_stderr(void)
{
struct log_target *target;
target = log_target_create();
if (!target)
return NULL;
target->tgt_stdout.out = stderr;
target->output = _stderr_output;
return target;
}
void log_init(const struct log_info *cat)
{
tall_log_ctx = talloc_named_const(NULL, 1, "logging");
log_info = cat;
}

89
libosmocore/src/msgb.c Normal file
View File

@@ -0,0 +1,89 @@
/* (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 <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <osmocore/msgb.h>
//#include <openbsc/gsm_data.h>
#include <osmocore/talloc.h>
//#include <openbsc/debug.h>
void *tall_msgb_ctx;
struct msgb *msgb_alloc(uint16_t size, const char *name)
{
struct msgb *msg;
msg = _talloc_zero(tall_msgb_ctx, sizeof(*msg) + size, name);
if (!msg) {
//LOGP(DRSL, LOGL_FATAL, "unable to allocate msgb\n");
return NULL;
}
msg->data_len = size;
msg->len = 0;
msg->data = msg->_data;
msg->head = msg->_data;
msg->tail = msg->_data;
return msg;
}
void msgb_free(struct msgb *m)
{
talloc_free(m);
}
void msgb_enqueue(struct llist_head *queue, struct msgb *msg)
{
llist_add_tail(&msg->list, queue);
}
struct msgb *msgb_dequeue(struct llist_head *queue)
{
struct llist_head *lh;
if (llist_empty(queue))
return NULL;
lh = queue->next;
llist_del(lh);
return llist_entry(lh, struct msgb, list);
}
void msgb_reset(struct msgb *msg)
{
msg->len = 0;
msg->data = msg->_data;
msg->head = msg->_data;
msg->tail = msg->_data;
msg->bts_link = NULL;
msg->trx = NULL;
msg->lchan = NULL;
msg->l2h = NULL;
msg->l3h = NULL;
msg->smsh = NULL;
}

329
libosmocore/src/rsl.c Normal file
View File

@@ -0,0 +1,329 @@
/* 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;
}
static const struct value_string rsl_err_vals[] = {
{ 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" },
{ 0, NULL }
};
const char *rsl_err_name(uint8_t err)
{
return get_value_string(rsl_err_vals, err);
}
static 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_rlm_cause_name(uint8_t err)
{
return get_value_string(rsl_rlm_cause_strs, 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)
{
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

@@ -0,0 +1,94 @@
/* 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");
}
}

130
libosmocore/src/select.c Normal file
View File

@@ -0,0 +1,130 @@
/* select filedescriptor handling, taken from:
* userspace logging daemon for the iptables ULOG target
* of the linux 2.4 netfilter subsystem.
*
* (C) 2000-2009 by Harald Welte <laforge@gnumonks.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <fcntl.h>
#include <osmocore/select.h>
#include <osmocore/linuxlist.h>
#include <osmocore/timer.h>
#include "../config.h"
#ifdef HAVE_SYS_SELECT_H
static int maxfd = 0;
static LLIST_HEAD(bsc_fds);
static int unregistered_count;
int bsc_register_fd(struct bsc_fd *fd)
{
int flags;
/* make FD nonblocking */
flags = fcntl(fd->fd, F_GETFL);
if (flags < 0)
return flags;
flags |= O_NONBLOCK;
flags = fcntl(fd->fd, F_SETFL, flags);
if (flags < 0)
return flags;
/* Register FD */
if (fd->fd > maxfd)
maxfd = fd->fd;
llist_add_tail(&fd->list, &bsc_fds);
return 0;
}
void bsc_unregister_fd(struct bsc_fd *fd)
{
unregistered_count++;
llist_del(&fd->list);
}
int bsc_select_main(int polling)
{
struct bsc_fd *ufd, *tmp;
fd_set readset, writeset, exceptset;
int work = 0, rc;
struct timeval no_time = {0, 0};
FD_ZERO(&readset);
FD_ZERO(&writeset);
FD_ZERO(&exceptset);
/* prepare read and write fdsets */
llist_for_each_entry(ufd, &bsc_fds, list) {
if (ufd->when & BSC_FD_READ)
FD_SET(ufd->fd, &readset);
if (ufd->when & BSC_FD_WRITE)
FD_SET(ufd->fd, &writeset);
if (ufd->when & BSC_FD_EXCEPT)
FD_SET(ufd->fd, &exceptset);
}
bsc_timer_check();
if (!polling)
bsc_prepare_timers();
rc = select(maxfd+1, &readset, &writeset, &exceptset, polling ? &no_time : bsc_nearest_timer());
if (rc < 0)
return 0;
/* fire timers */
bsc_update_timers();
/* call registered callback functions */
restart:
unregistered_count = 0;
llist_for_each_entry_safe(ufd, tmp, &bsc_fds, list) {
int flags = 0;
if (FD_ISSET(ufd->fd, &readset)) {
flags |= BSC_FD_READ;
FD_CLR(ufd->fd, &readset);
}
if (FD_ISSET(ufd->fd, &writeset)) {
flags |= BSC_FD_WRITE;
FD_CLR(ufd->fd, &writeset);
}
if (FD_ISSET(ufd->fd, &exceptset)) {
flags |= BSC_FD_EXCEPT;
FD_CLR(ufd->fd, &exceptset);
}
if (flags) {
work = 1;
ufd->cb(ufd, flags);
}
/* ugly, ugly hack. If more than one filedescriptors were
* unregistered, they might have been consecutive and
* llist_for_each_entry_safe() is no longer safe */
if (unregistered_count > 1)
goto restart;
}
return work;
}
#endif /* _HAVE_SYS_SELECT_H */

84
libosmocore/src/signal.c Normal file
View File

@@ -0,0 +1,84 @@
/* Generic signalling/notification infrastructure */
/* (C) 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 <osmocore/signal.h>
#include <osmocore/talloc.h>
#include <osmocore/linuxlist.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
void *tall_sigh_ctx;
static LLIST_HEAD(signal_handler_list);
struct signal_handler {
struct llist_head entry;
unsigned int subsys;
signal_cbfn *cbfn;
void *data;
};
int register_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data)
{
struct signal_handler *sig_data;
sig_data = talloc(tall_sigh_ctx, struct signal_handler);
if (!sig_data)
return -ENOMEM;
memset(sig_data, 0, sizeof(*sig_data));
sig_data->subsys = subsys;
sig_data->data = data;
sig_data->cbfn = cbfn;
/* FIXME: check if we already have a handler for this subsys/cbfn/data */
llist_add_tail(&sig_data->entry, &signal_handler_list);
return 0;
}
void unregister_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data)
{
struct signal_handler *handler;
llist_for_each_entry(handler, &signal_handler_list, entry) {
if (handler->cbfn == cbfn && handler->data == data
&& subsys == handler->subsys) {
llist_del(&handler->entry);
talloc_free(handler);
break;
}
}
}
void dispatch_signal(unsigned int subsys, unsigned int signal, void *signal_data)
{
struct signal_handler *handler;
llist_for_each_entry(handler, &signal_handler_list, entry) {
if (handler->subsys != subsys)
continue;
(*handler->cbfn)(subsys, signal, handler->data, signal_data);
}
}

View File

@@ -0,0 +1,66 @@
/* utility routines for keeping some statistics */
/* (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.
*
*/
#include <sys/types.h>
#include <osmocore/linuxlist.h>
#include <osmocore/talloc.h>
#include <osmocore/statistics.h>
static LLIST_HEAD(counters);
void *tall_ctr_ctx;
struct counter *counter_alloc(const char *name)
{
struct counter *ctr = talloc_zero(tall_ctr_ctx, struct counter);
if (!ctr)
return NULL;
ctr->name = name;
llist_add_tail(&ctr->list, &counters);
return ctr;
}
void counter_free(struct counter *ctr)
{
llist_del(&ctr->list);
talloc_free(ctr);
}
int counters_for_each(int (*handle_counter)(struct counter *, void *), void *data)
{
struct counter *ctr;
int rc = 0;
llist_for_each_entry(ctr, &counters, list) {
rc = handle_counter(ctr, data);
if (rc < 0)
return rc;
}
return rc;
}

1805
libosmocore/src/talloc.c Normal file

File diff suppressed because it is too large Load Diff

185
libosmocore/src/timer.c Normal file
View File

@@ -0,0 +1,185 @@
/*
* (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 <assert.h>
#include <string.h>
#include <osmocore/timer.h>
static LLIST_HEAD(timer_list);
static struct timeval s_nearest_time;
static struct timeval s_select_time;
#define MICRO_SECONDS 1000000LL
#define TIME_SMALLER(left, right) \
(left.tv_sec*MICRO_SECONDS+left.tv_usec) <= (right.tv_sec*MICRO_SECONDS+right.tv_usec)
void bsc_add_timer(struct timer_list *timer)
{
struct timer_list *list_timer;
/* TODO: Optimize and remember the closest item... */
timer->active = 1;
/* this might be called from within update_timers */
llist_for_each_entry(list_timer, &timer_list, entry)
if (timer == list_timer)
return;
timer->in_list = 1;
llist_add(&timer->entry, &timer_list);
}
void bsc_schedule_timer(struct timer_list *timer, int seconds, int microseconds)
{
struct timeval current_time;
gettimeofday(&current_time, NULL);
unsigned long long currentTime = current_time.tv_sec * MICRO_SECONDS + current_time.tv_usec;
currentTime += seconds * MICRO_SECONDS + microseconds;
timer->timeout.tv_sec = currentTime / MICRO_SECONDS;
timer->timeout.tv_usec = currentTime % MICRO_SECONDS;
bsc_add_timer(timer);
}
void bsc_del_timer(struct timer_list *timer)
{
if (timer->in_list) {
timer->active = 0;
timer->in_list = 0;
llist_del(&timer->entry);
}
}
int bsc_timer_pending(struct timer_list *timer)
{
return timer->active;
}
/*
* if we have a nearest time return the delta between the current
* time and the time of the nearest timer.
* If the nearest timer timed out return NULL and then we will
* dispatch everything after the select
*/
struct timeval *bsc_nearest_timer()
{
struct timeval current_time;
if (s_nearest_time.tv_sec == 0 && s_nearest_time.tv_usec == 0)
return NULL;
if (gettimeofday(&current_time, NULL) == -1)
return NULL;
unsigned long long nearestTime = s_nearest_time.tv_sec * MICRO_SECONDS + s_nearest_time.tv_usec;
unsigned long long currentTime = current_time.tv_sec * MICRO_SECONDS + current_time.tv_usec;
if (nearestTime < currentTime) {
s_select_time.tv_sec = 0;
s_select_time.tv_usec = 0;
} else {
s_select_time.tv_sec = (nearestTime - currentTime) / MICRO_SECONDS;
s_select_time.tv_usec = (nearestTime - currentTime) % MICRO_SECONDS;
}
return &s_select_time;
}
/*
* Find the nearest time and update s_nearest_time
*/
void bsc_prepare_timers()
{
struct timer_list *timer, *nearest_timer = NULL;
llist_for_each_entry(timer, &timer_list, entry) {
if (!nearest_timer || TIME_SMALLER(timer->timeout, nearest_timer->timeout)) {
nearest_timer = timer;
}
}
if (nearest_timer) {
s_nearest_time = nearest_timer->timeout;
} else {
memset(&s_nearest_time, 0, sizeof(struct timeval));
}
}
/*
* fire all timers... and remove them
*/
int bsc_update_timers()
{
struct timeval current_time;
struct timer_list *timer, *tmp;
int work = 0;
gettimeofday(&current_time, NULL);
/*
* The callbacks might mess with our list and in this case
* even llist_for_each_entry_safe is not safe to use. To allow
* del_timer, add_timer, schedule_timer to be called from within
* the callback we jump through some loops.
*
* First we set the handled flag of each active timer to zero,
* then we iterate over the list and execute the callbacks. As the
* list might have been changed (specially the next) from within
* the callback we have to start over again. Once every callback
* is dispatched we will remove the non-active from the list.
*
* TODO: If this is a performance issue we can poison a global
* variable in add_timer and del_timer and only then restart.
*/
llist_for_each_entry(timer, &timer_list, entry) {
timer->handled = 0;
}
restart:
llist_for_each_entry(timer, &timer_list, entry) {
if (!timer->handled && TIME_SMALLER(timer->timeout, current_time)) {
timer->handled = 1;
timer->active = 0;
(*timer->cb)(timer->data);
work = 1;
goto restart;
}
}
llist_for_each_entry_safe(timer, tmp, &timer_list, entry) {
timer->handled = 0;
if (!timer->active) {
bsc_del_timer(timer);
}
}
return work;
}
int bsc_timer_check(void)
{
struct timer_list *timer;
int i = 0;
llist_for_each_entry(timer, &timer_list, entry) {
i++;
}
return i;
}

View File

@@ -0,0 +1,171 @@
#include <stdio.h>
#include <stdint.h>
#include <osmocore/utils.h>
#include <osmocore/tlv.h>
struct tlv_definition tvlv_att_def;
int tlv_dump(struct tlv_parsed *dec)
{
int i;
for (i = 0; i <= 0xff; i++) {
if (!dec->lv[i].val)
continue;
printf("T=%02x L=%d\n", i, dec->lv[i].len);
}
return 0;
}
/* o_tag: output: tag found
* o_len: output: length of the data
* o_val: output: pointer to the data
* def: input: a structure defining the valid TLV tags / configurations
* buf: input: the input data buffer to be parsed
* buf_len: input: the length of the input data buffer
*
* Also, returns the number of bytes consumed by the TLV entry
*/
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)
{
uint8_t tag;
int len;
tag = *buf;
*o_tag = tag;
/* FIXME: use tables for knwon IEI */
switch (def->def[tag].type) {
case TLV_TYPE_T:
/* GSM TS 04.07 11.2.4: Type 1 TV or Type 2 T */
*o_val = buf;
*o_len = 0;
len = 1;
break;
case TLV_TYPE_TV:
*o_val = buf+1;
*o_len = 1;
len = 2;
break;
case TLV_TYPE_FIXED:
*o_val = buf+1;
*o_len = def->def[tag].fixed_len;
len = def->def[tag].fixed_len + 1;
break;
case TLV_TYPE_TLV:
/* GSM TS 04.07 11.2.4: Type 4 TLV */
if (buf + 1 > buf + buf_len)
return -1;
*o_val = buf+2;
*o_len = *(buf+1);
len = *o_len + 2;
if (len > buf_len)
return -2;
break;
case TLV_TYPE_TvLV:
if (*(buf+1) & 0x80) {
/* like TLV, but without highest bit of len */
if (buf + 1 > buf + buf_len)
return -1;
*o_val = buf+2;
*o_len = *(buf+1) & 0x7f;
len = *o_len + 2;
if (len > buf_len)
return -2;
break;
}
/* like TL16V, fallthrough */
case TLV_TYPE_TL16V:
if (2 > buf_len)
return -1;
*o_val = buf+3;
*o_len = *(buf+1) << 8 | *(buf+2);
len = *o_len + 3;
if (len > buf_len)
return -2;
break;
default:
return -3;
}
return len;
}
/* dec: output: a caller-allocated pointer to a struct tlv_parsed,
* def: input: a structure defining the valid TLV tags / configurations
* buf: input: the input data buffer to be parsed
* buf_len: input: the length of the input data buffer
* lv_tag: input: an initial LV tag at the start of the buffer
* lv_tag2: input: a second initial LV tag following lv_tag
*/
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)
{
int ofs = 0, num_parsed = 0;
uint16_t len;
memset(dec, 0, sizeof(*dec));
if (lv_tag) {
if (ofs > buf_len)
return -1;
dec->lv[lv_tag].val = &buf[ofs+1];
dec->lv[lv_tag].len = buf[ofs];
len = dec->lv[lv_tag].len + 1;
if (ofs + len > buf_len)
return -2;
num_parsed++;
ofs += len;
}
if (lv_tag2) {
if (ofs > buf_len)
return -1;
dec->lv[lv_tag2].val = &buf[ofs+1];
dec->lv[lv_tag2].len = buf[ofs];
len = dec->lv[lv_tag2].len + 1;
if (ofs + len > buf_len)
return -2;
num_parsed++;
ofs += len;
}
while (ofs < buf_len) {
int rv;
uint8_t tag;
const uint8_t *val;
rv = tlv_parse_one(&tag, &len, &val, def,
&buf[ofs], buf_len-ofs);
if (rv < 0)
return rv;
dec->lv[tag].val = val;
dec->lv[tag].len = len;
ofs += rv;
num_parsed++;
}
//tlv_dump(dec);
return num_parsed;
}
/* 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)
{
int i;
for (i = 0; i < ARRAY_SIZE(dst->def); i++) {
if (src->def[i].type == TLV_TYPE_NONE)
continue;
if (dst->def[i].type == TLV_TYPE_NONE)
dst->def[i] = src->def[i];
}
}
static __attribute__((constructor)) void on_dso_load_tlv(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(tvlv_att_def.def); i++)
tvlv_att_def.def[i].type = TLV_TYPE_TvLV;
}

50
libosmocore/src/utils.c Normal file
View File

@@ -0,0 +1,50 @@
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <stdio.h>
#include <osmocore/utils.h>
static char namebuf[255];
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;
}
snprintf(namebuf, sizeof(namebuf), "unknown 0x%x", val);
return namebuf;
}
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

@@ -0,0 +1,85 @@
/* 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;
}
void write_queue_clear(struct write_queue *queue)
{
while (!llist_empty(&queue->msg_queue)) {
struct msgb *msg = msgb_dequeue(&queue->msg_queue);
msgb_free(msg);
}
queue->current_length = 0;
queue->bfd.when &= ~BSC_FD_WRITE;
}

View File

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

View File

@@ -0,0 +1,5 @@
INCLUDES = $(all_includes) -I$(top_srcdir)/include
noinst_PROGRAMS = sms_test
sms_test_SOURCES = sms_test.c
sms_test_LDADD = $(top_builddir)/src/libosmocore.la

View File

@@ -0,0 +1,47 @@
/*
* (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <osmocore/msgb.h>
#include <osmocore/gsm_utils.h>
int main(int argc, char** argv)
{
printf("SMS testing\n");
struct msgb *msg;
uint8_t *sms;
uint8_t i;
/* test 7-bit coding/decoding */
const char *input = "test text";
uint8_t length;
uint8_t coded[256];
char result[256];
length = gsm_7bit_encode(coded, input);
gsm_7bit_decode(result, coded, length);
if (strcmp(result, input) != 0) {
printf("7 Bit coding failed... life sucks\n");
printf("Wanted: '%s' got '%s'\n", input, result);
}
}

View File

@@ -0,0 +1,6 @@
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

View File

@@ -0,0 +1,77 @@
/*
* (C) 2008 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 <stdio.h>
#include <osmocore/timer.h>
#include <osmocore/select.h>
#include "../../config.h"
static void timer_fired(void *data);
static struct timer_list timer_one = {
.cb = timer_fired,
.data = (void*)1,
};
static struct timer_list timer_two = {
.cb = timer_fired,
.data = (void*)2,
};
static struct timer_list timer_three = {
.cb = timer_fired,
.data = (void*)3,
};
static void timer_fired(void *_data)
{
unsigned long data = (unsigned long) _data;
printf("Fired timer: %lu\n", data);
if (data == 1) {
bsc_schedule_timer(&timer_one, 3, 0);
bsc_del_timer(&timer_two);
} else if (data == 2) {
printf("Should not be fired... bug in del_timer\n");
} else if (data == 3) {
printf("Timer fired not registering again\n");
} else {
printf("wtf... wrong data\n");
}
}
int main(int argc, char** argv)
{
printf("Starting... timer\n");
bsc_schedule_timer(&timer_one, 3, 0);
bsc_schedule_timer(&timer_two, 5, 0);
bsc_schedule_timer(&timer_three, 4, 0);
#ifdef HAVE_SYS_SELECT_H
while (1) {
bsc_select_main(0);
}
#else
printf("Select not supported on this platform!\n");
#endif
}

3
openbsc/.gitignore vendored
View File

@@ -36,9 +36,6 @@ ipaccess-find
ipaccess-firmware
ipaccess-proxy
isdnsync
bsc_nat
osmo-sgsn
osmo-gbproxy
#tests
tests/channel/channel_test

View File

@@ -14,8 +14,6 @@ Its currently supported interfaces towards the BTS are:
* A-bis over IP as used by the ip.access nanoBTS product family
You can find the project documentation at http://openbsc.gnumonks.org/
This project is still in its early days, and there are lots of areas where it
doesn't behave as per GSM spec.

View File

@@ -1,9 +1,6 @@
dnl Process this file with autoconf to produce a configure script
AC_INIT([openbsc],
m4_esyscmd([./git-version-gen .tarball-version]),
[openbsc-devel@lists.openbsc.org])
AM_INIT_AUTOMAKE([dist-bzip2])
AC_INIT(openbsc, 0.3.99.20onwaves)
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
dnl kernel style compile messages
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
@@ -17,34 +14,9 @@ AC_PROG_RANLIB
dnl checks for libraries
AC_SEARCH_LIBS(crypt, crypt,
[LIBCRYPT="-lcrypt"; AC_DEFINE([VTY_CRYPT_PW], [], [Use crypt functionality of vty.])])
AC_SEARCH_LIBS(gtp_new, gtp,
[LIBCRYPT="-lgtp"; AC_SUBST([GPRS_LIBGTP], [1])])
AM_CONDITIONAL(HAVE_LIBGTP, test "x$GPRS_LIBGTP" != "x")
AC_ARG_ENABLE([nat], [AS_HELP_STRING([--enable-nat], [Build the BSC NAT. Requires SCCP])],
[
PKG_CHECK_MODULES(LIBOSMOSCCP, libosmo-sccp >= 0.0.2)
osmo_ac_build_nat="yes"
],
[
osmo_ac_build_nat="no"
])
AM_CONDITIONAL(BUILD_NAT, test "x$osmo_ac_build_nat" = "xyes")
AC_ARG_ENABLE([osmo-bsc], [AS_HELP_STRING([--enable-osmo-bsc], [Build the Osmo BSC])],
[
PKG_CHECK_MODULES(LIBOSMOSCCP, libosmo-sccp >= 0.0.2)
osmo_ac_build_bsc="yes"
],
[
osmo_ac_build_bsc="no"
])
AM_CONDITIONAL(BUILD_BSC, test "x$osmo_ac_build_bsc" = "xyes")
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.1.16)
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.1.9)
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.1.23)
PKG_CHECK_MODULES(LIBOSMOSCCP, libosmo-sccp >= 0.0.3)
dnl checks for header files
AC_HEADER_STDC
@@ -69,16 +41,12 @@ AM_CONFIG_HEADER(bscconfig.h)
AC_OUTPUT(
openbsc.pc
include/openbsc/Makefile
include/vty/Makefile
include/Makefile
src/Makefile
src/ipaccess/Makefile
src/gprs/Makefile
src/nat/Makefile
src/bsc/Makefile
tests/Makefile
tests/debug/Makefile
tests/gsm0408/Makefile
tests/db/Makefile
tests/channel/Makefile
tests/bsc-nat/Makefile
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

@@ -1,58 +0,0 @@
#!/usr/bin/env python
"""
demonstrate a unblock bug on the GB Proxy..
"""
bts_ns_reset = "\x02\x00\x81\x01\x01\x82\x1f\xe7\x04\x82\x1f\xe7"
ns_reset_ack = "\x03\x01\x82\x1f\xe7\x04\x82\x1f\xe7"
bts_ns_unblock = "\x06"
ns_unblock_ack = "\x07"
bts_bvc_reset_0 = "\x00\x00\x00\x00\x22\x04\x82\x00\x00\x07\x81\x03\x3b\x81\x02"
ns_bvc_reset_0_ack = "\x00\x00\x00\x00\x23\x04\x82\x00\x00"
bts_bvc_reset_8167 = "\x00\x00\x00\x00\x22\x04\x82\x1f\xe7\x07\x81\x08\x08\x88\x72\xf4\x80\x10\x1c\x00\x9c\x40"
import socket
socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
socket.bind(("0.0.0.0", 0))
socket.setblocking(1)
import sys
port = int(sys.argv[1])
print "Sending data to port: %d" % port
def send_and_receive(packet):
socket.sendto(packet, ("127.0.0.1", port))
try:
data, addr = socket.recvfrom(4096)
except socket.error, e:
print "ERROR", e
import sys
sys.exit(0)
return data
#send stuff once
to_send = [
(bts_ns_reset, ns_reset_ack, "reset ack"),
(bts_ns_unblock, ns_unblock_ack, "unblock ack"),
(bts_bvc_reset_0, ns_bvc_reset_0_ack, "BVCI=0 reset ack"),
]
for (out, inp, type) in to_send:
res = send_and_receive(out)
if res != inp:
print "Failed to get the %s" % type
sys.exit(-1)
import time
time.sleep(3)
res = send_and_receive(bts_bvc_reset_8167)
print "Sent all messages... check wireshark for the last response"

View File

@@ -1,78 +0,0 @@
-- Simple LUA script to print the size of BSSGP messages over their type...
do
local ip_bucket = {}
local pdu_types = {}
pdu_types[ 6] = "PAGING"
pdu_types[11] = "SUSPEND"
pdu_types[12] = "SUSPEND-ACK"
pdu_types[32] = "BVC-BLOCK"
pdu_types[33] = "BVC-BLOCK-ACK"
pdu_types[34] = "BVC-RESET"
pdu_types[35] = "BVC-RESET-ACK"
pdu_types[36] = "UNBLOCK"
pdu_types[37] = "UNBLOCK-ACK"
pdu_types[38] = "FLOW-CONTROL-BVC"
pdu_types[39] = "FLOW-CONTROL-BVC-ACK"
pdu_types[40] = "FLOW-CONTROL-MS"
pdu_types[41] = "FLOW-CONTROL-MS-ACK"
pdu_types[44] = "LLC-DISCARDED"
local function init_listener()
-- handle the port as NS over IP
local udp_port_table = DissectorTable.get("udp.port")
local gprs_ns_dis = Dissector.get("gprs_ns")
udp_port_table:add(23000,gprs_ns_dis)
-- bssgp filters
local bssgp_pdu_get = Field.new("bssgp.pdu_type")
local udp_length_get = Field.new("udp.length")
local tap = Listener.new("ip", "udp.port == 23000")
function tap.packet(pinfo,tvb,ip)
local pdu = bssgp_pdu_get()
local len = udp_length_get()
-- only handle bssgp, but we also want the IP frame
if not pdu then
return
end
pdu = tostring(pdu)
if tonumber(pdu) == 0 or tonumber(pdu) == 1 then
return
end
local ip_src = tostring(ip.ip_src)
local bssgp_histo = ip_bucket[ip_src]
if not bssgp_histo then
bssgp_histo = {}
ip_bucket[ip_src] = bssgp_histo
end
local key = pdu
local bucket = bssgp_histo[key]
if not bucket then
bucket = {}
bssgp_histo[key] = bucket
end
table.insert(bucket, tostring(len))
print("IP: " .. ip_src .. " PDU: " .. pdu_types[tonumber(pdu)] .. " Length: " .. tostring(len))
end
function tap.draw()
-- well... this will not be called...
-- for ip,bssgp_histo in pairs(dumpers) do
-- print("IP " .. ip)
-- end
end
function tap.reset()
-- well... this will not be called...
end
end
init_listener()
end

View File

@@ -1,46 +0,0 @@
-- Create a file named by_ip/''ip_addess''.cap with all ip traffic of each ip host. (works for tshark only)
-- Dump files are created for both source and destination hosts
do
local dir = "by_tlli"
local dumpers = {}
local function init_listener()
local udp_port_table = DissectorTable.get("udp.port")
local gprs_ns_dis = Dissector.get("gprs_ns")
udp_port_table:add(23000,gprs_ns_dis)
local field_tlli = Field.new("bssgp.tlli")
local tap = Listener.new("ip", "udp.port == 23000")
-- we will be called once for every IP Header.
-- If there's more than one IP header in a given packet we'll dump the packet once per every header
function tap.packet(pinfo,tvb,ip)
local tlli = field_tlli()
if not tlli then
return
end
local tlli_str = tostring(tlli)
tlli_dmp = dumpers[tlli_str]
if not tlli_dmp then
local tlli_hex = string.format("0x%x", tonumber(tlli_str))
print("Creating dump for TLLI " .. tlli_hex)
tlli_dmp = Dumper.new_for_current(dir .. "/" .. tlli_hex .. ".pcap")
dumpers[tlli_str] = tlli_dmp
end
tlli_dmp:dump_current()
tlli_dmp:flush()
end
function tap.draw()
for tlli,dumper in pairs(dumpers) do
dumper:flush()
end
end
function tap.reset()
for tlli,dumper in pairs(dumpers) do
dumper:close()
end
dumpers = {}
end
end
init_listener()
end

View File

@@ -1,59 +0,0 @@
-- This script verifies that the N(U) is increasing...
--
do
local nu_state_src = {}
local function init_listener()
-- handle the port as NS over IP
local udp_port_table = DissectorTable.get("udp.port")
local gprs_ns_dis = Dissector.get("gprs_ns")
udp_port_table:add(23000,gprs_ns_dis)
-- we want to look here...
local llc_sapi_get = Field.new("llcgprs.sapib")
local llc_nu_get = Field.new("llcgprs.nu")
local bssgp_tlli_get = Field.new("bssgp.tlli")
local tap = Listener.new("ip", "udp.port == 23000")
function tap.packet(pinfo,tvb,ip)
local llc_sapi = llc_sapi_get()
local llc_nu = llc_nu_get()
local bssgp_tlli = bssgp_tlli_get()
if not llc_sapi or not llc_nu or not bssgp_tlli then
return
end
local ip_src = tostring(ip.ip_src)
local bssgp_tlli = tostring(bssgp_tlli)
local llc_nu = tostring(llc_nu)
local llc_sapi = tostring(llc_sapi)
local src_key = ip_src .. "-" .. bssgp_tlli .. "-" .. llc_sapi
local last_nu = nu_state_src[src_key]
if not last_nu then
-- print("Establishing mapping for " .. src_key)
nu_state_src[src_key] = llc_nu
return
end
local function tohex(number)
return string.format("0x%x", tonumber(number))
end
nu_state_src[src_key] = llc_nu
if tonumber(last_nu) + 1 ~= tonumber(llc_nu) then
print("JUMP in N(U) on TLLI " .. tohex(bssgp_tlli) .. " and SAPI: " .. llc_sapi .. " src: " .. ip_src)
print("\t last: " .. last_nu .. " now: " .. llc_nu)
end
end
function tap.draw()
end
function tap.reset()
end
end
init_listener()
end

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

@@ -31,8 +31,6 @@ GSM 04.08 3.4.13: RR connection release procedure
== Implementation in OpenBSC ==
THIS IS OUTDATED and will be updated...
chan_alloc.c:lchan_auto_release()
* checks if use count still > 0 (abort)
* calls gsm48_send_rr_release()

View File

@@ -1,3 +1,3 @@
SUBDIRS = openbsc
SUBDIRS = openbsc vty
noinst_HEADERS = mISDNif.h compat_af_isdn.h

View File

@@ -1,16 +1,13 @@
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 paging.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 \
vty.h socket.h \
crc24.h gprs_bssgp.h gprs_llc.h gprs_ns.h gprs_gmm.h \
gb_proxy.h gprs_sgsn.h gsm_04_08_gprs.h sgsn.h \
gprs_ns_frgre.h auth.h osmo_msc.h bsc_msc.h bsc_nat.h \
osmo_bsc_rf.h osmo_bsc.h network_listen.h bsc_nat_sccp.h
vty.h bssap.h bsc_msc.h bsc_nat.h osmo_bsc_rf.h \
osmo_bsc_grace.h
openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h
openbscdir = $(includedir)/openbsc

View File

@@ -106,7 +106,8 @@ int abis_nm_conn_mdrop_link(struct gsm_bts *bts, u_int8_t e1_port0, u_int8_t ts0
int abis_nm_perform_test(struct gsm_bts *bts, u_int8_t obj_class,
u_int8_t bts_nr, u_int8_t trx_nr, u_int8_t ts_nr,
u_int8_t test_nr, u_int8_t auton_report, struct msgb *msg);
u_int8_t test_nr, u_int8_t auton_report,
u_int8_t *phys_config, u_int16_t phys_config_len);
int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan);
@@ -171,6 +172,8 @@ 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);
void abis_nm_clear_queue(struct gsm_bts *bts);
int abis_nm_vty_init(void);

View File

@@ -68,7 +68,9 @@ unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans,
unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res);
u_int64_t str_to_imsi(const char *imsi_str);
u_int8_t lchan2chan_nr(const struct gsm_lchan *lchan);
int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id, u_int8_t reason);
int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id, u_int8_t release_reason);
int rsl_lchan_set_state(struct gsm_lchan *lchan, int);
int rsl_lchan_set_state(struct gsm_lchan *lchan, int);
@@ -85,9 +87,5 @@ int rsl_number_of_paging_subchannels(struct gsm_bts *bts);
int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db);
int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm);
/* SMSCB functionality */
int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
uint8_t cb_command, const uint8_t *data, int len);
#endif /* RSL_MT_H */

View File

@@ -1,10 +0,0 @@
#ifndef _AUTH_H
#define _AUTH_H
struct gsm_auth_tuple;
struct gsm_subscriber;
int auth_get_tuple_for_subscr(struct gsm_auth_tuple *atuple,
struct gsm_subscriber *subscr, int key_seq);
#endif /* _AUTH_H */

View File

@@ -1,38 +1,6 @@
/* GSM 08.08 like API for OpenBSC */
#ifndef OPENBSC_BSC_API_H
#define OPENBSC_BSC_API_H
#include "gsm_data.h"
#define BSC_API_CONN_POL_ACCEPT 0
#define BSC_API_CONN_POL_REJECT 1
struct bsc_api {
void (*sapi_n_reject)(struct gsm_subscriber_connection *conn, int dlci);
void (*cipher_mode_compl)(struct gsm_subscriber_connection *conn,
struct msgb *msg, uint8_t chosen_encr);
void (*cipher_mode_reject)(struct gsm_subscriber_connection *conn,
struct msgb *msg, uint16_t reason);
int (*compl_l3)(struct gsm_subscriber_connection *conn,
struct msgb *msg, uint16_t chosen_channel);
void (*dtap)(struct gsm_subscriber_connection *conn, struct msgb *msg);
void (*assign_compl)(struct gsm_subscriber_connection *conn,
uint16_t rr_cause);
void (*assign_fail)(struct gsm_subscriber_connection *conn,
uint16_t rr_cause);
void (*clear_request)(struct gsm_subscriber_connection *conn,
uint32_t cause);
void (*clear_compl)(struct gsm_subscriber_connection *conn);
};
int bsc_api_init(struct gsm_network *network, struct bsc_api *api);
int gsm0808_submit_dtap(struct gsm_subscriber_connection *conn, struct msgb *msg, int link_id);
int gsm0808_assign_req(struct gsm_subscriber_connection *conn, int chan_type, int audio);
int gsm0808_cipher_mode(struct gsm_subscriber_connection *conn, int cipher,
uint8_t *key, int len);
int gsm0808_page(struct gsm_bts *bts, unsigned int page_group,
unsigned int mi_len, uint8_t *mi, int chan_type);
int gsm0808_clear(struct gsm_subscriber_connection *conn);
#endif

View File

@@ -30,7 +30,6 @@ struct bsc_msc_connection {
struct write_queue write_queue;
int is_connected;
int is_authenticated;
int first_contact;
const char *ip;
int port;
int prio;

View File

@@ -25,12 +25,12 @@
#include "mgcp.h"
#include <sys/types.h>
#include <osmocom/sccp/sccp_types.h>
#include <osmocore/select.h>
#include <osmocore/msgb.h>
#include <osmocore/timer.h>
#include <osmocore/write_queue.h>
#include <osmocore/rate_ctr.h>
#include <osmocore/statistics.h>
#include <regex.h>
@@ -40,8 +40,6 @@
#define NAT_IPAC_PROTO_MGCP 0xfc
struct sccp_connections;
struct bsc_nat_parsed;
struct bsc_nat;
enum {
@@ -53,6 +51,39 @@ enum {
NAT_CON_TYPE_OTHER,
};
/*
* For the NAT we will need to analyze and later patch
* the received message. This would require us to parse
* the IPA and SCCP header twice. Instead of doing this
* we will have one analyze structure and have the patching
* and filter operate on the same structure.
*/
struct bsc_nat_parsed {
/* ip access prototype */
int ipa_proto;
/* source local reference */
struct sccp_source_reference *src_local_ref;
/* destination local reference */
struct sccp_source_reference *dest_local_ref;
/* called ssn number */
int called_ssn;
/* calling ssn number */
int calling_ssn;
/* sccp message type */
int sccp_type;
/* bssap type, e.g. 0 for BSS Management */
int bssap;
/* the gsm0808 message type */
int gsm_type;
};
/*
* Per BSC data structure
*/
@@ -79,19 +110,46 @@ struct bsc_connection {
struct bsc_nat *nat;
};
/*
* Per SCCP source local reference patch table. It needs to
* be updated on new SCCP connections, connection confirm and reject,
* and on the loss of the BSC connection.
*/
struct sccp_connections {
struct llist_head list_entry;
struct bsc_connection *bsc;
struct sccp_source_reference real_ref;
struct sccp_source_reference patched_ref;
struct sccp_source_reference remote_ref;
int has_remote_ref;
/* status */
int con_type;
int con_local;
/* GSM audio handling. That is 32 * multiplex + ts */
int crcx;
int msc_timeslot;
int bsc_timeslot;
/* timeout handling */
struct timespec creation_time;
};
/**
* Stats per BSC
*/
struct bsc_config_stats {
struct rate_ctr_group *ctrg;
};
struct {
struct counter *conn;
struct counter *calls;
} sccp;
enum bsc_cfg_ctr {
BCFG_CTR_SCCP_CONN,
BCFG_CTR_SCCP_CALLS,
BCFG_CTR_NET_RECONN,
BCFG_CTR_DROPPED_SCCP,
BCFG_CTR_DROPPED_CALLS,
struct {
struct counter *reconn;
} net;
};
/**
@@ -180,17 +238,18 @@ struct bsc_nat {
/* known BSC's */
struct llist_head bsc_configs;
int num_bsc;
int bsc_ip_dscp;
int bsc_ip_tos;
/* MGCP config */
struct mgcp_config *mgcp_cfg;
struct write_queue mgcp_queue;
uint8_t mgcp_msg[4096];
u_int8_t mgcp_msg[4096];
int mgcp_length;
/* msc things */
char *msc_ip;
int msc_port;
int first_contact;
struct bsc_msc_connection *msc_con;
char *token;
@@ -250,7 +309,7 @@ struct sccp_connections *patch_sccp_src_ref_to_msc(struct msgb *, struct bsc_nat
/**
* MGCP/Audio handling
*/
int bsc_write_mgcp(struct bsc_connection *bsc, const uint8_t *data, unsigned int length);
int bsc_write_mgcp(struct bsc_connection *bsc, const u_int8_t *data, unsigned int length);
int bsc_mgcp_assign(struct sccp_connections *, struct msgb *msg);
void bsc_mgcp_init(struct sccp_connections *);
void bsc_mgcp_dlcx(struct sccp_connections *);
@@ -263,7 +322,7 @@ void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg);
void bsc_mgcp_clear_endpoints_for(struct bsc_connection *bsc);
int bsc_mgcp_parse_response(const char *str, int *code, char transaction[60]);
int bsc_mgcp_extract_ci(const char *resp);
uint32_t bsc_mgcp_extract_ci(const char *resp);
int bsc_write(struct bsc_connection *bsc, struct msgb *msg, int id);
@@ -276,6 +335,4 @@ void bsc_nat_acc_lst_delete(struct bsc_nat_acc_lst *lst);
struct bsc_nat_acc_lst_entry *bsc_nat_acc_lst_entry_create(struct bsc_nat_acc_lst *);
int bsc_nat_msc_is_connected(struct bsc_nat *nat);
#endif

View File

@@ -1,92 +0,0 @@
/* NAT utilities using SCCP types */
/*
* (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
* (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.
*
*/
#ifndef BSC_NAT_SCCP_H
#define BSC_NAT_SCCP_H
#include <sys/types.h>
#include <osmocom/sccp/sccp_types.h>
/*
* For the NAT we will need to analyze and later patch
* the received message. This would require us to parse
* the IPA and SCCP header twice. Instead of doing this
* we will have one analyze structure and have the patching
* and filter operate on the same structure.
*/
struct bsc_nat_parsed {
/* ip access prototype */
int ipa_proto;
/* source local reference */
struct sccp_source_reference *src_local_ref;
/* destination local reference */
struct sccp_source_reference *dest_local_ref;
/* called ssn number */
int called_ssn;
/* calling ssn number */
int calling_ssn;
/* sccp message type */
int sccp_type;
/* bssap type, e.g. 0 for BSS Management */
int bssap;
/* the gsm0808 message type */
int gsm_type;
};
/*
* Per SCCP source local reference patch table. It needs to
* be updated on new SCCP connections, connection confirm and reject,
* and on the loss of the BSC connection.
*/
struct sccp_connections {
struct llist_head list_entry;
struct bsc_connection *bsc;
struct bsc_msc_connection *msc_con;
struct sccp_source_reference real_ref;
struct sccp_source_reference patched_ref;
struct sccp_source_reference remote_ref;
int has_remote_ref;
/* status */
int con_type;
int con_local;
/* GSM audio handling. That is 32 * multiplex + ts */
int crcx;
int msc_timeslot;
int bsc_timeslot;
/* timeout handling */
struct timespec creation_time;
};
#endif

View File

@@ -0,0 +1,40 @@
/* From GSM08.08 */
#ifndef BSSAP_H
#define BSSAP_H
#include <stdlib.h>
#include <osmocore/msgb.h>
#include <osmocore/protocol/gsm_08_08.h>
#include <openbsc/gsm_data.h>
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_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,7 +23,27 @@
#include "gsm_subscriber.h"
struct gsm_subscriber_connection;
/*
* Refcounting for the lchan. If the refcount drops to zero
* the channel will send a RSL release request.
*/
#define use_subscr_con(con) \
do { (con)->use_count++; \
DEBUGP(DREF, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) increases usage to: %d\n", \
(con)->lchan->ts->trx->bts->nr, (con)->lchan->ts->trx->nr, (con)->lchan->ts->nr, \
(con)->lchan->nr, (con)->use_count); \
} while(0);
#define put_subscr_con(con, reason) \
do { (con)->use_count--; \
DEBUGP(DREF, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) decreases usage to: %d\n", \
(con)->lchan->ts->trx->bts->nr, (con)->lchan->ts->trx->nr, (con)->lchan->ts->nr, \
(con)->lchan->nr, (con)->use_count); \
if ((con)->use_count <= 0) \
_lchan_release((con)->lchan, reason); \
} while(0);
/* Special allocator for C0 of BTS */
struct gsm_bts_trx_ts *ts_c0_alloc(struct gsm_bts *bts,
@@ -36,18 +56,21 @@ struct gsm_bts_trx_ts *ts_alloc(struct gsm_bts *bts,
/* Regular physical channel (TS) */
void ts_free(struct gsm_bts_trx_ts *ts);
/* Find an allocated channel */
struct gsm_lchan *lchan_find(struct gsm_bts *bts, struct gsm_subscriber *subscr);
/* Find an allocated channel for a specified subscriber */
struct gsm_subscriber_connection *connection_for_subscr(struct gsm_subscriber *subscr);
struct gsm_lchan *lchan_for_subscr(struct gsm_subscriber *subscr);
/* Allocate a logical channel (SDCCH, TCH, ...) */
struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type);
struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type, int allow_bigger);
/* Free a logical channel (SDCCH, TCH, ...) */
void lchan_free(struct gsm_lchan *lchan);
void lchan_reset(struct gsm_lchan *lchan);
/* Release the given lchan */
int lchan_release(struct gsm_lchan *lchan, int sach_deact, int reason);
/* internal.. do not use */
int _lchan_release(struct gsm_lchan *lchan, u_int8_t release_reason);
struct load_counter {
unsigned int total;

View File

@@ -1,8 +0,0 @@
#ifndef _CRC24_H
#define _CRC24_H
#define INIT_CRC24 0xffffff
u_int32_t crc24_calc(u_int32_t fcs, u_int8_t *cp, unsigned int len);
#endif

View File

@@ -44,14 +44,14 @@ int db_subscriber_assoc_imei(struct gsm_subscriber* subscriber, char *imei);
int db_sync_equipment(struct gsm_equipment *equip);
/* auth info */
int db_get_authinfo_for_subscr(struct gsm_auth_info *ainfo,
struct gsm_subscriber *subscr);
int db_sync_authinfo_for_subscr(struct gsm_auth_info *ainfo,
struct gsm_subscriber *subscr);
int db_get_lastauthtuple_for_subscr(struct gsm_auth_tuple *atuple,
struct gsm_subscriber *subscr);
int db_sync_lastauthtuple_for_subscr(struct gsm_auth_tuple *atuple,
struct gsm_subscriber *subscr);
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);
@@ -66,9 +66,6 @@ int db_apdu_blob_store(struct gsm_subscriber *subscr,
u_int8_t *apdu);
/* Statistics counter storage */
struct counter;
int db_store_counter(struct counter *ctr);
struct rate_ctr_group;
int db_store_rate_ctr_group(struct rate_ctr_group *ctrg);
#endif /* _DB_H */

View File

@@ -29,11 +29,6 @@ enum {
DHO,
DDB,
DREF,
DGPRS,
DNS,
DBSSGP,
DLLC,
DSNDCP,
DNAT,
Debug_LastEntry,
};
@@ -43,27 +38,15 @@ enum {
#define BSC_CTX_SUBSCR 1
#define BSC_CTX_BTS 2
#define BSC_CTX_SCCP 3
#define BSC_CTX_NSVC 4
#define BSC_CTX_BVC 5
/* target */
enum {
//DEBUG_FILTER_ALL = 1 << 0,
LOG_FILTER_IMSI = 1 << 1,
LOG_FILTER_NSVC = 1 << 2,
LOG_FILTER_BVC = 1 << 3,
};
/* we don't need a header dependency for this... */
struct gprs_nsvc;
struct bssgp_bvc_ctx;
void log_set_imsi_filter(struct log_target *target, const char *imsi);
void log_set_nsvc_filter(struct log_target *target,
struct gprs_nsvc *nsvc);
void log_set_bvc_filter(struct log_target *target,
struct bssgp_bvc_ctx *bctx);
extern const struct log_info log_info;

View File

@@ -66,6 +66,8 @@ struct e1inp_ts {
struct {
/* list of all signalling links on this TS */
struct llist_head sign_links;
/* delay for the queue */
int delay;
/* timer when to dequeue next frame */
struct timer_list tx_timer;
} sign;
@@ -93,6 +95,7 @@ struct e1inp_driver {
struct llist_head list;
const char *name;
int (*want_write)(struct e1inp_ts *ts);
int default_delay;
};
struct e1inp_line {

View File

@@ -1,39 +0,0 @@
#ifndef _GB_PROXY_H
#define _GB_PROXY_H
#include <sys/types.h>
#include <osmocore/msgb.h>
#include <openbsc/gprs_ns.h>
#include <osmocom/vty/command.h>
struct gbproxy_config {
/* parsed from config file */
u_int16_t nsip_sgsn_nsei;
/* misc */
struct gprs_ns_inst *nsi;
};
extern struct gbproxy_config gbcfg;
extern struct cmd_element show_gbproxy_cmd;
/* gb_proxy_vty .c */
int gbproxy_vty_init(void);
int gbproxy_parse_config(const char *config_file, struct gbproxy_config *cfg);
/* gb_proxy.c */
/* Main input function for Gb proxy */
int gbprox_rcvmsg(struct msgb *msg, struct gprs_nsvc *nsvc, uint16_t ns_bvci);
int gbprox_signal(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data);
/* Reset all persistent NS-VC's */
int gbprox_reset_persistent_nsvcs(struct gprs_ns_inst *nsi);
#endif

View File

@@ -1,232 +0,0 @@
#ifndef _GPRS_BSSGP_H
#define _GPRS_BSSGP_H
#include <stdint.h>
/* Section 5.4.1 */
#define BVCI_SIGNALLING 0x0000
#define BVCI_PTM 0x0001
/* Section 11.3.26 / Table 11.27 */
enum bssgp_pdu_type {
/* PDUs between RL and BSSGP SAPs */
BSSGP_PDUT_DL_UNITDATA = 0x00,
BSSGP_PDUT_UL_UNITDATA = 0x01,
BSSGP_PDUT_RA_CAPABILITY = 0x02,
BSSGP_PDUT_PTM_UNITDATA = 0x03,
/* PDUs between GMM SAPs */
BSSGP_PDUT_PAGING_PS = 0x06,
BSSGP_PDUT_PAGING_CS = 0x07,
BSSGP_PDUT_RA_CAPA_UDPATE = 0x08,
BSSGP_PDUT_RA_CAPA_UPDATE_ACK = 0x09,
BSSGP_PDUT_RADIO_STATUS = 0x0a,
BSSGP_PDUT_SUSPEND = 0x0b,
BSSGP_PDUT_SUSPEND_ACK = 0x0c,
BSSGP_PDUT_SUSPEND_NACK = 0x0d,
BSSGP_PDUT_RESUME = 0x0e,
BSSGP_PDUT_RESUME_ACK = 0x0f,
BSSGP_PDUT_RESUME_NACK = 0x10,
/* PDus between NM SAPs */
BSSGP_PDUT_BVC_BLOCK = 0x20,
BSSGP_PDUT_BVC_BLOCK_ACK = 0x21,
BSSGP_PDUT_BVC_RESET = 0x22,
BSSGP_PDUT_BVC_RESET_ACK = 0x23,
BSSGP_PDUT_BVC_UNBLOCK = 0x24,
BSSGP_PDUT_BVC_UNBLOCK_ACK = 0x25,
BSSGP_PDUT_FLOW_CONTROL_BVC = 0x26,
BSSGP_PDUT_FLOW_CONTROL_BVC_ACK = 0x27,
BSSGP_PDUT_FLOW_CONTROL_MS = 0x28,
BSSGP_PDUT_FLOW_CONTROL_MS_ACK = 0x29,
BSSGP_PDUT_FLUSH_LL = 0x2a,
BSSGP_PDUT_FLUSH_LL_ACK = 0x2b,
BSSGP_PDUT_LLC_DISCARD = 0x2c,
BSSGP_PDUT_SGSN_INVOKE_TRACE = 0x40,
BSSGP_PDUT_STATUS = 0x41,
/* PDUs between PFM SAP's */
BSSGP_PDUT_DOWNLOAD_BSS_PFC = 0x50,
BSSGP_PDUT_CREATE_BSS_PFC = 0x51,
BSSGP_PDUT_CREATE_BSS_PFC_ACK = 0x52,
BSSGP_PDUT_CREATE_BSS_PFC_NACK = 0x53,
BSSGP_PDUT_MODIFY_BSS_PFC = 0x54,
BSSGP_PDUT_MODIFY_BSS_PFC_ACK = 0x55,
BSSGP_PDUT_DELETE_BSS_PFC = 0x56,
BSSGP_PDUT_DELETE_BSS_PFC_ACK = 0x57,
};
/* Section 10.2.1 and 10.2.2 */
struct bssgp_ud_hdr {
uint8_t pdu_type;
uint32_t tlli;
uint8_t qos_profile[3];
uint8_t data[0]; /* TLV's */
} __attribute__((packed));
struct bssgp_normal_hdr {
uint8_t pdu_type;
uint8_t data[0]; /* TLV's */
};
enum bssgp_iei_type {
BSSGP_IE_ALIGNMENT = 0x00,
BSSGP_IE_BMAX_DEFAULT_MS = 0x01,
BSSGP_IE_BSS_AREA_ID = 0x02,
BSSGP_IE_BUCKET_LEAK_RATE = 0x03,
BSSGP_IE_BVCI = 0x04,
BSSGP_IE_BVC_BUCKET_SIZE = 0x05,
BSSGP_IE_BVC_MEASUREMENT = 0x06,
BSSGP_IE_CAUSE = 0x07,
BSSGP_IE_CELL_ID = 0x08,
BSSGP_IE_CHAN_NEEDED = 0x09,
BSSGP_IE_DRX_PARAMS = 0x0a,
BSSGP_IE_EMLPP_PRIO = 0x0b,
BSSGP_IE_FLUSH_ACTION = 0x0c,
BSSGP_IE_IMSI = 0x0d,
BSSGP_IE_LLC_PDU = 0x0e,
BSSGP_IE_LLC_FRAMES_DISCARDED = 0x0f,
BSSGP_IE_LOCATION_AREA = 0x10,
BSSGP_IE_MOBILE_ID = 0x11,
BSSGP_IE_MS_BUCKET_SIZE = 0x12,
BSSGP_IE_MS_RADIO_ACCESS_CAP = 0x13,
BSSGP_IE_OMC_ID = 0x14,
BSSGP_IE_PDU_IN_ERROR = 0x15,
BSSGP_IE_PDU_LIFETIME = 0x16,
BSSGP_IE_PRIORITY = 0x17,
BSSGP_IE_QOS_PROFILE = 0x18,
BSSGP_IE_RADIO_CAUSE = 0x19,
BSSGP_IE_RA_CAP_UPD_CAUSE = 0x1a,
BSSGP_IE_ROUTEING_AREA = 0x1b,
BSSGP_IE_R_DEFAULT_MS = 0x1c,
BSSGP_IE_SUSPEND_REF_NR = 0x1d,
BSSGP_IE_TAG = 0x1e,
BSSGP_IE_TLLI = 0x1f,
BSSGP_IE_TMSI = 0x20,
BSSGP_IE_TRACE_REFERENC = 0x21,
BSSGP_IE_TRACE_TYPE = 0x22,
BSSGP_IE_TRANSACTION_ID = 0x23,
BSSGP_IE_TRIGGER_ID = 0x24,
BSSGP_IE_NUM_OCT_AFF = 0x25,
BSSGP_IE_LSA_ID_LIST = 0x26,
BSSGP_IE_LSA_INFORMATION = 0x27,
BSSGP_IE_PACKET_FLOW_ID = 0x28,
BSSGP_IE_PACKET_FLOW_TIMER = 0x29,
BSSGP_IE_AGG_BSS_QOS_PROFILE = 0x3a,
BSSGP_IE_FEATURE_BITMAP = 0x3b,
BSSGP_IE_BUCKET_FULL_RATIO = 0x3c,
BSSGP_IE_SERVICE_UTRAN_CCO = 0x3d,
};
/* Section 11.3.8 / Table 11.10: Cause coding */
enum gprs_bssgp_cause {
BSSGP_CAUSE_PROC_OVERLOAD = 0x00,
BSSGP_CAUSE_EQUIP_FAIL = 0x01,
BSSGP_CAUSE_TRASIT_NET_FAIL = 0x02,
BSSGP_CAUSE_CAPA_GREATER_0KPBS = 0x03,
BSSGP_CAUSE_UNKNOWN_MS = 0x04,
BSSGP_CAUSE_UNKNOWN_BVCI = 0x05,
BSSGP_CAUSE_CELL_TRAF_CONG = 0x06,
BSSGP_CAUSE_SGSN_CONG = 0x07,
BSSGP_CAUSE_OML_INTERV = 0x08,
BSSGP_CAUSE_BVCI_BLOCKED = 0x09,
BSSGP_CAUSE_PFC_CREATE_FAIL = 0x0a,
BSSGP_CAUSE_SEM_INCORR_PDU = 0x20,
BSSGP_CAUSE_INV_MAND_INF = 0x21,
BSSGP_CAUSE_MISSING_MAND_IE = 0x22,
BSSGP_CAUSE_MISSING_COND_IE = 0x23,
BSSGP_CAUSE_UNEXP_COND_IE = 0x24,
BSSGP_CAUSE_COND_IE_ERR = 0x25,
BSSGP_CAUSE_PDU_INCOMP_STATE = 0x26,
BSSGP_CAUSE_PROTO_ERR_UNSPEC = 0x27,
BSSGP_CAUSE_PDU_INCOMP_FEAT = 0x28,
};
/* Our implementation */
/* gprs_bssgp_util.c */
extern struct gprs_ns_inst *bssgp_nsi;
struct msgb *bssgp_msgb_alloc(void);
const char *bssgp_cause_str(enum gprs_bssgp_cause cause);
/* Transmit a simple response such as BLOCK/UNBLOCK/RESET ACK/NACK */
int bssgp_tx_simple_bvci(uint8_t pdu_type, uint16_t nsei,
uint16_t bvci, uint16_t ns_bvci);
/* Chapter 10.4.14: Status */
int bssgp_tx_status(uint8_t cause, uint16_t *bvci, struct msgb *orig_msg);
/* gprs_bssgp.c */
#define BVC_S_BLOCKED 0x0001
/* The per-BTS context that we keep on the SGSN side of the BSSGP link */
struct bssgp_bvc_ctx {
struct llist_head list;
/* parsed RA ID and Cell ID of the remote BTS */
struct gprs_ra_id ra_id;
uint16_t cell_id;
/* NSEI and BVCI of underlying Gb link. Together they
* uniquely identify a link to a BTS (5.4.4) */
uint16_t bvci;
uint16_t nsei;
uint32_t state;
struct rate_ctr_group *ctrg;
/* we might want to add this as a shortcut later, avoiding the NSVC
* lookup for every packet, similar to a routing cache */
//struct gprs_nsvc *nsvc;
};
extern struct llist_head bssgp_bvc_ctxts;
/* Find a BTS Context based on parsed RA ID and Cell ID */
struct bssgp_bvc_ctx *btsctx_by_raid_cid(const struct gprs_ra_id *raid, uint16_t cid);
/* Find a BTS context based on BVCI+NSEI tuple */
struct bssgp_bvc_ctx *btsctx_by_bvci_nsei(uint16_t bvci, uint16_t nsei);
#include <osmocore/tlv.h>
/* BSSGP-UL-UNITDATA.ind */
int gprs_bssgp_rcvmsg(struct msgb *msg);
/* BSSGP-DL-UNITDATA.req */
struct sgsn_mm_ctx;
int gprs_bssgp_tx_dl_ud(struct msgb *msg, struct sgsn_mm_ctx *mmctx);
uint16_t bssgp_parse_cell_id(struct gprs_ra_id *raid, const uint8_t *buf);
/* Wrapper around TLV parser to parse BSSGP IEs */
static inline int bssgp_tlv_parse(struct tlv_parsed *tp, uint8_t *buf, int len)
{
return tlv_parse(tp, &tvlv_att_def, buf, len, 0, 0);
}
enum bssgp_paging_mode {
BSSGP_PAGING_PS,
BSSGP_PAGING_CS,
};
enum bssgp_paging_scope {
BSSGP_PAGING_BSS_AREA, /* all cells in BSS */
BSSGP_PAGING_LOCATION_AREA, /* all cells in LA */
BSSGP_PAGING_ROUTEING_AREA, /* all cells in RA */
BSSGP_PAGING_BVCI, /* one cell */
};
struct bssgp_paging_info {
enum bssgp_paging_mode mode;
enum bssgp_paging_scope scope;
struct gprs_ra_id raid;
uint16_t bvci;
const char *imsi;
uint32_t *ptmsi;
uint16_t drx_params;
uint8_t qos[3];
};
/* Send a single GMM-PAGING.req to a given NSEI/NS-BVCI */
int gprs_bssgp_tx_paging(uint16_t nsei, uint16_t ns_bvci,
struct bssgp_paging_info *pinfo);
/* gprs_bssgp_vty.c */
int gprs_bssgp_vty_init(void);
#endif /* _GPRS_BSSGP_H */

View File

@@ -1,18 +0,0 @@
#ifndef _GPRS_GMM_H
#define _GPRS_GMM_H
#include <osmocore/msgb.h>
#include <openbsc/gprs_sgsn.h>
int gsm48_tx_gsm_act_pdp_rej(struct sgsn_mm_ctx *mm, uint8_t tid,
uint8_t cause, uint8_t pco_len, uint8_t *pco_v);
int gsm48_tx_gsm_act_pdp_acc(struct sgsn_pdp_ctx *pdp);
int gsm48_tx_gsm_deact_pdp_acc(struct sgsn_pdp_ctx *pdp);
int gsm0408_gprs_rcvmsg(struct msgb *msg, struct gprs_llc_llme *llme);
int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli);
int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli,
uint8_t suspend_ref);
#endif /* _GPRS_GMM_H */

View File

@@ -1,162 +0,0 @@
#ifndef _GPRS_LLC_H
#define _GPRS_LLC_H
#include <stdint.h>
#include <openbsc/gprs_sgsn.h>
/* Section 4.7 LLC Layer Structure */
enum gprs_llc_sapi {
GPRS_SAPI_GMM = 1,
GPRS_SAPI_TOM2 = 2,
GPRS_SAPI_SNDCP3 = 3,
GPRS_SAPI_SNDCP5 = 5,
GPRS_SAPI_SMS = 7,
GPRS_SAPI_TOM8 = 8,
GPRS_SAPI_SNDCP9 = 9,
GPRS_SAPI_SNDCP11 = 11,
};
/* Section 6.4 Commands and Responses */
enum gprs_llc_u_cmd {
GPRS_LLC_U_DM_RESP = 0x01,
GPRS_LLC_U_DISC_CMD = 0x04,
GPRS_LLC_U_UA_RESP = 0x06,
GPRS_LLC_U_SABM_CMD = 0x07,
GPRS_LLC_U_FRMR_RESP = 0x08,
GPRS_LLC_U_XID = 0x0b,
GPRS_LLC_U_NULL_CMD = 0x00,
};
/* TS 04.64 Section 7.1.2 Table 7: LLC layer primitives (GMM/SNDCP/SMS/TOM) */
/* TS 04.65 Section 5.1.2 Table 2: Service primitives used by SNDCP */
enum gprs_llc_primitive {
/* GMM <-> LLME */
LLGMM_ASSIGN_REQ, /* GMM tells us new TLLI: TLLI old, TLLI new, Kc, CiphAlg */
LLGMM_RESET_REQ, /* GMM tells us to perform XID negotiation: TLLI */
LLGMM_RESET_CNF, /* LLC informs GMM that XID has completed: TLLI */
LLGMM_SUSPEND_REQ, /* GMM tells us MS has suspended: TLLI, Page */
LLGMM_RESUME_REQ, /* GMM tells us MS has resumed: TLLI */
LLGMM_PAGE_IND, /* LLC asks GMM to page MS: TLLI */
LLGMM_IOV_REQ, /* GMM tells us to perform XID: TLLI */
LLGMM_STATUS_IND, /* LLC informs GMM about error: TLLI, Cause */
/* LLE <-> (GMM/SNDCP/SMS/TOM) */
LL_RESET_IND, /* TLLI */
LL_ESTABLISH_REQ, /* TLLI, XID Req */
LL_ESTABLISH_IND, /* TLLI, XID Req, N201-I, N201-U */
LL_ESTABLISH_RESP, /* TLLI, XID Negotiated */
LL_ESTABLISH_CONF, /* TLLI, XID Neg, N201-i, N201-U */
LL_RELEASE_REQ, /* TLLI, Local */
LL_RELEASE_IND, /* TLLI, Cause */
LL_RELEASE_CONF, /* TLLI */
LL_XID_REQ, /* TLLI, XID Requested */
LL_XID_IND, /* TLLI, XID Req, N201-I, N201-U */
LL_XID_RESP, /* TLLI, XID Negotiated */
LL_XID_CONF, /* TLLI, XID Neg, N201-I, N201-U */
LL_DATA_REQ, /* TLLI, SN-PDU, Ref, QoS, Radio Prio, Ciph */
LL_DATA_IND, /* TLLI, SN-PDU */
LL_DATA_CONF, /* TLLI, Ref */
LL_UNITDATA_REQ, /* TLLI, SN-PDU, Ref, QoS, Radio Prio, Ciph */
LL_UNITDATA_IND, /* TLLI, SN-PDU */
LL_STATUS_IND, /* TLLI, Cause */
};
/* Section 4.5.2 Logical Link States + Annex C.2 */
enum gprs_llc_lle_state {
GPRS_LLES_UNASSIGNED = 1, /* No TLLI yet */
GPRS_LLES_ASSIGNED_ADM = 2, /* TLLI assigned */
GPRS_LLES_LOCAL_EST = 3, /* Local Establishment */
GPRS_LLES_REMOTE_EST = 4, /* Remote Establishment */
GPRS_LLES_ABM = 5,
GPRS_LLES_LOCAL_REL = 6, /* Local Release */
GPRS_LLES_TIMER_REC = 7, /* Timer Recovery */
};
enum gprs_llc_llme_state {
GPRS_LLMS_UNASSIGNED = 1, /* No TLLI yet */
GPRS_LLMS_ASSIGNED = 2, /* TLLI assigned */
};
/* Section 8.9.9 LLC layer parameter default values */
struct gprs_llc_params {
uint16_t iov_i_exp;
uint16_t t200_201;
uint16_t n200;
uint16_t n201_u;
uint16_t n201_i;
uint16_t mD;
uint16_t mU;
uint16_t kD;
uint16_t kU;
};
/* Section 4.7.1: Logical Link Entity: One per DLCI (TLLI + SAPI) */
struct gprs_llc_lle {
struct llist_head list;
uint32_t sapi;
struct gprs_llc_llme *llme;
enum gprs_llc_lle_state state;
struct timer_list t200;
struct timer_list t201; /* wait for acknowledgement */
uint16_t v_sent;
uint16_t v_ack;
uint16_t v_recv;
uint16_t vu_send;
uint16_t vu_recv;
/* Overflow Counter for ABM */
uint32_t oc_i_send;
uint32_t oc_i_recv;
/* Overflow Counter for unconfirmed transfer */
uint32_t oc_ui_send;
uint32_t oc_ui_recv;
unsigned int retrans_ctr;
struct gprs_llc_params params;
};
#define NUM_SAPIS 16
struct gprs_llc_llme {
struct llist_head list;
enum gprs_llc_llme_state state;
uint32_t tlli;
uint32_t old_tlli;
/* Crypto parameters */
enum gprs_ciph_algo algo;
uint8_t kc[8];
/* over which BSSGP BTS ctx do we need to transmit */
uint16_t bvci;
uint16_t nsei;
struct gprs_llc_lle lle[NUM_SAPIS];
};
extern struct llist_head gprs_llc_llmes;
/* BSSGP-UL-UNITDATA.ind */
int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv);
/* LL-UNITDATA.req */
int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command,
void *mmctx);
/* 04.64 Chapter 7.2.1.1 LLGMM-ASSIGN */
int gprs_llgmm_assign(struct gprs_llc_llme *llme,
uint32_t old_tlli, uint32_t new_tlli,
enum gprs_ciph_algo alg, const uint8_t *kc);
int gprs_llc_init(const char *cipher_plugin_path);
int gprs_llc_vty_init(void);
#endif

View File

@@ -1,232 +0,0 @@
#ifndef _GPRS_NS_H
#define _GPRS_NS_H
#include <stdint.h>
/* GPRS Networks Service (NS) messages on the Gb interface
* 3GPP TS 08.16 version 8.0.1 Release 1999 / ETSI TS 101 299 V8.0.1 (2002-05)
* 3GPP TS 48.016 version 6.5.0 Release 6 / ETSI TS 148 016 V6.5.0 (2005-11) */
struct gprs_ns_hdr {
uint8_t pdu_type;
uint8_t data[0];
} __attribute__((packed));
/* TS 08.16, Section 10.3.7, Table 14 */
enum ns_pdu_type {
NS_PDUT_UNITDATA = 0x00,
NS_PDUT_RESET = 0x02,
NS_PDUT_RESET_ACK = 0x03,
NS_PDUT_BLOCK = 0x04,
NS_PDUT_BLOCK_ACK = 0x05,
NS_PDUT_UNBLOCK = 0x06,
NS_PDUT_UNBLOCK_ACK = 0x07,
NS_PDUT_STATUS = 0x08,
NS_PDUT_ALIVE = 0x0a,
NS_PDUT_ALIVE_ACK = 0x0b,
/* TS 48.016 Section 10.3.7, Table 10.3.7.1 */
SNS_PDUT_ACK = 0x0c,
SNS_PDUT_ADD = 0x0d,
SNS_PDUT_CHANGE_WEIGHT = 0x0e,
SNS_PDUT_CONFIG = 0x0f,
SNS_PDUT_CONFIG_ACK = 0x10,
SNS_PDUT_DELETE = 0x11,
SNS_PDUT_SIZE = 0x12,
SNS_PDUT_SIZE_ACK = 0x13,
};
/* TS 08.16, Section 10.3, Table 12 */
enum ns_ctrl_ie {
NS_IE_CAUSE = 0x00,
NS_IE_VCI = 0x01,
NS_IE_PDU = 0x02,
NS_IE_BVCI = 0x03,
NS_IE_NSEI = 0x04,
/* TS 48.016 Section 10.3, Table 10.3.1 */
NS_IE_IPv4_LIST = 0x05,
NS_IE_IPv6_LIST = 0x06,
NS_IE_MAX_NR_NSVC = 0x07,
NS_IE_IPv4_EP_NR = 0x08,
NS_IE_IPv6_EP_NR = 0x09,
NS_IE_RESET_FLAG = 0x0a,
NS_IE_IP_ADDR = 0x0b,
};
/* TS 08.16, Section 10.3.2, Table 13 */
enum ns_cause {
NS_CAUSE_TRANSIT_FAIL = 0x00,
NS_CAUSE_OM_INTERVENTION = 0x01,
NS_CAUSE_EQUIP_FAIL = 0x02,
NS_CAUSE_NSVC_BLOCKED = 0x03,
NS_CAUSE_NSVC_UNKNOWN = 0x04,
NS_CAUSE_BVCI_UNKNOWN = 0x05,
NS_CAUSE_SEM_INCORR_PDU = 0x08,
NS_CAUSE_PDU_INCOMP_PSTATE = 0x0a,
NS_CAUSE_PROTO_ERR_UNSPEC = 0x0b,
NS_CAUSE_INVAL_ESSENT_IE = 0x0c,
NS_CAUSE_MISSING_ESSENT_IE = 0x0d,
/* TS 48.016 Section 10.3.2, Table 10.3.2.1 */
NS_CAUSE_INVAL_NR_IPv4_EP = 0x0e,
NS_CAUSE_INVAL_NR_IPv6_EP = 0x0f,
NS_CAUSE_INVAL_NR_NS_VC = 0x10,
NS_CAUSE_INVAL_WEIGH = 0x11,
NS_CAUSE_UNKN_IP_EP = 0x12,
NS_CAUSE_UNKN_IP_ADDR = 0x13,
NS_CAUSE_UNKN_IP_TEST_FAILED = 0x14,
};
/* Our Implementation */
#include <netinet/in.h>
#include <osmocore/linuxlist.h>
#include <osmocore/msgb.h>
#include <osmocore/timer.h>
#include <osmocore/select.h>
#define NS_TIMERS_COUNT 7
#define NS_TIMERS "(tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries)"
#define NS_TIMERS_HELP \
"(un)blocking Timer (Tns-block) timeout\n" \
"(un)blocking Timer (Tns-block) number of retries\n" \
"Reset Timer (Tns-reset) timeout\n" \
"Reset Timer (Tns-reset) number of retries\n" \
"Test Timer (Tns-test) timeout\n" \
enum ns_timeout {
NS_TOUT_TNS_BLOCK,
NS_TOUT_TNS_BLOCK_RETRIES,
NS_TOUT_TNS_RESET,
NS_TOUT_TNS_RESET_RETRIES,
NS_TOUT_TNS_TEST,
NS_TOUT_TNS_ALIVE,
NS_TOUT_TNS_ALIVE_RETRIES,
};
#define NSE_S_BLOCKED 0x0001
#define NSE_S_ALIVE 0x0002
enum gprs_ns_ll {
GPRS_NS_LL_UDP,
GPRS_NS_LL_E1,
GPRS_NS_LL_FR_GRE,
};
enum gprs_ns_evt {
GPRS_NS_EVT_UNIT_DATA,
};
struct gprs_nsvc;
typedef int gprs_ns_cb_t(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
struct msgb *msg, uint16_t bvci);
/* An instance of the NS protocol stack */
struct gprs_ns_inst {
/* callback to the user for incoming UNIT DATA IND */
gprs_ns_cb_t *cb;
/* linked lists of all NSVC in this instance */
struct llist_head gprs_nsvcs;
/* a NSVC object that's needed to deal with packets for unknown NSVC */
struct gprs_nsvc *unknown_nsvc;
uint16_t timeout[NS_TIMERS_COUNT];
/* NS-over-IP specific bits */
struct {
struct bsc_fd fd;
uint32_t local_ip;
uint16_t local_port;
} nsip;
/* NS-over-FR-over-GRE-over-IP specific bits */
struct {
struct bsc_fd fd;
uint32_t local_ip;
int enabled:1;
} frgre;
};
enum nsvc_timer_mode {
/* standard timers */
NSVC_TIMER_TNS_TEST,
NSVC_TIMER_TNS_ALIVE,
NSVC_TIMER_TNS_RESET,
_NSVC_TIMER_NR,
};
struct gprs_nsvc {
struct llist_head list;
struct gprs_ns_inst *nsi;
uint16_t nsei; /* end-to-end significance */
uint16_t nsvci; /* uniquely identifies NS-VC at SGSN */
uint32_t state;
uint32_t remote_state;
struct timer_list timer;
enum nsvc_timer_mode timer_mode;
int alive_retries;
unsigned int remote_end_is_sgsn:1;
unsigned int persistent:1;
struct rate_ctr_group *ctrg;
/* which link-layer are we based on? */
enum gprs_ns_ll ll;
union {
struct {
struct sockaddr_in bts_addr;
} ip;
struct {
struct sockaddr_in bts_addr;
} frgre;
};
};
/* Create a new NS protocol instance */
struct gprs_ns_inst *gprs_ns_instantiate(gprs_ns_cb_t *cb);
/* Destroy a NS protocol instance */
void gprs_ns_destroy(struct gprs_ns_inst *nsi);
/* Listen for incoming GPRS packets via NS/UDP */
int gprs_ns_nsip_listen(struct gprs_ns_inst *nsi);
struct sockaddr_in;
/* main function for higher layers (BSSGP) to send NS messages */
int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg);
int gprs_ns_tx_reset(struct gprs_nsvc *nsvc, uint8_t cause);
int gprs_ns_tx_block(struct gprs_nsvc *nsvc, uint8_t cause);
int gprs_ns_tx_unblock(struct gprs_nsvc *nsvc);
/* Listen for incoming GPRS packets via NS/FR/GRE */
int gprs_ns_frgre_listen(struct gprs_ns_inst *nsi);
/* Establish a connection (from the BSS) to the SGSN */
struct gprs_nsvc *nsip_connect(struct gprs_ns_inst *nsi,
struct sockaddr_in *dest, uint16_t nsei,
uint16_t nsvci);
struct gprs_nsvc *nsvc_create(struct gprs_ns_inst *nsi, uint16_t nsvci);
void nsvc_delete(struct gprs_nsvc *nsvc);
struct gprs_nsvc *nsvc_by_nsei(struct gprs_ns_inst *nsi, uint16_t nsei);
struct gprs_nsvc *nsvc_by_nsvci(struct gprs_ns_inst *nsi, uint16_t nsvci);
/* Initiate a RESET procedure (including timer start, ...)*/
void gprs_nsvc_reset(struct gprs_nsvc *nsvc, uint8_t cause);
/* Add NS-specific VTY stuff */
int gprs_ns_vty_init(struct gprs_ns_inst *nsi);
#define NS_ALLOC_SIZE 2048
#define NS_ALLOC_HEADROOM 20
static inline struct msgb *gprs_ns_msgb_alloc(void)
{
return msgb_alloc_headroom(NS_ALLOC_SIZE, NS_ALLOC_HEADROOM, "GPRS/NS");
}
#endif

View File

@@ -1,6 +0,0 @@
#ifndef _GPRS_NS_FRGRE_H
#define _GPRS_NS_FRGRE_H
int gprs_ns_frgre_sendmsg(struct gprs_nsvc *nsvc, struct msgb *msg);
#endif

View File

@@ -1,205 +0,0 @@
#ifndef _GPRS_SGSN_H
#define _GPRS_SGSN_H
#include <stdint.h>
#include <netinet/in.h>
#include <osmocore/gsm48.h>
#include <osmocom/crypt/gprs_cipher.h>
#define GSM_IMSI_LENGTH 17
#define GSM_IMEI_LENGTH 17
#define GSM_EXTENSION_LENGTH 15
struct gprs_llc_lle;
/* TS 04.08 4.1.3.3 GMM mobility management states on the network side */
enum gprs_mm_state {
GMM_DEREGISTERED, /* 4.1.3.3.1.1 */
GMM_COMMON_PROC_INIT, /* 4.1.3.3.1.2 */
GMM_REGISTERED_NORMAL, /* 4.1.3.3.2.1 */
GMM_REGISTERED_SUSPENDED, /* 4.1.3.3.2.2 */
GMM_DEREGISTERED_INIT, /* 4.1.3.3.1.4 */
};
enum gprs_mm_ctr {
GMM_CTR_PKTS_SIG_IN,
GMM_CTR_PKTS_SIG_OUT,
GMM_CTR_PKTS_UDATA_IN,
GMM_CTR_PKTS_UDATA_OUT,
GMM_CTR_BYTES_UDATA_IN,
GMM_CTR_BYTES_UDATA_OUT,
GMM_CTR_PDP_CTX_ACT,
GMM_CTR_SUSPEND,
GMM_CTR_PAGING_PS,
GMM_CTR_PAGING_CS,
GMM_CTR_RA_UPDATE,
};
enum gprs_pdp_ctx {
PDP_CTR_PKTS_UDATA_IN,
PDP_CTR_PKTS_UDATA_OUT,
PDP_CTR_BYTES_UDATA_IN,
PDP_CTR_BYTES_UDATA_OUT,
};
enum gprs_t3350_mode {
GMM_T3350_MODE_ATT,
GMM_T3350_MODE_RAU,
GMM_T3350_MODE_PTMSI_REALL,
};
#define MS_RADIO_ACCESS_CAPA
/* According to TS 03.60, Table 5: SGSN MM and PDP Contexts */
/* Extended by 3GPP TS 23.060, Table 6: SGSN MM and PDP Contexts */
struct sgsn_mm_ctx {
struct llist_head list;
char imsi[GSM_IMSI_LENGTH];
enum gprs_mm_state mm_state;
uint32_t p_tmsi;
uint32_t p_tmsi_old; /* old P-TMSI before new is confirmed */
uint32_t p_tmsi_sig;
char imei[GSM_IMEI_LENGTH];
/* Opt: Software Version Numbber / TS 23.195 */
char msisdn[GSM_EXTENSION_LENGTH];
struct gprs_ra_id ra;
uint16_t cell_id;
uint32_t cell_id_age;
uint16_t sac; /* Iu: Service Area Code */
uint32_t sac_age;/* Iu: Service Area Code age */
/* VLR number */
uint32_t new_sgsn_addr;
/* Authentication Triplets */
/* Kc */
/* Iu: CK, IK, KSI */
/* CKSN */
enum gprs_ciph_algo ciph_algo;
struct {
uint8_t buf[14]; /* 10.5.5.12a */
uint8_t len;
} ms_radio_access_capa;
struct {
uint8_t buf[4]; /* 10.5.5.12 */
uint8_t len;
} ms_network_capa;
uint16_t drx_parms;
int mnrg; /* MS reported to HLR? */
int ngaf; /* MS reported to MSC/VLR? */
int ppf; /* paging for GPRS + non-GPRS? */
/* SMS Parameters */
int recovery;
uint8_t radio_prio_sms;
struct llist_head pdp_list;
/* Additional bits not present in the GSM TS */
struct gprs_llc_llme *llme;
uint32_t tlli;
uint32_t tlli_new;
uint16_t nsei;
uint16_t bvci;
struct rate_ctr_group *ctrg;
struct timer_list timer;
unsigned int T; /* Txxxx number */
unsigned int num_T_exp; /* number of consecutive T expirations */
enum gprs_t3350_mode t3350_mode;
uint8_t t3370_id_type;
};
/* look-up a SGSN MM context based on TLLI + RAI */
struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
const struct gprs_ra_id *raid);
struct sgsn_mm_ctx *sgsn_mm_ctx_by_ptmsi(uint32_t tmsi);
struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi);
/* Allocate a new SGSN MM context */
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
const struct gprs_ra_id *raid);
enum pdp_ctx_state {
PDP_STATE_NONE,
PDP_STATE_CR_REQ,
PDP_STATE_CR_CONF,
};
enum pdp_type {
PDP_TYPE_NONE,
PDP_TYPE_ETSI_PPP,
PDP_TYPE_IANA_IPv4,
PDP_TYPE_IANA_IPv6,
};
struct sgsn_pdp_ctx {
struct llist_head list; /* list_head for mmctx->pdp_list */
struct llist_head g_list; /* list_head for global list */
struct sgsn_mm_ctx *mm; /* back pointer to MM CTX */
struct sgsn_ggsn_ctx *ggsn; /* which GGSN serves this PDP */
struct rate_ctr_group *ctrg;
//unsigned int id;
struct pdp_t *lib; /* pointer to libgtp PDP ctx */
enum pdp_ctx_state state;
enum pdp_type type;
uint32_t address;
char *apn_subscribed;
//char *apn_used;
uint16_t nsapi; /* SNDCP */
uint16_t sapi; /* LLC */
uint8_t ti; /* transaction identifier */
int vplmn_allowed;
uint32_t qos_profile_subscr;
//uint32_t qos_profile_req;
//uint32_t qos_profile_neg;
uint8_t radio_prio;
uint32_t tx_npdu_nr;
uint32_t rx_npdu_nr;
uint32_t tx_gtp_snd;
uint32_t rx_gtp_snu;
//uint32_t charging_id;
int reordering_reqd;
};
/* look up PDP context by MM context and NSAPI */
struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_nsapi(const struct sgsn_mm_ctx *mm,
uint8_t nsapi);
/* look up PDP context by MM context and transaction ID */
struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_tid(const struct sgsn_mm_ctx *mm,
uint8_t tid);
struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm,
uint8_t nsapi);
void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp);
struct sgsn_ggsn_ctx {
struct llist_head list;
uint32_t id;
unsigned int gtp_version;
struct in_addr remote_addr;
struct gsn_t *gsn;
};
struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_alloc(uint32_t id);
struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_by_id(uint32_t id);
struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_find_alloc(uint32_t id);
struct apn_ctx {
struct llist_head list;
struct sgsn_ggsn_ctx *ggsn;
char *name;
char *description;
};
extern struct llist_head sgsn_mm_ctxts;
extern struct llist_head sgsn_ggsn_ctxts;
extern struct llist_head sgsn_apn_ctxts;
extern struct llist_head sgsn_pdp_ctxts;
uint32_t sgsn_alloc_ptmsi(void);
#endif /* _GPRS_SGSN_H */

View File

@@ -11,33 +11,24 @@ struct gsm_bts;
struct gsm_subscriber;
struct gsm_network;
struct gsm_trans;
struct gsm_subscriber_connection;
#define GSM48_ALLOC_SIZE 1024
#define GSM48_ALLOC_HEADROOM 128
static inline struct msgb *gsm48_msgb_alloc(void)
{
return msgb_alloc_headroom(GSM48_ALLOC_SIZE, GSM48_ALLOC_HEADROOM,
"GSM 04.08");
}
/* config options controlling the behaviour of the lower leves */
void gsm0408_allow_everyone(int allow);
void gsm0408_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause);
int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg);
int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id);
int gsm0408_new_conn(struct gsm_subscriber_connection *conn);
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);
enum gsm_chan_t get_ctype_by_chreq(struct gsm_network *bts, u_int8_t ra);
enum gsm_chreq_reason_t get_reason_by_chreq(u_int8_t ra, int neci);
void gsm_net_update_ctype(struct gsm_network *net);
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_rej(struct gsm_lchan *lchan);
struct msgb *gsm48_msgb_alloc(void);
int gsm48_sendmsg(struct msgb *msg, struct gsm_trans *trans);
int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn);
int gsm48_tx_mm_auth_req(struct gsm_subscriber_connection *conn, u_int8_t *rand, int key_seq);
int gsm48_tx_mm_auth_rej(struct gsm_subscriber_connection *conn);
int gsm48_send_rr_release(struct gsm_lchan *lchan);
int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv);
int gsm48_send_rr_app_info(struct gsm_subscriber_connection *conn, u_int8_t apdu_id,
int gsm48_send_rr_app_info(struct gsm_lchan *lchan, u_int8_t apdu_id,
u_int8_t apdu_len, const u_int8_t *apdu);
int gsm48_send_rr_ass_cmd(struct gsm_lchan *dest_lchan, struct gsm_lchan *lchan, u_int8_t power_class);
int gsm48_send_ho_cmd(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan,
@@ -56,7 +47,7 @@ int decode_bcd_number(char *output, int output_len, const u_int8_t *bcd_lv,
int send_siemens_mrpci(struct gsm_lchan *lchan, u_int8_t *classmark2_lv);
int gsm48_extract_mi(uint8_t *classmark2, int length, char *mi_string, uint8_t *mi_type);
int gsm48_paging_extract_mi(struct gsm48_pag_resp *pag, int length, char *mi_string, u_int8_t *mi_type);
int gsm48_handle_paging_resp(struct gsm_subscriber_connection *conn, struct msgb *msg, struct gsm_subscriber *subscr);
int gsm48_handle_paging_resp(struct msgb *msg, struct gsm_subscriber *subscr);
int gsm48_lchan_modify(struct gsm_lchan *lchan, u_int8_t lchan_mode);
int gsm48_rx_rr_modif_ack(struct msgb *msg);
@@ -64,7 +55,5 @@ int gsm48_parse_meas_rep(struct gsm_meas_rep *rep, struct msgb *msg);
struct msgb *gsm48_create_mm_serv_rej(enum gsm48_reject_value value);
struct msgb *gsm48_create_loc_upd_rej(uint8_t cause);
void gsm48_lchan2chan_desc(struct gsm48_chan_desc *cd,
const struct gsm_lchan *lchan);
#endif

View File

@@ -1,383 +0,0 @@
#ifndef _GSM48_GPRS_H
#define _GSM48_GPRS_H
#include <stdint.h>
#include <osmocore/protocol/gsm_04_08.h>
/* Table 10.4 / 10.4a, GPRS Mobility Management (GMM) */
#define GSM48_MT_GMM_ATTACH_REQ 0x01
#define GSM48_MT_GMM_ATTACH_ACK 0x02
#define GSM48_MT_GMM_ATTACH_COMPL 0x03
#define GSM48_MT_GMM_ATTACH_REJ 0x04
#define GSM48_MT_GMM_DETACH_REQ 0x05
#define GSM48_MT_GMM_DETACH_ACK 0x06
#define GSM48_MT_GMM_RA_UPD_REQ 0x08
#define GSM48_MT_GMM_RA_UPD_ACK 0x09
#define GSM48_MT_GMM_RA_UPD_COMPL 0x0a
#define GSM48_MT_GMM_RA_UPD_REJ 0x0b
#define GSM48_MT_GMM_PTMSI_REALL_CMD 0x10
#define GSM48_MT_GMM_PTMSI_REALL_COMPL 0x11
#define GSM48_MT_GMM_AUTH_CIPH_REQ 0x12
#define GSM48_MT_GMM_AUTH_CIPH_RESP 0x13
#define GSM48_MT_GMM_AUTH_CIPH_REJ 0x14
#define GSM48_MT_GMM_ID_REQ 0x15
#define GSM48_MT_GMM_ID_RESP 0x16
#define GSM48_MT_GMM_STATUS 0x20
#define GSM48_MT_GMM_INFO 0x21
/* Table 10.4a, GPRS Session Management (GSM) */
#define GSM48_MT_GSM_ACT_PDP_REQ 0x41
#define GSM48_MT_GSM_ACT_PDP_ACK 0x42
#define GSM48_MT_GSM_ACT_PDP_REJ 0x43
#define GSM48_MT_GSM_REQ_PDP_ACT 0x44
#define GSM48_MT_GSM_REQ_PDP_ACT_REJ 0x45
#define GSM48_MT_GSM_DEACT_PDP_REQ 0x46
#define GSM48_MT_GSM_DEACT_PDP_ACK 0x47
#define GSM48_MT_GSM_ACT_AA_PDP_REQ 0x50
#define GSM48_MT_GSM_ACT_AA_PDP_ACK 0x51
#define GSM48_MT_GSM_ACT_AA_PDP_REJ 0x52
#define GSM48_MT_GSM_DEACT_AA_PDP_REQ 0x53
#define GSM48_MT_GSM_DEACT_AA_PDP_ACK 0x54
#define GSM48_MT_GSM_STATUS 0x55
/* Chapter 10.5.5.2 / Table 10.5.135 */
#define GPRS_ATT_T_ATTACH 1
#define GPRS_ATT_T_ATT_WHILE_IMSI 2
#define GPRS_ATT_T_COMBINED 3
/* Chapter 10.5.5.5 / Table 10.5.138 */
#define GPRS_DET_T_MO_GPRS 1
#define GPRS_DET_T_MO_IMSI 2
#define GPRS_DET_T_MO_COMBINED 3
/* Network to MS direction */
#define GPRS_DET_T_MT_REATT_REQ 1
#define GPRS_DET_T_MT_REATT_NOTREQ 2
#define GPRS_DET_T_MT_IMSI 3
/* Chapter 10.5.5.18 / Table 105.150 */
#define GPRS_UPD_T_RA 0
#define GPRS_UPD_T_RA_LA 1
#define GPRS_UPD_T_RA_LA_IMSI_ATT 2
#define GPRS_UPD_T_PERIODIC 3
enum gsm48_gprs_ie_mm {
GSM48_IE_GMM_CIPH_CKSN = 0x08, /* 10.5.1.2 */
GSM48_IE_GMM_TIMER_READY = 0x17, /* 10.5.7.3 */
GSM48_IE_GMM_ALLOC_PTMSI = 0x18, /* 10.5.1.4 */
GSM48_IE_GMM_PTMSI_SIG = 0x19, /* 10.5.5.8 */
GSM48_IE_GMM_AUTH_RAND = 0x21, /* 10.5.3.1 */
GSM48_IE_GMM_AUTH_SRES = 0x22, /* 10.5.3.2 */
GSM48_IE_GMM_IMEISV = 0x23, /* 10.5.1.4 */
GSM48_IE_GMM_DRX_PARAM = 0x27, /* 10.5.5.6 */
GSM48_IE_GMM_MS_NET_CAPA = 0x31, /* 10.5.5.12 */
GSM48_IE_GMM_PDP_CTX_STATUS = 0x32, /* 10.5.7.1 */
GSM48_IE_GMM_PS_LCS_CAPA = 0x33, /* 10.5.5.22 */
GSM48_IE_GMM_GMM_MBMS_CTX_ST = 0x35, /* 10.5.7.6 */
};
enum gsm48_gprs_ie_sm {
GSM48_IE_GSM_APN = 0x28, /* 10.5.6.1 */
GSM48_IE_GSM_PROTO_CONF_OPT = 0x27, /* 10.5.6.3 */
GSM48_IE_GSM_PDP_ADDR = 0x2b, /* 10.5.6.4 */
GSM48_IE_GSM_AA_TMR = 0x29, /* 10.5.7.3 */
GSM48_IE_GSM_NAME_FULL = 0x43, /* 10.5.3.5a */
GSM48_IE_GSM_NAME_SHORT = 0x45, /* 10.5.3.5a */
GSM48_IE_GSM_TIMEZONE = 0x46, /* 10.5.3.8 */
GSM48_IE_GSM_UTC_AND_TZ = 0x47, /* 10.5.3.9 */
GSM48_IE_GSM_LSA_ID = 0x48, /* 10.5.3.11 */
/* Fake IEs that are not present on the Layer3 air interface,
* but which we use to simplify internal APIs */
OSMO_IE_GSM_REQ_QOS = 0xfd,
OSMO_IE_GSM_REQ_PDP_ADDR = 0xfe,
};
/* Chapter 9.4.15 / Table 9.4.15 */
struct gsm48_ra_upd_ack {
uint8_t force_stby:4, /* 10.5.5.7 */
upd_result:4; /* 10.5.5.17 */
uint8_t ra_upd_timer; /* 10.5.7.3 */
struct gsm48_ra_id ra_id; /* 10.5.5.15 */
uint8_t data[0];
} __attribute__((packed));
/* Chapter 10.5.7.3 */
enum gsm48_gprs_tmr_unit {
GPRS_TMR_2SECONDS = 0 << 5,
GPRS_TMR_MINUTE = 1 << 5,
GPRS_TMR_6MINUTE = 2 << 5,
GPRS_TMR_DEACTIVATED = 3 << 5,
};
/* Chapter 9.4.2 / Table 9.4.2 */
struct gsm48_attach_ack {
uint8_t att_result:4, /* 10.5.5.7 */
force_stby:4; /* 10.5.5.1 */
uint8_t ra_upd_timer; /* 10.5.7.3 */
uint8_t radio_prio; /* 10.5.7.2 */
struct gsm48_ra_id ra_id; /* 10.5.5.15 */
uint8_t data[0];
} __attribute__((packed));
/* Chapter 9.4.9 / Table 9.4.9 */
struct gsm48_auth_ciph_req {
uint8_t ciph_alg:4, /* 10.5.5.3 */
imeisv_req:4; /* 10.5.5.10 */
uint8_t force_stby:4, /* 10.5.5.7 */
ac_ref_nr:4; /* 10.5.5.19 */
uint8_t data[0];
} __attribute__((packed));
/* optional: TV RAND, TV CKSN */
struct gsm48_auth_ciph_resp {
uint8_t ac_ref_nr:4,
spare:4;
uint8_t data[0];
} __attribute__((packed));
/* Chapter 9.5.1 / Table 9.5.1 */
struct gsm48_act_pdp_ctx_req {
uint8_t req_nsapi;
uint8_t req_llc_sapi;
uint8_t data[0];
} __attribute__((packed));
/* Chapter 10.5.5.14 / Table 10.5.147 */
enum gsm48_gmm_cause {
GMM_CAUSE_IMSI_UNKNOWN = 0x02,
GMM_CAUSE_ILLEGAL_MS = 0x03,
GMM_CAUSE_ILLEGAL_ME = 0x06,
GMM_CAUSE_GPRS_NOTALLOWED = 0x07,
GMM_CAUSE_GPRS_OTHER_NOTALLOWED = 0x08,
GMM_CAUSE_MS_ID_NOT_DERIVED = 0x09,
GMM_CAUSE_IMPL_DETACHED = 0x0a,
GMM_CAUSE_PLMN_NOTALLOWED = 0x0b,
GMM_CAUSE_LA_NOTALLOWED = 0x0c,
GMM_CAUSE_ROAMING_NOTALLOWED = 0x0d,
GMM_CAUSE_NO_GPRS_PLMN = 0x0e,
GMM_CAUSE_MSC_TEMP_NOTREACH = 0x10,
GMM_CAUSE_NET_FAIL = 0x11,
GMM_CAUSE_CONGESTION = 0x16,
GMM_CAUSE_SEM_INCORR_MSG = 0x5f,
GMM_CAUSE_INV_MAND_INFO = 0x60,
GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL = 0x61,
GMM_CAUSE_MSGT_INCOMP_P_STATE = 0x62,
GMM_CAUSE_IE_NOTEXIST_NOTIMPL = 0x63,
GMM_CAUSE_COND_IE_ERR = 0x64,
GMM_CAUSE_MSG_INCOMP_P_STATE = 0x65,
GMM_CAUSE_PROTO_ERR_UNSPEC = 0x6f,
};
/* Chapter 10.4.6.6 / Table 10.5.157 */
enum gsm48_gsm_cause {
GSM_CAUSE_INSUFF_RSRC = 0x1a,
GSM_CAUSE_MISSING_APN = 0x1b,
GSM_CAUSE_UNKNOWN_PDP = 0x1c,
GSM_CAUSE_AUTH_FAILED = 0x1d,
GSM_CAUSE_ACT_REJ_GGSN = 0x1e,
GSM_CAUSE_ACT_REJ_UNSPEC = 0x1f,
GSM_CAUSE_SERV_OPT_NOTSUPP = 0x20,
GSM_CAUSE_REQ_SERV_OPT_NOTSUB = 0x21,
GSM_CAUSE_SERV_OPT_TEMP_OOO = 0x22,
GSM_CAUSE_NSAPI_IN_USE = 0x23,
GSM_CAUSE_DEACT_REGULAR = 0x24,
GSM_CAUSE_QOS_NOT_ACCEPTED = 0x25,
GSM_CAUSE_NET_FAIL = 0x26,
GSM_CAUSE_REACT_RQD = 0x27,
GSM_CAUSE_FEATURE_NOTSUPP = 0x28,
GSM_CAUSE_INVALID_TRANS_ID = 0x51,
GSM_CAUSE_SEM_INCORR_MSG = 0x5f,
GSM_CAUSE_INV_MAND_INFO = 0x60,
GSM_CAUSE_MSGT_NOTEXIST_NOTIMPL = 0x61,
GSM_CAUSE_MSGT_INCOMP_P_STATE = 0x62,
GSM_CAUSE_IE_NOTEXIST_NOTIMPL = 0x63,
GSM_CAUSE_COND_IE_ERR = 0x64,
GSM_CAUSE_MSG_INCOMP_P_STATE = 0x65,
GSM_CAUSE_PROTO_ERR_UNSPEC = 0x6f,
};
/* Section 6.1.2.2: Session management states on the network side */
enum gsm48_pdp_state {
PDP_S_INACTIVE,
PDP_S_ACTIVE_PENDING,
PDP_S_ACTIVE,
PDP_S_INACTIVE_PENDING,
PDP_S_MODIFY_PENDING,
};
/* Table 10.5.155/3GPP TS 24.008 */
enum gsm48_pdp_type_org {
PDP_TYPE_ORG_ETSI = 0x00,
PDP_TYPE_ORG_IETF = 0x01,
};
enum gsm48_pdp_type_nr {
PDP_TYPE_N_ETSI_RESERVED = 0x00,
PDP_TYPE_N_ETSI_PPP = 0x01,
PDP_TYPE_N_IETF_IPv4 = 0x21,
PDP_TYPE_N_IETF_IPv6 = 0x57,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_reliab_class {
GSM48_QOS_RC_LLC_ACK_RLC_ACK_DATA_PROT = 2,
GSM48_QOS_RC_LLC_UN_RLC_ACK_DATA_PROT = 3,
GSM48_QOS_RC_LLC_UN_RLC_UN_PROT_DATA = 4,
GSM48_QOS_RC_LLC_UN_RLC_UN_DATA_UN = 5,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_preced_class {
GSM48_QOS_PC_HIGH = 1,
GSM48_QOS_PC_NORMAL = 2,
GSM48_QOS_PC_LOW = 3,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_peak_tput {
GSM48_QOS_PEAK_TPUT_1000bps = 1,
GSM48_QOS_PEAK_TPUT_2000bps = 2,
GSM48_QOS_PEAK_TPUT_4000bps = 3,
GSM48_QOS_PEAK_TPUT_8000bps = 4,
GSM48_QOS_PEAK_TPUT_16000bps = 5,
GSM48_QOS_PEAK_TPUT_32000bps = 6,
GSM48_QOS_PEAK_TPUT_64000bps = 7,
GSM48_QOS_PEAK_TPUT_128000bps = 8,
GSM48_QOS_PEAK_TPUT_256000bps = 9,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_mean_tput {
GSM48_QOS_MEAN_TPUT_100bph = 1,
GSM48_QOS_MEAN_TPUT_200bph = 2,
GSM48_QOS_MEAN_TPUT_500bph = 3,
GSM48_QOS_MEAN_TPUT_1000bph = 4,
GSM48_QOS_MEAN_TPUT_2000bph = 5,
GSM48_QOS_MEAN_TPUT_5000bph = 6,
GSM48_QOS_MEAN_TPUT_10000bph = 7,
GSM48_QOS_MEAN_TPUT_20000bph = 8,
GSM48_QOS_MEAN_TPUT_50000bph = 9,
GSM48_QOS_MEAN_TPUT_100kbph = 10,
GSM48_QOS_MEAN_TPUT_200kbph = 11,
GSM48_QOS_MEAN_TPUT_500kbph = 0xc,
GSM48_QOS_MEAN_TPUT_1Mbph = 0xd,
GSM48_QOS_MEAN_TPUT_2Mbph = 0xe,
GSM48_QOS_MEAN_TPUT_5Mbph = 0xf,
GSM48_QOS_MEAN_TPUT_10Mbph = 0x10,
GSM48_QOS_MEAN_TPUT_20Mbph = 0x11,
GSM48_QOS_MEAN_TPUT_50Mbph = 0x12,
GSM48_QOS_MEAN_TPUT_BEST_EFFORT = 0x1f,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_err_sdu {
GSM48_QOS_ERRSDU_NODETECT = 1,
GSM48_QOS_ERRSDU_YES = 2,
GSM48_QOS_ERRSDU_NO = 3,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_deliv_order {
GSM48_QOS_DO_ORDERED = 1,
GSM48_QOS_DO_UNORDERED = 2,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_traf_class {
GSM48_QOS_TC_CONVERSATIONAL = 1,
GSM48_QOS_TC_STREAMING = 2,
GSM48_QOS_TC_INTERACTIVE = 3,
GSM48_QOS_TC_BACKGROUND = 4,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_max_sdu_size {
/* values below in 10 octet granularity */
GSM48_QOS_MAXSDU_1502 = 0x97,
GSM48_QOS_MAXSDU_1510 = 0x98,
GSM48_QOS_MAXSDU_1520 = 0x99,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_max_bitrate {
GSM48_QOS_MBRATE_1k = 0x01,
GSM48_QOS_MBRATE_63k = 0x3f,
GSM48_QOS_MBRATE_64k = 0x40,
GSM48_QOS_MBRATE_568k = 0x7f,
GSM48_QOS_MBRATE_576k = 0x80,
GSM48_QOS_MBRATE_8640k = 0xfe,
GSM48_QOS_MBRATE_0k = 0xff,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_resid_ber {
GSM48_QOS_RBER_5e_2 = 0x01,
GSM48_QOS_RBER_1e_2 = 0x02,
GSM48_QOS_RBER_5e_3 = 0x03,
GSM48_QOS_RBER_4e_3 = 0x04,
GSM48_QOS_RBER_1e_3 = 0x05,
GSM48_QOS_RBER_1e_4 = 0x06,
GSM48_QOS_RBER_1e_5 = 0x07,
GSM48_QOS_RBER_1e_6 = 0x08,
GSM48_QOS_RBER_6e_8 = 0x09,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_sdu_err {
GSM48_QOS_SERR_1e_2 = 0x01,
GSM48_QOS_SERR_7e_2 = 0x02,
GSM48_QOS_SERR_1e_3 = 0x03,
GSM48_QOS_SERR_1e_4 = 0x04,
GSM48_QOS_SERR_1e_5 = 0x05,
GSM48_QOS_SERR_1e_6 = 0x06,
GSM48_QOS_SERR_1e_1 = 0x07,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
struct gsm48_qos {
/* octet 3 */
uint8_t reliab_class:3;
uint8_t delay_class:3;
uint8_t spare:2;
/* octet 4 */
uint8_t preced_class:3;
uint8_t spare2:1;
uint8_t peak_tput:4;
/* octet 5 */
uint8_t mean_tput:5;
uint8_t spare3:3;
/* octet 6 */
uint8_t deliv_err_sdu:3;
uint8_t deliv_order:2;
uint8_t traf_class:3;
/* octet 7 */
uint8_t max_sdu_size;
/* octet 8 */
uint8_t max_bitrate_up;
/* octet 9 */
uint8_t max_bitrate_down;
/* octet 10 */
uint8_t sdu_err_ratio:4;
uint8_t resid_ber:4;
/* octet 11 */
uint8_t handling_prio:2;
uint8_t xfer_delay:6;
/* octet 12 */
uint8_t guar_bitrate_up;
/* octet 13 */
uint8_t guar_bitrate_down;
/* octet 14 */
uint8_t src_stats_desc:4;
uint8_t sig_ind:1;
uint8_t spare5:3;
/* octet 15 */
uint8_t max_bitrate_down_ext;
/* octet 16 */
uint8_t guar_bitrate_down_ext;
};
int gprs_tlli_type(uint32_t tlli);
#endif /* _GSM48_GPRS_H */

View File

@@ -3,8 +3,6 @@
#include <osmocore/protocol/gsm_04_11.h>
#define UM_SAPI_SMS 3 /* See GSM 04.05/04.06 */
/* SMS deliver PDU */
struct sms_deliver {
u_int8_t mti:2; /* message type indicator */
@@ -25,7 +23,9 @@ struct sms_deliver {
struct msgb;
int gsm0411_rcv_sms(struct gsm_subscriber_connection *conn, struct msgb *msg);
int gsm0411_rcv_sms(struct msgb *msg, u_int8_t link_id);
int gsm411_send_sms_lchan(struct gsm_subscriber_connection *conn, struct gsm_sms *sms);
struct gsm_sms *sms_alloc(void);
void sms_free(struct gsm_sms *sms);
@@ -33,5 +33,4 @@ void sms_free(struct gsm_sms *sms);
void _gsm411_sms_trans_free(struct gsm_trans *trans);
int gsm411_send_sms_subscr(struct gsm_subscriber *subscr,
struct gsm_sms *sms);
void gsm411_sapi_n_reject(struct gsm_subscriber_connection *conn);
#endif

View File

@@ -3,33 +3,14 @@
#include <osmocore/msgb.h>
#include <osmocore/protocol/gsm_04_80.h>
#include <osmocore/gsm0480.h>
#define MAX_LEN_USSD_STRING 31
int gsm0480_send_ussd_response(const struct msgb *in_msg, const char* response_text,
const struct ussd_request *req);
int gsm0480_send_ussd_reject(const struct msgb *msg,
const struct ussd_request *request);
struct gsm_subscriber_connection;
struct ussd_request {
char text[MAX_LEN_USSD_STRING + 1];
u_int8_t transaction_id;
u_int8_t invoke_id;
};
int gsm0480_decode_ussd_request(const struct msgb *msg,
struct ussd_request *request);
int gsm0480_send_ussd_response(struct gsm_subscriber_connection *conn,
const struct msgb *in_msg, const char* response_text,
const struct ussd_request *req);
int gsm0480_send_ussd_reject(struct gsm_subscriber_connection *conn,
const struct msgb *msg,
const struct ussd_request *request);
struct msgb *gsm0480_create_notifySS(const char *text);
struct msgb *gsm0480_create_unstructuredSS_Notify(int alertLevel, const char *text);
int gsm0480_wrap_invoke(struct msgb *msg, int op, int link_id);
int gsm0480_wrap_facility(struct msgb *msg);
int gsm0480_send_ussdNotify(struct gsm_subscriber_connection *conn, int level, const char *text);
int gsm0480_send_releaseComplete(struct gsm_subscriber_connection *conn);
int gsm0480_send_ussdNotify(struct gsm_lchan *lchan, int level, const char *text);
int gsm0480_send_releaseComplete(struct gsm_lchan *lchan);
#endif

View File

@@ -3,6 +3,8 @@
#include <sys/types.h>
struct bsc_msc_connection;
enum gsm_phys_chan_config {
GSM_PCHAN_NONE,
GSM_PCHAN_CCCH,
@@ -43,15 +45,12 @@ enum gsm_chreq_reason_t {
#include <osmocore/timer.h>
#include <openbsc/gsm_04_08.h>
#include <openbsc/abis_rsl.h>
#include <openbsc/system_information.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 <osmocore/rxlev_stat.h>
#define TRX_NR_TS 8
#define TS_MAX_LCHAN 8
@@ -68,7 +67,6 @@ enum gsm_chreq_reason_t {
enum gsm_hooks {
GSM_HOOK_NM_SWLOAD,
GSM_HOOK_RR_PAGING,
GSM_HOOK_RR_SECURITY,
};
enum gsm_paging_event {
@@ -83,45 +81,16 @@ enum bts_gprs_mode {
BTS_GPRS_EGPRS = 2,
};
/* the data structure stored in msgb->cb for openbsc apps */
struct openbsc_msgb_cb {
unsigned char *bssgph;
unsigned char *llch;
/* Cell Identifier */
unsigned char *bssgp_cell_id;
/* Identifiers of a BTS, equal to 'struct bssgp_bts_ctx' */
u_int16_t nsei;
u_int16_t bvci;
/* Identifier of a MS (inside BTS), equal to 'struct sgsn_mm_ctx' */
u_int32_t tlli;
} __attribute__((packed));
#define OBSC_MSGB_CB(__msgb) ((struct openbsc_msgb_cb *)&((__msgb)->cb[0]))
#define msgb_tlli(__x) OBSC_MSGB_CB(__x)->tlli
#define msgb_nsei(__x) OBSC_MSGB_CB(__x)->nsei
#define msgb_bvci(__x) OBSC_MSGB_CB(__x)->bvci
#define msgb_gmmh(__x) (__x)->l3h
#define msgb_bssgph(__x) OBSC_MSGB_CB(__x)->bssgph
#define msgb_bssgp_len(__x) ((__x)->tail - (uint8_t *)msgb_bssgph(__x))
#define msgb_bcid(__x) OBSC_MSGB_CB(__x)->bssgp_cell_id
#define msgb_llch(__x) OBSC_MSGB_CB(__x)->llch
#define OBSC_LINKID_CB(__msgb) (__msgb)->cb[3]
enum gsm_security_event {
GSM_SECURITY_NOAVAIL,
GSM_SECURITY_AUTH_FAILED,
GSM_SECURITY_SUCCEEDED,
};
#define OBSC_NM_W_ACK_CB(__msgb) (__msgb)->cb[3]
struct msgb;
typedef int gsm_cbfn(unsigned int hooknum,
unsigned int event,
struct msgb *msg,
void *data, void *param);
struct osmo_bsc_rf;
struct sccp_connection;
/* Real authentication information containing Ki */
enum gsm_auth_algo {
AUTH_ALGO_NONE,
@@ -142,14 +111,55 @@ struct gsm_auth_tuple {
u_int8_t sres[4];
u_int8_t kc[8];
};
#define GSM_KEY_SEQ_INVAL 7 /* GSM 04.08 - 10.5.1.2 */
struct gsm_lchan;
struct gsm_subscriber;
struct gsm_mncc;
struct rtp_socket;
struct bsc_api;
/* 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;
int new_subscriber;
/* Timers... */
/* for assginment command */
struct timer_list T10;
/* for SCCP ... */
struct timer_list sccp_cc_timeout;
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;
/* which msc connection to use? */
struct bsc_msc_connection *msc_con;
/* Active connections */
struct llist_head active_connections;
};
#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 {
@@ -169,24 +179,6 @@ struct gsm_loc_updating_operation {
struct timer_list updating_timer;
unsigned int waiting_for_imsi : 1;
unsigned int waiting_for_imei : 1;
unsigned int key_seq : 4;
};
/*
* AUTHENTICATION/CIPHERING state
*/
struct gsm_security_operation {
struct gsm_auth_tuple atuple;
gsm_cbfn *cb;
void *cb_data;
};
/*
* A dummy to keep a connection up for at least
* a couple of seconds to work around MSC issues.
*/
struct gsm_anchor_operation {
struct timer_list timeout;
};
/* Maximum number of neighbor cells whose average we track */
@@ -204,9 +196,6 @@ struct neigh_meas_proc {
};
#define MAX_A5_KEY_LEN (128/8)
#define A38_XOR_MIN_KEY_LEN 12
#define A38_XOR_MAX_KEY_LEN 16
#define A38_COMP128_KEY_LEN 16
#define RSL_ENC_ALG_A5(x) (x+1)
/* is the data link established? who established it? */
@@ -233,16 +222,16 @@ struct gsm_subscriber_connection {
* Operations that have a state and might be pending
*/
struct gsm_loc_updating_operation *loc_operation;
struct gsm_security_operation *sec_operation;
struct gsm_anchor_operation *anch_operation;
/* use count. how many users use this channel */
unsigned int use_count;
int hand_off;
/* Are we part of a special "silent" call */
int silent_call;
/* back pointers */
int in_release;
struct gsm_lchan *lchan;
struct gsm_lchan *ho_lchan;
struct gsm_bts *bts;
};
@@ -278,8 +267,11 @@ struct gsm_lchan {
/* Established data link layer services */
u_int8_t sapis[8];
int sach_deact;
int release_reason;
/*
* MSC handling...
*/
struct bss_sccp_connection_data *msc_data;
/* GSM Random Access data */
struct gsm48_req_ref *rqd_ref;
@@ -298,13 +290,18 @@ struct gsm_lchan {
u_int16_t bound_port;
u_int16_t connect_port;
u_int16_t conn_id;
u_int8_t rtp_payload;
u_int8_t rtp_payload2;
u_int8_t speech_mode;
struct rtp_socket *rtp_socket;
} abis_ip;
struct gsm_subscriber_connection *conn;
struct gsm_subscriber_connection conn;
/* release reason */
u_int8_t release_reason;
/* timestamp */
struct timeval alloc_time;
};
struct gsm_e1_subslot {
@@ -330,19 +327,6 @@ struct gsm_bts_trx_ts {
struct tlv_parsed nm_attr;
u_int8_t nm_chan_comb;
struct {
/* Parameters below are configured by VTY */
int enabled;
u_int8_t maio;
u_int8_t hsn;
struct bitvec arfcns;
u_int8_t arfcns_data[1024/8];
/* This is the pre-computed MA for channel assignments */
struct bitvec ma;
u_int8_t ma_len; /* part of ma_data that is used */
u_int8_t ma_data[8]; /* 10.5.2.21: max 8 bytes value part */
} hopping;
/* To which E1 subslot are we connected */
struct gsm_e1_subslot e1_link;
@@ -357,8 +341,6 @@ struct gsm_bts_trx {
struct gsm_bts *bts;
/* number of this TRX in the BTS */
u_int8_t nr;
/* human readable name / description */
char *description;
/* how do we talk RSL with this TRX? */
struct gsm_e1_subslot rsl_e1_link;
u_int8_t rsl_tei;
@@ -383,17 +365,10 @@ struct gsm_bts_trx {
struct gsm_nm_state nm_state;
} pa;
} bs11;
struct {
unsigned int test_state;
u_int8_t test_nr;
struct rxlev_stats rxlev_stat;
} ipaccess;
};
struct gsm_bts_trx_ts ts[TRX_NR_TS];
};
#define GSM_BTS_SI(bts, i) (void *)(bts->si_buf[i])
enum gsm_bts_type {
GSM_BTS_TYPE_UNKNOWN,
GSM_BTS_TYPE_BS11,
@@ -407,17 +382,6 @@ struct gsm_bts_model {
const char *name;
struct tlv_definition nm_att_tlvdef;
struct bitvec features;
uint8_t _features_data[128/8];
};
enum gsm_bts_features {
BTS_FEAT_HSCSD,
BTS_FEAT_GPRS,
BTS_FEAT_EGPRS,
BTS_FEAT_ECSD,
BTS_FEAT_HOPPING,
};
/**
@@ -453,6 +417,10 @@ struct gsm_bts_paging_state {
struct gsm_bts *bts;
struct timer_list work_timer;
struct timer_list credit_timer;
/* free chans needed */
int free_chans_need;
/* load */
u_int16_t available_slots;
@@ -464,14 +432,11 @@ struct gsm_envabtse {
struct gsm_bts_gprs_nsvc {
struct gsm_bts *bts;
/* data read via VTY config file, to configure the BTS
* via OML from BSC */
int id;
u_int16_t nsvci;
u_int16_t local_port; /* on the BTS */
u_int16_t remote_port; /* on the SGSN */
u_int32_t remote_ip; /* on the SGSN */
u_int16_t local_port;
u_int16_t remote_port;
u_int32_t remote_ip;
struct gsm_nm_state nm_state;
};
@@ -483,8 +448,6 @@ struct gsm_bts {
struct gsm_network *network;
/* number of ths BTS in network */
u_int8_t nr;
/* human readable name / description */
char *description;
/* Cell Identity */
u_int16_t cell_identity;
/* location area code of this BTS */
@@ -542,13 +505,6 @@ struct gsm_bts {
} data;
} si_common;
/* do we use static (user-defined) system information messages? (bitmask) */
uint32_t si_mode_static;
/* bitmask of all SI that are present/valid in si_buf */
uint32_t si_valid;
/* buffers where we put the pre-computed SI */
sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE];
/* ip.accesss Unit ID's have Site/BTS/TRX layout */
union {
struct {
@@ -591,6 +547,10 @@ struct gsm_bts {
/* transceivers */
int num_trx;
struct llist_head trx_list;
/* Abis NM queue */
struct llist_head abis_queue;
int abis_nm_pend;
};
/* Some statistics of our network */
@@ -653,6 +613,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;
@@ -683,11 +651,15 @@ 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;
struct llist_head trans_list;
struct bsc_api *bsc_api;
unsigned int num_bts;
struct llist_head bts_list;
@@ -709,7 +681,31 @@ struct gsm_network {
struct {
enum rrlp_mode mode;
} rrlp;
int msc_prio;
enum gsm_chan_t ctype_by_chreq[16];
/* enable the DTXu and DTXd for this network */
int dtx_enabled;
/* Use a TCH for handling requests of type paging any */
int pag_any_tch;
/* a hack for On Waves. It must be signed */
int32_t core_country_code;
int32_t core_network_code;
/* a simple token for this network... */
char *bsc_token;
char *msc_ip;
int msc_port;
int msc_ip_dscp;
struct bsc_msc_connection *msc_con;
int ping_timeout;
int pong_timeout;
struct osmo_bsc_rf *rf;
char *mid_call_txt;
int mid_call_timeout;
char *ussd_welcome_txt;
};
#define SMS_HDR_SIZE 128
@@ -815,11 +811,6 @@ 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_btsmodel_set_feature(struct gsm_bts_model *model, enum gsm_bts_features feat);
int gsm_bts_has_feature(struct gsm_bts *bts, enum gsm_bts_features feat);
int gsm_bts_model_register(struct gsm_bts_model *model);
struct gsm_subscriber_connection *subscr_con_allocate(struct gsm_lchan *lchan);
void subscr_con_free(struct gsm_subscriber_connection *conn);
#endif

View File

@@ -7,7 +7,7 @@
#define GSM_IMEI_LENGTH 17
#define GSM_IMSI_LENGTH 17
#define GSM_NAME_LENGTH 160
#define GSM_NAME_LENGTH 128
#define GSM_EXTENSION_LENGTH 15 /* MSISDN can only be 15 digits length */
#define GSM_MIN_EXTEN 20000
@@ -81,8 +81,10 @@ 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_subscriber_connection *conn);
void subscr_put_channel(struct gsm_lchan *lchan);
void subscr_get_channel(struct gsm_subscriber *subscr,
int type, gsm_cbfn *cbfn, void *param);

View File

@@ -1,14 +1,8 @@
#ifndef _HANDOVER_H
#define _HANDOVER_H
struct gsm_subscriber_connection;
/* Hand over the specified logical channel to the specified new BTS.
* This is the main entry point for the actual handover algorithm,
* after it has decided it wants to initiate HO to a specific BTS */
int bsc_handover_start(struct gsm_lchan *old_lchan, struct gsm_bts *bts);
/* clear any operation for this connection */
void bsc_clear_handover(struct gsm_subscriber_connection *conn);
#endif /* _HANDOVER_H */

View File

@@ -30,7 +30,6 @@
#define RTP_PORT_DEFAULT 4000
#define RTP_PORT_NET_DEFAULT 16000
/**
* Calculate the RTP audio port for the given multiplex
* and the direction. This allows a semi static endpoint
@@ -76,6 +75,7 @@ struct mgcp_config;
#define MGCP_POLICY_REJECT 5
#define MGCP_POLICY_DEFER 6
typedef int (*mgcp_realloc)(struct mgcp_config *cfg, int endpoint);
typedef int (*mgcp_change)(struct mgcp_config *cfg, int endpoint, int state);
typedef int (*mgcp_policy)(struct mgcp_config *cfg, int endpoint, int state, const char *transactio_id);
typedef int (*mgcp_reset)(struct mgcp_config *cfg);
@@ -99,13 +99,14 @@ struct mgcp_port_range {
};
struct mgcp_config {
/* common configuration */
int source_port;
char *local_ip;
char *source_addr;
unsigned int number_endpoints;
char *bts_ip;
char *call_agent_addr;
/* default endpoint data */
struct in_addr bts_in;
char *audio_name;
int audio_payload;
@@ -115,16 +116,21 @@ struct mgcp_config {
struct mgcp_port_range net_ports;
int endp_dscp;
/* endpoint configuration */
unsigned int number_endpoints;
struct mgcp_endpoint *endpoints;
/* spec handling */
int force_realloc;
/* callback functionality */
mgcp_change change_cb;
mgcp_policy policy_cb;
mgcp_reset reset_cb;
mgcp_realloc realloc_cb;
void *data;
struct mgcp_endpoint *endpoints;
unsigned int last_call_id;
uint32_t last_call_id;
};
/* config management */
@@ -145,7 +151,7 @@ static inline int mgcp_timeslot_to_endpoint(int multiplex, int timeslot)
{
if (timeslot == 0)
timeslot = 1;
return timeslot + (31 * multiplex);
return timeslot + (32 * multiplex);
}

View File

@@ -69,8 +69,24 @@ struct mgcp_rtp_end {
int local_alloc;
};
enum {
MGCP_TAP_BTS_IN,
MGCP_TAP_BTS_OUT,
MGCP_TAP_NET_IN,
MGCP_TAP_NET_OUT,
/* last element */
MGCP_TAP_COUNT
};
struct mgcp_rtp_tap {
int enabled;
struct sockaddr_in forward;
};
struct mgcp_endpoint {
int ci;
int allocated;
uint32_t ci;
char *callid;
char *local_options;
int conn_mode;
@@ -86,6 +102,12 @@ struct mgcp_endpoint {
/* sequence bits */
struct mgcp_rtp_state net_state;
struct mgcp_rtp_state bts_state;
/* SSRC/seq/ts patching for loop */
int allow_patch;
/* tap for the endpoint */
struct mgcp_rtp_tap taps[MGCP_TAP_COUNT];
};
#define ENDPOINT_NUMBER(endp) abs(endp - endp->cfg->endpoints)

View File

@@ -1,16 +0,0 @@
#ifndef _OPENBSC_NWL_H
#define _OPENBSC_NWL_H
#include <stdint.h>
#include <openbsc/gsm_data.h>
void ipac_nwl_init(void);
/* Start a NWL test. It will raise the S_IPAC_TEST_COMPLETE signal. */
int ipac_nwl_test_start(struct gsm_bts_trx *trx, uint8_t testnr,
const uint8_t *phys_conf, unsigned int phys_conf_len);
int ipac_rxlevstat2whitelist(uint16_t *buf, const struct rxlev_stats *st, uint8_t min_rxlev,
uint16_t max_num_arfcns);
#endif /* _OPENBSC_NWL_H */

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