comparison libfdcore/messages.c @ 1425:b09f1b4c9fad

fd_msg_add_result: add function Add fd_msg_add_result() as a superset of fd_msg_rescode_set() to allow setting of either Result-Code or Experimental-Result (Grouped), depending upon whether the supplied vendor is 0 or not. Reimplement fd_msg_rescode_set() in terms of fd_msg_add_result().
author Luke Mewburn <luke@mewburn.net>
date Wed, 19 Feb 2020 10:26:29 +1100
parents 0d71c0b2eed4
children 566bb46cc73f
comparison
equal deleted inserted replaced
1424:c8057892e56b 1425:b09f1b4c9fad
40 static struct dict_object * dict_avp_OR = NULL; /* Origin-Realm */ 40 static struct dict_object * dict_avp_OR = NULL; /* Origin-Realm */
41 static struct dict_object * dict_avp_EM = NULL; /* Error-Message */ 41 static struct dict_object * dict_avp_EM = NULL; /* Error-Message */
42 static struct dict_object * dict_avp_ERH = NULL; /* Error-Reporting-Host */ 42 static struct dict_object * dict_avp_ERH = NULL; /* Error-Reporting-Host */
43 static struct dict_object * dict_avp_FAVP= NULL; /* Failed-AVP */ 43 static struct dict_object * dict_avp_FAVP= NULL; /* Failed-AVP */
44 static struct dict_object * dict_avp_RC = NULL; /* Result-Code */ 44 static struct dict_object * dict_avp_RC = NULL; /* Result-Code */
45 static struct dict_object * dict_avp_ER = NULL; /* Experimental-Result */
46 static struct dict_object * dict_avp_VI = NULL; /* Vendor-Id */
47 static struct dict_object * dict_avp_ERC = NULL; /* Experimental-Result-Code */
45 struct dict_object * fd_dict_avp_OSI = NULL; /* Origin-State-Id */ 48 struct dict_object * fd_dict_avp_OSI = NULL; /* Origin-State-Id */
46 struct dict_object * fd_dict_cmd_CER = NULL; /* Capabilities-Exchange-Request */ 49 struct dict_object * fd_dict_cmd_CER = NULL; /* Capabilities-Exchange-Request */
47 struct dict_object * fd_dict_cmd_DWR = NULL; /* Device-Watchdog-Request */ 50 struct dict_object * fd_dict_cmd_DWR = NULL; /* Device-Watchdog-Request */
48 struct dict_object * fd_dict_avp_DC = NULL; /* Disconnect-Cause */ 51 struct dict_object * fd_dict_avp_DC = NULL; /* Disconnect-Cause */
49 struct dict_object * fd_dict_cmd_DPR = NULL; /* Disconnect-Peer-Request */ 52 struct dict_object * fd_dict_cmd_DPR = NULL; /* Disconnect-Peer-Request */
61 64
62 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Result-Code", &dict_avp_RC , ENOENT) ); 65 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Result-Code", &dict_avp_RC , ENOENT) );
63 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Error-Message", &dict_avp_EM , ENOENT) ); 66 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Error-Message", &dict_avp_EM , ENOENT) );
64 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Error-Reporting-Host", &dict_avp_ERH , ENOENT) ); 67 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Error-Reporting-Host", &dict_avp_ERH , ENOENT) );
65 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Failed-AVP", &dict_avp_FAVP, ENOENT) ); 68 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Failed-AVP", &dict_avp_FAVP, ENOENT) );
69 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Experimental-Result", &dict_avp_ER, ENOENT) );
70 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Vendor-Id", &dict_avp_VI, ENOENT) );
71 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Experimental-Result-Code", &dict_avp_ERC, ENOENT) );
66 72
67 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Disconnect-Cause", &fd_dict_avp_DC , ENOENT) ); 73 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Disconnect-Cause", &fd_dict_avp_DC , ENOENT) );
68 74
69 CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Capabilities-Exchange-Request", &fd_dict_cmd_CER, ENOENT ) ); 75 CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Capabilities-Exchange-Request", &fd_dict_cmd_CER, ENOENT ) );
70 CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Device-Watchdog-Request", &fd_dict_cmd_DWR, ENOENT ) ); 76 CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Device-Watchdog-Request", &fd_dict_cmd_DWR, ENOENT ) );
164 /* Done! */ 170 /* Done! */
165 return 0; 171 return 0;
166 } 172 }
167 173
168 174
169 /* Add Result-Code and eventually Failed-AVP, Error-Message and Error-Reporting-Host AVPs */ 175 /* Add Result-Code or Experimental-Result, and eventually Failed-AVP, Error-Message and Error-Reporting-Host AVPs */
170 int fd_msg_rescode_set( struct msg * msg, char * rescode, char * errormsg, struct avp * optavp, int type_id ) 176 int fd_msg_add_result( struct msg * msg, vendor_id_t vendor, struct dict_object * restype, char * rescode, char * errormsg, struct avp * optavp, int type_id )
171 { 177 {
172 union avp_value val; 178 union avp_value val;
173 struct avp * avp_RC = NULL;
174 struct avp * avp_EM = NULL;
175 struct avp * avp_ERH = NULL;
176 struct avp * avp_FAVP= NULL;
177 uint32_t rc_val = 0; 179 uint32_t rc_val = 0;
178 int set_e_bit=0; 180 int set_e_bit=0;
179 int std_err_msg=0; 181 int std_err_msg=0;
180 182
181 TRACE_ENTRY("%p %s %p %p %d", msg, rescode, errormsg, optavp, type_id); 183 TRACE_ENTRY("%p %d %p %s %p %p %d", msg, vendor, restype, rescode, errormsg, optavp, type_id);
182 184
183 CHECK_PARAMS( msg && rescode ); 185 CHECK_PARAMS( msg && restype && rescode );
184 186
185 /* Find the enum value corresponding to the rescode string, this will give the class of error */ 187 /* Find the enum value corresponding to the rescode string, this will give the class of error */
186 { 188 {
187 struct dict_object * enum_obj = NULL; 189 struct dict_object * enum_obj = NULL;
190
191 /* Search in the restype */
188 struct dict_enumval_request req; 192 struct dict_enumval_request req;
189 memset(&req, 0, sizeof(struct dict_enumval_request)); 193 memset(&req, 0, sizeof(struct dict_enumval_request));
190 194 req.type_obj = restype;
191 /* First, get the enumerated type of the Result-Code AVP (this is fast, no need to cache the object) */
192 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_TYPE, TYPE_OF_AVP, dict_avp_RC, &(req.type_obj), ENOENT ) );
193 195
194 /* Now search for the value given as parameter */ 196 /* Now search for the value given as parameter */
195 req.search.enum_name = rescode; 197 req.search.enum_name = rescode;
196 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &req, &enum_obj, ENOTSUP) ); 198 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &req, &enum_obj, ENOTSUP) );
197 199
205 if (type_id == 1) { 207 if (type_id == 1) {
206 /* Add the Origin-Host and Origin-Realm AVP */ 208 /* Add the Origin-Host and Origin-Realm AVP */
207 CHECK_FCT( fd_msg_add_origin ( msg, 0 ) ); 209 CHECK_FCT( fd_msg_add_origin ( msg, 0 ) );
208 } 210 }
209 211
210 /* Create the Result-Code AVP */ 212 if (vendor == 0) {
211 CHECK_FCT( fd_msg_avp_new( dict_avp_RC, 0, &avp_RC ) ); 213 /* Vendor 0; create the Result-Code AVP */
212 214 struct avp * avp_RC = NULL;
213 /* Set its value */ 215 CHECK_FCT( fd_msg_avp_new( dict_avp_RC, 0, &avp_RC ) );
214 memset(&val, 0, sizeof(val)); 216
215 val.u32 = rc_val; 217 /* Set its value */
216 CHECK_FCT( fd_msg_avp_setvalue( avp_RC, &val ) ); 218 memset(&val, 0, sizeof(val));
217 219 val.u32 = rc_val;
218 /* Add it to the message */ 220 CHECK_FCT( fd_msg_avp_setvalue( avp_RC, &val ) );
219 CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_RC ) ); 221
222 /* Add it to the message */
223 CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_RC ) );
224 } else {
225 /* Vendor !0; create the Experimental-Result AVP */
226 struct avp * avp_ER = NULL;
227 CHECK_FCT( fd_msg_avp_new( dict_avp_ER, 0, &avp_ER ) );
228
229 /* Create the Vendor-Id AVP and add to Experimental-Result */
230 {
231 struct avp * avp_VI = NULL;
232 CHECK_FCT( fd_msg_avp_new( dict_avp_VI, 0, &avp_VI ) );
233
234 /* Set Vendor-Id value to vendor */
235 memset(&val, 0, sizeof(val));
236 val.u32 = vendor;
237 CHECK_FCT( fd_msg_avp_setvalue( avp_VI, &val ) );
238
239 /* Add it to Experimental-Result */
240 CHECK_FCT( fd_msg_avp_add( avp_ER, MSG_BRW_LAST_CHILD, avp_VI ) );
241 }
242
243 /* Create the Experimental-Result-Code AVP and add to Experimental-Result */
244 {
245 struct avp * avp_ERC = NULL;
246 CHECK_FCT( fd_msg_avp_new( dict_avp_ERC, 0, &avp_ERC ) );
247
248 /* Set Experimental-Result-Code value to rc_val */
249 memset(&val, 0, sizeof(val));
250 val.u32 = rc_val;
251 CHECK_FCT( fd_msg_avp_setvalue( avp_ERC, &val ) );
252
253 /* Add it to Experimental-Result */
254 CHECK_FCT( fd_msg_avp_add( avp_ER, MSG_BRW_LAST_CHILD, avp_ERC ) );
255 }
256
257 /* Add it to the message */
258 CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_ER ) );
259 }
220 260
221 if (type_id == 2) { 261 if (type_id == 2) {
222 /* Add the Error-Reporting-Host AVP */ 262 /* Add the Error-Reporting-Host AVP */
223 263 struct avp * avp_ERH = NULL;
224 CHECK_FCT( fd_msg_avp_new( dict_avp_ERH, 0, &avp_ERH ) ); 264 CHECK_FCT( fd_msg_avp_new( dict_avp_ERH, 0, &avp_ERH ) );
225 265
226 /* Set its value */ 266 /* Set its value */
227 memset(&val, 0, sizeof(val)); 267 memset(&val, 0, sizeof(val));
228 val.os.data = (uint8_t *)fd_g_config->cnf_diamid; 268 val.os.data = (uint8_t *)fd_g_config->cnf_diamid;
229 val.os.len = fd_g_config->cnf_diamid_len; 269 val.os.len = fd_g_config->cnf_diamid_len;
230 CHECK_FCT( fd_msg_avp_setvalue( avp_ERH, &val ) ); 270 CHECK_FCT( fd_msg_avp_setvalue( avp_ERH, &val ) );
231 271
232 /* Add it to the message */ 272 /* Add it to the message */
233 CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_ERH ) ); 273 CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_ERH ) );
234 274 }
235 } 275
236 276 /* Now add the optavp in a Failed-AVP if provided */
237 /* Now add the optavp in a FailedAVP if provided */
238 if (optavp) { 277 if (optavp) {
278 struct avp * avp_FAVP= NULL;
239 struct avp * optavp_cpy = NULL; 279 struct avp * optavp_cpy = NULL;
240 struct avp_hdr *opt_hdr, *optcpy_hdr; 280 struct avp_hdr *opt_hdr, *optcpy_hdr;
241 struct dict_object * opt_model = NULL; 281 struct dict_object * opt_model = NULL;
242 int is_grouped = 0; 282 int is_grouped = 0;
243 283
307 hdr->msg_flags &= ~ CMD_FLAG_ERROR; 347 hdr->msg_flags &= ~ CMD_FLAG_ERROR;
308 } 348 }
309 349
310 if (std_err_msg || errormsg) { 350 if (std_err_msg || errormsg) {
311 /* Add the Error-Message AVP */ 351 /* Add the Error-Message AVP */
312 352 struct avp * avp_EM = NULL;
313 CHECK_FCT( fd_msg_avp_new( dict_avp_EM, 0, &avp_EM ) ); 353 CHECK_FCT( fd_msg_avp_new( dict_avp_EM, 0, &avp_EM ) );
314 354
315 /* Set its value */ 355 /* Set its value */
316 memset(&val, 0, sizeof(val)); 356 memset(&val, 0, sizeof(val));
317 357
327 /* Add it to the message */ 367 /* Add it to the message */
328 CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_EM ) ); 368 CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_EM ) );
329 } 369 }
330 370
331 return 0; 371 return 0;
372 }
373
374 int fd_msg_rescode_set( struct msg * msg, char * rescode, char * errormsg, struct avp * optavp, int type_id )
375 {
376 struct dict_object * restype = NULL;
377 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_TYPE, TYPE_OF_AVP, dict_avp_RC, &restype, ENOENT ) );
378 return fd_msg_add_result(msg, 0, restype, rescode, errormsg, optavp, type_id);
332 } 379 }
333 380
334 static int fd_msg_send_int( struct msg ** pmsg, void (*anscb)(void *, struct msg **), void * data, void (*expirecb)(void *, DiamId_t, size_t, struct msg **), const struct timespec *timeout ) 381 static int fd_msg_send_int( struct msg ** pmsg, void (*anscb)(void *, struct msg **), void * data, void (*expirecb)(void *, DiamId_t, size_t, struct msg **), const struct timespec *timeout )
335 { 382 {
336 struct msg_hdr *hdr; 383 struct msg_hdr *hdr;
"Welcome to our mercurial repository"