blob: e9a49b8ff872b4b3b9c9b3217b7ab0d8110f4198 [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 <stdlib.h>
20#include <string.h>
21#include <ctype.h>
22#include <stdio.h>
23#include <stdbool.h>
24#include <ctype.h>
25#include <freeDiameter/freeDiameter-host.h>
26#include <freeDiameter/libfdproto.h>
27#include <freeDiameter/libfdcore.h>
28
29#include "log.h"
30#include "err_codes.h"
31#include "message_queues.h"
32#include "ipc_api.h"
33#include "s6a_fd.h"
34#include "s6a.h"
35#include "msgType.h"
36//#include "stage1_s6a_msg.h"
37#include "hss_message.h"
38
39extern int g_Q_mme_S6a_fd;
40extern struct fd_dict_objects g_fd_dict_objs;
41extern struct fd_dict_data g_fd_dict_data;
42
43/**
44 * @brief Parse subscription information for UE
45 * @param[in] avp_ptr - POinter to subscription data avp
46 * @param[out] ula information filled with parsed data
47 * @return void
48 */
49static void
50parse_ula_subscription_data(struct avp *avp_ptr, struct ula_Q_msg *ula)
51{
52 struct avp *next = NULL;
53 struct avp_hdr *element = NULL;
54
55 CHECK_FCT_DO(fd_msg_avp_hdr(avp_ptr, &element),
56 return);
57
58 if ((NULL == element) ||
59 (element->avp_code != g_fd_dict_data.subscription_data.avp_code))
60 return;
61
62 CHECK_FCT_DO(fd_msg_browse(avp_ptr, MSG_BRW_FIRST_CHILD, &next, NULL),
63 return);
64
65 for(;
66 NULL != next;
67 fd_msg_browse(next, MSG_BRW_NEXT, &next, NULL)) {
68
69 fd_msg_avp_hdr (next, &element);
70
71 if(NULL == element) return;
72
73 /*AVP: Access-Restriction-Data(1426)*/
74 if(g_fd_dict_data.access_restriction_data.avp_code ==
75 element->avp_code) {
76 ula->access_restriction_data = element->avp_value->u32;
77 continue;
78 }
79
80 /*AVP: Subscriber-Status(1424)*/
81 if(g_fd_dict_data.subscriber_status.avp_code == element->avp_code) {
82 ula->subscription_status = element->avp_value->i32;
83 continue;
84 }
85
86 /*AVP: Network-Access-Mode(1417)*/
87 if(g_fd_dict_data.net_access_mode.avp_code == element->avp_code) {
88 ula->net_access_mode = element->avp_value->i32;
89 continue;
90 }
91
92 /*AVP: Regional-Subscription-Zone-Code(1446)*/
93 if(g_fd_dict_data.reg_subs_zone_code.avp_code ==
94 element->avp_code) {
95 //element->avp_value : 10 string values of len 4
96 continue;
97 }
98
99 /*AVP: MSISDN(701)*/
100 if(g_fd_dict_data.MSISDN.avp_code == element->avp_code) {
101 memcpy(ula->MSISDN, element->avp_value->os.data, element->avp_value->os.len);
102 continue;
103 }
104
105 /*AVP: AMBR(1435)*/
106 /*AVP: Max-Requested-Bandwidth-UL(516)
107 AVP: Max-Requested-Bandwidth-DL(515*/
108 if(g_fd_dict_data.AMBR.avp_code == element->avp_code) {
109 /*AMBR has its own child elements, iterate through those*/
110 struct avp *ambr_itr = NULL;
111 struct avp_hdr *ambr_element = NULL;
112
113 CHECK_FCT_DO(fd_msg_browse(next, MSG_BRW_FIRST_CHILD,
114 &ambr_itr, NULL), return);
115
116 /*Iterate through subscription data child avps*/
117 while(NULL != ambr_itr) {
118 fd_msg_avp_hdr(ambr_itr, &ambr_element);
119
120 if(g_fd_dict_data.max_req_bandwidth_UL.avp_code ==
121 ambr_element->avp_code) {
122 ula->max_requested_bw_ul = ambr_element->avp_value->u32;
123 }
124
125 if(g_fd_dict_data.max_req_bandwidth_DL.avp_code ==
126 ambr_element->avp_code) {
127 ula->max_requested_bw_dl = ambr_element->avp_value->u32;
128 }
129
130 CHECK_FCT_DO(fd_msg_browse(ambr_itr, MSG_BRW_NEXT,
131 &ambr_itr, NULL), return);
132 }
133 continue;
134 }
135
136 /*AVP: APN-Configuration-Profile(1429)*/
137 /*AVP: Context-Identifier(1423)
138 AVP: All-APN-Configurations-Included-Indicator(1428)
139 AVP: APN-Configuration(1430)*/
140 if(g_fd_dict_data.APN_config_profile.avp_code == element->avp_code) {
141 /*APN profile has its own child elements, iterate through
142 * those*/
143 struct avp *apn_cfg_prof_itr = NULL;
144 struct avp_hdr *apn_cfg_element = NULL;
145
146 CHECK_FCT_DO(fd_msg_browse(next, MSG_BRW_FIRST_CHILD,
147 &apn_cfg_prof_itr, NULL), return);
148
149 /*Iterate through subscription data child avps*/
150 while(NULL != apn_cfg_prof_itr) {
151 fd_msg_avp_hdr(apn_cfg_prof_itr, &apn_cfg_element);
152
153 if(g_fd_dict_data.ctx_id.avp_code ==
154 apn_cfg_element->avp_code) {
155 ula->apn_config_profile_ctx_id =
156 apn_cfg_element->avp_value->u32;
157 } else
158 if(g_fd_dict_data.all_APN_configs_included_ind.avp_code ==
159 apn_cfg_element->avp_code) {
160 ula->all_APN_cfg_included_ind =
161 apn_cfg_element->avp_value->i32;
162 } else
163 if(g_fd_dict_data.APN_config.avp_code ==
164 apn_cfg_element->avp_code){
165 //APN configuration list : There is list of elements to read
166 //TODO : Write function to read all elements
167
168 }
169
170 CHECK_FCT_DO(fd_msg_browse(apn_cfg_prof_itr, MSG_BRW_NEXT,
171 &apn_cfg_prof_itr, NULL), return);
172 }
173 continue;
174 }
175
176 /*AVP: Subscribed-Periodic-RAU-TAU-Timer(1619)*/
177 if(g_fd_dict_data.subsc_periodic_RAU_TAU_tmr.avp_code
178 == element->avp_code) {
179 ula->RAU_TAU_timer = element->avp_value->u32;
180 continue;
181 }
182
183 }
184}
185
186/**
187 * @brief Call back registered to handle ULA from hss
188 * @param callback requiremd arguments
189 * @return int error code as success or failure
190 */
191int
192ula_resp_callback(struct msg **buf, struct avp *avp_ptr, struct session *sess,
193 void *data, enum disp_action *action)
194{
195 int sess_id_len, ue_idx;
196 unsigned char *sess_id= NULL;
197 struct s6_incoming_msg_data_t s6_incoming_msgs;
198 struct avp *subsc_ptr = NULL;
199
200 CHECK_FCT_DO(fd_sess_getsid(sess, &sess_id, (size_t*)&sess_id_len),
201 return S6A_FD_ERROR);
202
203 log_msg(LOG_INFO, "\nCallback ----- >session id=%s \n", sess_id);
204
205 s6_incoming_msgs.msg_data.ula_Q_msg_m.res = SUCCESS;
206 ue_idx = get_ue_idx_from_fd_resp(sess_id, sess_id_len);
207
208 /*AVP: Subscription-Data(1400)*/
209 fd_msg_search_avp(*buf, g_fd_dict_objs.subscription_data, &subsc_ptr);
210
211 /*Parse fd message and extract ula information*/
212 if(NULL != subsc_ptr) parse_ula_subscription_data(subsc_ptr, &s6_incoming_msgs.msg_data.ula_Q_msg_m);
213
214 fd_msg_free(*buf);
215 *buf = NULL;
216
217 s6_incoming_msgs.msg_type = update_loc_answer;
218 s6_incoming_msgs.ue_idx = ue_idx;
219
220 s6_incoming_msgs.destInstAddr = htonl(mmeAppInstanceNum_c);
221 s6_incoming_msgs.srcInstAddr = htonl(s6AppInstanceNum_c);
222
223 /*Send to stage2 queue*/
224 send_tipc_message(g_Q_mme_S6a_fd, mmeAppInstanceNum_c, (char*)&s6_incoming_msgs, S6_READ_MSG_BUF_SIZE);
225
226 return SUCCESS;
227}
228
229/*Handler for ULA coming from built in perf HS*/
230void
231handle_perf_hss_ula(int ue_idx, struct hss_ula_msg *ula)
232{
233 struct s6_incoming_msg_data_t msg;
234
235 msg.msg_type = update_loc_answer;
236 msg.ue_idx = ue_idx;
237 msg.msg_data.ula_Q_msg_m.res = ula->subscription_state;
238 /*Send to stage2 queue*/
239 write_ipc_channel(g_Q_mme_S6a_fd, (char*)&msg, S6_READ_MSG_BUF_SIZE);
240}