示例#1
0
unsigned int get_app_index(struct sip_msg* msg)
{
	unsigned int appearance;
	struct hdr_field *call_info;
	struct call_info_body *callinfo_b;
	struct to_body *call_info_b;
	struct to_param *param;

	if (0 == parse_call_info_header(msg)) {
		call_info = msg->call_info;
		while (call_info) {
			//LM_DBG("BODY=[%p]->[%.*s] sibling=[%p]\n", call_info,
			//	call_info->body.len, call_info->body.s,
			//	call_info->sibling);
			callinfo_b = call_info->parsed;
			while (callinfo_b) {
				call_info_b = &(callinfo_b->call_info_body);
				//LM_DBG(". body=[%.*s] param_lst=[%p] "
				//	"last_param=[%p]\n",
				//	call_info_b->body.len, call_info_b->body.s,
				//	call_info_b->param_lst,
				//	call_info_b->last_param);
				param = call_info_b->param_lst;
				while (param) {
					//LM_DBG(".. [%p]->[%d] "
					//	"[%.*s]=[%.*s]->[%p]\n",
					//	param, param->type,
					//	param->name.len, param->name.s,
					//	param->value.len, param->value.s,
					//	param->next);
					if (param->name.len==APPEARANCE_INDEX_LEN &&
						strncmp(APPEARANCE_INDEX_STR,
							param->name.s,
							APPEARANCE_INDEX_LEN)==0) {
						if (strno2int(&param->value,
								&appearance)<0) {
							LM_ERR("bad appearance-index"
								" [%.*s]\n",
								param->value.len,
								param->value.s);
							return 0;
						}
						LM_DBG("*** GOT APP-INDEX [%d]\n",
								appearance);
						return appearance;
					}
					param=param->next;
				}
				callinfo_b = callinfo_b->next;
			}
			call_info = call_info->sibling;
		}
	} else {
		LM_ERR("Unable to parse Call-Info header\n");
		return 0;
	}

	LM_ERR("appearance index not found\n");
	return 0;
}
示例#2
0
int sca_set_line(struct sip_msg *msg, str *line_s, int calling)
{
	struct dlg_cell *dlg;
	unsigned int idx;
	struct sca_line *line;

	/* extract the index from the call-info line */
	if ( parse_call_info_header( msg )!=0 ) {
		LM_ERR("missing or bogus Call-Info header in INVITE\n");
		return -1;
	}
	idx = get_appearance_index(msg);
	if (idx==0) {
		LM_ERR("failed to extract line index from Call-Info hdr\n");
		return -1;
	}

	LM_DBG("looking for line  <%.*s>, idx %d, calling %d \n",
		line_s->len, line_s->s, idx, calling);

	/* search for the line (with no creation) */
	line = get_sca_line( line_s, 0);
	if (line==NULL) {
		LM_ERR("used line <%.*s> not found in hash. Using without seizing?\n",
			line_s->len, line_s->s);
		return -1;
	}
	/* NOTE: the line is now locked !!!!! */

	/* check if the index is seized */
	if (calling) {
		if (line->seize_state!=idx) {
			LM_ERR("line not seized or seized for other index "
				"(idx=%d,seize=%d)\n",idx,line->seize_state);
			goto error;
		}
	}

	/* create and bind to the dialog */
	if (dlgf.create_dlg(msg,0)< 0) {
		LM_ERR("failed to create dialog\n");
		goto error;
	}

	dlg = dlgf.get_dlg();

	LM_DBG("INVITE dialog created: using line <%.*s>\n",
		line_s->len, line_s->s);

	/* store the line variable into dialog */
	if (calling) {
		if(dlgf.store_dlg_value(dlg, &calling_line_Dvar, line_s)< 0) {
			LM_ERR("Failed to store calling line\n");
			goto error;
		}
	} else {
		if(dlgf.store_dlg_value(dlg, &called_line_Dvar, line_s)< 0) {
			LM_ERR("Failed to store called line\n");
			goto error;
		}
	}

	/* register callbacks */
	if (dlgf.register_dlgcb( dlg,
	DLGCB_FAILED| DLGCB_CONFIRMED | DLGCB_TERMINATED | DLGCB_EXPIRED |
	DLGCB_EARLY , sca_dialog_callback, (void*)(long)idx, 0) != 0) {
		LM_ERR("cannot register callbacks for dialog\n");
		goto error;
	}

	/* STILL LOCKED HERE !! */
	terminate_line_sieze(line);
	/* lock released by above function */

	return 1;
error:
	unlock_sca_line(line);
	return -1;
}
示例#3
0
int sca_logic_notify(b2bl_cb_params_t *params, unsigned int b2b_event)
{
	int on_hold = 0;
	int sdp_session_num = 0, sdp_stream_num;
	sdp_session_cell_t* sdp_session;
	sdp_stream_cell_t* sdp_stream;
	struct sip_msg *msg = params->msg;
	b2bl_cb_ctx_t *cb_params = params->param;
	str *shared_line;
	unsigned int hash_index, appearance;
	b2b_sca_record_t *record;
	b2b_sca_call_t *call = NULL;
	str publish_hdr;
	unsigned int call_info_appearance;
	unsigned int call_info_appearance_state = 0;
	struct hdr_field *call_info;
	struct call_info_body *callinfo_b;
	struct to_body *call_info_b;
	struct to_param *param;

	if (b2b_sca_shutdown_completed) return B2B_FOLLOW_SCENARIO_CB_RET;
	if (params == NULL) {
		LM_ERR("callback event [%d] without cb params\n", b2b_event);
		return B2B_DROP_MSG_CB_RET;
	}

	shared_line = &cb_params->shared_line;
	hash_index = cb_params->hash_index;
	appearance = cb_params->appearance;

	LM_DBG("*** GOT NOTIFICATION TYPE [%d] WITH cb_params [%p]->[%.*s] appearance [%d] on hash index [%d]"
			" for b2bl entity [%d]\n",
			b2b_event, cb_params, shared_line->len, shared_line->s,
			appearance, hash_index, params->entity);


	if (msg && msg->call_info) {
		if (0 == parse_call_info_header(msg)) {
			call_info = msg->call_info;
			if (call_info) {
				LM_DBG("BODY=[%p]->[%.*s] sibling=[%p]\n", call_info,
					call_info->body.len, call_info->body.s, call_info->sibling);
				callinfo_b = call_info->parsed;
				while (callinfo_b) {
					call_info_b = &(callinfo_b->call_info_body);
					LM_DBG(". body=[%.*s] param_lst=[%p] last_param=[%p]\n",
						call_info_b->body.len, call_info_b->body.s,
						call_info_b->param_lst, call_info_b->last_param);
					param = call_info_b->param_lst;
					while (param) {
						LM_DBG(".. [%p]->[%d] [%.*s]=[%.*s]->[%p]\n",
							param, param->type, param->name.len, param->name.s,
							param->value.len, param->value.s, param->next);
						if (param->name.len==APPEARANCE_INDEX_LEN &&
							strncmp(APPEARANCE_INDEX_STR,
							param->name.s, APPEARANCE_INDEX_LEN)==0) {
							if (strno2int(&param->value,&call_info_appearance)<0) {
								LM_ERR("bad appearance-index [%.*s]\n",
									param->value.len, param->value.s);
								return -1;
							}
							if (appearance != call_info_appearance) {
								LM_ERR("got appearance[%d] while expecting[%d]\n",
									call_info_appearance, appearance);
								goto next_callinfo_b;
							} else {
								LM_DBG("*** GOT APP-INDEX [%d]\n",
									call_info_appearance);
							}
						} else if (param->name.len==APPEARANCE_STATE_LEN &&
							strncmp(APPEARANCE_STATE_STR,
							param->name.s, APPEARANCE_STATE_LEN)==0) {
							LM_DBG("*** GOT APP-STATE [%.*s]\n",
								param->value.len, param->value.s);
							if (param->value.len == strlen(APP_STATE_HELD_PRIVATE) &&
								strncmp(param->value.s,
									app_state[HELD_PRIVATE_STATE].s,
									param->value.len)==0) {
								call_info_appearance_state = HELD_PRIVATE_STATE;
							}
						}
						param=param->next;
					}
					goto handle_appearance;
next_callinfo_b:
					callinfo_b = callinfo_b->next;
				}
				call_info = call_info->sibling;
			}
		} else {
			LM_ERR("Unable to parse Call-Info header\n");
			return B2B_DROP_MSG_CB_RET;
		}
	}

handle_appearance:
	lock_get(&b2b_sca_htable[hash_index].lock);
	record = b2b_sca_search_record_safe(hash_index, shared_line);
	if (record == NULL) {
		lock_release(&b2b_sca_htable[hash_index].lock);
		LM_ERR("record not found for shared line [%.*s] on hash index [%d]\n",
			shared_line->len, shared_line->s, hash_index);
		return B2B_DROP_MSG_CB_RET;
	}

	b2b_sca_print_record(record);

	switch(b2b_event){
	case B2B_DESTROY_CB:
		/* Destroy the sca index record */
		shm_free(params->param);
		b2b_sca_delete_call_record(hash_index, record, appearance);
		break;
	case B2B_RE_INVITE_CB:
	case B2B_CONFIRMED_CB:
		call = b2b_sca_search_call_safe(record, appearance);
		if (call == NULL) {
			LM_ERR("call record not found for shared line [%.*s] with index [%d]\n",
						shared_line->len, shared_line->s, appearance);
			lock_release(&b2b_sca_htable[hash_index].lock);
			return B2B_DROP_MSG_CB_RET;
		}
		if (0 == parse_sdp(msg)) {
			sdp_session = get_sdp_session(msg, sdp_session_num);
			if(!sdp_session) break;
			sdp_stream_num = 0;
			for(;;) {
				sdp_stream = get_sdp_stream(msg, sdp_session_num, sdp_stream_num);
				if(!sdp_stream) break;
				if(sdp_stream->media.len==AUDIO_STR_LEN &&
					strncmp(sdp_stream->media.s,AUDIO_STR,AUDIO_STR_LEN)==0 &&
					sdp_stream->is_on_hold) {
					on_hold = 1;
					break;
				}
				sdp_stream_num++;
			}
			sdp_session_num++;
		}

		if (on_hold) {
			if (call_info_appearance_state)
				call->call_state = HELD_PRIVATE_STATE;
			else
				call->call_state = HELD_STATE;
		} else {
			call->call_state = ACTIVE_STATE;
		}
		break;
	default:
		LM_ERR("Unexpected event\n");
	}

	/* Prepare PUBLISH Call-Info header.  */
	if (build_publish_call_info_header(record, &publish_hdr) != 0) {
		lock_release(&b2b_sca_htable[hash_index].lock);
		LM_ERR("Unable to build PUBLISH Call-Info header\n");
		return B2B_FOLLOW_SCENARIO_CB_RET;
	}

	/* Save the record to db. */
	if (push_sca_info_to_db(record, appearance, 1) != 0)
		LM_ERR("DB out of synch\n");

	/* Notify the watchers. */
	sca_publish(record, &publish_hdr);

	b2b_sca_delete_record_if_empty(record, hash_index);

	lock_release(&b2b_sca_htable[hash_index].lock);

	if (publish_hdr.s != publish_call_info_hdr_buf)
		pkg_free(publish_hdr.s);

	return B2B_FOLLOW_SCENARIO_CB_RET;
}