예제 #1
0
/**
 * merge_avpl:
 * @param name the name of the new avpl.
 * @param avpl the avpl from which to get the avps.
 * @param copy_avps whether avps should be copied instead of referenced.
 *
 * Creates a new avpl containing the same avps as the given avpl
 * It will either reference or copie the avps.
 *
 * Return value: a pointer to the newly allocated string.
 *
 **/
extern AVPL* new_avpl_from_avpl(const gchar* name, AVPL* avpl, gboolean copy_avps) {
	AVPL* newavpl = new_avpl(name);
	void* cookie = NULL;
	AVP* avp;
	AVP* copy;

#ifdef _AVP_DEBUGGING
	dbg_print(dbg_avpl_op,3,dbg_fp,"new_avpl_from_avpl: %X from=%X name='%s'",newavpl,avpl,name);
#endif

	while(( avp = get_next_avp(avpl,&cookie) )) {
		if (copy_avps) {
			copy = avp_copy(avp);
			if ( ! insert_avp(newavpl,copy) ) {
				delete_avp(copy);
			}
		} else {
			insert_avp(newavpl,avp);
		}
	}

#ifdef _AVP_DEBUGGING
	dbg_print(dbg_avpl_op,8,dbg_fp,"new_avpl_from_avpl: done");
#endif

	return newavpl;
}
예제 #2
0
static mate_gog* new_gog(mate_cfg_gog* cfg, mate_gop* gop) {
	mate_gog* gog = (mate_gog*)g_slice_new(mate_max_size);
	gog->id = ++(cfg->last_id);
	gog->cfg = cfg;

	dbg_print (dbg_gog,1,dbg_facility,"new_gog: %s:%u for %s:%u",gog->cfg->name,gog->id,gop->cfg->name,gop->id);

	gog->avpl = new_avpl(cfg->name);
	gog->last_n = 0;

	gog->expiration = 0.0;
	gog->idle_expiration = 0.0;

	gog->start_time = rd->now;
	gog->release_time = 0.0;
	gog->last_time = 0.0;

	gog->gops = NULL;
	gog->last_gop = NULL;

	gog->num_of_gops = 0;
	gog->num_of_counting_gops = 0;
	gog->num_of_released_gops = 0;

	gog->gog_keys = g_ptr_array_new();

	adopt_gop(gog,gop);

	return gog;
}
예제 #3
0
extern mate_cfg_gop* new_gopcfg(gchar* name) {
	mate_cfg_gop* cfg = g_malloc(sizeof(mate_cfg_gop));

	cfg->name = g_strdup(name);
	cfg->last_id = 0;

	cfg->items = g_hash_table_new(g_direct_hash,g_direct_equal);
	cfg->transforms = NULL;

	cfg->extra = new_avpl("extra");

	cfg->hfid = -1;

	cfg->ett = -1;
	cfg->ett_attr = -1;
	cfg->ett_times = -1;
	cfg->ett_children = -1;

	cfg->hfid_start_time = -1;
	cfg->hfid_stop_time = -1;
	cfg->hfid_last_time = -1;

	cfg->hfid_gop_pdu = -1;
	cfg->hfid_gop_num_pdus = -1;

	cfg->my_hfids = g_hash_table_new(g_str_hash,g_str_equal);

	cfg->gop_index = g_hash_table_new(g_str_hash,g_str_equal);
	cfg->gog_index = g_hash_table_new(g_str_hash,g_str_equal);

	g_hash_table_insert(matecfg->gopcfgs,(gpointer) cfg->name, (gpointer) cfg);

	return cfg;
}
예제 #4
0
static mate_gop* new_gop(mate_cfg_gop* cfg, mate_pdu* pdu, gchar* key) {
	mate_gop* gop = (mate_gop*)g_slice_new(mate_max_size);

	gop->id = ++(cfg->last_id);
	gop->cfg = cfg;

	dbg_print(dbg_gop, 1, dbg_facility, "new_gop: %s: ``%s:%d''", key, gop->cfg->name, gop->id);

	gop->gop_key = key;
	gop->avpl = new_avpl(cfg->name);
	gop->last_n = 0;

	gop->gog = NULL;
	gop->next = NULL;

	gop->expiration = cfg->expiration > 0.0 ? cfg->expiration + rd->now : (float) -1.0 ;
	gop->idle_expiration = cfg->idle_timeout > 0.0 ? cfg->idle_timeout + rd->now : (float) -1.0 ;
	gop->time_to_die = cfg->lifetime > 0.0 ? cfg->lifetime + rd->now : (float) -1.0 ;
	gop->time_to_timeout = 0.0;

	gop->last_time = gop->start_time = rd->now;
	gop->release_time = 0.0;

	gop->num_of_pdus = 0;
	gop->num_of_after_release_pdus = 0;

	gop->pdus = pdu;
	gop->last_pdu = pdu;

	gop->released = FALSE;

	pdu->gop = gop;
	pdu->next = NULL;
	pdu->is_start = TRUE;
	pdu->time_in_gop = 0.0;

	g_hash_table_insert(cfg->gop_index,gop->gop_key,gop);
	return gop;
}
예제 #5
0
static mate_pdu* new_pdu(mate_cfg_pdu* cfg, guint32 framenum, field_info* proto, proto_tree* tree) {
	mate_pdu* pdu = (mate_pdu*)g_slice_new(mate_max_size);
	field_info* cfi;
	GPtrArray* ptrs;
	mate_range* range;
	mate_range* proto_range;
	tmp_pdu_data data;
	guint i,j;
	gint min_dist;
	field_info* range_fi;
	gint32 last_start;
	gint32 first_end;
	gint32 curr_end;
	int hfid;

	dbg_print (dbg_pdu,1,dbg_facility,"new_pdu: type=%s framenum=%i",cfg->name,framenum);

	pdu->id = ++(cfg->last_id);
	pdu->cfg = cfg;

	pdu->avpl = new_avpl(cfg->name);

	pdu->frame = framenum;
	pdu->next_in_frame = NULL;
	pdu->rel_time = rd->now;

	pdu->gop = NULL;
	pdu->next = NULL;
	pdu->time_in_gop = -1.0;

	pdu->first = FALSE;
	pdu->is_start = FALSE;
	pdu->is_stop = FALSE;
	pdu->after_release = FALSE;

	data.ranges = g_ptr_array_new();
	data.pdu  = pdu;
	data.tree = tree;

	/* first we create the proto range */
	proto_range = g_malloc(sizeof(mate_range));
	proto_range->start = proto->start;
	proto_range->end = proto->start + proto->length;
	g_ptr_array_add(data.ranges,proto_range);

	dbg_print(dbg_pdu,3,dbg_facility,"new_pdu: proto range %u-%u",proto_range->start,proto_range->end);

	last_start = proto_range->start;

	/* we move forward in the tranport */
	for (i = cfg->transport_ranges->len; i--; ) {
		hfid = *((int*)g_ptr_array_index(cfg->transport_ranges,i));
		ptrs = proto_get_finfo_ptr_array(tree, hfid);
		min_dist = 99999;
		range_fi = NULL;

		if (ptrs) {
			for (j=0; j < ptrs->len; j++) {
				cfi = (field_info*) g_ptr_array_index(ptrs,j);
				if (cfi->start < last_start && min_dist >= (last_start - cfi->start) ) {
					range_fi = cfi;
					min_dist = last_start - cfi->start;
				}
			}

			if ( range_fi ) {
				range = g_malloc(sizeof(*range));
				range->start = range_fi->start;
				range->end = range_fi->start + range_fi->length;
				g_ptr_array_add(data.ranges,range);

				last_start = range_fi->start;

				dbg_print(dbg_pdu,3,dbg_facility,"new_pdu: transport(%i) range %i-%i",hfid,range->start,range->end);
			} else {
				/* we missed a range  */
				dbg_print(dbg_pdu,6,dbg_facility,"new_pdu: transport(%i) missed",hfid);
			}

		}
	}

	if (cfg->payload_ranges) {

		first_end = proto_range->end;

		for (i = 0 ; i < cfg->payload_ranges->len; i++) {
			hfid = *((int*)g_ptr_array_index(cfg->payload_ranges,i));
			ptrs = proto_get_finfo_ptr_array(tree, hfid);
			min_dist = 99999;
			range_fi = NULL;

			if (ptrs) {
				for (j=0; j < ptrs->len; j++) {
					cfi = (field_info*) g_ptr_array_index(ptrs,j);
					curr_end = cfi->start + cfi->length;
					if (curr_end > first_end && min_dist >= (curr_end - first_end) ) {
						range_fi = cfi;
						min_dist = curr_end - first_end;
					}
				}

				if ( range_fi ) {
					range = g_malloc(sizeof(*range));
					range->start = range_fi->start;
					range->end = range_fi->start + range_fi->length;
					g_ptr_array_add(data.ranges,range);

					last_start = range_fi->start;

					dbg_print(dbg_pdu,3,dbg_facility,"new_pdu: payload(%i) range %i-%i",hfid,range->start,range->end);
				} else {
					/* we missed a range  */
					dbg_print(dbg_pdu,5,dbg_facility,"new_pdu: payload(%i) missed",hfid);
				}

			}
		}
	}

	g_hash_table_foreach(cfg->hfids_attr,get_pdu_fields,&data);

	apply_transforms(pdu->cfg->transforms,pdu->avpl);

	g_ptr_array_free(data.ranges,TRUE);

	return pdu;
}
예제 #6
0
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;
	}
}
예제 #7
0
/**
 * new_avpl_loose_match:
 * @param name the name of the resulting avpl
 * @param src avpl to be matched agains an "op" avpl
 * @param op the "op" avpl that will be matched against the src avpl
 * @param copy_avps whether the avps in the resulting avpl should be copied
 *
 * creates an avp list containing any avps in src matching any avps in op
 * it will eventually create an empty list in none match
 *
 * Return value: a pointer to the newly created avpl containing the
 *				 matching avps.
 **/
extern AVPL* new_avpl_loose_match(const gchar* name,
								  AVPL* src,
								  AVPL* op,
								  gboolean copy_avps) {

	AVPL* newavpl = new_avpl(scs_subscribe(avp_strings, name));
	AVPN* co = NULL;
	AVPN* cs = NULL;
	ptrdiff_t c;
	AVP* m;
	AVP* copy;

#ifdef _AVP_DEBUGGING
	dbg_print(dbg_avpl_op,3,dbg_fp,"new_avpl_loose_match: %X src=%X op=%X name='%s'",newavpl,src,op,name);
#endif


	cs = src->null.next;
	co = op->null.next;
	while(1) {

		if (!co->avp) {
			return newavpl;
		}

		if (!cs->avp) {
			return newavpl;
		}


		c = ADDRDIFF(co->avp->n, cs->avp->n);

		if ( c > 0 ) {
			if (co->avp) co = co->next;
		} else if (c < 0) {
			if (cs->avp) cs = cs->next;
		} else {
			m = match_avp(cs->avp,co->avp);
			if(m) {

				if (copy_avps) {
					copy = avp_copy(m);
					if ( ! insert_avp(newavpl,copy) ) {
						delete_avp(copy);
					}
				} else {
					insert_avp(newavpl,m);
				}


			}

			if (cs->avp) cs = cs->next;

		}
	}

#ifdef _AVP_DEBUGGING
	dbg_print(dbg_avpl_op,6,dbg_fp,"new_avpl_loose_match: done!");
#endif

	return NULL;
}
예제 #8
0
/**
 * loal_from_file:
 * @param filename the file containing a loals text representation.
 *
 * Given a filename it will attempt to load a loal containing a copy of
 * the avpls represented in the file.
 *
 * Return value: if successful a pointer to the new populated loal, else NULL.
 *
 **/
extern LoAL* loal_from_file(gchar* filename) {
	FILE *fp = NULL;
	gchar c;
	int i = 0;
	guint32 linenum = 1;
	gchar linenum_buf[MAX_ITEM_LEN];
	gchar name[MAX_ITEM_LEN];
	gchar value[MAX_ITEM_LEN];
	gchar op = '?';
	LoAL *loal = new_loal(filename);
	AVPL* curr = NULL;
	AVP* avp;

	enum _load_loal_states {
		START,
		BEFORE_NAME,
		IN_NAME,
		IN_VALUE,
		MY_IGNORE
	} state;

#ifndef _WIN32
	if (! getuid()) {
		return load_loal_error(fp,loal,curr,linenum,"MATE Will not run as root");
	}
#endif

	state = START;

	if (( fp = ws_fopen(filename,"r") )) {
		while(( c = (gchar) fgetc(fp) )){

			if ( feof(fp) ) {
				if ( ferror(fp) ) {
					report_read_failure(filename,errno);
					return load_loal_error(fp,loal,curr,linenum,"Error while reading '%f'",filename);
				}
				break;
			}

			if ( c == '\n' ) {
				linenum++;
			}

			if ( i >= MAX_ITEM_LEN - 1  ) {
				return load_loal_error(fp,loal,curr,linenum,"Maximum item length exceeded");
			}

			switch(state) {
				case MY_IGNORE:
					switch (c) {
						case '\n':
							state = START;
							i = 0;
							continue;
						default:
							continue;
					}
				case START:
					switch (c) {
						case ' ': case '\t':
							/* ignore whitespace at line start */
							continue;
						case '\n':
							/* ignore empty lines */
							i = 0;
							continue;
						case AVP_NAME_CHAR:
							state = IN_NAME;
							i = 0;
							name[i++] = c;
							name[i] = '\0';
							g_snprintf(linenum_buf,sizeof(linenum_buf),"%s:%u",filename,linenum);
							curr = new_avpl(linenum_buf);
							continue;
						case '#':
							state = MY_IGNORE;
							continue;
						default:
							return load_loal_error(fp,loal,curr,linenum,"expecting name got: '%c'",c);
					}
				case BEFORE_NAME:
					i = 0;
					name[0] = '\0';
					switch (c) {
						case '\\':
							c = (gchar) fgetc(fp);
							if (c != '\n') ungetc(c,fp);
							continue;
						case ' ':
						case '\t':
							continue;
						case AVP_NAME_CHAR:
							state = IN_NAME;

							name[i++] = c;
							name[i] = '\0';
							continue;
						case '\n':
							loal_append(loal,curr);
							state = START;
							continue;
						default:
							return load_loal_error(fp,loal,curr,linenum,"expecting name got: '%c'",c);
					}
					case IN_NAME:
						switch (c) {
							case ';':
								state = BEFORE_NAME;

								op = '?';
								name[i] = '\0';
								value[0] = '\0';
								i = 0;

								avp = new_avp(name,value,op);

								if (! insert_avp(curr,avp) ) {
									delete_avp(avp);
								}

								continue;
							case AVP_OP_CHAR:
								name[i] = '\0';
								i = 0;
								op = c;
								state = IN_VALUE;
								continue;
							case AVP_NAME_CHAR:
								name[i++] = c;
								continue;
							case '\n':
								return load_loal_error(fp,loal,curr,linenum,"operator expected found new line");
							default:
								return load_loal_error(fp,loal,curr,linenum,"name or match operator expected found '%c'",c);
						}
					case IN_VALUE:
						switch (c) {
							case '\\':
								value[i++] = (gchar) fgetc(fp);
								continue;
							case ';':
								state = BEFORE_NAME;

								value[i] = '\0';
								i = 0;

								avp = new_avp(name,value,op);

								if (! insert_avp(curr,avp) ) {
									delete_avp(avp);
								}
								continue;
							case '\n':
								return load_loal_error(fp,loal,curr,linenum,"';' expected found new line");
							default:
								value[i++] = c;
								continue;
						}
			}
		}
		fclose (fp);

		return loal;

	} else {
		report_open_failure(filename,errno,FALSE);
		return load_loal_error(NULL,loal,NULL,0,"Cannot Open file '%s'",filename);
	}
}
예제 #9
0
/**
 * new_avpl_exact_match:
 * @param name the name of the resulting avpl
 * @param src avpl to be matched agains an "op" avpl
 * @param op the "op" avpl that will be matched against the src avpl
 * @param copy_avps whether the avps in the resulting avpl should be copied
 *
 * creates an avp list containing every avp in src matching every avp in op
 * it will not create a list unless every avp in op is matched only once
 * to every avp in op.
 *
 * Return value: a pointer to the newly created avpl containing the
 *				 matching avps.
 **/
extern AVPL* new_avpl_exact_match(const gchar* name,AVPL* src, AVPL* op, gboolean copy_avps) {
	AVPL* newavpl = new_avpl(name);
	AVPN* co = NULL;
	AVPN* cs = NULL;
	ptrdiff_t c;
	AVP* m;
	AVP* copy;

#ifdef _AVP_DEBUGGING
	dbg_print(dbg_avpl_op,3,dbg_fp,"new_avpl_every_match: %X src=%X op=%X name='%s'",newavpl,src,op,name);
#endif

	if (op->len == 0)
		return newavpl;

	if (src->len == 0) {
		delete_avpl(newavpl,FALSE);
		return NULL;
	}

	cs = src->null.next;
	co = op->null.next;
	while(1) {

		c = ADDRDIFF(co->avp->n,cs->avp->n);

		if ( c > 0 ) {
			delete_avpl(newavpl,TRUE);
			return NULL;
		} else if (c < 0) {
			cs = cs->next;
			if (! cs->avp ) {
				delete_avpl(newavpl,TRUE);
				return NULL;
			}
		} else {
			m = match_avp(cs->avp,co->avp);

			if(m) {
				cs = cs->next;
				co = co->next;

				if (copy_avps) {
					copy = avp_copy(m);
					if ( ! insert_avp(newavpl,copy) ) {
						delete_avp(copy);
					}
				} else {
					insert_avp(newavpl,m);
				}


				if (!co->avp) {
					return newavpl;
				}
				if (!cs->avp) {
					delete_avpl(newavpl,TRUE);
					return NULL;
				}
			} else {
				delete_avpl(newavpl,TRUE);
				return NULL;
			}
		}

	}

	/* should never be reached */
	return NULL;
}
예제 #10
0
/**
* new_avpl_every_match:
 * @param name the name of the resulting avpl
 * @param src avpl to be matched agains an "op" avpl
 * @param op the "op" avpl that will be matched against the src avpl
 * @param copy_avps whether the avps in the resulting avpl should be copied
 *
 * creates an avp list containing any avps in src matching every avp in op
 * it will not create a list if there is not a match for every attribute in op
 *
 * Return value: a pointer to the newly created avpl containing the
 *				 matching avps.
 **/
extern AVPL* new_avpl_every_match(const gchar* name, AVPL* src, AVPL* op, gboolean copy_avps) {
	AVPL* newavpl;
	AVPN* co = NULL;
	AVPN* cs = NULL;
	ptrdiff_t c;
	AVP* m;
	AVP* copy;
	gboolean matches;

#ifdef _AVP_DEBUGGING
	dbg_print(dbg_avpl_op,3,dbg_fp,"new_avpl_every_match: %X src=%X op=%X name='%s'",newavpl,src,op,name);
#endif
	if (src->len == 0) return NULL;

	newavpl = new_avpl(scs_subscribe(avp_strings, name));

	if (op->len == 0)
		return newavpl;

	matches = TRUE;

	cs = src->null.next;
	co = op->null.next;
	while(1) {

		if (!co->avp) {
			break;
		}

		if (!cs->avp) {
			break;
		}

		c = ADDRDIFF(co->avp->n,cs->avp->n);

		if ( c > 0 ) {
			delete_avpl(newavpl,TRUE);
			return NULL;
		} else if (c < 0) {
			cs = cs->next;
			if (! cs->avp ) {
				break;
			}
		} else {
			m = match_avp(cs->avp,co->avp);

			if(m) {
				matches++;
				cs = cs->next;
				co = co->next;

				if (copy_avps) {
					copy = avp_copy(m);
					if ( ! insert_avp(newavpl,copy) ) {
						delete_avp(copy);
					}
				} else {
					insert_avp(newavpl,m);
				}

			} else {
				cs = cs->next;
			}
		}

	}

	if (matches) {
		return newavpl;
	} else {
		delete_avpl(newavpl,TRUE);
		return NULL;
	}
}
예제 #11
0
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);

}