nas_itti_messaging.c 10.8 KB
Newer Older
1
/*******************************************************************************
gauthier's avatar
GPLv3    
gauthier committed
2
3
    OpenAirInterface
    Copyright(c) 1999 - 2014 Eurecom
4

gauthier's avatar
GPLv3    
gauthier committed
5
6
7
8
    OpenAirInterface 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.
9
10


gauthier's avatar
GPLv3    
gauthier committed
11
12
13
14
    OpenAirInterface 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.
15

gauthier's avatar
GPLv3    
gauthier committed
16
17
18
19
    You should have received a copy of the GNU General Public License
    along with OpenAirInterface.The full GNU General Public License is
   included in this distribution in the file called "COPYING". If not,
   see <http://www.gnu.org/licenses/>.
20
21

  Contact Information
gauthier's avatar
GPLv3    
gauthier committed
22
23
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
24
  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
25

gauthier's avatar
GPLv3    
gauthier committed
26
  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
27

gauthier's avatar
GPLv3    
gauthier committed
28
 *******************************************************************************/
Cedric Roux's avatar
Cedric Roux committed
29
30
#include <string.h>

31
32
#include "intertask_interface.h"
#include "nas_itti_messaging.h"
gauthier's avatar
gauthier committed
33
#include "msc.h"
34

35
36
#   define TASK_ORIGIN  TASK_NAS_UE

gauthier's avatar
   
gauthier committed
37
#if (defined(ENABLE_NAS_UE_LOGGING) && defined(NAS_BUILT_IN_UE) )
38
static const uint8_t emm_message_ids[] = {
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
  ATTACH_REQUEST,
  ATTACH_ACCEPT,
  ATTACH_COMPLETE,
  ATTACH_REJECT,
  DETACH_REQUEST,
  DETACH_ACCEPT,
  TRACKING_AREA_UPDATE_REQUEST,
  TRACKING_AREA_UPDATE_ACCEPT,
  TRACKING_AREA_UPDATE_COMPLETE,
  TRACKING_AREA_UPDATE_REJECT,
  EXTENDED_SERVICE_REQUEST,
  SERVICE_REQUEST,
  SERVICE_REJECT,
  GUTI_REALLOCATION_COMMAND,
  GUTI_REALLOCATION_COMPLETE,
  AUTHENTICATION_REQUEST,
  AUTHENTICATION_RESPONSE,
  AUTHENTICATION_REJECT,
  AUTHENTICATION_FAILURE,
  IDENTITY_REQUEST,
  IDENTITY_RESPONSE,
  SECURITY_MODE_COMMAND,
  SECURITY_MODE_COMPLETE,
  SECURITY_MODE_REJECT,
  EMM_STATUS,
  EMM_INFORMATION,
  DOWNLINK_NAS_TRANSPORT,
  UPLINK_NAS_TRANSPORT,
  CS_SERVICE_NOTIFICATION,
winckel's avatar
winckel committed
68
69
};

70
static const uint8_t esm_message_ids[] = {
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
  ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST,
  ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT,
  ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REJECT,
  ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REQUEST,
  ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_ACCEPT,
  ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REJECT,
  MODIFY_EPS_BEARER_CONTEXT_REQUEST,
  MODIFY_EPS_BEARER_CONTEXT_ACCEPT,
  MODIFY_EPS_BEARER_CONTEXT_REJECT,
  DEACTIVATE_EPS_BEARER_CONTEXT_REQUEST,
  DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT,
  PDN_CONNECTIVITY_REQUEST,
  PDN_CONNECTIVITY_REJECT,
  PDN_DISCONNECT_REQUEST,
  PDN_DISCONNECT_REJECT,
  BEARER_RESOURCE_ALLOCATION_REQUEST,
  BEARER_RESOURCE_ALLOCATION_REJECT,
  BEARER_RESOURCE_MODIFICATION_REQUEST,
  BEARER_RESOURCE_MODIFICATION_REJECT,
  ESM_INFORMATION_REQUEST,
  ESM_INFORMATION_RESPONSE,
  ESM_STATUS,
winckel's avatar
winckel committed
93
94
};

95
static int _nas_find_message_index(const uint8_t message_id, const uint8_t *message_ids, const int ids_number)
winckel's avatar
winckel committed
96
{
97
98
99
100
101
  int i;

  for(i = 0; i < ids_number; i ++) {
    if (message_id == message_ids[i]) {
      return (2 + i);
winckel's avatar
winckel committed
102
    }
103
  }
winckel's avatar
winckel committed
104

105
  return (1);
winckel's avatar
winckel committed
106
107
}

winckel's avatar
winckel committed
108
int nas_itti_plain_msg(const char *buffer, const nas_message_t *msg, const int length, const int down_link)
winckel's avatar
winckel committed
109
{
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
  MessageDef *message_p;
  int data_length = length < NAS_DATA_LENGHT_MAX ? length : NAS_DATA_LENGHT_MAX;
  int message_type = -1;
  MessagesIds messageId_raw = -1;
  MessagesIds messageId_plain = -1;

  /* Define message ids */
  if (msg->header.protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE) {
    message_type    = 0;
    messageId_raw   = down_link ? NAS_DL_EMM_RAW_MSG : NAS_UL_EMM_RAW_MSG;
    messageId_plain = down_link ? NAS_DL_EMM_PLAIN_MSG : NAS_UL_EMM_PLAIN_MSG;
  } else {
    if (msg->header.protocol_discriminator == EPS_SESSION_MANAGEMENT_MESSAGE) {
      message_type    = 1;
      messageId_raw   = down_link ? NAS_DL_ESM_RAW_MSG : NAS_UL_ESM_RAW_MSG;
      messageId_plain = down_link ? NAS_DL_ESM_PLAIN_MSG : NAS_UL_ESM_PLAIN_MSG;
126
    }
127
  }
winckel's avatar
winckel committed
128

129
130
131
  if (message_type >= 0) {
    /* Create and send the RAW message */
    message_p = itti_alloc_new_message(TASK_ORIGIN, messageId_raw);
132

133
134
135
    NAS_DL_EMM_RAW_MSG(message_p).lenght = length;
    memset ((void *) &(NAS_DL_EMM_RAW_MSG(message_p).data), 0, NAS_DATA_LENGHT_MAX);
    memcpy ((void *) &(NAS_DL_EMM_RAW_MSG(message_p).data), buffer, data_length);
136

137
    itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
138

139
140
141
    /* Create and send the plain message */
    if (message_type == 0) {
      message_p = itti_alloc_new_message(TASK_ORIGIN, messageId_plain);
winckel's avatar
winckel committed
142

143
144
145
146
      NAS_DL_EMM_PLAIN_MSG(message_p).present = _nas_find_message_index(msg->plain.emm.header.message_type, emm_message_ids, sizeof(emm_message_ids) / sizeof(emm_message_ids[0]));
      memcpy ((void *) &(NAS_DL_EMM_PLAIN_MSG(message_p).choice), &msg->plain.emm, sizeof (EMM_msg));
    } else {
      message_p = itti_alloc_new_message(TASK_ORIGIN, messageId_plain);
winckel's avatar
winckel committed
147

148
149
      NAS_DL_ESM_PLAIN_MSG(message_p).present = _nas_find_message_index(msg->plain.esm.header.message_type, esm_message_ids, sizeof(esm_message_ids) / sizeof(esm_message_ids[0]));
      memcpy ((void *) &(NAS_DL_ESM_PLAIN_MSG(message_p).choice), &msg->plain.esm, sizeof (ESM_msg));
winckel's avatar
winckel committed
150
151
    }

152
153
154
155
    return itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
  }

  return EXIT_FAILURE;
winckel's avatar
winckel committed
156
157
}

winckel's avatar
winckel committed
158
int nas_itti_protected_msg(const char *buffer, const nas_message_t *msg, const int length, const int down_link)
winckel's avatar
winckel committed
159
{
160
  MessageDef *message_p = NULL;
winckel's avatar
winckel committed
161

162
163
  if (msg->header.protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE) {
    message_p = itti_alloc_new_message(TASK_ORIGIN, down_link ? NAS_DL_EMM_PROTECTED_MSG : NAS_UL_EMM_PROTECTED_MSG);
winckel's avatar
winckel committed
164

165
166
167
168
169
170
    memcpy ((void *) &(NAS_DL_EMM_PROTECTED_MSG(message_p).header), &msg->header, sizeof (nas_message_security_header_t));
    NAS_DL_EMM_PROTECTED_MSG(message_p).present = _nas_find_message_index(msg->security_protected.plain.emm.header.message_type, emm_message_ids, sizeof(emm_message_ids) / sizeof(emm_message_ids[0]));
    memcpy ((void *) &(NAS_DL_EMM_PROTECTED_MSG(message_p).choice), &msg->security_protected.plain.emm, sizeof (EMM_msg));
  } else {
    if (msg->header.protocol_discriminator == EPS_SESSION_MANAGEMENT_MESSAGE) {
      message_p = itti_alloc_new_message(TASK_ORIGIN, down_link ? NAS_DL_ESM_PROTECTED_MSG : NAS_UL_ESM_PROTECTED_MSG);
winckel's avatar
winckel committed
171

172
173
174
      memcpy ((void *) &(NAS_DL_ESM_PROTECTED_MSG(message_p).header), &msg->header, sizeof (nas_message_security_header_t));
      NAS_DL_ESM_PROTECTED_MSG(message_p).present =  _nas_find_message_index(msg->security_protected.plain.esm.header.message_type, esm_message_ids, sizeof(esm_message_ids) / sizeof(esm_message_ids[0]));
      memcpy ((void *) &(NAS_DL_ESM_PROTECTED_MSG(message_p).choice), &msg->security_protected.plain.esm, sizeof (ESM_msg));
winckel's avatar
winckel committed
175
    }
176
177
178
179
180
  }

  if (message_p != NULL) {
    return itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
  }
winckel's avatar
winckel committed
181

182
  return EXIT_FAILURE;
winckel's avatar
winckel committed
183
}
184
185
#endif

186

gauthier's avatar
gauthier committed
187

188
189
extern unsigned char NB_eNB_INST;

190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
int nas_itti_kenb_refresh_req(const Byte_t kenb[32])
{
  MessageDef *message_p;

  message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_KENB_REFRESH_REQ);

  memcpy(NAS_KENB_REFRESH_REQ(message_p).kenb, kenb, sizeof(NAS_KENB_REFRESH_REQ(message_p).kenb));

  MSC_LOG_TX_MESSAGE(
      MSC_NAS_UE,
      MSC_RRC_UE,
      NULL,0,
      "0 NAS_KENB_REFRESH_REQ KeNB "
      "%02x%02x%02x%02x"
      "%02x%02x%02x%02x"
      "%02x%02x%02x%02x"
      "%02x%02x%02x%02x"
      "%02x%02x%02x%02x"
      "%02x%02x%02x%02x"
      "%02x%02x%02x%02x"
      "%02x%02x%02x%02x",
      kenb[0],  kenb[1],  kenb[2],  kenb[3],
      kenb[4],  kenb[5],  kenb[6],  kenb[7],
      kenb[8],  kenb[9],  kenb[10], kenb[11],
      kenb[12], kenb[13], kenb[14], kenb[15],
      kenb[16], kenb[17], kenb[18], kenb[19],
      kenb[20], kenb[21], kenb[22], kenb[23],
      kenb[24], kenb[25], kenb[26], kenb[27],
      kenb[28], kenb[29], kenb[30], kenb[31]);

  return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + 0 /* TODO to be virtualized */, message_p);
}

223
224
int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat)
{
225
  MessageDef *message_p;
226

227
  message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_CELL_SELECTION_REQ);
228

229
230
  NAS_CELL_SELECTION_REQ(message_p).plmnID    = plmnID;
  NAS_CELL_SELECTION_REQ(message_p).rat       = rat;
231

gauthier's avatar
gauthier committed
232
233
234
235
236
237
238
239
  MSC_LOG_TX_MESSAGE(
  	  MSC_NAS_UE,
  	  MSC_RRC_UE,
  	  NULL,0,
  	  "0 NAS_CELL_SELECTION_REQ PLMN %X%X%X.%X%X%X",
  	  plmnID.MCCdigit1, plmnID.MCCdigit2, plmnID.MCCdigit3,
  	  plmnID.MNCdigit1, plmnID.MNCdigit2, plmnID.MNCdigit3);

240
  return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + 0 /* TODO to be virtualized */, message_p);
241
242
}

243
int nas_itti_nas_establish_req(as_cause_t cause, as_call_type_t type, as_stmsi_t s_tmsi, plmn_t plmnID, Byte_t *data, uint32_t length)
244
{
245
  MessageDef *message_p;
246

247
  message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_CONN_ESTABLI_REQ);
248

249
250
251
252
253
254
  NAS_CONN_ESTABLI_REQ(message_p).cause                       = cause;
  NAS_CONN_ESTABLI_REQ(message_p).type                        = type;
  NAS_CONN_ESTABLI_REQ(message_p).s_tmsi                      = s_tmsi;
  NAS_CONN_ESTABLI_REQ(message_p).plmnID                      = plmnID;
  NAS_CONN_ESTABLI_REQ(message_p).initialNasMsg.data          = data;
  NAS_CONN_ESTABLI_REQ(message_p).initialNasMsg.length        = length;
255

gauthier's avatar
gauthier committed
256
257
258
259
260
261
262
263
264
  MSC_LOG_TX_MESSAGE(
		  MSC_NAS_UE,
		  MSC_RRC_UE,
  	      NULL,0,
  	     "0 NAS_CONN_ESTABLI_REQ MME code %u m-TMSI %u PLMN %X%X%X.%X%X%X",
  	     s_tmsi.MMEcode, s_tmsi.m_tmsi,
  	     plmnID.MCCdigit1, plmnID.MCCdigit2, plmnID.MCCdigit3,
  	     plmnID.MNCdigit1, plmnID.MNCdigit2, plmnID.MNCdigit3);

265
  return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + 0 /* TODO to be virtualized */, message_p);
266
}
267
268
269

int nas_itti_ul_data_req(const uint32_t ue_id, void *const data, const uint32_t length)
{
270
  MessageDef *message_p;
271

272
  message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_UPLINK_DATA_REQ);
273

274
275
276
  NAS_UPLINK_DATA_REQ(message_p).UEid          = ue_id;
  NAS_UPLINK_DATA_REQ(message_p).nasMsg.data   = data;
  NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = length;
277

278
  return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + 0 /* TODO to be virtualized */, message_p);
279
280
}

winckel's avatar
winckel committed
281
int nas_itti_rab_establish_rsp(const as_stmsi_t s_tmsi, const as_rab_id_t rabID, const nas_error_code_t errCode)
282
{
283
  MessageDef *message_p;
284

285
  message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_RAB_ESTABLI_RSP);
286

287
288
289
  NAS_RAB_ESTABLI_RSP(message_p).s_tmsi       = s_tmsi;
  NAS_RAB_ESTABLI_RSP(message_p).rabID        = rabID;
  NAS_RAB_ESTABLI_RSP(message_p).errCode      = errCode;
290

gauthier's avatar
gauthier committed
291
292
293
294
295
296
  MSC_LOG_TX_MESSAGE(
		  MSC_NAS_UE,
		  MSC_RRC_UE,
  	      NULL,0,
  	     "0 NAS_RAB_ESTABLI_RSP MME code %u m-TMSI %u rb id %u status %u",
  	     s_tmsi.MMEcode, s_tmsi.m_tmsi,rabID, errCode );
297
  return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + 0 /* TODO to be virtualized */, message_p);
298
}