|
27 | 27 | #include <stdio.h> |
28 | 28 | #include <stdlib.h> |
29 | 29 |
|
| 30 | +#include "../../mem/mem.h" |
| 31 | +#include "../../status_report.h" |
30 | 32 | #include "reg_events.h" |
31 | 33 | #include "reg_records.h" |
32 | 34 |
|
33 | 35 | extern unsigned int default_expires; |
34 | 36 | extern const str uac_reg_state[]; |
| 37 | +extern void *uac_reg_srg; |
35 | 38 |
|
36 | 39 | static char call_id_ftag_buf[MD5_LEN]; |
37 | 40 |
|
| 41 | +#define UAC_REG_SR_AOR "aor=" |
| 42 | +#define UAC_REG_SR_CONTACT ";contact=" |
| 43 | +#define UAC_REG_SR_REGISTRAR ";registrar=" |
| 44 | +#define UAC_REG_SR_AOR_LEN (sizeof(UAC_REG_SR_AOR) - 1) |
| 45 | +#define UAC_REG_SR_CONTACT_LEN (sizeof(UAC_REG_SR_CONTACT) - 1) |
| 46 | +#define UAC_REG_SR_REGISTRAR_LEN (sizeof(UAC_REG_SR_REGISTRAR) - 1) |
| 47 | + |
38 | 48 | int send_unregister(unsigned int hash_index, reg_record_t *rec, str *auth_hdr, |
39 | 49 | unsigned int all_contacts); |
40 | 50 |
|
| 51 | +int reg_build_sr_identifier(const str *aor, const str *contact, |
| 52 | + const str *registrar, str *ident) |
| 53 | +{ |
| 54 | + int len; |
| 55 | + char *buf; |
| 56 | + char *p; |
| 57 | + |
| 58 | + if (!aor || !contact || !registrar || !aor->s || !contact->s || |
| 59 | + !registrar->s) { |
| 60 | + LM_ERR("missing data for status report identifier\n"); |
| 61 | + return -1; |
| 62 | + } |
| 63 | + |
| 64 | + len = UAC_REG_SR_AOR_LEN + aor->len + |
| 65 | + UAC_REG_SR_CONTACT_LEN + contact->len + |
| 66 | + UAC_REG_SR_REGISTRAR_LEN + registrar->len; |
| 67 | + buf = pkg_malloc(len); |
| 68 | + if (!buf) { |
| 69 | + LM_ERR("oom\n"); |
| 70 | + return -1; |
| 71 | + } |
| 72 | + |
| 73 | + p = buf; |
| 74 | + memcpy(p, UAC_REG_SR_AOR, UAC_REG_SR_AOR_LEN); |
| 75 | + p += UAC_REG_SR_AOR_LEN; |
| 76 | + memcpy(p, aor->s, aor->len); |
| 77 | + p += aor->len; |
| 78 | + memcpy(p, UAC_REG_SR_CONTACT, UAC_REG_SR_CONTACT_LEN); |
| 79 | + p += UAC_REG_SR_CONTACT_LEN; |
| 80 | + memcpy(p, contact->s, contact->len); |
| 81 | + p += contact->len; |
| 82 | + memcpy(p, UAC_REG_SR_REGISTRAR, UAC_REG_SR_REGISTRAR_LEN); |
| 83 | + p += UAC_REG_SR_REGISTRAR_LEN; |
| 84 | + memcpy(p, registrar->s, registrar->len); |
| 85 | + |
| 86 | + ident->s = buf; |
| 87 | + ident->len = len; |
| 88 | + return 0; |
| 89 | +} |
| 90 | + |
41 | 91 | void reg_print_record(reg_record_t *rec) { |
42 | 92 | LM_DBG("checking uac=[%p] state=[%d][%.*s] expires=[%d]" |
43 | 93 | " last_register_sent=[%d] registration_timeout=[%d]" |
@@ -166,6 +216,7 @@ int add_record(uac_reg_map_t *uac, str *now, unsigned int mode, |
166 | 216 | char *p; |
167 | 217 | slinkedl_list_t *list; |
168 | 218 | slinkedl_element_t *new_elem = NULL; |
| 219 | + int is_new = 1; |
169 | 220 |
|
170 | 221 | /* Reserve space for record */ |
171 | 222 | size = sizeof(reg_record_t) + MD5_LEN + |
@@ -304,13 +355,35 @@ int add_record(uac_reg_map_t *uac, str *now, unsigned int mode, |
304 | 355 | if (mode == REG_DB_LOAD_RECORD) { |
305 | 356 | coords->extra = (void*)(unsigned long)uac->hash_code; |
306 | 357 | if (slinkedl_replace(reg_htable[uac->hash_code].p_list, |
307 | | - match_reload_record, coords, new_elem) == 0) |
| 358 | + match_reload_record, coords, new_elem) == 0) { |
308 | 359 | /* this is a new record altogether */ |
309 | 360 | slinkedl_append_element(reg_htable[uac->hash_code].p_list, new_elem); |
| 361 | + } else { |
| 362 | + is_new = 0; |
| 363 | + } |
310 | 364 | } |
311 | 365 |
|
312 | 366 | reg_print_record(record); |
313 | 367 |
|
| 368 | + if (uac_reg_srg && is_new) { |
| 369 | + str sr_ident = {NULL, 0}; |
| 370 | + if (reg_build_sr_identifier(&record->td.rem_uri, &record->contact_uri, |
| 371 | + &record->td.rem_target, &sr_ident) == 0) { |
| 372 | + if (sr_register_identifier(uac_reg_srg, STR2CI(sr_ident), |
| 373 | + SR_STATUS_NOT_READY, |
| 374 | + (char *)uac_reg_state[NOT_REGISTERED_STATE].s, |
| 375 | + uac_reg_state[NOT_REGISTERED_STATE].len, 20) == 0) { |
| 376 | + sr_add_report_fmt(uac_reg_srg, STR2CI(sr_ident), 0, |
| 377 | + "created with state %.*s\n", |
| 378 | + uac_reg_state[NOT_REGISTERED_STATE].len, |
| 379 | + uac_reg_state[NOT_REGISTERED_STATE].s); |
| 380 | + } else { |
| 381 | + LM_ERR("failed to register status report identifier\n"); |
| 382 | + } |
| 383 | + pkg_free(sr_ident.s); |
| 384 | + } |
| 385 | + } |
| 386 | + |
314 | 387 | return 0; |
315 | 388 | } |
316 | 389 |
|
@@ -354,8 +427,25 @@ void destroy_reg_htable(void) { |
354 | 427 | } |
355 | 428 | } |
356 | 429 |
|
| 430 | +static int reg_state_to_sr_status(int state) |
| 431 | +{ |
| 432 | + switch (state) { |
| 433 | + case REGISTERED_STATE: |
| 434 | + return SR_STATUS_READY; |
| 435 | + case REGISTERING_STATE: |
| 436 | + case AUTHENTICATING_STATE: |
| 437 | + case UNREGISTERING_STATE: |
| 438 | + case AUTHENTICATING_UNREGISTER_STATE: |
| 439 | + return SR_STATUS_LOADING_DATA; |
| 440 | + default: |
| 441 | + return SR_STATUS_NOT_READY; |
| 442 | + } |
| 443 | +} |
| 444 | + |
357 | 445 | void reg_change_state(reg_record_t *rec, int new_state) |
358 | 446 | { |
| 447 | + str sr_ident = {NULL, 0}; |
| 448 | + |
359 | 449 | rec->state = new_state; |
360 | 450 | switch (new_state) { |
361 | 451 | case NOT_REGISTERED_STATE: |
@@ -392,4 +482,16 @@ void reg_change_state(reg_record_t *rec, int new_state) |
392 | 482 | LM_ERR("Unhandled new state %d \n",new_state); |
393 | 483 | break; |
394 | 484 | } |
| 485 | + |
| 486 | + if (uac_reg_srg && reg_build_sr_identifier(&rec->td.rem_uri, |
| 487 | + &rec->contact_uri, &rec->td.rem_target, &sr_ident) == 0) { |
| 488 | + sr_set_status(uac_reg_srg, STR2CI(sr_ident), |
| 489 | + reg_state_to_sr_status(new_state), |
| 490 | + (char *)uac_reg_state[new_state].s, |
| 491 | + uac_reg_state[new_state].len, 0); |
| 492 | + sr_add_report_fmt(uac_reg_srg, STR2CI(sr_ident), 0, |
| 493 | + "state changed to %.*s\n", |
| 494 | + uac_reg_state[new_state].len, uac_reg_state[new_state].s); |
| 495 | + pkg_free(sr_ident.s); |
| 496 | + } |
395 | 497 | } |
0 commit comments