|
|
@ -62,16 +62,16 @@ struct feature_sub {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static struct feature_pvt {
|
|
|
|
static struct feature_pvt {
|
|
|
|
ast_mutex_t lock; /* Channel private lock */
|
|
|
|
ast_mutex_t lock; /* Channel private lock */
|
|
|
|
char tech[AST_MAX_EXTENSION]; /* Technology to abstract */
|
|
|
|
char tech[AST_MAX_EXTENSION]; /* Technology to abstract */
|
|
|
|
char dest[AST_MAX_EXTENSION]; /* Destination to abstract */
|
|
|
|
char dest[AST_MAX_EXTENSION]; /* Destination to abstract */
|
|
|
|
struct ast_channel *subchan;
|
|
|
|
struct ast_channel *subchan;
|
|
|
|
struct feature_sub subs[3]; /* Subs */
|
|
|
|
struct feature_sub subs[3]; /* Subs */
|
|
|
|
struct ast_channel *owner; /* Current Master Channel */
|
|
|
|
struct ast_channel *owner; /* Current Master Channel */
|
|
|
|
struct feature_pvt *next; /* Next entity */
|
|
|
|
struct feature_pvt *next; /* Next entity */
|
|
|
|
} *features = NULL;
|
|
|
|
} *features = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
#define SUB_REAL 0 /* Active call */
|
|
|
|
#define SUB_REAL 0 /* Active call */
|
|
|
|
#define SUB_CALLWAIT 1 /* Call-Waiting call on hold */
|
|
|
|
#define SUB_CALLWAIT 1 /* Call-Waiting call on hold */
|
|
|
|
#define SUB_THREEWAY 2 /* Three-way call */
|
|
|
|
#define SUB_THREEWAY 2 /* Three-way call */
|
|
|
|
|
|
|
|
|
|
|
@ -453,33 +453,33 @@ static struct ast_channel *features_new(struct feature_pvt *p, int state, int in
|
|
|
|
ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
|
|
|
|
ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tmp->tech = &features_tech;
|
|
|
|
tmp->tech = &features_tech;
|
|
|
|
for (x=1;x<4;x++) {
|
|
|
|
for (x=1;x<4;x++) {
|
|
|
|
snprintf(tmp->name, sizeof(tmp->name), "Feature/%s/%s-%d", p->tech, p->dest, x);
|
|
|
|
snprintf(tmp->name, sizeof(tmp->name), "Feature/%s/%s-%d", p->tech, p->dest, x);
|
|
|
|
for (y=0;y<3;y++) {
|
|
|
|
for (y=0;y<3;y++) {
|
|
|
|
if (y == index)
|
|
|
|
if (y == index)
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
if (p->subs[x].owner && !strcasecmp(p->subs[x].owner->name, tmp->name))
|
|
|
|
if (p->subs[x].owner && !strcasecmp(p->subs[x].owner->name, tmp->name))
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (y >= 3)
|
|
|
|
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tmp->type = type;
|
|
|
|
if (y >= 3)
|
|
|
|
ast_setstate(tmp, state);
|
|
|
|
break;
|
|
|
|
tmp->writeformat = p->subchan->writeformat;
|
|
|
|
}
|
|
|
|
tmp->rawwriteformat = p->subchan->rawwriteformat;
|
|
|
|
tmp->type = type;
|
|
|
|
tmp->readformat = p->subchan->readformat;
|
|
|
|
ast_setstate(tmp, state);
|
|
|
|
tmp->rawreadformat = p->subchan->rawreadformat;
|
|
|
|
tmp->writeformat = p->subchan->writeformat;
|
|
|
|
tmp->nativeformats = p->subchan->readformat;
|
|
|
|
tmp->rawwriteformat = p->subchan->rawwriteformat;
|
|
|
|
tmp->tech_pvt = p;
|
|
|
|
tmp->readformat = p->subchan->readformat;
|
|
|
|
p->subs[index].owner = tmp;
|
|
|
|
tmp->rawreadformat = p->subchan->rawreadformat;
|
|
|
|
if (!p->owner)
|
|
|
|
tmp->nativeformats = p->subchan->readformat;
|
|
|
|
p->owner = tmp;
|
|
|
|
tmp->tech_pvt = p;
|
|
|
|
ast_mutex_lock(&usecnt_lock);
|
|
|
|
p->subs[index].owner = tmp;
|
|
|
|
usecnt++;
|
|
|
|
if (!p->owner)
|
|
|
|
ast_mutex_unlock(&usecnt_lock);
|
|
|
|
p->owner = tmp;
|
|
|
|
ast_update_use_count();
|
|
|
|
ast_mutex_lock(&usecnt_lock);
|
|
|
|
|
|
|
|
usecnt++;
|
|
|
|
|
|
|
|
ast_mutex_unlock(&usecnt_lock);
|
|
|
|
|
|
|
|
ast_update_use_count();
|
|
|
|
return tmp;
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|