summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/mncc.h19
-rw-r--r--src/host/layer23/src/mobile/mncc_sock.c35
2 files changed, 54 insertions, 0 deletions
diff --git a/src/host/layer23/include/osmocom/bb/mobile/mncc.h b/src/host/layer23/include/osmocom/bb/mobile/mncc.h
index a56f5098..91e6ff9d 100644
--- a/src/host/layer23/include/osmocom/bb/mobile/mncc.h
+++ b/src/host/layer23/include/osmocom/bb/mobile/mncc.h
@@ -29,6 +29,8 @@
#include <osmocom/core/linuxlist.h>
#include <osmocom/gsm/mncc.h>
+#define MNCC_SOCK_VERSION 5
+
struct gsm_call {
struct llist_head entry;
@@ -111,6 +113,8 @@ struct gsm_call {
#define GSM_TCHH_FRAME 0x0302
#define GSM_TCH_FRAME_AMR 0x0303
+#define MNCC_SOCKET_HELLO 0x0400
+
#define GSM_MAX_FACILITY 128
#define GSM_MAX_SSVERSION 128
#define GSM_MAX_USERUSER 128
@@ -173,6 +177,21 @@ struct gsm_data_frame {
unsigned char data[0];
};
+struct gsm_mncc_hello {
+ uint32_t msg_type;
+ uint32_t version;
+
+ /* The sizes of some structures */
+ uint32_t mncc_size;
+ uint32_t data_frame_size;
+
+ /* Some offsets */
+ uint32_t called_offset;
+ uint32_t signal_offset;
+ uint32_t emergency_offset;
+ uint32_t lchan_type_offset;
+};
+
const char *get_mncc_name(int value);
int mncc_recv(struct osmocom_ms *ms, int msg_type, void *arg);
void mncc_set_cause(struct gsm_mncc *data, int loc, int val);
diff --git a/src/host/layer23/src/mobile/mncc_sock.c b/src/host/layer23/src/mobile/mncc_sock.c
index d7d56cc0..5d8d2dd1 100644
--- a/src/host/layer23/src/mobile/mncc_sock.c
+++ b/src/host/layer23/src/mobile/mncc_sock.c
@@ -206,6 +206,38 @@ static int mncc_sock_cb(struct osmo_fd *bfd, unsigned int flags)
return rc;
}
+/* Send a version indication to the remote */
+static void mncc_sock_queue_hello(struct mncc_sock_state *state)
+{
+ struct gsm_mncc_hello *hello;
+ struct msgb *msg;
+
+ msg = msgb_alloc(sizeof(*hello), "MNCC_SOCKET_HELLO");
+ if (!msg) {
+ LOGP(DMNCC, LOGL_ERROR, "Failed to allocate MNCC_SOCKET_HELLO\n");
+ mncc_sock_close(state);
+ return;
+ }
+
+ /* Put header */
+ hello = (struct gsm_mncc_hello *) msgb_put(msg, sizeof(*hello));
+ hello->msg_type = MNCC_SOCKET_HELLO;
+ hello->version = MNCC_SOCK_VERSION;
+
+ /* The sizes of some structures */
+ hello->mncc_size = sizeof(struct gsm_mncc);
+ hello->data_frame_size = sizeof(struct gsm_data_frame);
+
+ /* Some offsets */
+ hello->called_offset = offsetof(struct gsm_mncc, called);
+ hello->signal_offset = offsetof(struct gsm_mncc, signal);
+ hello->emergency_offset = offsetof(struct gsm_mncc, emergency);
+ hello->lchan_type_offset = offsetof(struct gsm_mncc, lchan_type);
+
+ msgb_enqueue(&state->upqueue, msg);
+ state->conn_bfd.when |= BSC_FD_WRITE;
+}
+
/* accept a new connection */
static int mncc_sock_accept(struct osmo_fd *bfd, unsigned int flags)
{
@@ -246,6 +278,9 @@ static int mncc_sock_accept(struct osmo_fd *bfd, unsigned int flags)
LOGP(DMNCC, LOGL_NOTICE, "MNCC Socket has connection with external "
"call control application\n");
+ /* Send HELLO */
+ mncc_sock_queue_hello(state);
+
return 0;
}