Newer
Older
for(i = 0; i < 20 ; i++){
flags = ZT_IOMUX_WRITEEMPTY | ZT_IOMUX_NOWAIT;
res = ioctl(chan->fds[0], ZT_IOMUX, &flags);
if(flags & ZT_IOMUX_WRITEEMPTY)
break;
if( ast_safe_sleep(chan, 50)){
res = -1;
break;
}
}
return res;
}
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
static int sayfile(struct ast_channel *mychannel,char *fname)
{
int res;
res = ast_streamfile(mychannel, fname, mychannel->language);
if (!res)
res = ast_waitstream(mychannel, "");
else
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
ast_stopstream(mychannel);
return res;
}
static int saycharstr(struct ast_channel *mychannel,char *str)
{
int res;
res = ast_say_character_str(mychannel,str,NULL,mychannel->language);
if (!res)
res = ast_waitstream(mychannel, "");
else
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
ast_stopstream(mychannel);
return res;
}
static int saynum(struct ast_channel *mychannel, int num)
{
int res;
res = ast_say_number(mychannel, num, NULL, mychannel->language, NULL);
if(!res)
res = ast_waitstream(mychannel, "");
else
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
ast_stopstream(mychannel);
return res;
}
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
/* Retrieve an int from a config file */
static int retrieve_astcfgint(char *category, char *name, int min, int max, int defl)
{
char *var;
int ret;
var = ast_variable_retrieve(cfg, category, name);
if(var){
ret = myatoi(var);
if(ret < min)
ret = min;
if(ret > max)
ret = max;
}
else
ret = defl;
return ret;
}
static int telem_any(struct ast_channel *chan, char *entry)
{
int res;
char c;
static int morsespeed;
static int morsefreq;
static int morseampl;
static int morseidfreq = 0;
static int morseidampl;
static char mcat[] = MORSE;
res = 0;
if(!morseidfreq){ /* Get the morse parameters if not already loaded */
morsespeed = retrieve_astcfgint( mcat, "speed", 5, 20, 20);
morsefreq = retrieve_astcfgint( mcat, "frequency", 300, 3000, 800);
morseampl = retrieve_astcfgint( mcat, "amplitude", 200, 8192, 4096);
morseidampl = retrieve_astcfgint( mcat, "idamplitude", 200, 8192, 2048);
morseidfreq = retrieve_astcfgint( mcat, "idfrequency", 300, 3000, 330);
}
/* Is it a file, or a tone sequence? */
if(entry[0] == '|'){
c = entry[1];
if((c >= 'a')&&(c <= 'z'))
c -= 0x20;
switch(c){
case 'I': /* Morse ID */
res = send_morse(chan, entry + 2, morsespeed, morseidfreq, morseidampl);
break;
case 'M': /* Morse Message */
res = send_morse(chan, entry + 2, morsespeed, morsefreq, morseampl);
break;
case 'T': /* Tone sequence */
res = send_tone_telemetry(chan, entry + 2);
break;
default:
res = -1;
}
}
else
res = sayfile(chan, entry); /* File */
return res;
}
/*
* This function looks up a telemetry name in the config file, and does a telemetry response as configured.
*
* 4 types of telemtry are handled: Morse ID, Morse Message, Tone Sequence, and a File containing a recording.
*/
static int telem_lookup(struct ast_channel *chan, char *node, char *name)
{
int res;
int i;
char *entry;
char *telemetry;
char *telemetry_save;
res = 0;
telemetry_save = NULL;
entry = NULL;
/* Retrieve the section name for telemetry from the node section */
telemetry = ast_variable_retrieve(cfg, node, TELEMETRY);
if(telemetry){
telemetry_save = ast_strdupa(telemetry);
if(!telemetry_save){
ast_log(LOG_WARNING,"ast_strdupa() failed in telem_lookup()\n");
return res;
}
entry = ast_variable_retrieve(cfg, telemetry_save, name);
}
/* Try to look up the telemetry name */
if(!entry){
/* Telemetry name wasn't found in the config file, use the default */
for(i = 0; i < sizeof(tele_defs)/sizeof(struct telem_defaults) ; i++){
if(!strcasecmp(tele_defs[i].name, name))
entry = tele_defs[i].value;
}
}
if(entry)
telem_any(chan, entry);
else{
ast_log(LOG_WARNING, "Telemetry name not found: %s\n", name);
res = -1;
}
return res;
}
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
/*
* Retrieve a wait interval
*/
static int get_wait_interval(struct rpt *myrpt, int type)
{
int interval;
char *wait_times;
char *wait_times_save;
wait_times_save = NULL;
wait_times = ast_variable_retrieve(cfg, myrpt->name, "wait_times");
if(wait_times){
wait_times_save = ast_strdupa(wait_times);
if(!wait_times_save){
ast_log(LOG_WARNING, "Out of memory in wait_interval()\n");
wait_times = NULL;
}
}
switch(type){
case DLY_TELEM:
if(wait_times)
interval = retrieve_astcfgint(wait_times_save, "telemwait", 500, 5000, 1000);
else
interval = 1000;
break;
case DLY_ID:
if(wait_times)
interval = retrieve_astcfgint(wait_times_save, "idwait",250,5000,500);
else
interval = 500;
break;
case DLY_UNKEY:
if(wait_times)
interval = retrieve_astcfgint(wait_times_save, "unkeywait",500,5000,1000);
else
interval = 1000;
break;
case DLY_CALLTERM:
if(wait_times)
interval = retrieve_astcfgint(wait_times_save, "calltermwait",500,5000,1500);
else
interval = 1500;
break;
default:
return 0;
}
return interval;
}
/*
* Wait a configurable interval of time
*/
static void wait_interval(struct rpt *myrpt, int type, struct ast_channel *chan)
{
int interval;
if((interval = get_wait_interval(myrpt, type)))
ast_safe_sleep(chan,interval);
return;
}
static void *rpt_tele_thread(void *this)
int res = 0,haslink,hastx,hasremote,imdone = 0, unkeys_queued, x;
struct rpt_tele *mytele = (struct rpt_tele *)this;
struct rpt_tele *tlist;
struct rpt *myrpt;
struct rpt_link *l,*m,linkbase;
struct ast_channel *mychannel;
char *p,*ct,*ct_copy,*ident, *nodename;
/* get a pointer to myrpt */
myrpt = mytele->rpt;
/* Snag copies of a few key myrpt variables */
rpt_mutex_lock(&myrpt->lock);
insque((struct qelem *)mytele, (struct qelem *)myrpt->tele.next); /* Moved from rpt_telemetry() */
nodename = ast_strdupa(myrpt->name);
ident = ast_strdupa(myrpt->ident);
rpt_mutex_unlock(&myrpt->lock);
mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
if (!mychannel)
{
fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
rpt_mutex_lock(&myrpt->lock);
remque((struct qelem *)mytele);
ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
rpt_mutex_unlock(&myrpt->lock);
free(mytele);
rpt_mutex_lock(&myrpt->lock);
mytele->chan = mychannel; /* Save a copy of the channel so we can access it externally if need be */
rpt_mutex_unlock(&myrpt->lock);
/* make a conference for the tx */
ci.chan = 0;
/* If there's an ID queued, or tail message queued, */
/* only connect the ID audio to the local tx conference so */
/* linked systems can't hear it */
ci.confno = (((mytele->mode == ID) || (mytele->mode == IDTALKOVER) || (mytele->mode == UNKEY) ||
(mytele->mode == TAILMSG)) ?
myrpt->txconf : myrpt->conf);
ci.confmode = ZT_CONF_CONFANN;
/* first put the channel on the conference in announce mode */
if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1)
{
ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
rpt_mutex_lock(&myrpt->lock);
remque((struct qelem *)mytele);
rpt_mutex_unlock(&myrpt->lock);
ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
free(mytele);
ast_hangup(mychannel);
pthread_exit(NULL);
}
ast_stopstream(mychannel);
switch(mytele->mode)
{
case ID:
Jim Dixon
committed
case ID1:
/* wait a bit */
wait_interval(myrpt, (mytele->mode == ID) ? DLY_ID : DLY_TELEM,mychannel);
res = telem_any(mychannel, ident);
imdone=1;
break;
case TAILMSG:
res = ast_streamfile(mychannel, myrpt->tailmessages[myrpt->tailmessagen], mychannel->language);
break;
case IDTALKOVER:
p = ast_variable_retrieve(cfg, nodename, "idtalkover");
if(p)
res = telem_any(mychannel, p);
imdone=1;
break;
case PROC:
/* wait a little bit longer */
wait_interval(myrpt, DLY_TELEM, mychannel);
res = ast_streamfile(mychannel, "rpt/callproceeding", mychannel->language);
break;
case TERM:
/* wait a little bit longer */
wait_interval(myrpt, DLY_CALLTERM, mychannel);
res = ast_streamfile(mychannel, "rpt/callterminated", mychannel->language);
break;
case COMPLETE:
/* wait a little bit */
wait_interval(myrpt, DLY_TELEM, mychannel);
res = telem_lookup(mychannel, myrpt->name, "functcomplete");
break;
case MACRO_NOTFOUND:
/* wait a little bit */
wait_interval(myrpt, DLY_TELEM, mychannel);
res = ast_streamfile(mychannel, "rpt/macro_notfound", mychannel->language);
break;
case MACRO_BUSY:
/* wait a little bit */
wait_interval(myrpt, DLY_TELEM, mychannel);
res = ast_streamfile(mychannel, "rpt/macro_busy", mychannel->language);
break;
case UNKEY:
/*
* Reset the Unkey to CT timer
*/
x = get_wait_interval(myrpt, DLY_UNKEY);
rpt_mutex_lock(&myrpt->lock);
myrpt->unkeytocttimer = x; /* Must be protected as it is changed below */
rpt_mutex_unlock(&myrpt->lock);
/*
* If there's one already queued, don't do another
*/
tlist = myrpt->tele.next;
unkeys_queued = 0;
if (tlist != &myrpt->tele)
{
rpt_mutex_lock(&myrpt->lock);
while(tlist != &myrpt->tele){
if (tlist->mode == UNKEY) unkeys_queued++;
tlist = tlist->next;
}
rpt_mutex_unlock(&myrpt->lock);
}
if( unkeys_queued > 1){
imdone = 1;
break;
}
/* Wait for the telemetry timer to expire */
/* Periodically check the timer since it can be re-initialized above */
while(myrpt->unkeytocttimer)
{
int ctint;
if(myrpt->unkeytocttimer > 100)
ctint = 100;
else
ctint = myrpt->unkeytocttimer;
ast_safe_sleep(mychannel, ctint);
rpt_mutex_lock(&myrpt->lock);
if(myrpt->unkeytocttimer < ctint)
myrpt->unkeytocttimer = 0;
else
myrpt->unkeytocttimer -= ctint;
rpt_mutex_unlock(&myrpt->lock);
}
/*
* Now, the carrier on the rptr rx should be gone.
* If it re-appeared, then forget about sending the CT
*/
if(myrpt->keyed){
imdone = 1;
break;
}
hastx = 0;
hasremote = 0;
l = myrpt->links.next;
if (l != &myrpt->links)
{
rpt_mutex_lock(&myrpt->lock);
while(l != &myrpt->links)
{
if (l->name[0] == '0')
{
l = l->next;
continue;
}
haslink = 1;
if (l->mode) {
hastx++;
if (l->isremote) hasremote++;
}
l = l->next;
}
rpt_mutex_unlock(&myrpt->lock);
res = telem_lookup(mychannel, myrpt->name, (!hastx) ? "remotemon" : "remotetx");
if(res)
ast_log(LOG_WARNING, "telem_lookup:remotexx failed on %s\n", mychannel->name);
/* if in remote cmd mode, indicate it */
if (myrpt->cmdnode[0])
{
ast_safe_sleep(mychannel,200);
res = telem_lookup(mychannel, myrpt->name, "cmdmode");
if(res)
ast_log(LOG_WARNING, "telem_lookup:cmdmode failed on %s\n", mychannel->name);
ast_stopstream(mychannel);
}
}
else if((ct = ast_variable_retrieve(cfg, nodename, "unlinkedct"))){ /* Unlinked Courtesy Tone */
ct_copy = ast_strdupa(ct);
res = telem_lookup(mychannel, myrpt->name, ct_copy);
if(res)
ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name);
}
if (hasremote && (!myrpt->cmdnode[0]))
{
/* set for all to hear */
ci.chan = 0;
ci.confno = myrpt->conf;
ci.confmode = ZT_CONF_CONFANN;
/* first put the channel on the conference in announce mode */
if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1)
{
ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
rpt_mutex_lock(&myrpt->lock);
remque((struct qelem *)mytele);
rpt_mutex_unlock(&myrpt->lock);
ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
free(mytele);
ast_hangup(mychannel);
pthread_exit(NULL);
}
if((ct = ast_variable_retrieve(cfg, nodename, "remotect"))){ /* Unlinked Courtesy Tone */
ast_safe_sleep(mychannel,200);
ct_copy = ast_strdupa(ct);
res = telem_lookup(mychannel, myrpt->name, ct_copy);
if(res)
ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name);
}
}
imdone = 1;
break;
case REMDISC:
/* wait a little bit */
wait_interval(myrpt, DLY_TELEM, mychannel);
res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
if (!res)
res = ast_waitstream(mychannel, "");
else
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
ast_stopstream(mychannel);
ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language);
res = ast_streamfile(mychannel, ((mytele->mylink.connected) ?
"rpt/remote_disc" : "rpt/remote_busy"), mychannel->language);
break;
case REMALREADY:
/* wait a little bit */
wait_interval(myrpt, DLY_TELEM, mychannel);
res = ast_streamfile(mychannel, "rpt/remote_already", mychannel->language);
break;
case REMNOTFOUND:
/* wait a little bit */
wait_interval(myrpt, DLY_TELEM, mychannel);
res = ast_streamfile(mychannel, "rpt/remote_notfound", mychannel->language);
break;
case REMGO:
/* wait a little bit */
wait_interval(myrpt, DLY_TELEM, mychannel);
res = ast_streamfile(mychannel, "rpt/remote_go", mychannel->language);
break;
case CONNECTED:
/* wait a little bit */
wait_interval(myrpt, DLY_TELEM, mychannel);
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
if (!res)
res = ast_waitstream(mychannel, "");
else
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
ast_stopstream(mychannel);
ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language);
res = ast_streamfile(mychannel, "rpt/connected", mychannel->language);
break;
case CONNFAIL:
res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
if (!res)
res = ast_waitstream(mychannel, "");
else
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
ast_stopstream(mychannel);
ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language);
res = ast_streamfile(mychannel, "rpt/connection_failed", mychannel->language);
break;
case STATUS:
/* wait a little bit */
wait_interval(myrpt, DLY_TELEM, mychannel);
hastx = 0;
linkbase.next = &linkbase;
linkbase.prev = &linkbase;
rpt_mutex_lock(&myrpt->lock);
/* make our own list of links */
l = myrpt->links.next;
while(l != &myrpt->links)
{
if (l->name[0] == '0')
}
m = malloc(sizeof(struct rpt_link));
if (!m)
{
ast_log(LOG_WARNING, "Cannot alloc memory on %s\n", mychannel->name);
rpt_mutex_unlock(&myrpt->lock);
ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
pthread_exit(NULL);
}
memcpy(m,l,sizeof(struct rpt_link));
m->next = m->prev = NULL;
insque((struct qelem *)m,(struct qelem *)linkbase.next);
l = l->next;
}
rpt_mutex_unlock(&myrpt->lock);
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
if (!res)
res = ast_waitstream(mychannel, "");
else
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
ast_stopstream(mychannel);
ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language);
if (!res)
res = ast_waitstream(mychannel, "");
else
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
ast_stopstream(mychannel);
if (myrpt->callmode)
{
hastx = 1;
res = ast_streamfile(mychannel, "rpt/autopatch_on", mychannel->language);
if (!res)
res = ast_waitstream(mychannel, "");
else
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
ast_stopstream(mychannel);
}
l = linkbase.next;
while(l != &linkbase)
{
hastx = 1;
res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
if (!res)
res = ast_waitstream(mychannel, "");
else
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
ast_stopstream(mychannel);
ast_say_character_str(mychannel,l->name,NULL,mychannel->language);
if (!res)
res = ast_waitstream(mychannel, "");
else
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
ast_stopstream(mychannel);
res = ast_streamfile(mychannel, ((l->mode) ?
"rpt/tranceive" : "rpt/monitor"), mychannel->language);
if (!res)
res = ast_waitstream(mychannel, "");
else
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
ast_stopstream(mychannel);
l = l->next;
}
if (!hastx)
{
res = ast_streamfile(mychannel, "rpt/repeat_only", mychannel->language);
if (!res)
res = ast_waitstream(mychannel, "");
else
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
ast_stopstream(mychannel);
}
/* destroy our local link queue */
l = linkbase.next;
while(l != &linkbase)
{
m = l;
l = l->next;
remque((struct qelem *)m);
free(m);
}
imdone = 1;
break;
case TIMEOUT:
res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
if (!res)
res = ast_waitstream(mychannel, "");
else
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
ast_stopstream(mychannel);
ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language);
res = ast_streamfile(mychannel, "rpt/timeout", mychannel->language);
break;
wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */
Jim Dixon
committed
localtime_r(&t, &localtm);
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
/* Say the phase of the day is before the time */
if((localtm.tm_hour >= 0) && (localtm.tm_hour < 12))
p = "rpt/goodmorning";
else if((localtm.tm_hour >= 12) && (localtm.tm_hour < 18))
p = "rpt/goodafternoon";
else
p = "rpt/goodevening";
if (sayfile(mychannel,p) == -1)
{
imdone = 1;
break;
}
/* Say the time is ... */
if (sayfile(mychannel,"rpt/thetimeis") == -1)
{
imdone = 1;
break;
}
/* Say the time */
res = ast_say_time(mychannel, t, "", mychannel->language);
if (!res)
res = ast_waitstream(mychannel, "");
ast_stopstream(mychannel);
imdone = 1;
break;
case STATS_VERSION:
p = strstr(tdesc, "version");
if(!p)
break;
if(sscanf(p, "version %d.%d", &vmajor, &vminor) != 2)
break;
wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
/* Say "version" */
if (sayfile(mychannel,"rpt/version") == -1)
{
imdone = 1;
break;
}
if(!res) /* Say "X" */
ast_say_number(mychannel, vmajor, "", mychannel->language, (char *) NULL);
if (!res)
res = ast_waitstream(mychannel, "");
ast_stopstream(mychannel);
if (saycharstr(mychannel,".") == -1)
{
imdone = 1;
break;
}
if(!res) /* Say "Y" */
ast_say_number(mychannel, vminor, "", mychannel->language, (char *) NULL);
if (!res){
res = ast_waitstream(mychannel, "");
ast_stopstream(mychannel);
}
else
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
imdone = 1;
break;
case ARB_ALPHA:
wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */
if(mytele->param)
saycharstr(mychannel, mytele->param);
imdone = 1;
break;
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
case REV_PATCH:
wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */
if(mytele->param) {
/* Parts of this section taken from app_parkandannounce */
char *tpl_working, *tpl_current;
char *tmp[100], *myparm;
int looptemp=0,i=0, dres = 0;
tpl_working = strdupa(mytele->param);
myparm = strsep(&tpl_working,",");
tpl_current=strsep(&tpl_working, ":");
while(tpl_current && looptemp < sizeof(tmp)) {
tmp[looptemp]=tpl_current;
looptemp++;
tpl_current=strsep(&tpl_working,":");
}
for(i=0; i<looptemp; i++) {
if(!strcmp(tmp[i], "PARKED")) {
ast_say_digits(mychannel, atoi(myparm), "", mychannel->language);
} else if(!strcmp(tmp[i], "NODE")) {
ast_say_digits(mychannel, atoi(myrpt->name), "", mychannel->language);
} else {
dres = ast_streamfile(mychannel, tmp[i], mychannel->language);
if(!dres) {
dres = ast_waitstream(mychannel, "");
} else {
ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[i], mychannel->name);
dres = 0;
}
}
}
}
imdone = 1;
break;
case TEST_TONE:
imdone = 1;
myrpt->stopgen = 0;
if ((res = ast_tonepair_start(mychannel, 1004.0, 0, 99999999, 7200.0)))
break;
while(mychannel->generatordata && (!myrpt->stopgen)) {
if (ast_safe_sleep(mychannel,1)) break;
imdone = 1;
}
break;
}
if (!imdone)
{
if (!res)
res = ast_waitstream(mychannel, "");
else {
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
res = 0;
}
}
ast_stopstream(mychannel);
rpt_mutex_lock(&myrpt->lock);
if (mytele->mode == TAILMSG)
{
if (!res)
{
myrpt->tailmessagen++;
if(myrpt->tailmessagen >= myrpt->tailmessagemax) myrpt->tailmessagen = 0;
}
else
{
myrpt->tmsgtimer = myrpt->tailsquashedtime;
}
}
remque((struct qelem *)mytele);
rpt_mutex_unlock(&myrpt->lock);
free(mytele);
ast_hangup(mychannel);
#ifdef APP_RPT_LOCK_DEBUG
{
struct lockthread *t;
sleep(5);
ast_mutex_lock(&locklock);
t = get_lockthread(pthread_self());
if (t) memset(t,0,sizeof(struct lockthread));
ast_mutex_unlock(&locklock);
}
#endif
pthread_exit(NULL);
}
static void rpt_telemetry(struct rpt *myrpt,int mode, void *data)
{
struct rpt_tele *tele;
struct rpt_link *mylink = (struct rpt_link *) data;
int res;
pthread_attr_t attr;
tele = malloc(sizeof(struct rpt_tele));
if (!tele)
{
ast_log(LOG_WARNING, "Unable to allocate memory\n");
pthread_exit(NULL);
return;
}
/* zero it out */
memset((char *)tele,0,sizeof(struct rpt_tele));
tele->rpt = myrpt;
tele->mode = mode;
rpt_mutex_lock(&myrpt->lock);
if((mode == CONNFAIL) || (mode == REMDISC) || (mode == CONNECTED)){
memset(&tele->mylink,0,sizeof(struct rpt_link));
if (mylink){
memcpy(&tele->mylink,mylink,sizeof(struct rpt_link));
}
}
else if ((mode == ARB_ALPHA) || (mode == REV_PATCH)) {
strncpy(tele->param, (char *) data, TELEPARAMSIZE - 1);
tele->param[TELEPARAMSIZE - 1] = 0;
}
rpt_mutex_unlock(&myrpt->lock);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
res = ast_pthread_create(&tele->threadid,&attr,rpt_tele_thread,(void *) tele);
if(res < 0)
ast_log(LOG_WARNING, "Could not create telemetry thread: %s",strerror(res));
return;
}
static void *rpt_call(void *this)
{
ZT_CONFINFO ci; /* conference info */
struct rpt *myrpt = (struct rpt *)this;
int res;
int stopped,congstarted;
struct ast_channel *mychannel,*genchannel;
myrpt->mydtmf = 0;
/* allocate a pseudo-channel thru asterisk */
mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
if (!mychannel)
{
fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
pthread_exit(NULL);
}
ci.chan = 0;
ci.confno = myrpt->conf; /* use the pseudo conference */
ci.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER
| ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER;
/* first put the channel on the conference */
if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1)
{
ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
ast_hangup(mychannel);
myrpt->callmode = 0;
pthread_exit(NULL);
}
/* allocate a pseudo-channel thru asterisk */
genchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
if (!genchannel)
{
fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
ast_hangup(mychannel);
pthread_exit(NULL);
}
ci.chan = 0;
ci.confno = myrpt->conf;
ci.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER
| ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER;
/* first put the channel on the conference */
if (ioctl(genchannel->fds[0],ZT_SETCONF,&ci) == -1)
{
ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
ast_hangup(mychannel);
ast_hangup(genchannel);
myrpt->callmode = 0;
pthread_exit(NULL);
}
if (myrpt->tonezone && (tone_zone_set_zone(mychannel->fds[0],myrpt->tonezone) == -1))
{
ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->tonezone);
ast_hangup(mychannel);
ast_hangup(genchannel);
myrpt->callmode = 0;
pthread_exit(NULL);
}
if (myrpt->tonezone && (tone_zone_set_zone(genchannel->fds[0],myrpt->tonezone) == -1))
{
ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->tonezone);
ast_hangup(mychannel);
ast_hangup(genchannel);
myrpt->callmode = 0;
pthread_exit(NULL);
}
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
/* start dialtone */
if (tone_zone_play_tone(mychannel->fds[0],ZT_TONE_DIALTONE) < 0)
{
ast_log(LOG_WARNING, "Cannot start dialtone\n");
ast_hangup(mychannel);
ast_hangup(genchannel);
myrpt->callmode = 0;
pthread_exit(NULL);
}
stopped = 0;
congstarted = 0;
while ((myrpt->callmode == 1) || (myrpt->callmode == 4))
{
if ((myrpt->callmode == 1) && (myrpt->cidx > 0) && (!stopped))
{
stopped = 1;
/* stop dial tone */
tone_zone_play_tone(mychannel->fds[0],-1);
}
if ((myrpt->callmode == 4) && (!congstarted))
{
congstarted = 1;
/* start congestion tone */
tone_zone_play_tone(mychannel->fds[0],ZT_TONE_CONGESTION);
}
if (res < 0)
{
ast_hangup(mychannel);
ast_hangup(genchannel);
rpt_mutex_lock(&myrpt->lock);
rpt_mutex_unlock(&myrpt->lock);
pthread_exit(NULL);
}
}
/* stop any tone generation */
tone_zone_play_tone(mychannel->fds[0],-1);
/* end if done */
if (!myrpt->callmode)
{
ast_hangup(mychannel);
ast_hangup(genchannel);
rpt_mutex_lock(&myrpt->lock);
rpt_mutex_unlock(&myrpt->lock);
if (myrpt->ourcallerid && *myrpt->ourcallerid){
char *name, *loc, *instr;
instr = strdup(myrpt->ourcallerid);
if(instr){
ast_callerid_parse(instr, &name, &loc);
if(loc){
if(mychannel->cid.cid_num)
free(mychannel->cid.cid_num);
mychannel->cid.cid_num = strdup(loc);
}
if(name){
if(mychannel->cid.cid_name)
free(mychannel->cid.cid_name);
mychannel->cid.cid_name = strdup(name);
}
free(instr);
}
strncpy(mychannel->exten, myrpt->exten, sizeof(mychannel->exten) - 1);
strncpy(mychannel->context, myrpt->ourcontext, sizeof(mychannel->context) - 1);
Russell Bryant
committed
ast_string_field_set(mychannel, accountcode, myrpt->acctcode);
mychannel->priority = 1;
ast_channel_undefer_dtmf(mychannel);
if (ast_pbx_start(mychannel) < 0)
{
ast_log(LOG_WARNING, "Unable to start PBX!!\n");
ast_hangup(mychannel);
ast_hangup(genchannel);
rpt_mutex_lock(&myrpt->lock);
rpt_mutex_unlock(&myrpt->lock);