Merge commit '100224df0b711c7bf6c1150ce18cf595350cf0bd'
authorHarald Welte <laforge@gnumonks.org>
Wed, 28 Apr 2010 09:43:37 +0000 (11:43 +0200)
committerHarald Welte <laforge@gnumonks.org>
Wed, 28 Apr 2010 09:43:37 +0000 (11:43 +0200)
src/shared/libosmocore/.gitignore
src/shared/libosmocore/include/osmocore/Makefile.am
src/shared/libosmocore/include/osmocore/gsm0808.h [new file with mode: 0644]
src/shared/libosmocore/include/osmocore/gsm_utils.h
src/shared/libosmocore/include/osmocore/protocol/gsm_08_08.h [new file with mode: 0644]
src/shared/libosmocore/src/Makefile.am
src/shared/libosmocore/src/gsm0808.c [new file with mode: 0644]
src/shared/libosmocore/src/select.c

index d61cdc5..06904fa 100644 (file)
@@ -7,6 +7,7 @@ Makefile.in
 *.la
 *.pc
 aclocal.m4
+m4/*.m4
 autom4te.cache
 config.h*
 config.sub
@@ -23,3 +24,7 @@ libtool
 
 .tarball-version
 .version
+
+tests/sms/sms_test
+tests/timer/timer_test
+
index 1c3a33f..56f926b 100644 (file)
@@ -1,7 +1,7 @@
 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
+                  gsm48_ie.h logging.h gsm0808.h
 
 if ENABLE_TALLOC
 osmocore_HEADERS += talloc.h
diff --git a/src/shared/libosmocore/include/osmocore/gsm0808.h b/src/shared/libosmocore/include/osmocore/gsm0808.h
new file mode 100644 (file)
index 0000000..a40713f
--- /dev/null
@@ -0,0 +1,41 @@
+/* (C) 2009,2010 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009,2010 by On-Waves
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+#ifndef OSMOCORE_GSM0808_H
+#define OSMOCORE_GSM0808_H
+
+#include "tlv.h"
+
+struct msgb;
+
+struct msgb *gsm0808_create_layer3(struct msgb *msg, uint16_t netcode, uint16_t countrycode, int lac, int ci);
+struct msgb *gsm0808_create_reset(void);
+struct msgb *gsm0808_create_clear_complete(void);
+struct msgb *gsm0808_create_cipher_complete(struct msgb *layer3, uint8_t alg_id);
+struct msgb *gsm0808_create_cipher_reject(uint8_t cause);
+struct msgb *gsm0808_create_classmark_update(const uint8_t *classmark, uint8_t length);
+struct msgb *gsm0808_create_sapi_reject(uint8_t link_id);
+struct msgb *gsm0808_create_assignment_completed(struct gsm_lchan *lchan, uint8_t rr_cause,
+                                                uint8_t chosen_channel, uint8_t encr_alg_id,
+                                                uint8_t speech_mode);
+struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause);
+
+const struct tlv_definition *gsm0808_att_tlvdef();
+
+#endif
index c87e967..195e865 100644 (file)
 
 #include <stdint.h>
 
+#define ADD_MODULO(sum, delta, modulo) do {    \
+       if ((sum += delta) >= modulo)           \
+               sum -= modulo;                  \
+       } while (0)
+
+#define GSM_MAX_FN     (26*51*2048)
+
 struct gsm_time {
        uint32_t        fn;     /* FN count */
        uint16_t        t1;     /* FN div (26*51) */
diff --git a/src/shared/libosmocore/include/osmocore/protocol/gsm_08_08.h b/src/shared/libosmocore/include/osmocore/protocol/gsm_08_08.h
new file mode 100644 (file)
index 0000000..6b8f935
--- /dev/null
@@ -0,0 +1,303 @@
+/* From GSM08.08 */
+
+#ifndef GSM_0808_H
+#define GSM_0808_H
+
+#include <stdlib.h>
+
+/*
+ * this is from GSM 03.03 CGI but is copied in GSM 08.08
+ * in § 3.2.2.27 for Cell Identifier List
+ */
+enum CELL_IDENT {
+       CELL_IDENT_WHOLE_GLOBAL         = 0,
+       CELL_IDENT_LAC_AND_CI           = 1,
+       CELL_IDENT_CI                   = 2,
+       CELL_IDENT_NO_CELL              = 3,
+       CELL_IDENT_LAI_AND_LAC          = 4,
+       CELL_IDENT_LAC                  = 5,
+       CELL_IDENT_BSS                  = 6,
+       CELL_IDENT_UTRAN_PLMN_LAC_RNC   = 8,
+       CELL_IDENT_UTRAN_RNC            = 9,
+       CELL_IDENT_UTRAN_LAC_RNC        = 10,
+};
+
+
+/* GSM 08.06 § 6.3 */
+enum BSSAP_MSG_TYPE {
+       BSSAP_MSG_BSS_MANAGEMENT    = 0x0,
+       BSSAP_MSG_DTAP              = 0x1,
+};
+
+struct bssmap_header {
+       uint8_t type;
+       uint8_t length;
+} __attribute__((packed));
+
+struct dtap_header {
+       uint8_t type;
+       uint8_t link_id;
+       uint8_t length;
+} __attribute__((packed));
+
+
+enum BSS_MAP_MSG_TYPE {
+       BSS_MAP_MSG_RESERVED_0          = 0,
+
+       /* ASSIGNMENT MESSAGES */
+       BSS_MAP_MSG_ASSIGMENT_RQST      = 1,
+       BSS_MAP_MSG_ASSIGMENT_COMPLETE  = 2,
+       BSS_MAP_MSG_ASSIGMENT_FAILURE   = 3,
+
+       /*  HANDOVER MESSAGES */
+       BSS_MAP_MSG_HANDOVER_RQST               = 16,
+       BSS_MAP_MSG_HANDOVER_REQUIRED           = 17,
+       BSS_MAP_MSG_HANDOVER_RQST_ACKNOWLEDGE= 18,
+       BSS_MAP_MSG_HANDOVER_CMD                = 19,
+       BSS_MAP_MSG_HANDOVER_COMPLETE           = 20,
+       BSS_MAP_MSG_HANDOVER_SUCCEEDED          = 21,
+       BSS_MAP_MSG_HANDOVER_FAILURE            = 22,
+       BSS_MAP_MSG_HANDOVER_PERFORMED          = 23,
+       BSS_MAP_MSG_HANDOVER_CANDIDATE_ENQUIRE  = 24,
+       BSS_MAP_MSG_HANDOVER_CANDIDATE_RESPONSE = 25,
+       BSS_MAP_MSG_HANDOVER_REQUIRED_REJECT    = 26,
+       BSS_MAP_MSG_HANDOVER_DETECT             = 27,
+
+       /* RELEASE MESSAGES */
+       BSS_MAP_MSG_CLEAR_CMD           = 32,
+       BSS_MAP_MSG_CLEAR_COMPLETE              = 33,
+       BSS_MAP_MSG_CLEAR_RQST          = 34,
+       BSS_MAP_MSG_RESERVED_1                  = 35,
+       BSS_MAP_MSG_RESERVED_2                  = 36,
+       BSS_MAP_MSG_SAPI_N_REJECT               = 37,
+       BSS_MAP_MSG_CONFUSION                   = 38,
+
+       /* OTHER CONNECTION RELATED MESSAGES */
+       BSS_MAP_MSG_SUSPEND                     = 40,
+       BSS_MAP_MSG_RESUME                      = 41,
+       BSS_MAP_MSG_CONNECTION_ORIENTED_INFORMATION = 42,
+       BSS_MAP_MSG_PERFORM_LOCATION_RQST       = 43,
+       BSS_MAP_MSG_LSA_INFORMATION             = 44,
+       BSS_MAP_MSG_PERFORM_LOCATION_RESPONSE   = 45,
+       BSS_MAP_MSG_PERFORM_LOCATION_ABORT      = 46,
+       BSS_MAP_MSG_COMMON_ID                   = 47,
+
+       /* GENERAL MESSAGES */
+       BSS_MAP_MSG_RESET                       = 48,
+       BSS_MAP_MSG_RESET_ACKNOWLEDGE           = 49,
+       BSS_MAP_MSG_OVERLOAD                    = 50,
+       BSS_MAP_MSG_RESERVED_3                  = 51,
+       BSS_MAP_MSG_RESET_CIRCUIT               = 52,
+       BSS_MAP_MSG_RESET_CIRCUIT_ACKNOWLEDGE   = 53,
+       BSS_MAP_MSG_MSC_INVOKE_TRACE            = 54,
+       BSS_MAP_MSG_BSS_INVOKE_TRACE            = 55,
+       BSS_MAP_MSG_CONNECTIONLESS_INFORMATION  = 58,
+
+       /* TERRESTRIAL RESOURCE MESSAGES */
+       BSS_MAP_MSG_BLOCK                       = 64,
+       BSS_MAP_MSG_BLOCKING_ACKNOWLEDGE        = 65,
+       BSS_MAP_MSG_UNBLOCK                     = 66,
+       BSS_MAP_MSG_UNBLOCKING_ACKNOWLEDGE      = 67,
+       BSS_MAP_MSG_CIRCUIT_GROUP_BLOCK         = 68,
+       BSS_MAP_MSG_CIRCUIT_GROUP_BLOCKING_ACKNOWLEDGE  = 69,
+       BSS_MAP_MSG_CIRCUIT_GROUP_UNBLOCK       = 70,
+       BSS_MAP_MSG_CIRCUIT_GROUP_UNBLOCKING_ACKNOWLEDGE = 71,
+       BSS_MAP_MSG_UNEQUIPPED_CIRCUIT          = 72,
+       BSS_MAP_MSG_CHANGE_CIRCUIT              = 78,
+       BSS_MAP_MSG_CHANGE_CIRCUIT_ACKNOWLEDGE  = 79,
+
+       /* RADIO RESOURCE MESSAGES */
+       BSS_MAP_MSG_RESOURCE_RQST               = 80,
+       BSS_MAP_MSG_RESOURCE_INDICATION         = 81,
+       BSS_MAP_MSG_PAGING                      = 82,
+       BSS_MAP_MSG_CIPHER_MODE_CMD             = 83,
+       BSS_MAP_MSG_CLASSMARK_UPDATE            = 84,
+       BSS_MAP_MSG_CIPHER_MODE_COMPLETE        = 85,
+       BSS_MAP_MSG_QUEUING_INDICATION          = 86,
+       BSS_MAP_MSG_COMPLETE_LAYER_3            = 87,
+       BSS_MAP_MSG_CLASSMARK_RQST              = 88,
+       BSS_MAP_MSG_CIPHER_MODE_REJECT          = 89,
+       BSS_MAP_MSG_LOAD_INDICATION             = 90,
+
+       /* VGCS/VBS */
+       BSS_MAP_MSG_VGCS_VBS_SETUP              = 4,
+       BSS_MAP_MSG_VGCS_VBS_SETUP_ACK          = 5,
+       BSS_MAP_MSG_VGCS_VBS_SETUP_REFUSE       = 6,
+       BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RQST    = 7,
+       BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RESULT  = 28,
+       BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_FAILURE = 29,
+       BSS_MAP_MSG_VGCS_VBS_QUEUING_INDICATION = 30,
+       BSS_MAP_MSG_UPLINK_RQST         = 31,
+       BSS_MAP_MSG_UPLINK_RQST_ACKNOWLEDGE     = 39,
+       BSS_MAP_MSG_UPLINK_RQST_CONFIRMATION    = 73,
+       BSS_MAP_MSG_UPLINK_RELEASE_INDICATION   = 74,
+       BSS_MAP_MSG_UPLINK_REJECT_CMD   = 75,
+       BSS_MAP_MSG_UPLINK_RELEASE_CMD  = 76,
+       BSS_MAP_MSG_UPLINK_SEIZED_CMD   = 77,
+};
+
+enum GSM0808_IE_CODING {
+       GSM0808_IE_CIRCUIT_IDENTITY_CODE        = 1,
+       GSM0808_IE_RESERVED_0                   = 2,
+       GSM0808_IE_RESOURCE_AVAILABLE           = 3,
+       GSM0808_IE_CAUSE                        = 4,
+       GSM0808_IE_CELL_IDENTIFIER              = 5,
+       GSM0808_IE_PRIORITY                     = 6,
+       GSM0808_IE_LAYER_3_HEADER_INFORMATION   = 7,
+       GSM0808_IE_IMSI                         = 8,
+       GSM0808_IE_TMSI                         = 9,
+       GSM0808_IE_ENCRYPTION_INFORMATION       = 10,
+       GSM0808_IE_CHANNEL_TYPE                 = 11,
+       GSM0808_IE_PERIODICITY                  = 12,
+       GSM0808_IE_EXTENDED_RESOURCE_INDICATOR  = 13,
+       GSM0808_IE_NUMBER_OF_MSS                = 14,
+       GSM0808_IE_RESERVED_1                   = 15,
+       GSM0808_IE_RESERVED_2                   = 16,
+       GSM0808_IE_RESERVED_3                   = 17,
+       GSM0808_IE_CLASSMARK_INFORMATION_T2     = 18,
+       GSM0808_IE_CLASSMARK_INFORMATION_T3     = 19,
+       GSM0808_IE_INTERFERENCE_BAND_TO_USE     = 20,
+       GSM0808_IE_RR_CAUSE                     = 21,
+       GSM0808_IE_RESERVED_4                   = 22,
+       GSM0808_IE_LAYER_3_INFORMATION          = 23,
+       GSM0808_IE_DLCI                         = 24,
+       GSM0808_IE_DOWNLINK_DTX_FLAG            = 25,
+       GSM0808_IE_CELL_IDENTIFIER_LIST         = 26,
+       GSM0808_IE_RESPONSE_RQST                = 27,
+       GSM0808_IE_RESOURCE_INDICATION_METHOD   = 28,
+       GSM0808_IE_CLASSMARK_INFORMATION_TYPE_1 = 29,
+       GSM0808_IE_CIRCUIT_IDENTITY_CODE_LIST   = 30,
+       GSM0808_IE_DIAGNOSTIC                   = 31,
+       GSM0808_IE_LAYER_3_MESSAGE_CONTENTS     = 32,
+       GSM0808_IE_CHOSEN_CHANNEL               = 33,
+       GSM0808_IE_TOTAL_RESOURCE_ACCESSIBLE    = 34,
+       GSM0808_IE_CIPHER_RESPONSE_MODE         = 35,
+       GSM0808_IE_CHANNEL_NEEDED               = 36,
+       GSM0808_IE_TRACE_TYPE                   = 37,
+       GSM0808_IE_TRIGGERID                    = 38,
+       GSM0808_IE_TRACE_REFERENCE              = 39,
+       GSM0808_IE_TRANSACTIONID                = 40,
+       GSM0808_IE_MOBILE_IDENTITY              = 41,
+       GSM0808_IE_OMCID                        = 42,
+       GSM0808_IE_FORWARD_INDICATOR            = 43,
+       GSM0808_IE_CHOSEN_ENCR_ALG              = 44,
+       GSM0808_IE_CIRCUIT_POOL                 = 45,
+       GSM0808_IE_CIRCUIT_POOL_LIST            = 46,
+       GSM0808_IE_TIME_INDICATION              = 47,
+       GSM0808_IE_RESOURCE_SITUATION           = 48,
+       GSM0808_IE_CURRENT_CHANNEL_TYPE_1       = 49,
+       GSM0808_IE_QUEUEING_INDICATOR           = 50,
+       GSM0808_IE_SPEECH_VERSION               = 64,
+       GSM0808_IE_ASSIGNMENT_REQUIREMENT       = 51,
+       GSM0808_IE_TALKER_FLAG                  = 53,
+       GSM0808_IE_CONNECTION_RELEASE_RQSTED    = 54,
+       GSM0808_IE_GROUP_CALL_REFERENCE         = 55,
+       GSM0808_IE_EMLPP_PRIORITY               = 56,
+       GSM0808_IE_CONFIG_EVO_INDI              = 57,
+       GSM0808_IE_OLD_BSS_TO_NEW_BSS_INFORMATION       = 58,
+       GSM0808_IE_LSA_IDENTIFIER               = 59,
+       GSM0808_IE_LSA_IDENTIFIER_LIST          = 60,
+       GSM0808_IE_LSA_INFORMATION              = 61,
+       GSM0808_IE_LCS_QOS                      = 62,
+       GSM0808_IE_LSA_ACCESS_CTRL_SUPPR        = 63,
+       GSM0808_IE_LCS_PRIORITY                 = 67,
+       GSM0808_IE_LOCATION_TYPE                = 68,
+       GSM0808_IE_LOCATION_ESTIMATE            = 69,
+       GSM0808_IE_POSITIONING_DATA             = 70,
+       GSM0808_IE_LCS_CAUSE                    = 71,
+       GSM0808_IE_LCS_CLIENT_TYPE              = 72,
+       GSM0808_IE_APDU                         = 73,
+       GSM0808_IE_NETWORK_ELEMENT_IDENTITY     = 74,
+       GSM0808_IE_GPS_ASSISTANCE_DATA          = 75,
+       GSM0808_IE_DECIPHERING_KEYS             = 76,
+       GSM0808_IE_RETURN_ERROR_RQST            = 77,
+       GSM0808_IE_RETURN_ERROR_CAUSE           = 78,
+       GSM0808_IE_SEGMENTATION                 = 79,
+       GSM0808_IE_SERVICE_HANDOVER             = 80,
+       GSM0808_IE_SOURCE_RNC_TO_TARGET_RNC_TRANSPARENT_UMTS    = 81,
+       GSM0808_IE_SOURCE_RNC_TO_TARGET_RNC_TRANSPARENT_CDMA2000= 82,
+       GSM0808_IE_RESERVED_5                   = 65,
+       GSM0808_IE_RESERVED_6                   = 66,
+};
+
+enum gsm0808_cause {
+       GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE                   = 0,
+       GSM0808_CAUSE_RADIO_INTERFACE_FAILURE                           = 1,
+       GSM0808_CAUSE_UPLINK_QUALITY                                    = 2,
+       GSM0808_CAUSE_UPLINK_STRENGTH                                   = 3,
+       GSM0808_CAUSE_DOWNLINK_QUALITY                                  = 4,
+       GSM0808_CAUSE_DOWNLINK_STRENGTH                                 = 5,
+       GSM0808_CAUSE_DISTANCE                                          = 6,
+       GSM0808_CAUSE_O_AND_M_INTERVENTION                              = 7,
+       GSM0808_CAUSE_RESPONSE_TO_MSC_INVOCATION                        = 8,
+       GSM0808_CAUSE_CALL_CONTROL                                      = 9,
+       GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION                 = 10,
+       GSM0808_CAUSE_HANDOVER_SUCCESSFUL                               = 11,
+       GSM0808_CAUSE_BETTER_CELL                                       = 12,
+       GSM0808_CAUSE_DIRECTED_RETRY                                    = 13,
+       GSM0808_CAUSE_JOINED_GROUP_CALL_CHANNEL                         = 14,
+       GSM0808_CAUSE_TRAFFIC                                           = 15,
+       GSM0808_CAUSE_EQUIPMENT_FAILURE                                 = 32,
+       GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE                       = 33,
+       GSM0808_CAUSE_RQSTED_TERRESTRIAL_RESOURCE_UNAVAILABLE   = 34,
+       GSM0808_CAUSE_CCCH_OVERLOAD                                     = 35,
+       GSM0808_CAUSE_PROCESSOR_OVERLOAD                                = 36,
+       GSM0808_CAUSE_BSS_NOT_EQUIPPED                                  = 37,
+       GSM0808_CAUSE_MS_NOT_EQUIPPED                                   = 38,
+       GSM0808_CAUSE_INVALID_CELL                                      = 39,
+       GSM0808_CAUSE_TRAFFIC_LOAD                                      = 40,
+       GSM0808_CAUSE_PREEMPTION                                        = 41,
+       GSM0808_CAUSE_RQSTED_TRANSCODING_RATE_ADAPTION_UNAVAILABLE      = 48,
+       GSM0808_CAUSE_CIRCUIT_POOL_MISMATCH                             = 49,
+       GSM0808_CAUSE_SWITCH_CIRCUIT_POOL                               = 50,
+       GSM0808_CAUSE_RQSTED_SPEECH_VERSION_UNAVAILABLE         = 51,
+       GSM0808_CAUSE_LSA_NOT_ALLOWED                                   = 52,
+       GSM0808_CAUSE_CIPHERING_ALGORITHM_NOT_SUPPORTED                 = 64,
+       GSM0808_CAUSE_TERRESTRIAL_CIRCUIT_ALREADY_ALLOCATED             = 80,
+       GSM0808_CAUSE_INVALID_MESSAGE_CONTENTS                          = 81,
+       GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING              = 82,
+       GSM0808_CAUSE_INCORRECT_VALUE                                   = 83,
+       GSM0808_CAUSE_UNKNOWN_MESSAGE_TYPE                              = 84,
+       GSM0808_CAUSE_UNKNOWN_INFORMATION_ELEMENT                       = 85,
+       GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC                = 96,
+};
+
+/* GSM 08.08 3.2.2.11 Channel Type */
+enum gsm0808_chan_indicator {
+       GSM0808_CHAN_SPEECH = 1,
+       GSM0808_CHAN_DATA   = 2,
+       GSM0808_CHAN_SIGN   = 3,
+};
+
+enum gsm0808_chan_rate_type_data {
+       GSM0808_DATA_FULL_BM    = 0x8,
+       GSM0808_DATA_HALF_LM    = 0x9,
+       GSM0808_DATA_FULL_RPREF = 0xa,
+       GSM0808_DATA_HALF_PREF  = 0xb,
+       GSM0808_DATA_FULL_PREF_NO_CHANGE        = 0x1a,
+       GSM0808_DATA_HALF_PREF_NO_CHANGE        = 0x1b,
+       GSM0808_DATA_MULTI_MASK = 0x20,
+       GSM0808_DATA_MULTI_MASK_NO_CHANGE       = 0x30,
+};
+
+enum gsm0808_chan_rate_type_speech {
+       GSM0808_SPEECH_FULL_BM  = 0x8,
+       GSM0808_SPEECH_HALF_LM  = 0x9,
+       GSM0808_SPEECH_FULL_PREF= 0xa,
+       GSM0808_SPEECH_HALF_PREF= 0xb,
+       GSM0808_SPEECH_FULL_PREF_NO_CHANGE      = 0x1a,
+       GSM0808_SPEECH_HALF_PREF_NO_CHANGE      = 0x1b,
+       GSM0808_SPEECH_PERM     = 0xf,
+       GSM0808_SPEECH_PERM_NO_CHANGE = 0x1f,
+};
+
+enum gsm0808_permitted_speech {
+       GSM0808_PERM_FR1        = 0x01,
+       GSM0808_PERM_FR2        = 0x11,
+       GSM0808_PERM_FR3        = 0x21,
+       GSM0808_PERM_HR1        = GSM0808_PERM_FR1 | 0x4,
+       GSM0808_PERM_HR2        = GSM0808_PERM_FR2 | 0x4,
+       GSM0808_PERM_HR3        = GSM0808_PERM_FR3 | 0x4,
+};
+
+#endif
index 1697807..20e99db 100644 (file)
@@ -10,7 +10,7 @@ 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
+                        logging.c gsm0808.c
 
 if ENABLE_TALLOC
 libosmocore_la_SOURCES += talloc.c
diff --git a/src/shared/libosmocore/src/gsm0808.c b/src/shared/libosmocore/src/gsm0808.c
new file mode 100644 (file)
index 0000000..7a7eb3a
--- /dev/null
@@ -0,0 +1,295 @@
+/* (C) 2009,2010 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009,2010 by On-Waves
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <osmocore/gsm0808.h>
+#include <osmocore/protocol/gsm_08_08.h>
+#include <osmocore/gsm48.h>
+
+#include <arpa/inet.h>
+
+#define BSSMAP_MSG_SIZE 512
+#define BSSMAP_MSG_HEADROOM 128
+
+struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc, uint16_t cc, int lac, int _ci)
+{
+       uint8_t *data;
+       uint16_t *ci;
+       struct msgb* msg;
+       struct gsm48_loc_area_id *lai;
+
+       msg  = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
+                                  "bssmap cmpl l3");
+       if (!msg)
+               return NULL;
+
+       /* create the bssmap header */
+       msg->l3h = msgb_put(msg, 2);
+       msg->l3h[0] = 0x0;
+
+       /* create layer 3 header */
+       data = msgb_put(msg, 1);
+       data[0] = BSS_MAP_MSG_COMPLETE_LAYER_3;
+
+       /* create the cell header */
+       data = msgb_put(msg, 3);
+       data[0] = GSM0808_IE_CELL_IDENTIFIER;
+       data[1] = 1 + sizeof(*lai) + 2;
+       data[2] = CELL_IDENT_WHOLE_GLOBAL;
+
+       lai = (struct gsm48_loc_area_id *) msgb_put(msg, sizeof(*lai));
+       gsm48_generate_lai(lai, cc, nc, lac);
+
+       ci = (uint16_t *) msgb_put(msg, 2);
+       *ci = htons(_ci);
+
+       /* copy the layer3 data */
+       data = msgb_put(msg, msgb_l3len(msg_l3) + 2);
+       data[0] = GSM0808_IE_LAYER_3_INFORMATION;
+       data[1] = msgb_l3len(msg_l3);
+       memcpy(&data[2], msg_l3->l3h, data[1]);
+
+       /* update the size */
+       msg->l3h[1] = msgb_l3len(msg) - 2;
+
+       return msg;
+}
+
+struct msgb *gsm0808_create_reset(void)
+{
+       struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
+                                              "bssmap: reset");
+       if (!msg)
+               return NULL;
+
+       msg->l3h = msgb_put(msg, 6);
+       msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
+       msg->l3h[1] = 0x04;
+       msg->l3h[2] = 0x30;
+       msg->l3h[3] = 0x04;
+       msg->l3h[4] = 0x01;
+       msg->l3h[5] = 0x20;
+       return msg;
+}
+
+struct msgb *gsm0808_create_clear_complete(void)
+{
+       struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
+                                              "bssmap: clear complete");
+       if (!msg)
+               return NULL;
+
+       msg->l3h = msgb_put(msg, 3);
+       msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
+       msg->l3h[1] = 1;
+       msg->l3h[2] = BSS_MAP_MSG_CLEAR_COMPLETE;
+
+       return msg;
+}
+
+struct msgb *gsm0808_create_cipher_complete(struct msgb *layer3, uint8_t alg_id)
+{
+       struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
+                                              "cipher-complete");
+       if (!msg)
+               return NULL;
+
+        /* send response with BSS override for A5/1... cheating */
+       msg->l3h = msgb_put(msg, 3);
+       msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
+       msg->l3h[1] = 0xff;
+       msg->l3h[2] = BSS_MAP_MSG_CIPHER_MODE_COMPLETE;
+
+       /* include layer3 in case we have at least two octets */
+       if (layer3 && msgb_l3len(layer3) > 2) {
+               msg->l4h = msgb_put(msg, msgb_l3len(layer3) + 2);
+               msg->l4h[0] = GSM0808_IE_LAYER_3_MESSAGE_CONTENTS;
+               msg->l4h[1] = msgb_l3len(layer3);
+               memcpy(&msg->l4h[2], layer3->l3h, msgb_l3len(layer3));
+       }
+
+       /* and the optional BSS message */
+       msg->l4h = msgb_put(msg, 2);
+       msg->l4h[0] = GSM0808_IE_CHOSEN_ENCR_ALG;
+       msg->l4h[1] = alg_id;
+
+       /* update the size */
+       msg->l3h[1] = msgb_l3len(msg) - 2;
+       return msg;
+}
+
+struct msgb *gsm0808_create_cipher_reject(uint8_t cause)
+{
+       struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
+                                              "bssmap: clear complete");
+       if (!msg)
+               return NULL;
+
+       msg->l3h = msgb_put(msg, 3);
+       msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
+       msg->l3h[1] = 2;
+       msg->l3h[2] = BSS_MAP_MSG_CIPHER_MODE_REJECT;
+       msg->l3h[3] = cause;
+
+       return msg;
+}
+
+struct msgb *gsm0808_create_classmark_update(const uint8_t *classmark_data, uint8_t length)
+{
+       struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
+                                              "classmark-update");
+       if (!msg)
+               return NULL;
+
+       msg->l3h = msgb_put(msg, 3);
+       msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
+       msg->l3h[1] = 0xff;
+       msg->l3h[2] = BSS_MAP_MSG_CLASSMARK_UPDATE;
+
+       msg->l4h = msgb_put(msg, length);
+       memcpy(msg->l4h, classmark_data, length);
+
+       /* update the size */
+       msg->l3h[1] = msgb_l3len(msg) - 2;
+       return msg;
+}
+
+struct msgb *gsm0808_create_sapi_reject(uint8_t link_id)
+{
+       struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
+                                              "bssmap: sapi 'n' reject");
+       if (!msg)
+               return NULL;
+
+       msg->l3h = msgb_put(msg, 5);
+       msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
+       msg->l3h[1] = 3;
+       msg->l3h[2] = BSS_MAP_MSG_SAPI_N_REJECT;
+       msg->l3h[3] = link_id;
+       msg->l3h[4] = GSM0808_CAUSE_BSS_NOT_EQUIPPED;
+
+       return msg;
+}
+
+struct msgb *gsm0808_create_assignment_completed(struct gsm_lchan *lchan, uint8_t rr_cause,
+                                                uint8_t chosen_channel, uint8_t encr_alg_id,
+                                                uint8_t speech_mode)
+{
+       uint8_t *data;
+
+       struct msgb *msg = msgb_alloc(35, "bssmap: ass compl");
+       if (!msg)
+               return NULL;
+
+       msg->l3h = msgb_put(msg, 3);
+       msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
+       msg->l3h[1] = 0xff;
+       msg->l3h[2] = BSS_MAP_MSG_ASSIGMENT_COMPLETE;
+
+       /* write 3.2.2.22 */
+       data = msgb_put(msg, 2);
+       data[0] = GSM0808_IE_RR_CAUSE;
+       data[1] = rr_cause;
+
+       /* write cirtcuit identity  code 3.2.2.2 */
+       /* write cell identifier 3.2.2.17 */
+       /* write chosen channel 3.2.2.33 when BTS picked it */
+       data = msgb_put(msg, 2);
+       data[0] = GSM0808_IE_CHOSEN_CHANNEL;
+       data[1] = chosen_channel;
+
+       /* write chosen encryption algorithm 3.2.2.44 */
+       data = msgb_put(msg, 2);
+       data[0] = GSM0808_IE_CHOSEN_ENCR_ALG;
+       data[1] = encr_alg_id;
+
+       /* write circuit pool 3.2.2.45 */
+       /* write speech version chosen: 3.2.2.51 when BTS picked it */
+       if (speech_mode != 0) {
+               data = msgb_put(msg, 2);
+               data[0] = GSM0808_IE_SPEECH_VERSION;
+               data[1] = speech_mode;
+       }
+
+       /* write LSA identifier 3.2.2.15 */
+
+
+       /* update the size */
+       msg->l3h[1] = msgb_l3len(msg) - 2;
+       return msg;
+}
+
+struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause)
+{
+       uint8_t *data;
+       struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
+                                              "bssmap: ass fail");
+       if (!msg)
+               return NULL;
+
+       msg->l3h = msgb_put(msg, 6);
+       msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
+       msg->l3h[1] = 0xff;
+       msg->l3h[2] = BSS_MAP_MSG_ASSIGMENT_FAILURE;
+       msg->l3h[3] = GSM0808_IE_CAUSE;
+       msg->l3h[4] = 1;
+       msg->l3h[5] = cause;
+
+       /* RR cause 3.2.2.22 */
+       if (rr_cause) {
+               data = msgb_put(msg, 2);
+               data[0] = GSM0808_IE_RR_CAUSE;
+               data[1] = *rr_cause;
+       }
+
+       /* Circuit pool 3.22.45 */
+       /* Circuit pool list 3.2.2.46 */
+
+       /* update the size */
+       msg->l3h[1] = msgb_l3len(msg) - 2;
+       return msg;
+}
+
+static const struct tlv_definition bss_att_tlvdef = {
+       .def = {
+               [GSM0808_IE_IMSI]                   = { TLV_TYPE_TLV },
+               [GSM0808_IE_TMSI]                   = { TLV_TYPE_TLV },
+               [GSM0808_IE_CELL_IDENTIFIER_LIST]   = { TLV_TYPE_TLV },
+               [GSM0808_IE_CHANNEL_NEEDED]         = { TLV_TYPE_TV },
+               [GSM0808_IE_EMLPP_PRIORITY]         = { TLV_TYPE_TV },
+               [GSM0808_IE_CHANNEL_TYPE]           = { TLV_TYPE_TLV },
+               [GSM0808_IE_PRIORITY]               = { TLV_TYPE_TLV },
+               [GSM0808_IE_CIRCUIT_IDENTITY_CODE]  = { TLV_TYPE_TV },
+               [GSM0808_IE_DOWNLINK_DTX_FLAG]      = { TLV_TYPE_TV },
+               [GSM0808_IE_INTERFERENCE_BAND_TO_USE] = { TLV_TYPE_TV },
+               [GSM0808_IE_CLASSMARK_INFORMATION_T2] = { TLV_TYPE_TLV },
+               [GSM0808_IE_GROUP_CALL_REFERENCE]   = { TLV_TYPE_TLV },
+               [GSM0808_IE_TALKER_FLAG]            = { TLV_TYPE_T },
+               [GSM0808_IE_CONFIG_EVO_INDI]        = { TLV_TYPE_TV },
+               [GSM0808_IE_LSA_ACCESS_CTRL_SUPPR]  = { TLV_TYPE_TV },
+               [GSM0808_IE_SERVICE_HANDOVER]       = { TLV_TYPE_TV},
+               [GSM0808_IE_ENCRYPTION_INFORMATION] = { TLV_TYPE_TLV },
+               [GSM0808_IE_CIPHER_RESPONSE_MODE]   = { TLV_TYPE_TV },
+       },
+};
+
+const struct tlv_definition *gsm0808_att_tlvdef()
+{
+       return &bss_att_tlvdef;
+}
index 9517778..2f6afa7 100644 (file)
@@ -121,7 +121,8 @@ restart:
                /* 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)
+               /* this seems to happen with the last element of the list as well */
+               if (unregistered_count >= 1)
                        goto restart;
        }
        return work;