blob: 62f26f8af1fda7672173b1c2bfb6ec1cfa6cdb83 [file] [log] [blame]
anjana_sreekumar@infosys.com991c2062020-01-08 11:42:57 +05301/*
2 * Copyright (c) 2003-2018, Great Software Laboratory Pvt. Ltd.
3 * Copyright (c) 2017 Intel Corporation
4 * Copyright (c) 2019, Infosys Ltd.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <pthread.h>
22#include <string.h>
23#include <unistd.h>
24#include <stdbool.h>
25#include <freeDiameter/freeDiameter-host.h>
26#include <freeDiameter/libfdcore.h>
27#include <freeDiameter/libfdproto.h>
28
29#include "err_codes.h"
30#include "message_queues.h"
31#include "ipc_api.h"
32#include "sec.h"
33#include "s6a_fd.h"
34#include "s6a.h"
35#include "s6a_config.h"
36#include "msgType.h"
37//#include "detach_stage1_info.h"
38
39/************************************************************************
40Current file : Stage - AIR handler of S6A
41ATTACH stages :
42@@@ Stage 1 : IAM-->[stage1 handler]-->AIR, ULR
43 Stage 2 : AIA, ULA -->[stage2 handler]--> Auth req
44 Stage 3 : Auth resp-->[stage1 handler]-->Sec mode cmd
45 Stage 4 : sec mode resp-->[stage1 handler]-->esm infor req
46 Stage 5 : esm infor resp-->[stage1 handler]-->create session
47 Stage 6 : create session resp-->[stage1 handler]-->init ctx setup
48 Stage 7 : attach complete-->[stage1 handler]-->modify bearer
49**************************************************************************/
50
51/****Globals and externs ***/
52
53static int g_Q_detachread_fd;
54
55/*Making global just to avoid stack passing*/
56
57static char buf[S6A_PURGEREQ_STAGE1_BUF_SIZE];
58
59extern s6a_config g_s6a_cfg;
60extern struct fd_dict_objects g_fd_dict_objs;
61extern struct fd_dict_data g_fd_dict_data;
62/****Global and externs end***/
63
64/**
65Initialize the stage settings, Q,
66destination communication etc.
67*/
68static void
69init_stage()
70{
71 log_msg(LOG_INFO, "Waiting for session detach initialiser from mme-app\n");
72 if ((g_Q_detachread_fd = open_ipc_channel(S6A_DTCHREQ_STAGE1_QUEUE, IPC_READ)) == -1){
73 log_msg(LOG_ERROR, "Error in opening reader detach channel.\n");
74 pthread_exit(NULL);
75 }
76 return;
77}
78
79/**
80* Read next message from stage Q for processing.
81*/
82static int
83read_next_msg()
84{
85 int bytes_read=0;
86 memset(buf, 0, S6A_PURGEREQ_STAGE1_BUF_SIZE);
87 while (bytes_read < S6A_PURGEREQ_STAGE1_BUF_SIZE) {//TODO : Recheck condition
88 if ((bytes_read = read_ipc_channel(
89 g_Q_detachread_fd, buf, S6A_PURGEREQ_STAGE1_BUF_SIZE)) == -1) {
90 log_msg(LOG_ERROR, "Error in reading from AIR Q.\n");
91 /* TODO : Add proper error handling */
92 }
93 log_msg(LOG_INFO, "Purge msg received, len - %d\n", bytes_read);
94 }
95 return bytes_read;
96}
97
98/**
99 * @brief Prepare PUR freediameter message, dump and post to HSS
100 * @param[in] ue_idx UE indx to append to session id
101 * @param[in] imsi - IMSI
102 * @return int Sucess or failure code
103 */
104static int
105send_purge(int ue_idx, char imsi[])
106{
107 struct msg *fd_msg = NULL;
108 union avp_value val;
109 struct s6a_sess_info s6a_sess = {.sess_id="", .sess_id_len = 0};
110
111 if(SUCCESS != create_fd_sess_id(&s6a_sess, ue_idx)) return S6A_FD_ERROR;
112
113 CHECK_FCT_DO(fd_msg_new(g_fd_dict_objs.PUR, MSGFL_ALLOC_ETEID, &fd_msg),
114 return S6A_FD_ERROR);
115
116 /*AVP: Session-Id*/
117 val.os.data = (unsigned char*)s6a_sess.sess_id;
118 val.os.len = strlen(s6a_sess.sess_id);
119 add_fd_msg(&val, g_fd_dict_objs.sess_id, &fd_msg);
120
121 /*AVP: Auth-Session-State*/
122 val.i32 = 1; /*NO_STATE_MAINTAINED*/
123 val.os.len = 0;
124 add_fd_msg(&val, g_fd_dict_objs.auth_sess_state, &fd_msg);
125
126 /*AVP: Origin-Host/Realm*/
127 CHECK_FCT_DO(fd_msg_add_origin(fd_msg, 0), return S6A_FD_ERROR);
128
129 /*AVP: Destination-Host*/
130 val.os.data = (unsigned char *)g_s6a_cfg.hss_host_name;
131 val.os.len = strlen(g_s6a_cfg.hss_host_name);
132 add_fd_msg(&val, g_fd_dict_objs.dest_host, &fd_msg);
133
134 /*AVP: Destination-Realm*/
135 val.os.data = (unsigned char*)g_s6a_cfg.realm;
136 val.os.len = strlen(g_s6a_cfg.realm);
137 add_fd_msg(&val, g_fd_dict_objs.dest_realm, &fd_msg);
138
139 /*AVP: User-Name*/
140 val.os.data = (unsigned char*)imsi;
141 val.os.len = strlen(imsi);
142 add_fd_msg(&val, g_fd_dict_objs.user_name, &fd_msg);
143
144 /*AVP: PUR-Flags*/
145 val.u32 = true;
146 val.os.len = 0;
147 add_fd_msg(&val, g_fd_dict_objs.PUR_flags, &fd_msg);
148
149 dump_fd_msg(fd_msg);
150
151 /*Post message to hss*/
152 CHECK_FCT_DO(fd_msg_send(&fd_msg, NULL, NULL), return S6A_FD_ERROR);
153
154 return SUCCESS;
155}
156
157static void
158send_rpc_purge(int ue_idx, char imsi[])
159{
160 /* TODO: For builitn HSS, we are not sending purge request to HSS,
161 * returning dummy reply. Send request to builtin HSS and
162 * handle response.
163 */
164 handle_perf_hss_purge_resp(ue_idx);
165 return;
166}
167
168/**
169* Stage specific message processing.
170*/
171static int
172detach_processing()
173{
174 struct s6a_purge_Q_msg *purge_msg = (struct s6a_purge_Q_msg*)buf;
175 char imsi[16] = {0};
176
177 /*Parse and validate the buffer*/
178 imsi_bin_to_str(purge_msg->IMSI, imsi);
179 log_msg(LOG_INFO, "IMSI recvd - %s\n", imsi);
180
181 if (HSS_FD == g_s6a_cfg.hss_type)
182 send_purge(purge_msg->ue_idx, imsi);
183 else {
184 log_msg(LOG_INFO, "Sending over IPC \n");
185 send_rpc_purge(purge_msg->ue_idx, imsi);
186 }
187
188 return SUCCESS;
189}
190
191/**
192* Post message to next handler of the stage
193*/
194static int
195post_to_next()
196{
197 return SUCCESS;
198}
199
200/**
201* Thread exit function for future reference.
202*/
203void
204shutdown_detach()
205{
206 close_ipc_channel(g_Q_detachread_fd);
207 log_msg(LOG_INFO, "Shutdown detach handler \n");
208 pthread_exit(NULL);
209 return;
210}
211
212
213/**
214* Thread function for stage.
215*/
216void*
217detach_handler(void *data)
218{
219 init_stage();
220
221 sleep(5);
222
223 log_msg(LOG_INFO, "Detach Q handler ready.\n");
224
225 while(1){
226 read_next_msg();
227
228 detach_processing();
229
230 post_to_next();
231 }
232
233 return NULL;
234}
235