/** * avpl_transform: * @param src the source avpl for the transform operation. * @param op a pointer to the avpl transformation object to apply. * * Applies the "op" transformation to an avpl, matches it and eventually * replaces or inserts the transformed avps. * * Return value: whether the transformation was performed or not. **/ extern void avpl_transform(AVPL* src, AVPL_Transf* op) { AVPL* avpl = NULL; AVPN* cs; AVPN* cm; AVPN* n; #ifdef _AVP_DEBUGGING dbg_print(dbg_avpl_op,3,dbg_fp,"avpl_transform: src=%X op=%X",src,op); #endif for ( ; op ; op = op->next) { avpl = new_avpl_from_match(op->match_mode, src->name,src, op->match, TRUE); if (avpl) { switch (op->replace_mode) { case AVPL_NO_REPLACE: delete_avpl(avpl,TRUE); return; case AVPL_INSERT: merge_avpl(src,op->replace,TRUE); delete_avpl(avpl,TRUE); return; case AVPL_REPLACE: cs = src->null.next; cm = avpl->null.next; while(cs->avp) { if (cm->avp && cs->avp->n == cm->avp->n && cs->avp->v == cm->avp->v) { n = cs->next; cs->prev->next = cs->next; cs->next->prev = cs->prev; g_slice_free(any_avp_type,(any_avp_type*)cs); cs = n; cm = cm->next; } else { cs = cs->next; } } merge_avpl(src,op->replace,TRUE); delete_avpl(avpl,TRUE); return; } } } }
/* applies the extras for which type to what avpl */ static void apply_extras(AVPL* from, AVPL* to, AVPL* extras) { AVPL* our_extras = new_avpl_loose_match("",from, extras, FALSE) ; if (our_extras) { merge_avpl(to,our_extras,TRUE); delete_avpl(our_extras,FALSE); } }
extern AVPL* new_avpl_from_match(avpl_match_mode mode, const gchar* name,AVPL* src, AVPL* op, gboolean copy_avps) { AVPL* avpl = NULL; switch (mode) { case AVPL_STRICT: avpl = new_avpl_exact_match(name,src,op,copy_avps); break; case AVPL_LOOSE: avpl = new_avpl_loose_match(name,src,op,copy_avps); break; case AVPL_EVERY: avpl = new_avpl_every_match(name,src,op,copy_avps); break; case AVPL_NO_MATCH: avpl = new_avpl_from_avpl(name,src,copy_avps); merge_avpl(avpl, op, copy_avps); break; } return avpl; }
static void analyze_pdu(mate_pdu* pdu) { /* TODO: return a g_boolean to tell we've destroyed the pdu when the pdu is unnassigned destroy the unassigned pdu */ mate_cfg_gop* cfg = NULL; mate_gop* gop = NULL; gchar* gop_key; gchar* orig_gop_key = NULL; AVPL* candidate_start = NULL; AVPL* candidate_stop = NULL; AVPL* is_start = NULL; AVPL* is_stop = NULL; AVPL* gopkey_match = NULL; LoAL* gog_keys = NULL; AVPL* curr_gogkey = NULL; void* cookie = NULL; AVPL* gogkey_match = NULL; gchar* gogkey_str = NULL; dbg_print (dbg_gop,1,dbg_facility,"analyze_pdu: %s",pdu->cfg->name); if (! (cfg = g_hash_table_lookup(mc->gops_by_pduname,pdu->cfg->name)) ) return; if ((gopkey_match = new_avpl_exact_match("gop_key_match",pdu->avpl,cfg->key, TRUE))) { gop_key = avpl_to_str(gopkey_match); g_hash_table_lookup_extended(cfg->gop_index,(gconstpointer)gop_key,(gpointer)&orig_gop_key,(gpointer)&gop); if ( gop ) { g_free(gop_key); /* is the gop dead ? */ if ( ! gop->released && ( ( gop->cfg->lifetime > 0.0 && gop->time_to_die >= rd->now) || ( gop->cfg->idle_timeout > 0.0 && gop->time_to_timeout >= rd->now) ) ) { dbg_print (dbg_gop,4,dbg_facility,"analyze_pdu: expiring released gop"); gop->released = TRUE; if (gop->gog && gop->cfg->start) gop->gog->num_of_released_gops++; } /* TODO: is the gop expired? */ gop_key = orig_gop_key; dbg_print (dbg_gop,2,dbg_facility,"analyze_pdu: got gop: %s",gop_key); if (( candidate_start = cfg->start )) { dbg_print (dbg_gop,2,dbg_facility,"analyze_pdu: got candidate start"); if (( is_start = new_avpl_exact_match("",pdu->avpl, candidate_start, FALSE) )) { delete_avpl(is_start,FALSE); if ( gop->released ) { dbg_print (dbg_gop,3,dbg_facility,"analyze_pdu: start on released gop, let's create a new gop"); g_hash_table_remove(cfg->gop_index,gop_key); gop->gop_key = NULL; gop = new_gop(cfg,pdu,gop_key); g_hash_table_insert(cfg->gop_index,gop_key,gop); } else { dbg_print (dbg_gop,1,dbg_facility,"analyze_pdu: duplicate start on gop"); } } } pdu->gop = gop; if (gop->last_pdu) gop->last_pdu->next = pdu; gop->last_pdu = pdu; pdu->next = NULL; pdu->time_in_gop = rd->now - gop->start_time; if (gop->released) pdu->after_release = TRUE; } else { dbg_print (dbg_gop,1,dbg_facility,"analyze_pdu: no gop already"); if ( ! cfg->start ) { /* there is no GopStart, we'll check for matching GogKeys if we have one we'll create the Gop */ apply_extras(pdu->avpl,gopkey_match,cfg->extra); gog_keys = g_hash_table_lookup(mc->gogs_by_gopname,cfg->name); if (gog_keys) { while (( curr_gogkey = get_next_avpl(gog_keys,&cookie) )) { if (( gogkey_match = new_avpl_exact_match(cfg->name,gopkey_match,curr_gogkey,FALSE) )) { gogkey_str = avpl_to_str(gogkey_match); if (g_hash_table_lookup(cfg->gog_index,gogkey_str)) { gop = new_gop(cfg,pdu,gop_key); g_hash_table_insert(cfg->gop_index,gop_key,gop); delete_avpl(gogkey_match,FALSE); g_free(gogkey_str); break; } else { delete_avpl(gogkey_match,FALSE); g_free(gogkey_str); } } } if ( ! gop ) { g_free(gop_key); delete_avpl(gopkey_match,TRUE); return; } } else { g_free(gop_key); delete_avpl(gopkey_match,TRUE); return; } } else { candidate_start = cfg->start; if (( is_start = new_avpl_exact_match("",pdu->avpl, candidate_start, FALSE) )) { delete_avpl(is_start,FALSE); gop = new_gop(cfg,pdu,gop_key); } else { g_free(gop_key); return; } pdu->gop = gop; } } if (gop->last_pdu) gop->last_pdu->next = pdu; gop->last_pdu = pdu; pdu->next = NULL; pdu->time_in_gop = rd->now - gop->start_time; gop->num_of_pdus++; gop->time_to_timeout = cfg->idle_timeout > 0.0 ? cfg->idle_timeout + rd->now : (float) -1.0 ; dbg_print (dbg_gop,4,dbg_facility,"analyze_pdu: merge with key"); merge_avpl(gop->avpl,gopkey_match,TRUE); delete_avpl(gopkey_match,TRUE); dbg_print (dbg_gop,4,dbg_facility,"analyze_pdu: apply extras"); apply_extras(pdu->avpl,gop->avpl,gop->cfg->extra); gop->last_time = pdu->rel_time; if ( ! gop->released) { candidate_stop = cfg->stop; if (candidate_stop) { is_stop = new_avpl_exact_match("",pdu->avpl, candidate_stop,FALSE); } else { is_stop = new_avpl(""); } if(is_stop) { dbg_print (dbg_gop,1,dbg_facility,"analyze_pdu: is a `stop"); delete_avpl(is_stop,FALSE); if (! gop->released) { gop->released = TRUE; gop->release_time = pdu->rel_time; if (gop->gog && gop->cfg->start) gop->gog->num_of_released_gops++; } pdu->is_stop = TRUE; } } if (gop->last_n != gop->avpl->len) apply_transforms(gop->cfg->transforms,gop->avpl); gop->last_n = gop->avpl->len; if (gop->gog) { reanalyze_gop(gop); } else { analyze_gop(gop); } } else { dbg_print (dbg_gop,4,dbg_facility,"analyze_pdu: no match for this pdu"); pdu->gop = NULL; } }
static void analyze_gog_config(gpointer k _U_, gpointer v, gpointer p _U_) { mate_cfg_gog* cfg = v; void* avp_cookie; void* avpl_cookie; AVP* avp; AVPL* avpl; AVPL* gopkey_avpl; AVPL* key_avps; LoAL* gog_keys = NULL; hf_register_info hfri = { NULL, {NULL, NULL, FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL}}; gint* ett; /* create the hf array for this gog */ hfri.p_id = &(cfg->hfid); hfri.hfinfo.name = g_strdup(cfg->name); hfri.hfinfo.abbrev = g_strdup_printf("mate.%s",cfg->name); hfri.hfinfo.blurb = g_strdup_printf("%s Id",cfg->name); hfri.hfinfo.type = FT_UINT32; hfri.hfinfo.display = BASE_DEC; g_array_append_val(matecfg->hfrs,hfri); hfri.p_id = &(cfg->hfid_gog_num_of_gops); hfri.hfinfo.name = "number of GOPs"; hfri.hfinfo.abbrev = g_strdup_printf("mate.%s.NumOfGops",cfg->name); hfri.hfinfo.type = FT_UINT32; hfri.hfinfo.display = BASE_DEC; hfri.hfinfo.blurb = g_strdup_printf("Number of GOPs assigned to this %s",cfg->name); g_array_append_val(matecfg->hfrs,hfri); hfri.p_id = &(cfg->hfid_gog_gopstart); hfri.hfinfo.name = "GopStart frame"; hfri.hfinfo.abbrev = g_strdup_printf("mate.%s.GopStart",cfg->name); hfri.hfinfo.type = FT_FRAMENUM; hfri.hfinfo.display = BASE_NONE; hfri.hfinfo.blurb = g_strdup("The start frame of a GOP"); g_array_append_val(matecfg->hfrs,hfri); hfri.p_id = &(cfg->hfid_gog_gopstop); hfri.hfinfo.name = "GopStop frame"; hfri.hfinfo.abbrev = g_strdup_printf("mate.%s.GopStop",cfg->name); hfri.hfinfo.type = FT_FRAMENUM; hfri.hfinfo.display = BASE_NONE; hfri.hfinfo.blurb = g_strdup("The stop frame of a GOP"); g_array_append_val(matecfg->hfrs,hfri); hfri.p_id = &(cfg->hfid_start_time); hfri.hfinfo.name = g_strdup_printf("%s start time",cfg->name); hfri.hfinfo.abbrev = g_strdup_printf("mate.%s.StartTime",cfg->name); hfri.hfinfo.type = FT_FLOAT; hfri.hfinfo.blurb = g_strdup_printf("Seconds passed since the beginning of capture to the start of this %s",cfg->name); g_array_append_val(matecfg->hfrs,hfri); hfri.p_id = &(cfg->hfid_last_time); hfri.hfinfo.name = g_strdup_printf("%s duration",cfg->name); hfri.hfinfo.abbrev = g_strdup_printf("mate.%s.Duration",cfg->name); hfri.hfinfo.blurb = g_strdup_printf("Time passed between the start of this %s and the last pdu assigned to it",cfg->name); g_array_append_val(matecfg->hfrs,hfri); /* this might become mate.gogname.gopname */ hfri.p_id = &(cfg->hfid_gog_gop); hfri.hfinfo.name = "a GOP"; hfri.hfinfo.abbrev = g_strdup_printf("mate.%s.Gop",cfg->name); hfri.hfinfo.type = FT_STRING; hfri.hfinfo.display = BASE_NONE; hfri.hfinfo.blurb = g_strdup_printf("a GOPs assigned to this %s",cfg->name); g_array_append_val(matecfg->hfrs,hfri); /* index the keys of gog for every gop and insert the avps of the keys to the hfarray */ key_avps = new_avpl(""); avpl_cookie = NULL; while (( avpl = get_next_avpl(cfg->keys,&avpl_cookie) )) { if (! ( gog_keys = g_hash_table_lookup(matecfg->gogs_by_gopname,avpl->name))) { gog_keys = new_loal(avpl->name); g_hash_table_insert(matecfg->gogs_by_gopname,gog_keys->name,gog_keys); } gopkey_avpl = new_avpl_from_avpl(cfg->name, avpl, TRUE); loal_append(gog_keys,gopkey_avpl); avp_cookie = NULL; while (( avp = get_next_avp(avpl,&avp_cookie) )) { if (! g_hash_table_lookup(cfg->my_hfids,avp->n)) { new_attr_hfri(cfg->name,cfg->my_hfids,avp->n); insert_avp(key_avps,avp); } } } /* insert the extra avps to the hfarray */ avp_cookie = NULL; while (( avp = get_next_avp(cfg->extra,&avp_cookie) )) { if (! g_hash_table_lookup(cfg->my_hfids,avp->n)) { new_attr_hfri(cfg->name,cfg->my_hfids,avp->n); } } /* every key_avp ios an extra as well. one day every Member will have its own extras */ merge_avpl(cfg->extra,key_avps,TRUE); analyze_transform_hfrs(cfg->name,cfg->transforms,cfg->my_hfids); ett = &cfg->ett; g_array_append_val(matecfg->ett,ett); ett = &cfg->ett_attr; g_array_append_val(matecfg->ett,ett); ett = &cfg->ett_children; g_array_append_val(matecfg->ett,ett); ett = &cfg->ett_times; g_array_append_val(matecfg->ett,ett); ett = &cfg->ett_gog_gop; g_array_append_val(matecfg->ett,ett); }